diff --git a/.gitignore b/.gitignore index 6334517..26875dfe 100644 --- a/.gitignore +++ b/.gitignore
@@ -343,6 +343,7 @@ /third_party/libphonenumber/libphonenumber_without_metadata.xml /third_party/libphonenumber/src /third_party/libsrtp +/third_party/libupnp /third_party/libvpx_new/source/libvpx /third_party/libwebm/source /third_party/libyuv
diff --git a/DEPS b/DEPS index a1c7ee2..94fa037 100644 --- a/DEPS +++ b/DEPS
@@ -39,11 +39,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '2da1a854b0836001533aa29ade89d87f420cbbc3', + 'skia_revision': 'fd2b067b9e6a8cc93581a61c67bb8ce3c626f60f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'a88d3ee6e26eb25fc1a0940a862b5ee3c057fc94', + 'v8_revision': '8f399c6b3c29cff086f7a355231d997d9152c00e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -59,7 +59,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': '24c1eec13f277f27cb27edfb3d191e8bd2223e7c', + 'pdfium_revision': 'ae2d47b22d213cb36a66326c3167cfbbae90b9d4', # 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. @@ -193,7 +193,7 @@ Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '525a71ab8ee3b61da48138f7e1c406989d2879fc', 'src/third_party/libjingle/source/talk': - Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '49460575f3cf8e99012eea942d46369d249d37f0', # commit position 10255 + Var('chromium_git') + '/external/webrtc/trunk/talk.git' + '@' + '8eb896f736638be2c704cfc032c740fecf15d816', # commit position 10273 'src/third_party/usrsctp/usrsctplib': Var('chromium_git') + '/external/usrsctplib.git' + '@' + '36444a999739e9e408f8f587cb4c3ffeef2e50ac', # from svn revision 9215 @@ -217,7 +217,7 @@ Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067', 'src/third_party/webrtc': - Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '8b3854ad414184f379b3f3ca7d1754dc506ce6f9', # commit position 10255 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '651bd16c1a0430dde5ba0eaec9bd5734916d9043', # commit position 10272 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'),
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index be7dccf..900e7c9 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -656,13 +656,13 @@ '--root', input_api.change.RepositoryRoot()] for f in input_api.AffectedFiles(): args += ['--file', f.LocalPath()] - checkperms = input_api.subprocess.Popen(args, - stdout=input_api.subprocess.PIPE) - errors = checkperms.communicate()[0].strip() - if errors: - return [output_api.PresubmitError('checkperms.py failed.', - errors.splitlines())] - return [] + try: + input_api.subprocess.check_output(args) + return [] + except input_api.subprocess.CalledProcessError as error: + return [output_api.PresubmitError( + 'checkperms.py failed:', + long_text=error.output)] def _CheckNoAuraWindowPropertyHInHeaders(input_api, output_api):
diff --git a/android_webview/tools/WebViewShell/test/webexposed/global-interface-listing-expected.txt b/android_webview/tools/WebViewShell/test/webexposed/global-interface-listing-expected.txt index 5c81de36..5a8d9b7 100644 --- a/android_webview/tools/WebViewShell/test/webexposed/global-interface-listing-expected.txt +++ b/android_webview/tools/WebViewShell/test/webexposed/global-interface-listing-expected.txt
@@ -309,6 +309,7 @@ getter style method constructor setter selectorText + setter style interface CSSStyleSheet getter cssRules getter ownerRule @@ -1574,6 +1575,7 @@ setter onwaiting setter outerText setter spellcheck + setter style setter tabIndex setter title setter translate @@ -2603,6 +2605,8 @@ method constructor method count method get + method getAll + method getAllKeys method getKey method openCursor method openKeyCursor @@ -2626,8 +2630,11 @@ method delete method deleteIndex method get + method getAll + method getAllKeys method index method openCursor + method openKeyCursor method put interface IDBOpenDBRequest getter onblocked @@ -2650,6 +2657,7 @@ getter db getter error getter mode + getter objectStoreNames getter onabort getter oncomplete getter onerror @@ -3585,6 +3593,7 @@ setter ontoggle setter onvolumechange setter onwaiting + setter style setter tabIndex interface SVGEllipseElement getter cx @@ -5606,6 +5615,8 @@ method constructor method count method get + method getAll + method getAllKeys method getKey method openCursor method openKeyCursor @@ -5629,8 +5640,11 @@ method delete method deleteIndex method get + method getAll + method getAllKeys method index method openCursor + method openKeyCursor method put interface webkitIDBRequest getter error @@ -5647,6 +5661,7 @@ getter db getter error getter mode + getter objectStoreNames getter onabort getter oncomplete getter onerror
diff --git a/ash/display/display_info.cc b/ash/display/display_info.cc index 2d18271..54380aa 100644 --- a/ash/display/display_info.cc +++ b/ash/display/display_info.cc
@@ -114,7 +114,8 @@ DisplayInfo DisplayInfo::CreateFromSpecWithID(const std::string& spec, int64 id) { #if defined(OS_WIN) - gfx::Rect bounds_in_native(aura::WindowTreeHost::GetNativeScreenSize()); + gfx::Rect bounds_in_native( + gfx::Size(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN))); #else // Default bounds for a display. const int kDefaultHostWindowX = 200;
diff --git a/ash/test/test_keyboard_ui.cc b/ash/test/test_keyboard_ui.cc index b99266c..67b6993 100644 --- a/ash/test/test_keyboard_ui.cc +++ b/ash/test/test_keyboard_ui.cc
@@ -20,6 +20,10 @@ return keyboard_; } +bool TestKeyboardUI::ShouldWindowOverscroll(aura::Window* window) const { + return true; +} + aura::Window* TestKeyboardUI::GetKeyboardWindow() { if (!keyboard_) { keyboard_.reset(new aura::Window(&delegate_));
diff --git a/ash/test/test_keyboard_ui.h b/ash/test/test_keyboard_ui.h index d1c1f75..2b8a24ed 100644 --- a/ash/test/test_keyboard_ui.h +++ b/ash/test/test_keyboard_ui.h
@@ -22,6 +22,7 @@ ~TestKeyboardUI() override; bool HasKeyboardWindow() const override; + bool ShouldWindowOverscroll(aura::Window* window) const override; aura::Window* GetKeyboardWindow() override; private:
diff --git a/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDex.java b/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDex.java index 2c28673..7696a14 100644 --- a/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDex.java +++ b/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDex.java
@@ -19,7 +19,7 @@ */ public class ChromiumMultiDex { - private static final String TAG = "cr.base.multidex"; + private static final String TAG = "base_multidex"; /** * Installs secondary dexes if possible.
diff --git a/base/sys_info_android.cc b/base/sys_info_android.cc index c288ae2..0eeb581 100644 --- a/base/sys_info_android.cc +++ b/base/sys_info_android.cc
@@ -59,8 +59,8 @@ // cannot be acquired. Use the latest Android release with a higher bug fix // version to avoid unnecessarily comparison errors with the latest release. // This should be manually kept up-to-date on each Android release. -const int kDefaultAndroidMajorVersion = 5; -const int kDefaultAndroidMinorVersion = 1; +const int kDefaultAndroidMajorVersion = 6; +const int kDefaultAndroidMinorVersion = 0; const int kDefaultAndroidBugfixVersion = 99; // Parse out the OS version numbers from the system properties.
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseInstrumentationTestRunner.java b/base/test/android/javatests/src/org/chromium/base/test/BaseInstrumentationTestRunner.java index 0eab2314..58e5b1c 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/BaseInstrumentationTestRunner.java +++ b/base/test/android/javatests/src/org/chromium/base/test/BaseInstrumentationTestRunner.java
@@ -20,6 +20,7 @@ import org.chromium.base.SysUtils; import org.chromium.base.multidex.ChromiumMultiDex; import org.chromium.base.test.BaseTestResult.SkipCheck; +import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.Restriction; import org.chromium.test.reporter.TestStatusListener; @@ -31,7 +32,7 @@ * An Instrumentation test runner that checks SDK level for tests with specific requirements. */ public class BaseInstrumentationTestRunner extends InstrumentationTestRunner { - private static final String TAG = "cr.base.test"; + private static final String TAG = "base_test"; @Override public void onCreate(Bundle arguments) { @@ -45,7 +46,7 @@ @Override protected TestResult createTestResult() { BaseTestResult r = new BaseTestResult(BaseInstrumentationTestRunner.this); - addSkipChecks(r); + addTestHooks(r); return r; } }; @@ -54,17 +55,24 @@ } /** - * Adds the desired SkipChecks to result. Subclasses can add additional SkipChecks. + * Override this method to register hooks and checks to be run for each test. Make sure to call + * the base implementation if you do so. + * + * @see BaseTestResult#addSkipCheck(BaseTestResult.SkipCheck) + * @see BaseTestResult#addPreTestHook(BaseTestResult.PreTestHook) */ - protected void addSkipChecks(BaseTestResult result) { + protected void addTestHooks(BaseTestResult result) { result.addSkipCheck(new MinAndroidSdkLevelSkipCheck()); result.addSkipCheck(new RestrictionSkipCheck()); + + result.addPreTestHook(CommandLineFlags.getRegistrationHook()); } /** * Checks if any restrictions exist and skip the test if it meets those restrictions. */ public class RestrictionSkipCheck implements SkipCheck { + @Override public boolean shouldSkip(TestCase testCase) { Method method; try {
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java b/base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java index 5802f40..64ad9f2 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java +++ b/base/test/android/javatests/src/org/chromium/base/test/BaseTestResult.java
@@ -14,7 +14,6 @@ import junit.framework.TestResult; import org.chromium.base.Log; -import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.parameter.BaseParameter; import org.chromium.base.test.util.parameter.Parameter; import org.chromium.base.test.util.parameter.Parameterizable; @@ -22,6 +21,7 @@ import java.io.PrintWriter; import java.io.StringWriter; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; @@ -33,19 +33,21 @@ * A test result that can skip tests. */ public class BaseTestResult extends TestResult { - private static final String TAG = "cr.base.test"; + private static final String TAG = "base_test"; private static final int SLEEP_INTERVAL_MS = 50; private static final int WAIT_DURATION_MS = 5000; private final Instrumentation mInstrumentation; private final List<SkipCheck> mSkipChecks; + private final List<PreTestHook> mPreTestHooks; /** * Creates an instance of BaseTestResult. */ public BaseTestResult(Instrumentation instrumentation) { mSkipChecks = new ArrayList<>(); + mPreTestHooks = new ArrayList<>(); mInstrumentation = instrumentation; } @@ -64,6 +66,19 @@ } /** + * An interface for classes that have some code to run before a test. They run after + * {@link SkipCheck}s. Provides access to the test method (and the annotations defined for it) + * and the instrumentation context. + */ + public interface PreTestHook { + /** + * @param targetContext the instrumentation context that will be used during the test. + * @param testMethod the test method to be run. + */ + public void run(Context targetContext, Method testMethod); + } + + /** * Adds a check for whether a test should run. * * @param skipCheck The check to add. @@ -72,6 +87,15 @@ mSkipChecks.add(skipCheck); } + /** + * Adds hooks that will be executed before each test that runs. + * + * @param preTestHook The hook to add. + */ + public void addPreTestHook(PreTestHook preTestHook) { + mPreTestHooks.add(preTestHook); + } + protected boolean shouldSkip(TestCase test) { for (SkipCheck s : mSkipChecks) { if (s.shouldSkip(test)) return true; @@ -79,6 +103,19 @@ return false; } + private void runPreTestHooks(TestCase test) { + try { + Method testMethod = test.getClass().getMethod(test.getName()); + Context targetContext = getTargetContext(); + + for (PreTestHook hook : mPreTestHooks) { + hook.run(targetContext, testMethod); + } + } catch (NoSuchMethodException e) { + Log.e(TAG, "Unable to run pre test hooks.", e); + } + } + @Override protected void run(TestCase test) { if (shouldSkip(test)) { @@ -92,13 +129,7 @@ endTest(test); } else { - try { - CommandLineFlags.setUp( - getTargetContext(), - test.getClass().getMethod(test.getName())); - } catch (NoSuchMethodException e) { - Log.e(TAG, "Unable to set up CommandLineFlags", e); - } + runPreTestHooks(test); if (test instanceof Parameterizable) { try {
diff --git a/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java b/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java index 16697d3..408074c 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java +++ b/base/test/android/javatests/src/org/chromium/base/test/util/CommandLineFlags.java
@@ -10,6 +10,7 @@ import org.chromium.base.BaseChromiumApplication; import org.chromium.base.CommandLine; +import org.chromium.base.test.BaseTestResult.PreTestHook; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; @@ -102,4 +103,14 @@ } private CommandLineFlags() {} + + public static PreTestHook getRegistrationHook() { + return new PreTestHook() { + @Override + public void run(Context targetContext, Method testMethod) { + CommandLineFlags.setUp(targetContext, testMethod); + } + + }; + } }
diff --git a/build/android/gyp/javac.py b/build/android/gyp/javac.py index 65b36a5..f1965811 100755 --- a/build/android/gyp/javac.py +++ b/build/android/gyp/javac.py
@@ -150,12 +150,6 @@ return new_args -def _FilterJMakeOutput(stdout): - if md5_check.PRINT_EXPLANATIONS: - return stdout - return re.sub(r'\b(Jmake version|Writing project database).*?\n', '', stdout) - - def _FixTempPathsInIncrementalMetadata(pdb_path, temp_dir): # The .pdb records absolute paths. Fix up paths within /tmp (srcjars). if os.path.exists(pdb_path): @@ -209,7 +203,8 @@ os.makedirs(java_dir) for srcjar in options.java_srcjars: if changed_paths: - changed_paths.update(changes.IterChangedSubpaths(srcjar)) + changed_paths.update(os.path.join(java_dir, f) + for f in changes.IterChangedSubpaths(srcjar)) build_utils.ExtractAll(srcjar, path=java_dir, pattern='*.java') jar_srcs = build_utils.FindInDirectory(java_dir, '*.java') jar_srcs = _FilterJavaFiles(jar_srcs, options.javac_includes) @@ -237,10 +232,16 @@ # being in a temp dir makes it unstable (breaks md5 stamping). cmd = javac_cmd + ['-d', classes_dir] + java_files + # JMake prints out some diagnostic logs that we want to ignore. + # This assumes that all compiler output goes through stderr. + stdout_filter = lambda s: '' + if md5_check.PRINT_EXPLANATIONS: + stdout_filter = None + build_utils.CheckOutput( cmd, print_stdout=options.chromium_code, - stdout_filter=_FilterJMakeOutput, + stdout_filter=stdout_filter, stderr_filter=ColorJavacOutput) if options.main_class or options.manifest_entry:
diff --git a/build/android/gyp/pack_relocations.py b/build/android/gyp/pack_relocations.py index 02e4499..e112265 100755 --- a/build/android/gyp/pack_relocations.py +++ b/build/android/gyp/pack_relocations.py
@@ -20,7 +20,6 @@ import optparse import os -import shlex import shutil import sys import tempfile @@ -69,7 +68,8 @@ options, _ = parser.parse_args(args) enable_packing = (options.enable_packing == '1' and options.configuration_name == 'Release') - exclude_packing_set = set(shlex.split(options.exclude_packing_list)) + exclude_packing_set = set(build_utils.ParseGypList( + options.exclude_packing_list)) libraries = [] for libs_arg in options.libraries:
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 09bd6d2..4122126c 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -1237,14 +1237,6 @@ " of the Chromium linker.") } - _enable_relocation_packing = false - if (defined(invoker.enable_relocation_packing) && - invoker.enable_relocation_packing) { - _enable_relocation_packing = relocation_packing_supported - assert(_use_chromium_linker, - "Relocation packing requires use of the" + " Chromium linker.") - } - if (is_component_build) { _native_libs += [ "$root_shlib_dir/libc++_shared.so" ] _chromium_linker_dep += [ "//build/android:cpplib_stripped" ] @@ -1478,9 +1470,10 @@ inputs += [ _build_config ] deps += [ ":$build_config_target" ] + rebased_gdbserver = rebase_path(android_gdbserver, root_build_dir) skip_packing_list = [ - "gdbserver", - "libchromium_android_linker$shlib_extension", + rebased_gdbserver, + "libchromium_android_linker.so", ] enable_packing_arg = 0 @@ -1509,7 +1502,6 @@ } if (is_debug) { - rebased_gdbserver = rebase_path([ android_gdbserver ], root_build_dir) inputs += [ android_gdbserver ] args += [ "--libraries=$rebased_gdbserver" ] }
diff --git a/build/ios/grit_whitelist.txt b/build/ios/grit_whitelist.txt index d9169e4..d1771cc 100644 --- a/build/ios/grit_whitelist.txt +++ b/build/ios/grit_whitelist.txt
@@ -706,7 +706,6 @@ IDS_PASSWORDS_SHOW_PASSWORDS_TAB_TITLE IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON IDS_PASSWORD_MANAGER_SAVE_BUTTON -IDS_PASSWORD_MANAGER_SAVE_PASSWORD_SMART_LOCK_NO_THANKS_BUTTON IDS_PASSWORD_MANAGER_SMART_LOCK IDS_PASSWORD_MANAGER_SMART_LOCK_PAGE IDS_PAST_TIME_TODAY
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java index 7780bd3a..ac47b79 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
@@ -85,7 +85,7 @@ static final String ACTION_CLOSE_ALL_INCOGNITO = "com.google.android.apps.chrome.document.CLOSE_ALL_INCOGNITO"; - private static final String TAG = "cr.document.CLActivity"; + private static final String TAG = "document_CLActivity"; /** New instance should be launched in the foreground. */ public static final int LAUNCH_MODE_FOREGROUND = 0;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java index 73fb9a8b..c855aa0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
@@ -10,6 +10,7 @@ import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Canvas; +import android.graphics.Paint; import android.graphics.Rect; import android.os.SystemClock; import android.text.Editable; @@ -18,6 +19,7 @@ import android.text.Spanned; import android.text.TextUtils; import android.text.TextWatcher; +import android.text.style.ReplacementSpan; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.KeyEvent; @@ -32,6 +34,7 @@ import android.view.inputmethod.InputConnectionWrapper; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.SysUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.UrlUtilities; @@ -53,6 +56,11 @@ public class UrlBar extends VerticallyFixedEditText { private static final String TAG = "UrlBar"; + // TextView becomes very slow on long strings, so we limit maximum length + // of what is displayed to the user, see limitDisplayableLength(). + private static final int MAX_DISPLAYABLE_LENGHT = 4000; + private static final int MAX_DISPLAYABLE_LENGHT_LOW_END = 1000; + /** The contents of the URL that precede the path/query after being formatted. */ private String mFormattedUrlLocation; @@ -759,6 +767,7 @@ // URL is being edited). if (!TextUtils.equals(getEditableText(), text)) { super.setText(text, type); + limitDisplayableLength(); mAccessibilityTextOverride = null; } @@ -784,6 +793,25 @@ } } + private void limitDisplayableLength() { + // To limit displayable length we replace middle portion of the string with ellipsis. + // That affects only presentation of the text, and doesn't affect other aspects like + // copying to the clipboard, getting text with getText(), etc. + final int maxLength = SysUtils.isLowEndDevice() + ? MAX_DISPLAYABLE_LENGHT_LOW_END : MAX_DISPLAYABLE_LENGHT; + + Editable text = getText(); + int textLength = text.length(); + if (textLength <= maxLength) return; + + int spanLeft = text.nextSpanTransition(0, textLength, EllipsisSpan.class); + if (spanLeft != textLength) return; + + spanLeft = maxLength / 2; + text.setSpan(EllipsisSpan.INSTANCE, spanLeft, textLength - spanLeft, + Editable.SPAN_INCLUSIVE_EXCLUSIVE); + } + /** * Returns the portion of the URL that precedes the path/query section of the URL. * @@ -1002,4 +1030,26 @@ mUserText = null; } } + + /** + * Span that displays ellipsis instead of the text. Used to hide portion of + * very large string to get decent performance from TextView. + */ + private static class EllipsisSpan extends ReplacementSpan { + private static final String ELLIPSIS = "..."; + + public static final EllipsisSpan INSTANCE = new EllipsisSpan(); + + @Override + public int getSize(Paint paint, CharSequence text, + int start, int end, Paint.FontMetricsInt fm) { + return (int) paint.measureText(ELLIPSIS); + } + + @Override + public void draw(Canvas canvas, CharSequence text, int start, int end, + float x, int top, int y, int bottom, Paint paint) { + canvas.drawText(ELLIPSIS, x, y, paint); + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ContentSetting.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ContentSetting.java index e797737..2c24c029 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ContentSetting.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ContentSetting.java
@@ -20,7 +20,9 @@ private int mValue; /** - * Converts the enum value to int. + * Converts the enum value to int. The integer value should be used when dealing with native + * code (reading from or writing to native content settings). Non-native code that needs a + * simple data type (e.g. preferences) should use the string representation. */ public int toInt() { return mValue; @@ -38,6 +40,18 @@ return null; } + /** + * Converts a string to its equivalent ContentSetting. + * @param value The string to convert. + * @return What value the enum is representing (or null if failed). + */ + public static ContentSetting fromString(String value) { + for (ContentSetting enumValue : ContentSetting.values()) { + if (enumValue.toString().equals(value)) return enumValue; + } + return null; + } + private ContentSetting(int value) { this.mValue = value; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java index d1a8e90..f41d8d3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SingleWebsitePreferences.java
@@ -555,7 +555,7 @@ @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - ContentSetting permission = ContentSetting.fromInt(Integer.parseInt((String) newValue)); + ContentSetting permission = ContentSetting.fromString((String) newValue); if (PREF_CAMERA_CAPTURE_PERMISSION.equals(preference.getKey())) { mSite.setCameraPermission(permission); } else if (PREF_COOKIES_PERMISSION.equals(preference.getKey())) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java index 16693b0..31c41c0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
@@ -57,7 +57,7 @@ */ public class ShareHelper { - private static final String TAG = "cr.chrome.browser"; + private static final String TAG = "share"; private static final String PACKAGE_NAME_KEY = "last_shared_package_name"; private static final String CLASS_NAME_KEY = "last_shared_class_name";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java index 028bb02..c8f55759 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java
@@ -41,7 +41,7 @@ */ public class PassphraseDialogFragment extends DialogFragment implements OnClickListener { - private static final String TAG = "cr.Sync.UI"; + private static final String TAG = "Sync_UI"; /** * A listener for passphrase events.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/AsyncDocumentLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/AsyncDocumentLauncher.java index 2ec4a1e..8d8aeae 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/AsyncDocumentLauncher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/AsyncDocumentLauncher.java
@@ -25,7 +25,7 @@ * that our task exists before firing the next Intent. */ public class AsyncDocumentLauncher { - private static final String TAG = "cr.document.AsyncLaunc"; + private static final String TAG = "document_AsyncLaunc"; /** * Milliseconds to wait for Android to acknowledge that our Activity's task exists.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java index 2bad5d5..22bada4a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActivity.java
@@ -6,6 +6,7 @@ import android.content.Intent; import android.graphics.Bitmap; +import android.graphics.Color; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; @@ -330,12 +331,17 @@ && (mWebappInfo.themeColor() & 0xFF000000L) != 0) { mBrandColor = (int) mWebappInfo.themeColor(); } - int color = mBrandColor == null - ? ApiCompatibilityUtils.getColor(getResources(), R.color.default_primary_color) - : mBrandColor; - ApiCompatibilityUtils.setTaskDescription(this, title, icon, color); - ApiCompatibilityUtils.setStatusBarColor(getWindow(), color); + int taskDescriptionColor = + ApiCompatibilityUtils.getColor(getResources(), R.color.default_primary_color); + int statusBarColor = Color.BLACK; + if (mBrandColor != null) { + taskDescriptionColor = mBrandColor; + statusBarColor = ColorUtils.getDarkenedColorForStatusBar(mBrandColor); + } + + ApiCompatibilityUtils.setTaskDescription(this, title, icon, taskDescriptionColor); + ApiCompatibilityUtils.setStatusBarColor(getWindow(), statusBarColor); } @Override
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 33b6471..e8c11ec 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java
@@ -11,6 +11,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.compositor.layouts.Layout; import org.chromium.chrome.browser.tab.Tab; @@ -245,6 +246,7 @@ * crashed in background is restored in foreground. This is a regression test for * http://crbug.com/399521. */ + @DisabledTest // Flaked on the try bot: http://crbug.com/543153 @LargeTest @Feature({"ProcessManagement"}) public void testCrashInBackground() throws InterruptedException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java index 277aa3a..248f646e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ntp/NewTabPageTest.java
@@ -12,6 +12,7 @@ import android.view.ViewGroup; import org.chromium.base.ThreadUtils; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; import org.chromium.chrome.browser.UrlConstants; @@ -150,6 +151,7 @@ /** * Tests opening a most visited item in a new tab. */ + @DisabledTest // Flaked on the try bot. http://crbug.com/543138 @SmallTest @Feature({"NewTabPage"}) public void testOpenMostVisitedItemInNewTab() throws InterruptedException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java index 517498bf..f4c5de5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/UrlBarTest.java
@@ -4,6 +4,9 @@ package org.chromium.chrome.browser.omnibox; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; import android.content.Intent; import android.test.suitebuilder.annotation.SmallTest; import android.text.Editable; @@ -31,6 +34,12 @@ */ public class UrlBarTest extends ChromeActivityTestCaseBase<ChromeActivity> { + // 9000+ chars of goodness + private static final String HUGE_URL = + "data:text/plain,H" + + new String(new char[9000]).replace('\0', 'u') + + "ge!"; + public UrlBarTest() { super(ChromeActivity.class); } @@ -538,6 +547,46 @@ assertTrue(OmniboxTestUtils.waitForFocusAndKeyboardActive(urlBar, true)); } + @SmallTest + @Feature({"Omnibox"}) + public void testCopyHuge() throws InterruptedException { + startMainActivityWithURL(HUGE_URL); + OmniboxTestUtils.toggleUrlBarFocus(getUrlBar(), true); + assertEquals(HUGE_URL, copyUrlToClipboard(android.R.id.copy)); + } + + @SmallTest + @Feature({"Omnibox"}) + public void testCutHuge() throws InterruptedException { + startMainActivityWithURL(HUGE_URL); + OmniboxTestUtils.toggleUrlBarFocus(getUrlBar(), true); + assertEquals(HUGE_URL, copyUrlToClipboard(android.R.id.cut)); + } + + /** + * Clears the clipboard, executes specified action on the omnibox and + * returns clipboard's content. Action can be either android.R.id.copy + * or android.R.id.cut. + */ + private String copyUrlToClipboard(final int action) { + ClipboardManager clipboardManager = (ClipboardManager) + getActivity().getSystemService(Context.CLIPBOARD_SERVICE); + + clipboardManager.setPrimaryClip(ClipData.newPlainText(null, "")); + + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + assertTrue(getUrlBar().onTextContextMenuItem(action)); + } + }); + + ClipData clip = clipboardManager.getPrimaryClip(); + CharSequence text = (clip != null && clip.getItemCount() != 0) + ? clip.getItemAt(0).getText() : null; + return text != null ? text.toString() : null; + } + @Override public void startMainActivity() throws InterruptedException { // Each test will start the activity.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/util/FeatureUtilitiesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/util/FeatureUtilitiesTest.java index c24133c..b1c3b14 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/util/FeatureUtilitiesTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/util/FeatureUtilitiesTest.java
@@ -17,6 +17,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.AdvancedMockContext; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.sync.signin.AccountManagerHelper; import org.chromium.sync.test.util.MockAccountManager; @@ -221,6 +222,7 @@ assertTrue(hasAuthenticator); } + @DisabledTest // Flaked on the try bot: http://crbug.com/543160 @SmallTest @Feature({"FeatureUtilities", "GoogleAccounts"}) public void testHasNoGoogleAccountCorrectlyDetected() {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestBase.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestBase.java index 57b1ce4..b7f68009 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestBase.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappActivityTestBase.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.webapps; import android.content.Intent; -import android.graphics.Color; import android.net.Uri; import org.chromium.base.ThreadUtils; @@ -33,6 +32,18 @@ super(WebappActivity0.class); } + /** + * Creates the Intent that starts the WebAppActivity. This is meant to be overriden by other + * tests in order for them to pass some specific values. + */ + protected Intent createIntent() { + Intent intent = new Intent(getInstrumentation().getTargetContext(), WebappActivity0.class); + intent.setData(Uri.parse(WebappActivity.WEBAPP_SCHEME + "://" + WEBAPP_ID)); + intent.putExtra(ShortcutHelper.EXTRA_ID, WEBAPP_ID); + intent.putExtra(ShortcutHelper.EXTRA_URL, "about:blank"); + return intent; + } + @Override protected void setUp() throws Exception { super.setUp(); @@ -44,12 +55,7 @@ // Default to a webapp that just loads about:blank to avoid a network load. This results // in the URL bar showing since {@link UrlUtils} cannot parse this type of URL. - Intent intent = new Intent(getInstrumentation().getTargetContext(), WebappActivity0.class); - intent.setData(Uri.parse(WebappActivity.WEBAPP_SCHEME + "://" + WEBAPP_ID)); - intent.putExtra(ShortcutHelper.EXTRA_ID, WEBAPP_ID); - intent.putExtra(ShortcutHelper.EXTRA_THEME_COLOR, (long) Color.MAGENTA); - intent.putExtra(ShortcutHelper.EXTRA_URL, "about:blank"); - setActivityIntent(intent); + setActivityIntent(createIntent()); waitUntilIdle();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java index 6ecf388..6bfac0b8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java
@@ -171,8 +171,11 @@ /** * Tests that a WebappActivity can be brought forward by calling * WebContentsDelegateAndroid.activateContents(). + * + * Flaky: https://crbug.com/539755 + * @MediumTest */ - @MediumTest + @DisabledTest public void testActivateContents() throws Exception { runForegroundingTest(true); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenTest.java index 1dc22e4d..82c9732 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenTest.java
@@ -63,10 +63,10 @@ @SmallTest @Feature({"Webapps"}) @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public void testSplashscreenThemeColor() { + public void testSplashscreenThemeColorWhenNotSpecified() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; - assertEquals(Color.MAGENTA, getActivity().getWindow().getStatusBarColor()); + assertEquals(Color.BLACK, getActivity().getWindow().getStatusBarColor()); } private void setActivityWebappInfoFromBitmap(Bitmap image) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenThemeColorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenThemeColorTest.java new file mode 100644 index 0000000..120785d --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappSplashScreenThemeColorTest.java
@@ -0,0 +1,38 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.webapps; + +import android.annotation.TargetApi; +import android.content.Intent; +import android.graphics.Color; +import android.os.Build; +import android.test.suitebuilder.annotation.SmallTest; + +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.ShortcutHelper; +import org.chromium.chrome.browser.util.ColorUtils; + +/** + * Tests for splashscreen. + */ +public class WebappSplashScreenThemeColorTest extends WebappActivityTestBase { + + @Override + protected Intent createIntent() { + Intent intent = super.createIntent(); + intent.putExtra(ShortcutHelper.EXTRA_THEME_COLOR, (long) Color.MAGENTA); + return intent; + } + + @SmallTest + @Feature({"Webapps"}) + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public void testSplashscreenThemeColorWhenSpecified() { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return; + + assertEquals(ColorUtils.getDarkenedColorForStatusBar(Color.MAGENTA), + getActivity().getWindow().getStatusBarColor()); + } +}
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h index 204ac22..850903f 100644 --- a/chrome/app/chrome_command_ids.h +++ b/chrome/app/chrome_command_ids.h
@@ -276,6 +276,7 @@ #define IDC_CONTENT_CONTEXT_COPYLINKLOCATION 50104 #define IDC_CONTENT_CONTEXT_COPYEMAILADDRESS 50105 #define IDC_CONTENT_CONTEXT_OPENLINKWITH 50106 +#define IDC_CONTENT_CONTEXT_COPYLINKTEXT 50107 // Image items. #define IDC_CONTENT_CONTEXT_SAVEIMAGEAS 50110 #define IDC_CONTENT_CONTEXT_COPYIMAGELOCATION 50111
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 0fb2c67..0a8c55f 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -731,6 +731,10 @@ Copy &email address </message> + <message name="IDS_CONTENT_CONTEXT_COPYLINKTEXT" desc="The name of the Copy Link Text command in the content area context menu"> + Copy link te&xt + </message> + <message name="IDS_CONTENT_CONTEXT_SAVEIMAGEAS" desc="The name of the Save Image As command in the content area context menu"> Sa&ve image as... </message> @@ -937,6 +941,10 @@ Copy &Email Address </message> + <message name="IDS_CONTENT_CONTEXT_COPYLINKTEXT" desc="In Title Case: The name of the Copy Link Text command in the content area context menu"> + Copy Link Te&xt + </message> + <message name="IDS_CONTENT_CONTEXT_SAVEIMAGEAS" desc="In Title Case: The name of the Save Image As command in the content area context menu"> Sa&ve Image As... </message> @@ -5985,9 +5993,6 @@ <message name="IDS_PASSWORD_MANAGER_SMART_LOCK_PAGE" desc="URL of the passwords dashboard."> https://passwords.google.com/?hl=[GRITLANGCODE] </message> - <message name="IDS_PASSWORD_MANAGER_SAVE_PASSWORD_SMART_LOCK_NO_THANKS_BUTTON" desc="Text for the button the user clicks to dismiss save password bubble."> - No thanks - </message> <message name="IDS_FLAGS_ENABLE_SUGGESTIONS_WITH_SUB_STRING_MATCH_NAME" desc="Name of the flag to enable substring matching for Autofill suggestions."> Substring matching for Autofill suggestions. </message> @@ -13658,7 +13663,7 @@ <message name="IDS_LEGACY_SUPERVISED_USER_CREATED_TEXT" desc="Informative text for the confirmation dialog that appears after a supervised user has been created."> A supervised user named <ph name="NEW_PROFILE_NAME">$1<ex>New User</ex></ph> has been created. To set which websites this supervised user can view, you can configure restrictions and settings by visiting <ph name="BEGIN_LINK"><a target="_blank" href="$3"></ph><ph name="DISPLAY_LINK">$4</ph><ph name="END_LINK"></a><ex></a></ex></ph>. If you do not change the default settings, <ph name="NEW_PROFILE_NAME">$1<ex>New User</ex></ph> can browse all sites on the web. - Please check your email at <ph name="ACCOUNT_EMAIL">$2<ex>jane.doe@gmail.com</ex></ph> for these and further instructions. +Please check your email at <ph name="ACCOUNT_EMAIL">$2<ex>jane.doe@gmail.com</ex></ph> for these and further instructions. </message> <message name="IDS_LEGACY_SUPERVISED_USER_CREATED_DONE_BUTTON" desc="Text for the button that closes the dialog without making any additional changes, on the supervised user creation confirmation dialog."> Got it
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 5b4af92..62fa372 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -957,6 +957,18 @@ #endif } +bool ChromeContentBrowserClient::DoesSiteRequireDedicatedProcess( + content::BrowserContext* browser_context, + const GURL& effective_site_url) { +#if defined(ENABLE_EXTENSIONS) + if (ChromeContentBrowserClientExtensionsPart::DoesSiteRequireDedicatedProcess( + browser_context, effective_site_url)) { + return true; + } +#endif + return false; +} + // TODO(creis, nick): https://crbug.com/160576 describes a weakness in our // origin-lock enforcement, where we don't have a way to efficiently know // effective URLs on the IO thread, and wind up killing processes that e.g.
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 2d5ee03..0b0debac 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -68,12 +68,14 @@ content::WebContentsViewDelegate* GetWebContentsViewDelegate( content::WebContents* web_contents) override; void RenderProcessWillLaunch(content::RenderProcessHost* host) override; - bool ShouldUseProcessPerSite(content::BrowserContext* browser_context, - const GURL& effective_url) override; - bool ShouldLockToOrigin(content::BrowserContext* browser_context, - const GURL& effective_site_url) override; GURL GetEffectiveURL(content::BrowserContext* browser_context, const GURL& url) override; + bool ShouldUseProcessPerSite(content::BrowserContext* browser_context, + const GURL& effective_url) override; + bool DoesSiteRequireDedicatedProcess(content::BrowserContext* browser_context, + const GURL& effective_url) override; + bool ShouldLockToOrigin(content::BrowserContext* browser_context, + const GURL& effective_site_url) override; void GetAdditionalWebUISchemes( std::vector<std::string>* additional_schemes) override; void GetAdditionalWebUIHostsToIgnoreParititionCheck(
diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc index bb82828..15ea34cf 100644 --- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc +++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/renderer_host/chrome_extension_message_filter.h" #include "chrome/browser/sync_file_system/local/sync_file_system_backend.h" #include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension_process_policy.h" #include "components/guest_view/browser/guest_view_message_filter.h" #include "content/public/browser/browser_thread.h" @@ -184,6 +185,26 @@ } // static +bool ChromeContentBrowserClientExtensionsPart::DoesSiteRequireDedicatedProcess( + content::BrowserContext* browser_context, + const GURL& effective_site_url) { + if (effective_site_url.SchemeIs(extensions::kExtensionScheme)) { + // --isolate-extensions should isolate extensions, except for hosted apps. + // Isolating hosted apps is a good idea, but ought to be a separate knob. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kIsolateExtensions)) { + const Extension* extension = + ExtensionRegistry::Get(browser_context) + ->enabled_extensions() + .GetExtensionOrAppByURL(effective_site_url); + if (extension && !extension->is_hosted_app()) + return true; + } + } + return false; +} + +// static bool ChromeContentBrowserClientExtensionsPart::ShouldLockToOrigin( content::BrowserContext* browser_context, const GURL& effective_site_url) {
diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.h b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.h index fbdad7f..6dca654b 100644 --- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.h +++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.h
@@ -28,6 +28,9 @@ static GURL GetEffectiveURL(Profile* profile, const GURL& url); static bool ShouldUseProcessPerSite(Profile* profile, const GURL& effective_url); + static bool DoesSiteRequireDedicatedProcess( + content::BrowserContext* browser_context, + const GURL& effective_site_url); static bool ShouldLockToOrigin(content::BrowserContext* browser_context, const GURL& effective_site_url); static bool CanCommitURL(content::RenderProcessHost* process_host,
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 00fcdc7..e031b50 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -140,6 +140,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/material_design/material_design_controller.h" #include "url/gurl.h" #if defined(ENABLE_SUPERVISED_USERS) @@ -2325,10 +2326,14 @@ EXPECT_EQ("name", theme->name()); EXPECT_EQ("description", theme->description()); - // Cleanup the "Cached Theme.pak" file. Ideally, this would be installed in a + // Cleanup the "Cached Theme.pak" file (or "Cached Theme Material Design.pak" + // when Material Design is enabled). Ideally, this would be installed in a // temporary directory, but it automatically installs to the extension's // directory, and we don't want to copy the whole extension for a unittest. - base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename); + base::FilePath theme_file = extension_path.Append( + ui::MaterialDesignController::IsModeMaterial() + ? chrome::kThemePackMaterialDesignFilename + : chrome::kThemePackFilename); ASSERT_TRUE(base::PathExists(theme_file)); ASSERT_TRUE(base::DeleteFile(theme_file, false)); // Not recursive. }
diff --git a/chrome/browser/net/file_downloader_unittest.cc b/chrome/browser/net/file_downloader_unittest.cc new file mode 100644 index 0000000..0eb5474f --- /dev/null +++ b/chrome/browser/net/file_downloader_unittest.cc
@@ -0,0 +1,130 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/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/thread_task_runner_handle.h" +#include "chrome/browser/net/file_downloader.h" +#include "content/public/browser/browser_thread.h" +#include "net/url_request/test_url_fetcher_factory.h" +#include "net/url_request/url_request_test_util.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +const char kURL[] = "https://www.url.com/path"; +const char kFilename[] = "filename.ext"; +const char kFileContents1[] = "file contents"; +const char kFileContents2[] = "different contents"; + +class FileDownloaderTest : public testing::Test { + public: + FileDownloaderTest() + : request_context_(new net::TestURLRequestContextGetter( + base::ThreadTaskRunnerHandle::Get())), + url_fetcher_factory_(nullptr) {} + + void SetUp() override { + ASSERT_TRUE(dir_.CreateUniqueTempDir()); + path_ = dir_.path().AppendASCII(kFilename); + ASSERT_FALSE(base::PathExists(path_)); + } + + MOCK_METHOD1(OnDownloadFinished, void(bool success)); + + protected: + const base::FilePath& path() const { return path_; } + + void SetValidResponse() { + url_fetcher_factory_.SetFakeResponse( + GURL(kURL), kFileContents1, net::HTTP_OK, + net::URLRequestStatus::SUCCESS); + } + + void SetValidResponse2() { + url_fetcher_factory_.SetFakeResponse( + GURL(kURL), kFileContents2, net::HTTP_OK, + net::URLRequestStatus::SUCCESS); + } + + void SetFailedResponse() { + url_fetcher_factory_.SetFakeResponse( + GURL(kURL), std::string(), net::HTTP_NOT_FOUND, + net::URLRequestStatus::SUCCESS); + } + + void Download(bool overwrite, bool expect_success) { + FileDownloader downloader( + GURL(kURL), path_, overwrite, request_context_.get(), + base::Bind(&FileDownloaderTest::OnDownloadFinished, + base::Unretained(this))); + EXPECT_CALL(*this, OnDownloadFinished(expect_success)); + // 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(); + } + + private: + base::ScopedTempDir dir_; + base::FilePath path_; + + base::MessageLoop message_loop_; + scoped_refptr<net::TestURLRequestContextGetter> request_context_; + net::FakeURLFetcherFactory url_fetcher_factory_; +}; + +TEST_F(FileDownloaderTest, Success) { + SetValidResponse(); + Download(true, true); + EXPECT_TRUE(base::PathExists(path())); + std::string contents; + ASSERT_TRUE(base::ReadFileToString(path(), &contents)); + EXPECT_EQ(std::string(kFileContents1), contents); +} + +TEST_F(FileDownloaderTest, Failure) { + SetFailedResponse(); + Download(true, false); + EXPECT_FALSE(base::PathExists(path())); +} + +TEST_F(FileDownloaderTest, Overwrite) { + SetValidResponse(); + Download(true, true); + ASSERT_TRUE(base::PathExists(path())); + std::string contents; + ASSERT_TRUE(base::ReadFileToString(path(), &contents)); + ASSERT_EQ(std::string(kFileContents1), contents); + + SetValidResponse2(); + Download(true, true); + // The file should have been overwritten with the new contents. + EXPECT_TRUE(base::PathExists(path())); + ASSERT_TRUE(base::ReadFileToString(path(), &contents)); + EXPECT_EQ(std::string(kFileContents2), contents); +} + +TEST_F(FileDownloaderTest, DontOverwrite) { + SetValidResponse(); + Download(true, true); + ASSERT_TRUE(base::PathExists(path())); + std::string contents; + ASSERT_TRUE(base::ReadFileToString(path(), &contents)); + EXPECT_EQ(std::string(kFileContents1), contents); + + SetValidResponse2(); + Download(false, true); + // The file should still have the old contents. + EXPECT_TRUE(base::PathExists(path())); + ASSERT_TRUE(base::ReadFileToString(path(), &contents)); + EXPECT_EQ(std::string(kFileContents1), contents); +}
diff --git a/chrome/browser/password_manager/password_store_mac.cc b/chrome/browser/password_manager/password_store_mac.cc index f067dd8..bbb9b94 100644 --- a/chrome/browser/password_manager/password_store_mac.cc +++ b/chrome/browser/password_manager/password_store_mac.cc
@@ -238,6 +238,12 @@ forms->weak_clear(); } +// True if the form has no password to be stored in Keychain. +bool IsLoginDatabaseOnlyForm(const autofill::PasswordForm& form) { + return form.blacklisted_by_user || !form.federation_url.is_empty() || + form.scheme == autofill::PasswordForm::SCHEME_USERNAME_ONLY; +} + } // namespace #pragma mark - @@ -470,12 +476,9 @@ bool FormsMatchForMerge(const PasswordForm& form_a, const PasswordForm& form_b, FormMatchStrictness strictness) { - // We never merge blacklist entries between our store and the Keychain, - // and federated logins should not be stored in the Keychain at all. - if (form_a.blacklisted_by_user || form_b.blacklisted_by_user || - !form_a.federation_url.is_empty() || !form_b.federation_url.is_empty()) { + if (IsLoginDatabaseOnlyForm(form_a) || IsLoginDatabaseOnlyForm(form_b)) return false; - } + bool equal_realm = form_a.signon_realm == form_b.signon_realm; if (strictness == FUZZY_FORM_MATCH) { equal_realm |= form_a.is_public_suffix_match; @@ -493,7 +496,7 @@ ScopedVector<autofill::PasswordForm> remaining; MoveAllFormsOut( forms, [&remaining, extracted](scoped_ptr<autofill::PasswordForm> form) { - if (form->blacklisted_by_user || !form->federation_url.is_empty()) + if (IsLoginDatabaseOnlyForm(*form)) extracted->push_back(form.Pass()); else remaining.push_back(form.Pass()); @@ -721,7 +724,7 @@ bool MacKeychainPasswordFormAdapter::HasPasswordsMergeableWithForm( const PasswordForm& query_form) { - if (!query_form.federation_url.is_empty()) + if (IsLoginDatabaseOnlyForm(query_form)) return false; std::string username = base::UTF16ToUTF8(query_form.username_value); std::vector<SecKeychainItemRef> matches = @@ -768,7 +771,7 @@ bool MacKeychainPasswordFormAdapter::AddPassword(const PasswordForm& form) { // We should never be trying to store a blacklist in the keychain. - DCHECK(!form.blacklisted_by_user); + DCHECK(!IsLoginDatabaseOnlyForm(form)); std::string server; std::string security_domain; @@ -848,9 +851,8 @@ // We don't store blacklist entries in the keychain, so the answer to "what // Keychain item goes with this form" is always "nothing" for blacklists. // Same goes for federated logins. - if (form.blacklisted_by_user || !form.federation_url.is_empty()) { + if (IsLoginDatabaseOnlyForm(form)) return NULL; - } std::string path; // Path doesn't make sense for Android app credentials. @@ -916,6 +918,9 @@ case PasswordForm::SCHEME_BASIC: return kSecAuthenticationTypeHTTPBasic; case PasswordForm::SCHEME_DIGEST: return kSecAuthenticationTypeHTTPDigest; case PasswordForm::SCHEME_OTHER: return kSecAuthenticationTypeDefault; + case PasswordForm::SCHEME_USERNAME_ONLY: + NOTREACHED(); + break; } NOTREACHED(); return kSecAuthenticationTypeDefault; @@ -1261,7 +1266,7 @@ } bool PasswordStoreMac::AddToKeychainIfNecessary(const PasswordForm& form) { - if (form.blacklisted_by_user || !form.federation_url.is_empty()) + if (IsLoginDatabaseOnlyForm(form)) return true; MacKeychainPasswordFormAdapter keychainAdapter(keychain_.get()); return keychainAdapter.AddPassword(form);
diff --git a/chrome/browser/password_manager/save_password_infobar_delegate.cc b/chrome/browser/password_manager/save_password_infobar_delegate.cc index 3841aed..afa1a7c 100644 --- a/chrome/browser/password_manager/save_password_infobar_delegate.cc +++ b/chrome/browser/password_manager/save_password_infobar_delegate.cc
@@ -22,10 +22,7 @@ namespace { int GetCancelButtonText(password_manager::CredentialSourceType source_type) { - return source_type == - password_manager::CredentialSourceType::CREDENTIAL_SOURCE_API - ? IDS_PASSWORD_MANAGER_SAVE_PASSWORD_SMART_LOCK_NO_THANKS_BUTTON - : IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON; + return IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON; } } // namespace @@ -140,12 +137,7 @@ bool SavePasswordInfoBarDelegate::Cancel() { DCHECK(form_to_save_.get()); - if (source_type_ == - password_manager::CredentialSourceType::CREDENTIAL_SOURCE_API) { - InfoBarDismissed(); - } else { - form_to_save_->PermanentlyBlacklist(); - infobar_response_ = password_manager::metrics_util::NEVER_REMEMBER_PASSWORD; - } + form_to_save_->PermanentlyBlacklist(); + infobar_response_ = password_manager::metrics_util::NEVER_REMEMBER_PASSWORD; return true; }
diff --git a/chrome/browser/password_manager/save_password_infobar_delegate_unittest.cc b/chrome/browser/password_manager/save_password_infobar_delegate_unittest.cc index e316ab7..4b9aaa6 100644 --- a/chrome/browser/password_manager/save_password_infobar_delegate_unittest.cc +++ b/chrome/browser/password_manager/save_password_infobar_delegate_unittest.cc
@@ -128,8 +128,7 @@ TEST_F(SavePasswordInfoBarDelegateTest, CancelTestCredentialSourceAPI) { scoped_ptr<MockPasswordFormManager> password_form_manager( CreateMockFormManager()); - EXPECT_CALL(*password_form_manager.get(), PermanentlyBlacklist()) - .Times(testing::Exactly(0)); + EXPECT_CALL(*password_form_manager.get(), PermanentlyBlacklist()); scoped_ptr<ConfirmInfoBarDelegate> infobar(CreateDelegate( password_form_manager.Pass(), password_manager::CredentialSourceType::CREDENTIAL_SOURCE_API, false)); @@ -140,8 +139,7 @@ CancelTestCredentialSourcePasswordManager) { scoped_ptr<MockPasswordFormManager> password_form_manager( CreateMockFormManager()); - EXPECT_CALL(*password_form_manager.get(), PermanentlyBlacklist()) - .Times(testing::Exactly(1)); + EXPECT_CALL(*password_form_manager.get(), PermanentlyBlacklist()); scoped_ptr<ConfirmInfoBarDelegate> infobar(CreateDelegate( password_form_manager.Pass(), password_manager::CredentialSourceType:: CREDENTIAL_SOURCE_PASSWORD_MANAGER,
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index cf6bdd76..ea31298 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -241,9 +241,10 @@ {66, -1, IDC_CONTENT_CONTEXT_LOAD_ORIGINAL_IMAGE}, {67, -1, IDC_CONTENT_CONTEXT_FORCESAVEPASSWORD}, {68, -1, IDC_ROUTE_MEDIA}, + {69, -1, IDC_CONTENT_CONTEXT_COPYLINKTEXT}, // Add new items here and use |enum_id| from the next line. // Also, add new items to RenderViewContextMenuItem enum in histograms.xml. - {69, -1, 0}, // Must be the last. Increment |enum_id| when new IDC + {70, -1, 0}, // Must be the last. Increment |enum_id| when new IDC // was added. }; @@ -361,6 +362,11 @@ scw.WriteURL(text); } +void WriteTextToClipboard(const base::string16& text) { + ui::ScopedClipboardWriter scw(ui::CLIPBOARD_TYPE_COPY_PASTE); + scw.WriteText(text); +} + bool g_custom_id_ranges_initialized = false; } // namespace @@ -812,6 +818,11 @@ params_.link_url.SchemeIs(url::kMailToScheme) ? IDS_CONTENT_CONTEXT_COPYEMAILADDRESS : IDS_CONTENT_CONTEXT_COPYLINKLOCATION); + + if (!params_.link_text.empty()) { + menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_COPYLINKTEXT, + IDS_CONTENT_CONTEXT_COPYLINKTEXT); + } } void RenderViewContextMenu::AppendImageItems() { @@ -1212,6 +1223,9 @@ case IDC_CONTENT_CONTEXT_COPYLINKLOCATION: return params_.unfiltered_link_url.is_valid(); + case IDC_CONTENT_CONTEXT_COPYLINKTEXT: + return !params_.link_text.empty(); + case IDC_CONTENT_CONTEXT_SAVELINKAS: { PrefService* local_state = g_browser_process->local_state(); DCHECK(local_state); @@ -1552,6 +1566,10 @@ WriteURLToClipboard(params_.unfiltered_link_url); break; + case IDC_CONTENT_CONTEXT_COPYLINKTEXT: + WriteTextToClipboard(params_.link_text); + break; + case IDC_CONTENT_CONTEXT_COPYIMAGELOCATION: case IDC_CONTENT_CONTEXT_COPYAVLOCATION: WriteURLToClipboard(params_.src_url);
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 ee0d4e58..6ab5ea6a 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
@@ -51,15 +51,33 @@ public: ContextMenuBrowserTest() {} - TestRenderViewContextMenu* CreateContextMenu( + protected: + scoped_ptr<TestRenderViewContextMenu> CreateContextMenuMediaTypeNone( const GURL& unfiltered_url, const GURL& url, + const base::string16& link_text) { + return CreateContextMenu(unfiltered_url, url, link_text, + blink::WebContextMenuData::MediaTypeNone); + } + + scoped_ptr<TestRenderViewContextMenu> CreateContextMenuMediaTypeImage( + const GURL& url) { + return CreateContextMenu(GURL(), url, base::string16(), + blink::WebContextMenuData::MediaTypeImage); + } + + private: + scoped_ptr<TestRenderViewContextMenu> CreateContextMenu( + const GURL& unfiltered_url, + const GURL& url, + const base::string16& link_text, blink::WebContextMenuData::MediaType media_type) { content::ContextMenuParams params; params.media_type = media_type; params.unfiltered_link_url = unfiltered_url; params.link_url = url; params.src_url = url; + params.link_text = link_text; WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); params.page_url = web_contents->GetController().GetActiveEntry()->GetURL(); @@ -68,39 +86,34 @@ params.writing_direction_left_to_right = 0; params.writing_direction_right_to_left = 0; #endif // OS_MACOSX - TestRenderViewContextMenu* menu = new TestRenderViewContextMenu( - browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), - params); + scoped_ptr<TestRenderViewContextMenu> menu( + new TestRenderViewContextMenu(web_contents->GetMainFrame(), params)); menu->Init(); return menu; } - - TestRenderViewContextMenu* CreateContextMenuMediaTypeNone( - const GURL& unfiltered_url, - const GURL& url) { - return CreateContextMenu(unfiltered_url, url, - blink::WebContextMenuData::MediaTypeNone); - } }; IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenEntryPresentForNormalURLs) { - scoped_ptr<TestRenderViewContextMenu> menu(CreateContextMenuMediaTypeNone( - GURL("http://www.google.com/"), GURL("http://www.google.com/"))); + scoped_ptr<TestRenderViewContextMenu> menu = CreateContextMenuMediaTypeNone( + GURL("http://www.google.com/"), GURL("http://www.google.com/"), + base::ASCIIToUTF16("Google")); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKTEXT)); } IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenEntryAbsentForFilteredURLs) { - scoped_ptr<TestRenderViewContextMenu> menu( - CreateContextMenuMediaTypeNone(GURL("chrome://history"), GURL())); + scoped_ptr<TestRenderViewContextMenu> menu = CreateContextMenuMediaTypeNone( + GURL("chrome://history"), GURL(), base::ASCIIToUTF16("History")); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWTAB)); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENLINKNEWWINDOW)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); + ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKTEXT)); } IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, @@ -319,9 +332,8 @@ command_line->AppendSwitch( data_reduction_proxy::switches::kEnableDataReductionProxy); - scoped_ptr<TestRenderViewContextMenu> menu( - CreateContextMenu(GURL(), GURL("http://url.com/image.png"), - blink::WebContextMenuData::MediaTypeImage)); + scoped_ptr<TestRenderViewContextMenu> menu = + CreateContextMenuMediaTypeImage(GURL("http://url.com/image.png")); ASSERT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB)); ASSERT_TRUE(menu->IsItemPresent( @@ -334,9 +346,8 @@ command_line->AppendSwitch( data_reduction_proxy::switches::kEnableDataReductionProxy); - scoped_ptr<TestRenderViewContextMenu> menu( - CreateContextMenu(GURL(), GURL("https://url.com/image.png"), - blink::WebContextMenuData::MediaTypeImage)); + scoped_ptr<TestRenderViewContextMenu> menu = + CreateContextMenuMediaTypeImage(GURL("https://url.com/image.png")); ASSERT_FALSE( menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPEN_ORIGINAL_IMAGE_NEW_TAB)); @@ -344,9 +355,8 @@ } IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, OpenImageInNewTab) { - scoped_ptr<TestRenderViewContextMenu> menu( - CreateContextMenu(GURL(), GURL("http://url.com/image.png"), - blink::WebContextMenuData::MediaTypeImage)); + scoped_ptr<TestRenderViewContextMenu> menu = + CreateContextMenuMediaTypeImage(GURL("http://url.com/image.png")); ASSERT_FALSE( menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPEN_ORIGINAL_IMAGE_NEW_TAB)); ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB));
diff --git a/chrome/browser/resources/feedback/js/event_handler.js b/chrome/browser/resources/feedback/js/event_handler.js index 1e9d4aa..315be255 100644 --- a/chrome/browser/resources/feedback/js/event_handler.js +++ b/chrome/browser/resources/feedback/js/event_handler.js
@@ -70,6 +70,9 @@ 'B206D8716769728278D2D300349C6CB7D7DE2EF9', // http://crbug.com/510270 'EFCF5358672FEE04789FD2EC3638A67ADEDB6C8C', // http://crbug.com/514696 'FAD85BC419FE00995D196312F53448265EFA86F1', // http://crbug.com/516527 + 'F33B037DEDA65F226B7409C2ADB0CF3F8565AB03', // http://crbug.com/541769 + '969C788BCBC82FBBE04A17360CA165C23A419257', // http://crbug.com/541769 + '3BC3740BFC58F06088B300274B4CFBEA20136342', // http://crbug.com/541769 ];
diff --git a/chrome/browser/site_details.cc b/chrome/browser/site_details.cc index 54970b6b..bf9d947 100644 --- a/chrome/browser/site_details.cc +++ b/chrome/browser/site_details.cc
@@ -7,7 +7,12 @@ #include "base/metrics/histogram.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" + +#if defined(ENABLE_EXTENSIONS) +#include "extensions/browser/extension_registry.h" #include "extensions/common/constants.h" +#include "extensions/common/extension.h" +#endif using content::BrowserThread; using content::RenderProcessHost; @@ -16,7 +21,9 @@ namespace { -bool ShouldIsolate(IsolationScenarioType policy, const GURL& site) { +bool ShouldIsolate(content::BrowserContext* browser_context, + IsolationScenarioType policy, + const GURL& site) { switch (policy) { case ISOLATE_ALL_SITES: return true; @@ -26,8 +33,19 @@ // the New Tab Page gets counted as two processes under this policy, and // extensions are isolated as well. return !site.SchemeIs(url::kHttpScheme); - case ISOLATE_EXTENSIONS: - return site.SchemeIs(extensions::kExtensionScheme); + case ISOLATE_EXTENSIONS: { +#if !defined(ENABLE_EXTENSIONS) + return false; +#else + if (!site.SchemeIs(extensions::kExtensionScheme)) + return false; + extensions::ExtensionRegistry* registry = + extensions::ExtensionRegistry::Get(browser_context); + const extensions::Extension* extension = + registry->enabled_extensions().GetExtensionOrAppByURL(site); + return extension && !extension->is_hosted_app(); +#endif + } } NOTREACHED(); return true; @@ -41,7 +59,10 @@ void IsolationScenario::CollectSiteInfoForScenario(SiteInstance* primary, const GURL& site) { - const GURL& isolated = ShouldIsolate(policy, site) ? site : GURL("http://"); + const GURL& isolated = + ShouldIsolate(primary->GetBrowserContext(), policy, site) + ? site + : GURL("http://"); sites.insert(isolated); browsing_instance_site_map[primary->GetId()].insert(isolated); }
diff --git a/chrome/browser/site_details_browsertest.cc b/chrome/browser/site_details_browsertest.cc index bd3420fc..eb8d4703 100644 --- a/chrome/browser/site_details_browsertest.cc +++ b/chrome/browser/site_details_browsertest.cc
@@ -691,8 +691,7 @@ EXPECT_THAT(GetRenderProcessCount(), EqualsIfExtensionsIsolated(3)); } -// TODO(nick): This test demonstrates that --isolate-extensions currently -// isolates hosted apps too. It shouldn't. http://crbug.com/535073 +// Verifies that --isolate-extensions doesn't isolate hosted apps. IN_PROC_BROWSER_TEST_F(SiteDetailsBrowserTest, IsolateExtensionsHostedApps) { GURL app_with_web_iframe_url = embedded_test_server()->GetURL( "app.org", "/cross_site_iframe_factory.html?app.org(b.com)"); @@ -716,6 +715,16 @@ "SiteIsolation.IsolateExtensionsProcessCountNoLimit"), ElementsAre(Bucket(1, 1))); EXPECT_THAT(GetRenderProcessCount(), EqualsIfExtensionsIsolated(1)); + EXPECT_THAT(details->uma()->GetAllSamples( + "SiteIsolation.IsolateAllSitesProcessCountEstimate"), + ElementsAre(Bucket(2, 1))); + EXPECT_THAT(details->uma()->GetAllSamples( + "SiteIsolation.IsolateAllSitesProcessCountLowerBound"), + ElementsAre(Bucket(2, 1))); + EXPECT_THAT(details->uma()->GetAllSamples( + "SiteIsolation.IsolateAllSitesProcessCountNoLimit"), + ElementsAre(Bucket(2, 1))); + EXPECT_THAT(GetRenderProcessCount(), EqualsIfSitePerProcess(2)); ui_test_utils::NavigateToURL(browser(), app_in_web_iframe_url); details = new TestMemoryDetails(); @@ -733,11 +742,22 @@ "SiteIsolation.IsolateExtensionsProcessCountNoLimit"), ElementsAre(Bucket(1, 1))); EXPECT_THAT(GetRenderProcessCount(), EqualsIfExtensionsIsolated(1)); + EXPECT_THAT(details->uma()->GetAllSamples( + "SiteIsolation.IsolateAllSitesProcessCountEstimate"), + ElementsAre(Bucket(2, 1))); + EXPECT_THAT(details->uma()->GetAllSamples( + "SiteIsolation.IsolateAllSitesProcessCountLowerBound"), + ElementsAre(Bucket(2, 1))); + EXPECT_THAT(details->uma()->GetAllSamples( + "SiteIsolation.IsolateAllSitesProcessCountNoLimit"), + ElementsAre(Bucket(2, 1))); + EXPECT_THAT(GetRenderProcessCount(), EqualsIfSitePerProcess(2)); // Now install app.org as a hosted app. CreateHostedApp("App", GURL("http://app.org")); - // Reload the same two pages. + // Reload the same two pages, and verify that the hosted app still is not + // isolated by --isolate-extensions, but is isolated by --site-per-process. ui_test_utils::NavigateToURL(browser(), app_with_web_iframe_url); details = new TestMemoryDetails(); details->StartFetchAndWait(); @@ -746,14 +766,24 @@ ElementsAre(Bucket(1, 1))); EXPECT_THAT(details->uma()->GetAllSamples( "SiteIsolation.IsolateExtensionsProcessCountEstimate"), - ElementsAre(Bucket(2, 1))); + ElementsAre(Bucket(1, 1))); EXPECT_THAT(details->uma()->GetAllSamples( "SiteIsolation.IsolateExtensionsProcessCountLowerBound"), - ElementsAre(Bucket(2, 1))); + ElementsAre(Bucket(1, 1))); EXPECT_THAT(details->uma()->GetAllSamples( "SiteIsolation.IsolateExtensionsProcessCountNoLimit"), + ElementsAre(Bucket(1, 1))); + EXPECT_THAT(GetRenderProcessCount(), EqualsIfExtensionsIsolated(1)); + EXPECT_THAT(details->uma()->GetAllSamples( + "SiteIsolation.IsolateAllSitesProcessCountEstimate"), ElementsAre(Bucket(2, 1))); - EXPECT_THAT(GetRenderProcessCount(), EqualsIfExtensionsIsolated(2)); + EXPECT_THAT(details->uma()->GetAllSamples( + "SiteIsolation.IsolateAllSitesProcessCountLowerBound"), + ElementsAre(Bucket(2, 1))); + EXPECT_THAT(details->uma()->GetAllSamples( + "SiteIsolation.IsolateAllSitesProcessCountNoLimit"), + ElementsAre(Bucket(2, 1))); + EXPECT_THAT(GetRenderProcessCount(), EqualsIfSitePerProcess(2)); ui_test_utils::NavigateToURL(browser(), app_in_web_iframe_url); details = new TestMemoryDetails(); @@ -763,13 +793,22 @@ ElementsAre(Bucket(1, 1))); EXPECT_THAT(details->uma()->GetAllSamples( "SiteIsolation.IsolateExtensionsProcessCountEstimate"), - ElementsAre(Bucket(2, 1))); + ElementsAre(Bucket(1, 1))); EXPECT_THAT(details->uma()->GetAllSamples( "SiteIsolation.IsolateExtensionsProcessCountLowerBound"), - ElementsAre(Bucket(2, 1))); + ElementsAre(Bucket(1, 1))); EXPECT_THAT(details->uma()->GetAllSamples( "SiteIsolation.IsolateExtensionsProcessCountNoLimit"), + ElementsAre(Bucket(1, 1))); + EXPECT_THAT(GetRenderProcessCount(), EqualsIfExtensionsIsolated(1)); + EXPECT_THAT(details->uma()->GetAllSamples( + "SiteIsolation.IsolateAllSitesProcessCountEstimate"), ElementsAre(Bucket(2, 1))); - - EXPECT_THAT(GetRenderProcessCount(), EqualsIfExtensionsIsolated(2)); + EXPECT_THAT(details->uma()->GetAllSamples( + "SiteIsolation.IsolateAllSitesProcessCountLowerBound"), + ElementsAre(Bucket(2, 1))); + EXPECT_THAT(details->uma()->GetAllSamples( + "SiteIsolation.IsolateAllSitesProcessCountNoLimit"), + ElementsAre(Bucket(2, 1))); + EXPECT_THAT(GetRenderProcessCount(), EqualsIfSitePerProcess(2)); }
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc index 3012a0f..e5fff4a8 100644 --- a/chrome/browser/themes/theme_service.cc +++ b/chrome/browser/themes/theme_service.cc
@@ -80,11 +80,6 @@ // ExtensionService::GarbageCollectExtensions() does something similar. const int kRemoveUnusedThemesStartupDelay = 30; -// The filename to be used for a cached theme created while material design is -// enabled. -const base::FilePath::CharType kThemePackMaterialDesignFilename[] = - FILE_PATH_LITERAL("Cached Theme Material Design.pak"); - SkColor IncreaseLightness(SkColor color, double percent) { color_utils::HSL result; color_utils::SkColorToHSL(color, &result); @@ -554,7 +549,7 @@ base::FilePath path = prefs->GetFilePath(prefs::kCurrentThemePackFilename); if (path != base::FilePath()) { path = path.Append(ui::MaterialDesignController::IsModeMaterial() - ? kThemePackMaterialDesignFilename + ? chrome::kThemePackMaterialDesignFilename : chrome::kThemePackFilename); SwapThemeSupplier(BrowserThemePack::BuildFromDataPack(path, current_id)); loaded_pack = theme_supplier_.get() != nullptr; @@ -675,7 +670,7 @@ // Write the packed file to disk. base::FilePath pack_path = extension->path().Append(ui::MaterialDesignController::IsModeMaterial() - ? kThemePackMaterialDesignFilename + ? chrome::kThemePackMaterialDesignFilename : chrome::kThemePackFilename); service->GetFileTaskRunner()->PostTask( FROM_HERE,
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 38628cb..140d7163 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -129,7 +129,7 @@ deps += [ "//net" ] } - if (!is_android && !is_ios) { + if ((!is_android || use_aura) && !is_ios) { sources += rebase_path(gypi_values.chrome_browser_ui_non_mobile_sources, ".", "//chrome") @@ -144,6 +144,10 @@ "//device/bluetooth", "//third_party/libusb", ] + + if (is_android) { + deps -= [ "//third_party/libusb" ] + } } if (enable_basic_printing || enable_print_preview) { @@ -298,17 +302,21 @@ deps += [ "//chrome/browser:jni_headers", "//crypto:platform", - "//components/web_contents_delegate_android", ] - deps -= [ - "//chrome/browser/ui/views", - "//ui/events", - ] - sources += rebase_path(gypi_values.chrome_browser_ui_android_sources, - ".", - "//chrome") defines += [ "CHROME_BUILD_ID=" + android_chrome_build_id ] + + if (!use_aura) { + sources += + rebase_path(gypi_values.chrome_browser_ui_android_non_aura_sources, + ".", + "//chrome") + deps += [ "//components/web_contents_delegate_android" ] + deps -= [ + "//chrome/browser/ui/views", + "//ui/events", + ] + } } if (is_mac) { @@ -429,7 +437,7 @@ rebase_path(gypi_values.chrome_browser_ui_autofill_dialog_sources, ".", "//chrome") - if (!is_android && !is_ios) { + if ((!is_android || use_aura) && !is_ios) { sources += rebase_path( gypi_values.chrome_browser_ui_autofill_dialog_non_mobile_sources, ".",
diff --git a/chrome/browser/ui/ash/chrome_keyboard_ui.cc b/chrome/browser/ui/ash/chrome_keyboard_ui.cc index 24f0fe3..7af78fd 100644 --- a/chrome/browser/ui/ash/chrome_keyboard_ui.cc +++ b/chrome/browser/ui/ash/chrome_keyboard_ui.cc
@@ -4,7 +4,9 @@ #include "chrome/browser/ui/ash/chrome_keyboard_ui.h" +#include "ash/root_window_controller.h" #include "ash/shell.h" +#include "ash/shell_window_ids.h" #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" #include "chrome/browser/media/media_capture_devices_dispatcher.h" #include "content/public/browser/host_zoom_map.h" @@ -176,6 +178,24 @@ KeyboardUIContent::ShowKeyboardContainer(container); } +bool ChromeKeyboardUI::ShouldWindowOverscroll(aura::Window* window) const { + aura::Window* root_window = window->GetRootWindow(); + if (!root_window) + return true; + + if (root_window != GetKeyboardRootWindow()) + return false; + + ash::RootWindowController* root_window_controller = + ash::GetRootWindowController(root_window); + // Shell ime window container contains virtual keyboard windows and IME + // windows(IME windows are created by chrome.app.window.create api). They + // should never be overscrolled. + return !root_window_controller + ->GetContainer(ash::kShellWindowId_ImeWindowParentContainer) + ->Contains(window); +} + void ChromeKeyboardUI::SetUpdateInputType(ui::TextInputType type) { // TODO(bshe): Need to check the affected window's profile once multi-profile // is supported.
diff --git a/chrome/browser/ui/ash/chrome_keyboard_ui.h b/chrome/browser/ui/ash/chrome_keyboard_ui.h index d241324..a005fd8 100644 --- a/chrome/browser/ui/ash/chrome_keyboard_ui.h +++ b/chrome/browser/ui/ash/chrome_keyboard_ui.h
@@ -37,6 +37,9 @@ explicit ChromeKeyboardUI(content::BrowserContext* context); ~ChromeKeyboardUI() override; + // keyboard::KeyboardUIContent overrides + bool ShouldWindowOverscroll(aura::Window* window) const override; + private: // keyboard::KeyboardControllerProxy overrides ui::InputMethod* GetInputMethod() override;
diff --git a/chrome/browser/ui/ash/keyboard_controller_browsertest.cc b/chrome/browser/ui/ash/keyboard_controller_browsertest.cc index 8635c411..b2f0afc 100644 --- a/chrome/browser/ui/ash/keyboard_controller_browsertest.cc +++ b/chrome/browser/ui/ash/keyboard_controller_browsertest.cc
@@ -4,8 +4,15 @@ #include "ash/shell.h" #include "base/command_line.h" +#include "chrome/browser/apps/app_browsertest_util.h" +#include "chrome/browser/profiles/profile_manager.h" #include "chrome/test/base/in_process_browser_test.h" +#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" +#include "extensions/browser/app_window/app_window.h" +#include "extensions/common/extension.h" +#include "extensions/common/extension_builder.h" +#include "extensions/common/value_builder.h" #include "ui/base/ime/dummy_text_input_client.h" #include "ui/base/ime/input_method.h" #include "ui/base/ime/input_method_factory.h" @@ -130,3 +137,75 @@ EXPECT_EQ(screen_bounds.height(), keyboard_bounds.height() + keyboard_bounds.y()); } + +class VirtualKeyboardAppWindowTest : public extensions::PlatformAppBrowserTest { + public: + VirtualKeyboardAppWindowTest() {} + ~VirtualKeyboardAppWindowTest() override {} + + // Ensure that the virtual keyboard is enabled. + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch(keyboard::switches::kEnableVirtualKeyboard); + } + + private: + DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardAppWindowTest); +}; + +// Tests that ime window won't overscroll. See crbug.com/529880. +IN_PROC_BROWSER_TEST_F(VirtualKeyboardAppWindowTest, + DisableOverscrollForImeWindow) { + scoped_refptr<extensions::Extension> extension = + extensions::ExtensionBuilder() + .SetManifest(extensions::DictionaryBuilder() + .Set("name", "test extension") + .Set("version", "1") + .Set("manifest_version", 2)) + .Build(); + + extensions::AppWindow::CreateParams non_ime_params; + non_ime_params.frame = extensions::AppWindow::FRAME_NONE; + extensions::AppWindow* non_ime_app_window = + CreateAppWindowFromParams(extension.get(), non_ime_params); + int non_ime_window_visible_height = non_ime_app_window->web_contents() + ->GetRenderWidgetHostView() + ->GetVisibleViewportSize() + .height(); + + extensions::AppWindow::CreateParams ime_params; + ime_params.frame = extensions::AppWindow::FRAME_NONE; + ime_params.is_ime_window = true; + extensions::AppWindow* ime_app_window = + CreateAppWindowFromParams(extension.get(), ime_params); + int ime_window_visible_height = ime_app_window->web_contents() + ->GetRenderWidgetHostView() + ->GetVisibleViewportSize() + .height(); + + ASSERT_EQ(non_ime_window_visible_height, ime_window_visible_height); + ASSERT_TRUE(ime_window_visible_height > 0); + + int screen_height = ash::Shell::GetPrimaryRootWindow()->bounds().height(); + gfx::Rect test_bounds(0, 0, 0, screen_height - ime_window_visible_height + 1); + keyboard::KeyboardController* controller = + keyboard::KeyboardController::GetInstance(); + controller->ShowKeyboard(true); + controller->ui()->GetKeyboardWindow()->SetBounds(test_bounds); + gfx::Rect keyboard_bounds = controller->GetContainerWindow()->bounds(); + // Starts overscroll. + controller->NotifyKeyboardBoundsChanging(keyboard_bounds); + + // Non ime window should have smaller visible view port due to overlap with + // virtual keyboard. + EXPECT_LT(non_ime_app_window->web_contents() + ->GetRenderWidgetHostView() + ->GetVisibleViewportSize() + .height(), + non_ime_window_visible_height); + // Ime window should have not be affected by virtual keyboard. + EXPECT_EQ(ime_app_window->web_contents() + ->GetRenderWidgetHostView() + ->GetVisibleViewportSize() + .height(), + ime_window_visible_height); +}
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 4df5abb..f62796d 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -186,6 +186,8 @@ case NEW_FOREGROUND_TAB: case NEW_BACKGROUND_TAB: { WebContents* new_tab = current_tab->Clone(); + if (disposition == NEW_BACKGROUND_TAB) + new_tab->WasHidden(); browser->tab_strip_model()->AddWebContents( new_tab, -1, ui::PAGE_TRANSITION_LINK, (disposition == NEW_FOREGROUND_TAB) ?
diff --git a/chrome/browser/ui/views/BUILD.gn b/chrome/browser/ui/views/BUILD.gn index c012e65..8831767 100644 --- a/chrome/browser/ui/views/BUILD.gn +++ b/chrome/browser/ui/views/BUILD.gn
@@ -4,7 +4,7 @@ import("//build/config/ui.gni") -assert(!is_android) +assert(toolkit_views) component("views") { output_name = "browser_ui_views"
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc index c91b0f1..8b1a2b36 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc
@@ -128,10 +128,16 @@ listener.WaitUntilSatisfied(); } +// Disabled on CrOS. See crbug.com/543194. +#if defined(OS_CHROMEOS) +#define MAYBE_DoubleClickToolbarActionToClose DISABLED_DoubleClickToolbarActionToClose +#else +#define MAYBE_DoubleClickToolbarActionToClose DoubleClickToolbarActionToClose +#endif // Tests that clicking on the toolbar action a second time when the action is // already open results in closing the popup, and doesn't re-open it. IN_PROC_BROWSER_TEST_F(ToolbarActionViewInteractiveUITest, - DoubleClickToolbarActionToClose) { + MAYBE_DoubleClickToolbarActionToClose) { ASSERT_TRUE(LoadExtension( test_data_dir_.AppendASCII("ui").AppendASCII("browser_action_popup"))); base::RunLoop().RunUntilIdle(); // Ensure the extension is fully loaded.
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 57c4a82..ca50abb 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi
@@ -13,74 +13,10 @@ 'browser/ui/accelerator_utils.h', 'browser/ui/android/android_about_app_info.cc', 'browser/ui/android/android_about_app_info.h', - 'browser/ui/android/autofill/autofill_dialog_controller_android.cc', - 'browser/ui/android/autofill/autofill_dialog_controller_android.h', - 'browser/ui/android/autofill/autofill_dialog_result.cc', - 'browser/ui/android/autofill/autofill_dialog_result.h', - 'browser/ui/android/autofill/autofill_keyboard_accessory_view.cc', - 'browser/ui/android/autofill/autofill_keyboard_accessory_view.h', - 'browser/ui/android/autofill/autofill_logger_android.cc', - 'browser/ui/android/autofill/autofill_logger_android.h', - 'browser/ui/android/autofill/autofill_popup_view_android.cc', - 'browser/ui/android/autofill/autofill_popup_view_android.h', - 'browser/ui/android/autofill/card_unmask_prompt_view_android.cc', - 'browser/ui/android/autofill/card_unmask_prompt_view_android.h', - 'browser/ui/android/autofill/password_generation_popup_view_android.cc', - 'browser/ui/android/autofill/password_generation_popup_view_android.h', - 'browser/ui/android/bluetooth_chooser_android.cc', - 'browser/ui/android/bluetooth_chooser_android.h', - 'browser/ui/android/certificate_viewer_android.cc', - 'browser/ui/android/certificate_viewer_android.h', - 'browser/ui/android/chrome_http_auth_handler.cc', - 'browser/ui/android/chrome_http_auth_handler.h', - 'browser/ui/android/color_chooser_dialog_android.cc', - 'browser/ui/android/connection_info_popup_android.cc', - 'browser/ui/android/connection_info_popup_android.h', - 'browser/ui/android/content_settings/popup_blocked_infobar_delegate.cc', - 'browser/ui/android/content_settings/popup_blocked_infobar_delegate.h', - 'browser/ui/android/context_menu_helper.cc', - 'browser/ui/android/context_menu_helper.h', 'browser/ui/android/external_protocol_dialog_android.cc', - 'browser/ui/android/infobars/app_banner_infobar_android.cc', - 'browser/ui/android/infobars/app_banner_infobar_android.h', - 'browser/ui/android/infobars/confirm_infobar.cc', - 'browser/ui/android/infobars/confirm_infobar.h', - 'browser/ui/android/infobars/data_reduction_proxy_infobar.cc', - 'browser/ui/android/infobars/data_reduction_proxy_infobar.h', - 'browser/ui/android/infobars/download_overwrite_infobar.cc', - 'browser/ui/android/infobars/download_overwrite_infobar.h', - 'browser/ui/android/infobars/infobar_android.cc', - 'browser/ui/android/infobars/infobar_android.h', - 'browser/ui/android/infobars/infobar_container_android.cc', - 'browser/ui/android/infobars/infobar_container_android.h', - 'browser/ui/android/infobars/save_password_infobar.cc', - 'browser/ui/android/infobars/save_password_infobar.h', - 'browser/ui/android/infobars/translate_infobar.cc', - 'browser/ui/android/infobars/translate_infobar.h', - 'browser/ui/android/javascript_app_modal_dialog_android.cc', - 'browser/ui/android/login_prompt_android.cc', - 'browser/ui/android/omnibox/omnibox_url_emphasizer.cc', - 'browser/ui/android/omnibox/omnibox_url_emphasizer.h', - 'browser/ui/android/omnibox/omnibox_view_util.cc', - 'browser/ui/android/omnibox/omnibox_view_util.h', - 'browser/ui/android/simple_message_box_android.cc', - 'browser/ui/android/ssl_client_certificate_request.cc', - 'browser/ui/android/ssl_client_certificate_request.h', 'browser/ui/android/status_tray_android.cc', - 'browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.cc', - 'browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.h', - 'browser/ui/android/tab_model/single_tab_model.cc', - 'browser/ui/android/tab_model/single_tab_model.h', - 'browser/ui/android/tab_model/tab_model.cc', - 'browser/ui/android/tab_model/tab_model.h', - 'browser/ui/android/tab_model/tab_model_jni_bridge.cc', - 'browser/ui/android/tab_model/tab_model_jni_bridge.h', 'browser/ui/android/tab_model/tab_model_list.cc', 'browser/ui/android/tab_model/tab_model_list.h', - 'browser/ui/android/website_settings_popup_android.cc', - 'browser/ui/android/website_settings_popup_android.h', - 'browser/ui/android/window_android_helper.cc', - 'browser/ui/android/window_android_helper.h', 'browser/ui/app_list/app_list_util.cc', 'browser/ui/app_list/app_list_util.h', # All other browser/ui/app_list files go in chrome_browser_ui_app_list_sources. @@ -140,7 +76,6 @@ 'browser/ui/browser_mac.h', 'browser/ui/browser_navigator_params.cc', 'browser/ui/browser_navigator_params.h', - 'browser/ui/browser_otr_state_android.cc', 'browser/ui/browser_ui_prefs.cc', 'browser/ui/browser_ui_prefs.h', 'browser/ui/browser_win.cc', @@ -484,13 +419,78 @@ 'browser/ui/zoom/chrome_zoom_level_prefs.cc', 'browser/ui/zoom/chrome_zoom_level_prefs.h', ], - 'chrome_browser_ui_android_sources': [ + 'chrome_browser_ui_android_non_aura_sources': [ + 'browser/ui/android/autofill/autofill_dialog_controller_android.cc', + 'browser/ui/android/autofill/autofill_dialog_controller_android.h', + 'browser/ui/android/autofill/autofill_dialog_result.cc', + 'browser/ui/android/autofill/autofill_dialog_result.h', + 'browser/ui/android/autofill/autofill_keyboard_accessory_view.cc', + 'browser/ui/android/autofill/autofill_keyboard_accessory_view.h', + 'browser/ui/android/autofill/autofill_logger_android.cc', + 'browser/ui/android/autofill/autofill_logger_android.h', + 'browser/ui/android/autofill/autofill_popup_view_android.cc', + 'browser/ui/android/autofill/autofill_popup_view_android.h', + 'browser/ui/android/autofill/card_unmask_prompt_view_android.cc', + 'browser/ui/android/autofill/card_unmask_prompt_view_android.h', 'browser/ui/android/autofill/credit_card_scanner_view_android.cc', 'browser/ui/android/autofill/credit_card_scanner_view_android.h', + 'browser/ui/android/autofill/password_generation_popup_view_android.cc', + 'browser/ui/android/autofill/password_generation_popup_view_android.h', + 'browser/ui/android/bluetooth_chooser_android.cc', + 'browser/ui/android/bluetooth_chooser_android.h', + 'browser/ui/android/certificate_viewer_android.cc', + 'browser/ui/android/certificate_viewer_android.h', + 'browser/ui/android/chrome_http_auth_handler.cc', + 'browser/ui/android/chrome_http_auth_handler.h', + 'browser/ui/android/color_chooser_dialog_android.cc', + 'browser/ui/android/connection_info_popup_android.cc', + 'browser/ui/android/connection_info_popup_android.h', + 'browser/ui/android/content_settings/popup_blocked_infobar_delegate.cc', + 'browser/ui/android/content_settings/popup_blocked_infobar_delegate.h', + 'browser/ui/android/context_menu_helper.cc', + 'browser/ui/android/context_menu_helper.h', + 'browser/ui/android/infobars/app_banner_infobar_android.cc', + 'browser/ui/android/infobars/app_banner_infobar_android.h', + 'browser/ui/android/infobars/confirm_infobar.cc', + 'browser/ui/android/infobars/confirm_infobar.h', + 'browser/ui/android/infobars/data_reduction_proxy_infobar.cc', + 'browser/ui/android/infobars/data_reduction_proxy_infobar.h', + 'browser/ui/android/infobars/download_overwrite_infobar.cc', + 'browser/ui/android/infobars/download_overwrite_infobar.h', 'browser/ui/android/infobars/generated_password_saved_infobar.cc', 'browser/ui/android/infobars/generated_password_saved_infobar.h', + 'browser/ui/android/infobars/infobar_android.cc', + 'browser/ui/android/infobars/infobar_android.h', + 'browser/ui/android/infobars/infobar_container_android.cc', + 'browser/ui/android/infobars/infobar_container_android.h', + 'browser/ui/android/infobars/save_password_infobar.cc', + 'browser/ui/android/infobars/save_password_infobar.h', + 'browser/ui/android/infobars/translate_infobar.cc', + 'browser/ui/android/infobars/translate_infobar.h', + 'browser/ui/android/javascript_app_modal_dialog_android.cc', + 'browser/ui/android/login_prompt_android.cc', + 'browser/ui/android/omnibox/omnibox_url_emphasizer.cc', + 'browser/ui/android/omnibox/omnibox_url_emphasizer.h', + 'browser/ui/android/omnibox/omnibox_view_util.cc', + 'browser/ui/android/omnibox/omnibox_view_util.h', + 'browser/ui/android/simple_message_box_android.cc', 'browser/ui/android/snackbars/auto_signin_snackbar_controller.cc', 'browser/ui/android/snackbars/auto_signin_snackbar_controller.h', + 'browser/ui/android/ssl_client_certificate_request.cc', + 'browser/ui/android/ssl_client_certificate_request.h', + 'browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.cc', + 'browser/ui/android/tab_contents/chrome_web_contents_view_delegate_android.h', + 'browser/ui/android/tab_model/single_tab_model.cc', + 'browser/ui/android/tab_model/single_tab_model.h', + 'browser/ui/android/tab_model/tab_model.cc', + 'browser/ui/android/tab_model/tab_model.h', + 'browser/ui/android/tab_model/tab_model_jni_bridge.cc', + 'browser/ui/android/tab_model/tab_model_jni_bridge.h', + 'browser/ui/android/website_settings_popup_android.cc', + 'browser/ui/android/website_settings_popup_android.h', + 'browser/ui/android/window_android_helper.cc', + 'browser/ui/android/window_android_helper.h', + 'browser/ui/browser_otr_state_android.cc', 'browser/ui/screen_capture_notification_ui_stub.cc', 'browser/ui/webui/popular_sites_internals_message_handler.cc', 'browser/ui/webui/popular_sites_internals_message_handler.h', @@ -3016,7 +3016,7 @@ '../ui/events/events.gyp:events', 'chrome_browser_ui_views.gyp:browser_ui_views', ], - 'sources': [ '<@(chrome_browser_ui_android_sources)' ], + 'sources': [ '<@(chrome_browser_ui_android_non_aura_sources)' ], }], ['OS=="mac"', { 'sources': [ '<@(chrome_browser_ui_mac_sources)' ],
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index d9263ea..52dee95560 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi
@@ -144,6 +144,7 @@ 'browser/net/chrome_network_delegate_unittest.cc', 'browser/net/dns_probe_runner_unittest.cc', 'browser/net/dns_probe_service_unittest.cc', + 'browser/net/file_downloader_unittest.cc', 'browser/net/net_error_tab_helper_unittest.cc', 'browser/net/predictor_unittest.cc', 'browser/net/probe_message_unittest.cc',
diff --git a/chrome/common/chrome_constants.cc b/chrome/common/chrome_constants.cc index 4a1610f..31fcdc8 100644 --- a/chrome/common/chrome_constants.cc +++ b/chrome/common/chrome_constants.cc
@@ -169,6 +169,8 @@ const base::FilePath::CharType kSupervisedUserSettingsFilename[] = FPL("Managed Mode Settings"); const base::FilePath::CharType kThemePackFilename[] = FPL("Cached Theme.pak"); +const base::FilePath::CharType kThemePackMaterialDesignFilename[] = + FPL("Cached Theme Material Design.pak"); const base::FilePath::CharType kWebAppDirname[] = FPL("Web Applications"); #if defined(OS_WIN)
diff --git a/chrome/common/chrome_constants.h b/chrome/common/chrome_constants.h index 8dea2f32..bc13ee09 100644 --- a/chrome/common/chrome_constants.h +++ b/chrome/common/chrome_constants.h
@@ -80,6 +80,7 @@ extern const base::FilePath::CharType kSingletonSocketFilename[]; extern const base::FilePath::CharType kSupervisedUserSettingsFilename[]; extern const base::FilePath::CharType kThemePackFilename[]; +extern const base::FilePath::CharType kThemePackMaterialDesignFilename[]; extern const base::FilePath::CharType kWebAppDirname[]; #if defined(OS_WIN)
diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index c61a523..c0d6265 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc
@@ -628,9 +628,7 @@ #endif } -void ChromeContentClient::AddIsolatedSchemes(std::set<std::string>* schemes) { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kIsolateExtensions)) { - schemes->insert(extensions::kExtensionScheme); - } +bool ChromeContentClient::IsSupplementarySiteIsolationModeEnabled() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kIsolateExtensions); }
diff --git a/chrome/common/chrome_content_client.h b/chrome/common/chrome_content_client.h index 09d8018..9a4db246 100644 --- a/chrome/common/chrome_content_client.h +++ b/chrome/common/chrome_content_client.h
@@ -81,7 +81,7 @@ void AddServiceWorkerSchemes(std::set<std::string>* schemes) override; - void AddIsolatedSchemes(std::set<std::string>* schemes) override; + bool IsSupplementarySiteIsolationModeEnabled() override; }; #endif // CHROME_COMMON_CHROME_CONTENT_CLIENT_H_
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc index 8c5a691..4639049e 100644 --- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -207,6 +207,16 @@ " <INPUT type='text' id='username'/>" " <INPUT type='password' id='password'/>"; +const char kTwoNoUsernameFormsHTML[] = + "<FORM name='form1' action='http://www.bidule.com'>" + " <INPUT type='password' id='password1' name='password'/>" + " <INPUT type='submit' value='Login'/>" + "</FORM>" + "<FORM name='form2' action='http://www.bidule.com'>" + " <INPUT type='password' id='password2' name='password'/>" + " <INPUT type='submit' value='Login'/>" + "</FORM>"; + // Sets the "readonly" attribute of |element| to the value given by |read_only|. void SetElementReadOnly(WebInputElement& element, bool read_only) { element.setAttribute(WebString::fromUTF8("readonly"), @@ -2270,4 +2280,19 @@ ExpectFormSubmittedWithUsernameAndPasswords(kBobUsername, kBobPassword, ""); } +// Tests that we can correctly suggest to autofill two forms without username +// fields. +TEST_F(PasswordAutofillAgentTest, ShowSuggestionForNonUsernameFieldForms) { + LoadHTML(kTwoNoUsernameFormsHTML); + fill_data_.username_field.name.clear(); + fill_data_.username_field.value.clear(); + UpdateOriginForHTML(kTwoNoUsernameFormsHTML); + SimulateOnFillPasswordForm(fill_data_); + + SimulateElementClick("password1"); + CheckSuggestions(std::string(), false); + SimulateElementClick("password2"); + CheckSuggestions(std::string(), false); +} + } // namespace autofill
diff --git a/chrome/renderer/extensions/cast_streaming_native_handler.cc b/chrome/renderer/extensions/cast_streaming_native_handler.cc index 4e10f1e6..b861f826 100644 --- a/chrome/renderer/extensions/cast_streaming_native_handler.cc +++ b/chrome/renderer/extensions/cast_streaming_native_handler.cc
@@ -663,23 +663,23 @@ if (params->codec_name == "OPUS") { config->codec = media::cast::CODEC_AUDIO_OPUS; config->rtp_timebase = 48000; - config->rtp_payload_type = 127; + config->rtp_payload_type = media::cast::kDefaultRtpAudioPayloadType; } else if (params->codec_name == "PCM16") { config->codec = media::cast::CODEC_AUDIO_PCM16; config->rtp_timebase = 48000; - config->rtp_payload_type = 127; + config->rtp_payload_type = media::cast::kDefaultRtpAudioPayloadType; } else if (params->codec_name == "AAC") { config->codec = media::cast::CODEC_AUDIO_AAC; config->rtp_timebase = 48000; - config->rtp_payload_type = 127; + config->rtp_payload_type = media::cast::kDefaultRtpAudioPayloadType; } else if (params->codec_name == "VP8") { config->codec = media::cast::CODEC_VIDEO_VP8; config->rtp_timebase = 90000; - config->rtp_payload_type = 96; + config->rtp_payload_type = media::cast::kDefaultRtpVideoPayloadType; } else if (params->codec_name == "H264") { config->codec = media::cast::CODEC_VIDEO_H264; config->rtp_timebase = 90000; - config->rtp_payload_type = 96; + config->rtp_payload_type = media::cast::kDefaultRtpVideoPayloadType; } if (params->rtp_timebase) { config->rtp_timebase = *params->rtp_timebase;
diff --git a/chrome/renderer/media/cast_rtp_stream.cc b/chrome/renderer/media/cast_rtp_stream.cc index d92d751f..49a48f1 100644 --- a/chrome/renderer/media/cast_rtp_stream.cc +++ b/chrome/renderer/media/cast_rtp_stream.cc
@@ -49,7 +49,7 @@ CastRtpPayloadParams DefaultOpusPayload() { CastRtpPayloadParams payload; - payload.payload_type = 127; + payload.payload_type = media::cast::kDefaultRtpAudioPayloadType; payload.max_latency_ms = media::cast::kDefaultRtpMaxDelayMs; payload.ssrc = 1; payload.feedback_ssrc = 2; @@ -65,13 +65,13 @@ CastRtpPayloadParams DefaultVp8Payload() { CastRtpPayloadParams payload; - payload.payload_type = 96; + payload.payload_type = media::cast::kDefaultRtpVideoPayloadType; payload.max_latency_ms = media::cast::kDefaultRtpMaxDelayMs; payload.ssrc = 11; payload.feedback_ssrc = 12; payload.clock_rate = media::cast::kVideoFrequency; - payload.max_bitrate = 2000; - payload.min_bitrate = 50; + payload.max_bitrate = media::cast::kDefaultMaxVideoBitRate; + payload.min_bitrate = media::cast::kDefaultMinVideoBitRate; payload.channels = 1; payload.max_frame_rate = media::cast::kDefaultMaxFrameRate; payload.codec_name = kCodecNameVp8; @@ -85,8 +85,8 @@ payload.ssrc = 11; payload.feedback_ssrc = 12; payload.clock_rate = media::cast::kVideoFrequency; - payload.max_bitrate = 2000; - payload.min_bitrate = 50; + payload.max_bitrate = media::cast::kDefaultMaxVideoBitRate; + payload.min_bitrate = media::cast::kDefaultMinVideoBitRate; payload.channels = 1; payload.max_frame_rate = media::cast::kDefaultMaxFrameRate; payload.codec_name = kCodecNameH264;
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeInstrumentationTestRunner.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeInstrumentationTestRunner.java index 53da512..16cfa52 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeInstrumentationTestRunner.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeInstrumentationTestRunner.java
@@ -210,8 +210,8 @@ } @Override - protected void addSkipChecks(BaseTestResult result) { - super.addSkipChecks(result); + protected void addTestHooks(BaseTestResult result) { + super.addTestHooks(result); result.addSkipCheck(new DisableInTabbedModeSkipCheck()); result.addSkipCheck(new ChromeRestrictionSkipCheck()); }
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 1996a9d4..3c8d2ee 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -676,9 +676,9 @@ bool PasswordAutofillAgent::TextFieldDidEndEditing( const blink::WebInputElement& element) { - LoginToPasswordInfoMap::const_iterator iter = - login_to_password_info_.find(element); - if (iter == login_to_password_info_.end()) + WebInputToPasswordInfoMap::const_iterator iter = + web_input_to_password_info_.find(element); + if (iter == web_input_to_password_info_.end()) return false; const PasswordInfo& password_info = iter->second; @@ -714,8 +714,9 @@ blink::WebInputElement mutable_element = element; // We need a non-const. mutable_element.setAutofilled(false); - LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(element); - if (iter != login_to_password_info_.end()) { + WebInputToPasswordInfoMap::iterator iter = + web_input_to_password_info_.find(element); + if (iter != web_input_to_password_info_.end()) { iter->second.password_was_edited_last = false; // If wait_for_username is true we will fill when the username loses focus. if (iter->second.fill_data.wait_for_username) @@ -734,9 +735,9 @@ if (element.isTextField()) nonscript_modified_values_[element] = element.value(); - LoginToPasswordInfoMap::iterator password_info_iter = - login_to_password_info_.find(element); - if (password_info_iter != login_to_password_info_.end()) { + WebInputToPasswordInfoMap::iterator password_info_iter = + web_input_to_password_info_.find(element); + if (password_info_iter != web_input_to_password_info_.end()) { password_info_iter->second.username_was_edited = true; } @@ -762,7 +763,7 @@ PasswordToLoginMap::iterator iter = password_to_username_.find(element); if (iter != password_to_username_.end()) { - login_to_password_info_[iter->second].password_was_edited_last = true; + web_input_to_password_info_[iter->second].password_was_edited_last = true; // Note that the suggested value of |mutable_element| was reset when its // value changed. mutable_element.setAutofilled(false); @@ -848,6 +849,14 @@ if (!element.isPasswordField()) { *username_element = &element; } else { + WebInputToPasswordInfoMap::iterator iter = + web_input_to_password_info_.find(element); + if (iter != web_input_to_password_info_.end()) { + // It's a password field without corresponding username field. + *username_element = nullptr; + *password_info = &iter->second; + return true; + } PasswordToLoginMap::const_iterator password_iter = password_to_username_.find(element); if (password_iter == password_to_username_.end()) @@ -855,10 +864,10 @@ *username_element = &password_iter->second; } - LoginToPasswordInfoMap::iterator iter = - login_to_password_info_.find(**username_element); + WebInputToPasswordInfoMap::iterator iter = + web_input_to_password_info_.find(**username_element); - if (iter == login_to_password_info_.end()) + if (iter == web_input_to_password_info_.end()) return false; *password_info = &iter->second; @@ -891,8 +900,9 @@ if (element.value().length() > kMaximumTextSizeForAutocomplete) return false; - bool username_is_available = - !username_element->isNull() && IsElementEditable(*username_element); + bool username_is_available = username_element && + !username_element->isNull() && + IsElementEditable(*username_element); // If the element is a password field, a popup should only be shown if there // is no username or the corresponding username element is not editable since // it is only in that case that the username element does not have a @@ -915,7 +925,8 @@ // for the call to ShowSuggestionPopup. return ShowSuggestionPopup( password_info->fill_data, - username_element->isNull() ? element : *username_element, + (!username_element || username_element->isNull()) ? element + : *username_element, show_all && !element.isPasswordField(), element.isPasswordField()); } @@ -1292,16 +1303,19 @@ if (password_field_name.empty()) break; - // We might have already filled this form if there are two <form> elements - // with identical markup. - if (login_to_password_info_.find(username_element) != - login_to_password_info_.end()) - continue; - // Get pointer to password element. (We currently only support single // password forms). password_element = (*iter)[password_field_name]; + blink::WebInputElement main_element = + username_element.isNull() ? password_element : username_element; + + // We might have already filled this form if there are two <form> elements + // with identical markup. + if (web_input_to_password_info_.find(main_element) != + web_input_to_password_info_.end()) + continue; + // If wait_for_username is true, we don't want to initially fill the form // until the user types in a valid username. if (!form_data.wait_for_username) { @@ -1317,9 +1331,9 @@ PasswordInfo password_info; password_info.fill_data = form_data; password_info.password_field = password_element; - login_to_password_info_[username_element] = password_info; + web_input_to_password_info_[main_element] = password_info; password_to_username_[password_element] = username_element; - login_to_password_info_key_[username_element] = key; + web_element_to_password_info_key_[main_element] = key; } } @@ -1396,9 +1410,9 @@ blink::WebInputElement selected_element = user_input; if (show_on_password_field && !selected_element.isPasswordField()) { - LoginToPasswordInfoMap::const_iterator iter = - login_to_password_info_.find(user_input); - DCHECK(iter != login_to_password_info_.end()); + WebInputToPasswordInfoMap::const_iterator iter = + web_input_to_password_info_.find(user_input); + DCHECK(iter != web_input_to_password_info_.end()); selected_element = iter->second.password_field; } gfx::Rect bounding_box(selected_element.boundsInViewportSpace()); @@ -1407,9 +1421,9 @@ if (!show_on_password_field || !user_input.isPasswordField()) { username = user_input; } - LoginToPasswordInfoKeyMap::const_iterator key_it = - login_to_password_info_key_.find(username); - DCHECK(key_it != login_to_password_info_key_.end()); + WebElementToPasswordInfoKeyMap::const_iterator key_it = + web_element_to_password_info_key_.find(user_input); + DCHECK(key_it != web_element_to_password_info_key_.end()); float scale = render_frame()->GetRenderView()->GetWebView()->pageScaleFactor(); @@ -1433,11 +1447,11 @@ } void PasswordAutofillAgent::FrameClosing() { - for (auto const& iter : login_to_password_info_) { - login_to_password_info_key_.erase(iter.first); + for (auto const& iter : web_input_to_password_info_) { + web_element_to_password_info_key_.erase(iter.first); password_to_username_.erase(iter.second.password_field); } - login_to_password_info_.clear(); + web_input_to_password_info_.clear(); provisionally_saved_form_.reset(); nonscript_modified_values_.clear(); }
diff --git a/components/autofill/content/renderer/password_autofill_agent.h b/components/autofill/content/renderer/password_autofill_agent.h index 33dba50..af38bf5 100644 --- a/components/autofill/content/renderer/password_autofill_agent.h +++ b/components/autofill/content/renderer/password_autofill_agent.h
@@ -105,8 +105,9 @@ bool username_was_edited; PasswordInfo(); }; - typedef std::map<blink::WebInputElement, PasswordInfo> LoginToPasswordInfoMap; - typedef std::map<blink::WebElement, int> LoginToPasswordInfoKeyMap; + typedef std::map<blink::WebInputElement, PasswordInfo> + WebInputToPasswordInfoMap; + typedef std::map<blink::WebElement, int> WebElementToPasswordInfoKeyMap; typedef std::map<blink::WebInputElement, blink::WebInputElement> PasswordToLoginMap; @@ -240,9 +241,9 @@ LegacyPasswordAutofillAgent legacy_; // The logins we have filled so far with their associated info. - LoginToPasswordInfoMap login_to_password_info_; + WebInputToPasswordInfoMap web_input_to_password_info_; // And the keys under which PasswordAutofillManager can find the same info. - LoginToPasswordInfoKeyMap login_to_password_info_key_; + WebElementToPasswordInfoKeyMap web_element_to_password_info_key_; // A (sort-of) reverse map to |login_to_password_info_|. PasswordToLoginMap password_to_username_;
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.cc b/components/autofill/content/renderer/password_form_conversion_utils.cc index 30a0405b..c820450 100644 --- a/components/autofill/content/renderer/password_form_conversion_utils.cc +++ b/components/autofill/content/renderer/password_form_conversion_utils.cc
@@ -4,7 +4,7 @@ #include "components/autofill/content/renderer/password_form_conversion_utils.h" -#include <vector> +#include <string> #include "base/i18n/case_conversion.h" #include "base/lazy_instance.h" @@ -30,7 +30,6 @@ using blink::WebFrame; using blink::WebInputElement; using blink::WebString; -using blink::WebVector; namespace autofill { namespace { @@ -132,8 +131,15 @@ void PopulateSyntheticFormFromWebForm(const WebFormElement& web_form, SyntheticForm* synthetic_form) { - synthetic_form->control_elements = - form_util::ExtractAutofillableElementsInForm(web_form); + // TODO(vabr): The fact that we are actually passing all form fields, not just + // autofillable ones (cause of http://crbug.com/537396, see also + // http://crbug.com/543006) is not tested yet, due to difficulties to fake + // test frame origin to match GAIA login page. Once this code gets moved to + // browser, we need to add tests for this as well. + blink::WebVector<blink::WebFormControlElement> web_control_elements; + web_form.getFormControlElements(web_control_elements); + synthetic_form->control_elements.assign(web_control_elements.begin(), + web_control_elements.end()); synthetic_form->action = web_form.action(); synthetic_form->document = web_form.document(); } @@ -246,7 +252,7 @@ // the username to be updated even if the form is changed after page load. // See https://crbug.com/476092 for more details. auto predictions_iterator = form_predictions.begin(); - for (;predictions_iterator != form_predictions.end(); + for (; predictions_iterator != form_predictions.end(); ++predictions_iterator) { if (predictions_iterator->first.action == form_data.action && predictions_iterator->first.name == form_data.name) { @@ -268,10 +274,10 @@ const FormFieldData& target_field = prediction->first; const PasswordFormFieldPredictionType& type = prediction->second; - for (size_t i = 0; i < form.control_elements.size(); ++i) { - if (form.control_elements[i].nameForAutofill() == target_field.name) { + for (size_t i = 0; i < autofillable_elements.size(); ++i) { + if (autofillable_elements[i].nameForAutofill() == target_field.name) { const WebInputElement* input_element = - toWebInputElement(&form.control_elements[i]); + toWebInputElement(&autofillable_elements[i]); // TODO(sebsg): Investigate why this guard is necessary, see // https://crbug.com/517490 for more details. if (input_element) { @@ -322,8 +328,8 @@ // the form will be ignored. // TODO(msramek): Move this logic to the browser, and disable filling only // for the sync credential and if passwords are being synced. - if (IsGaiaReauthenticationForm( - GURL(form.document.url()).GetOrigin(), form.control_elements)) { + if (IsGaiaReauthenticationForm(GURL(form.document.url()).GetOrigin(), + form.control_elements)) { return false; } @@ -544,7 +550,7 @@ bool IsGaiaReauthenticationForm( const GURL& origin, - const WebVector<blink::WebFormControlElement>& control_elements) { + const std::vector<blink::WebFormControlElement>& control_elements) { if (origin != GaiaUrls::GetInstance()->gaia_url().GetOrigin()) return false;
diff --git a/components/autofill/content/renderer/password_form_conversion_utils.h b/components/autofill/content/renderer/password_form_conversion_utils.h index 257e202..42092289 100644 --- a/components/autofill/content/renderer/password_form_conversion_utils.h +++ b/components/autofill/content/renderer/password_form_conversion_utils.h
@@ -6,11 +6,11 @@ #define COMPONENTS_AUTOFILL_CONTENT_RENDERER_PASSWORD_FORM_CONVERSION_UTILS_H_ #include <map> +#include <vector> #include "base/memory/scoped_ptr.h" #include "components/autofill/core/common/password_form_field_prediction_map.h" #include "third_party/WebKit/public/platform/WebString.h" -#include "third_party/WebKit/public/platform/WebVector.h" #include "url/gurl.h" namespace blink { @@ -28,12 +28,12 @@ struct PasswordForm; // Tests whether the given form is a GAIA reauthentication form. The form is -// not passed directly as WebFormElement, but by specifying its |url| and +// not passed directly as WebFormElement, but by specifying its |origin| and // |control_elements|. This is for better performance and easier testing. // TODO(msramek): Move this logic to the browser. bool IsGaiaReauthenticationForm( const GURL& origin, - const blink::WebVector<blink::WebFormControlElement>& control_elements); + const std::vector<blink::WebFormControlElement>& control_elements); typedef std::map<const blink::WebInputElement, blink::WebString> ModifiedValues;
diff --git a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc index c4c71e8..ba9d8d2d 100644 --- a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc +++ b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
@@ -850,145 +850,112 @@ } TEST_F(MAYBE_PasswordFormConversionUtilsTest, IsGaiaReauthFormIgnored) { - scoped_ptr<PasswordFormBuilder> builder; - FormsPredictionsMap predictions; - WebFormElement form; - WebVector<WebFormControlElement> control_elements; + struct TestCase { + const char* origin; + struct KeyValue { + KeyValue() : name(nullptr), value(nullptr) {} + KeyValue(const char* new_name, const char* new_value) + : name(new_name), value(new_value) {} + const char* name; + const char* value; + } hidden_fields[2]; + bool expected_form_is_reauth; + } cases[] = { + // A common password form is parsed successfully. + {"https://example.com", + {TestCase::KeyValue(), TestCase::KeyValue()}, + false}, + // A common password form, even if it appears on a GAIA reauth url, + // is parsed successfully. + {"https://accounts.google.com", + {TestCase::KeyValue(), TestCase::KeyValue()}, + false}, + // Not a transactional reauth. + {"https://accounts.google.com", + {TestCase::KeyValue("continue", "https://passwords.google.com/settings"), + TestCase::KeyValue()}, + false}, + // A reauth form that is not for a password site is parsed successfuly. + {"https://accounts.google.com", + {TestCase::KeyValue("continue", "https://mail.google.com"), + TestCase::KeyValue("rart", "")}, + false}, + // A reauth form for a password site is recognised as such. + {"https://accounts.google.com", + {TestCase::KeyValue("continue", "https://passwords.google.com"), + TestCase::KeyValue("rart", "")}, + true}, + // Path, params or fragment in "continue" should not have influence. + {"https://accounts.google.com", + {TestCase::KeyValue("continue", + "https://passwords.google.com/path?param=val#frag"), + TestCase::KeyValue("rart", "")}, + true}, + // Password site is inaccesible via HTTP, but because of HSTS the + // following link should still continue to https://passwords.google.com. + {"https://accounts.google.com", + {TestCase::KeyValue("continue", "http://passwords.google.com"), + TestCase::KeyValue("rart", "")}, + true}, + // Make sure testing sites are disabled as well. + {"https://accounts.google.com", + {TestCase::KeyValue( + "continue", + "https://passwords-ac-testing.corp.google.com/settings"), + TestCase::KeyValue("rart", "")}, + true}, + // Specifying default port doesn't change anything. + {"https://accounts.google.com", + {TestCase::KeyValue("continue", "passwords.google.com:443"), + TestCase::KeyValue("rart", "")}, + true}, + // Encoded URL is considered the same. + {"https://accounts.google.com", + {TestCase::KeyValue("continue", + "https://passwords.%67oogle.com/settings"), + TestCase::KeyValue("rart", "")}, + true}, + // Fully qualified domain should work as well. + {"https://accounts.google.com", + {TestCase::KeyValue("continue", + "https://passwords.google.com./settings"), + TestCase::KeyValue("rart", "")}, + true}, + // A correctly looking form, but on a different page. + {"https://google.com", + {TestCase::KeyValue("continue", "https://passwords.google.com"), + TestCase::KeyValue("rart", "")}, + false}, + }; - // A common password form is parsed successfully. - builder.reset(new PasswordFormBuilder("https://example.com")); - builder->AddTextField("username", "", nullptr); - builder->AddPasswordField("password", "", nullptr); - std::string html = builder->ProduceHTML(); - LoadWebFormFromHTML(html, &form); - form.getFormControlElements(control_elements); - EXPECT_FALSE(IsGaiaReauthenticationForm( - GURL("https://example.com"), control_elements)); - - // A common password form, even if it appears on a GAIA reauth url, - // is parsed successfully. - builder.reset(new PasswordFormBuilder("https://accounts.google.com")); - builder->AddTextField("username", "", nullptr); - builder->AddPasswordField("password", "", nullptr); - html = builder->ProduceHTML(); - LoadWebFormFromHTML(html, &form); - form.getFormControlElements(control_elements); - EXPECT_FALSE(IsGaiaReauthenticationForm( - GURL("https://accounts.google.com"), control_elements)); - - // Not a transactional reauth. - builder.reset(new PasswordFormBuilder("https://accounts.google.com")); - builder->AddTextField("username", "", nullptr); - builder->AddPasswordField("password", "", nullptr); - builder->AddHiddenField( - "continue", "https://passwords.google.com/settings"); - html = builder->ProduceHTML(); - LoadWebFormFromHTML(html, &form); - form.getFormControlElements(control_elements); - EXPECT_FALSE(IsGaiaReauthenticationForm( - GURL("https://accounts.google.com"), control_elements)); - - // A reauth form that is not for a password site is parsed successfuly. - builder.reset(new PasswordFormBuilder("https://accounts.google.com")); - builder->AddTextField("username", "", nullptr); - builder->AddPasswordField("password", "", nullptr); - builder->AddHiddenField("rart", ""); - builder->AddHiddenField("continue", "https://mail.google.com"); - html = builder->ProduceHTML(); - LoadWebFormFromHTML(html, &form); - form.getFormControlElements(control_elements); - EXPECT_FALSE(IsGaiaReauthenticationForm( - GURL("https://accounts.google.com"), control_elements)); - - // A reauth form for a password site is ignored. - builder.reset(new PasswordFormBuilder("https://accounts.google.com")); - builder->AddTextField("username", "", nullptr); - builder->AddPasswordField("password", "", nullptr); - builder->AddHiddenField("rart", ""); - builder->AddHiddenField("continue", "https://passwords.google.com"); - html = builder->ProduceHTML(); - LoadWebFormFromHTML(html, &form); - form.getFormControlElements(control_elements); - EXPECT_TRUE(IsGaiaReauthenticationForm( - GURL("https://accounts.google.com"), control_elements)); - - // Password site is inaccesible via HTTP, but because of HSTS the following - // link should still continue to https://passwords.google.com. - builder.reset(new PasswordFormBuilder("https://accounts.google.com")); - builder->AddTextField("username", "", nullptr); - builder->AddPasswordField("password", "", nullptr); - builder->AddHiddenField("rart", ""); - builder->AddHiddenField("continue", "http://passwords.google.com"); - html = builder->ProduceHTML(); - LoadWebFormFromHTML(html, &form); - form.getFormControlElements(control_elements); - EXPECT_TRUE(IsGaiaReauthenticationForm( - GURL("https://accounts.google.com"), control_elements)); - - // Make sure testing sites are disabled as well. - builder.reset(new PasswordFormBuilder("https://accounts.google.com")); - builder->AddTextField("username", "", nullptr); - builder->AddPasswordField("password", "", nullptr); - builder->AddHiddenField("rart", ""); - builder->AddHiddenField( - "continue", "https://passwords-ac-testing.corp.google.com/settings"); - html = builder->ProduceHTML(); - LoadWebFormFromHTML(html, &form); - form.getFormControlElements(control_elements); - EXPECT_TRUE(IsGaiaReauthenticationForm( - GURL("https://accounts.google.com"), control_elements)); - - // Specifying default port doesn't change anything. - builder.reset(new PasswordFormBuilder("https://accounts.google.com")); - builder->AddTextField("username", "", nullptr); - builder->AddPasswordField("password", "", nullptr); - builder->AddHiddenField("rart", ""); - builder->AddHiddenField("continue", "passwords.google.com:443"); - html = builder->ProduceHTML(); - LoadWebFormFromHTML(html, &form); - form.getFormControlElements(control_elements); - EXPECT_TRUE(IsGaiaReauthenticationForm( - GURL("https://accounts.google.com"), control_elements)); - - // Encoded URL is considered the same. - builder.reset(new PasswordFormBuilder("https://accounts.google.com")); - builder->AddTextField("username", "", nullptr); - builder->AddPasswordField("password", "", nullptr); - builder->AddHiddenField("rart", ""); - builder->AddHiddenField( - "continue", "https://passwords.%67oogle.com/settings&rart=123"); - html = builder->ProduceHTML(); - LoadWebFormFromHTML(html, &form); - form.getFormControlElements(control_elements); - EXPECT_TRUE(IsGaiaReauthenticationForm( - GURL("https://accounts.google.com"), control_elements)); - - // Fully qualified domain name is considered a different hostname by GURL. - // Ideally this would not be the case, but this quirk can be avoided by - // verification on the server. This test is simply documentation of this - // behavior. - builder.reset(new PasswordFormBuilder("https://accounts.google.com")); - builder->AddTextField("username", "", nullptr); - builder->AddPasswordField("password", "", nullptr); - builder->AddHiddenField("rart", ""); - builder->AddHiddenField("continue", "https://passwords.google.com./settings"); - html = builder->ProduceHTML(); - LoadWebFormFromHTML(html, &form); - form.getFormControlElements(control_elements); - EXPECT_TRUE(IsGaiaReauthenticationForm( - GURL("https://accounts.google.com"), control_elements)); - - // A correctly looking form, but on a different page. - builder.reset(new PasswordFormBuilder("https://google.com")); - builder->AddTextField("username", "", nullptr); - builder->AddPasswordField("password", "", nullptr); - builder->AddHiddenField("rart", ""); - builder->AddHiddenField("continue", "https://passwords.google.com"); - html = builder->ProduceHTML(); - LoadWebFormFromHTML(html, &form); - form.getFormControlElements(control_elements); - EXPECT_FALSE(IsGaiaReauthenticationForm( - GURL("https://google.com"), control_elements)); + for (TestCase& test_case : cases) { + SCOPED_TRACE(testing::Message("origin=") + << test_case.origin + << ", hidden_fields[0]=" << test_case.hidden_fields[0].name + << "/" << test_case.hidden_fields[0].value + << ", hidden_fields[1]=" << test_case.hidden_fields[1].name + << "/" << test_case.hidden_fields[1].value + << ", expected_form_is_reauth=" + << test_case.expected_form_is_reauth); + scoped_ptr<PasswordFormBuilder> builder(new PasswordFormBuilder("")); + builder->AddTextField("username", "", nullptr); + builder->AddPasswordField("password", "", nullptr); + for (TestCase::KeyValue& hidden_field : test_case.hidden_fields) { + if (hidden_field.name) + builder->AddHiddenField(hidden_field.name, hidden_field.value); + } + std::string html = builder->ProduceHTML(); + WebFormElement form; + LoadWebFormFromHTML(html, &form); + std::vector<WebFormControlElement> control_elements; + WebVector<blink::WebFormControlElement> web_control_elements; + form.getFormControlElements(web_control_elements); + control_elements.assign(web_control_elements.begin(), + web_control_elements.end()); + EXPECT_EQ(test_case.expected_form_is_reauth, + IsGaiaReauthenticationForm(GURL(test_case.origin).GetOrigin(), + control_elements)); + } } TEST_F(MAYBE_PasswordFormConversionUtilsTest,
diff --git a/components/autofill/core/common/password_form.h b/components/autofill/core/common/password_form.h index 57a9d9df..e114f0d 100644 --- a/components/autofill/core/common/password_form.h +++ b/components/autofill/core/common/password_form.h
@@ -53,12 +53,14 @@ // Enum to differentiate between HTML form based authentication, and dialogs // using basic or digest schemes. Default is SCHEME_HTML. Only PasswordForms // of the same Scheme will be matched/autofilled against each other. - enum Scheme { + enum Scheme : int { SCHEME_HTML, SCHEME_BASIC, SCHEME_DIGEST, SCHEME_OTHER, - SCHEME_LAST = SCHEME_OTHER + SCHEME_USERNAME_ONLY, + + SCHEME_LAST = SCHEME_USERNAME_ONLY } scheme; // During form parsing, Chrome tries to partly understand the type of the form
diff --git a/components/autofill/core/common/save_password_progress_logger.cc b/components/autofill/core/common/save_password_progress_logger.cc index 57ffd1d..b70d818 100644 --- a/components/autofill/core/common/save_password_progress_logger.cc +++ b/components/autofill/core/common/save_password_progress_logger.cc
@@ -57,6 +57,8 @@ return SavePasswordProgressLogger::STRING_SCHEME_DIGEST; case PasswordForm::SCHEME_OTHER: return SavePasswordProgressLogger::STRING_OTHER; + case PasswordForm::SCHEME_USERNAME_ONLY: + return SavePasswordProgressLogger::STRING_SCHEME_USERNAME_ONLY; } NOTREACHED(); return SavePasswordProgressLogger::STRING_INVALID; @@ -179,6 +181,8 @@ return "Basic"; case SavePasswordProgressLogger::STRING_SCHEME_DIGEST: return "Digest"; + case SavePasswordProgressLogger::STRING_SCHEME_USERNAME_ONLY: + return "Username only"; case SavePasswordProgressLogger::STRING_SCHEME_MESSAGE: return "Scheme"; case SavePasswordProgressLogger::STRING_SIGNON_REALM:
diff --git a/components/autofill/core/common/save_password_progress_logger.h b/components/autofill/core/common/save_password_progress_logger.h index ccfa6cc..15d5e27 100644 --- a/components/autofill/core/common/save_password_progress_logger.h +++ b/components/autofill/core/common/save_password_progress_logger.h
@@ -42,6 +42,7 @@ STRING_SCHEME_HTML, STRING_SCHEME_BASIC, STRING_SCHEME_DIGEST, + STRING_SCHEME_USERNAME_ONLY, STRING_SCHEME_MESSAGE, STRING_SIGNON_REALM, STRING_ORIGIN,
diff --git a/components/components_tests.gyp b/components/components_tests.gyp index 24a280d..c73e745 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp
@@ -434,6 +434,7 @@ 'password_manager/core/browser/password_manager_metrics_util_unittest.cc', 'password_manager/core/browser/password_manager_settings_migration_experiment_unittest.cc', 'password_manager/core/browser/password_manager_unittest.cc', + 'password_manager/core/browser/password_manager_util_unittest.cc', 'password_manager/core/browser/password_store_default_unittest.cc', 'password_manager/core/browser/password_store_unittest.cc', 'password_manager/core/browser/password_syncable_service_unittest.cc',
diff --git a/components/favicon/content/content_favicon_driver.cc b/components/favicon/content/content_favicon_driver.cc index 5d71df02..8cf9066 100644 --- a/components/favicon/content/content_favicon_driver.cc +++ b/components/favicon/content/content_favicon_driver.cc
@@ -113,10 +113,6 @@ return entry ? entry->GetURL() : GURL(); } -bool ContentFaviconDriver::GetActiveFaviconValidity() { - return GetFaviconStatus().valid; -} - void ContentFaviconDriver::SetActiveFaviconValidity(bool valid) { GetFaviconStatus().valid = valid; }
diff --git a/components/favicon/content/content_favicon_driver.h b/components/favicon/content/content_favicon_driver.h index adbc7e7..1af8bb1 100644 --- a/components/favicon/content/content_favicon_driver.h +++ b/components/favicon/content/content_favicon_driver.h
@@ -47,7 +47,6 @@ int StartDownload(const GURL& url, int max_bitmap_size) override; bool IsOffTheRecord() override; GURL GetActiveURL() override; - bool GetActiveFaviconValidity() override; void SetActiveFaviconValidity(bool valid) override; GURL GetActiveFaviconURL() override; void SetActiveFaviconURL(const GURL& url) override;
diff --git a/components/favicon/core/favicon_driver.h b/components/favicon/core/favicon_driver.h index cf9a4a59..0c2747e 100644 --- a/components/favicon/core/favicon_driver.h +++ b/components/favicon/core/favicon_driver.h
@@ -61,10 +61,6 @@ // otherwise. virtual GURL GetActiveURL() = 0; - // Returns whether the page's favicon is valid (returns false if the default - // favicon is being used). - virtual bool GetActiveFaviconValidity() = 0; - // Sets whether the page's favicon is valid (if false, the default favicon is // being used). virtual void SetActiveFaviconValidity(bool valid) = 0;
diff --git a/components/favicon/core/favicon_handler.cc b/components/favicon/core/favicon_handler.cc index d8ec1ea..3d15052 100644 --- a/components/favicon/core/favicon_handler.cc +++ b/components/favicon/core/favicon_handler.cc
@@ -568,8 +568,7 @@ preferred_icon_size(), favicon_bitmap_results); bool has_valid_result = HasValidResult(favicon_bitmap_results); - if (has_results && handler_type_ == FAVICON && - !download_largest_icon_ && !driver_->GetActiveFaviconValidity() && + if (has_results && handler_type_ == FAVICON && !download_largest_icon_ && (!current_candidate() || DoUrlsAndIconsMatch(*current_candidate(), favicon_bitmap_results))) { if (has_valid_result) {
diff --git a/components/favicon/core/favicon_handler_unittest.cc b/components/favicon/core/favicon_handler_unittest.cc index ca89afaa..2afd9bf 100644 --- a/components/favicon/core/favicon_handler_unittest.cc +++ b/components/favicon/core/favicon_handler_unittest.cc
@@ -229,7 +229,7 @@ GURL GetActiveURL() override { return url_; } - bool GetActiveFaviconValidity() override { return favicon_validity_; } + bool GetActiveFaviconValidity() { return favicon_validity_; } void SetActiveFaviconValidity(bool favicon_validity) override { favicon_validity_ = favicon_validity;
diff --git a/components/favicon/ios/web_favicon_driver.cc b/components/favicon/ios/web_favicon_driver.cc index cadd60f..b1a8e11a 100644 --- a/components/favicon/ios/web_favicon_driver.cc +++ b/components/favicon/ios/web_favicon_driver.cc
@@ -72,16 +72,12 @@ return item ? item->GetURL() : GURL(); } -bool WebFaviconDriver::GetActiveFaviconValidity() { - return !ActiveURLChangedSinceFetchFavicon() && GetFaviconStatus().valid; -} - void WebFaviconDriver::SetActiveFaviconValidity(bool validity) { GetFaviconStatus().valid = validity; } GURL WebFaviconDriver::GetActiveFaviconURL() { - return ActiveURLChangedSinceFetchFavicon() ? GURL() : GetFaviconStatus().url; + return GetFaviconStatus().url; } void WebFaviconDriver::SetActiveFaviconURL(const GURL& url) { @@ -92,17 +88,8 @@ GetFaviconStatus().image = image; } -bool WebFaviconDriver::ActiveURLChangedSinceFetchFavicon() { - // On iOS the active URL can change in between calls to FetchFavicon(). For - // instance, FetchFavicon() is not synchronously called when the active URL - // changes as a result of CRWSessionController::goToEntry(). - // TODO(stuartmorgan): Remove this once iOS always triggers favicon fetches - // synchronously after active URL changes. - return GetActiveURL() != fetch_favicon_url_; -} - web::FaviconStatus& WebFaviconDriver::GetFaviconStatus() { - DCHECK(!ActiveURLChangedSinceFetchFavicon()); + DCHECK(web_state()->GetNavigationManager()->GetVisibleItem()); return web_state()->GetNavigationManager()->GetVisibleItem()->GetFavicon(); }
diff --git a/components/favicon/ios/web_favicon_driver.h b/components/favicon/ios/web_favicon_driver.h index 0be7bce..1e17e49 100644 --- a/components/favicon/ios/web_favicon_driver.h +++ b/components/favicon/ios/web_favicon_driver.h
@@ -35,7 +35,6 @@ int StartDownload(const GURL& url, int max_bitmap_size) override; bool IsOffTheRecord() override; GURL GetActiveURL() override; - bool GetActiveFaviconValidity() override; void SetActiveFaviconValidity(bool valid) override; GURL GetActiveFaviconURL() override; void SetActiveFaviconURL(const GURL& url) override; @@ -50,9 +49,6 @@ bookmarks::BookmarkModel* bookmark_model); ~WebFaviconDriver() override; - // Returns whether the active URL has changed since FetchFavicon() was called. - bool ActiveURLChangedSinceFetchFavicon(); - // web::WebStateObserver implementation. void FaviconUrlUpdated( const std::vector<web::FaviconURL>& candidates) override;
diff --git a/components/html_viewer/html_document.cc b/components/html_viewer/html_document.cc index 1d976f7..fd6df51 100644 --- a/components/html_viewer/html_document.cc +++ b/components/html_viewer/html_document.cc
@@ -317,7 +317,8 @@ new ViewTreeDelegateImpl(this)); transferable_state_.owns_view_tree_connection = true; mus::ViewTreeConnection::Create( - transferable_state_.view_tree_delegate_impl.get(), request.Pass()); + transferable_state_.view_tree_delegate_impl.get(), request.Pass(), + mus::ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } } // namespace html_viewer
diff --git a/components/html_viewer/web_url_loader_impl.cc b/components/html_viewer/web_url_loader_impl.cc index 2dfbcce..2de84cd 100644 --- a/components/html_viewer/web_url_loader_impl.cc +++ b/components/html_viewer/web_url_loader_impl.cc
@@ -349,4 +349,9 @@ ReadMore(); } +void WebURLLoaderImpl::setLoadingTaskRunner( + blink::WebTaskRunner* web_task_runner) { + // TODO(alexclarke): Consider hooking this up. +} + } // namespace html_viewer
diff --git a/components/html_viewer/web_url_loader_impl.h b/components/html_viewer/web_url_loader_impl.h index c8a788f..f829331 100644 --- a/components/html_viewer/web_url_loader_impl.h +++ b/components/html_viewer/web_url_loader_impl.h
@@ -47,6 +47,7 @@ blink::WebURLLoaderClient* client); virtual void cancel(); virtual void setDefersLoading(bool defers_loading); + virtual void setLoadingTaskRunner(blink::WebTaskRunner* web_task_runner); void OnReceivedResponse(const blink::WebURLRequest& request, mojo::URLResponsePtr response);
diff --git a/components/metrics/proto/cast_logs.proto b/components/metrics/proto/cast_logs.proto index f433614..604f57e 100644 --- a/components/metrics/proto/cast_logs.proto +++ b/components/metrics/proto/cast_logs.proto
@@ -144,6 +144,9 @@ // An optional value for the associated event optional int64 value = 8; + + // An optional value for the multi-room group uuid. + optional int64 group_uuid = 10; } repeated CastEventProto cast_event = 3; }
diff --git a/components/mus/example/client/BUILD.gn b/components/mus/example/client/BUILD.gn index 2310d55..d0710b4f 100644 --- a/components/mus/example/client/BUILD.gn +++ b/components/mus/example/client/BUILD.gn
@@ -18,11 +18,10 @@ ] deps = [ - ":resources", "//base", + "//components/mus/example/common", "//components/mus/example/wm:interfaces", "//mojo/application/public/cpp", - "//mandoline/ui/aura", "//mojo/application/public/cpp:sources", "//mojo/converters/geometry", "//skia", @@ -39,18 +38,3 @@ "//components/mus", ] } - -repack("resources") { - sources = [ - "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", - "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", - "$root_gen_dir/ui/strings/ui_strings_en-US.pak", - "$root_gen_dir/ui/views/resources/views_resources_100_percent.pak", - ] - output = "$root_out_dir/example_resources.pak" - deps = [ - "//ui/strings", - "//ui/resources", - "//ui/views/resources", - ] -}
diff --git a/components/mus/example/client/client_application_delegate.cc b/components/mus/example/client/client_application_delegate.cc index e73d4a4..c7fbe88 100644 --- a/components/mus/example/client/client_application_delegate.cc +++ b/components/mus/example/client/client_application_delegate.cc
@@ -4,14 +4,9 @@ #include "components/mus/example/client/client_application_delegate.h" -#include "components/mus/example/wm/wm.mojom.h" -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_host_factory.h" -#include "mandoline/ui/aura/aura_init.h" -#include "mandoline/ui/aura/native_widget_view_manager.h" +#include "components/mus/example/common/mus_views_init.h" #include "mojo/application/public/cpp/application_connection.h" #include "mojo/application/public/cpp/application_impl.h" -#include "mojo/converters/geometry/geometry_type_converters.h" #include "ui/views/background.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" @@ -23,15 +18,15 @@ void ClientApplicationDelegate::Initialize(mojo::ApplicationImpl* app) { app_ = app; - mojom::WMPtr wm; - mojo::URLRequestPtr request(mojo::URLRequest::New()); - request->url = "mojo:example_wm"; - app->ConnectToService(request.Pass(), &wm); + mus_views_init_.reset(new MUSViewsInit(app)); for (int i = 0; i < 3; ++i) { - mojo::ViewTreeClientPtr view_tree_client; - mus::ViewTreeConnection::Create(this, GetProxy(&view_tree_client).Pass()); - wm->OpenWindow(view_tree_client.Pass()); + views::WidgetDelegateView* widget_delegate = new views::WidgetDelegateView; + widget_delegate->GetContentsView()->set_background( + views::Background::CreateSolidBackground(0xFFDDDDDD)); + + views::Widget* widget = views::Widget::CreateWindow(widget_delegate); + widget->Show(); } } @@ -39,28 +34,3 @@ mojo::ApplicationConnection* connection) { return false; } - -void ClientApplicationDelegate::OnEmbed(mus::View* root) { - if (!aura_init_) { - aura_init_.reset( - new mandoline::AuraInit(root, app_->shell(), "example_resources.pak")); - } - - views::WidgetDelegateView* widget_delegate = new views::WidgetDelegateView; - widget_delegate->GetContentsView()->set_background( - views::Background::CreateSolidBackground(0xFFDDDDDD)); - - views::Widget* widget = new views::Widget; - views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); - params.delegate = widget_delegate; - params.native_widget = - new mandoline::NativeWidgetViewManager(widget, app_->shell(), root); - params.bounds = root->bounds().To<gfx::Rect>(); - params.bounds.set_x(0); - params.bounds.set_y(0); - widget->Init(params); - widget->Show(); -} - -void ClientApplicationDelegate::OnConnectionLost( - mus::ViewTreeConnection* connection) {}
diff --git a/components/mus/example/client/client_application_delegate.h b/components/mus/example/client/client_application_delegate.h index 3a8f28d..dc304ad 100644 --- a/components/mus/example/client/client_application_delegate.h +++ b/components/mus/example/client/client_application_delegate.h
@@ -7,35 +7,25 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" -#include "components/mus/public/cpp/view_tree_delegate.h" #include "mojo/application/public/cpp/application_delegate.h" #include "mojo/application/public/cpp/interface_factory_impl.h" -namespace mandoline { -class AuraInit; -} +class MUSViewsInit; -class ClientApplicationDelegate : public mojo::ApplicationDelegate, - public mus::ViewTreeDelegate { +class ClientApplicationDelegate : public mojo::ApplicationDelegate { public: ClientApplicationDelegate(); ~ClientApplicationDelegate() override; - // Overridden from ApplicationDelegate: - void Initialize(mojo::ApplicationImpl* app) override; - private: // ApplicationDelegate: + void Initialize(mojo::ApplicationImpl* app) override; bool ConfigureIncomingConnection( mojo::ApplicationConnection* connection) override; - // mus::ViewTreeDelegate: - void OnEmbed(mus::View* root) override; - void OnConnectionLost(mus::ViewTreeConnection* connection) override; - mojo::ApplicationImpl* app_; - scoped_ptr<mandoline::AuraInit> aura_init_; + scoped_ptr<MUSViewsInit> mus_views_init_; DISALLOW_COPY_AND_ASSIGN(ClientApplicationDelegate); };
diff --git a/components/mus/example/common/BUILD.gn b/components/mus/example/common/BUILD.gn new file mode 100644 index 0000000..1e665027 --- /dev/null +++ b/components/mus/example/common/BUILD.gn
@@ -0,0 +1,52 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/ui.gni") +import("//mojo/public/mojo_application.gni") +import("//third_party/mojo/src/mojo/public/tools/bindings/mojom.gni") +import("//tools/grit/repack.gni") + +source_set("common") { + testonly = true + + sources = [ + "mus_views_init.cc", + "mus_views_init.h", + ] + + deps = [ + "//base", + "//components/mus/example/wm:interfaces", + "//components/mus/public/cpp", + "//components/mus/public/interfaces", + "//mojo/application/public/cpp", + "//mandoline/ui/aura", + "//mojo/application/public/cpp:sources", + "//third_party/mojo/src/mojo/public/cpp/bindings", + "//ui/views", + ] + + data_deps = [ + "//components/mus", + ] + + public_deps = [ + ":resources", + ] +} + +repack("resources") { + sources = [ + "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", + "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", + "$root_gen_dir/ui/strings/ui_strings_en-US.pak", + "$root_gen_dir/ui/views/resources/views_resources_100_percent.pak", + ] + output = "$root_out_dir/example_resources.pak" + deps = [ + "//ui/strings", + "//ui/resources", + "//ui/views/resources", + ] +}
diff --git a/components/mus/example/common/DEPS b/components/mus/example/common/DEPS new file mode 100644 index 0000000..7caf211 --- /dev/null +++ b/components/mus/example/common/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + # TODO(sky): nuke this. Refactor mandoline/ui/aura into mojo. + "+mandoline/ui/aura", +]
diff --git a/components/mus/example/common/mus_views_init.cc b/components/mus/example/common/mus_views_init.cc new file mode 100644 index 0000000..e1f4faf --- /dev/null +++ b/components/mus/example/common/mus_views_init.cc
@@ -0,0 +1,59 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/mus/example/common/mus_views_init.h" + +#include "components/mus/example/wm/wm.mojom.h" +#include "components/mus/public/cpp/view_tree_connection.h" +#include "components/mus/public/interfaces/view_tree.mojom.h" +#include "mandoline/ui/aura/aura_init.h" +#include "mandoline/ui/aura/native_widget_view_manager.h" +#include "mojo/application/public/cpp/application_connection.h" +#include "mojo/application/public/cpp/application_impl.h" + +MUSViewsInit::MUSViewsInit(mojo::ApplicationImpl* app) : app_(app) {} + +MUSViewsInit::~MUSViewsInit() {} + +mus::View* MUSViewsInit::CreateWindow() { + mojom::WMPtr wm; + mojo::URLRequestPtr request(mojo::URLRequest::New()); + request->url = "mojo:example_wm"; + app_->ConnectToService(request.Pass(), &wm); + mojo::ViewTreeClientPtr view_tree_client; + mojo::InterfaceRequest<mojo::ViewTreeClient> view_tree_client_request = + GetProxy(&view_tree_client); + wm->OpenWindow(view_tree_client.Pass()); + mus::ViewTreeConnection* view_tree_connection = + mus::ViewTreeConnection::Create( + this, view_tree_client_request.Pass(), + mus::ViewTreeConnection::CreateType::WAIT_FOR_EMBED); + DCHECK(view_tree_connection->GetRoot()); + return view_tree_connection->GetRoot(); +} + +views::NativeWidget* MUSViewsInit::CreateNativeWidget( + views::internal::NativeWidgetDelegate* delegate) { + return new mandoline::NativeWidgetViewManager(delegate, app_->shell(), + CreateWindow()); +} + +void MUSViewsInit::OnBeforeWidgetInit( + views::Widget::InitParams* params, + views::internal::NativeWidgetDelegate* delegate) {} + +void MUSViewsInit::OnEmbed(mus::View* root) { + if (!aura_init_) { + aura_init_.reset( + new mandoline::AuraInit(root, app_->shell(), "example_resources.pak")); + } +} + +void MUSViewsInit::OnConnectionLost(mus::ViewTreeConnection* connection) {} + +#if defined(OS_WIN) +HICON MUSViewsInit::GetSmallWindowIcon() const { + return nullptr; +} +#endif
diff --git a/components/mus/example/common/mus_views_init.h b/components/mus/example/common/mus_views_init.h new file mode 100644 index 0000000..710020f --- /dev/null +++ b/components/mus/example/common/mus_views_init.h
@@ -0,0 +1,50 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_MUS_EXAMPLE_COMMON_MUS_VIEWS_INIT_H_ +#define COMPONENTS_MUS_EXAMPLE_COMMON_MUS_VIEWS_INIT_H_ + +#include "base/memory/scoped_ptr.h" +#include "components/mus/public/cpp/view_tree_delegate.h" +#include "ui/views/views_delegate.h" + +namespace mandoline { +class AuraInit; +} + +namespace mojo { +class ApplicationImpl; +} + +// Does the necessary setup to use mus, views and the example wm. +class MUSViewsInit : public views::ViewsDelegate, public mus::ViewTreeDelegate { + public: + explicit MUSViewsInit(mojo::ApplicationImpl* app); + ~MUSViewsInit() override; + + private: + mus::View* CreateWindow(); + + // views::ViewsDelegate: + views::NativeWidget* CreateNativeWidget( + views::internal::NativeWidgetDelegate* delegate) override; + void OnBeforeWidgetInit( + views::Widget::InitParams* params, + views::internal::NativeWidgetDelegate* delegate) override; + + // mus::ViewTreeDelegate: + void OnEmbed(mus::View* root) override; + void OnConnectionLost(mus::ViewTreeConnection* connection) override; +#if defined(OS_WIN) + HICON GetSmallWindowIcon() const override; +#endif + + mojo::ApplicationImpl* app_; + + scoped_ptr<mandoline::AuraInit> aura_init_; + + DISALLOW_COPY_AND_ASSIGN(MUSViewsInit); +}; + +#endif // COMPONENTS_MUS_EXAMPLE_COMMON_MUS_VIEWS_INIT_H_
diff --git a/components/mus/example/window_type_launcher/BUILD.gn b/components/mus/example/window_type_launcher/BUILD.gn index 16b5c8c5..e2a06a22 100644 --- a/components/mus/example/window_type_launcher/BUILD.gn +++ b/components/mus/example/window_type_launcher/BUILD.gn
@@ -18,11 +18,9 @@ ] deps = [ - ":resources", "//base", - "//components/mus/example/wm:interfaces", + "//components/mus/example/common", "//mojo/application/public/cpp", - "//mandoline/ui/aura", "//mojo/application/public/cpp:sources", "//mojo/converters/geometry", "//skia", @@ -32,7 +30,6 @@ "//ui/gfx/geometry", "//ui/mojo/events:interfaces", "//ui/views", - "//ui/wm", ] resources = [ "$root_out_dir/example_resources.pak" ] @@ -41,18 +38,3 @@ "//components/mus", ] } - -repack("resources") { - sources = [ - "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", - "$root_gen_dir/ui/strings/app_locale_settings_en-US.pak", - "$root_gen_dir/ui/strings/ui_strings_en-US.pak", - "$root_gen_dir/ui/views/resources/views_resources_100_percent.pak", - ] - output = "$root_out_dir/example_resources.pak" - deps = [ - "//ui/strings", - "//ui/resources", - "//ui/views/resources", - ] -}
diff --git a/components/mus/example/window_type_launcher/window_type_launcher.cc b/components/mus/example/window_type_launcher/window_type_launcher.cc index c7c436f..f41c1dc 100644 --- a/components/mus/example/window_type_launcher/window_type_launcher.cc +++ b/components/mus/example/window_type_launcher/window_type_launcher.cc
@@ -5,11 +5,7 @@ #include "components/mus/example/window_type_launcher/window_type_launcher.h" #include "base/strings/utf_string_conversions.h" -#include "components/mus/example/wm/wm.mojom.h" -#include "components/mus/public/cpp/view_tree_connection.h" -#include "components/mus/public/cpp/view_tree_host_factory.h" -#include "mandoline/ui/aura/aura_init.h" -#include "mandoline/ui/aura/native_widget_view_manager.h" +#include "components/mus/example/common/mus_views_init.h" #include "mojo/application/public/cpp/application_connection.h" #include "mojo/application/public/cpp/application_impl.h" #include "mojo/converters/geometry/geometry_type_converters.h" @@ -26,7 +22,6 @@ #include "ui/views/layout/grid_layout.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" -#include "ui/wm/core/shadow_types.h" using views::MenuItemView; using views::MenuRunner; @@ -353,44 +348,25 @@ WindowTypeLauncher::WindowTypeLauncher() : app_(nullptr) {} WindowTypeLauncher::~WindowTypeLauncher() {} -void WindowTypeLauncher::Initialize(mojo::ApplicationImpl* app) { - app_ = app; - - mojom::WMPtr wm; - mojo::URLRequestPtr request(mojo::URLRequest::New()); - request->url = "mojo:example_wm"; - app->ConnectToService(request.Pass(), &wm); - - mojo::ViewTreeClientPtr view_tree_client; - mus::ViewTreeConnection::Create(this, GetProxy(&view_tree_client).Pass()); - wm->OpenWindow(view_tree_client.Pass()); -} - bool WindowTypeLauncher::ConfigureIncomingConnection( mojo::ApplicationConnection* connection) { return false; } -void WindowTypeLauncher::OnEmbed(mus::View* root) { - if (!aura_init_) { - aura_init_.reset( - new mandoline::AuraInit(root, app_->shell(), "example_resources.pak")); - } +void WindowTypeLauncher::Initialize(mojo::ApplicationImpl* app) { + app_ = app; + + mus_views_init_.reset(new MUSViewsInit(app)); + + // TODO(sky): total hack! This is necessary as WindowTypeLauncherView is + // created before AuraInit. WindowTypeLauncherView uses resources that are + // configured by MUSViewsInit once a View is created. By creating a Widget + // here we ensure the necessary state has been setup. + views::Widget::CreateWindow(new views::WidgetDelegateView); views::Widget* widget = new views::Widget; - // TODO(sky): make this TYPE_WINDOW. I need to fix resources in order to use - // TYPE_WINDOW. - views::Widget::InitParams params( - views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW); params.delegate = new WindowTypeLauncherView; - params.native_widget = - new mandoline::NativeWidgetViewManager(widget, app_->shell(), root); - params.bounds = root->bounds().To<gfx::Rect>(); - params.bounds.set_x(0); - params.bounds.set_y(0); widget->Init(params); widget->Show(); } - -void WindowTypeLauncher::OnConnectionLost(mus::ViewTreeConnection* connection) { -}
diff --git a/components/mus/example/window_type_launcher/window_type_launcher.h b/components/mus/example/window_type_launcher/window_type_launcher.h index f3136f3..9e763e9 100644 --- a/components/mus/example/window_type_launcher/window_type_launcher.h +++ b/components/mus/example/window_type_launcher/window_type_launcher.h
@@ -7,35 +7,25 @@ #include "base/macros.h" #include "base/memory/scoped_ptr.h" -#include "components/mus/public/cpp/view_tree_delegate.h" #include "mojo/application/public/cpp/application_delegate.h" #include "mojo/application/public/cpp/interface_factory_impl.h" -namespace mandoline { - class AuraInit; -} +class MUSViewsInit; -class WindowTypeLauncher : public mojo::ApplicationDelegate, - public mus::ViewTreeDelegate { -public: +class WindowTypeLauncher : public mojo::ApplicationDelegate { + public: WindowTypeLauncher(); ~WindowTypeLauncher() override; - // Overridden from ApplicationDelegate: - void Initialize(mojo::ApplicationImpl* app) override; - -private: + private: // ApplicationDelegate: + void Initialize(mojo::ApplicationImpl* app) override; bool ConfigureIncomingConnection( mojo::ApplicationConnection* connection) override; - // mus::ViewTreeDelegate: - void OnEmbed(mus::View* root) override; - void OnConnectionLost(mus::ViewTreeConnection* connection) override; - mojo::ApplicationImpl* app_; - scoped_ptr<mandoline::AuraInit> aura_init_; + scoped_ptr<MUSViewsInit> mus_views_init_; DISALLOW_COPY_AND_ASSIGN(WindowTypeLauncher); };
diff --git a/components/mus/gles2/command_buffer_local.cc b/components/mus/gles2/command_buffer_local.cc index bb6f854..ede0274 100644 --- a/components/mus/gles2/command_buffer_local.cc +++ b/components/mus/gles2/command_buffer_local.cc
@@ -237,6 +237,16 @@ return IsFenceSyncRelease(release); } +bool CommandBufferLocal::IsFenceSyncFlushReceived(uint64_t release) { + return IsFenceSyncRelease(release); +} + +bool CommandBufferLocal::CanWaitUnverifiedSyncToken( + const gpu::SyncToken* sync_token) { + // All sync tokens must be flushed before being waited on. + return false; +} + void CommandBufferLocal::PumpCommands() { if (!decoder_->MakeCurrent()) { command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
diff --git a/components/mus/gles2/command_buffer_local.h b/components/mus/gles2/command_buffer_local.h index 75c7bc4..54c03bf 100644 --- a/components/mus/gles2/command_buffer_local.h +++ b/components/mus/gles2/command_buffer_local.h
@@ -76,6 +76,8 @@ uint64_t GenerateFenceSyncRelease() override; bool IsFenceSyncRelease(uint64_t release) override; bool IsFenceSyncFlushed(uint64_t release) override; + bool IsFenceSyncFlushReceived(uint64_t release) override; + bool CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) override; private: void PumpCommands();
diff --git a/components/mus/public/cpp/lib/view_tree_client_impl.cc b/components/mus/public/cpp/lib/view_tree_client_impl.cc index 2a8516c2..bd2a8eb 100644 --- a/components/mus/public/cpp/lib/view_tree_client_impl.cc +++ b/components/mus/public/cpp/lib/view_tree_client_impl.cc
@@ -70,8 +70,12 @@ ViewTreeConnection* ViewTreeConnection::Create( ViewTreeDelegate* delegate, - mojo::InterfaceRequest<mojo::ViewTreeClient> request) { - return new ViewTreeClientImpl(delegate, request.Pass()); + mojo::InterfaceRequest<mojo::ViewTreeClient> request, + CreateType create_type) { + ViewTreeClientImpl* client = new ViewTreeClientImpl(delegate, request.Pass()); + if (create_type == CreateType::WAIT_FOR_EMBED) + client->WaitForEmbed(); + return client; } ViewTreeClientImpl::ViewTreeClientImpl( @@ -112,6 +116,13 @@ delegate_->OnConnectionLost(this); } +void ViewTreeClientImpl::WaitForEmbed() { + DCHECK(!root_); + // OnEmbed() is the first function called. + binding_.WaitForIncomingMethodCall(); + // TODO(sky): deal with pipe being closed before we get OnEmbed(). +} + void ViewTreeClientImpl::DestroyView(Id view_id) { DCHECK(tree_); tree_->DeleteView(view_id, ActionCompletedCallback());
diff --git a/components/mus/public/cpp/lib/view_tree_client_impl.h b/components/mus/public/cpp/lib/view_tree_client_impl.h index 95e5593..b532c735 100644 --- a/components/mus/public/cpp/lib/view_tree_client_impl.h +++ b/components/mus/public/cpp/lib/view_tree_client_impl.h
@@ -23,6 +23,9 @@ mojo::InterfaceRequest<mojo::ViewTreeClient> request); ~ViewTreeClientImpl() override; + // Wait for OnEmbed(), returning when done. + void WaitForEmbed(); + bool connected() const { return tree_; } ConnectionSpecificId connection_id() const { return connection_id_; }
diff --git a/components/mus/public/cpp/lib/view_tree_host_factory.cc b/components/mus/public/cpp/lib/view_tree_host_factory.cc index 1da65c9..4f649fe 100644 --- a/components/mus/public/cpp/lib/view_tree_host_factory.cc +++ b/components/mus/public/cpp/lib/view_tree_host_factory.cc
@@ -15,7 +15,9 @@ ViewTreeDelegate* delegate, mojo::ViewTreeHostPtr* host) { mojo::ViewTreeClientPtr tree_client; - ViewTreeConnection::Create(delegate, GetProxy(&tree_client)); + ViewTreeConnection::Create( + delegate, GetProxy(&tree_client), + ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); factory->CreateViewTreeHost(GetProxy(host), host_client.Pass(), tree_client.Pass()); }
diff --git a/components/mus/public/cpp/tests/view_manager_test_base.cc b/components/mus/public/cpp/tests/view_manager_test_base.cc index 508cd82..e4bf2ba 100644 --- a/components/mus/public/cpp/tests/view_manager_test_base.cc +++ b/components/mus/public/cpp/tests/view_manager_test_base.cc
@@ -95,7 +95,9 @@ void ViewManagerTestBase::Create( mojo::ApplicationConnection* connection, mojo::InterfaceRequest<mojo::ViewTreeClient> request) { - ViewTreeConnection::Create(this, request.Pass()); + ViewTreeConnection::Create( + this, request.Pass(), + ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } } // namespace mus
diff --git a/components/mus/public/cpp/view_tree_connection.h b/components/mus/public/cpp/view_tree_connection.h index 984e664..ee1095a0 100644 --- a/components/mus/public/cpp/view_tree_connection.h +++ b/components/mus/public/cpp/view_tree_connection.h
@@ -20,13 +20,22 @@ // every time an app is embedded. class ViewTreeConnection { public: + enum class CreateType { + // Indicates Create() should wait for OnEmbed(). If true, the + // ViewTreeConnection returned from Create() will have its root, otherwise + // the ViewTreeConnection will get the root at a later time. + WAIT_FOR_EMBED, + DONT_WAIT_FOR_EMBED + }; + virtual ~ViewTreeConnection() {} // The returned ViewTreeConnection instance owns itself, and is deleted when // the last root is destroyed or the connection to the service is broken. static ViewTreeConnection* Create( ViewTreeDelegate* delegate, - mojo::InterfaceRequest<mojo::ViewTreeClient> request); + mojo::InterfaceRequest<mojo::ViewTreeClient> request, + CreateType create_type); // Returns the root of this connection. virtual View* GetRoot() = 0;
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index 764d291..ceb54cd 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -192,6 +192,7 @@ "password_manager_metrics_util_unittest.cc", "password_manager_settings_migration_experiment_unittest.cc", "password_manager_unittest.cc", + "password_manager_util_unittest.cc", "password_store_default_unittest.cc", "password_store_unittest.cc", "password_syncable_service_unittest.cc",
diff --git a/components/password_manager/core/browser/credential_manager_pending_request_task.cc b/components/password_manager/core/browser/credential_manager_pending_request_task.cc index f51edc8..85650de 100644 --- a/components/password_manager/core/browser/credential_manager_pending_request_task.cc +++ b/components/password_manager/core/browser/credential_manager_pending_request_task.cc
@@ -7,6 +7,7 @@ #include "components/autofill/core/common/password_form.h" #include "components/password_manager/core/browser/affiliated_match_helper.h" #include "components/password_manager/core/browser/password_manager_client.h" +#include "components/password_manager/core/browser/password_manager_util.h" #include "components/password_manager/core/common/credential_manager_types.h" #include "url/gurl.h" @@ -70,6 +71,7 @@ // TODO(mkwst): This doesn't create a PasswordForm that we can use to create // a FederatedCredential (via CreatePasswordFormFromCredentialInfo). We need // to fix that. + password_manager_util::TrimUsernameOnlyCredentials(&affiliated_results); local_results.insert(local_results.end(), affiliated_results.begin(), affiliated_results.end()); affiliated_results.weak_clear();
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc index 30199b4d..f241b00 100644 --- a/components/password_manager/core/browser/login_database.cc +++ b/components/password_manager/core/browser/login_database.cc
@@ -1020,7 +1020,8 @@ base::Time::FromInternalValue(s.ColumnInt64(COLUMN_DATE_CREATED)); form->blacklisted_by_user = (s.ColumnInt(COLUMN_BLACKLISTED_BY_USER) > 0); int scheme_int = s.ColumnInt(COLUMN_SCHEME); - DCHECK((scheme_int >= 0) && (scheme_int <= PasswordForm::SCHEME_OTHER)); + DCHECK_LE(0, scheme_int); + DCHECK_GE(PasswordForm::SCHEME_LAST, scheme_int); form->scheme = static_cast<PasswordForm::Scheme>(scheme_int); int type_int = s.ColumnInt(COLUMN_PASSWORD_TYPE); DCHECK(type_int >= 0 && type_int <= PasswordForm::TYPE_GENERATED);
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc index b2bffc8..44123a0 100644 --- a/components/password_manager/core/browser/password_manager_util.cc +++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -58,4 +58,20 @@ forms->swap(unique_forms); } +void TrimUsernameOnlyCredentials( + ScopedVector<autofill::PasswordForm>* android_credentials) { + ScopedVector<autofill::PasswordForm> result; + for (auto& form : *android_credentials) { + if (form->scheme == autofill::PasswordForm::SCHEME_USERNAME_ONLY) { + if (form->federation_url.is_empty()) + continue; + else + form->skip_zero_click = true; + } + result.push_back(form); + form = nullptr; + } + android_credentials->swap(result); +} + } // namespace password_manager_util
diff --git a/components/password_manager/core/browser/password_manager_util.h b/components/password_manager/core/browser/password_manager_util.h index a9168eb..ef2517b 100644 --- a/components/password_manager/core/browser/password_manager_util.h +++ b/components/password_manager/core/browser/password_manager_util.h
@@ -37,6 +37,11 @@ ScopedVector<autofill::PasswordForm>* duplicates, std::vector<std::vector<autofill::PasswordForm*>>* tag_groups); +// Removes Android username-only credentials from |android_credentials|. +// Transforms federated credentials into non zero-click ones. +void TrimUsernameOnlyCredentials( + ScopedVector<autofill::PasswordForm>* android_credentials); + } // namespace password_manager_util #endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_MANAGER_UTIL_H_
diff --git a/components/password_manager/core/browser/password_manager_util_unittest.cc b/components/password_manager/core/browser/password_manager_util_unittest.cc new file mode 100644 index 0000000..6b29f1a --- /dev/null +++ b/components/password_manager/core/browser/password_manager_util_unittest.cc
@@ -0,0 +1,57 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/password_manager/core/browser/password_manager_util.h" + +#include "base/strings/utf_string_conversions.h" +#include "components/password_manager/core/browser/password_manager_test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +const char kTestAndroidRealm[] = "android://hash@com.example.beta.android"; +const char kTestFederationURL[] = "https://google.com/"; +const char kTestUsername[] = "Username"; +const char kTestUsername2[] = "Username2"; +const char kTestPassword[] = "12345"; + +autofill::PasswordForm GetTestAndroidCredentials(const char* signon_realm) { + autofill::PasswordForm form; + form.scheme = autofill::PasswordForm::SCHEME_HTML; + form.signon_realm = signon_realm; + form.username_value = base::ASCIIToUTF16(kTestUsername); + form.password_value = base::ASCIIToUTF16(kTestPassword); + form.ssl_valid = true; + return form; +} + +} // namespace + +using password_manager::UnorderedPasswordFormElementsAre; + +TEST(PasswordManagerUtil, TrimUsernameOnlyCredentials) { + ScopedVector<autofill::PasswordForm> forms, expected_forms; + forms.push_back( + new autofill::PasswordForm(GetTestAndroidCredentials(kTestAndroidRealm))); + expected_forms.push_back( + new autofill::PasswordForm(GetTestAndroidCredentials(kTestAndroidRealm))); + + autofill::PasswordForm username_only; + username_only.scheme = autofill::PasswordForm::SCHEME_USERNAME_ONLY; + username_only.signon_realm = kTestAndroidRealm; + username_only.username_value = base::ASCIIToUTF16(kTestUsername2); + forms.push_back(new autofill::PasswordForm(username_only)); + + username_only.federation_url = GURL(kTestFederationURL); + username_only.skip_zero_click = false; + forms.push_back(new autofill::PasswordForm(username_only)); + username_only.skip_zero_click = true; + expected_forms.push_back(new autofill::PasswordForm(username_only)); + + password_manager_util::TrimUsernameOnlyCredentials(&forms); + + EXPECT_THAT(forms.get(), + UnorderedPasswordFormElementsAre(expected_forms.get())); +}
diff --git a/components/password_manager/core/browser/password_store.cc b/components/password_manager/core/browser/password_store.cc index 8c5ed6e..8cd883d3 100644 --- a/components/password_manager/core/browser/password_store.cc +++ b/components/password_manager/core/browser/password_store.cc
@@ -12,6 +12,7 @@ #include "base/thread_task_runner_handle.h" #include "components/autofill/core/common/password_form.h" #include "components/password_manager/core/browser/affiliated_match_helper.h" +#include "components/password_manager/core/browser/password_manager_util.h" #include "components/password_manager/core/browser/password_store_consumer.h" #include "components/password_manager/core/browser/password_syncable_service.h" #include "url/origin.h" @@ -410,6 +411,7 @@ more_results.begin(), more_results.end(), [](PasswordForm* form) { return form->federation_url.is_empty(); }); more_results.erase(it_first_federated, more_results.end()); + password_manager_util::TrimUsernameOnlyCredentials(&more_results); results.insert(results.end(), more_results.begin(), more_results.end()); more_results.weak_clear(); }
diff --git a/components/password_manager/core/browser/password_store_unittest.cc b/components/password_manager/core/browser/password_store_unittest.cc index 9f29f1560..fea071ad 100644 --- a/components/password_manager/core/browser/password_store_unittest.cc +++ b/components/password_manager/core/browser/password_store_unittest.cc
@@ -501,6 +501,12 @@ "", "", L"", L"", L"", L"username_value_3b", L"", true, true, 1}, + // Third credential for the same application which is username-only. + {PasswordForm::SCHEME_USERNAME_ONLY, + kTestAndroidRealm1, + "", "", L"", L"", L"", + L"username_value_3c", + L"", true, true, 1}, // Credential for another Android application affiliated with the realm // of the observed from. {PasswordForm::SCHEME_HTML, @@ -552,7 +558,7 @@ expected_results.push_back(new PasswordForm(*all_credentials[1])); expected_results.push_back(new PasswordForm(*all_credentials[2])); expected_results.push_back(new PasswordForm(*all_credentials[3])); - expected_results.push_back(new PasswordForm(*all_credentials[4])); + expected_results.push_back(new PasswordForm(*all_credentials[5])); for (PasswordForm* result : expected_results) { if (result->signon_realm != observed_form.signon_realm && !IsValidAndroidFacetURI(result->signon_realm))
diff --git a/components/pdf_viewer/pdf_viewer.cc b/components/pdf_viewer/pdf_viewer.cc index bc5f822..01336a3d 100644 --- a/components/pdf_viewer/pdf_viewer.cc +++ b/components/pdf_viewer/pdf_viewer.cc
@@ -414,7 +414,9 @@ void Create( mojo::ApplicationConnection* connection, mojo::InterfaceRequest<mojo::ViewTreeClient> request) override { - mus::ViewTreeConnection::Create(this, request.Pass()); + mus::ViewTreeConnection::Create( + this, request.Pass(), + mus::ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } void DrawBitmap(EmbedderData* embedder_data) {
diff --git a/components/scheduler/base/task_queue_manager.cc b/components/scheduler/base/task_queue_manager.cc index df22aff..848d915 100644 --- a/components/scheduler/base/task_queue_manager.cc +++ b/components/scheduler/base/task_queue_manager.cc
@@ -94,15 +94,15 @@ queues_.erase(task_queue); selector_.RemoveQueue(task_queue.get()); - // We need to remove |task_queue| from delayed_wakeup_map_ which is a little - // awkward since it's keyed by time. O(n) running time. - for (DelayedWakeupMultimap::iterator iter = delayed_wakeup_map_.begin(); - iter != delayed_wakeup_map_.end();) { + // We need to remove |task_queue| from delayed_wakeup_multimap_ which is a + // little awkward since it's keyed by time. O(n) running time. + for (DelayedWakeupMultimap::iterator iter = delayed_wakeup_multimap_.begin(); + iter != delayed_wakeup_multimap_.end();) { if (iter->second == task_queue.get()) { DelayedWakeupMultimap::iterator temp = iter; iter++; // O(1) amortized. - delayed_wakeup_map_.erase(temp); + delayed_wakeup_multimap_.erase(temp); } else { iter++; } @@ -146,10 +146,20 @@ void TaskQueueManager::UnregisterAsUpdatableTaskQueue( internal::TaskQueueImpl* queue) { DCHECK(main_thread_checker_.CalledOnValidThread()); + MoveNewlyUpdatableQueuesIntoUpdatableQueueSet(); +#ifndef NDEBUG + { + base::AutoLock lock(newly_updatable_lock_); + DCHECK(!(updatable_queue_set_.find(queue) == updatable_queue_set_.end() && + std::find(newly_updatable_.begin(), newly_updatable_.end(), + queue) != newly_updatable_.end())); + } +#endif updatable_queue_set_.erase(queue); } void TaskQueueManager::MoveNewlyUpdatableQueuesIntoUpdatableQueueSet() { + DCHECK(main_thread_checker_.CalledOnValidThread()); base::AutoLock lock(newly_updatable_lock_); while (!newly_updatable_.empty()) { updatable_queue_set_.insert(newly_updatable_.back()); @@ -168,14 +178,7 @@ // Move any ready delayed tasks into the incomming queues. WakeupReadyDelayedQueues(&lazy_now); - // Insert any newly updatable queues into the updatable_queue_set_. - { - base::AutoLock lock(newly_updatable_lock_); - while (!newly_updatable_.empty()) { - updatable_queue_set_.insert(newly_updatable_.back()); - newly_updatable_.pop_back(); - } - } + MoveNewlyUpdatableQueuesIntoUpdatableQueueSet(); auto iter = updatable_queue_set_.begin(); while (iter != updatable_queue_set_.end()) { @@ -213,13 +216,14 @@ // Make sure there's one (and only one) task posted to |main_task_runner_| // to call |DelayedDoWork| at |delayed_run_time|. - if (delayed_wakeup_map_.find(delayed_run_time) == delayed_wakeup_map_.end()) { + if (delayed_wakeup_multimap_.find(delayed_run_time) == + delayed_wakeup_multimap_.end()) { base::TimeDelta delay = std::max(base::TimeDelta(), delayed_run_time - lazy_now->Now()); main_task_runner_->PostDelayedTask(FROM_HERE, delayed_queue_wakeup_closure_, delay); } - delayed_wakeup_map_.insert(std::make_pair(delayed_run_time, queue)); + delayed_wakeup_multimap_.insert(std::make_pair(delayed_run_time, queue)); } void TaskQueueManager::DelayedDoWork() { @@ -238,8 +242,9 @@ // the elements sorted by key, so the begin() iterator points to the earliest // queue to wakeup. std::set<internal::TaskQueueImpl*> dedup_set; - while (!delayed_wakeup_map_.empty()) { - DelayedWakeupMultimap::iterator next_wakeup = delayed_wakeup_map_.begin(); + while (!delayed_wakeup_multimap_.empty()) { + DelayedWakeupMultimap::iterator next_wakeup = + delayed_wakeup_multimap_.begin(); if (next_wakeup->first > lazy_now->Now()) break; // A queue could have any number of delayed tasks pending so it's worthwhile @@ -249,7 +254,7 @@ // queue to execute a task from. if (dedup_set.insert(next_wakeup->second).second) next_wakeup->second->MoveReadyDelayedTasksToIncomingQueue(lazy_now); - delayed_wakeup_map_.erase(next_wakeup); + delayed_wakeup_multimap_.erase(next_wakeup); } }
diff --git a/components/scheduler/base/task_queue_manager.h b/components/scheduler/base/task_queue_manager.h index ee305d4..404f71c 100644 --- a/components/scheduler/base/task_queue_manager.h +++ b/components/scheduler/base/task_queue_manager.h
@@ -221,7 +221,7 @@ typedef std::multimap<base::TimeTicks, internal::TaskQueueImpl*> DelayedWakeupMultimap; - DelayedWakeupMultimap delayed_wakeup_map_; + DelayedWakeupMultimap delayed_wakeup_multimap_; base::AtomicSequenceNumber task_sequence_num_; base::debug::TaskAnnotator task_annotator_;
diff --git a/components/scheduler/child/web_task_runner_impl.cc b/components/scheduler/child/web_task_runner_impl.cc index b4794a4c..56591ac4 100644 --- a/components/scheduler/child/web_task_runner_impl.cc +++ b/components/scheduler/child/web_task_runner_impl.cc
@@ -36,4 +36,8 @@ base::TimeDelta::FromMillisecondsD(delayMs)); } +blink::WebTaskRunner* WebTaskRunnerImpl::clone() { + return new WebTaskRunnerImpl(task_runner_); +} + } // namespace scheduler
diff --git a/components/scheduler/child/web_task_runner_impl.h b/components/scheduler/child/web_task_runner_impl.h index 73a1e46f..c9cc55d 100644 --- a/components/scheduler/child/web_task_runner_impl.h +++ b/components/scheduler/child/web_task_runner_impl.h
@@ -34,6 +34,7 @@ void postDelayedTask(const blink::WebTraceLocation& web_location, blink::WebTaskRunner::Task* task, double delayMs) override; + blink::WebTaskRunner* clone() override; private: scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/components/tracing.gyp b/components/tracing.gyp index 8bf23d2..93f7074c 100644 --- a/components/tracing.gyp +++ b/components/tracing.gyp
@@ -30,6 +30,8 @@ 'tracing/child_memory_dump_manager_delegate_impl.h', 'tracing/child_trace_message_filter.cc', 'tracing/child_trace_message_filter.h', + 'tracing/graphics_memory_dump_provider_android.cc', + 'tracing/graphics_memory_dump_provider_android.h', 'tracing/trace_config_file.cc', 'tracing/trace_config_file.h', 'tracing/tracing_export.h',
diff --git a/components/tracing/BUILD.gn b/components/tracing/BUILD.gn index 92e50c43..b8ab5a9 100644 --- a/components/tracing/BUILD.gn +++ b/components/tracing/BUILD.gn
@@ -8,6 +8,8 @@ "child_memory_dump_manager_delegate_impl.h", "child_trace_message_filter.cc", "child_trace_message_filter.h", + "graphics_memory_dump_provider_android.cc", + "graphics_memory_dump_provider_android.h", "tracing_export.h", "tracing_messages.cc", "tracing_messages.h",
diff --git a/components/tracing/graphics_memory_dump_provider_android.cc b/components/tracing/graphics_memory_dump_provider_android.cc new file mode 100644 index 0000000..dcafe402 --- /dev/null +++ b/components/tracing/graphics_memory_dump_provider_android.cc
@@ -0,0 +1,140 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/tracing/graphics_memory_dump_provider_android.h" + +#include <fcntl.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/un.h> + +#include "base/files/scoped_file.h" +#include "base/posix/eintr_wrapper.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_tokenizer.h" +#include "base/trace_event/process_memory_dump.h" +#include "base/trace_event/process_memory_totals.h" + +using base::trace_event::MemoryAllocatorDump; + +namespace tracing { + +// static +const char GraphicsMemoryDumpProvider::kDumpBaseName[] = + "gpu/android_memtrack/"; + +// static +GraphicsMemoryDumpProvider* GraphicsMemoryDumpProvider::GetInstance() { + return base::Singleton< + GraphicsMemoryDumpProvider, + base::LeakySingletonTraits<GraphicsMemoryDumpProvider>>::get(); +} + +bool GraphicsMemoryDumpProvider::OnMemoryDump( + const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) { + const char kAbstractSocketName[] = "chrome_tracing_memtrack_helper"; + struct sockaddr_un addr; + + const int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0); + if (sock == -1) + return false; + // Ensures that sock is always closed, even in case of early returns. + base::ScopedFD sock_closer(sock); + + // Set recv() timeout to 250 ms. + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 250000; + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + + // Connect to the UNIX abstract (i.e. no physical filesystem link) socket. + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(&addr.sun_path[1], kAbstractSocketName, sizeof(addr.sun_path) - 2); + + if (connect(sock, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr))) { + LOG(WARNING) << "Could not connect to the memtrack_helper daemon. Please " + "build memtrack_helper, adb push to the device and run it " + "before starting the trace to get graphics memory data."; + return false; + } + + // Check that the socket is owned by root (the memtrack_helper) process and + // not an (untrusted) user process. + struct ucred cred; + socklen_t cred_len = sizeof(cred); + if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len) < 0 || + (static_cast<unsigned>(cred_len) < sizeof(cred)) || + cred.uid != 0 /* root */) { + LOG(WARNING) << "Untrusted (!= root) memtrack_helper daemon detected."; + return false; + } + + // Send the trace(PID) request. + char buf[4096]; + const int buf_pid_len = snprintf(buf, sizeof(buf) - 1, "%d", getpid()); + if (HANDLE_EINTR(send(sock, buf, buf_pid_len + 1, 0)) <= 0) + return false; + + // The response consists of a few lines, each one with a key value pair. E.g.: + // graphics_total 10616832 + // graphics_pss 10616832 + // gl_total 17911808 + // gl_pss 17911808 + ssize_t rsize; + if ((rsize = HANDLE_EINTR(recv(sock, buf, sizeof(buf), 0))) <= 0) + return false; + + buf[sizeof(buf) - 1] = '\0'; + ParseResponseAndAddToDump(buf, static_cast<size_t>(rsize), pmd); + return true; +} + +void GraphicsMemoryDumpProvider::ParseResponseAndAddToDump( + const char* response, + size_t length, + base::trace_event::ProcessMemoryDump* pmd) { + base::CStringTokenizer tokenizer(response, response + length, " \n"); + while (true) { + if (!tokenizer.GetNext()) + break; + base::StringPiece row_name = tokenizer.token_piece(); + if (!tokenizer.GetNext()) + break; + base::StringPiece value_str = tokenizer.token_piece(); + int64_t value; + if (!base::StringToInt64(value_str, &value) || value < 0) + continue; // Skip invalid or negative values. + + // Turn entries like graphics_total into a row named "graphics" and + // column named "total". + std::string column_name = "memtrack_"; + size_t key_split_point = row_name.find_last_of('_'); + if (key_split_point > 0 && key_split_point < row_name.size() - 1) { + row_name.substr(key_split_point + 1).AppendToString(&column_name); + row_name = row_name.substr(0, key_split_point); + } else { + column_name += "unknown"; + } + + // Append a row to the memory dump. + std::string dump_name; + dump_name.reserve(arraysize(kDumpBaseName) + row_name.size() + 1); + dump_name.assign(kDumpBaseName); + row_name.AppendToString(&dump_name); + MemoryAllocatorDump* mad = pmd->GetOrCreateAllocatorDump(dump_name); + const auto& long_lived_column_name = key_names_.insert(column_name).first; + mad->AddScalar(long_lived_column_name->c_str(), + MemoryAllocatorDump::kUnitsBytes, value); + } +} + +GraphicsMemoryDumpProvider::GraphicsMemoryDumpProvider() {} + +GraphicsMemoryDumpProvider::~GraphicsMemoryDumpProvider() {} + +} // namespace tracing
diff --git a/components/tracing/graphics_memory_dump_provider_android.h b/components/tracing/graphics_memory_dump_provider_android.h new file mode 100644 index 0000000..3a9aa65 --- /dev/null +++ b/components/tracing/graphics_memory_dump_provider_android.h
@@ -0,0 +1,52 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_TRACING_GRAPHICS_MEMORY_DUMP_PROVIDER_ANDROID_H_ +#define COMPONENTS_TRACING_GRAPHICS_MEMORY_DUMP_PROVIDER_ANDROID_H_ + +#include <string> + +#include "base/containers/hash_tables.h" +#include "base/memory/singleton.h" +#include "base/trace_event/memory_dump_provider.h" +#include "components/tracing/tracing_export.h" + +namespace tracing { + +// Dump provider which collects memory stats about graphics memory on Android. +// This requires the presence of the memtrack_helper daemon, which must be +// executed separetely via a (root) adb shell command. The dump provider will +// fail (and hence disabled by the MemoryDumpManager) in absence of the helper. +// See the design-doc https://goo.gl/4Y30p9 for more details. +class TRACING_EXPORT GraphicsMemoryDumpProvider + : public base::trace_event::MemoryDumpProvider { + public: + static GraphicsMemoryDumpProvider* GetInstance(); + + // MemoryDumpProvider implementation. + bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, + base::trace_event::ProcessMemoryDump* pmd) override; + + private: + friend struct base::DefaultSingletonTraits<GraphicsMemoryDumpProvider>; + + void ParseResponseAndAddToDump(const char* buf, + size_t length, + base::trace_event::ProcessMemoryDump* pmd); + + GraphicsMemoryDumpProvider(); + ~GraphicsMemoryDumpProvider() override; + + static const char kDumpBaseName[]; // Used by the unittest. + + // Stores key names coming from the memtrack helper in long-lived storage. + // This is to allow using cheap char* strings in tracing without copies. + base::hash_set<std::string> key_names_; + + DISALLOW_COPY_AND_ASSIGN(GraphicsMemoryDumpProvider); +}; + +} // namespace tracing + +#endif // COMPONENTS_TRACING_GRAPHICS_MEMORY_DUMP_PROVIDER_ANDROID_H_
diff --git a/components/web_view/frame_apptest.cc b/components/web_view/frame_apptest.cc index 40c31bf..915e1b52 100644 --- a/components/web_view/frame_apptest.cc +++ b/components/web_view/frame_apptest.cc
@@ -383,9 +383,13 @@ mojo::ApplicationConnection* connection, mojo::InterfaceRequest<mojo::ViewTreeClient> request) override { if (view_and_frame_) { - mus::ViewTreeConnection::Create(view_and_frame_.get(), request.Pass()); + mus::ViewTreeConnection::Create( + view_and_frame_.get(), request.Pass(), + mus::ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } else { - mus::ViewTreeConnection::Create(this, request.Pass()); + mus::ViewTreeConnection::Create( + this, request.Pass(), + mus::ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } }
diff --git a/components/web_view/web_view_impl.cc b/components/web_view/web_view_impl.cc index 4bd3485..f11e812 100644 --- a/components/web_view/web_view_impl.cc +++ b/components/web_view/web_view_impl.cc
@@ -111,7 +111,9 @@ void WebViewImpl::GetViewTreeClient( mojo::InterfaceRequest<mojo::ViewTreeClient> view_tree_client) { - mus::ViewTreeConnection::Create(this, view_tree_client.Pass()); + mus::ViewTreeConnection::Create( + this, view_tree_client.Pass(), + mus::ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } void WebViewImpl::Find(int32_t request_id, const mojo::String& search_text) {
diff --git a/content/browser/blob_storage/blob_storage_registry_unittest.cc b/content/browser/blob_storage/blob_storage_registry_unittest.cc new file mode 100644 index 0000000..9ff10d6 --- /dev/null +++ b/content/browser/blob_storage/blob_storage_registry_unittest.cc
@@ -0,0 +1,87 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "storage/browser/blob/blob_storage_registry.h" + +#include "base/callback.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace storage { +namespace { +using Entry = BlobStorageRegistry::Entry; +using BlobState = BlobStorageRegistry::BlobState; + +TEST(BlobStorageRegistry, UUIDRegistration) { + const std::string kBlob1 = "Blob1"; + BlobStorageRegistry registry; + + EXPECT_FALSE(registry.DeleteEntry(kBlob1)); + EXPECT_EQ(0u, registry.blob_count()); + + Entry* entry = registry.CreateEntry(kBlob1); + ASSERT_NE(nullptr, entry); + EXPECT_EQ(BlobState::RESERVED, entry->state); + EXPECT_EQ(1u, entry->refcount); + EXPECT_FALSE(entry->exceeded_memory); + EXPECT_FALSE(entry->data.get() || entry->data_builder.get()); + EXPECT_EQ(0u, entry->construction_complete_callbacks.size()); + + EXPECT_EQ(entry, registry.GetEntry(kBlob1)); + EXPECT_TRUE(registry.DeleteEntry(kBlob1)); + entry = registry.CreateEntry(kBlob1); + + EXPECT_TRUE(entry->TestAndSetState(BlobState::RESERVED, + BlobState::ASYNC_TRANSPORTATION)); + EXPECT_FALSE( + entry->TestAndSetState(BlobState::CONSTRUCTION, BlobState::RESERVED)); + EXPECT_FALSE(entry->TestAndSetState(BlobState::ACTIVE, BlobState::RESERVED)); + EXPECT_TRUE(entry->TestAndSetState(BlobState::ASYNC_TRANSPORTATION, + BlobState::CONSTRUCTION)); + EXPECT_EQ(BlobState::CONSTRUCTION, entry->state); + EXPECT_EQ(1u, registry.blob_count()); +} + +TEST(BlobStorageRegistry, URLRegistration) { + const std::string kBlob = "Blob1"; + const std::string kBlob2 = "Blob2"; + const GURL kURL = GURL("blob://Blob1"); + const GURL kURL2 = GURL("blob://Blob2"); + BlobStorageRegistry registry; + + EXPECT_FALSE(registry.IsURLMapped(kURL)); + EXPECT_EQ(nullptr, registry.GetEntryFromURL(kURL, nullptr)); + EXPECT_FALSE(registry.DeleteURLMapping(kURL, nullptr)); + EXPECT_FALSE(registry.CreateUrlMapping(kURL, kBlob)); + EXPECT_EQ(0u, registry.url_count()); + Entry* entry = registry.CreateEntry(kBlob); + + EXPECT_FALSE(registry.IsURLMapped(kURL)); + EXPECT_TRUE(registry.CreateUrlMapping(kURL, kBlob)); + EXPECT_FALSE(registry.CreateUrlMapping(kURL, kBlob2)); + + EXPECT_TRUE(registry.IsURLMapped(kURL)); + EXPECT_EQ(entry, registry.GetEntryFromURL(kURL, nullptr)); + std::string uuid; + EXPECT_EQ(entry, registry.GetEntryFromURL(kURL, &uuid)); + EXPECT_EQ(kBlob, uuid); + EXPECT_EQ(1u, registry.url_count()); + + registry.CreateEntry(kBlob2); + EXPECT_TRUE(registry.CreateUrlMapping(kURL2, kBlob2)); + EXPECT_EQ(2u, registry.url_count()); + EXPECT_TRUE(registry.DeleteURLMapping(kURL2, &uuid)); + EXPECT_EQ(kBlob2, uuid); + EXPECT_FALSE(registry.IsURLMapped(kURL2)); + + // Both urls point to the same blob. + EXPECT_TRUE(registry.CreateUrlMapping(kURL2, kBlob)); + std::string uuid2; + EXPECT_EQ(registry.GetEntryFromURL(kURL, &uuid), + registry.GetEntryFromURL(kURL2, &uuid2)); + EXPECT_EQ(uuid, uuid2); +} + +} // namespace +} // namespace storage
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index f1f28187..83e1917 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -88,6 +88,7 @@ #if defined(OS_ANDROID) #include "base/android/jni_android.h" +#include "components/tracing/graphics_memory_dump_provider_android.h" #include "content/browser/android/browser_startup_controller.h" #include "content/browser/android/browser_surface_texture_manager.h" #include "content/browser/android/in_process_surface_texture_manager.h" @@ -1162,7 +1163,6 @@ #if !defined(OS_IOS) HistogramSynchronizer::GetInstance(); - #if defined(OS_ANDROID) // Up the priority of the UI thread. base::PlatformThread::SetCurrentThreadPriority(base::ThreadPriority::DISPLAY); @@ -1194,6 +1194,10 @@ // BrowserProcessSubThread::IOThreadPreCleanUp). base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( BrowserGpuMemoryBufferManager::current(), io_thread_->task_runner()); +#if defined(OS_ANDROID) + base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( + tracing::GraphicsMemoryDumpProvider::GetInstance()); +#endif { TRACE_EVENT0("startup", "BrowserThreadsStarted::Subsystem:AudioMan");
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 1899fbe..6263bcb7 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -1532,8 +1532,8 @@ if (rfh->GetSiteInstance()->GetSiteURL().SchemeIs(kGuestScheme)) return false; - GURL effective_url = SiteInstanceImpl::GetEffectiveURL( - rfh->GetSiteInstance()->GetBrowserContext(), dest_url); + BrowserContext* context = rfh->GetSiteInstance()->GetBrowserContext(); + GURL effective_url = SiteInstanceImpl::GetEffectiveURL(context, dest_url); // TODO(nasko, nick): These following --site-per-process checks are // overly simplistic. Update them to match all the cases @@ -1547,7 +1547,8 @@ // The sites differ. If either one requires a dedicated process, // then a transfer is needed. return rfh->GetSiteInstance()->RequiresDedicatedProcess() || - SiteIsolationPolicy::DoesSiteRequireDedicatedProcess(effective_url); + SiteInstanceImpl::DoesSiteRequireDedicatedProcess(context, + effective_url); } SiteInstance* RenderFrameHostManager::ConvertToSiteInstance(
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc index cd5ac038..46751c2 100644 --- a/content/browser/site_instance_impl.cc +++ b/content/browser/site_instance_impl.cc
@@ -213,7 +213,8 @@ bool SiteInstanceImpl::RequiresDedicatedProcess() { if (!has_site_) return false; - return SiteIsolationPolicy::DoesSiteRequireDedicatedProcess(site_); + return SiteInstanceImpl::DoesSiteRequireDedicatedProcess(GetBrowserContext(), + site_); } void SiteInstanceImpl::IncrementRelatedActiveContentsCount() { @@ -233,12 +234,12 @@ return browsing_instance_->browser_context(); } -/*static*/ +// static SiteInstance* SiteInstance::Create(BrowserContext* browser_context) { return new SiteInstanceImpl(new BrowsingInstance(browser_context)); } -/*static*/ +// static SiteInstance* SiteInstance::CreateForURL(BrowserContext* browser_context, const GURL& url) { // This will create a new SiteInstance and BrowsingInstance. @@ -247,7 +248,7 @@ return instance->GetSiteInstanceForURL(url); } -/*static*/ +// static bool SiteInstance::IsSameWebSite(BrowserContext* browser_context, const GURL& real_src_url, const GURL& real_dest_url) { @@ -287,7 +288,7 @@ net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); } -/*static*/ +// static GURL SiteInstance::GetSiteForURL(BrowserContext* browser_context, const GURL& real_url) { // TODO(fsamuel, creis): For some reason appID is not recognized as a host. @@ -332,13 +333,31 @@ return GURL(); } -/*static*/ +// static GURL SiteInstanceImpl::GetEffectiveURL(BrowserContext* browser_context, const GURL& url) { return GetContentClient()->browser()-> GetEffectiveURL(browser_context, url); } +// static +bool SiteInstanceImpl::DoesSiteRequireDedicatedProcess( + BrowserContext* browser_context, + const GURL& effective_url) { + // If --site-per-process is enabled, site isolation is enabled everywhere. + if (SiteIsolationPolicy::UseDedicatedProcessesForAllSites()) + return true; + + // Let the content embedder enable site isolation for specific URLs. + if (GetContentClient()->IsSupplementarySiteIsolationModeEnabled() && + GetContentClient()->browser()->DoesSiteRequireDedicatedProcess( + browser_context, effective_url)) { + return true; + } + + return false; +} + void SiteInstanceImpl::RenderProcessHostDestroyed(RenderProcessHost* host) { DCHECK_EQ(process_, host); process_->RemoveObserver(this); @@ -350,7 +369,7 @@ // protection. If only some sites are isolated, we need additional logic to // prevent the non-isolated sites from requesting resources for isolated // sites. https://crbug.com/509125 - if (SiteIsolationPolicy::DoesSiteRequireDedicatedProcess(site_)) { + if (RequiresDedicatedProcess()) { // Guest processes cannot be locked to its site because guests always have // a fixed SiteInstance. The site of GURLs a guest loads doesn't match that // SiteInstance. So we skip locking the guest process to the site.
diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h index 8c4b8ed..152c3f12 100644 --- a/content/browser/site_instance_impl.h +++ b/content/browser/site_instance_impl.h
@@ -85,6 +85,15 @@ static GURL GetEffectiveURL(BrowserContext* browser_context, const GURL& url); + // Returns true if pages loaded from |effective_url| ought to be handled only + // by a renderer process isolated from other sites. If --site-per-process is + // on the command line, this is true for all sites. In other site isolation + // modes, only a subset of sites will require dedicated processes. + // + // |effective_url| must be an effective URL. + static bool DoesSiteRequireDedicatedProcess(BrowserContext* browser_context, + const GURL& effective_url); + protected: friend class BrowsingInstance; friend class SiteInstance;
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc index c8f4168..3b26b61 100644 --- a/content/child/blink_platform_impl.cc +++ b/content/child/blink_platform_impl.cc
@@ -34,6 +34,7 @@ #include "blink/public/resources/grit/blink_image_resources.h" #include "blink/public/resources/grit/blink_resources.h" #include "components/mime_util/mime_util.h" +#include "components/scheduler/child/web_task_runner_impl.h" #include "components/scheduler/child/webthread_impl_for_worker_scheduler.h" #include "content/app/resources/grit/content_resources.h" #include "content/app/strings/grit/content_strings.h" @@ -478,7 +479,8 @@ // data URLs to bypass the ResourceDispatcher. return new WebURLLoaderImpl( child_thread ? child_thread->resource_dispatcher() : NULL, - MainTaskRunnerForCurrentThread()); + make_scoped_ptr(new scheduler::WebTaskRunnerImpl( + base::ThreadTaskRunnerHandle::Get()))); } blink::WebSocketHandle* BlinkPlatformImpl::createWebSocketHandle() { @@ -1363,16 +1365,6 @@ return base::trace_event::TraceLog::GetInstance()->process_id(); } -scoped_refptr<base::SingleThreadTaskRunner> -BlinkPlatformImpl::MainTaskRunnerForCurrentThread() { - if (main_thread_task_runner_.get() && - main_thread_task_runner_->BelongsToCurrentThread()) { - return main_thread_task_runner_; - } else { - return base::ThreadTaskRunnerHandle::Get(); - } -} - bool BlinkPlatformImpl::IsMainThread() const { return main_thread_task_runner_.get() && main_thread_task_runner_->BelongsToCurrentThread();
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h index 4ec1659..f9bf754b9 100644 --- a/content/child/blink_platform_impl.h +++ b/content/child/blink_platform_impl.h
@@ -195,8 +195,6 @@ bool IsMainThread() const; - scoped_refptr<base::SingleThreadTaskRunner> MainTaskRunnerForCurrentThread(); - scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; WebThemeEngineImpl native_theme_engine_; WebFallbackThemeEngineImpl fallback_theme_engine_;
diff --git a/content/child/request_info.cc b/content/child/request_info.cc index b115b7d..2af34cd5d 100644 --- a/content/child/request_info.cc +++ b/content/child/request_info.cc
@@ -27,7 +27,8 @@ enable_upload_progress(false), do_not_prompt_for_login(false), report_raw_headers(false), - extra_data(NULL) {} + extra_data(NULL), + loading_web_task_runner(nullptr) {} RequestInfo::~RequestInfo() {}
diff --git a/content/child/request_info.h b/content/child/request_info.h index e610ac8..037c1db 100644 --- a/content/child/request_info.h +++ b/content/child/request_info.h
@@ -17,9 +17,14 @@ #include "content/public/common/resource_type.h" #include "net/base/request_priority.h" #include "third_party/WebKit/public/platform/WebReferrerPolicy.h" +#include "third_party/WebKit/public/platform/WebTaskRunner.h" #include "third_party/WebKit/public/platform/WebURLRequest.h" #include "url/gurl.h" +namespace blink { +class WebTaskRunner; +} // namespace blink + namespace content { // Structure used when calling BlinkPlatformImpl::CreateResourceLoader(). @@ -110,6 +115,9 @@ // Extra data associated with this request. We do not own this pointer. blink::WebURLRequest::ExtraData* extra_data; + // Optional, the specific task queue to execute loading tasks on. + scoped_ptr<blink::WebTaskRunner> loading_web_task_runner; + private: DISALLOW_COPY_AND_ASSIGN(RequestInfo); };
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc index 684f3ee..0c990721 100644 --- a/content/child/resource_dispatcher.cc +++ b/content/child/resource_dispatcher.cc
@@ -18,6 +18,7 @@ #include "base/strings/string_util.h" #include "content/child/request_extra_data.h" #include "content/child/request_info.h" +#include "content/child/resource_scheduling_filter.h" #include "content/child/shared_memory_received_data_factory.h" #include "content/child/site_isolation_stats_gatherer.h" #include "content/child/sync_load_response.h" @@ -414,6 +415,9 @@ new ResourceHostMsg_ReleaseDownloadedFile(request_id)); } + if (resource_scheduling_filter_.get()) + resource_scheduling_filter_->ClearRequestIdTaskRunner(request_id); + return true; } @@ -599,6 +603,13 @@ request->url, request_info.download_to_file); + if (resource_scheduling_filter_.get() && + request_info.loading_web_task_runner) { + resource_scheduling_filter_->SetRequestIdTaskRunner( + request_id, + make_scoped_ptr(request_info.loading_web_task_runner->clone())); + } + message_sender_->Send(new ResourceHostMsg_RequestResource( request_info.routing_id, request_id, *request)); @@ -805,4 +816,9 @@ return request.Pass(); } +void ResourceDispatcher::SetResourceSchedulingFilter( + scoped_refptr<ResourceSchedulingFilter> resource_scheduling_filter) { + resource_scheduling_filter_ = resource_scheduling_filter; +} + } // namespace content
diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h index 864b081..05500f5 100644 --- a/content/child/resource_dispatcher.h +++ b/content/child/resource_dispatcher.h
@@ -39,6 +39,7 @@ class RequestPeer; class ResourceDispatcherDelegate; class ResourceRequestBody; +class ResourceSchedulingFilter; class ThreadedDataProvider; struct ResourceResponseInfo; struct RequestInfo; @@ -129,6 +130,9 @@ main_thread_task_runner_ = main_thread_task_runner; } + void SetResourceSchedulingFilter( + scoped_refptr<ResourceSchedulingFilter> resource_scheduling_filter); + private: friend class ResourceDispatcherTest; @@ -249,6 +253,7 @@ base::TimeTicks io_timestamp_; scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; + scoped_refptr<ResourceSchedulingFilter> resource_scheduling_filter_; base::WeakPtrFactory<ResourceDispatcher> weak_factory_;
diff --git a/content/child/resource_scheduling_filter.cc b/content/child/resource_scheduling_filter.cc index 843cd871..6445c00 100644 --- a/content/child/resource_scheduling_filter.cc +++ b/content/child/resource_scheduling_filter.cc
@@ -9,9 +9,32 @@ #include "content/child/resource_dispatcher.h" #include "ipc/ipc_message.h" #include "ipc/ipc_message_start.h" +#include "third_party/WebKit/public/platform/WebTaskRunner.h" +#include "third_party/WebKit/public/platform/WebTraceLocation.h" namespace content { +namespace { +class DispatchMessageTask : public blink::WebTaskRunner::Task { + public: + DispatchMessageTask( + base::WeakPtr<ResourceSchedulingFilter> resource_scheduling_filter, + const IPC::Message& message) + : resource_scheduling_filter_(resource_scheduling_filter), + message_(message) {} + + void run() override { + if (!resource_scheduling_filter_.get()) + return; + resource_scheduling_filter_->DispatchMessage(message_); + } + + private: + base::WeakPtr<ResourceSchedulingFilter> resource_scheduling_filter_; + const IPC::Message message_; +}; +} // namespace + ResourceSchedulingFilter::ResourceSchedulingFilter( const scoped_refptr<base::SingleThreadTaskRunner>& main_thread_task_runner, ResourceDispatcher* resource_dispatcher) @@ -26,12 +49,42 @@ } bool ResourceSchedulingFilter::OnMessageReceived(const IPC::Message& message) { - main_thread_task_runner_->PostTask( - FROM_HERE, base::Bind(&ResourceSchedulingFilter::DispatchMessage, - weak_ptr_factory_.GetWeakPtr(), message)); + base::AutoLock lock(request_id_to_task_runner_map_lock_); + int request_id; + + base::PickleIterator pickle_iterator(message); + if (!pickle_iterator.ReadInt(&request_id)) { + NOTREACHED() << "malformed resource message"; + return true; + } + // Dispatch the message on the request id specific task runner, if there is + // one, or on the general main_thread_task_runner if there isn't. + RequestIdToTaskRunnerMap::const_iterator iter = + request_id_to_task_runner_map_.find(request_id); + if (iter != request_id_to_task_runner_map_.end()) { + // TODO(alexclarke): Find a way to let blink and chromium FROM_HERE coexist. + iter->second->postTask( + blink::WebTraceLocation(__FUNCTION__, __FILE__), + new DispatchMessageTask(weak_ptr_factory_.GetWeakPtr(), message)); + } else { + main_thread_task_runner_->PostTask( + FROM_HERE, base::Bind(&ResourceSchedulingFilter::DispatchMessage, + weak_ptr_factory_.GetWeakPtr(), message)); + } return true; } +void ResourceSchedulingFilter::SetRequestIdTaskRunner( + int id, scoped_ptr<blink::WebTaskRunner> web_task_runner) { + base::AutoLock lock(request_id_to_task_runner_map_lock_); + request_id_to_task_runner_map_.insert(id, web_task_runner.Pass()); +} + +void ResourceSchedulingFilter::ClearRequestIdTaskRunner(int id) { + base::AutoLock lock(request_id_to_task_runner_map_lock_); + request_id_to_task_runner_map_.erase(id); +} + bool ResourceSchedulingFilter::GetSupportedMessageClasses( std::vector<uint32>* supported_message_classes) const { supported_message_classes->push_back(ResourceMsgStart);
diff --git a/content/child/resource_scheduling_filter.h b/content/child/resource_scheduling_filter.h index 7ea73c90..fd245592 100644 --- a/content/child/resource_scheduling_filter.h +++ b/content/child/resource_scheduling_filter.h
@@ -5,12 +5,19 @@ #ifndef CONTENT_CHILD_RESOURCE_SCHEDULING_FILTER_H_ #define CONTENT_CHILD_RESOURCE_SCHEDULING_FILTER_H_ +#include <map> + #include "base/containers/hash_tables.h" +#include "base/containers/scoped_ptr_map.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "content/common/content_export.h" #include "ipc/message_filter.h" +namespace blink { +class WebTaskRunner; +} + namespace content { class ResourceDispatcher; @@ -28,11 +35,25 @@ bool GetSupportedMessageClasses( std::vector<uint32>* supported_message_classes) const override; - protected: - ~ResourceSchedulingFilter() override; + // Sets the task runner associated with request messages with |id|. + void SetRequestIdTaskRunner( + int id, scoped_ptr<blink::WebTaskRunner> web_task_runner); + + // Removes the task runner associated with |id|. + void ClearRequestIdTaskRunner(int id); void DispatchMessage(const IPC::Message& message); + private: + ~ResourceSchedulingFilter() override; + + typedef base::ScopedPtrMap<int, scoped_ptr<blink::WebTaskRunner>> + RequestIdToTaskRunnerMap; + + // This lock guards |request_id_to_task_runner_map_| + base::Lock request_id_to_task_runner_map_lock_; + RequestIdToTaskRunnerMap request_id_to_task_runner_map_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; ResourceDispatcher* resource_dispatcher_; // NOT OWNED base::WeakPtrFactory<ResourceSchedulingFilter> weak_ptr_factory_;
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc index bf669cc..68851d4 100644 --- a/content/child/web_url_loader_impl.cc +++ b/content/child/web_url_loader_impl.cc
@@ -16,6 +16,7 @@ #include "base/strings/string_util.h" #include "base/time/time.h" #include "components/mime_util/mime_util.h" +#include "components/scheduler/child/web_task_runner_impl.h" #include "content/child/child_thread_impl.h" #include "content/child/ftp_directory_listing_response_delegate.h" #include "content/child/multipart_response_delegate.h" @@ -42,6 +43,7 @@ #include "net/ssl/ssl_connection_status_flags.h" #include "net/url_request/url_request_data_job.h" #include "third_party/WebKit/public/platform/WebHTTPLoadInfo.h" +#include "third_party/WebKit/public/platform/WebTraceLocation.h" #include "third_party/WebKit/public/platform/WebURL.h" #include "third_party/WebKit/public/platform/WebURLError.h" #include "third_party/WebKit/public/platform/WebURLLoadTiming.h" @@ -254,7 +256,7 @@ public: Context(WebURLLoaderImpl* loader, ResourceDispatcher* resource_dispatcher, - scoped_refptr<base::SingleThreadTaskRunner> task_runner); + scoped_ptr<blink::WebTaskRunner> task_runner); WebURLLoaderClient* client() const { return client_; } void set_client(WebURLLoaderClient* client) { client_ = client; } @@ -267,6 +269,7 @@ blink::WebThreadedDataReceiver* threaded_data_receiver); void Start(const WebURLRequest& request, SyncLoadResponse* sync_load_response); + void SetWebTaskRunner(scoped_ptr<blink::WebTaskRunner> task_runner); // RequestPeer methods: void OnUploadProgress(uint64 position, uint64 size) override; @@ -295,6 +298,19 @@ friend class base::RefCounted<Context>; ~Context() override; + class HandleDataURLTask : public blink::WebTaskRunner::Task { + public: + explicit HandleDataURLTask(scoped_refptr<Context> context) + : context_(context) {} + + void run() override { + context_->HandleDataURL(); + } + + private: + scoped_refptr<Context> context_; + }; + // Called when the body data stream is detached from the reader side. void CancelBodyStreaming(); // We can optimize the handling of data URLs in most cases. @@ -305,7 +321,7 @@ WebURLRequest request_; WebURLLoaderClient* client_; ResourceDispatcher* resource_dispatcher_; - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + scoped_ptr<blink::WebTaskRunner> web_task_runner_; WebReferrerPolicy referrer_policy_; scoped_ptr<FtpDirectoryListingResponseDelegate> ftp_listing_delegate_; scoped_ptr<MultipartResponseDelegate> multipart_delegate_; @@ -319,11 +335,11 @@ WebURLLoaderImpl::Context::Context( WebURLLoaderImpl* loader, ResourceDispatcher* resource_dispatcher, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) + scoped_ptr<blink::WebTaskRunner> web_task_runner) : loader_(loader), client_(NULL), resource_dispatcher_(resource_dispatcher), - task_runner_(task_runner), + web_task_runner_(web_task_runner.Pass()), referrer_policy_(blink::WebReferrerPolicyDefault), defers_loading_(NOT_DEFERRING), request_id_(-1) { @@ -359,8 +375,11 @@ defers_loading_ = SHOULD_DEFER; } else if (!value && defers_loading_ != NOT_DEFERRING) { if (defers_loading_ == DEFERRED_DATA) { - task_runner_->PostTask(FROM_HERE, - base::Bind(&Context::HandleDataURL, this)); + // TODO(alexclarke): Find a way to let blink and chromium FROM_HERE + // coexist. + web_task_runner_->postTask( + ::blink::WebTraceLocation(__FUNCTION__, __FILE__), + new HandleDataURLTask(this)); } defers_loading_ = NOT_DEFERRING; } @@ -418,8 +437,11 @@ GetInfoFromDataURL(sync_load_response->url, sync_load_response, &sync_load_response->data); } else { - task_runner_->PostTask(FROM_HERE, - base::Bind(&Context::HandleDataURL, this)); + // TODO(alexclarke): Find a way to let blink and chromium FROM_HERE + // coexist. + web_task_runner_->postTask( + ::blink::WebTraceLocation(__FUNCTION__, __FILE__), + new HandleDataURLTask(this)); } return; } @@ -482,6 +504,7 @@ GetRequestContextFrameTypeForWebURLRequest(request); request_info.extra_data = request.extraData(); request_info.report_raw_headers = request.reportRawHeaders(); + request_info.loading_web_task_runner.reset(web_task_runner_->clone()); scoped_refptr<ResourceRequestBody> request_body = GetRequestBodyForWebURLRequest(request).get(); @@ -496,6 +519,11 @@ request_info, request_body.get(), this); } +void WebURLLoaderImpl::Context::SetWebTaskRunner( + scoped_ptr<blink::WebTaskRunner> web_task_runner) { + web_task_runner_ = web_task_runner.Pass(); +} + void WebURLLoaderImpl::Context::OnUploadProgress(uint64 position, uint64 size) { if (client_) client_->didSendData(loader_, position, size); @@ -841,8 +869,8 @@ WebURLLoaderImpl::WebURLLoaderImpl( ResourceDispatcher* resource_dispatcher, - scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : context_(new Context(this, resource_dispatcher, task_runner)) { + scoped_ptr<blink::WebTaskRunner> web_task_runner) + : context_(new Context(this, resource_dispatcher, web_task_runner.Pass())) { } WebURLLoaderImpl::~WebURLLoaderImpl() { @@ -1059,4 +1087,11 @@ return context_->AttachThreadedDataReceiver(threaded_data_receiver); } +void WebURLLoaderImpl::setLoadingTaskRunner( + blink::WebTaskRunner* loading_task_runner) { + // There's no guarantee on the lifetime of |loading_task_runner| so we take a + // copy. + context_->SetWebTaskRunner(make_scoped_ptr(loading_task_runner->clone())); +} + } // namespace content
diff --git a/content/child/web_url_loader_impl.h b/content/child/web_url_loader_impl.h index ebad018..b31b57e 100644 --- a/content/child/web_url_loader_impl.h +++ b/content/child/web_url_loader_impl.h
@@ -36,9 +36,10 @@ class CONTENT_EXPORT WebURLLoaderImpl : public NON_EXPORTED_BASE(blink::WebURLLoader) { public: - explicit WebURLLoaderImpl( - ResourceDispatcher* resource_dispatcher, - scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + // Takes ownership of |web_task_runner|. + WebURLLoaderImpl(ResourceDispatcher* resource_dispatcher, + scoped_ptr<blink::WebTaskRunner> web_task_runner); ~WebURLLoaderImpl() override; static void PopulateURLResponse(const GURL& url, @@ -67,6 +68,7 @@ int intra_priority_value) override; bool attachThreadedDataReceiver( blink::WebThreadedDataReceiver* threaded_data_receiver) override; + void setLoadingTaskRunner(blink::WebTaskRunner* loading_task_runner) override; private: class Context;
diff --git a/content/child/web_url_loader_impl_unittest.cc b/content/child/web_url_loader_impl_unittest.cc index 6fb686e4..00354dd 100644 --- a/content/child/web_url_loader_impl_unittest.cc +++ b/content/child/web_url_loader_impl_unittest.cc
@@ -13,6 +13,7 @@ #include "base/message_loop/message_loop.h" #include "base/single_thread_task_runner.h" #include "base/time/time.h" +#include "components/scheduler/child/web_task_runner_impl.h" #include "content/child/request_extra_data.h" #include "content/child/request_info.h" #include "content/child/resource_dispatcher.h" @@ -106,7 +107,10 @@ TestWebURLLoaderClient( ResourceDispatcher* dispatcher, scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : loader_(new WebURLLoaderImpl(dispatcher, task_runner)), + : loader_( + new WebURLLoaderImpl( + dispatcher, + make_scoped_ptr(new scheduler::WebTaskRunnerImpl(task_runner)))), expect_multipart_response_(false), delete_on_receive_redirect_(false), delete_on_receive_response_(false),
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc index cb509a83..9bd4471b 100644 --- a/content/common/gpu/client/command_buffer_proxy_impl.cc +++ b/content/common/gpu/client/command_buffer_proxy_impl.cc
@@ -21,6 +21,7 @@ #include "gpu/command_buffer/common/cmd_buffer_common.h" #include "gpu/command_buffer/common/command_buffer_shared.h" #include "gpu/command_buffer/common/gpu_memory_allocation.h" +#include "gpu/command_buffer/common/sync_token.h" #include "gpu/command_buffer/service/image_factory.h" #include "ui/gfx/geometry/size.h" #include "ui/gl/gl_bindings.h" @@ -505,6 +506,10 @@ } bool CommandBufferProxyImpl::IsFenceSyncFlushed(uint64_t release) { + return release != 0 && release <= flushed_fence_sync_release_; +} + +bool CommandBufferProxyImpl::IsFenceSyncFlushReceived(uint64_t release) { CheckLock(); if (last_state_.error != gpu::error::kNoError) return false; @@ -528,6 +533,15 @@ return false; } +bool CommandBufferProxyImpl::CanWaitUnverifiedSyncToken( + const gpu::SyncToken* sync_token) { + // Can only wait on an unverified sync token if it is from the same channel. + const uint64_t token_channel = sync_token->command_buffer_id() >> 32; + const uint64_t channel = command_buffer_id_ >> 32; + return (sync_token->namespace_id() == gpu::CommandBufferNamespace::GPU_IO && + token_channel == channel); +} + uint32 CommandBufferProxyImpl::InsertSyncPoint() { CheckLock(); if (last_state_.error != gpu::error::kNoError)
diff --git a/content/common/gpu/client/command_buffer_proxy_impl.h b/content/common/gpu/client/command_buffer_proxy_impl.h index 61ba775..31326466 100644 --- a/content/common/gpu/client/command_buffer_proxy_impl.h +++ b/content/common/gpu/client/command_buffer_proxy_impl.h
@@ -126,6 +126,8 @@ uint64_t GenerateFenceSyncRelease() override; bool IsFenceSyncRelease(uint64_t release) override; bool IsFenceSyncFlushed(uint64_t release) override; + bool IsFenceSyncFlushReceived(uint64_t release) override; + bool CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) override; bool ProduceFrontBuffer(const gpu::Mailbox& mailbox); void SetContextLostCallback(const base::Closure& callback);
diff --git a/content/common/site_isolation_policy.cc b/content/common/site_isolation_policy.cc index d36786e..0423101 100644 --- a/content/common/site_isolation_policy.cc +++ b/content/common/site_isolation_policy.cc
@@ -11,57 +11,17 @@ namespace content { -namespace { - -class SiteIsolationWhitelist { - public: - SiteIsolationWhitelist() { - // Call into the embedder to get the list of isolated schemes from the - // command-line configuration. - // - // TODO(nick): https://crbug.com/133403 Because the AtExitManager doesn't - // run between unit tests, it's not possible for unit tests to safely alter - // the isolated schemes here. - GetContentClient()->AddIsolatedSchemes(&isolated_schemes_); - } - ~SiteIsolationWhitelist() {} - - const std::set<std::string>& isolated_schemes() const { - return isolated_schemes_; - } - - bool should_isolate_all_sites() const { - // TODO(nick): https://crbug.com/133403 We ought to cache the value of this - // switch here, but cannot because the AtExitManager doesn't run between - // unit tests. - return base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kSitePerProcess); - } - - private: - std::set<std::string> isolated_schemes_; - DISALLOW_COPY_AND_ASSIGN(SiteIsolationWhitelist); -}; - -base::LazyInstance<SiteIsolationWhitelist> g_site_isolation_whitelist = - LAZY_INSTANCE_INITIALIZER; - -} // namespace - // static bool SiteIsolationPolicy::AreCrossProcessFramesPossible() { - const SiteIsolationWhitelist& whitelist = g_site_isolation_whitelist.Get(); - return whitelist.should_isolate_all_sites() || - !whitelist.isolated_schemes().empty(); + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSitePerProcess) || + GetContentClient()->IsSupplementarySiteIsolationModeEnabled(); } // static -bool SiteIsolationPolicy::DoesSiteRequireDedicatedProcess( - const GURL& effective_url) { - const SiteIsolationWhitelist& whitelist = g_site_isolation_whitelist.Get(); - return whitelist.should_isolate_all_sites() || - (!whitelist.isolated_schemes().empty() && - whitelist.isolated_schemes().count(effective_url.scheme())); +bool SiteIsolationPolicy::UseDedicatedProcessesForAllSites() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSitePerProcess); } // static @@ -73,16 +33,7 @@ // static bool SiteIsolationPolicy::IsSwappedOutStateForbidden() { - return true; -} - -// static -bool SiteIsolationPolicy::IsolateAllSitesForTesting() { - // TODO(nick): Re-enable once https://crbug.com/133403 is fixed. - // if (!(g_site_isolation_whitelist == nullptr)) return false; - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kSitePerProcess); - return true; + return AreCrossProcessFramesPossible(); } } // namespace content
diff --git a/content/common/site_isolation_policy.h b/content/common/site_isolation_policy.h index 86020c0e..68d1e44 100644 --- a/content/common/site_isolation_policy.h +++ b/content/common/site_isolation_policy.h
@@ -34,15 +34,8 @@ // particular site merits protection. static bool AreCrossProcessFramesPossible(); - // Returns true if pages loaded from |effective_url| ought to be handled only - // by a renderer process isolated from other sites. If --site-per-process is - // on the command line, this is true for all sites. In other site isolation - // modes, only a subset of sites will require dedicated processes. - // - // |effective_url| must be an effective URL -- practically speaking, that - // means that this function should only be called on the UI thread in the - // browser process. - static bool DoesSiteRequireDedicatedProcess(const GURL& effective_url); + // Returns true if every site should be placed in a dedicated process. + static bool UseDedicatedProcessesForAllSites(); // Returns true if navigation and history code should maintain per-frame // navigation entries. This is an in-progress feature related to site @@ -61,13 +54,6 @@ // should be removed and its callers cleaned up. static bool IsSwappedOutStateForbidden(); - // Overrides the default site isolation mode so that all sites are - // isolated. Returns true if successful. Can fail if SiteIsolationPolicy - // has already been consulted at runtime prior to the override call -- - // if so, try calling this earlier in the test, maybe before creating - // any renderer processes. - static bool IsolateAllSitesForTesting(); - private: SiteIsolationPolicy(); // Not instantiable.
diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 13b8121..bf67833 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi
@@ -354,6 +354,7 @@ 'browser/background_sync/background_sync_network_observer_unittest.cc', 'browser/background_sync/background_sync_power_observer_unittest.cc', 'browser/background_sync/background_sync_service_impl_unittest.cc', + 'browser/blob_storage/blob_storage_registry_unittest.cc', 'browser/browser_io_surface_manager_mac_unittest.cc', 'browser/browser_thread_unittest.cc', 'browser/browser_url_handler_impl_unittest.cc',
diff --git a/content/gpu/DEPS b/content/gpu/DEPS index 87a7a0d..f9f4c04 100644 --- a/content/gpu/DEPS +++ b/content/gpu/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/tracing", "+content/child", "+libEGL", "+libGLESv2",
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc index d27ef2b9..93d03aa4 100644 --- a/content/gpu/gpu_main.cc +++ b/content/gpu/gpu_main.cc
@@ -47,6 +47,11 @@ #include "ui/gl/gl_switches.h" #include "ui/gl/gpu_switching_manager.h" +#if defined(OS_ANDROID) +#include "base/trace_event/memory_dump_manager.h" +#include "components/tracing/graphics_memory_dump_provider_android.h" +#endif + #if defined(OS_WIN) #include "base/win/windows_version.h" #include "base/win/scoped_com_initializer.h" @@ -383,6 +388,11 @@ if (watchdog_thread.get()) watchdog_thread->AddPowerObserver(); +#if defined(OS_ANDROID) + base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( + tracing::GraphicsMemoryDumpProvider::GetInstance()); +#endif + { TRACE_EVENT0("gpu", "Run Message Loop"); main_message_loop.Run();
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index e710ed2..a9e7d2e 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -39,6 +39,12 @@ return false; } +bool ContentBrowserClient::DoesSiteRequireDedicatedProcess( + BrowserContext* browser_context, + const GURL& effective_url) { + return false; +} + bool ContentBrowserClient::ShouldLockToOrigin(BrowserContext* browser_context, const GURL& effective_url) { return true;
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 5104d99..7213c7b 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -180,9 +180,22 @@ virtual bool ShouldUseProcessPerSite(BrowserContext* browser_context, const GURL& effective_url); + // Returns true if site isolation should be enabled for |effective_url|. This + // call allows the embedder to supplement the site isolation policy enforced + // by the content layer. + // + // Will only be called if both of the following happen: + // 1. The embedder asked to be consulted, by returning true from + // ContentClient::IsSupplementarySiteIsolationModeEnabled(). + // 2. The content layer didn't decide to isolate |effective_url| according + // to its internal policy (e.g. because of --site-per-process). + virtual bool DoesSiteRequireDedicatedProcess(BrowserContext* browser_context, + const GURL& effective_url); + // Returns true unless the effective URL is part of a site that cannot live in - // a process dedicated to that site. This is only called if - // SiteIsolationPolicy::DoesSiteRequireDedicatedProcess returns true. + // a process restricted to just that site. This is only called if site + // isolation is enabled for this URL, and is a bug workaround. + // // TODO(nick): Remove this function once https://crbug.com/160576 is fixed, // and origin lock can be applied to all URLs. virtual bool ShouldLockToOrigin(BrowserContext* browser_context,
diff --git a/content/public/common/content_client.cc b/content/public/common/content_client.cc index 421a0a3..3c8d235 100644 --- a/content/public/common/content_client.cc +++ b/content/public/common/content_client.cc
@@ -112,4 +112,8 @@ } #endif +bool ContentClient::IsSupplementarySiteIsolationModeEnabled() { + return false; +} + } // namespace content
diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h index 2c016348..246f4221 100644 --- a/content/public/common/content_client.h +++ b/content/public/common/content_client.h
@@ -147,9 +147,12 @@ // trustworthy schemes should be added. virtual void AddServiceWorkerSchemes(std::set<std::string>* schemes) {} - // Gives the embedder a chance to register schemes for which site isolation - // should be enabled. - virtual void AddIsolatedSchemes(std::set<std::string>* schemes) {} + // Returns true if the embedder wishes to supplement the site isolation policy + // used by the content layer. Returning true enables the infrastructure for + // out-of-process iframes, and causes the content layer to consult + // ContentBrowserClient::DoesSiteRequireDedicatedProcess() when making process + // model decisions. + virtual bool IsSupplementarySiteIsolationModeEnabled(); private: friend class ContentClientInitializer; // To set these pointers.
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc index 36d2f97..1a05f68 100644 --- a/content/public/test/test_utils.cc +++ b/content/public/test/test_utils.cc
@@ -193,9 +193,7 @@ } void IsolateAllSitesForTesting(base::CommandLine* command_line) { - EXPECT_TRUE(SiteIsolationPolicy::IsolateAllSitesForTesting()) - << "IsolateAllSitesForTesting() called after " - << "SiteIsolationPolicy was already used"; + command_line->AppendSwitch(switches::kSitePerProcess); } MessageLoopRunner::MessageLoopRunner()
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 5aab6d02..c24ed13 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -1040,9 +1040,10 @@ const scoped_refptr<base::SingleThreadTaskRunner>& resource_task_queue) { // Add a filter that forces resource messages to be dispatched via a // particular task runner. - resource_scheduling_filter_ = - new ResourceSchedulingFilter(resource_task_queue, resource_dispatcher()); - channel()->AddFilter(resource_scheduling_filter_.get()); + scoped_refptr<ResourceSchedulingFilter> filter( + new ResourceSchedulingFilter(resource_task_queue, resource_dispatcher())); + channel()->AddFilter(filter.get()); + resource_dispatcher()->SetResourceSchedulingFilter(filter); // The ChildResourceMessageFilter and the ResourceDispatcher need to use the // same queue to ensure tasks are executed in the expected order.
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index 190d5578..9eed365 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h
@@ -109,7 +109,6 @@ class RendererBlinkPlatformImpl; class RendererDemuxerAndroid; class ResourceDispatchThrottler; -class ResourceSchedulingFilter; class V8SamplingProfiler; class VideoCaptureImplManager; class WebGraphicsContext3DCommandBufferImpl; @@ -616,8 +615,6 @@ scoped_refptr<base::SingleThreadTaskRunner> main_thread_compositor_task_runner_; - scoped_refptr<ResourceSchedulingFilter> resource_scheduling_filter_; - // Compositor settings. bool is_gpu_rasterization_enabled_; bool is_gpu_rasterization_forced_;
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 353d9ea..1d4293da 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -7,7 +7,6 @@ #include "base/auto_reset.h" #include "base/bind.h" #include "base/command_line.h" -#include "base/debug/dump_without_crashing.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/memory/singleton.h" @@ -1294,20 +1293,6 @@ void RenderWidget::OnSetFocus(bool enable) { has_focus_ = enable; - - // TODO(nasko): This code is here to help diagnose https://crbug.com/541578. - if (webwidget_->isWebView()) { - blink::WebView* view = static_cast<blink::WebView*>(webwidget_); - if (view->mainFrame()->isWebRemoteFrame()) { - blink::WebFrame* mainFrame = view->mainFrame(); - - base::debug::Alias(&mainFrame); - base::debug::Alias(&is_swapped_out_); - - base::debug::DumpWithoutCrashing(); - } - } - if (webwidget_) webwidget_->setFocus(enable); }
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index c2ca182..9da0779 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -19,6 +19,7 @@ #include "build/build_config.h" #include "cc/blink/context_provider_web_context.h" #include "components/scheduler/child/web_scheduler_impl.h" +#include "components/scheduler/child/web_task_runner_impl.h" #include "components/scheduler/renderer/renderer_scheduler.h" #include "components/scheduler/renderer/webthread_impl_for_renderer_scheduler.h" #include "components/url_formatter/url_formatter.h" @@ -32,6 +33,7 @@ #include "content/child/simple_webmimeregistry_impl.h" #include "content/child/thread_safe_sender.h" #include "content/child/web_database_observer_impl.h" +#include "content/child/web_url_loader_impl.h" #include "content/child/webblobregistry_impl.h" #include "content/child/webfileutilities_impl.h" #include "content/child/webmessageportchannel_impl.h" @@ -237,6 +239,7 @@ sudden_termination_disables_(0), plugin_refresh_allowed_(true), default_task_runner_(renderer_scheduler->DefaultTaskRunner()), + loading_task_runner_(renderer_scheduler->LoadingTaskRunner()), web_scrollbar_behavior_(new WebScrollbarBehaviorImpl) { #if !defined(OS_ANDROID) && !defined(OS_WIN) if (g_sandbox_enabled && sandboxEnabled()) { @@ -273,6 +276,19 @@ //------------------------------------------------------------------------------ +blink::WebURLLoader* RendererBlinkPlatformImpl::createURLLoader() { + ChildThreadImpl* child_thread = ChildThreadImpl::current(); + // There may be no child thread in RenderViewTests. These tests can still use + // data URLs to bypass the ResourceDispatcher. + scoped_ptr<scheduler::WebTaskRunnerImpl> task_runner( + new scheduler::WebTaskRunnerImpl( + loading_task_runner_->BelongsToCurrentThread() + ? loading_task_runner_ : base::ThreadTaskRunnerHandle::Get())); + return new content::WebURLLoaderImpl( + child_thread ? child_thread->resource_dispatcher() : NULL, + task_runner.Pass()); +} + blink::WebThread* RendererBlinkPlatformImpl::currentThread() { if (main_thread_->isCurrentThread()) return main_thread_.get();
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index 6a64c59..32edd5f 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -205,6 +205,8 @@ return web_database_observer_impl_.get(); } + blink::WebURLLoader* createURLLoader() override; + private: bool CheckPreparsedJsCachingEnabled() const; @@ -254,6 +256,7 @@ scoped_ptr<DeviceOrientationEventPump> device_orientation_event_pump_; scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; scoped_refptr<IPC::SyncMessageFilter> sync_message_filter_; scoped_refptr<ThreadSafeSender> thread_safe_sender_; scoped_refptr<QuotaMessageFilter> quota_message_filter_;
diff --git a/content/test/mock_weburlloader.h b/content/test/mock_weburlloader.h index db26111a..4b96ed3d 100644 --- a/content/test/mock_weburlloader.h +++ b/content/test/mock_weburlloader.h
@@ -23,6 +23,8 @@ blink::WebURLLoaderClient* client)); MOCK_METHOD0(cancel, void()); MOCK_METHOD1(setDefersLoading, void(bool value)); + MOCK_METHOD1(setLoadingTaskRunner, + void(blink::WebTaskRunner* loading_task_runner)); private: DISALLOW_COPY_AND_ASSIGN(MockWebURLLoader);
diff --git a/content/test/weburl_loader_mock.cc b/content/test/weburl_loader_mock.cc index b7f29e4..9e534722 100644 --- a/content/test/weburl_loader_mock.cc +++ b/content/test/weburl_loader_mock.cc
@@ -147,3 +147,7 @@ } NOTIMPLEMENTED(); } + +void WebURLLoaderMock::setLoadingTaskRunner(blink::WebTaskRunner*) { + NOTIMPLEMENTED(); +}
diff --git a/content/test/weburl_loader_mock.h b/content/test/weburl_loader_mock.h index 025eaef5..a098a8e 100644 --- a/content/test/weburl_loader_mock.h +++ b/content/test/weburl_loader_mock.h
@@ -55,6 +55,8 @@ bool isDeferred() { return is_deferred_; } + void setLoadingTaskRunner(blink::WebTaskRunner*) override; + private: WebURLLoaderMockFactory* factory_; blink::WebURLLoaderClient* client_;
diff --git a/extensions/browser/updater/update_service_browsertest.cc b/extensions/browser/updater/update_service_browsertest.cc index bd9a55e..097de35 100644 --- a/extensions/browser/updater/update_service_browsertest.cc +++ b/extensions/browser/updater/update_service_browsertest.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/bind.h" +#include "base/files/scoped_temp_dir.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -96,6 +97,8 @@ class FakeUpdateURLFetcherFactory : public net::URLFetcherFactory { public: + FakeUpdateURLFetcherFactory() { EXPECT_TRUE(dir_.CreateUniqueTempDir()); } + ~FakeUpdateURLFetcherFactory() override {} void RegisterFakeExtension(const std::string& id, @@ -156,11 +159,17 @@ net::TestURLFetcher* fetcher = new net::FakeURLFetcher(url, delegate, response.first, response.second, net::URLRequestStatus::SUCCESS); - fetcher->SetResponseFilePath(base::FilePath::FromUTF8Unsafe(url.path())); + base::FilePath path = dir_.path().Append( + base::FilePath::FromUTF8Unsafe(url.path().substr(1))); + fetcher->SetResponseFilePath(path); return scoped_ptr<net::URLFetcher>(fetcher); } + base::ScopedTempDir dir_; + std::map<std::string, std::string> fake_extensions_; + + DISALLOW_COPY_AND_ASSIGN(FakeUpdateURLFetcherFactory); }; } // namespace
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_sync_point.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_sync_point.txt index 80df38e..3ec5e1e0 100644 --- a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_sync_point.txt +++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_sync_point.txt
@@ -67,13 +67,31 @@ The command + void GenUnverifiedSyncTokenCHROMIUM(uint64 fence_sync, + GLbyte *sync_token) + + converts <fence_sync> which is only visible to the current context to a + sync token which may be waited upon by a context which only needs flush + order guarantee with respect to the fence sync context. For example, if + the two contexts are on the same channel but on different streams, flush + order guarantee is enough to guarantee that the server will receive the + release command before the wait command. The <fence_sync> command must be + flushed before this function may be called, otherwise an INVALID_OPERATION + error is generated. The generated <sync_token> must be generated on the + same context as when InsertSyncPointCHROMIUM was called. + + The command + void WaitSyncTokenCHROMIUM(const GLbyte *sync_token) causes the current context to stop submitting commands until the specified fence sync becomes signaled. This is implemented as a server-side wait. <sync_token> is a sync token generated by GenSyncPointCHROMIUM. If - <sync_token> isn't a valid sync token returned by GenSyncPointCHROMIUM, the - command is equivalent to a no-op and no error is generated. + <sync_token> was generated by GenUnverifiedSyncTokenCHROMIUM and the + corresponding fence sync context required more than just flush ordering + to guarantee synchronization, a INVALID_OPERATION error is generated. If + <sync_token> isn't a valid sync token returned by GenSyncPointCHROMIUM or + GenUnverifiedSyncTokenCHROMIUM, the result is undefined. New Tokens @@ -89,6 +107,10 @@ INVALID_OPERATION is generated if the <fence_sync> parameter of GenSyncPointCHROMIUM has not been flushed to the server. + INVALID_OPERATION is generated if the <sync_token> parameter of + WaitSyncTokenCHROMIUM was generated using GenUnverifiedSyncTokenCHROMIUM + but the two contexts must be synchronized with more than just flush order. + New State None. @@ -97,5 +119,7 @@ 2/25/2013 Documented the extension - 9/8/2015 Modified functions to InsertFenceSyncCHROMIUM, + 9/8/2015 Modified functions InsertFenceSyncCHROMIUM, GenSyncTokenCHROMIUM, and WaitSyncTokenCHROMIUM. + + 10/12/2015 Added function GenUnverifiedSyncTokenCHROMIUM.
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index 3b30b9b..901c7531 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -329,6 +329,8 @@ #define glWaitSyncPointCHROMIUM GLES2_GET_FUN(WaitSyncPointCHROMIUM) #define glInsertFenceSyncCHROMIUM GLES2_GET_FUN(InsertFenceSyncCHROMIUM) #define glGenSyncTokenCHROMIUM GLES2_GET_FUN(GenSyncTokenCHROMIUM) +#define glGenUnverifiedSyncTokenCHROMIUM \ + GLES2_GET_FUN(GenUnverifiedSyncTokenCHROMIUM) #define glWaitSyncTokenCHROMIUM GLES2_GET_FUN(WaitSyncTokenCHROMIUM) #define glDrawBuffersEXT GLES2_GET_FUN(DrawBuffersEXT) #define glDiscardBackbufferCHROMIUM GLES2_GET_FUN(DiscardBackbufferCHROMIUM)
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 5affdcb..8a32238 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -4096,6 +4096,12 @@ 'extension': "CHROMIUM_sync_point", 'chromium': True, }, + 'GenUnverifiedSyncTokenCHROMIUM': { + 'type': 'Custom', + 'impl_func': False, + 'extension': "CHROMIUM_sync_point", + 'chromium': True, + }, 'WaitSyncTokenCHROMIUM': { 'type': 'Custom', 'impl_func': False,
diff --git a/gpu/command_buffer/client/client_test_helper.h b/gpu/command_buffer/client/client_test_helper.h index a0733b5..a5b9bf6 100644 --- a/gpu/command_buffer/client/client_test_helper.h +++ b/gpu/command_buffer/client/client_test_helper.h
@@ -117,6 +117,8 @@ MOCK_METHOD0(GenerateFenceSyncRelease, uint64_t()); MOCK_METHOD1(IsFenceSyncRelease, bool(uint64_t release)); MOCK_METHOD1(IsFenceSyncFlushed, bool(uint64_t release)); + MOCK_METHOD1(IsFenceSyncFlushReceived, bool(uint64_t release)); + MOCK_METHOD1(CanWaitUnverifiedSyncToken, bool(const SyncToken*)); private: DISALLOW_COPY_AND_ASSIGN(MockClientGpuControl);
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 4b2ee2b..284f00d 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1488,6 +1488,10 @@ GLbyte* sync_token) { gles2::GetGLContext()->GenSyncTokenCHROMIUM(fence_sync, sync_token); } +void GL_APIENTRY GLES2GenUnverifiedSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token) { + gles2::GetGLContext()->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token); +} void GL_APIENTRY GLES2WaitSyncTokenCHROMIUM(const GLbyte* sync_token) { gles2::GetGLContext()->WaitSyncTokenCHROMIUM(sync_token); } @@ -2738,6 +2742,11 @@ reinterpret_cast<GLES2FunctionPointer>(glGenSyncTokenCHROMIUM), }, { + "glGenUnverifiedSyncTokenCHROMIUM", + reinterpret_cast<GLES2FunctionPointer>( + glGenUnverifiedSyncTokenCHROMIUM), + }, + { "glWaitSyncTokenCHROMIUM", reinterpret_cast<GLES2FunctionPointer>(glWaitSyncTokenCHROMIUM), },
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index b722d6e..ec5b9f8 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -2775,6 +2775,16 @@ } } +void GenUnverifiedSyncTokenCHROMIUMImmediate(GLuint64 fence_sync) { + const uint32_t s = 0; // TODO(gman): compute correct size + gles2::cmds::GenUnverifiedSyncTokenCHROMIUMImmediate* c = + GetImmediateCmdSpaceTotalSize< + gles2::cmds::GenUnverifiedSyncTokenCHROMIUMImmediate>(s); + if (c) { + c->Init(fence_sync); + } +} + void WaitSyncTokenCHROMIUM(GLuint namespace_id, GLuint64 command_buffer_id, GLuint64 release_count) {
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index b1a2aa8..e91bbd6b 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -5380,6 +5380,29 @@ SetGLError(GL_INVALID_VALUE, "glGenSyncTokenCHROMIUM", "invalid fence sync"); return; + } else if (!gpu_control_->IsFenceSyncFlushReceived(fence_sync)) { + SetGLError(GL_INVALID_OPERATION, "glGenSyncTokenCHROMIUM", + "fence sync must be flushed before generating sync token"); + return; + } + + // Copy the data over after setting the data to ensure alignment. + SyncToken sync_token_data(gpu_control_->GetNamespaceID(), + gpu_control_->GetCommandBufferID(), fence_sync); + sync_token_data.SetVerifyFlush(); + memcpy(sync_token, &sync_token_data, sizeof(sync_token_data)); +} + +void GLES2Implementation::GenUnverifiedSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token) { + if (!sync_token) { + SetGLError(GL_INVALID_VALUE, "glGenNonFlushedSyncTokenCHROMIUM", + "empty sync_token"); + return; + } else if (!gpu_control_->IsFenceSyncRelease(fence_sync)) { + SetGLError(GL_INVALID_VALUE, "glGenNonFlushedSyncTokenCHROMIUM", + "invalid fence sync"); + return; } else if (!gpu_control_->IsFenceSyncFlushed(fence_sync)) { SetGLError(GL_INVALID_OPERATION, "glGenSyncTokenCHROMIUM", "fence sync must be flushed before generating sync token"); @@ -5401,6 +5424,14 @@ // Copy the data over before data access to ensure alignment. SyncToken sync_token_data; memcpy(&sync_token_data, sync_token, sizeof(SyncToken)); + + if (!sync_token_data.verified_flush() && + !gpu_control_->CanWaitUnverifiedSyncToken(&sync_token_data)) { + SetGLError(GL_INVALID_VALUE, "glWaitSyncTokenCHROMIUM", + "Cannot wait on sync_token which has not been verified"); + return; + } + helper_->WaitSyncTokenCHROMIUM(sync_token_data.namespace_id(), sync_token_data.command_buffer_id(), sync_token_data.release_count());
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 3d551a9..2e09d49 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1031,6 +1031,9 @@ void GenSyncTokenCHROMIUM(GLuint64 fence_sync, GLbyte* sync_token) override; +void GenUnverifiedSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token) override; + void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override; void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override;
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index d53e647..8ff533d 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -18,6 +18,7 @@ #include "gpu/command_buffer/client/ring_buffer.h" #include "gpu/command_buffer/client/transfer_buffer.h" #include "gpu/command_buffer/common/command_buffer.h" +#include "gpu/command_buffer/common/sync_token.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gmock/include/gmock/gmock.h" @@ -3761,7 +3762,7 @@ const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO; const GLuint64 kCommandBufferId = 234u; const GLuint64 kFenceSync = 123u; - GLbyte sync_token[GL_SYNC_TOKEN_SIZE_CHROMIUM]; + GLbyte sync_token_data[GL_SYNC_TOKEN_SIZE_CHROMIUM]; EXPECT_CALL(*gpu_control_, GetNamespaceID()) .WillRepeatedly(testing::Return(kNamespaceId)); @@ -3773,14 +3774,57 @@ EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync)) .WillOnce(testing::Return(false)); - gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token); + gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token_data); + EXPECT_EQ(GL_INVALID_VALUE, CheckError()); + + EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync)) + .WillOnce(testing::Return(true)); + EXPECT_CALL(*gpu_control_, IsFenceSyncFlushReceived(kFenceSync)) + .WillOnce(testing::Return(false)); + gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token_data); + EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); + + EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync)) + .WillOnce(testing::Return(true)); + EXPECT_CALL(*gpu_control_, IsFenceSyncFlushReceived(kFenceSync)) + .WillOnce(testing::Return(true)); + ClearCommands(); + gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token_data); + EXPECT_TRUE(NoCommandsWritten()); + EXPECT_EQ(GL_NO_ERROR, CheckError()); + + SyncToken sync_token; + memcpy(&sync_token, sync_token_data, sizeof(SyncToken)); + EXPECT_TRUE(sync_token.verified_flush()); + EXPECT_EQ(kNamespaceId, sync_token.namespace_id()); + EXPECT_EQ(kCommandBufferId, sync_token.command_buffer_id()); + EXPECT_EQ(kFenceSync, sync_token.release_count()); +} + +TEST_F(GLES2ImplementationTest, GenUnverifiedSyncTokenCHROMIUM) { + const CommandBufferNamespace kNamespaceId = CommandBufferNamespace::GPU_IO; + const GLuint64 kCommandBufferId = 234u; + const GLuint64 kFenceSync = 123u; + GLbyte sync_token_data[GL_SYNC_TOKEN_SIZE_CHROMIUM]; + + EXPECT_CALL(*gpu_control_, GetNamespaceID()) + .WillRepeatedly(testing::Return(kNamespaceId)); + EXPECT_CALL(*gpu_control_, GetCommandBufferID()) + .WillRepeatedly(testing::Return(kCommandBufferId)); + + gl_->GenUnverifiedSyncTokenCHROMIUM(kFenceSync, nullptr); + EXPECT_EQ(GL_INVALID_VALUE, CheckError()); + + EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync)) + .WillOnce(testing::Return(false)); + gl_->GenUnverifiedSyncTokenCHROMIUM(kFenceSync, sync_token_data); EXPECT_EQ(GL_INVALID_VALUE, CheckError()); EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync)) .WillOnce(testing::Return(true)); EXPECT_CALL(*gpu_control_, IsFenceSyncFlushed(kFenceSync)) .WillOnce(testing::Return(false)); - gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token); + gl_->GenUnverifiedSyncTokenCHROMIUM(kFenceSync, sync_token_data); EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync)) @@ -3788,9 +3832,16 @@ EXPECT_CALL(*gpu_control_, IsFenceSyncFlushed(kFenceSync)) .WillOnce(testing::Return(true)); ClearCommands(); - gl_->GenSyncTokenCHROMIUM(kFenceSync, sync_token); + gl_->GenUnverifiedSyncTokenCHROMIUM(kFenceSync, sync_token_data); EXPECT_TRUE(NoCommandsWritten()); EXPECT_EQ(GL_NO_ERROR, CheckError()); + + SyncToken sync_token; + memcpy(&sync_token, sync_token_data, sizeof(SyncToken)); + EXPECT_FALSE(sync_token.verified_flush()); + EXPECT_EQ(kNamespaceId, sync_token.namespace_id()); + EXPECT_EQ(kCommandBufferId, sync_token.command_buffer_id()); + EXPECT_EQ(kFenceSync, sync_token.release_count()); } TEST_F(GLES2ImplementationTest, WaitSyncTokenCHROMIUM) { @@ -3801,7 +3852,7 @@ EXPECT_CALL(*gpu_control_, IsFenceSyncRelease(kFenceSync)) .WillOnce(testing::Return(true)); - EXPECT_CALL(*gpu_control_, IsFenceSyncFlushed(kFenceSync)) + EXPECT_CALL(*gpu_control_, IsFenceSyncFlushReceived(kFenceSync)) .WillOnce(testing::Return(true)); EXPECT_CALL(*gpu_control_, GetNamespaceID()) .WillOnce(testing::Return(kNamespaceId));
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index 3f96294..b737e5c 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -3095,6 +3095,7 @@ } // TODO(zmo): Implement unit test for InsertFenceSyncCHROMIUM // TODO(zmo): Implement unit test for GenSyncTokenCHROMIUM +// TODO(zmo): Implement unit test for GenUnverifiedSyncTokenCHROMIUM TEST_F(GLES2ImplementationTest, DrawBuffersEXT) { GLenum data[1][1] = {{0}};
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index 9b97beb..2671b0b8 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -764,6 +764,8 @@ virtual void WaitSyncPointCHROMIUM(GLuint sync_point) = 0; virtual GLuint64 InsertFenceSyncCHROMIUM() = 0; virtual void GenSyncTokenCHROMIUM(GLuint64 fence_sync, GLbyte* sync_token) = 0; +virtual void GenUnverifiedSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token) = 0; virtual void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) = 0; virtual void DrawBuffersEXT(GLsizei count, const GLenum* bufs) = 0; virtual void DiscardBackbufferCHROMIUM() = 0;
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index e795738b..ee4e044e 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -740,6 +740,8 @@ void WaitSyncPointCHROMIUM(GLuint sync_point) override; GLuint64 InsertFenceSyncCHROMIUM() override; void GenSyncTokenCHROMIUM(GLuint64 fence_sync, GLbyte* sync_token) override; +void GenUnverifiedSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token) override; void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override; void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override; void DiscardBackbufferCHROMIUM() override;
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index e7511e4..6bdbb54 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1016,6 +1016,9 @@ } void GLES2InterfaceStub::GenSyncTokenCHROMIUM(GLuint64 /* fence_sync */, GLbyte* /* sync_token */) {} +void GLES2InterfaceStub::GenUnverifiedSyncTokenCHROMIUM( + GLuint64 /* fence_sync */, + GLbyte* /* sync_token */) {} void GLES2InterfaceStub::WaitSyncTokenCHROMIUM(const GLbyte* /* sync_token */) { } void GLES2InterfaceStub::DrawBuffersEXT(GLsizei /* count */,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index f9580d0c..c918a5f 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -740,6 +740,8 @@ void WaitSyncPointCHROMIUM(GLuint sync_point) override; GLuint64 InsertFenceSyncCHROMIUM() override; void GenSyncTokenCHROMIUM(GLuint64 fence_sync, GLbyte* sync_token) override; +void GenUnverifiedSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token) override; void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override; void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override; void DiscardBackbufferCHROMIUM() override;
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 86c547d..f0855dc5 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2171,6 +2171,14 @@ gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token); } +void GLES2TraceImplementation::GenUnverifiedSyncTokenCHROMIUM( + GLuint64 fence_sync, + GLbyte* sync_token) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", + "GLES2Trace::GenUnverifiedSyncTokenCHROMIUM"); + gl_->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token); +} + void GLES2TraceImplementation::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::WaitSyncTokenCHROMIUM"); gl_->WaitSyncTokenCHROMIUM(sync_token);
diff --git a/gpu/command_buffer/client/gpu_control.h b/gpu/command_buffer/client/gpu_control.h index 7000152..6730e80 100644 --- a/gpu/command_buffer/client/gpu_control.h +++ b/gpu/command_buffer/client/gpu_control.h
@@ -27,6 +27,7 @@ } namespace gpu { +struct SyncToken; // Common interface for GpuControl implementations. class GPU_EXPORT GpuControl { @@ -99,10 +100,20 @@ // Fence Syncs use release counters at a context level, these fence syncs // need to be flushed before they can be shared with other contexts across // channels. Subclasses should implement these functions and take care of - // figuring out when a fence sync has been flushed. + // figuring out when a fence sync has been flushed. The difference between + // IsFenceSyncFlushed and IsFenceSyncFlushReceived, one is testing is the + // client has issued the flush, and the other is testing if the service + // has received the flush. virtual uint64_t GenerateFenceSyncRelease() = 0; virtual bool IsFenceSyncRelease(uint64_t release) = 0; virtual bool IsFenceSyncFlushed(uint64_t release) = 0; + virtual bool IsFenceSyncFlushReceived(uint64_t release) = 0; + + // Under some circumstances a sync token may be used which has not been + // verified to have been flushed. For example, fence syncs queued on the + // same channel as the wait command guarantee that the fence sync will + // be enqueued first so does not need to be flushed. + virtual bool CanWaitUnverifiedSyncToken(const SyncToken* sync_token) = 0; private: DISALLOW_COPY_AND_ASSIGN(GpuControl);
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index 9e97d6e..f6ef278 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -309,6 +309,7 @@ GL_APICALL void GL_APIENTRY glWaitSyncPointCHROMIUM (GLuint sync_point); GL_APICALL GLuint64 GL_APIENTRY glInsertFenceSyncCHROMIUM (void); GL_APICALL void GL_APIENTRY glGenSyncTokenCHROMIUM (GLuint64 fence_sync, GLbyte* sync_token); +GL_APICALL void GL_APIENTRY glGenUnverifiedSyncTokenCHROMIUM (GLuint64 fence_sync, GLbyte* sync_token); GL_APICALL void GL_APIENTRY glWaitSyncTokenCHROMIUM (const GLbyte* sync_token); GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei count, const GLenum* bufs); GL_APICALL void GL_APIENTRY glDiscardBackbufferCHROMIUM (void);
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 7dea6b5..85b44ef 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -13539,6 +13539,46 @@ static_assert(offsetof(GenSyncTokenCHROMIUMImmediate, fence_sync) == 4, "offset of GenSyncTokenCHROMIUMImmediate fence_sync should be 4"); +struct GenUnverifiedSyncTokenCHROMIUMImmediate { + typedef GenUnverifiedSyncTokenCHROMIUMImmediate ValueType; + static const CommandId kCmdId = kGenUnverifiedSyncTokenCHROMIUMImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + static const uint8 cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3); + + static uint32_t ComputeSize(uint32_t size_in_bytes) { + return static_cast<uint32_t>(sizeof(ValueType) + // NOLINT + RoundSizeToMultipleOfEntries(size_in_bytes)); + } + + void SetHeader(uint32_t size_in_bytes) { + header.SetCmdByTotalSize<ValueType>(size_in_bytes); + } + + void Init(GLuint64 _fence_sync) { + uint32_t total_size = 0; // TODO(gman): get correct size. + SetHeader(total_size); + fence_sync = _fence_sync; + } + + void* Set(void* cmd, GLuint64 _fence_sync) { + uint32_t total_size = 0; // TODO(gman): get correct size. + static_cast<ValueType*>(cmd)->Init(_fence_sync); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); + } + + gpu::CommandHeader header; + uint32_t fence_sync; +}; + +static_assert(sizeof(GenUnverifiedSyncTokenCHROMIUMImmediate) == 8, + "size of GenUnverifiedSyncTokenCHROMIUMImmediate should be 8"); +static_assert( + offsetof(GenUnverifiedSyncTokenCHROMIUMImmediate, header) == 0, + "offset of GenUnverifiedSyncTokenCHROMIUMImmediate header should be 0"); +static_assert( + offsetof(GenUnverifiedSyncTokenCHROMIUMImmediate, fence_sync) == 4, + "offset of GenUnverifiedSyncTokenCHROMIUMImmediate fence_sync should be 4"); + struct WaitSyncTokenCHROMIUM { typedef WaitSyncTokenCHROMIUM ValueType; static const CommandId kCmdId = kWaitSyncTokenCHROMIUM;
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 39e1705..471460c 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -298,29 +298,30 @@ OP(WaitSyncPointCHROMIUM) /* 539 */ \ OP(InsertFenceSyncCHROMIUM) /* 540 */ \ OP(GenSyncTokenCHROMIUMImmediate) /* 541 */ \ - OP(WaitSyncTokenCHROMIUM) /* 542 */ \ - OP(DrawBuffersEXTImmediate) /* 543 */ \ - OP(DiscardBackbufferCHROMIUM) /* 544 */ \ - OP(ScheduleOverlayPlaneCHROMIUM) /* 545 */ \ - OP(SwapInterval) /* 546 */ \ - OP(FlushDriverCachesCHROMIUM) /* 547 */ \ - OP(MatrixLoadfCHROMIUMImmediate) /* 548 */ \ - OP(MatrixLoadIdentityCHROMIUM) /* 549 */ \ - OP(GenPathsCHROMIUM) /* 550 */ \ - OP(DeletePathsCHROMIUM) /* 551 */ \ - OP(IsPathCHROMIUM) /* 552 */ \ - OP(PathCommandsCHROMIUM) /* 553 */ \ - OP(PathParameterfCHROMIUM) /* 554 */ \ - OP(PathParameteriCHROMIUM) /* 555 */ \ - OP(PathStencilFuncCHROMIUM) /* 556 */ \ - OP(StencilFillPathCHROMIUM) /* 557 */ \ - OP(StencilStrokePathCHROMIUM) /* 558 */ \ - OP(CoverFillPathCHROMIUM) /* 559 */ \ - OP(CoverStrokePathCHROMIUM) /* 560 */ \ - OP(StencilThenCoverFillPathCHROMIUM) /* 561 */ \ - OP(StencilThenCoverStrokePathCHROMIUM) /* 562 */ \ - OP(BlendBarrierKHR) /* 563 */ \ - OP(ApplyScreenSpaceAntialiasingCHROMIUM) /* 564 */ + OP(GenUnverifiedSyncTokenCHROMIUMImmediate) /* 542 */ \ + OP(WaitSyncTokenCHROMIUM) /* 543 */ \ + OP(DrawBuffersEXTImmediate) /* 544 */ \ + OP(DiscardBackbufferCHROMIUM) /* 545 */ \ + OP(ScheduleOverlayPlaneCHROMIUM) /* 546 */ \ + OP(SwapInterval) /* 547 */ \ + OP(FlushDriverCachesCHROMIUM) /* 548 */ \ + OP(MatrixLoadfCHROMIUMImmediate) /* 549 */ \ + OP(MatrixLoadIdentityCHROMIUM) /* 550 */ \ + OP(GenPathsCHROMIUM) /* 551 */ \ + OP(DeletePathsCHROMIUM) /* 552 */ \ + OP(IsPathCHROMIUM) /* 553 */ \ + OP(PathCommandsCHROMIUM) /* 554 */ \ + OP(PathParameterfCHROMIUM) /* 555 */ \ + OP(PathParameteriCHROMIUM) /* 556 */ \ + OP(PathStencilFuncCHROMIUM) /* 557 */ \ + OP(StencilFillPathCHROMIUM) /* 558 */ \ + OP(StencilStrokePathCHROMIUM) /* 559 */ \ + OP(CoverFillPathCHROMIUM) /* 560 */ \ + OP(CoverStrokePathCHROMIUM) /* 561 */ \ + OP(StencilThenCoverFillPathCHROMIUM) /* 562 */ \ + OP(StencilThenCoverStrokePathCHROMIUM) /* 563 */ \ + OP(BlendBarrierKHR) /* 564 */ \ + OP(ApplyScreenSpaceAntialiasingCHROMIUM) /* 565 */ enum CommandId { kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/common/sync_token.h b/gpu/command_buffer/common/sync_token.h index 76fdc1c4..cceb44e 100644 --- a/gpu/command_buffer/common/sync_token.h +++ b/gpu/command_buffer/common/sync_token.h
@@ -24,14 +24,16 @@ // details. struct GPU_EXPORT SyncToken { SyncToken() - : namespace_id_(CommandBufferNamespace::INVALID), + : verified_flush_(false), + namespace_id_(CommandBufferNamespace::INVALID), command_buffer_id_(0), release_count_(0) {} SyncToken(CommandBufferNamespace namespace_id, uint64_t command_buffer_id, uint64_t release_count) - : namespace_id_(namespace_id), + : verified_flush_(false), + namespace_id_(namespace_id), command_buffer_id_(command_buffer_id), release_count_(release_count) {} @@ -43,12 +45,17 @@ release_count_ = release_count; } + void SetVerifyFlush() { + verified_flush_ = true; + } + int8_t* GetData() { return reinterpret_cast<int8_t*>(this); } const int8_t* GetConstData() const { return reinterpret_cast<const int8_t*>(this); } + bool verified_flush() const { return verified_flush_; } CommandBufferNamespace namespace_id() const { return namespace_id_; } uint64_t command_buffer_id() const { return command_buffer_id_; } uint64_t release_count() const { return release_count_; } @@ -64,6 +71,7 @@ } private: + bool verified_flush_; CommandBufferNamespace namespace_id_; uint64_t command_buffer_id_; uint64_t release_count_;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 626e362b..10550fa5 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -12499,6 +12499,12 @@ return error::kUnknownCommand; } +error::Error GLES2DecoderImpl::HandleGenUnverifiedSyncTokenCHROMIUMImmediate( + uint32 immediate_data_size, + const void* cmd_data) { + return error::kUnknownCommand; +} + error::Error GLES2DecoderImpl::HandleWaitSyncTokenCHROMIUM( uint32 immediate_data_size, const void* cmd_data) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h index 691c9dcc..1e54d41 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
@@ -465,6 +465,8 @@ // TODO(gman): GenSyncTokenCHROMIUMImmediate +// TODO(gman): GenUnverifiedSyncTokenCHROMIUMImmediate + // TODO(gman): WaitSyncTokenCHROMIUM // TODO(gman): DrawBuffersEXTImmediate
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc index 17f087ee..60bb39ec 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.cc +++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -967,6 +967,15 @@ return release <= flushed_fence_sync_release_; } +bool InProcessCommandBuffer::IsFenceSyncFlushReceived(uint64_t release) { + return IsFenceSyncFlushed(release); +} + +bool InProcessCommandBuffer::CanWaitUnverifiedSyncToken( + const SyncToken* sync_token) { + return false; +} + uint32 InProcessCommandBuffer::CreateStreamTextureOnGpuThread( uint32 client_texture_id) { #if defined(OS_ANDROID)
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h index 7843aa3a..3cac88e4 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.h +++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -133,6 +133,8 @@ uint64_t GenerateFenceSyncRelease() override; bool IsFenceSyncRelease(uint64_t release) override; bool IsFenceSyncFlushed(uint64_t release) override; + bool IsFenceSyncFlushReceived(uint64_t release) override; + bool CanWaitUnverifiedSyncToken(const SyncToken* sync_token) override; // The serializer interface to the GPU service (i.e. thread). class Service {
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc index b0414cd6..bb803bbf5 100644 --- a/gpu/command_buffer/tests/gl_manager.cc +++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -520,4 +520,12 @@ return IsFenceSyncRelease(release); } +bool GLManager::IsFenceSyncFlushReceived(uint64_t release) { + return IsFenceSyncRelease(release); +} + +bool GLManager::CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) { + return false; +} + } // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h index 901bae8..0140198 100644 --- a/gpu/command_buffer/tests/gl_manager.h +++ b/gpu/command_buffer/tests/gl_manager.h
@@ -135,6 +135,8 @@ uint64_t GenerateFenceSyncRelease() override; bool IsFenceSyncRelease(uint64_t release) override; bool IsFenceSyncFlushed(uint64_t release) override; + bool IsFenceSyncFlushReceived(uint64_t release) override; + bool CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) override; private: void PumpCommands();
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc index 3168fa9..f139f097 100644 --- a/gpu/gles2_conform_support/egl/display.cc +++ b/gpu/gles2_conform_support/egl/display.cc
@@ -365,4 +365,12 @@ return IsFenceSyncRelease(release); } +bool Display::IsFenceSyncFlushReceived(uint64_t release) { + return IsFenceSyncRelease(release); +} + +bool Display::CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) { + return false; +} + } // namespace egl
diff --git a/gpu/gles2_conform_support/egl/display.h b/gpu/gles2_conform_support/egl/display.h index a3c69ab..d1953cf0d 100644 --- a/gpu/gles2_conform_support/egl/display.h +++ b/gpu/gles2_conform_support/egl/display.h
@@ -103,6 +103,8 @@ uint64_t GenerateFenceSyncRelease() override; bool IsFenceSyncRelease(uint64_t release) override; bool IsFenceSyncFlushed(uint64_t release) override; + bool IsFenceSyncFlushReceived(uint64_t release) override; + bool CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) override; private: EGLNativeDisplayType display_id_;
diff --git a/infra/config/cq.cfg b/infra/config/cq.cfg index bd043e2..cf1d7a2 100644 --- a/infra/config/cq.cfg +++ b/infra/config/cq.cfg
@@ -49,6 +49,10 @@ builders { name: "linux_chromium_compile_dbg_ng" } builders { name: "linux_chromium_gn_chromeos_rel" } builders { name: "linux_chromium_rel_ng" } + builders { + name: "linux_chromium_chromeos_asan_rel_ng" + experiment_percentage: 10 + } } buckets { name: "tryserver.chromium.mac" @@ -61,6 +65,10 @@ name: "mac_chromium_10.10_rel_ng" experiment_percentage: 100 } + builders { + name: "mac_chromium_asan_rel_ng" + experiment_percentage: 10 + } } buckets { name: "tryserver.chromium.win"
diff --git a/infra/scripts/legacy/scripts/common/gtest_utils.py b/infra/scripts/legacy/scripts/common/gtest_utils.py deleted file mode 100755 index 4a307194..0000000 --- a/infra/scripts/legacy/scripts/common/gtest_utils.py +++ /dev/null
@@ -1,167 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2012 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import json -import os -import re -import tempfile - - -# These labels should match the ones output by gtest's JSON. -TEST_UNKNOWN_LABEL = 'UNKNOWN' -TEST_SUCCESS_LABEL = 'SUCCESS' -TEST_FAILURE_LABEL = 'FAILURE' -TEST_FAILURE_ON_EXIT_LABEL = 'FAILURE_ON_EXIT' -TEST_CRASH_LABEL = 'CRASH' -TEST_TIMEOUT_LABEL = 'TIMEOUT' -TEST_SKIPPED_LABEL = 'SKIPPED' -TEST_WARNING_LABEL = 'WARNING' - -FULL_RESULTS_FILENAME = 'full_results.json' -TIMES_MS_FILENAME = 'times_ms.json' - -def CompressList(lines, max_length, middle_replacement): - """Ensures that |lines| is no longer than |max_length|. If |lines| need to - be compressed then the middle items are replaced by |middle_replacement|. - """ - if len(lines) <= max_length: - return lines - remove_from_start = max_length / 2 - return (lines[:remove_from_start] + - [middle_replacement] + - lines[len(lines) - (max_length - remove_from_start):]) - - -class GTestJSONParser(object): - # Limit of output snippet lines. Avoids flooding the logs with amount - # of output that gums up the infrastructure. - OUTPUT_SNIPPET_LINES_LIMIT = 5000 - - def __init__(self, mastername=None): - self.json_file_path = None - self.delete_json_file = False - - self.disabled_tests = set() - self.passed_tests = set() - self.failed_tests = set() - self.flaky_tests = set() - self.test_logs = {} - self.run_results = {} - - self.parsing_errors = [] - - self.master_name = mastername - - # List our labels that match the ones output by gtest JSON. - self.SUPPORTED_LABELS = (TEST_UNKNOWN_LABEL, - TEST_SUCCESS_LABEL, - TEST_FAILURE_LABEL, - TEST_FAILURE_ON_EXIT_LABEL, - TEST_CRASH_LABEL, - TEST_TIMEOUT_LABEL, - TEST_SKIPPED_LABEL) - - def ProcessLine(self, line): - # Deliberately do nothing - we parse out-of-band JSON summary - # instead of in-band stdout. - pass - - def PassedTests(self): - return sorted(self.passed_tests) - - def FailedTests(self, include_fails=False, include_flaky=False): - return sorted(self.failed_tests) - - def TriesForTest(self, test): - """Returns a list containing the state for all tries of the given test.""" - return self.run_results.get(test, [TEST_UNKNOWN_LABEL]) - - def FailureDescription(self, test): - return self.test_logs.get(test, []) - - @staticmethod - def MemoryToolReportHashes(): - return [] - - def ParsingErrors(self): - return self.parsing_errors - - def ClearParsingErrors(self): - self.parsing_errors = ['Cleared.'] - - def DisabledTests(self): - return len(self.disabled_tests) - - def FlakyTests(self): - return len(self.flaky_tests) - - @staticmethod - def RunningTests(): - return [] - - def PrepareJSONFile(self, cmdline_path): - if cmdline_path: - self.json_file_path = cmdline_path - # If the caller requested JSON summary, do not delete it. - self.delete_json_file = False - else: - fd, self.json_file_path = tempfile.mkstemp() - os.close(fd) - # When we create the file ourselves, delete it to avoid littering. - self.delete_json_file = True - return self.json_file_path - - def ProcessJSONFile(self, build_dir): - if not self.json_file_path: - return - - with open(self.json_file_path) as json_file: - try: - json_output = json_file.read() - json_data = json.loads(json_output) - except ValueError: - # Only signal parsing error if the file is non-empty. Empty file - # most likely means the binary doesn't support JSON output. - if json_output: - self.parsing_errors = json_output.split('\n') - else: - self.ProcessJSONData(json_data, build_dir) - - if self.delete_json_file: - os.remove(self.json_file_path) - - def ProcessJSONData(self, json_data, build_dir=None): - self.disabled_tests.update(json_data['disabled_tests']) - - for iteration_data in json_data['per_iteration_data']: - for test_name, test_runs in iteration_data.iteritems(): - if test_runs[-1]['status'] == 'SUCCESS': - self.passed_tests.add(test_name) - else: - self.failed_tests.add(test_name) - - self.run_results[test_name] = [] - self.test_logs.setdefault(test_name, []) - for run_index, run_data in enumerate(test_runs, start=1): - # Mark as flaky if the run result differs. - if run_data['status'] != test_runs[0]['status']: - self.flaky_tests.add(test_name) - if run_data['status'] in self.SUPPORTED_LABELS: - self.run_results[test_name].append(run_data['status']) - else: - self.run_results[test_name].append(TEST_UNKNOWN_LABEL) - run_lines = ['%s (run #%d):' % (test_name, run_index)] - # Make sure the annotations are ASCII to avoid character set related - # errors. They are mostly informational anyway, and more detailed - # info can be obtained from the original JSON output. - ascii_lines = run_data['output_snippet'].encode('ascii', - errors='replace') - decoded_lines = CompressList( - ascii_lines.decode('string_escape').split('\n'), - self.OUTPUT_SNIPPET_LINES_LIMIT, - '<truncated, full output is in gzipped JSON ' - 'output at end of step>') - run_lines.extend(decoded_lines) - self.test_logs[test_name].extend(run_lines)
diff --git a/infra/scripts/legacy/scripts/slave/annotation_utils.py b/infra/scripts/legacy/scripts/slave/annotation_utils.py deleted file mode 100644 index 331daa2..0000000 --- a/infra/scripts/legacy/scripts/slave/annotation_utils.py +++ /dev/null
@@ -1,132 +0,0 @@ -# Copyright 2013 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Generates annotated output. - -TODO(stip): Move the gtest_utils gtest parser selection code from runtest.py -to here. -TODO(stip): Move the perf dashboard code from runtest.py to here. -""" - -import re - -from slave import slave_utils - - -# Status codes that can be returned by the evaluateCommand method. -# From buildbot.status.builder. -# See: http://docs.buildbot.net/current/developer/results.html -SUCCESS, WARNINGS, FAILURE, SKIPPED, EXCEPTION, RETRY = range(6) - - -def getText(result, observer, name): - """Generate a text summary for the waterfall. - - Updates the waterfall with any unusual test output, with a link to logs of - failed test steps. - """ - GTEST_DASHBOARD_BASE = ('http://test-results.appspot.com' - '/dashboards/flakiness_dashboard.html') - - # TODO(xusydoc): unify this with gtest reporting below so getText() is - # less confusing - if hasattr(observer, 'PerformanceSummary'): - basic_info = [name] - summary_text = ['<div class="BuildResultInfo">'] - summary_text.extend(observer.PerformanceSummary()) - summary_text.append('</div>') - return basic_info + summary_text - - # basic_info is an array of lines to display on the waterfall. - basic_info = [name] - - disabled = observer.DisabledTests() - if disabled: - basic_info.append('%s disabled' % str(disabled)) - - flaky = observer.FlakyTests() - if flaky: - basic_info.append('%s flaky' % str(flaky)) - - failed_test_count = len(observer.FailedTests()) - if failed_test_count == 0: - if result == SUCCESS: - return basic_info - elif result == WARNINGS: - return basic_info + ['warnings'] - - if observer.RunningTests(): - basic_info += ['did not complete'] - - # TODO(xusydoc): see if 'crashed or hung' should be tracked by RunningTests(). - if failed_test_count: - failure_text = ['failed %d' % failed_test_count] - if observer.master_name: - # Include the link to the flakiness dashboard. - failure_text.append('<div class="BuildResultInfo">') - failure_text.append('<a href="%s#testType=%s' - '&tests=%s">' % (GTEST_DASHBOARD_BASE, - name, - ','.join(observer.FailedTests()))) - failure_text.append('Flakiness dashboard') - failure_text.append('</a>') - failure_text.append('</div>') - else: - failure_text = ['crashed or hung'] - return basic_info + failure_text - - -def annotate(test_name, result, log_processor, perf_dashboard_id=None): - """Given a test result and tracker, update the waterfall with test results.""" - - # Always print raw exit code of the subprocess. This is very helpful - # for debugging, especially when one gets the "crashed or hung" message - # with no output (exit code can have some clues, especially on Windows). - print 'exit code (as seen by runtest.py): %d' % result - - get_text_result = SUCCESS - - for failure in sorted(log_processor.FailedTests()): - clean_test_name = re.sub(r'[^\w\.\-]', '_', failure) - slave_utils.WriteLogLines(clean_test_name, - log_processor.FailureDescription(failure)) - for report_hash in sorted(log_processor.MemoryToolReportHashes()): - slave_utils.WriteLogLines(report_hash, - log_processor.MemoryToolReport(report_hash)) - - if log_processor.ParsingErrors(): - # Generate a log file containing the list of errors. - slave_utils.WriteLogLines('log parsing error(s)', - log_processor.ParsingErrors()) - - log_processor.ClearParsingErrors() - - if hasattr(log_processor, 'evaluateCommand'): - parser_result = log_processor.evaluateCommand('command') - if parser_result > result: - result = parser_result - - if result == SUCCESS: - if (len(log_processor.ParsingErrors()) or - len(log_processor.FailedTests()) or - len(log_processor.MemoryToolReportHashes())): - print '@@@STEP_WARNINGS@@@' - get_text_result = WARNINGS - elif result == slave_utils.WARNING_EXIT_CODE: - print '@@@STEP_WARNINGS@@@' - get_text_result = WARNINGS - else: - print '@@@STEP_FAILURE@@@' - get_text_result = FAILURE - - for desc in getText(get_text_result, log_processor, test_name): - print '@@@STEP_TEXT@%s@@@' % desc - - if hasattr(log_processor, 'PerformanceLogs'): - if not perf_dashboard_id: - raise Exception('runtest.py error: perf step specified but' - 'no test_id in factory_properties!') - for logname, log in log_processor.PerformanceLogs().iteritems(): - lines = [str(l).rstrip() for l in log] - slave_utils.WriteLogLines(logname, lines, perf=perf_dashboard_id)
diff --git a/infra/scripts/legacy/scripts/slave/runtest.py b/infra/scripts/legacy/scripts/slave/runtest.py index 0bf9d1a3..ac54b3d 100755 --- a/infra/scripts/legacy/scripts/slave/runtest.py +++ b/infra/scripts/legacy/scripts/slave/runtest.py
@@ -21,9 +21,7 @@ import sys from common import chromium_utils -from common import gtest_utils -from slave import annotation_utils from slave import build_directory from slave import slave_utils from slave import xvfb @@ -120,13 +118,6 @@ return command -def _UsingGtestJson(options): - """Returns True if we're using GTest JSON summary.""" - return (options.annotate == 'gtest' and - not options.run_python_script and - not options.run_shell_script) - - def _GenerateRunIsolatedCommand(build_dir, test_exe_path, options, command): """Converts the command to run through the run isolate script. @@ -158,23 +149,6 @@ return command -def _SymbolizeSnippetsInJSON(options, json_file_name): - if not json_file_name: - return - symbolize_command = _GetSanitizerSymbolizeCommand( - strip_path_prefix=options.strip_path_prefix, - json_file_name=json_file_name) - try: - p = subprocess.Popen(symbolize_command, stderr=subprocess.PIPE) - (_, stderr) = p.communicate() - except OSError as e: - print 'Exception while symbolizing snippets: %s' % e - - if p.returncode != 0: - print "Error: failed to symbolize snippets in JSON:\n" - print stderr - - def _Main(options, args, extra_env): """Using the target build configuration, run the executable given in the first non-option argument, passing any following arguments to that @@ -240,10 +214,6 @@ command.extend(args[1:]) log_processor = None - if _UsingGtestJson(options): - log_processor = gtest_utils.GTestJSONParser( - options.build_properties.get('mastername')) - try: # TODO(dpranke): checking on test_exe is a temporary hack until we # can change the buildbot master to pass --xvfb instead of --no-xvfb @@ -260,10 +230,9 @@ with_wm=(options.factory_properties.get('window_manager', 'True') == 'True')) - if _UsingGtestJson(options): - json_file_name = log_processor.PrepareJSONFile( - options.test_launcher_summary_output) - command.append('--test-launcher-summary-output=%s' % json_file_name) + if options.test_launcher_summary_output: + command.append('--test-launcher-summary-output=%s' % + options.test_launcher_summary_output) command = _GenerateRunIsolatedCommand(build_dir, test_exe_path, options, command) @@ -302,13 +271,6 @@ finally: if start_xvfb: xvfb.StopVirtualX(None) - if _UsingGtestJson(options): - if options.use_symbolization_script: - _SymbolizeSnippetsInJSON(options, json_file_name) - log_processor.ProcessJSONFile(options.build_dir) - - if options.annotate: - annotation_utils.annotate(options.test_type, result, log_processor) return result
diff --git a/ipc/ipc_channel_reader.cc b/ipc/ipc_channel_reader.cc index 326c6d7e..de6a128 100644 --- a/ipc/ipc_channel_reader.cc +++ b/ipc/ipc_channel_reader.cc
@@ -6,6 +6,7 @@ #include <algorithm> +#include "base/metrics/histogram_macros.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_logging.h" #include "ipc/ipc_message.h" @@ -95,6 +96,10 @@ int pickle_len = static_cast<int>(info.pickle_end - p); Message translated_message(p, pickle_len); + UMA_HISTOGRAM_MEMORY_KB( + "Memory.IPCChannelReader.ReceivedMessageSize", + static_cast<base::HistogramBase::Sample>(translated_message.size())); + for (const auto& id : info.attachment_ids) translated_message.AddPlaceholderBrokerableAttachmentWithId(id);
diff --git a/mandoline/ui/omnibox/omnibox_application.cc b/mandoline/ui/omnibox/omnibox_application.cc index 893c0a3..7c3eb17 100644 --- a/mandoline/ui/omnibox/omnibox_application.cc +++ b/mandoline/ui/omnibox/omnibox_application.cc
@@ -190,7 +190,9 @@ void OmniboxImpl::GetViewTreeClient( mojo::InterfaceRequest<mojo::ViewTreeClient> request) { - mus::ViewTreeConnection::Create(this, request.Pass()); + mus::ViewTreeConnection::Create( + this, request.Pass(), + mus::ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED); } void OmniboxImpl::ShowForURL(const mojo::String& url) {
diff --git a/media/blink/mock_weburlloader.h b/media/blink/mock_weburlloader.h index 70dd5a6..68cf6da 100644 --- a/media/blink/mock_weburlloader.h +++ b/media/blink/mock_weburlloader.h
@@ -23,6 +23,7 @@ blink::WebURLLoaderClient* client)); MOCK_METHOD0(cancel, void()); MOCK_METHOD1(setDefersLoading, void(bool value)); + MOCK_METHOD1(setLoadingTaskRunner, void(blink::WebTaskRunner* task_runner)); private: DISALLOW_COPY_AND_ASSIGN(MockWebURLLoader);
diff --git a/media/cast/cast_defines.h b/media/cast/cast_defines.h index f4fb3c8..11a1bfd2 100644 --- a/media/cast/cast_defines.h +++ b/media/cast/cast_defines.h
@@ -74,6 +74,10 @@ kDefaultRtcpIntervalMs = 500, kDefaultRtpHistoryMs = 1000, kDefaultRtpMaxDelayMs = 100, + kDefaultRtpAudioPayloadType = 127, + kDefaultRtpVideoPayloadType = 96, + kDefaultMinVideoBitRate = 50, + kDefaultMaxVideoBitRate = 2000, }; enum PacketType {
diff --git a/media/cast/test/receiver.cc b/media/cast/test/receiver.cc index ccaf37e..6c07e378 100644 --- a/media/cast/test/receiver.cc +++ b/media/cast/test/receiver.cc
@@ -122,8 +122,8 @@ void GetAudioPayloadtype(FrameReceiverConfig* audio_config) { test::InputBuilder input("Choose audio receiver payload type.", DEFAULT_AUDIO_PAYLOAD_TYPE, - 96, - 127); + kDefaultRtpVideoPayloadType /* low_range */, + kDefaultRtpAudioPayloadType /* high_range */); audio_config->rtp_payload_type = input.GetIntInput(); } @@ -138,8 +138,8 @@ void GetVideoPayloadtype(FrameReceiverConfig* video_config) { test::InputBuilder input("Choose video receiver payload type.", DEFAULT_VIDEO_PAYLOAD_TYPE, - 96, - 127); + kDefaultRtpVideoPayloadType /* low_range */, + kDefaultRtpAudioPayloadType /* high_range */); video_config->rtp_payload_type = input.GetIntInput(); }
diff --git a/media/cast/test/utility/default_config.cc b/media/cast/test/utility/default_config.cc index ccb60a4..b1b0cc2 100644 --- a/media/cast/test/utility/default_config.cc +++ b/media/cast/test/utility/default_config.cc
@@ -5,6 +5,7 @@ #include "media/cast/test/utility/default_config.h" #include "base/bind.h" +#include "media/cast/cast_config.h" #include "media/cast/net/cast_transport_config.h" namespace { @@ -30,7 +31,7 @@ config.receiver_ssrc = 2; config.sender_ssrc = 1; config.rtp_max_delay_ms = kDefaultRtpMaxDelayMs; - config.rtp_payload_type = 127; + config.rtp_payload_type = kDefaultRtpAudioPayloadType; config.rtp_timebase = 48000; config.channels = 2; config.target_frame_rate = 100; // 10ms of signal per frame @@ -43,7 +44,7 @@ config.receiver_ssrc = 12; config.sender_ssrc = 11; config.rtp_max_delay_ms = kDefaultRtpMaxDelayMs; - config.rtp_payload_type = 96; + config.rtp_payload_type = kDefaultRtpVideoPayloadType; config.rtp_timebase = kVideoFrequency; config.channels = 1; config.target_frame_rate = kDefaultMaxFrameRate;
diff --git a/media/midi/java/src/org/chromium/media/midi/MidiOutputPortAndroid.java b/media/midi/java/src/org/chromium/media/midi/MidiOutputPortAndroid.java index 8de149b..00ff9a0 100644 --- a/media/midi/java/src/org/chromium/media/midi/MidiOutputPortAndroid.java +++ b/media/midi/java/src/org/chromium/media/midi/MidiOutputPortAndroid.java
@@ -36,7 +36,7 @@ */ private final int mIndex; - private static final String TAG = "cr.media.midi"; + private static final String TAG = "media_midi"; /** * constructor
diff --git a/mojo/gles2/command_buffer_client_impl.cc b/mojo/gles2/command_buffer_client_impl.cc index d642953..172ceca 100644 --- a/mojo/gles2/command_buffer_client_impl.cc +++ b/mojo/gles2/command_buffer_client_impl.cc
@@ -423,4 +423,14 @@ return release != 0 && release <= flushed_fence_sync_release_; } +bool CommandBufferClientImpl::IsFenceSyncFlushReceived(uint64_t release) { + return IsFenceSyncFlushed(release); +} + +bool CommandBufferClientImpl::CanWaitUnverifiedSyncToken( + const gpu::SyncToken* sync_token) { + // All sync tokens must be flushed before being waited on. + return false; +} + } // namespace gles2
diff --git a/mojo/gles2/command_buffer_client_impl.h b/mojo/gles2/command_buffer_client_impl.h index 2c3c925..b4ead3b0d 100644 --- a/mojo/gles2/command_buffer_client_impl.h +++ b/mojo/gles2/command_buffer_client_impl.h
@@ -79,6 +79,8 @@ uint64_t GenerateFenceSyncRelease() override; bool IsFenceSyncRelease(uint64_t release) override; bool IsFenceSyncFlushed(uint64_t release) override; + bool IsFenceSyncFlushReceived(uint64_t release) override; + bool CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) override; private: class SyncClientImpl;
diff --git a/mojo/gpu/mojo_gles2_impl_autogen.cc b/mojo/gpu/mojo_gles2_impl_autogen.cc index f256ba0..30767c17 100644 --- a/mojo/gpu/mojo_gles2_impl_autogen.cc +++ b/mojo/gpu/mojo_gles2_impl_autogen.cc
@@ -1666,6 +1666,11 @@ MojoGLES2MakeCurrent(context_); glGenSyncTokenCHROMIUM(fence_sync, sync_token); } +void MojoGLES2Impl::GenUnverifiedSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token) { + MojoGLES2MakeCurrent(context_); + glGenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token); +} void MojoGLES2Impl::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) { MojoGLES2MakeCurrent(context_); glWaitSyncTokenCHROMIUM(sync_token);
diff --git a/mojo/gpu/mojo_gles2_impl_autogen.h b/mojo/gpu/mojo_gles2_impl_autogen.h index 6d9d0a8..457054ab 100644 --- a/mojo/gpu/mojo_gles2_impl_autogen.h +++ b/mojo/gpu/mojo_gles2_impl_autogen.h
@@ -767,6 +767,8 @@ void WaitSyncPointCHROMIUM(GLuint sync_point) override; GLuint64 InsertFenceSyncCHROMIUM() override; void GenSyncTokenCHROMIUM(GLuint64 fence_sync, GLbyte* sync_token) override; + void GenUnverifiedSyncTokenCHROMIUM(GLuint64 fence_sync, + GLbyte* sync_token) override; void WaitSyncTokenCHROMIUM(const GLbyte* sync_token) override; void DrawBuffersEXT(GLsizei count, const GLenum* bufs) override; void DiscardBackbufferCHROMIUM() override;
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc index 8833729..cf82a5b 100644 --- a/net/disk_cache/backend_unittest.cc +++ b/net/disk_cache/backend_unittest.cc
@@ -89,6 +89,10 @@ std::set<std::string>* keys_to_match, size_t* count); + // Computes the expected size of entry metadata, i.e. the total size without + // the actual data stored. This depends only on the entry's |key| size. + int GetEntryMetadataSize(std::string key); + // Actual tests: void BackendBasics(); void BackendKeying(); @@ -282,6 +286,18 @@ return true; } +int DiskCacheBackendTest::GetEntryMetadataSize(std::string key) { + // For blockfile and memory backends, it is just the key size. + if (!simple_cache_mode_) + return key.size(); + + // For the simple cache, we must add the file header and EOF, and that for + // every stream. + return disk_cache::kSimpleEntryStreamCount * + (sizeof(disk_cache::SimpleFileHeader) + + sizeof(disk_cache::SimpleFileEOF) + key.size()); +} + void DiskCacheBackendTest::BackendBasics() { InitCache(); disk_cache::Entry *entry1 = NULL, *entry2 = NULL; @@ -1679,12 +1695,7 @@ InitCache(); // The cache is initially empty. - if (memory_only_ || simple_cache_mode_) { - // TODO(msramek): Implement. - EXPECT_EQ(net::ERR_NOT_IMPLEMENTED, CalculateSizeOfAllEntries()); - } else { - EXPECT_EQ(0, CalculateSizeOfAllEntries()); - } + EXPECT_EQ(0, CalculateSizeOfAllEntries()); // Generate random entries and populate them with data of respective // sizes 0, 1, ..., count - 1 bytes. @@ -1697,10 +1708,15 @@ scoped_refptr<net::StringIOBuffer> buffer = new net::StringIOBuffer(data); // Alternate between writing to the first and second stream to test that - // we are not taking just the first stream into account. + // we are not taking just the first stream into account. For convenience, + // the last written stream should be 0. This is because writing to + // the stream 1 in simple cache triggers a write to the stream 0 as well. + // This will happen asynchronously and possibly later than our call to + // |CalculateSizeOfAllEntries|. disk_cache::Entry* entry; ASSERT_EQ(net::OK, OpenEntry(key, &entry)); - ASSERT_EQ(count, WriteData(entry, count % 2, 0, buffer.get(), count, true)); + ASSERT_EQ(count, + WriteData(entry, (count + 1) % 2, 0, buffer.get(), count, true)); entry->Close(); ++count; @@ -1708,16 +1724,10 @@ // The resulting size should be (0 + 1 + ... + count - 1) plus keys. int result = CalculateSizeOfAllEntries(); - if (memory_only_ || simple_cache_mode_) { - // TODO(msramek): Implement. - EXPECT_EQ(net::ERR_NOT_IMPLEMENTED, result); - } else { - int total_key_size = 0; - for (std::string key : key_pool) - total_key_size += key.size(); - - EXPECT_EQ((count - 1) * count / 2 + total_key_size, result); - } + int total_metadata_size = 0; + for (std::string key : key_pool) + total_metadata_size += GetEntryMetadataSize(key); + EXPECT_EQ((count - 1) * count / 2 + total_metadata_size, result); // Add another entry and test if the size is updated. Then remove it and test // if the size is back to original value. @@ -1734,32 +1744,16 @@ entry->Close(); int new_result = CalculateSizeOfAllEntries(); - if (memory_only_ || simple_cache_mode_) { - // TODO(msramek): Implement. - EXPECT_EQ(net::ERR_NOT_IMPLEMENTED, new_result); - } else { - EXPECT_EQ(result + last_entry_size + static_cast<int>(key.size()), - new_result); - } + EXPECT_EQ(result + last_entry_size + GetEntryMetadataSize(key), new_result); DoomEntry(key); new_result = CalculateSizeOfAllEntries(); - if (memory_only_ || simple_cache_mode_) { - // TODO(msramek): Implement. - EXPECT_EQ(net::ERR_NOT_IMPLEMENTED, new_result); - } else { - EXPECT_EQ(result, new_result); - } + EXPECT_EQ(result, new_result); } // After dooming the entries, the size should be back to zero. ASSERT_EQ(net::OK, DoomAllEntries()); - if (memory_only_ || simple_cache_mode_) { - // TODO(msramek): Implement. - EXPECT_EQ(net::ERR_NOT_IMPLEMENTED, CalculateSizeOfAllEntries()); - } else { - EXPECT_EQ(0, CalculateSizeOfAllEntries()); - } + EXPECT_EQ(0, CalculateSizeOfAllEntries()); } TEST_F(DiskCacheBackendTest, CalculateSizeOfAllEntries) {
diff --git a/net/disk_cache/memory/mem_backend_impl.cc b/net/disk_cache/memory/mem_backend_impl.cc index ca8cf1b..9948660 100644 --- a/net/disk_cache/memory/mem_backend_impl.cc +++ b/net/disk_cache/memory/mem_backend_impl.cc
@@ -184,8 +184,7 @@ int MemBackendImpl::CalculateSizeOfAllEntries( const CompletionCallback& callback) { - // TODO(msramek): Implement. - return net::ERR_NOT_IMPLEMENTED; + return current_size_; } class MemBackendImpl::MemIterator : public Backend::Iterator {
diff --git a/net/disk_cache/simple/simple_backend_impl.cc b/net/disk_cache/simple/simple_backend_impl.cc index f985e58a..d1c111e 100644 --- a/net/disk_cache/simple/simple_backend_impl.cc +++ b/net/disk_cache/simple/simple_backend_impl.cc
@@ -442,19 +442,6 @@ return DoomEntriesBetween(Time(), Time(), callback); } -void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, - Time end_time, - const CompletionCallback& callback, - int result) { - if (result != net::OK) { - callback.Run(result); - return; - } - scoped_ptr<std::vector<uint64> > removed_key_hashes( - index_->GetEntriesBetween(initial_time, end_time).release()); - DoomEntries(removed_key_hashes.get(), callback); -} - int SimpleBackendImpl::DoomEntriesBetween( const Time initial_time, const Time end_time, @@ -472,8 +459,8 @@ int SimpleBackendImpl::CalculateSizeOfAllEntries( const CompletionCallback& callback) { - // TODO(msramek): Implement. - return net::ERR_NOT_IMPLEMENTED; + return index_->ExecuteWhenReady(base::Bind( + &SimpleBackendImpl::IndexReadyForSizeCalculation, AsWeakPtr(), callback)); } class SimpleBackendImpl::SimpleIterator final : public Iterator { @@ -570,6 +557,27 @@ callback.Run(result.net_error); } +void SimpleBackendImpl::IndexReadyForDoom(Time initial_time, + Time end_time, + const CompletionCallback& callback, + int result) { + if (result != net::OK) { + callback.Run(result); + return; + } + scoped_ptr<std::vector<uint64>> removed_key_hashes( + index_->GetEntriesBetween(initial_time, end_time).release()); + DoomEntries(removed_key_hashes.get(), callback); +} + +void SimpleBackendImpl::IndexReadyForSizeCalculation( + const CompletionCallback& callback, + int result) { + if (result == net::OK) + result = static_cast<int>(index_->GetCacheSize()); + callback.Run(result); +} + SimpleBackendImpl::DiskStatResult SimpleBackendImpl::InitCacheStructureOnDisk( const base::FilePath& path, uint64 suggested_max_size) {
diff --git a/net/disk_cache/simple/simple_backend_impl.h b/net/disk_cache/simple/simple_backend_impl.h index c9debd0..c8cac2112 100644 --- a/net/disk_cache/simple/simple_backend_impl.h +++ b/net/disk_cache/simple/simple_backend_impl.h
@@ -140,6 +140,10 @@ const CompletionCallback& callback, int result); + // Calculates the size of the entire cache. Invoked when the index is ready. + void IndexReadyForSizeCalculation(const CompletionCallback& callback, + int result); + // Try to create the directory if it doesn't exist. This must run on the IO // thread. static DiskStatResult InitCacheStructureOnDisk(const base::FilePath& path,
diff --git a/net/disk_cache/simple/simple_index.cc b/net/disk_cache/simple/simple_index.cc index fd01abd..555780119d 100644 --- a/net/disk_cache/simple/simple_index.cc +++ b/net/disk_cache/simple/simple_index.cc
@@ -239,6 +239,11 @@ return entries_set_.size(); } +uint64 SimpleIndex::GetCacheSize() const { + DCHECK(initialized_); + return cache_size_; +} + void SimpleIndex::Insert(uint64 entry_hash) { DCHECK(io_thread_checker_.CalledOnValidThread()); // Upon insert we don't know yet the size of the entry.
diff --git a/net/disk_cache/simple/simple_index.h b/net/disk_cache/simple/simple_index.h index 11adab9..5a8046d 100644 --- a/net/disk_cache/simple/simple_index.h +++ b/net/disk_cache/simple/simple_index.h
@@ -130,6 +130,10 @@ // Returns number of indexed entries. int32 GetEntryCount() const; + // Returns the size of the entire cache in bytes. Can only be called after the + // index has been initialized. + uint64 GetCacheSize() const; + // Returns whether the index has been initialized yet. bool initialized() const { return initialized_; }
diff --git a/net/ftp/ftp_directory_listing_parser_vms.cc b/net/ftp/ftp_directory_listing_parser_vms.cc index eb92a19..2874548 100644 --- a/net/ftp/ftp_directory_listing_parser_vms.cc +++ b/net/ftp/ftp_directory_listing_parser_vms.cc
@@ -262,6 +262,9 @@ space, base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); } + if (columns.empty()) + return false; + FtpDirectoryListingEntry entry; if (!ParseVmsFilename(columns[0], &entry.name, &entry.type)) return false;
diff --git a/net/ftp/ftp_directory_listing_parser_vms_unittest.cc b/net/ftp/ftp_directory_listing_parser_vms_unittest.cc index 08ee9e1..f566481b 100644 --- a/net/ftp/ftp_directory_listing_parser_vms_unittest.cc +++ b/net/ftp/ftp_directory_listing_parser_vms_unittest.cc
@@ -165,6 +165,31 @@ } } +TEST_F(FtpDirectoryListingParserVmsTest, EmptyColumnZero) { + std::vector<base::string16> lines; + + // The parser requires a directory header before accepting regular input. + lines.push_back(ASCIIToUTF16("garbage")); + + base::char16 data[] = {0x0}; + lines.push_back(base::string16(data, 1)); + + std::vector<FtpDirectoryListingEntry> entries; + EXPECT_FALSE(ParseFtpDirectoryListingVms(lines, &entries)); +} + +TEST_F(FtpDirectoryListingParserVmsTest, EmptyColumnWhitespace) { + std::vector<base::string16> lines; + + // The parser requires a directory header before accepting regular input. + lines.push_back(ASCIIToUTF16("garbage")); + + lines.push_back(ASCIIToUTF16(" ")); + + std::vector<FtpDirectoryListingEntry> entries; + EXPECT_FALSE(ParseFtpDirectoryListingVms(lines, &entries)); +} + } // namespace } // namespace net
diff --git a/net/spdy/hpack/hpack_encoder.cc b/net/spdy/hpack/hpack_encoder.cc index 95adfe2..5a126e7f7 100644 --- a/net/spdy/hpack/hpack_encoder.cc +++ b/net/spdy/hpack/hpack_encoder.cc
@@ -23,9 +23,7 @@ huffman_table_(table), min_table_size_setting_received_(std::numeric_limits<size_t>::max()), allow_huffman_compression_(true), - should_emit_table_size_(false), - char_counts_(NULL), - total_char_counts_(NULL) {} + should_emit_table_size_(false) {} HpackEncoder::~HpackEncoder() {} @@ -156,24 +154,6 @@ output_stream_.AppendUint32(str.size()); output_stream_.AppendBytes(str); } - UpdateCharacterCounts(str); -} - -void HpackEncoder::SetCharCountsStorage(std::vector<size_t>* char_counts, - size_t* total_char_counts) { - CHECK_LE(256u, char_counts->size()); - char_counts_ = char_counts; - total_char_counts_ = total_char_counts; -} - -void HpackEncoder::UpdateCharacterCounts(base::StringPiece str) { - if (char_counts_ == NULL || total_char_counts_ == NULL) { - return; - } - for (StringPiece::const_iterator it = str.begin(); it != str.end(); ++it) { - ++(*char_counts_)[static_cast<uint8>(*it)]; - } - (*total_char_counts_) += str.size(); } void HpackEncoder::MaybeEmitTableSize() {
diff --git a/net/spdy/hpack/hpack_encoder.h b/net/spdy/hpack/hpack_encoder.h index 37c0783b..8b0865f 100644 --- a/net/spdy/hpack/hpack_encoder.h +++ b/net/spdy/hpack/hpack_encoder.h
@@ -53,11 +53,6 @@ // SETTINGS_HEADER_TABLE_SIZE update from the remote decoding endpoint. void ApplyHeaderTableSizeSetting(size_t size_setting); - // Sets externally-owned storage for aggregating character counts of emitted - // literal representations. - void SetCharCountsStorage(std::vector<size_t>* char_counts, - size_t* total_char_counts); - size_t CurrentHeaderTableSizeSetting() const { return header_table_.settings_size_bound(); } @@ -77,8 +72,6 @@ // Emits a Huffman or identity string (whichever is smaller). void EmitString(base::StringPiece str); - void UpdateCharacterCounts(base::StringPiece str); - // Emits the current dynamic table size if the table size was recently // updated and we have not yet emitted it (Section 6.3). void MaybeEmitTableSize(); @@ -99,10 +92,6 @@ bool allow_huffman_compression_; bool should_emit_table_size_; - // Externally-owned, nullable storage for character counts of literals. - std::vector<size_t>* char_counts_; - size_t* total_char_counts_; - DISALLOW_COPY_AND_ASSIGN(HpackEncoder); };
diff --git a/net/spdy/hpack/hpack_encoder_test.cc b/net/spdy/hpack/hpack_encoder_test.cc index 0790a5b7..441d724 100644 --- a/net/spdy/hpack/hpack_encoder_test.cc +++ b/net/spdy/hpack/hpack_encoder_test.cc
@@ -44,9 +44,6 @@ } void EmitString(StringPiece str) { encoder_->EmitString(str); } void TakeString(string* out) { encoder_->output_stream_.TakeString(out); } - void UpdateCharacterCounts(StringPiece str) { - encoder_->UpdateCharacterCounts(str); - } static void CookieToCrumbs(StringPiece cookie, std::vector<StringPiece>* out) { Representations tmp; @@ -401,29 +398,6 @@ EXPECT_THAT(out, ElementsAre("foo=1", "bar=2 ", "bar=3")); } -TEST_F(HpackEncoderTest, UpdateCharacterCounts) { - std::vector<size_t> counts(256, 0); - size_t total_counts = 0; - encoder_.SetCharCountsStorage(&counts, &total_counts); - - char kTestString[] = - "foo\0\1\xff" - "boo"; - peer_.UpdateCharacterCounts( - StringPiece(kTestString, arraysize(kTestString) - 1)); - - std::vector<size_t> expect(256, 0); - expect[static_cast<uint8>('f')] = 1; - expect[static_cast<uint8>('o')] = 4; - expect[static_cast<uint8>('\0')] = 1; - expect[static_cast<uint8>('\1')] = 1; - expect[static_cast<uint8>('\xff')] = 1; - expect[static_cast<uint8>('b')] = 1; - - EXPECT_EQ(expect, counts); - EXPECT_EQ(9u, total_counts); -} - TEST_F(HpackEncoderTest, DecomposeRepresentation) { test::HpackEncoderPeer peer(NULL); std::vector<StringPiece> out;
diff --git a/net/test/android/javatests/src/org/chromium/net/test/BaseTestServer.java b/net/test/android/javatests/src/org/chromium/net/test/BaseTestServer.java index 049306b..75f1272 100644 --- a/net/test/android/javatests/src/org/chromium/net/test/BaseTestServer.java +++ b/net/test/android/javatests/src/org/chromium/net/test/BaseTestServer.java
@@ -10,7 +10,7 @@ /** A base class for simple test servers. */ public abstract class BaseTestServer implements Runnable { - private static final String TAG = "cr.net.test"; + private static final String TAG = "net_test"; private AtomicBoolean mKeepRunning; private final Object mLock;
diff --git a/net/url_request/test_url_fetcher_factory.cc b/net/url_request/test_url_fetcher_factory.cc index 6f9344b..048b8dd 100644 --- a/net/url_request/test_url_fetcher_factory.cc +++ b/net/url_request/test_url_fetcher_factory.cc
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/files/file_util.h" #include "base/location.h" +#include "base/logging.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "base/thread_task_runner_handle.h" @@ -47,6 +48,7 @@ fake_load_flags_(0), fake_response_code_(-1), fake_response_destination_(STRING), + write_response_file_(false), fake_was_fetched_via_proxy_(false), fake_was_cached_(false), fake_response_bytes_(0), @@ -155,16 +157,17 @@ void TestURLFetcher::SaveResponseToFileAtPath( const base::FilePath& file_path, scoped_refptr<base::SequencedTaskRunner> file_task_runner) { + write_response_file_ = true; SetResponseFilePath(file_path); // Asynchronous IO is not supported, so file_task_runner is ignored. - base::ThreadRestrictions::ScopedAllowIO allow_io; - const size_t written_bytes = base::WriteFile( - file_path, fake_response_string_.c_str(), fake_response_string_.size()); - DCHECK_EQ(written_bytes, fake_response_string_.size()); } void TestURLFetcher::SaveResponseToTemporaryFile( scoped_refptr<base::SequencedTaskRunner> file_task_runner) { + base::FilePath path; + if (!base::CreateTemporaryFile(&path)) + DLOG(ERROR) << "SaveResponseToTemporaryFile failed creating temp file"; + SaveResponseToFileAtPath(path, file_task_runner); } void TestURLFetcher::SaveResponseWithWriter( @@ -227,6 +230,16 @@ // Overriden to do nothing. It is assumed the caller will notify the delegate. if (delegate_for_tests_) delegate_for_tests_->OnRequestStart(id_); + + // If the response should go into a file, write it out now. + if (fake_status_.is_success() && fake_response_code_ == net::HTTP_OK && + write_response_file_ && !fake_response_file_path_.empty()) { + base::ThreadRestrictions::ScopedAllowIO allow_io; + size_t written_bytes = + base::WriteFile(fake_response_file_path_, fake_response_string_.c_str(), + fake_response_string_.size()); + DCHECK_EQ(fake_response_string_.size(), written_bytes); + } } const GURL& TestURLFetcher::GetOriginalURL() const { @@ -379,6 +392,7 @@ FakeURLFetcher::~FakeURLFetcher() {} void FakeURLFetcher::Start() { + TestURLFetcher::Start(); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&FakeURLFetcher::RunDelegate, weak_factory_.GetWeakPtr()));
diff --git a/net/url_request/test_url_fetcher_factory.h b/net/url_request/test_url_fetcher_factory.h index 18360bd..75cdebf 100644 --- a/net/url_request/test_url_fetcher_factory.h +++ b/net/url_request/test_url_fetcher_factory.h
@@ -229,6 +229,7 @@ ResponseDestinationType fake_response_destination_; std::string fake_response_string_; base::FilePath fake_response_file_path_; + bool write_response_file_; bool fake_was_fetched_via_proxy_; bool fake_was_cached_; int64 fake_response_bytes_;
diff --git a/net/url_request/url_fetcher_core.cc b/net/url_request/url_fetcher_core.cc index 1dafe84..1ecf9e54 100644 --- a/net/url_request/url_fetcher_core.cc +++ b/net/url_request/url_fetcher_core.cc
@@ -7,14 +7,12 @@ #include <stdint.h> #include "base/bind.h" -#include "base/debug/dump_without_crashing.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/profiler/scoped_tracker.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" -#include "base/strings/string_util.h" #include "base/thread_task_runner_handle.h" #include "base/tracked_objects.h" #include "net/base/elements_upload_data_stream.h" @@ -737,22 +735,6 @@ } void URLFetcherCore::DidFinishWriting(int result) { - // Record a stack trace if saved more than 1 MB to an in-memory string. - // TODO(mmenke): Remove once a hard limit on the URLFetcherStringWriter's - // buffer size has been implemented. See https://crbug.com/535601. - URLFetcherStringWriter* string_writer = - response_writer_ ? response_writer_->AsStringWriter() : nullptr; - if (string_writer && string_writer->data().size() > 1024 * 1024) { - char url_buf[128]; - base::strlcpy(url_buf, original_url_.spec().c_str(), arraysize(url_buf)); - size_t response_size = string_writer->data().size(); - base::debug::StackTrace stack_trace = stack_trace_; - base::debug::Alias(url_buf); - base::debug::Alias(&response_size); - base::debug::Alias(&stack_trace); - base::debug::DumpWithoutCrashing(); - } - if (result != OK) { CancelRequestAndInformDelegate(result); return;
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.cc b/ppapi/proxy/ppapi_command_buffer_proxy.cc index 56e7486..c404b8a 100644 --- a/ppapi/proxy/ppapi_command_buffer_proxy.cc +++ b/ppapi/proxy/ppapi_command_buffer_proxy.cc
@@ -204,6 +204,15 @@ return release <= flushed_fence_sync_release_; } +bool PpapiCommandBufferProxy::IsFenceSyncFlushReceived(uint64_t release) { + return IsFenceSyncFlushed(release); +} + +bool PpapiCommandBufferProxy::CanWaitUnverifiedSyncToken( + const gpu::SyncToken* sync_token) { + return false; +} + uint32 PpapiCommandBufferProxy::InsertSyncPoint() { uint32 sync_point = 0; if (last_state_.error == gpu::error::kNoError) {
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.h b/ppapi/proxy/ppapi_command_buffer_proxy.h index dc480579..c8f588d 100644 --- a/ppapi/proxy/ppapi_command_buffer_proxy.h +++ b/ppapi/proxy/ppapi_command_buffer_proxy.h
@@ -73,6 +73,8 @@ uint64_t GenerateFenceSyncRelease() override; bool IsFenceSyncRelease(uint64_t release) override; bool IsFenceSyncFlushed(uint64_t release) override; + bool IsFenceSyncFlushReceived(uint64_t release) override; + bool CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) override; private: bool Send(IPC::Message* msg);
diff --git a/storage/browser/BUILD.gn b/storage/browser/BUILD.gn index 6206f37..e3bfa81 100644 --- a/storage/browser/BUILD.gn +++ b/storage/browser/BUILD.gn
@@ -18,6 +18,8 @@ "blob/blob_reader.h", "blob/blob_storage_context.cc", "blob/blob_storage_context.h", + "blob/blob_storage_registry.cc", + "blob/blob_storage_registry.h", "blob/blob_url_request_job.cc", "blob/blob_url_request_job.h", "blob/blob_url_request_job_factory.cc",
diff --git a/storage/browser/blob/blob_storage_registry.cc b/storage/browser/blob/blob_storage_registry.cc new file mode 100644 index 0000000..805a677d --- /dev/null +++ b/storage/browser/blob/blob_storage_registry.cc
@@ -0,0 +1,116 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "storage/browser/blob/blob_storage_registry.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "base/stl_util.h" +#include "url/gurl.h" + +namespace storage { +using BlobState = BlobStorageRegistry::BlobState; + +namespace { +// We can't use GURL directly for these hash fragment manipulations +// since it doesn't have specific knowlege of the BlobURL format. GURL +// treats BlobURLs as if they were PathURLs which don't support hash +// fragments. + +bool BlobUrlHasRef(const GURL& url) { + return url.spec().find('#') != std::string::npos; +} + +GURL ClearBlobUrlRef(const GURL& url) { + size_t hash_pos = url.spec().find('#'); + if (hash_pos == std::string::npos) + return url; + return GURL(url.spec().substr(0, hash_pos)); +} + +} // namespace + +BlobStorageRegistry::Entry::Entry(int refcount, BlobState state) + : refcount(refcount), state(state), exceeded_memory(false) {} + +BlobStorageRegistry::Entry::~Entry() {} + +bool BlobStorageRegistry::Entry::TestAndSetState(BlobState expected, + BlobState set) { + if (state != expected) + return false; + state = set; + return true; +} + +BlobStorageRegistry::BlobStorageRegistry() {} + +BlobStorageRegistry::~BlobStorageRegistry() { + // Note: We don't bother calling the construction complete callbacks, as we + // are only being destructed at the end of the life of the browser process. + // So it shouldn't matter. +} + +BlobStorageRegistry::Entry* BlobStorageRegistry::CreateEntry( + const std::string& uuid) { + DCHECK(!ContainsKey(blob_map_, uuid)); + Entry* entry = new Entry(1, BlobState::RESERVED); + blob_map_.add(uuid, make_scoped_ptr(entry)); + return entry; +} + +bool BlobStorageRegistry::DeleteEntry(const std::string& uuid) { + return blob_map_.erase(uuid) == 1; +} + +BlobStorageRegistry::Entry* BlobStorageRegistry::GetEntry( + const std::string& uuid) { + BlobMap::iterator found = blob_map_.find(uuid); + if (found == blob_map_.end()) + return nullptr; + return found->second; +} + +bool BlobStorageRegistry::CreateUrlMapping(const GURL& blob_url, + const std::string& uuid) { + DCHECK(!BlobUrlHasRef(blob_url)); + if (blob_map_.find(uuid) == blob_map_.end() || IsURLMapped(blob_url)) + return false; + url_to_uuid_[blob_url] = uuid; + return true; +} + +bool BlobStorageRegistry::DeleteURLMapping(const GURL& blob_url, + std::string* uuid) { + DCHECK(!BlobUrlHasRef(blob_url)); + URLMap::iterator found = url_to_uuid_.find(blob_url); + if (found == url_to_uuid_.end()) + return false; + if (uuid) + uuid->assign(found->second); + url_to_uuid_.erase(found); + return true; +} + +bool BlobStorageRegistry::IsURLMapped(const GURL& blob_url) const { + return ContainsKey(url_to_uuid_, blob_url); +} + +BlobStorageRegistry::Entry* BlobStorageRegistry::GetEntryFromURL( + const GURL& url, + std::string* uuid) { + URLMap::iterator found = + url_to_uuid_.find(BlobUrlHasRef(url) ? ClearBlobUrlRef(url) : url); + if (found == url_to_uuid_.end()) + return nullptr; + Entry* entry = GetEntry(found->second); + if (entry && uuid) + uuid->assign(found->second); + return entry; +} + +} // namespace storage
diff --git a/storage/browser/blob/blob_storage_registry.h b/storage/browser/blob/blob_storage_registry.h new file mode 100644 index 0000000..8a79493e --- /dev/null +++ b/storage/browser/blob/blob_storage_registry.h
@@ -0,0 +1,108 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef STORAGE_BROWSER_BLOB_BLOB_STORAGE_REGISTRY_H_ +#define STORAGE_BROWSER_BLOB_BLOB_STORAGE_REGISTRY_H_ + +#include <map> +#include <string> +#include <vector> + +#include "base/callback_forward.h" +#include "base/containers/scoped_ptr_hash_map.h" +#include "base/macros.h" +#include "storage/browser/blob/internal_blob_data.h" +#include "storage/browser/storage_browser_export.h" + +class GURL; + +namespace storage { + +// This class stores the blob data in the various states of construction, as +// well as URL mappings to blob uuids. +// Implementation notes: +// * There is no implicit refcounting in this class, except for setting the +// refcount to 1 on registration. +// * When removing a uuid registration, we do not check for URL mappings to that +// uuid. The user must keep track of these. +class STORAGE_EXPORT BlobStorageRegistry { + public: + enum class BlobState { + // First the renderer reserves the uuid. + RESERVED = 1, + // Second, we are asynchronously transporting data to the browser. + ASYNC_TRANSPORTATION, + // Third, we construct the blob when we have all of the data. + CONSTRUCTION, + // Finally, the blob is built. + ACTIVE + }; + + struct STORAGE_EXPORT Entry { + size_t refcount; + BlobState state; + std::vector<base::Callback<void(bool)>> construction_complete_callbacks; + + // Flags + bool exceeded_memory; + + // data and data_builder are mutually exclusive. + scoped_ptr<InternalBlobData> data; + scoped_ptr<InternalBlobData::Builder> data_builder; + + Entry() = delete; + Entry(int refcount, BlobState state); + ~Entry(); + + // Performs a test-and-set on the state of the given blob. If the state + // isn't as expected, we return false. Otherwise we set the new state and + // return true. + bool TestAndSetState(BlobState expected, BlobState set); + }; + + BlobStorageRegistry(); + ~BlobStorageRegistry(); + + // Creates the blob entry with a refcount of 1 and a state of RESERVED. If + // the blob is already in use, we return null. + Entry* CreateEntry(const std::string& uuid); + + // Removes the blob entry with the given uuid. This does not unmap any + // URLs that are pointing to this uuid. Returns if the entry existed. + bool DeleteEntry(const std::string& uuid); + + // Gets the blob entry for the given uuid. Returns nullptr if the entry + // does not exist. + Entry* GetEntry(const std::string& uuid); + + // Creates a url mapping from blob uuid to the given url. Returns false if + // the uuid isn't mapped to an entry or if there already is a map for the URL. + bool CreateUrlMapping(const GURL& url, const std::string& uuid); + + // Removes the given URL mapping. Optionally populates a uuid string of the + // removed entry uuid. Returns false if the url isn't mapped. + bool DeleteURLMapping(const GURL& url, std::string* uuid); + + // Returns if the url is mapped to a blob uuid. + bool IsURLMapped(const GURL& blob_url) const; + + // Returns the entry from the given url, and optionally populates the uuid for + // that entry. Returns a nullptr if the mapping or entry doesn't exist. + Entry* GetEntryFromURL(const GURL& url, std::string* uuid); + + size_t blob_count() const { return blob_map_.size(); } + size_t url_count() const { return url_to_uuid_.size(); } + + private: + using BlobMap = base::ScopedPtrHashMap<std::string, scoped_ptr<Entry>>; + using URLMap = std::map<GURL, std::string>; + + BlobMap blob_map_; + URLMap url_to_uuid_; + + DISALLOW_COPY_AND_ASSIGN(BlobStorageRegistry); +}; + +} // namespace storage +#endif // STORAGE_BROWSER_BLOB_BLOB_STORAGE_REGISTRY_H_
diff --git a/storage/browser/blob/internal_blob_data.h b/storage/browser/blob/internal_blob_data.h index aa47101..7ec2bf8b 100644 --- a/storage/browser/blob/internal_blob_data.h +++ b/storage/browser/blob/internal_blob_data.h
@@ -23,6 +23,7 @@ protected: friend class BlobStorageContext; + friend class BlobStorageRegistry; friend class ViewBlobInternalsJob; // Removes the given blob uuid from the internal ShareableBlobDataItems.
diff --git a/storage/storage_browser.gyp b/storage/storage_browser.gyp index de1d166..3f4b7ea 100644 --- a/storage/storage_browser.gyp +++ b/storage/storage_browser.gyp
@@ -37,6 +37,8 @@ 'browser/blob/blob_reader.h', 'browser/blob/blob_storage_context.cc', 'browser/blob/blob_storage_context.h', + 'browser/blob/blob_storage_registry.cc', + 'browser/blob/blob_storage_registry.h', 'browser/blob/blob_url_request_job.cc', 'browser/blob/blob_url_request_job.h', 'browser/blob/blob_url_request_job_factory.cc',
diff --git a/sync/android/java/src/org/chromium/sync/signin/AccountManagerHelper.java b/sync/android/java/src/org/chromium/sync/signin/AccountManagerHelper.java index ce696aa8..e7816e6 100644 --- a/sync/android/java/src/org/chromium/sync/signin/AccountManagerHelper.java +++ b/sync/android/java/src/org/chromium/sync/signin/AccountManagerHelper.java
@@ -38,7 +38,7 @@ * Use the AccountManagerHelper.get(someContext) to instantiate it */ public class AccountManagerHelper { - private static final String TAG = "cr.Sync.Signin"; + private static final String TAG = "Sync_Signin"; private static final Pattern AT_SYMBOL = Pattern.compile("@");
diff --git a/testing/android/reporter/java/src/org/chromium/test/reporter/TestStatusReceiver.java b/testing/android/reporter/java/src/org/chromium/test/reporter/TestStatusReceiver.java index df61396..f0a0d7e 100644 --- a/testing/android/reporter/java/src/org/chromium/test/reporter/TestStatusReceiver.java +++ b/testing/android/reporter/java/src/org/chromium/test/reporter/TestStatusReceiver.java
@@ -19,7 +19,7 @@ */ public class TestStatusReceiver extends BroadcastReceiver { - private static final String TAG = "cr.test.reporter"; + private static final String TAG = "test_reporter"; private final List<FailCallback> mFailCallbacks = new ArrayList<FailCallback>(); private final List<HeartbeatCallback> mHeartbeatCallbacks = new ArrayList<HeartbeatCallback>();
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 12993c58..dba727b 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -798,6 +798,705 @@ crbug.com/402379 [ Win7 Debug ] storage/indexeddb/cursor-continue-validity.html [ Pass Slow ] crbug.com/402379 [ Win7 Debug ] storage/indexeddb/mozilla/indexes.html [ Pass Slow ] +crbug.com/404597 css1/basic/class_as_selector.html [ NeedsRebaseline ] +crbug.com/404597 css1/basic/comments.html [ NeedsRebaseline ] +crbug.com/404597 css1/basic/containment.html [ NeedsRebaseline ] +crbug.com/404597 css1/basic/contextual_selectors.html [ NeedsRebaseline ] +crbug.com/404597 css1/basic/grouping.html [ NeedsRebaseline ] +crbug.com/404597 css1/basic/id_as_selector.html [ NeedsRebaseline ] +crbug.com/404597 css1/basic/inheritance.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/acid_test.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_bottom.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_bottom_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_bottom_width.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_bottom_width_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_color.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_color_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_left.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_left_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_left_width.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_left_width_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_right.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_right_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_right_width.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_right_width_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_style.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_style_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_top.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_top_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_top_width.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_top_width_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_width.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/border_width_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/clear.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/clear_float.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/float.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/float_elements_in_series.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/float_margin.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/float_on_text_elements.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/height.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/margin.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/margin_bottom.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/margin_bottom_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/margin_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/margin_left.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/margin_left_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/margin_right.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/margin_right_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/margin_top.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/margin_top_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/padding.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/padding_bottom.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/padding_bottom_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/padding_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/padding_left.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/padding_left_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/padding_right.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/padding_right_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/padding_top.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/padding_top_inline.html [ NeedsRebaseline ] +crbug.com/404597 css1/box_properties/width.html [ NeedsRebaseline ] +crbug.com/404597 css1/cascade/cascade_order.html [ NeedsRebaseline ] +crbug.com/404597 css1/cascade/important.html [ NeedsRebaseline ] +crbug.com/404597 css1/classification/display.html [ NeedsRebaseline ] +crbug.com/404597 css1/classification/list_style.html [ NeedsRebaseline ] +crbug.com/404597 css1/classification/list_style_image.html [ NeedsRebaseline ] +crbug.com/404597 css1/classification/list_style_position.html [ NeedsRebaseline ] +crbug.com/404597 css1/classification/list_style_type.html [ NeedsRebaseline ] +crbug.com/404597 css1/classification/white_space.html [ NeedsRebaseline ] +crbug.com/404597 css1/color_and_background/background.html [ NeedsRebaseline ] +crbug.com/404597 css1/color_and_background/background_attachment.html [ NeedsRebaseline ] +crbug.com/404597 css1/color_and_background/background_color.html [ NeedsRebaseline ] +crbug.com/404597 css1/color_and_background/background_image.html [ NeedsRebaseline ] +crbug.com/404597 css1/color_and_background/background_position.html [ NeedsRebaseline ] +crbug.com/404597 css1/color_and_background/background_repeat.html [ NeedsRebaseline ] +crbug.com/404597 css1/color_and_background/color.html [ NeedsRebaseline ] +crbug.com/404597 css1/conformance/forward_compatible_parsing.html [ NeedsRebaseline ] +crbug.com/404597 css1/font_properties/font.html [ NeedsRebaseline ] +crbug.com/404597 css1/font_properties/font_family.html [ NeedsRebaseline ] +crbug.com/404597 css1/font_properties/font_size.html [ NeedsRebaseline ] +crbug.com/404597 css1/font_properties/font_style.html [ NeedsRebaseline ] +crbug.com/404597 css1/font_properties/font_variant.html [ NeedsRebaseline ] +crbug.com/404597 css1/font_properties/font_weight.html [ NeedsRebaseline ] +crbug.com/404597 css1/formatting_model/canvas.html [ NeedsRebaseline ] +crbug.com/404597 css1/formatting_model/floating_elements.html [ NeedsRebaseline ] +crbug.com/404597 css1/formatting_model/height_of_lines.html [ NeedsRebaseline ] +crbug.com/404597 css1/formatting_model/horizontal_formatting.html [ NeedsRebaseline ] +crbug.com/404597 css1/formatting_model/inline_elements.html [ NeedsRebaseline ] +crbug.com/404597 css1/formatting_model/replaced_elements.html [ NeedsRebaseline ] +crbug.com/404597 css1/formatting_model/vertical_formatting.html [ NeedsRebaseline ] +crbug.com/404597 css1/pseudo/anchor.html [ NeedsRebaseline ] +crbug.com/404597 css1/pseudo/firstletter.html [ NeedsRebaseline ] +crbug.com/404597 css1/pseudo/firstline.html [ NeedsRebaseline ] +crbug.com/404597 css1/pseudo/multiple_pseudo_elements.html [ NeedsRebaseline ] +crbug.com/404597 css1/pseudo/pseudo_elements_in_selectors.html [ NeedsRebaseline ] +crbug.com/404597 css1/text_properties/letter_spacing.html [ NeedsRebaseline ] +crbug.com/404597 css1/text_properties/line_height.html [ NeedsRebaseline ] +crbug.com/404597 css1/text_properties/text_align.html [ NeedsRebaseline ] +crbug.com/404597 css1/text_properties/text_decoration.html [ NeedsRebaseline ] +crbug.com/404597 css1/text_properties/text_indent.html [ NeedsRebaseline ] +crbug.com/404597 css1/text_properties/text_transform.html [ NeedsRebaseline ] +crbug.com/404597 css1/text_properties/vertical_align.html [ NeedsRebaseline ] +crbug.com/404597 css1/text_properties/word_spacing.html [ NeedsRebaseline ] +crbug.com/404597 css1/units/color_units.html [ NeedsRebaseline ] +crbug.com/404597 css1/units/length_units.html [ NeedsRebaseline ] +crbug.com/404597 css1/units/percentage_units.html [ NeedsRebaseline ] +crbug.com/404597 css1/units/urls.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-height-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-height-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-height-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-height-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-height-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-height-006.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-height-007.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-height-008.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-height-009.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-height-010.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-height-011.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-height-012.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-max-height-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-max-height-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-max-height-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-max-height-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-max-height-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-max-height-006.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-max-height-007.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-max-height-008.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-max-height-009.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-max-height-010.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-max-height-011.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-max-height-012.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-006.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-007.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-008.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-009.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-010.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-011.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-012.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-013.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-014.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-015.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-016.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-021.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-022.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-023.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-non-replaced-width-024.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-007.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-008.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-009.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-010.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-011.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-012.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-014.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-016.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-017.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-018.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-019.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-021.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-022.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-023.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-024.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-025.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-026.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-028.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-029.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-030.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-031.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-032.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-033.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-height-035.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-006.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-008.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-013.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-015.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-020.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-022.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-027.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-029.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-034.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-036.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-041.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-043.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-048.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-050.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-055.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-057.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-062.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-064.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-069.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-071.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/absolute-replaced-width-076.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/abspos-containing-block-initial-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-006.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-007.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-008.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-009.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-010.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-011.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-012.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-013.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-014.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-015.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-height-016.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-width-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-width-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-width-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-width-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-width-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-width-006.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-width-007.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-non-replaced-width-008.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-replaced-height-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-replaced-height-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-replaced-height-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-replaced-height-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-replaced-height-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-replaced-height-007.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-replaced-width-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/block-replaced-width-006.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/border-conflict-style-079.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/border-conflict-style-088.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/border-spacing-applies-to-015.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/c543-txt-decor-000.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/empty-inline-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/empty-inline-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/empty-inline-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-non-replaced-height-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-non-replaced-width-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-non-replaced-width-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-non-replaced-width-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-non-replaced-width-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-non-replaced-width-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-non-replaced-width-006.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-height-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-height-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-height-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-height-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-height-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-height-007.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-width-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-width-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-width-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-width-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-width-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-width-006.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/float-replaced-width-011.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/floating-replaced-height-008.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/height-width-inline-table-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/height-width-table-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-non-replaced-height-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-non-replaced-height-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-non-replaced-width-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-non-replaced-width-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-replaced-height-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-replaced-height-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-replaced-height-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-replaced-height-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-replaced-height-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-replaced-height-007.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-replaced-height-008.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-replaced-width-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-block-replaced-width-006.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-non-replaced-height-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-non-replaced-height-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-non-replaced-width-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-non-replaced-width-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-height-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-height-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-height-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-height-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-height-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-height-007.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-height-008.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-width-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-width-006.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-width-011.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-width-012.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-width-013.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-width-014.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-replaced-width-015.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/inline-table-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-003.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-004.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-005.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-006.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-007.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-008.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-009.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-010.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-012.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-013.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/margin-applies-to-015.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/outline-color-applies-to-008.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/outline-color-applies-to-014.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/replaced-elements-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/replaced-intrinsic-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/table-caption-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/table-caption-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/table-caption-horizontal-alignment-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/table-caption-optional-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/table-caption-optional-002.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/table-height-algorithm-023.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/table-height-algorithm-024.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/width-non-replaced-inline-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/20110323/width-replaced-element-001.htm [ NeedsRebaseline ] +crbug.com/404597 css2.1/t010403-shand-border-00-c.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t040102-keywords-01-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0402-c71-fwd-parsing-01-f.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t040302-c61-phys-len-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t040302-c61-rel-len-00-b-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t040303-c62-percent-00-b-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t040304-c64-uri-00-a-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t040306-c63-color-00-b-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0510-c25-pseudo-elmnt-00-c.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t051201-c23-first-line-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t051202-c24-first-lttr-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t051202-c26-psudo-nest-00-c.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0602-c13-inheritance-00-e.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0602-inherit-bdr-pad-b-00.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t060403-c21-pseu-cls-00-e-i.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t060403-c21-pseu-id-00-e-i.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0803-c5502-mrgn-r-00-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0803-c5502-mrgn-r-02-c.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0803-c5504-mrgn-l-00-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0803-c5504-mrgn-l-02-c.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0803-c5505-mrgn-00-b-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0803-c5505-mrgn-02-c.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t080301-c411-vt-mrgn-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0804-c5507-padn-r-00-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0804-c5509-padn-l-00-b-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0804-c5510-padn-00-b-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0805-c5511-ibrdr-tw-00-a.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0805-c5512-ibrdr-rw-00-a.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0805-c5513-ibrdr-bw-00-a.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0805-c5514-ibrdr-lw-00-a.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0805-c5515-ibrdr-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0805-c5516-brdr-c-00-a.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0805-c5516-ibrdr-c-00-a.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0805-c5517-ibrdr-s-00-a.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0805-c5519-brdr-r-02-e.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0805-c5521-brdr-l-02-e.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0805-c5522-brdr-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t09-c5526c-display-00-e.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t090204-display-change-01-b-ao.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c414-flt-02-c.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c414-flt-03-c.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c414-flt-04-c.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c414-flt-fit-00-d.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c414-flt-fit-01-d-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c414-flt-wrap-00-e.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c414-flt-wrap-01-d-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c5525-fltblck-01-d.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c5525-fltclr-00-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c5525-fltcont-00-d-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c5525-flthw-00-c-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c5525-fltinln-00-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c5525-fltmrgn-00-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c5525-fltmult-00-d-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c5525-fltwidth-00-c-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c5525-fltwidth-02-c-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c5525-fltwidth-03-c-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c5526-fltclr-00-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0905-c5526-flthw-00-c-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t090501-c414-flt-00-d.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t090501-c414-flt-01-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t090501-c414-flt-ln-00-d.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t090501-c414-flt-ln-01-d-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t090501-c414-flt-ln-02-d.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t090501-c414-flt-ln-03-d.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t090501-c5525-flt-l-00-b-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t090501-c5525-flt-r-00-b-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1002-c5523-width-00-b-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1002-c5523-width-02-b-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t100303-c412-blockw-00-d-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t100304-c43-rpl-bbx-01-d-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1005-c5524-width-00-b-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1005-c5524-width-01-b-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1008-c44-ln-box-00-d-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1008-c44-ln-box-01-d-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1008-c44-ln-box-02-d-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1008-c44-ln-box-03-d-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t100801-c42-ibx-ht-00-d-a.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t100801-c544-valgn-00-a-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t100801-c544-valgn-01-d-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t100801-c548-leadin-00-d-a.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t100801-c548-ln-ht-01-b-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t100801-c548-ln-ht-02-b-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counter-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counter-01-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counter-02-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counter-03-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counter-04-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counter-05-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counter-06-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counter-08-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counter-13-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counter-14-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counter-16-f.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counters-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counters-01-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counters-02-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counters-03-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counters-04-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counters-05-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counters-06-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counters-08-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counters-13-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counters-14-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1202-counters-18-f.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1204-order-00-c.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1204-order-01-d.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t120401-scope-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t120401-scope-01-c.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1205-c561-list-displ-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1205-c565-list-pos-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1205-c566-list-stl-00-e-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t140201-c534-bgre-00-b-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t140201-c534-bgre-01-b-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t140201-c534-bgreps-00-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t140201-c534-bgreps-01-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t140201-c534-bgreps-02-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t140201-c534-bgreps-03-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t140201-c534-bgreps-04-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t140201-c534-bgreps-05-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t140201-c535-bg-fixd-00-b-g.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t140201-c537-bgfxps-00-c-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1503-c522-font-family-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1507-c526-font-sz-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1507-c526-font-sz-01-b-a.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1507-c526-font-sz-02-b-a.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1508-c527-font-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1508-c527-font-03-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1508-c527-font-04-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1508-c527-font-05-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1508-c527-font-07-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1508-c527-font-10-c.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1601-c547-indent-00-b-a.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1601-c547-indent-01-d.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1602-c546-txt-align-00-b.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1605-c545-txttrans-00-b-ag.html [ NeedsRebaseline ] +crbug.com/404597 css2.1/t1606-c562-white-sp-00-b-ag.html [ NeedsRebaseline ] +crbug.com/404597 css3/css3-modsel-35.html [ NeedsRebaseline ] +crbug.com/404597 css3/css3-modsel-37.html [ NeedsRebaseline ] +crbug.com/404597 css3/flexbox/button.html [ NeedsRebaseline ] +crbug.com/404597 css3/flexbox/flexbox-baseline-margins.html [ NeedsRebaseline ] +crbug.com/404597 css3/flexbox/flexbox-baseline.html [ NeedsRebaseline ] +crbug.com/404597 css3/flexbox/repaint.html [ NeedsRebaseline ] +crbug.com/404597 css3/font-feature-settings-rendering.html [ NeedsRebaseline ] +crbug.com/404597 css3/masking/clip-path-inset-corners.html [ NeedsRebaseline ] +crbug.com/404597 css3/masking/mask-repeat-space-border.html [ NeedsRebaseline ] +crbug.com/404597 css3/masking/mask-repeat-space-content.html [ NeedsRebaseline ] +crbug.com/404597 css3/masking/mask-repeat-space-padding.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-13.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-15.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-159.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-161.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-166.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-166a.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-167.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-167a.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-168.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-168a.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-169.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-169a.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-17.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-18.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-18a.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-18b.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-18c.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-19b.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-2.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-22.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-23.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-24.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-25.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-28.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-28b.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-29.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-29b.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-30.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-31.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-34.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-35.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-37.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-38.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-39.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-39a.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-39b.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-39c.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-41.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-41a.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-42.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-42a.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-45.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-45b.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-46.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-46b.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-6.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-64.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-68.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-69.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-7.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-70.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-73.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-73b.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-74.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-74b.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-75.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-75b.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-76.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-76b.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-79.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-8.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-80.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-82.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-82b.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-113.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-113b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-114.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-114b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-119.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-121.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-122.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-123.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-13.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-139.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-139b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-140.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-140b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-15.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-159.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-161.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-166.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-166a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-167.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-167a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-168.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-168a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-169.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-169a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-17.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-18.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-18a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-18b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-18c.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-19b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-2.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-22.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-23.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-24.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-25.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-28.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-28b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-29.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-29b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-30.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-31.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-34.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-35.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-37.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-38.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-39.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-39a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-39b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-39c.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-41.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-41a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-42.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-42a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-45.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-45b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-46.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-46b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-47.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-48.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-49.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-6.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-64.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-68.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-69.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-7.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-70.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-73.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-73b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-74.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-74b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-75.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-75b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-76.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-76b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-79.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-8.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-80.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-82.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-82b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-113.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-113b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-114.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-114b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-119.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-121.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-122.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-123.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-13.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-139.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-139b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-140.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-140b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-15.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-159.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-161.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-166.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-166a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-167.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-167a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-168.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-168a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-169.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-169a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-17.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-18.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-18a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-18b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-18c.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-19b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-2.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-22.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-23.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-24.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-25.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-28.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-28b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-29.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-29b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-30.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-31.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-34.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-35.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-37.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-38.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-39.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-39a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-39b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-39c.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-41.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-41a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-42.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-42a.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-45.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-45b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-46.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-46b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-47.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-48.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-49.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-6.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-64.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-68.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-69.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-7.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-70.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-73.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-73b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-74.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-74b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-75.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-75b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-76.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-76b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-79.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-8.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-80.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-82.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-82b.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-14c.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-14c.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-14e.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/html/css3-modsel-14e.html [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xhtml/css3-modsel-14c.xml [ NeedsRebaseline ] +crbug.com/404597 css3/selectors3/xml/css3-modsel-14e.xml [ NeedsRebaseline ] +crbug.com/404597 css2.1/t0402-c71-fwd-parsing-02-f.html [ NeedsRebaseline ] + crbug.com/419993 [ Debug ] fast/css/giant-stylesheet-crash.html [ Pass Slow ] # Part of a larger issue referenced in the bug. This specific issue will be fixed shortly. @@ -1131,6 +1830,9 @@ crbug.com/509025 [ Yosemite ] virtual/pointerevent/fast/events/context-no-deselect.html [ Failure ] crbug.com/509025 [ Yosemite ] virtual/trustedeventsdefaultaction/fast/events/context-no-deselect.html [ Failure ] crbug.com/509025 [ Yosemite ] virtual/prefer_compositing_to_lcd_text/compositing/overflow/theme-affects-visual-overflow.html [ Failure ] +crbug.com/509025 [ Yosemite ] virtual/rootlayerscrolls/scrollbars/rtl/overflow-scroll-rtl.html [ ImageOnlyFailure ] +crbug.com/509025 [ Yosemite ] virtual/rootlayerscrolls/scrollbars/scrollbars-on-positioned-content.html [ ImageOnlyFailure ] +crbug.com/509025 [ Yosemite ] virtual/rootlayerscrolls/scrollbars/short-scrollbar.html [ ImageOnlyFailure ] crbug.com/443596 media/sources-fallback-codecs.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index 3047692..e7cc164d 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -120,6 +120,11 @@ "args": ["--root-layer-scrolls"] }, { + "prefix": "rootlayerscrolls", + "base": "scrollbars", + "args": ["--root-layer-scrolls"] + }, + { "prefix": "scroll_customization", "base": "fast/scroll-behavior", "args": ["--enable-blink-features=ScrollCustomization"]
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot-register-failure-worker-not-activated.html b/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot-register-failure-worker-not-activated.html new file mode 100644 index 0000000..7768008 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/background_sync/oneshot-register-failure-worker-not-activated.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<title>sync.register() is rejected when the service worker is not active yet</title> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="../serviceworker/resources/test-helpers.js"></script> +</head> +<body> +<script> +async_test(function(test) { + var workerUrl = 'resources/empty_worker.js'; + var workerScope = 'resources/scope/' + location.pathname; + var swRegistration; + service_worker_unregister_and_register(test, workerUrl, workerScope) + .then(function(serviceWorkerRegistration) { + swRegistration = serviceWorkerRegistration; + assert_not_equals(swRegistration.installing, null, 'The worker should be installing'); + assert_equals(swRegistration.active, null, 'The worker should not be active yet'); + return swRegistration.sync.register(); + }) + .then(function(syncRegistration) { + assert_unreached('sync.register() must not succeed without an active service worker'); + }, function(e) { + assert_equals(e.name, 'AbortError'); + assert_equals(e.message, 'Registration failed - no active Service Worker'); + return service_worker_unregister_and_done(test, workerScope); + }) + .catch(unreached_rejection(test)); +}, 'sync.register() is rejected when the service worker is not active yet'); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/background_sync/periodic-register-failure-worker-not-activated.html b/third_party/WebKit/LayoutTests/http/tests/background_sync/periodic-register-failure-worker-not-activated.html new file mode 100644 index 0000000..9ef2e76a --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/background_sync/periodic-register-failure-worker-not-activated.html
@@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html> +<head> +<title>periodicSync.register() is rejected when the service worker is not active yet</title> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="../serviceworker/resources/test-helpers.js"></script> +</head> +<body> +<script> +async_test(function(test) { + var workerUrl = 'resources/empty_worker.js'; + var workerScope = 'resources/scope/' + location.pathname; + var swRegistration; + service_worker_unregister_and_register(test, workerUrl, workerScope) + .then(function(serviceWorkerRegistration) { + swRegistration = serviceWorkerRegistration; + assert_not_equals(swRegistration.installing, null, 'The worker should be installing'); + assert_equals(swRegistration.active, null, 'The worker should not be active yet'); + return swRegistration.periodicSync.register(); + }) + .then(function(syncRegistration) { + assert_unreached('periodicSync.register() must not succeed without an active service worker'); + }, function(e) { + assert_equals(e.name, 'AbortError'); + assert_equals(e.message, 'Registration failed - no active Service Worker'); + return service_worker_unregister_and_done(test, workerScope); + }) + .catch(unreached_rejection(test)); +}, 'periodicSync.register() is rejected when the service worker is not active yet'); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/subresourceIntegrity/resources/simple-result.js b/third_party/WebKit/LayoutTests/http/tests/security/subresourceIntegrity/resources/simple-result.js new file mode 100644 index 0000000..528d220 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/subresourceIntegrity/resources/simple-result.js
@@ -0,0 +1 @@ +window.result = true;
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/subresourceIntegrity/subresource-integrity-same-resource-different-integrity.html b/third_party/WebKit/LayoutTests/http/tests/security/subresourceIntegrity/subresource-integrity-same-resource-different-integrity.html new file mode 100644 index 0000000..d9aa089 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/security/subresourceIntegrity/subresource-integrity-same-resource-different-integrity.html
@@ -0,0 +1,98 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Subresource Integrity loading the same resource many times in a row, with different integrity values</title> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> + +<div id="log"></div> + +<div id="container"></div> +<script> + var SRIScriptTest = function(pass, name, src, integrityValue, crossoriginValue) { + this.pass = pass; + this.name = "Script: " + name; + this.src = src; + this.integrityValue = integrityValue; + this.crossoriginValue = crossoriginValue; + } + + SRIScriptTest.prototype.execute = function() { + var test = async_test(this.name); + var e = document.createElement("script"); + e.src = this.src; + e.setAttribute("integrity", this.integrityValue); + if(this.crossoriginValue) { + e.setAttribute("crossorigin", this.crossoriginValue); + } + if(this.pass) { + e.addEventListener("load", function() {test.done()}); + e.addEventListener("error", function() { + test.step(function(){ assert_unreached("Good load fired error handler.") }) + }); + } else { + e.addEventListener("load", function() { + test.step(function() { assert_unreached("Bad load succeeded.") }) + }); + e.addEventListener("error", function() {test.done()}); + } + document.body.appendChild(e); + }; + + window.result = false; + + new SRIScriptTest( + true, + "Same-origin with correct sha256 hash.", + "resources/simple-result.js", + "sha256-xJjeC55VpJ4nhSNBPBfw2QrsylPyXeQGxMd1l4unH58=" + ).execute(); + + new SRIScriptTest( + true, + "Same-origin with correct sha384 hash.", + "resources/simple-result.js", + "sha384-VsVEqbvsJzugHbbmJwqnn6S5D8oMWupN9NRvS7irxl3+YHlxEjKC6q5nWWC7dlmP" + ).execute(); + + new SRIScriptTest( + true, + "Same-origin with correct sha512 hash.", + "resources/simple-result.js", + "sha512-9Zotk1Xb/bjPvI/B9vAB3osGwSxgL4vnadYWg6uHLDFnO2pV71DWCUxJrdBLNqwxPcS3EieDnKCzQ01kwE+LNw==" + ).execute(); + + new SRIScriptTest( + true, + "Same-origin with empty integrity.", + "resources/simple-result.js", + "" + ).execute(); + + new SRIScriptTest( + false, + "Same-origin with incorrect hash.", + "non-resources/simple-result.js", + "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" + ).execute(); + + new SRIScriptTest( + true, + "Same-origin with multiple sha256 hashes, including correct.", + "resources/simple-result.js", + "sha256-xJjeC55VpJ4nhSNBPBfw2QrsylPyXeQGxMd1l4unH58= sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" + ).execute(); + + new SRIScriptTest( + true, + "Same-origin with sha256 mismatch, sha512 match", + "resources/simple-result.js", + "sha512-9Zotk1Xb/bjPvI/B9vAB3osGwSxgL4vnadYWg6uHLDFnO2pV71DWCUxJrdBLNqwxPcS3EieDnKCzQ01kwE+LNw== sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" + ).execute(); + + new SRIScriptTest( + false, + "Same-origin with sha256 match, sha512 mismatch", + "resources/simple-result.js", + "sha512-deadbeefspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg== sha256-xJjeC55VpJ4nhSNBPBfw2QrsylPyXeQGxMd1l4unH58= sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead" + ).execute(); +</script>
diff --git a/third_party/WebKit/LayoutTests/scrollbars/disabled-composited-scrollbar-expected.html b/third_party/WebKit/LayoutTests/scrollbars/disabled-composited-scrollbar-expected.html new file mode 100644 index 0000000..83f0fd6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/scrollbars/disabled-composited-scrollbar-expected.html
@@ -0,0 +1,10 @@ +<!DOCTYPE html> +<style> +.scroller { + overflow-y: scroll; + width: 100px; + height: 100px; + background-color: #eef; +} +</style> +<div class="scroller"></div>
diff --git a/third_party/WebKit/LayoutTests/scrollbars/disabled-composited-scrollbar.html b/third_party/WebKit/LayoutTests/scrollbars/disabled-composited-scrollbar.html new file mode 100644 index 0000000..ac376f1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/scrollbars/disabled-composited-scrollbar.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<style> +.scroller { + will-change: transform; + overflow-y: scroll; + width: 100px; + height: 100px; + background-color: #eef; +} +</style> +<div class="scroller"></div>
diff --git a/third_party/WebKit/LayoutTests/virtual/rootlayerscrolls/scrollbars/README.txt b/third_party/WebKit/LayoutTests/virtual/rootlayerscrolls/scrollbars/README.txt new file mode 100644 index 0000000..c2812d9a --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/rootlayerscrolls/scrollbars/README.txt
@@ -0,0 +1,2 @@ +# This suite runs the tests in scrollbars with the --root-layer-scrolls +flag. Root layer scrolling is tracked in http://crbug.com/417782.
diff --git a/third_party/WebKit/PRESUBMIT.py b/third_party/WebKit/PRESUBMIT.py index 34620ff4..54025cedf 100644 --- a/third_party/WebKit/PRESUBMIT.py +++ b/third_party/WebKit/PRESUBMIT.py
@@ -295,18 +295,20 @@ """Check that all files have their permissions properly set.""" if input_api.platform == 'win32': return [] - path = input_api.os_path.join( - '..', '..', 'tools', 'checkperms', 'checkperms.py') - args = [sys.executable, path, '--root', input_api.change.RepositoryRoot()] + args = [input_api.python_executable, + input_api.os_path.join( + input_api.change.RepositoryRoot(), + 'tools/checkperms/checkperms.py'), + '--root', input_api.change.RepositoryRoot()] for f in input_api.AffectedFiles(): args += ['--file', f.LocalPath()] - checkperms = input_api.subprocess.Popen( - args, stdout=input_api.subprocess.PIPE) - errors = checkperms.communicate()[0].strip() - if errors: + try: + input_api.subprocess.check_output(args) + return [] + except input_api.subprocess.CalledProcessError as error: return [output_api.PresubmitError( - 'checkperms.py failed.', errors.splitlines())] - return [] + 'checkperms.py failed:', + long_text=error.output)] def _CheckForInvalidPreferenceError(input_api, output_api):
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp index d38e6cc..7c178f9 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.cpp
@@ -18,6 +18,7 @@ #include "platform/ThreadSafeFunctional.h" #include "platform/TraceEvent.h" #include "public/platform/Platform.h" +#include "public/platform/WebScheduler.h" #include "wtf/MainThread.h" #include "wtf/text/TextEncodingRegistry.h" @@ -162,7 +163,7 @@ class SourceStream : public v8::ScriptCompiler::ExternalSourceStream { WTF_MAKE_NONCOPYABLE(SourceStream); public: - SourceStream() + explicit SourceStream(WebTaskRunner* loadingTaskRunner) : v8::ScriptCompiler::ExternalSourceStream() , m_cancelled(false) , m_finished(false) @@ -170,6 +171,7 @@ , m_queueTailPosition(0) , m_bookmarkPosition(0) , m_lengthOfBOM(0) + , m_loadingTaskRunner(adoptPtr(loadingTaskRunner->clone())) { } @@ -219,7 +221,7 @@ } // Inform main thread to re-queue the data. - Platform::current()->mainThread()->taskRunner()->postTask( + m_loadingTaskRunner->postTask( FROM_HERE, bind(&SourceStream::fetchDataFromResourceBuffer, this, 0)); } @@ -370,16 +372,18 @@ // We store this separately, to avoid having to guard all // m_queueLeadPosition references with a mutex. unsigned m_lengthOfBOM; // Used by both threads; guarded by m_mutex. + + OwnPtr<WebTaskRunner> m_loadingTaskRunner; }; size_t ScriptStreamer::kSmallScriptThreshold = 30 * 1024; -void ScriptStreamer::startStreaming(PendingScript& script, PendingScript::Type scriptType, Settings* settings, ScriptState* scriptState) +void ScriptStreamer::startStreaming(PendingScript& script, PendingScript::Type scriptType, Settings* settings, ScriptState* scriptState, WebTaskRunner* loadingTaskRunner) { // We don't yet know whether the script will really be streamed. E.g., // suppressing streaming for short scripts is done later. Record only the // sure negative cases here. - bool startedStreaming = startStreamingInternal(script, scriptType, settings, scriptState); + bool startedStreaming = startStreamingInternal(script, scriptType, settings, scriptState, loadingTaskRunner); if (!startedStreaming) Platform::current()->histogramEnumeration(startedStreamingHistogramName(scriptType), 0, 2); } @@ -421,7 +425,7 @@ // notifyFinished might already be called, or it might be called in the // future (if the parsing finishes earlier because of a parse error). - Platform::current()->mainThread()->taskRunner()->postTask(FROM_HERE, threadSafeBind(&ScriptStreamer::streamingComplete, AllowCrossThreadAccess(this))); + m_loadingTaskRunner->postTask(FROM_HERE, threadSafeBind(&ScriptStreamer::streamingComplete, AllowCrossThreadAccess(this))); // The task might delete ScriptStreamer, so it's not safe to do anything // after posting it. Note that there's no way to guarantee that this @@ -513,7 +517,7 @@ ASSERT(!m_stream); ASSERT(!m_source); - m_stream = new SourceStream(); + m_stream = new SourceStream(m_loadingTaskRunner.get()); // m_source takes ownership of m_stream. m_source = adoptPtr(new v8::ScriptCompiler::StreamedSource(m_stream, m_encoding)); @@ -564,7 +568,7 @@ notifyFinishedToClient(); } -ScriptStreamer::ScriptStreamer(ScriptResource* resource, PendingScript::Type scriptType, ScriptState* scriptState, v8::ScriptCompiler::CompileOptions compileOptions) +ScriptStreamer::ScriptStreamer(ScriptResource* resource, PendingScript::Type scriptType, ScriptState* scriptState, v8::ScriptCompiler::CompileOptions compileOptions, WebTaskRunner* loadingTaskRunner) : m_resource(resource) , m_detached(false) , m_stream(0) @@ -577,6 +581,7 @@ , m_scriptState(scriptState) , m_scriptType(scriptType) , m_encoding(v8::ScriptCompiler::StreamedSource::TWO_BYTE) // Unfortunately there's no dummy encoding value in the enum; let's use one we don't stream. + , m_loadingTaskRunner(adoptPtr(loadingTaskRunner->clone())) { } @@ -632,7 +637,7 @@ m_client->notifyFinished(m_resource); } -bool ScriptStreamer::startStreamingInternal(PendingScript& script, PendingScript::Type scriptType, Settings* settings, ScriptState* scriptState) +bool ScriptStreamer::startStreamingInternal(PendingScript& script, PendingScript::Type scriptType, Settings* settings, ScriptState* scriptState, WebTaskRunner* loadingTaskRunner) { ASSERT(isMainThread()); ASSERT(scriptState->contextIsValid()); @@ -665,7 +670,7 @@ // The Resource might go out of scope if the script is no longer // needed. This makes PendingScript notify the ScriptStreamer when it is // destroyed. - script.setStreamer(ScriptStreamer::create(resource, scriptType, scriptState, compileOption)); + script.setStreamer(ScriptStreamer::create(resource, scriptType, scriptState, compileOption, loadingTaskRunner)); return true; }
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.h b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.h index e3eb425..c002175 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamer.h
@@ -21,6 +21,7 @@ class ScriptState; class Settings; class SourceStream; +class WebTaskRunner; // ScriptStreamer streams incomplete script data to V8 so that it can be parsed // while it's loaded. PendingScript holds a reference to ScriptStreamer. At the @@ -32,9 +33,9 @@ class CORE_EXPORT ScriptStreamer final : public RefCountedWillBeRefCountedGarbageCollected<ScriptStreamer> { WTF_MAKE_NONCOPYABLE(ScriptStreamer); public: - static PassRefPtrWillBeRawPtr<ScriptStreamer> create(ScriptResource* resource, PendingScript::Type scriptType, ScriptState* scriptState, v8::ScriptCompiler::CompileOptions compileOptions) + static PassRefPtrWillBeRawPtr<ScriptStreamer> create(ScriptResource* resource, PendingScript::Type scriptType, ScriptState* scriptState, v8::ScriptCompiler::CompileOptions compileOptions, WebTaskRunner* loadingTaskRunner) { - return adoptRefWillBeNoop(new ScriptStreamer(resource, scriptType, scriptState, compileOptions)); + return adoptRefWillBeNoop(new ScriptStreamer(resource, scriptType, scriptState, compileOptions, loadingTaskRunner)); } ~ScriptStreamer(); @@ -42,7 +43,7 @@ // Launches a task (on a background thread) which will stream the given // PendingScript into V8 as it loads. - static void startStreaming(PendingScript&, PendingScript::Type, Settings*, ScriptState*); + static void startStreaming(PendingScript&, PendingScript::Type, Settings*, ScriptState*, WebTaskRunner*); // Returns false if we cannot stream the given encoding. static bool convertEncoding(const char* encodingName, v8::ScriptCompiler::StreamedSource::Encoding*); @@ -107,12 +108,12 @@ // streamed. Non-const for testing. static size_t kSmallScriptThreshold; - ScriptStreamer(ScriptResource*, PendingScript::Type, ScriptState*, v8::ScriptCompiler::CompileOptions); + ScriptStreamer(ScriptResource*, PendingScript::Type, ScriptState*, v8::ScriptCompiler::CompileOptions, WebTaskRunner*); void streamingComplete(); void notifyFinishedToClient(); - static bool startStreamingInternal(PendingScript&, PendingScript::Type, Settings*, ScriptState*); + static bool startStreamingInternal(PendingScript&, PendingScript::Type, Settings*, ScriptState*, WebTaskRunner*); // This pointer is weak. If PendingScript and its Resource are deleted // before ScriptStreamer, PendingScript will notify ScriptStreamer of its @@ -149,6 +150,8 @@ // Encoding of the streamed script. Saved for sanity checking purposes. v8::ScriptCompiler::StreamedSource::Encoding m_encoding; + + OwnPtr<WebTaskRunner> m_loadingTaskRunner; }; } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp index 62d9c84c..cbfdd8c 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp
@@ -18,6 +18,7 @@ #include "platform/heap/Handle.h" #include "platform/testing/UnitTestHelpers.h" #include "public/platform/Platform.h" +#include "public/platform/WebScheduler.h" #include <gtest/gtest.h> #include <v8.h> @@ -64,7 +65,8 @@ class ScriptStreamingTest : public ::testing::Test { public: ScriptStreamingTest() - : m_scope(v8::Isolate::GetCurrent()) + : m_loadingTaskRunner(Platform::current()->currentThread()->scheduler()->loadingTaskRunner()) + , m_scope(v8::Isolate::GetCurrent()) , m_settings(Settings::create()) , m_resourceRequest("http://www.streaming-test.com/") , m_resource(new ScriptResource(m_resourceRequest, "UTF-8")) @@ -116,6 +118,7 @@ testing::runPendingTasks(); } + WebTaskRunner* m_loadingTaskRunner; // NOT OWNED V8TestingScope m_scope; OwnPtr<Settings> m_settings; // The Resource and PendingScript where we stream from. These don't really @@ -142,7 +145,7 @@ TEST_F(ScriptStreamingTest, CompilingStreamedScript) { // Test that we can successfully compile a streamed script. - ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState()); + ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState(), m_loadingTaskRunner); TestScriptResourceClient client; pendingScript().watchForLoad(&client); @@ -173,7 +176,7 @@ // Test that scripts with parse errors are handled properly. In those cases, // the V8 side typically finished before loading finishes: make sure we // handle it gracefully. - ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState()); + ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState(), m_loadingTaskRunner); TestScriptResourceClient client; pendingScript().watchForLoad(&client); appendData("function foo() {"); @@ -205,7 +208,7 @@ { // Test that the upper layers (PendingScript and up) can be ramped down // while streaming is ongoing, and ScriptStreamer handles it gracefully. - ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState()); + ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState(), m_loadingTaskRunner); TestScriptResourceClient client; pendingScript().watchForLoad(&client); appendData("function foo() {"); @@ -234,7 +237,7 @@ // is suppressed (V8 doesn't parse while the script is loading), and the // upper layer (ScriptResourceClient) should get a notification when the // script is loaded. - ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState()); + ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState(), m_loadingTaskRunner); TestScriptResourceClient client; pendingScript().watchForLoad(&client); appendData("function foo() {"); @@ -263,7 +266,7 @@ // Empty scripts should also be streamed properly, that is, the upper layer // (ScriptResourceClient) should be notified when an empty script has been // loaded. - ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState()); + ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState(), m_loadingTaskRunner); TestScriptResourceClient client; pendingScript().watchForLoad(&client); @@ -284,7 +287,7 @@ // Small scripts shouldn't be streamed. ScriptStreamer::setSmallScriptThresholdForTesting(100); - ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState()); + ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState(), m_loadingTaskRunner); TestScriptResourceClient client; pendingScript().watchForLoad(&client); @@ -308,7 +311,7 @@ // chunk is small. ScriptStreamer::setSmallScriptThresholdForTesting(100); - ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState()); + ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState(), m_loadingTaskRunner); TestScriptResourceClient client; pendingScript().watchForLoad(&client); @@ -338,7 +341,7 @@ // loading it. m_resource->setEncoding("windows-1252"); - ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState()); + ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState(), m_loadingTaskRunner); TestScriptResourceClient client; pendingScript().watchForLoad(&client); @@ -367,7 +370,7 @@ // will also affect encoding detection. m_resource->setEncoding("windows-1252"); // This encoding is wrong on purpose. - ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState()); + ScriptStreamer::startStreaming(pendingScript(), PendingScript::ParsingBlocking, m_settings.get(), m_scope.scriptState(), m_loadingTaskRunner); TestScriptResourceClient client; pendingScript().watchForLoad(&client);
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp index 5a47712..3bd0390 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp
@@ -360,9 +360,8 @@ { static_assert(sizeof(BufferValueType) == 2, "BufferValueType should be 2 bytes"); fillHole(); - String data = String(m_buffer.data(), m_buffer.size()); - data.impl()->truncateAssumingIsolated((m_position + 1) / sizeof(BufferValueType)); - return data; + ASSERT((m_position + 1) / sizeof(BufferValueType) <= m_buffer.size()); + return String(m_buffer.data(), (m_position + 1) / sizeof(BufferValueType)); } void SerializedScriptValueWriter::writeReferenceCount(uint32_t numberOfReferences)
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index a6bc05b..9fa9677 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -5696,6 +5696,13 @@ return true; } +WebTaskRunner* Document::loadingTaskRunner() const +{ + if (frame()) + return frame()->frameScheduler()->loadingTaskRunner(); + return Platform::current()->currentThread()->scheduler()->loadingTaskRunner(); +} + DEFINE_TRACE(Document) { #if ENABLE(OILPAN)
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h index 9dcaf66..8792af4f 100644 --- a/third_party/WebKit/Source/core/dom/Document.h +++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -1050,6 +1050,8 @@ using WeakDocumentSet = WillBeHeapHashSet<RawPtrWillBeWeakMember<Document>>; static WeakDocumentSet& liveDocumentSet(); + WebTaskRunner* loadingTaskRunner() const; + protected: Document(const DocumentInit&, DocumentClassFlags = DefaultDocumentClass);
diff --git a/third_party/WebKit/Source/core/dom/PendingScript.cpp b/third_party/WebKit/Source/core/dom/PendingScript.cpp index a7b460ed..3f64d88 100644 --- a/third_party/WebKit/Source/core/dom/PendingScript.cpp +++ b/third_party/WebKit/Source/core/dom/PendingScript.cpp
@@ -157,15 +157,17 @@ ASSERT(resource->type() == Resource::Script); ScriptResource* scriptResource = toScriptResource(resource); String integrityAttr = m_element->fastGetAttribute(HTMLNames::integrityAttr); - if (scriptResource->integrityAlreadyChecked()) { - if (scriptResource->integrityMetadata() != integrityAttr) - m_integrityFailure = true; - } else if (resource->resourceBuffer()) { - scriptResource->setIntegrityAlreadyChecked(true); - m_integrityFailure = !SubresourceIntegrity::CheckSubresourceIntegrity(*m_element, resource->resourceBuffer()->data(), resource->resourceBuffer()->size(), resource->url(), *resource); - // TODO(jww) this integrity metadata should actually be - // normalized so that order doesn't matter. - scriptResource->setIntegrityMetadata(integrityAttr); + if (!integrityAttr.isEmpty() && !scriptResource->integrityMetadata().isEmpty()) { + if (scriptResource->integrityAlreadyChecked()) { + if (scriptResource->integrityMetadata() != integrityAttr) + m_integrityFailure = true; + } else if (resource->resourceBuffer()) { + scriptResource->setIntegrityAlreadyChecked(true); + m_integrityFailure = !SubresourceIntegrity::CheckSubresourceIntegrity(*m_element, resource->resourceBuffer()->data(), resource->resourceBuffer()->size(), resource->url(), *resource); + // TODO(jww) this integrity metadata should actually be + // normalized so that order doesn't matter. + scriptResource->setIntegrityMetadata(integrityAttr); + } } }
diff --git a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp index a379ffe4..0477cd8 100644 --- a/third_party/WebKit/Source/core/dom/ScriptLoader.cpp +++ b/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
@@ -50,6 +50,7 @@ #include "core/svg/SVGScriptElement.h" #include "platform/MIMETypeRegistry.h" #include "platform/weborigin/SecurityOrigin.h" +#include "public/platform/WebFrameScheduler.h" #include "wtf/StdLibExtras.h" #include "wtf/text/StringBuilder.h" #include "wtf/text/StringHash.h" @@ -259,7 +260,7 @@ if (frame) { ScriptState* scriptState = ScriptState::forMainWorld(frame); if (scriptState->contextIsValid()) - ScriptStreamer::startStreaming(m_pendingScript, PendingScript::Async, frame->settings(), scriptState); + ScriptStreamer::startStreaming(m_pendingScript, PendingScript::Async, frame->settings(), scriptState, frame->frameScheduler()->loadingTaskRunner()); } contextDocument->scriptRunner()->queueScriptForExecution(this, ScriptRunner::ASYNC_EXECUTION); // Note that watchForLoad can immediately call notifyFinished.
diff --git a/third_party/WebKit/Source/core/dom/ScriptRunnerTest.cpp b/third_party/WebKit/Source/core/dom/ScriptRunnerTest.cpp index 6db3012..18683001 100644 --- a/third_party/WebKit/Source/core/dom/ScriptRunnerTest.cpp +++ b/third_party/WebKit/Source/core/dom/ScriptRunnerTest.cpp
@@ -72,7 +72,7 @@ explicit MockWebTaskRunner(Deque<OwnPtr<WebTaskRunner::Task>>* tasks) : m_tasks(tasks) { } ~MockWebTaskRunner() override { } - virtual void postTask(const WebTraceLocation&, Task* task) + void postTask(const WebTraceLocation&, Task* task) override { m_tasks->append(adoptPtr(task)); } @@ -82,6 +82,12 @@ ASSERT_NOT_REACHED(); } + WebTaskRunner* clone() override + { + ASSERT_NOT_REACHED(); + return nullptr; + } + Deque<OwnPtr<WebTaskRunner::Task>>* m_tasks; // NOT OWNED };
diff --git a/third_party/WebKit/Source/core/fetch/FetchContext.h b/third_party/WebKit/Source/core/fetch/FetchContext.h index 054b465..22869f1 100644 --- a/third_party/WebKit/Source/core/fetch/FetchContext.h +++ b/third_party/WebKit/Source/core/fetch/FetchContext.h
@@ -48,6 +48,7 @@ class ResourceResponse; class ResourceRequest; class ResourceTimingInfo; +class WebTaskRunner; enum FetchResourceType { FetchMainResource, @@ -106,6 +107,8 @@ virtual ResourceLoadPriority modifyPriorityForExperiments(ResourceLoadPriority priority, Resource::Type, const FetchRequest&, ResourcePriority::VisibilityStatus) { return priority; } + virtual WebTaskRunner* loadingTaskRunner() const { return nullptr; } + protected: FetchContext() { } };
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp index d901976..09a6763 100644 --- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp +++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -189,6 +189,14 @@ #endif } +WebTaskRunner* ResourceFetcher::loadingTaskRunner() +{ + if (!m_context) + return nullptr; + + return m_context->loadingTaskRunner(); +} + Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const { KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL);
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h index 066cb6b..d082cf7 100644 --- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h +++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
@@ -146,6 +146,8 @@ bool clientDefersImage(const KURL&) const; void determineRequestContext(ResourceRequest&, Resource::Type); + WebTaskRunner* loadingTaskRunner(); + void updateAllImageResourcePriorities(); private:
diff --git a/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp b/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp index b8dbb1d..fdb7702 100644 --- a/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp +++ b/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp
@@ -142,6 +142,7 @@ m_loader = adoptPtr(Platform::current()->createURLLoader()); ASSERT(m_loader); + m_loader->setLoadingTaskRunner(m_fetcher->loadingTaskRunner()); WrappedResourceRequest wrappedRequest(m_request); m_loader->loadAsynchronously(wrappedRequest, this); }
diff --git a/third_party/WebKit/Source/core/fetch/ScriptResource.cpp b/third_party/WebKit/Source/core/fetch/ScriptResource.cpp index 71fea58..50935706 100644 --- a/third_party/WebKit/Source/core/fetch/ScriptResource.cpp +++ b/third_party/WebKit/Source/core/fetch/ScriptResource.cpp
@@ -102,7 +102,7 @@ bool ScriptResource::mustRefetchDueToIntegrityMetadata(const FetchRequest& request) const { - if (!m_integrityChecked || request.integrityMetadata().isEmpty()) + if (request.integrityMetadata().isEmpty()) return false; // TODO(jww) this integrity metadata should actually be
diff --git a/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp b/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp index 3589b67..51b92074 100644 --- a/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp +++ b/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp
@@ -33,7 +33,7 @@ #include "platform/Task.h" #include "platform/ThreadSafeFunctional.h" #include "public/platform/Platform.h" -#include "public/platform/WebScheduler.h" +#include "public/platform/WebTaskRunner.h" #include "wtf/text/TextPosition.h" namespace blink { @@ -81,9 +81,9 @@ #endif -void BackgroundHTMLParser::start(PassRefPtr<WeakReference<BackgroundHTMLParser>> reference, PassOwnPtr<Configuration> config, WebScheduler* scheduler) +void BackgroundHTMLParser::start(PassRefPtr<WeakReference<BackgroundHTMLParser>> reference, PassOwnPtr<Configuration> config, PassOwnPtr<WebTaskRunner> loadingTaskRunner) { - new BackgroundHTMLParser(reference, config, scheduler); + new BackgroundHTMLParser(reference, config, loadingTaskRunner); // Caller must free by calling stop(). } @@ -93,7 +93,7 @@ { } -BackgroundHTMLParser::BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser>> reference, PassOwnPtr<Configuration> config, WebScheduler* scheduler) +BackgroundHTMLParser::BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser>> reference, PassOwnPtr<Configuration> config, PassOwnPtr<WebTaskRunner> loadingTaskRunner) : m_weakFactory(reference, this) , m_token(adoptPtr(new HTMLToken)) , m_tokenizer(HTMLTokenizer::create(config->options)) @@ -106,7 +106,7 @@ , m_xssAuditor(config->xssAuditor.release()) , m_preloadScanner(config->preloadScanner.release()) , m_decoder(config->decoder.release()) - , m_scheduler(scheduler) + , m_loadingTaskRunner(loadingTaskRunner) , m_startingScript(false) { ASSERT(m_outstandingTokenLimit > 0); @@ -157,7 +157,7 @@ m_lastSeenEncodingData = encodingData; m_xssAuditor->setEncoding(encodingData.encoding()); - m_scheduler->loadingTaskRunner()->postTask( + m_loadingTaskRunner->postTask( FROM_HERE, threadSafeBind(&HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser, AllowCrossThreadAccess(m_parser), encodingData)); } @@ -291,7 +291,7 @@ chunk->startingScript = m_startingScript; m_startingScript = false; - m_scheduler->loadingTaskRunner()->postTask( + m_loadingTaskRunner->postTask( FROM_HERE, new Task(threadSafeBind(&HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser, AllowCrossThreadAccess(m_parser), chunk.release())));
diff --git a/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h b/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h index 6922c310..d3f7c8e3 100644 --- a/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h +++ b/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h
@@ -42,7 +42,7 @@ class HTMLDocumentParser; class XSSAuditor; -class WebScheduler; +class WebTaskRunner; class BackgroundHTMLParser { WTF_MAKE_FAST_ALLOCATED(BackgroundHTMLParser); @@ -63,7 +63,7 @@ size_t pendingTokenLimit; }; - static void start(PassRefPtr<WeakReference<BackgroundHTMLParser>>, PassOwnPtr<Configuration>, WebScheduler*); + static void start(PassRefPtr<WeakReference<BackgroundHTMLParser>>, PassOwnPtr<Configuration>, PassOwnPtr<WebTaskRunner>); struct Checkpoint { WTF_MAKE_FAST_ALLOCATED(CheckPoint); @@ -90,7 +90,7 @@ void forcePlaintextForTextDocument(); private: - BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser>>, PassOwnPtr<Configuration>, WebScheduler*); + BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser>>, PassOwnPtr<Configuration>, PassOwnPtr<WebTaskRunner>); ~BackgroundHTMLParser(); void appendDecodedBytes(const String&); @@ -118,7 +118,7 @@ OwnPtr<TokenPreloadScanner> m_preloadScanner; OwnPtr<TextResourceDecoder> m_decoder; DocumentEncodingData m_lastSeenEncodingData; - WebScheduler* m_scheduler; // NOT OWNED, scheduler will outlive BackgroundHTMLParser + OwnPtr<WebTaskRunner> m_loadingTaskRunner; bool m_startingScript; };
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp index 070fd43..80f5c23 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
@@ -50,6 +50,7 @@ #include "platform/TraceEvent.h" #include "platform/heap/Handle.h" #include "public/platform/Platform.h" +#include "public/platform/WebFrameScheduler.h" #include "public/platform/WebScheduler.h" #include "public/platform/WebThread.h" #include "wtf/RefCounted.h" @@ -143,7 +144,8 @@ , m_tokenizer(syncPolicy == ForceSynchronousParsing ? HTMLTokenizer::create(m_options) : nullptr) , m_scriptRunner(HTMLScriptRunner::create(&document, this)) , m_treeBuilder(HTMLTreeBuilder::create(this, &document, parserContentPolicy(), reportErrors, m_options)) - , m_parserScheduler(HTMLParserScheduler::create(this)) + , m_loadingTaskRunner(adoptPtr(document.loadingTaskRunner()->clone())) + , m_parserScheduler(HTMLParserScheduler::create(this, m_loadingTaskRunner.get())) , m_xssAuditorDelegate(&document) , m_weakFactory(this) , m_preloader(HTMLResourcePreloader::create(document)) @@ -166,6 +168,7 @@ , m_token(adoptPtr(new HTMLToken)) , m_tokenizer(HTMLTokenizer::create(m_options)) , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, this->parserContentPolicy(), m_options)) + , m_loadingTaskRunner(adoptPtr(fragment->document().loadingTaskRunner()->clone())) , m_xssAuditorDelegate(&fragment->document()) , m_weakFactory(this) , m_shouldUseThreading(false) @@ -801,7 +804,7 @@ ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); ASSERT(config->preloadScanner->isSafeToSendToAnotherThread()); HTMLParserThread::shared()->postTask(threadSafeBind(&BackgroundHTMLParser::start, reference.release(), config.release(), - AllowCrossThreadAccess(Platform::current()->currentThread()->scheduler()))); + adoptPtr(m_loadingTaskRunner->clone()))); } void HTMLDocumentParser::stopBackgroundParser()
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h index 8fba554..f41d9b03 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h +++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
@@ -187,6 +187,7 @@ OwnPtrWillBeMember<HTMLTreeBuilder> m_treeBuilder; OwnPtr<HTMLPreloadScanner> m_preloadScanner; OwnPtr<HTMLPreloadScanner> m_insertionPreloadScanner; + OwnPtr<WebTaskRunner> m_loadingTaskRunner; OwnPtr<HTMLParserScheduler> m_parserScheduler; HTMLSourceTracker m_sourceTracker; TextPosition m_textPosition;
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp b/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp index c15e43b5..58a3ded9 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
@@ -82,9 +82,9 @@ m_processedElementTokens += count; } -HTMLParserScheduler::HTMLParserScheduler(HTMLDocumentParser* parser) +HTMLParserScheduler::HTMLParserScheduler(HTMLDocumentParser* parser, WebTaskRunner* loadingTaskRunner) : m_parser(parser) - , m_loadingTaskRunner(Platform::current()->currentThread()->scheduler()->loadingTaskRunner()) + , m_loadingTaskRunner(adoptPtr(loadingTaskRunner->clone())) , m_cancellableContinueParse(CancellableTaskFactory::create(this, &HTMLParserScheduler::continueParsing)) , m_isSuspendedWithActiveTimer(false) {
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h b/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h index d7878dbc..ad3ccaa 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h +++ b/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
@@ -36,6 +36,7 @@ class Document; class HTMLDocumentParser; +class WebTaskRunner; class ActiveParserSession : public NestingLevelIncrementer { STACK_ALLOCATED(); @@ -72,9 +73,9 @@ class HTMLParserScheduler { WTF_MAKE_NONCOPYABLE(HTMLParserScheduler); WTF_MAKE_FAST_ALLOCATED(HTMLParserScheduler); public: - static PassOwnPtr<HTMLParserScheduler> create(HTMLDocumentParser* parser) + static PassOwnPtr<HTMLParserScheduler> create(HTMLDocumentParser* parser, WebTaskRunner* loadingTaskRunner) { - return adoptPtr(new HTMLParserScheduler(parser)); + return adoptPtr(new HTMLParserScheduler(parser, loadingTaskRunner)); } ~HTMLParserScheduler(); @@ -98,13 +99,13 @@ void detach(); // Clear active tasks if any. private: - explicit HTMLParserScheduler(HTMLDocumentParser*); + HTMLParserScheduler(HTMLDocumentParser*, WebTaskRunner*); bool shouldYield(const SpeculationsPumpSession&, bool startingScript) const; void continueParsing(); HTMLDocumentParser* m_parser; - WebTaskRunner* m_loadingTaskRunner; // NOT OWNED + OwnPtr<WebTaskRunner> m_loadingTaskRunner; OwnPtr<CancellableTaskFactory> m_cancellableContinueParse; bool m_isSuspendedWithActiveTimer;
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp b/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp index 3d80848..35b1258 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp
@@ -40,6 +40,7 @@ #include "core/html/parser/NestingLevelIncrementer.h" #include "platform/NotImplemented.h" #include "public/platform/Platform.h" +#include "public/platform/WebFrameScheduler.h" namespace blink { @@ -287,7 +288,7 @@ if (m_document->frame()) { ScriptState* scriptState = ScriptState::forMainWorld(m_document->frame()); if (scriptState->contextIsValid()) - ScriptStreamer::startStreaming(m_parserBlockingScript, PendingScript::ParsingBlocking, m_document->frame()->settings(), scriptState); + ScriptStreamer::startStreaming(m_parserBlockingScript, PendingScript::ParsingBlocking, m_document->frame()->settings(), scriptState, m_document->loadingTaskRunner()); } m_parserBlockingScript.watchForLoad(this); @@ -303,7 +304,7 @@ if (m_document->frame() && !pendingScript.isReady()) { ScriptState* scriptState = ScriptState::forMainWorld(m_document->frame()); if (scriptState->contextIsValid()) - ScriptStreamer::startStreaming(pendingScript, PendingScript::Deferred, m_document->frame()->settings(), scriptState); + ScriptStreamer::startStreaming(pendingScript, PendingScript::Deferred, m_document->frame()->settings(), scriptState, m_document->loadingTaskRunner()); } ASSERT(pendingScript.resource());
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp index 60a312d..ca1eb69 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -1368,26 +1368,6 @@ } } -bool CompositedLayerMapping::hasUnpositionedOverflowControlsLayers() const -{ - if (GraphicsLayer* layer = layerForHorizontalScrollbar()) { - if (!layer->drawsContent()) - return true; - } - - if (GraphicsLayer* layer = layerForVerticalScrollbar()) { - if (!layer->drawsContent()) - return true; - } - - if (GraphicsLayer* layer = layerForScrollCorner()) { - if (!layer->drawsContent()) - return true; - } - - return false; -} - enum ApplyToGraphicsLayersModeFlags { ApplyToLayersAffectedByPreserve3D = (1 << 0), ApplyToSquashingLayer = (1 << 1),
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h index 39fdd93..796ef35 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h +++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
@@ -132,7 +132,6 @@ IntRect pixelSnappedCompositedBounds() const; void positionOverflowControlsLayers(); - bool hasUnpositionedOverflowControlsLayers() const; // Returns true if the assignment actually changed the assigned squashing layer. bool updateSquashingLayerAssignment(PaintLayer* squashedLayer, size_t nextSquashedLayerIndex);
diff --git a/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerUpdater.cpp b/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerUpdater.cpp index 4834aefd..db4df44 100644 --- a/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerUpdater.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/GraphicsLayerUpdater.cpp
@@ -100,10 +100,8 @@ m_needsRebuildTree = true; mapping->updateGraphicsLayerGeometry(compositingContainer, context.compositingStackingContext(), layersNeedingPaintInvalidation); - - if (mapping->hasUnpositionedOverflowControlsLayers()) - layer.scrollableArea()->positionOverflowControls(); - + if (PaintLayerScrollableArea* scrollableArea = layer.scrollableArea()) + scrollableArea->positionOverflowControls(); updateType = mapping->updateTypeForChildren(updateType); mapping->clearNeedsGraphicsLayerUpdate(); }
diff --git a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h index cc0cc2c..0fce6b65 100644 --- a/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h +++ b/third_party/WebKit/Source/core/layout/line/BreakingContextInlineHeaders.h
@@ -559,7 +559,7 @@ float lastSpaceWordSpacing = 0; float wordSpacingForWordMeasurement = 0; - float wrapW = m_width.uncommittedWidth() + inlineLogicalWidth(m_current.object(), !m_appliedStartWidth, true); + float wrapW = m_width.uncommittedWidth(); float charWidth = 0; // Auto-wrapping text should wrap in the middle of a word only if it could not wrap before the word, // which is only possible if the word is the first thing on the line, that is, if |w| is zero. @@ -815,7 +815,7 @@ WordMeasurement& wordMeasurement = wordMeasurements.last(); wordMeasurement.layoutText = layoutText; - // IMPORTANT: current.m_pos is > length here! + // IMPORTANT: current.offset() is > layoutText.textLength() here! float additionalTempWidth = 0; wordMeasurement.startOffset = lastSpace; wordMeasurement.endOffset = m_current.offset();
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp index 57adb2a7..ff2440b7 100644 --- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp +++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -64,6 +64,7 @@ #include "platform/network/ResourceTimingInfo.h" #include "platform/weborigin/SchemeRegistry.h" #include "platform/weborigin/SecurityPolicy.h" +#include "public/platform/WebFrameScheduler.h" #include <algorithm> @@ -735,6 +736,11 @@ return static_cast<ResourceLoadPriority>(modifiedPriority); } +WebTaskRunner* FrameFetchContext::loadingTaskRunner() const +{ + return frame()->frameScheduler()->loadingTaskRunner(); +} + DEFINE_TRACE(FrameFetchContext) { visitor->trace(m_document);
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.h b/third_party/WebKit/Source/core/loader/FrameFetchContext.h index a8137621..c2cbc75 100644 --- a/third_party/WebKit/Source/core/loader/FrameFetchContext.h +++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.h
@@ -108,6 +108,8 @@ void countClientHintsResourceWidth() override; void countClientHintsViewportWidth() override; + WebTaskRunner* loadingTaskRunner() const override; + DECLARE_VIRTUAL_TRACE(); private:
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp index 68d09cd..3c711ab 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp +++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -1072,6 +1072,7 @@ if (m_frame->document()) m_frame->document()->detach(); m_documentLoader = m_provisionalDocumentLoader.release(); + m_frame->updateFrameSecurityOrigin(); return true; }
diff --git a/third_party/WebKit/Source/modules/background_sync/PeriodicSyncManager.cpp b/third_party/WebKit/Source/modules/background_sync/PeriodicSyncManager.cpp index 849acb7f..03ed3ed 100644 --- a/third_party/WebKit/Source/modules/background_sync/PeriodicSyncManager.cpp +++ b/third_party/WebKit/Source/modules/background_sync/PeriodicSyncManager.cpp
@@ -54,6 +54,10 @@ ScriptPromise PeriodicSyncManager::registerFunction(ScriptState* scriptState, ExecutionContext* context, const PeriodicSyncRegistrationOptions& options) { + // TODO(jkarlin): Wait for the registration to become active instead of rejecting. See crbug.com/542437. + if (!m_registration->active()) + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(AbortError, "Registration failed - no active Service Worker")); + ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise();
diff --git a/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp b/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp index 4e0ac16..dae56c1ee 100644 --- a/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp +++ b/third_party/WebKit/Source/modules/background_sync/SyncManager.cpp
@@ -42,6 +42,10 @@ ScriptPromise SyncManager::registerFunction(ScriptState* scriptState, ExecutionContext* context, const SyncRegistrationOptions& options) { + // TODO(jkarlin): Wait for the registration to become active instead of rejecting. See crbug.com/542437. + if (!m_registration->active()) + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(AbortError, "Registration failed - no active Service Worker")); + ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise();
diff --git a/third_party/WebKit/Source/platform/TimerTest.cpp b/third_party/WebKit/Source/platform/TimerTest.cpp index 91b62dc..a75a16a 100644 --- a/third_party/WebKit/Source/platform/TimerTest.cpp +++ b/third_party/WebKit/Source/platform/TimerTest.cpp
@@ -77,7 +77,7 @@ explicit MockWebTaskRunner(std::priority_queue<DelayedTask>* timerTasks) : m_timerTasks(timerTasks) { } ~MockWebTaskRunner() override { } - virtual void postTask(const WebTraceLocation&, Task* task) + void postTask(const WebTraceLocation&, Task* task) override { m_timerTasks->push(DelayedTask(task, 0)); } @@ -87,6 +87,12 @@ m_timerTasks->push(DelayedTask(task, delayMs * 0.001)); } + WebTaskRunner* clone() override + { + ASSERT_NOT_REACHED(); + return nullptr; + } + std::priority_queue<DelayedTask>* m_timerTasks; // NOT OWNED };
diff --git a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp index 8cf1c048..abc94b7 100644 --- a/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/RecordingImageBufferSurfaceTest.cpp
@@ -260,7 +260,7 @@ MockWebTaskRunner() : m_task(0) { } ~MockWebTaskRunner() override { } - virtual void postTask(const WebTraceLocation&, Task* task) + void postTask(const WebTraceLocation&, Task* task) override { EXPECT_EQ((Task*)0, m_task); m_task = task; @@ -268,6 +268,12 @@ void postDelayedTask(const WebTraceLocation&, Task*, double delayMs) override { ASSERT_NOT_REACHED(); }; + WebTaskRunner* clone() override + { + ASSERT_NOT_REACHED(); + return nullptr; + } + Task* m_task; };
diff --git a/third_party/WebKit/Source/web/AssociatedURLLoader.cpp b/third_party/WebKit/Source/web/AssociatedURLLoader.cpp index 6170c8d..4c838f7 100644 --- a/third_party/WebKit/Source/web/AssociatedURLLoader.cpp +++ b/third_party/WebKit/Source/web/AssociatedURLLoader.cpp
@@ -383,4 +383,9 @@ m_loader->setDefersLoading(defersLoading); } +void AssociatedURLLoader::setLoadingTaskRunner(blink::WebTaskRunner*) +{ + // TODO(alexclarke): Maybe support this one day if it proves worthwhile. +} + } // namespace blink
diff --git a/third_party/WebKit/Source/web/AssociatedURLLoader.h b/third_party/WebKit/Source/web/AssociatedURLLoader.h index 41b0c26..6dcd06e 100644 --- a/third_party/WebKit/Source/web/AssociatedURLLoader.h +++ b/third_party/WebKit/Source/web/AssociatedURLLoader.h
@@ -54,6 +54,7 @@ void loadAsynchronously(const WebURLRequest&, WebURLLoaderClient*) override; void cancel() override; void setDefersLoading(bool) override; + void setLoadingTaskRunner(blink::WebTaskRunner*) override; private:
diff --git a/third_party/WebKit/Source/wtf/text/StringBuffer.h b/third_party/WebKit/Source/wtf/text/StringBuffer.h index 5e780e63..f38e0cf 100644 --- a/third_party/WebKit/Source/wtf/text/StringBuffer.h +++ b/third_party/WebKit/Source/wtf/text/StringBuffer.h
@@ -70,7 +70,7 @@ ASSERT(m_data); if (m_data->length() == newLength) return; - m_data->truncateAssumingIsolated(newLength); + m_data = m_data->substring(0, newLength); } } // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/text/StringBuilder.cpp b/third_party/WebKit/Source/wtf/text/StringBuilder.cpp index f3a40bc3..c4c831a 100644 --- a/third_party/WebKit/Source/wtf/text/StringBuilder.cpp +++ b/third_party/WebKit/Source/wtf/text/StringBuilder.cpp
@@ -57,12 +57,6 @@ return; } - if (m_buffer->hasOneRef()) { - m_buffer->truncateAssumingIsolated(m_length); - m_string = m_buffer.release(); - return; - } - m_string = m_buffer->substring(0, m_length); }
diff --git a/third_party/WebKit/Source/wtf/text/StringImpl.cpp b/third_party/WebKit/Source/wtf/text/StringImpl.cpp index 303ee9d..56b81dab 100644 --- a/third_party/WebKit/Source/wtf/text/StringImpl.cpp +++ b/third_party/WebKit/Source/wtf/text/StringImpl.cpp
@@ -682,7 +682,7 @@ targetLength = converter(data16, targetLength, source16, length, locale, &status); if (U_SUCCESS(status)) { if (length > 0) - output->truncateAssumingIsolated(targetLength); + return output->substring(0, targetLength); return output.release(); } if (status != U_BUFFER_OVERFLOW_ERROR)
diff --git a/third_party/WebKit/Source/wtf/text/StringImpl.h b/third_party/WebKit/Source/wtf/text/StringImpl.h index 5681b234..521d59a2 100644 --- a/third_party/WebKit/Source/wtf/text/StringImpl.h +++ b/third_party/WebKit/Source/wtf/text/StringImpl.h
@@ -218,15 +218,6 @@ static PassRefPtr<StringImpl> createUninitialized(unsigned length, LChar*& data); static PassRefPtr<StringImpl> createUninitialized(unsigned length, UChar*& data); - // If this StringImpl has only one reference, we can truncate the string by - // updating its m_length property without actually re-allocating its buffer. - void truncateAssumingIsolated(unsigned length) - { - ASSERT(hasOneRef()); - ASSERT(length <= m_length); - m_length = length; - } - unsigned length() const { return m_length; } bool is8Bit() const { return m_is8Bit; } @@ -452,11 +443,11 @@ private: unsigned m_refCount; - unsigned m_length; + const unsigned m_length; mutable unsigned m_hash : 24; unsigned m_isAtomic : 1; - unsigned m_is8Bit : 1; - unsigned m_isStatic : 1; + const unsigned m_is8Bit : 1; + const unsigned m_isStatic : 1; }; template <>
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py index 575b431..9aa1711 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/port/base.py
@@ -1587,6 +1587,7 @@ return [ # For example, to turn on force-compositing-mode in the svg/ directory: # PhysicalTestSuite('svg', ['--force-compositing-mode']), + PhysicalTestSuite('css', ["--always-use-complex-text"]), PhysicalTestSuite('fast/text', ["--always-use-complex-text", "--enable-direct-write", "--enable-font-antialiasing"]), ]
diff --git a/third_party/WebKit/public/platform/WebTaskRunner.h b/third_party/WebKit/public/platform/WebTaskRunner.h index 4369ad9..6d12febc 100644 --- a/third_party/WebKit/public/platform/WebTaskRunner.h +++ b/third_party/WebKit/public/platform/WebTaskRunner.h
@@ -28,11 +28,14 @@ // Schedule a task to be run on the the associated WebThread. // Takes ownership of |Task|. Can be called from any thread. - virtual void postTask(const WebTraceLocation&, Task*) {} + virtual void postTask(const WebTraceLocation&, Task*) = 0; // Schedule a task to be run after |delayMs| on the the associated WebThread. // Takes ownership of |Task|. Can be called from any thread. - virtual void postDelayedTask(const WebTraceLocation&, Task*, double delayMs) {} + virtual void postDelayedTask(const WebTraceLocation&, Task*, double delayMs) = 0; + + // Returns a clone of the WebTaskRunner. + virtual WebTaskRunner* clone() = 0; #ifdef INSIDE_BLINK // Helpers for posting bound functions as tasks.
diff --git a/third_party/WebKit/public/platform/WebURLLoader.h b/third_party/WebKit/public/platform/WebURLLoader.h index eada222..3a91423 100644 --- a/third_party/WebKit/public/platform/WebURLLoader.h +++ b/third_party/WebKit/public/platform/WebURLLoader.h
@@ -37,6 +37,7 @@ namespace blink { class WebData; +class WebTaskRunner; class WebThreadedDataReceiver; class WebURLLoaderClient; class WebURLResponse; @@ -78,6 +79,10 @@ // of the data receiver is assumed by the WebURLLoader and the receiver should // be deleted on the main thread when no longer needed. virtual bool attachThreadedDataReceiver(WebThreadedDataReceiver*) { return false; } + + // Sets the task runner for which any loading tasks should be posted on. + // Takes ownership of the WebTaskRunner. + virtual void setLoadingTaskRunner(WebTaskRunner*) = 0; }; } // namespace blink
diff --git a/third_party/android_platform/config.gni b/third_party/android_platform/config.gni index 88f6362..cef7f6b8 100644 --- a/third_party/android_platform/config.gni +++ b/third_party/android_platform/config.gni
@@ -3,7 +3,7 @@ # found in the LICENSE file. relocation_packer_target = - "//third_party/android_platform/relocation_packer($host_toolchain)" + "//third_party/android_platform:android_relocation_packer($host_toolchain)" relocation_packer_dir = get_label_info("$relocation_packer_target", "root_out_dir") relocation_packer_exe = "${relocation_packer_dir}/android_relocation_packer"
diff --git a/third_party/libaddressinput/BUILD.gn b/third_party/libaddressinput/BUILD.gn index 1307c71..0191886 100644 --- a/third_party/libaddressinput/BUILD.gn +++ b/third_party/libaddressinput/BUILD.gn
@@ -135,7 +135,7 @@ ] } -if (!is_android) { +if (!is_android || use_aura) { # The list of files in libaddressinput.gypi. gypi_values = exec_script("//build/gypi_to_gn.py", [ rebase_path("src/cpp/libaddressinput.gypi") ],
diff --git a/third_party/libjingle/README.chromium b/third_party/libjingle/README.chromium index 6ac2c94..689c46d 100644 --- a/third_party/libjingle/README.chromium +++ b/third_party/libjingle/README.chromium
@@ -1,7 +1,7 @@ Name: libjingle URL: http://code.google.com/p/webrtc/ Version: unknown -Revision: 10255 +Revision: 10273 License: BSD License File: source/talk/COPYING Security Critical: yes
diff --git a/third_party/mojo/src/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h b/third_party/mojo/src/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h index ef8b025..0c5bf56 100644 --- a/third_party/mojo/src/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h +++ b/third_party/mojo/src/mojo/public/c/gles2/gles2_call_visitor_chromium_extension_autogen.h
@@ -332,6 +332,10 @@ void, (GLuint64 fence_sync, GLbyte* sync_token), (fence_sync, sync_token)) +VISIT_GL_CALL(GenUnverifiedSyncTokenCHROMIUM, + void, + (GLuint64 fence_sync, GLbyte* sync_token), + (fence_sync, sync_token)) VISIT_GL_CALL(WaitSyncTokenCHROMIUM, void, (const GLbyte* sync_token),
diff --git a/tools/android/forwarder2/BUILD.gn b/tools/android/forwarder2/BUILD.gn index 7d77bdc..5fcd43c 100644 --- a/tools/android/forwarder2/BUILD.gn +++ b/tools/android/forwarder2/BUILD.gn
@@ -5,9 +5,7 @@ # GYP: //tools/android/forwarder2/forwarder.gyp:forwarder2 group("forwarder2") { data_deps = [ - ":host_forwarder($host_toolchain)", ":host_forwarder_copy($host_toolchain)", - ":device_forwarder($default_toolchain)", ":device_forwarder_prepare_dist($default_toolchain)", ] } @@ -45,7 +43,9 @@ "//build/config/sanitizers:deps", "//tools/android/common", ] - data_deps = [ "//build/android/pylib/device/commands" ] + data_deps = [ + "//build/android/pylib/device/commands", + ] } # GYP: //tools/android/forwarder2/forwarder.gyp:forwarder2 @@ -90,15 +90,25 @@ } # GYP: //tools/android/forwarder2/forwarder.gyp:forwarder2 - copy("host_forwarder_copy") { + action("host_forwarder_copy") { + # Symlink rather than copy. When copied and using a component build, it + # fails to find libbase.so (since it's actually at clang_x64/libbase.so). + script = "//build/symlink.py" + _src = "$root_out_dir/host_forwarder" + _target = "$root_build_dir/host_forwarder" sources = [ - "$root_out_dir/host_forwarder", + _src, ] outputs = [ - "$root_build_dir/host_forwarder", + _target, ] deps = [ ":host_forwarder", ] + args = [ + "-f", + rebase_path(_src, root_build_dir), + rebase_path(_target, root_build_dir), + ] } }
diff --git a/tools/android/memtrack_helper/BUILD.gn b/tools/android/memtrack_helper/BUILD.gn index 339b99a6..5948cb5 100644 --- a/tools/android/memtrack_helper/BUILD.gn +++ b/tools/android/memtrack_helper/BUILD.gn
@@ -2,11 +2,22 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +# Unwind tables create a dependency on libc++. By removing them +# the final binary will not require anything more than libc and libdl. +# This makes its deployment easier in component=shared_library mode. +config("android_binary_no_libcpp_config") { + cflags = [ + "-fno-unwind-tables", + "-fno-asynchronous-unwind-tables", + ] +} + executable("memtrack_helper") { sources = [ "memtrack_helper.c", "memtrack_helper.h", ] + configs += [ ":android_binary_no_libcpp_config" ] } executable("memtrack_helper_test_client") { @@ -14,4 +25,5 @@ "memtrack_helper.h", "memtrack_helper_test_client.c", ] + configs += [ ":android_binary_no_libcpp_config" ] }
diff --git a/tools/android/memtrack_helper/memtrack_helper.gyp b/tools/android/memtrack_helper/memtrack_helper.gyp index 31eed4b..9a93801e 100644 --- a/tools/android/memtrack_helper/memtrack_helper.gyp +++ b/tools/android/memtrack_helper/memtrack_helper.gyp
@@ -7,11 +7,17 @@ { 'target_name': 'memtrack_helper-unstripped', 'type': 'executable', - 'link_settings': { - 'libraries': [ - '-ldl', - ], - }, + # Unwind tables create a dependency on libc++. By removing them + # the final binary will not require anything more than libc and libdl. + # This makes its deployment easier in component=shared_library mode. + 'cflags!': [ + '-funwind-tables', + '-fasynchronous-unwind-tables', + ], + 'cflags': [ + '-fno-unwind-tables', + '-fno-asynchronous-unwind-tables', + ], 'sources': [ 'memtrack_helper.c', ],
diff --git a/tools/checkperms/checkperms.py b/tools/checkperms/checkperms.py index 7de86de..33f9fcf 100755 --- a/tools/checkperms/checkperms.py +++ b/tools/checkperms/checkperms.py
@@ -457,9 +457,6 @@ options.root = os.path.abspath(options.root) if options.files: - # --file implies --bare (for PRESUBMIT.py). - options.bare = True - errors = check_files(options.root, options.files) else: api = get_scm(options.root, options.bare)
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 9035cd7..e5a1386 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -18706,6 +18706,11 @@ </summary> </histogram> +<histogram name="Memory.IPCChannelReader.ReceivedMessageSize" units="bytes"> + <owner>dskiba@chromium.org</owner> + <summary>Size of messages received by IPC::ChannelReader.</summary> +</histogram> + <histogram name="Memory.NativeClient" units="KB"> <owner>hajimehoshi@chromium.org</owner> <owner>kenjibaheux@google.com</owner> @@ -70231,6 +70236,7 @@ <int value="65" label="IDC_WRITING_DIRECTION_RTL"/> <int value="66" label="IDC_CONTENT_CONTEXT_LOAD_ORIGINAL_IMAGE"/> <int value="67" label="IDC_CONTENT_CONTEXT_FORCESAVEPASSWORD"/> + <int value="69" label="IDC_CONTENT_CONTEXT_COPYLINKTEXT"/> </enum> <enum name="ReportProcessingResult" type="int">
diff --git a/tools/telemetry/telemetry/web_perf/metrics/memory_timeline.py b/tools/telemetry/telemetry/web_perf/metrics/memory_timeline.py index e10db36..06cefc95 100644 --- a/tools/telemetry/telemetry/web_perf/metrics/memory_timeline.py +++ b/tools/telemetry/telemetry/web_perf/metrics/memory_timeline.py
@@ -29,9 +29,8 @@ def ContainedIn(dump, interaction): return interaction.start < dump.start and dump.end < interaction.end - def HasMmapsDuringInteractions(dump): - return dump.has_mmaps and any(ContainedIn(dump, interaction) - for interaction in interactions) + def OccursDuringInteractions(dump): + return any(ContainedIn(dump, interaction) for interaction in interactions) def ReportResultsForProcess(memory_dumps, process_name): if not memory_dumps: @@ -51,9 +50,13 @@ none_value_reason=none_reason, improvement_direction=improvement_direction.DOWN)) - memory_dumps = filter(HasMmapsDuringInteractions, + memory_dumps = filter(OccursDuringInteractions, model.IterGlobalMemoryDumps()) + # Either all dumps should contain memory maps (Android, Linux), or none + # of them (Windows, Mac). + assert len(set(dump.has_mmaps for dump in memory_dumps)) <= 1 + ReportResultsForProcess(memory_dumps, 'total') process_dumps_by_name = _AggregateDicts(
diff --git a/tools/telemetry/telemetry/web_perf/metrics/memory_timeline_unittest.py b/tools/telemetry/telemetry/web_perf/metrics/memory_timeline_unittest.py index 1d3f466..001b05f 100644 --- a/tools/telemetry/telemetry/web_perf/metrics/memory_timeline_unittest.py +++ b/tools/telemetry/telemetry/web_perf/metrics/memory_timeline_unittest.py
@@ -19,12 +19,11 @@ process_dump.process_name = name process_dump.start = start if memory_usage is None: - process_dump.has_mmaps = False memory_usage = {} - else: - process_dump.has_mmaps = True - if not isinstance(memory_usage, dict): + elif not isinstance(memory_usage, dict): memory_usage = dict.fromkeys(memory_timeline.DEFAULT_METRICS, memory_usage) + process_dump.has_mmaps = any(metric in memory_usage for metric + in memory_timeline.DEFAULT_METRICS) process_dump.GetMemoryUsage = mock.Mock(return_value=memory_usage) return process_dump @@ -103,16 +102,26 @@ TestInteraction(12, 15)] self.assertEquals([123, 555], self.getOverallPssTotal(model, interactions)) - def testDumpsWithNoMemoryMapsAreFilteredOut(self): + def testDumpsWithNoMemoryMaps(self): + model = MockTimelineModel([ + MockProcessDumpEvent('dump1', 'browser', 2, {'blink': 123}), + MockProcessDumpEvent('dump2', 'browser', 5, {'blink': 456})]) + interactions = [TestInteraction(1, 10)] + results = self.getResultsDict(model, interactions) + self.assertItemsEqual(['blink_total', 'blink_browser'], results.keys()) + self.assertListEqual([123, 456], results['blink_total']) + self.assertListEqual([123, 456], results['blink_browser']) + + def testDumpsWithSomeMemoryMaps(self): model = MockTimelineModel([ MockProcessDumpEvent('dump1', 'browser', 2, 123), MockProcessDumpEvent('dump2', 'browser', 5, None)]) interactions = [TestInteraction(1, 10)] - self.assertEquals([123], self.getOverallPssTotal(model, interactions)) + self.assertRaises(AssertionError, self.getResultsDict, model, interactions) def testReturnsNoneWhenAllDumpsAreFilteredOut(self): model = MockTimelineModel([ - MockProcessDumpEvent('dump1', 'bowser', 5, None), + MockProcessDumpEvent('dump1', 'bowser', 0, 123), MockProcessDumpEvent('dump2', 'browser', 11, 789)]) interactions = [TestInteraction(1, 10)] self.assertEquals(None, self.getOverallPssTotal(model, interactions))
diff --git a/ui/aura/bench/bench_main.cc b/ui/aura/bench/bench_main.cc index 6b6bef6..ce85572 100644 --- a/ui/aura/bench/bench_main.cc +++ b/ui/aura/bench/bench_main.cc
@@ -150,6 +150,16 @@ gl->ShallowFlushCHROMIUM(); } +gfx::Size GetFullscreenSize() { +#if defined(OS_WIN) + return gfx::Size(GetSystemMetrics(SM_CXSCREEN), + GetSystemMetrics(SM_CYSCREEN)); +#else + NOTIMPLEMENTED(); + return gfx::Size(1024, 768); +#endif +} + // A benchmark that adds a texture layer that is updated every frame. class WebGLBench : public BenchCompositorObserver { public: @@ -312,7 +322,7 @@ aura::Env::CreateInstance(true); aura::Env::GetInstance()->set_context_factory(context_factory.get()); scoped_ptr<aura::TestScreen> test_screen( - aura::TestScreen::CreateFullscreen()); + aura::TestScreen::Create(GetFullscreenSize())); gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, test_screen.get()); scoped_ptr<aura::WindowTreeHost> host( test_screen->CreateHostForPrimaryDisplay());
diff --git a/ui/aura/remote_window_tree_host_win.cc b/ui/aura/remote_window_tree_host_win.cc index 681c3ce9..6c43c996 100644 --- a/ui/aura/remote_window_tree_host_win.cc +++ b/ui/aura/remote_window_tree_host_win.cc
@@ -94,7 +94,8 @@ host_(NULL), ignore_mouse_moves_until_set_cursor_ack_(0), event_flags_(0), - window_size_(aura::WindowTreeHost::GetNativeScreenSize()) { + window_size_(GetSystemMetrics(SM_CXSCREEN), + GetSystemMetrics(SM_CYSCREEN)) { CHECK(!g_instance); g_instance = this; prop_.reset(new ui::ViewProp(NULL, kWindowTreeHostWinKey, this));
diff --git a/ui/aura/test/test_screen.cc b/ui/aura/test/test_screen.cc index 1320b1c..bc5ceeff 100644 --- a/ui/aura/test/test_screen.cc +++ b/ui/aura/test/test_screen.cc
@@ -34,11 +34,6 @@ return new TestScreen(gfx::Rect(size.IsEmpty() ? kDefaultSize : size)); } -// static -TestScreen* TestScreen::CreateFullscreen() { - return new TestScreen(gfx::Rect(WindowTreeHost::GetNativeScreenSize())); -} - TestScreen::~TestScreen() { }
diff --git a/ui/aura/test/test_screen.h b/ui/aura/test/test_screen.h index f137cd8..dd3662aa 100644 --- a/ui/aura/test/test_screen.h +++ b/ui/aura/test/test_screen.h
@@ -28,8 +28,6 @@ // Creates a gfx::Screen of the specified size. If no size is specified, then // creates a 800x600 screen. |size| is in physical pixels. static TestScreen* Create(const gfx::Size& size); - // Creates a TestScreen that uses fullscreen for the display. - static TestScreen* CreateFullscreen(); ~TestScreen() override; WindowTreeHost* CreateHostForPrimaryDisplay();
diff --git a/ui/aura/window_tree_host.h b/ui/aura/window_tree_host.h index 908d924..1571969 100644 --- a/ui/aura/window_tree_host.h +++ b/ui/aura/window_tree_host.h
@@ -82,10 +82,6 @@ // transform and insets. virtual void UpdateRootWindowSize(const gfx::Size& host_size); - // Returns the actual size of the screen. - // (gfx::Screen only reports on the virtual desktop exposed by Aura.) - static gfx::Size GetNativeScreenSize(); - // Converts |point| from the root window's coordinate system to native // screen's. void ConvertPointToNativeScreen(gfx::Point* point) const;
diff --git a/ui/aura/window_tree_host_mac.mm b/ui/aura/window_tree_host_mac.mm index 4734bf0..c6748a6 100644 --- a/ui/aura/window_tree_host_mac.mm +++ b/ui/aura/window_tree_host_mac.mm
@@ -102,10 +102,4 @@ return new WindowTreeHostMac(bounds); } -// static -gfx::Size WindowTreeHost::GetNativeScreenSize() { - NOTIMPLEMENTED(); - return gfx::Size(1024, 768); -} - } // namespace aura
diff --git a/ui/aura/window_tree_host_ozone.cc b/ui/aura/window_tree_host_ozone.cc index 90212e2f..87e33688a 100644 --- a/ui/aura/window_tree_host_ozone.cc +++ b/ui/aura/window_tree_host_ozone.cc
@@ -116,10 +116,4 @@ return new WindowTreeHostOzone(bounds); } -// static -gfx::Size WindowTreeHost::GetNativeScreenSize() { - NOTIMPLEMENTED(); - return gfx::Size(); -} - } // namespace aura
diff --git a/ui/aura/window_tree_host_win.cc b/ui/aura/window_tree_host_win.cc index 0727401..ea7bf24 100644 --- a/ui/aura/window_tree_host_win.cc +++ b/ui/aura/window_tree_host_win.cc
@@ -31,12 +31,6 @@ return new WindowTreeHostWin(bounds); } -// static -gfx::Size WindowTreeHost::GetNativeScreenSize() { - return gfx::Size(GetSystemMetrics(SM_CXSCREEN), - GetSystemMetrics(SM_CYSCREEN)); -} - WindowTreeHostWin::WindowTreeHostWin(const gfx::Rect& bounds) : has_capture_(false), widget_(gfx::kNullAcceleratedWidget),
diff --git a/ui/aura/window_tree_host_x11.cc b/ui/aura/window_tree_host_x11.cc index 084296c3..7f2c720 100644 --- a/ui/aura/window_tree_host_x11.cc +++ b/ui/aura/window_tree_host_x11.cc
@@ -661,12 +661,6 @@ return new WindowTreeHostX11(bounds); } -// static -gfx::Size WindowTreeHost::GetNativeScreenSize() { - ::XDisplay* xdisplay = gfx::GetXDisplay(); - return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); -} - namespace test { void SetUseOverrideRedirectWindowByDefault(bool override_redirect) {
diff --git a/ui/keyboard/content/keyboard_ui_content.cc b/ui/keyboard/content/keyboard_ui_content.cc index 010abde..40952ad 100644 --- a/ui/keyboard/content/keyboard_ui_content.cc +++ b/ui/keyboard/content/keyboard_ui_content.cc
@@ -160,6 +160,9 @@ void KeyboardUIContent::UpdateInsetsForWindow(aura::Window* window) { aura::Window* keyboard_window = GetKeyboardWindow(); + if (!ShouldWindowOverscroll(window)) + return; + scoped_ptr<content::RenderWidgetHostIterator> widgets( content::RenderWidgetHost::GetRenderWidgetHosts()); while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { @@ -198,6 +201,10 @@ return keyboard_contents_; } +bool KeyboardUIContent::ShouldWindowOverscroll(aura::Window* window) const { + return true; +} + void KeyboardUIContent::ReloadKeyboardIfNeeded() { DCHECK(keyboard_contents_); if (keyboard_contents_->GetURL() != GetVirtualKeyboardUrl()) { @@ -222,19 +229,13 @@ // window is created while the keyboard is visible. scoped_ptr<content::RenderWidgetHostIterator> widgets( content::RenderWidgetHost::GetRenderWidgetHosts()); - aura::Window* keyboard_window = GetKeyboardWindow(); - aura::Window* root_window = keyboard_window->GetRootWindow(); while (content::RenderWidgetHost* widget = widgets->GetNextHost()) { content::RenderWidgetHostView* view = widget->GetView(); // Can be NULL, e.g. if the RenderWidget is being destroyed or // the render process crashed. if (view) { aura::Window* window = view->GetNativeView(); - // If virtual keyboard failed to load, a widget that displays error - // message will be created and adds as a child of the virtual keyboard - // window. We want to avoid add BoundsChangedObserver to that window. - if (!keyboard_window->Contains(window) && - window->GetRootWindow() == root_window) { + if (ShouldWindowOverscroll(window)) { gfx::Rect window_bounds = window->GetBoundsInScreen(); gfx::Rect intersect = gfx::IntersectRects(window_bounds, new_bounds); @@ -283,6 +284,13 @@ window->RemoveObserver(this); } +const aura::Window* KeyboardUIContent::GetKeyboardRootWindow() const { + if (!keyboard_contents_) { + return nullptr; + } + return keyboard_contents_->GetNativeView()->GetRootWindow(); +} + void KeyboardUIContent::LoadContents(const GURL& url) { if (keyboard_contents_) { content::OpenURLParams params(
diff --git a/ui/keyboard/content/keyboard_ui_content.h b/ui/keyboard/content/keyboard_ui_content.h index 1c6fc25..af45c12 100644 --- a/ui/keyboard/content/keyboard_ui_content.h +++ b/ui/keyboard/content/keyboard_ui_content.h
@@ -72,6 +72,7 @@ // Overridden from KeyboardUI: aura::Window* GetKeyboardWindow() override; bool HasKeyboardWindow() const override; + bool ShouldWindowOverscroll(aura::Window* window) const override; void ReloadKeyboardIfNeeded() override; void InitInsets(const gfx::Rect& new_bounds) override; void ResetInsets() override; @@ -91,6 +92,8 @@ content::BrowserContext* browser_context() { return browser_context_; } + const aura::Window* GetKeyboardRootWindow() const; + private: friend class TestApi; @@ -124,4 +127,4 @@ } // namespace keyboard -#endif // UI_KEYBOARD_CONTENT_KEYBOARD_UI_CONTENT_H_ \ No newline at end of file +#endif // UI_KEYBOARD_CONTENT_KEYBOARD_UI_CONTENT_H_
diff --git a/ui/keyboard/keyboard_controller_unittest.cc b/ui/keyboard/keyboard_controller_unittest.cc index 741e1d2d..a999b207 100644 --- a/ui/keyboard/keyboard_controller_unittest.cc +++ b/ui/keyboard/keyboard_controller_unittest.cc
@@ -96,6 +96,9 @@ // Overridden from KeyboardUI: bool HasKeyboardWindow() const override { return window_; } + bool ShouldWindowOverscroll(aura::Window* window) const override { + return true; + } aura::Window* GetKeyboardWindow() override { if (!window_) { window_.reset(new aura::Window(&delegate_));
diff --git a/ui/keyboard/keyboard_ui.h b/ui/keyboard/keyboard_ui.h index 895617ff..b4fc21c6 100644 --- a/ui/keyboard/keyboard_ui.h +++ b/ui/keyboard/keyboard_ui.h
@@ -36,6 +36,11 @@ // Whether the keyboard window has been created. virtual bool HasKeyboardWindow() const = 0; + // Whether this window should do an overscroll to avoid occlusion by the + // virtual keyboard. IME windows and virtual keyboard windows should always + // avoid overscroll. + virtual bool ShouldWindowOverscroll(aura::Window* window) const = 0; + // Gets the InputMethod that will provide notifications about changes in the // text input context. virtual ui::InputMethod* GetInputMethod() = 0;
diff --git a/ui/views/views_delegate.cc b/ui/views/views_delegate.cc index 30d85252..a0f8d196 100644 --- a/ui/views/views_delegate.cc +++ b/ui/views/views_delegate.cc
@@ -6,6 +6,7 @@ #include "base/command_line.h" #include "ui/views/views_touch_selection_controller_factory.h" +#include "ui/views/widget/native_widget_private.h" #if defined(USE_AURA) #include "ui/views/touchui/touch_selection_menu_runner_views.h" @@ -29,6 +30,11 @@ return views_delegate; } +NativeWidget* ViewsDelegate::CreateNativeWidget( + internal::NativeWidgetDelegate* delegate) { + return internal::NativeWidgetPrivate::CreateNativeWidget(delegate); +} + void ViewsDelegate::SaveWindowPlacement(const Widget* widget, const std::string& window_name, const gfx::Rect& bounds,
diff --git a/ui/views/views_delegate.h b/ui/views/views_delegate.h index c881daa..8cb0940 100644 --- a/ui/views/views_delegate.h +++ b/ui/views/views_delegate.h
@@ -88,6 +88,11 @@ // Returns the ViewsDelegate instance if there is one, or nullptr otherwise. static ViewsDelegate* GetInstance(); + // Allows the delegate to override creation of the default NativeWidget + // implementation used by Widget. + virtual NativeWidget* CreateNativeWidget( + internal::NativeWidgetDelegate* delegate); + // Saves the position, size and "show" state for the window with the // specified name. virtual void SaveWindowPlacement(const Widget* widget,
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc index e1fc508..189522a 100644 --- a/ui/views/widget/widget.cc +++ b/ui/views/widget/widget.cc
@@ -59,8 +59,14 @@ NativeWidget* CreateNativeWidget(NativeWidget* native_widget, internal::NativeWidgetDelegate* delegate) { if (!native_widget) { - native_widget = - internal::NativeWidgetPrivate::CreateNativeWidget(delegate); + if (ViewsDelegate::GetInstance()) { + native_widget = ViewsDelegate::GetInstance()->CreateNativeWidget( + delegate); + } + if (!native_widget) { + native_widget = + internal::NativeWidgetPrivate::CreateNativeWidget(delegate); + } } return native_widget; }