diff --git a/AUTHORS b/AUTHORS index 9278d9d..412f738 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -221,7 +221,6 @@ Franklin Ta <fta2012@gmail.com> Frédéric Jacob <frederic.jacob.78@gmail.com> Frédéric Wang <fred.wang@free.fr> -Fu Junwei <junwei.fu@intel.com> Gaetano Mendola <mendola@gmail.com> Gajendra N <gajendra.n@samsung.com> Gajendra Singh <wxjg68@motorola.com>
diff --git a/BUILD.gn b/BUILD.gn index 613a340..9af0273 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -365,12 +365,6 @@ ] } - if (is_linux && !is_chromeos && !is_chromecast && !use_ozone) { - # TODO(thomasanderson): Remove this once we build using - # GTK3 by default. (crbug.com/132847, crbug.com/79722) - deps += [ "//chrome/browser/ui/libgtkui:libgtk3ui" ] - } - if (use_ozone) { deps += [ "//ui/ozone",
diff --git a/DEPS b/DEPS index 4c5562a..f5580a8 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,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': '4b66512a6384d32c1a89396bd4a229c03cce67a0', + 'skia_revision': 'c43559e6e6bd403c5f3abc46a33e996498eef63f', # 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': '73183b7b5de332bdff347b1c9403ae5bb1fb36a7', + 'v8_revision': 'abb293d2c26943d89c113d3f23baa88ff9830e3f', # 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. @@ -96,7 +96,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'd31d896231ad698f50692b012810969c4d03f0a9', + 'catapult_revision': 'fadc168f513f08690b97aea9fa132464bf1648f7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -232,7 +232,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' + '@' + '149997cfe303770079d5b4887e937f80a2b5c46b', # commit position 16571 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '7eb7de80bd811a2c7c9e9da245862298529487ec', # commit position 16606 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'),
diff --git a/android_webview/apk/java/proguard.flags b/android_webview/apk/java/proguard.flags index dbbc1bb..495d4861 100644 --- a/android_webview/apk/java/proguard.flags +++ b/android_webview/apk/java/proguard.flags
@@ -6,6 +6,10 @@ # build/android/stacktrace/java_deobfuscate.py to fix the stacktrace up for us. -keepnames,allowoptimization class *** { *; } +-keepclassmembers class org.chromium.android_webview.AwPdfExporter { + android.view.ViewGroup mContainerView; +} + # Keep the factory and its public members; it's the main entry point used by the # framework. -keep class com.android.webview.chromium.WebViewChromiumFactoryProvider { @@ -16,7 +20,6 @@ public *; } - -keep class com.android.webview.chromium.WebViewDatabaseAdapter { public *; }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentViewClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentViewClient.java index c258f92..ff33c778 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContentViewClient.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContentViewClient.java
@@ -4,10 +4,15 @@ package org.chromium.android_webview; +import android.content.Context; +import android.content.Intent; import android.view.KeyEvent; +import org.chromium.base.Log; import org.chromium.content.browser.ContentViewClient; +import java.net.URISyntaxException; + /** * ContentViewClient implementation for WebView */ @@ -17,12 +22,40 @@ private final AwContentsClient mAwContentsClient; private final AwSettings mAwSettings; private final AwContents mAwContents; + private final Context mContext; public AwContentViewClient(AwContentsClient awContentsClient, AwSettings awSettings, - AwContents awContents) { + AwContents awContents, Context context) { mAwContentsClient = awContentsClient; mAwSettings = awSettings; mAwContents = awContents; + mContext = context; + } + + @Override + public void onBackgroundColorChanged(int color) { + mAwContentsClient.onBackgroundColorChanged(color); + } + + @Override + public void onStartContentIntent(Context context, String contentUrl, boolean isMainFrame) { + // Make sure that this URL is a valid scheme for this callback if interpreted as an intent, + // even though we don't dispatch it as an intent here, because many WebView apps will once + // it reaches them. + String scheme = null; + try { + Intent intent = Intent.parseUri(contentUrl, Intent.URI_INTENT_SCHEME); + scheme = intent.getScheme(); + } catch (URISyntaxException e) { + // Just don't set the scheme, it will be rejected. + } + if (!isAcceptableContentIntentScheme(scheme)) { + Log.w(TAG, "Invalid scheme for URI %s", contentUrl); + return; + } + // Comes from WebViewImpl::detectContentOnTouch in Blink, so must be user-initiated, and + // isn't a redirect. + mAwContentsClient.shouldIgnoreNavigation(context, contentUrl, isMainFrame, true, false); } @Override @@ -30,7 +63,7 @@ if (mAwContentsClient.hasWebViewClient()) { // The check below is reflecting Chrome's behavior and is a workaround for // http://b/7697782. - if (!shouldPropagateKey(event.getKeyCode())) return true; + if (!ContentViewClient.shouldPropagateKey(event.getKeyCode())) return true; return mAwContentsClient.shouldOverrideKeyEvent(event); }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 7c8df9f..83b9150 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -762,7 +762,7 @@ mAwViewMethods = new AwViewMethodsImpl(); mFullScreenTransitionsState = new FullScreenTransitionsState( mContainerView, mInternalAccessAdapter, mAwViewMethods); - mContentViewClient = new AwContentViewClient(contentsClient, settings, this); + mContentViewClient = new AwContentViewClient(contentsClient, settings, this, mContext); mLayoutSizer = dependencyFactory.createLayoutSizer(); mSettings = settings; mLayoutSizer.setDelegate(new AwLayoutSizerDelegate()); @@ -1056,7 +1056,7 @@ mWindowAndroid = getWindowAndroid(mContext); mContentViewCore = new ContentViewCore(mContext, PRODUCT_VERSION); mViewAndroidDelegate = new AwViewAndroidDelegate(mContainerView, - mContentsClient, mContentViewCore.getRenderCoordinates()); + mContentViewCore.getRenderCoordinates()); initializeContentViewCore(mContentViewCore, mContext, mViewAndroidDelegate, mInternalAccessAdapter, webContents, new AwGestureStateListener(), mContentViewClient, mWindowAndroid.getWindowAndroid());
diff --git a/android_webview/java/src/org/chromium/android_webview/AwPdfExporter.java b/android_webview/java/src/org/chromium/android_webview/AwPdfExporter.java index 97f84fb..b22350e9 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwPdfExporter.java +++ b/android_webview/java/src/org/chromium/android_webview/AwPdfExporter.java
@@ -33,7 +33,9 @@ // Maintain a reference to the top level object (i.e. WebView) since in a common // use case (offscreen webview) application may expect the framework's print manager // to own the Webview (via PrintDocumentAdapter). - // NOTE: it looks unused, but please do not remove this reference. + // NOTE: it looks unused, but please do not remove this reference. There is also a proguard + // configuration to prevent this variable to be optimized away. Any name changes should + // be reflected there. private ViewGroup mContainerView; AwPdfExporter(ViewGroup containerView) {
diff --git a/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java b/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java index d2f26ef6..80753a42 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java +++ b/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java
@@ -4,7 +4,6 @@ package org.chromium.android_webview; -import android.content.Intent; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -22,9 +21,6 @@ * Implementation of the abstract class {@link ViewAndroidDelegate} for WebView. */ public class AwViewAndroidDelegate extends ViewAndroidDelegate { - /** Used for logging. */ - private static final String TAG = "AwVAD"; - /** * The current container view. This view can be updated with * {@link #updateCurrentContainerView()}. @@ -37,7 +33,6 @@ */ private final Map<View, Position> mAnchorViews = new LinkedHashMap<>(); - private final AwContentsClient mContentsClient; private final RenderCoordinates mRenderCoordinates; /** @@ -64,10 +59,8 @@ } @VisibleForTesting - public AwViewAndroidDelegate(ViewGroup containerView, AwContentsClient contentsClient, - RenderCoordinates renderCoordinates) { + public AwViewAndroidDelegate(ViewGroup containerView, RenderCoordinates renderCoordinates) { mContainerView = containerView; - mContentsClient = contentsClient; mRenderCoordinates = renderCoordinates; } @@ -144,24 +137,6 @@ } @Override - public void onBackgroundColorChanged(int color) { - mContentsClient.onBackgroundColorChanged(color); - } - - @Override - public void startContentIntent(Intent intent, String contentUrl, boolean isMainFrame) { - // Make sure that this URL is a valid scheme for this callback if interpreted as an intent, - // even though we don't dispatch it as an intent here, because many WebView apps will once - // it reaches them. - assert intent != null; - - // Comes from WebViewImpl::detectContentOnTouch in Blink, so must be user-initiated, and - // isn't a redirect. - mContentsClient.shouldIgnoreNavigation(mContainerView.getContext(), contentUrl, - isMainFrame, true, false); - } - - @Override public ViewGroup getContainerView() { return mContainerView; }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsAnchorViewTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsAnchorViewTest.java index 237eaa565..ea1578e 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsAnchorViewTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsAnchorViewTest.java
@@ -27,7 +27,7 @@ public void setUp() throws Exception { super.setUp(); mContainerView = new FrameLayout(getActivity()); - mViewDelegate = new AwViewAndroidDelegate(mContainerView, null, new RenderCoordinates()); + mViewDelegate = new AwViewAndroidDelegate(mContainerView, new RenderCoordinates()); } @Feature({"AndroidWebView"})
diff --git a/android_webview/native/aw_metrics_service_client_impl.cc b/android_webview/native/aw_metrics_service_client_impl.cc index 3668f26..7566b51 100644 --- a/android_webview/native/aw_metrics_service_client_impl.cc +++ b/android_webview/native/aw_metrics_service_client_impl.cc
@@ -10,6 +10,7 @@ #include "base/files/file_util.h" #include "base/guid.h" #include "base/i18n/rtl.h" +#include "base/threading/sequenced_worker_pool.h" #include "components/metrics/call_stack_profile_metrics_provider.h" #include "components/metrics/enabled_state_provider.h" #include "components/metrics/gpu/gpu_metrics_provider.h"
diff --git a/ash/common/system/tray/system_tray_notifier.h b/ash/common/system/tray/system_tray_notifier.h index bd65d94..fe2b28c2b4 100644 --- a/ash/common/system/tray/system_tray_notifier.h +++ b/ash/common/system/tray/system_tray_notifier.h
@@ -9,6 +9,7 @@ #include "ash/ash_export.h" #include "ash/common/accessibility_types.h" +#include "base/callback_forward.h" #include "base/macros.h" #include "base/observer_list.h" #include "base/strings/string16.h"
diff --git a/ash/common/wm_shell.cc b/ash/common/wm_shell.cc index 2053c17..4aa1183 100644 --- a/ash/common/wm_shell.cc +++ b/ash/common/wm_shell.cc
@@ -54,6 +54,7 @@ #include "base/bind.h" #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "base/threading/sequenced_worker_pool.h" #include "services/preferences/public/cpp/pref_client_store.h" #include "services/preferences/public/interfaces/preferences.mojom.h" #include "services/service_manager/public/cpp/connector.h"
diff --git a/ash/mus/window_manager.cc b/ash/mus/window_manager.cc index 03a99b4..dc70051 100644 --- a/ash/mus/window_manager.cc +++ b/ash/mus/window_manager.cc
@@ -31,6 +31,7 @@ #include "ash/shell_init_params.h" #include "ash/wm/ash_focus_rules.h" #include "base/memory/ptr_util.h" +#include "base/threading/sequenced_worker_pool.h" #include "services/service_manager/public/cpp/connector.h" #include "services/ui/common/accelerator_util.h" #include "services/ui/common/types.h"
diff --git a/ash/mus/window_manager_application.cc b/ash/mus/window_manager_application.cc index 0a8abdb..c3dbcf5 100644 --- a/ash/mus/window_manager_application.cc +++ b/ash/mus/window_manager_application.cc
@@ -13,6 +13,7 @@ #include "ash/mus/window_manager.h" #include "base/bind.h" #include "base/memory/ptr_util.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_task_runner_handle.h" #include "chromeos/audio/cras_audio_handler.h" #include "chromeos/dbus/dbus_thread_manager.h"
diff --git a/ash/shell.cc b/ash/shell.cc index e765b34..f1ecea4f 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -95,6 +95,7 @@ #include "base/command_line.h" #include "base/memory/ptr_util.h" #include "base/sys_info.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/trace_event/trace_event.h" #include "chromeos/audio/audio_a11y_controller.h" #include "chromeos/chromeos_switches.h"
diff --git a/base/values.cc b/base/values.cc index 96e3aa5..e835e008 100644 --- a/base/values.cc +++ b/base/values.cc
@@ -78,7 +78,7 @@ auto IsImplemented = [](Value::Type type) { return type == Value::Type::NONE || type == Value::Type::BOOLEAN || type == Value::Type::INTEGER || type == Value::Type::DOUBLE || - type == Value::Type::STRING; + type == Value::Type::STRING || type == Value::Type::BINARY; }; return lhs == rhs || (IsImplemented(lhs) && IsImplemented(rhs)); @@ -91,6 +91,13 @@ return WrapUnique(new Value(Type::NONE)); } +// static +std::unique_ptr<BinaryValue> BinaryValue::CreateWithCopiedBuffer( + const char* buffer, + size_t size) { + return MakeUnique<BinaryValue>(std::vector<char>(buffer, buffer + size)); +} + Value::Value(const Value& that) { InternalCopyConstructFrom(that); } @@ -119,10 +126,12 @@ case Type::STRING: string_value_.Init(); return; + case Type::BINARY: + binary_value_.Init(); + return; // TODO(crbug.com/646113): Implement these once the corresponding derived // classes are removed. - case Type::BINARY: case Type::LIST: case Type::DICTIONARY: return; @@ -166,6 +175,14 @@ Value::Value(StringPiece in_string) : Value(in_string.as_string()) {} +Value::Value(const std::vector<char>& in_blob) : type_(Type::BINARY) { + binary_value_.Init(in_blob); +} + +Value::Value(std::vector<char>&& in_blob) : type_(Type::BINARY) { + binary_value_.Init(std::move(in_blob)); +} + Value& Value::operator=(const Value& that) { if (this != &that) { DCHECK(IsAssignmentSafe(type_, that.type_)); @@ -229,6 +246,19 @@ return *string_value_; } +const std::vector<char>& Value::GetBlob() const { + CHECK(is_blob()); + return *binary_value_; +} + +size_t Value::GetSize() const { + return GetBlob().size(); +} + +const char* Value::GetBuffer() const { + return GetBlob().data(); +} + bool Value::GetAsBoolean(bool* out_value) const { if (out_value && is_bool()) { *out_value = bool_value_; @@ -290,7 +320,11 @@ } bool Value::GetAsBinary(const BinaryValue** out_value) const { - return false; + if (out_value && is_blob()) { + *out_value = this; + return true; + } + return is_blob(); } bool Value::GetAsList(ListValue** out_value) { @@ -328,6 +362,10 @@ // Value when that code is deleted. case Type::STRING: return new StringValue(*string_value_); + // For now, make BinaryValues for backward-compatibility. Convert to + // Value when that code is deleted. + case Type::BINARY: + return new BinaryValue(*binary_value_); default: // All other types should be handled by subclasses. @@ -355,6 +393,8 @@ return double_value_ == other->double_value_; case Type::STRING: return *string_value_ == *(other->string_value_); + case Type::BINARY: + return *binary_value_ == *(other->binary_value_); default: // This method should only be getting called for the above types -- all // subclasses need to provide their own implementation;. @@ -405,10 +445,12 @@ case Type::STRING: string_value_.Init(*that.string_value_); return; + case Type::BINARY: + binary_value_.Init(*that.binary_value_); + return; // TODO(crbug.com/646113): Implement these once the corresponding derived // classes are removed. - case Type::BINARY: case Type::LIST: case Type::DICTIONARY: return; @@ -429,10 +471,12 @@ case Type::STRING: string_value_.InitFromMove(std::move(that.string_value_)); return; + case Type::BINARY: + binary_value_.InitFromMove(std::move(that.binary_value_)); + return; // TODO(crbug.com/646113): Implement these once the corresponding derived // classes are removed. - case Type::BINARY: case Type::LIST: case Type::DICTIONARY: return; @@ -453,10 +497,12 @@ case Type::STRING: *string_value_ = *that.string_value_; return; + case Type::BINARY: + *binary_value_ = *that.binary_value_; + return; // TODO(crbug.com/646113): Implement these once the corresponding derived // classes are removed. - case Type::BINARY: case Type::LIST: case Type::DICTIONARY: return; @@ -477,10 +523,12 @@ case Type::STRING: *string_value_ = std::move(*that.string_value_); return; + case Type::BINARY: + *binary_value_ = std::move(*that.binary_value_); + return; // TODO(crbug.com/646113): Implement these once the corresponding derived // classes are removed. - case Type::BINARY: case Type::LIST: case Type::DICTIONARY: return; @@ -499,54 +547,18 @@ case Type::STRING: string_value_.Destroy(); return; + case Type::BINARY: + binary_value_.Destroy(); + return; // TODO(crbug.com/646113): Implement these once the corresponding derived // classes are removed. - case Type::BINARY: case Type::LIST: case Type::DICTIONARY: return; } } -///////////////////// BinaryValue //////////////////// - -BinaryValue::BinaryValue() : Value(Type::BINARY), size_(0) {} - -BinaryValue::BinaryValue(std::unique_ptr<char[]> buffer, size_t size) - : Value(Type::BINARY), buffer_(std::move(buffer)), size_(size) {} - -BinaryValue::~BinaryValue() { -} - -// static -std::unique_ptr<BinaryValue> BinaryValue::CreateWithCopiedBuffer( - const char* buffer, - size_t size) { - std::unique_ptr<char[]> buffer_copy(new char[size]); - memcpy(buffer_copy.get(), buffer, size); - return MakeUnique<BinaryValue>(std::move(buffer_copy), size); -} - -bool BinaryValue::GetAsBinary(const BinaryValue** out_value) const { - if (out_value) - *out_value = this; - return true; -} - -BinaryValue* BinaryValue::DeepCopy() const { - return CreateWithCopiedBuffer(buffer_.get(), size_).release(); -} - -bool BinaryValue::Equals(const Value* other) const { - if (other->GetType() != GetType()) - return false; - const BinaryValue* other_binary = static_cast<const BinaryValue*>(other); - if (other_binary->size_ != size_) - return false; - return !memcmp(GetBuffer(), other_binary->GetBuffer(), size_); -} - ///////////////////// DictionaryValue //////////////////// // static @@ -768,7 +780,7 @@ return false; if (out_value) - *out_value = static_cast<const BinaryValue*>(value); + *out_value = value; return true; } @@ -1162,7 +1174,7 @@ return false; if (out_value) - *out_value = static_cast<const BinaryValue*>(value); + *out_value = value; return true; }
diff --git a/base/values.h b/base/values.h index 5c74eb8..9b4ebef 100644 --- a/base/values.h +++ b/base/values.h
@@ -36,12 +36,12 @@ namespace base { -class BinaryValue; class DictionaryValue; class ListValue; class Value; using FundamentalValue = Value; using StringValue = Value; +using BinaryValue = Value; // The Value class is the base class for Values. A Value can be instantiated // via the Create*Value() factory methods, or by directly creating instances of @@ -64,6 +64,14 @@ static std::unique_ptr<Value> CreateNullValue(); + // For situations where you want to keep ownership of your buffer, this + // factory method creates a new BinaryValue by copying the contents of the + // buffer that's passed in. + // DEPRECATED, use MakeUnique<Value>(const std::vector<char>&) instead. + // TODO(crbug.com/646113): Delete this and migrate callsites. + static std::unique_ptr<BinaryValue> CreateWithCopiedBuffer(const char* buffer, + size_t size); + Value(const Value& that); Value(Value&& that); Value(); // A null value. @@ -85,6 +93,9 @@ explicit Value(const string16& in_string); explicit Value(StringPiece in_string); + explicit Value(const std::vector<char>& in_blob); + explicit Value(std::vector<char>&& in_blob); + Value& operator=(const Value& that); Value& operator=(Value&& that); @@ -116,6 +127,10 @@ int GetInt() const; double GetDouble() const; // Implicitly converts from int if necessary. const std::string& GetString() const; + const std::vector<char>& GetBlob() const; + + size_t GetSize() const; // DEPRECATED, use GetBlob().size() instead. + const char* GetBuffer() const; // DEPRECATED, use GetBlob().data() instead. // These methods allow the convenient retrieval of the contents of the Value. // If the current object can be converted into the given type, the value is @@ -167,44 +182,10 @@ int int_value_; double double_value_; ManualConstructor<std::string> string_value_; + ManualConstructor<std::vector<char>> binary_value_; }; }; -class BASE_EXPORT BinaryValue: public Value { - public: - // Creates a BinaryValue with a null buffer and size of 0. - BinaryValue(); - - // Creates a BinaryValue, taking ownership of the bytes pointed to by - // |buffer|. - BinaryValue(std::unique_ptr<char[]> buffer, size_t size); - - ~BinaryValue() override; - - // For situations where you want to keep ownership of your buffer, this - // factory method creates a new BinaryValue by copying the contents of the - // buffer that's passed in. - static std::unique_ptr<BinaryValue> CreateWithCopiedBuffer(const char* buffer, - size_t size); - - size_t GetSize() const { return size_; } - - // May return NULL. - char* GetBuffer() { return buffer_.get(); } - const char* GetBuffer() const { return buffer_.get(); } - - // Overridden from Value: - bool GetAsBinary(const BinaryValue** out_value) const override; - BinaryValue* DeepCopy() const override; - bool Equals(const Value* other) const override; - - private: - std::unique_ptr<char[]> buffer_; - size_t size_; - - DISALLOW_COPY_AND_ASSIGN(BinaryValue); -}; - // DictionaryValue provides a key-value dictionary with (optional) "path" // parsing for recursive access; see the comment at the top of the file. Keys // are |std::string|s and should be UTF-8 encoded.
diff --git a/base/values_unittest.cc b/base/values_unittest.cc index 9f2d9d62..e62b6e57 100644 --- a/base/values_unittest.cc +++ b/base/values_unittest.cc
@@ -9,6 +9,7 @@ #include <limits> #include <memory> #include <utility> +#include <vector> #include "base/memory/ptr_util.h" #include "base/strings/string16.h" @@ -82,6 +83,12 @@ EXPECT_EQ("foobar", value.GetString()); } +TEST(ValuesTest, ConstructBinary) { + BinaryValue value(std::vector<char>({0xF, 0x0, 0x0, 0xB, 0xA, 0x2})); + EXPECT_EQ(Value::Type::BINARY, value.type()); + EXPECT_EQ(std::vector<char>({0xF, 0x0, 0x0, 0xB, 0xA, 0x2}), value.GetBlob()); +} + // Group of tests for the copy constructors and copy-assigmnent. For equality // checks comparisons of the interesting fields are done instead of relying on // Equals being correct. @@ -146,6 +153,19 @@ EXPECT_EQ(value.GetString(), blank.GetString()); } +TEST(ValuesTest, CopyBinary) { + BinaryValue value(std::vector<char>({0xF, 0x0, 0x0, 0xB, 0xA, 0x2})); + BinaryValue copied_value(value); + EXPECT_EQ(value.type(), copied_value.type()); + EXPECT_EQ(value.GetBlob(), copied_value.GetBlob()); + + Value blank; + + blank = value; + EXPECT_EQ(value.type(), blank.type()); + EXPECT_EQ(value.GetBlob(), blank.GetBlob()); +} + // Group of tests for the move constructors and move-assigmnent. TEST(ValuesTest, MoveBool) { FundamentalValue true_value(true); @@ -208,6 +228,20 @@ EXPECT_EQ("foobar", blank.GetString()); } +TEST(ValuesTest, MoveBinary) { + const std::vector<char> buffer = {0xF, 0x0, 0x0, 0xB, 0xA, 0x2}; + BinaryValue value(buffer); + BinaryValue moved_value(std::move(value)); + EXPECT_EQ(Value::Type::BINARY, moved_value.type()); + EXPECT_EQ(buffer, moved_value.GetBlob()); + + Value blank; + + blank = BinaryValue(buffer); + EXPECT_EQ(Value::Type::BINARY, blank.type()); + EXPECT_EQ(buffer, blank.GetBlob()); +} + TEST(ValuesTest, Basic) { // Test basic dictionary getting/setting DictionaryValue settings; @@ -301,16 +335,15 @@ } TEST(ValuesTest, BinaryValue) { - // Default constructor creates a BinaryValue with a null buffer and size 0. - std::unique_ptr<BinaryValue> binary(new BinaryValue()); + // Default constructor creates a BinaryValue with a buffer of size 0. + auto binary = MakeUnique<Value>(Value::Type::BINARY); ASSERT_TRUE(binary.get()); - ASSERT_EQ(NULL, binary->GetBuffer()); ASSERT_EQ(0U, binary->GetSize()); // Test the common case of a non-empty buffer - std::unique_ptr<char[]> buffer(new char[15]); - char* original_buffer = buffer.get(); - binary.reset(new BinaryValue(std::move(buffer), 15)); + std::vector<char> buffer(15); + char* original_buffer = buffer.data(); + binary.reset(new BinaryValue(std::move(buffer))); ASSERT_TRUE(binary.get()); ASSERT_TRUE(binary->GetBuffer()); ASSERT_EQ(original_buffer, binary->GetBuffer()); @@ -608,10 +641,9 @@ StringValue* original_string16 = scoped_string16.get(); original_dict.Set("string16", std::move(scoped_string16)); - std::unique_ptr<char[]> original_buffer(new char[42]); - memset(original_buffer.get(), '!', 42); + std::vector<char> original_buffer(42, '!'); std::unique_ptr<BinaryValue> scoped_binary( - new BinaryValue(std::move(original_buffer), 42)); + new BinaryValue(std::move(original_buffer))); BinaryValue* original_binary = scoped_binary.get(); original_dict.Set("binary", std::move(scoped_binary)); @@ -697,13 +729,10 @@ ASSERT_TRUE(copy_binary); ASSERT_NE(copy_binary, original_binary); ASSERT_TRUE(copy_binary->IsType(Value::Type::BINARY)); - ASSERT_NE(original_binary->GetBuffer(), - static_cast<BinaryValue*>(copy_binary)->GetBuffer()); - ASSERT_EQ(original_binary->GetSize(), - static_cast<BinaryValue*>(copy_binary)->GetSize()); - ASSERT_EQ(0, memcmp(original_binary->GetBuffer(), - static_cast<BinaryValue*>(copy_binary)->GetBuffer(), - original_binary->GetSize())); + ASSERT_NE(original_binary->GetBuffer(), copy_binary->GetBuffer()); + ASSERT_EQ(original_binary->GetSize(), copy_binary->GetSize()); + ASSERT_EQ(0, memcmp(original_binary->GetBuffer(), copy_binary->GetBuffer(), + original_binary->GetSize())); Value* copy_value = NULL; ASSERT_TRUE(copy_dict->Get("list", ©_value)); @@ -829,10 +858,9 @@ Value* original_string16 = scoped_string16.get(); original_dict.Set("string16", std::move(scoped_string16)); - std::unique_ptr<char[]> original_buffer(new char[42]); - memset(original_buffer.get(), '!', 42); + std::vector<char> original_buffer(42, '!'); std::unique_ptr<BinaryValue> scoped_binary( - new BinaryValue(std::move(original_buffer), 42)); + new BinaryValue(std::move(original_buffer))); Value* original_binary = scoped_binary.get(); original_dict.Set("binary", std::move(scoped_binary)); @@ -1069,7 +1097,7 @@ FundamentalValue int_value(1234); FundamentalValue double_value(12.34567); StringValue string_value("foo"); - BinaryValue binary_value; + BinaryValue binary_value(Value::Type::BINARY); DictionaryValue dict_value; ListValue list_value;
diff --git a/cc/output/color_lut_cache.cc b/cc/output/color_lut_cache.cc index 612573d..aa22d50 100644 --- a/cc/output/color_lut_cache.cc +++ b/cc/output/color_lut_cache.cc
@@ -76,7 +76,7 @@ samples[y].set_y(u * inverse); samples[y].set_z(v * inverse); } - transform->transform(samples.data(), samples.size()); + transform->Transform(samples.data(), samples.size()); T* lutp2 = lutp + lut_samples; FloatToLUT(reinterpret_cast<float*>(samples.data()), lutp2, lut_samples * 3);
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 2d1e3e8..da28944f 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -198,7 +198,6 @@ "//services/service_manager/public/interfaces:interfaces_java", "//services/service_manager/public/java:service_manager_java", "//services/shape_detection/public/interfaces:interfaces_java", - "//skia/public/interfaces:interfaces_java", "//third_party/WebKit/public:android_mojo_bindings_java", "//third_party/WebKit/public:blink_headers_java", "//third_party/WebKit/public:mojo_bindings_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/BarcodeDetectionImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/BarcodeDetectionImpl.java index f7d8f73..6d46e5f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/BarcodeDetectionImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/BarcodeDetectionImpl.java
@@ -20,10 +20,11 @@ import org.chromium.gfx.mojom.PointF; import org.chromium.gfx.mojom.RectF; import org.chromium.mojo.system.MojoException; +import org.chromium.mojo.system.SharedBufferHandle; +import org.chromium.mojo.system.SharedBufferHandle.MapFlags; import org.chromium.services.service_manager.InterfaceFactory; import org.chromium.shape_detection.mojom.BarcodeDetection; import org.chromium.shape_detection.mojom.BarcodeDetectionResult; -import org.chromium.skia.mojom.ColorType; import java.nio.ByteBuffer; @@ -42,7 +43,8 @@ } @Override - public void detect(org.chromium.skia.mojom.Bitmap bitmapData, DetectResponse callback) { + public void detect( + SharedBufferHandle frameData, int width, int height, DetectResponse callback) { if (!ExternalAuthUtils.getInstance().canUseGooglePlayServices( mContext, new UserRecoverableErrorHandler.Silent())) { Log.e(TAG, "Google Play Services not available"); @@ -59,21 +61,9 @@ return; } - // TODO(junwei.fu): Consider supporting other bitmap pixel formats, - // https://crbug.com/684921. - if (bitmapData.colorType != ColorType.RGBA_8888 - && bitmapData.colorType != ColorType.BGRA_8888) { - Log.e(TAG, "Unsupported bitmap pixel format"); - callback.call(new BarcodeDetectionResult[0]); - return; - } - - int width = bitmapData.width; - int height = bitmapData.height; final long numPixels = (long) width * height; // TODO(mcasas): https://crbug.com/670028 homogeneize overflow checking. - if (bitmapData.pixelData == null || width <= 0 || height <= 0 - || numPixels > (Long.MAX_VALUE / 4)) { + if (!frameData.isValid() || width <= 0 || height <= 0 || numPixels > (Long.MAX_VALUE / 4)) { callback.call(new BarcodeDetectionResult[0]); return; } @@ -81,7 +71,7 @@ // Mapping |frameData| will fail if the intended mapped size is larger // than its actual capacity, which is limited by the appropriate // mojo::edk::Configuration entry. - ByteBuffer imageBuffer = ByteBuffer.wrap(bitmapData.pixelData); + ByteBuffer imageBuffer = frameData.map(0, numPixels * 4, MapFlags.none()); if (imageBuffer.capacity() <= 0) { callback.call(new BarcodeDetectionResult[0]); return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/TextDetectionImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/TextDetectionImpl.java index 6af95153..2f4fab0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/TextDetectionImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/shapedetection/TextDetectionImpl.java
@@ -18,10 +18,11 @@ import org.chromium.chrome.browser.externalauth.UserRecoverableErrorHandler; import org.chromium.gfx.mojom.RectF; import org.chromium.mojo.system.MojoException; +import org.chromium.mojo.system.SharedBufferHandle; +import org.chromium.mojo.system.SharedBufferHandle.MapFlags; import org.chromium.services.service_manager.InterfaceFactory; import org.chromium.shape_detection.mojom.TextDetection; import org.chromium.shape_detection.mojom.TextDetectionResult; -import org.chromium.skia.mojom.ColorType; import java.nio.ByteBuffer; @@ -40,7 +41,8 @@ } @Override - public void detect(org.chromium.skia.mojom.Bitmap bitmapData, DetectResponse callback) { + public void detect( + SharedBufferHandle frameData, int width, int height, DetectResponse callback) { if (!ExternalAuthUtils.getInstance().canUseGooglePlayServices( mContext, new UserRecoverableErrorHandler.Silent())) { Log.e(TAG, "Google Play Services not available"); @@ -57,21 +59,9 @@ return; } - // TODO(junwei.fu): Consider supporting other bitmap pixel formats, - // https://crbug.com/684921. - if (bitmapData.colorType != ColorType.RGBA_8888 - && bitmapData.colorType != ColorType.BGRA_8888) { - Log.e(TAG, "Unsupported bitmap pixel format"); - callback.call(new TextDetectionResult[0]); - return; - } - - int width = bitmapData.width; - int height = bitmapData.height; final long numPixels = (long) width * height; // TODO(xianglu): https://crbug.com/670028 homogeneize overflow checking. - if (bitmapData.pixelData == null || width <= 0 || height <= 0 - || numPixels > (Long.MAX_VALUE / 4)) { + if (!frameData.isValid() || width <= 0 || height <= 0 || numPixels > (Long.MAX_VALUE / 4)) { callback.call(new TextDetectionResult[0]); return; } @@ -79,7 +69,7 @@ // Mapping |frameData| will fail if the intended mapped size is larger // than its actual capacity, which is limited by the appropriate // mojo::edk::Configuration entry. - ByteBuffer imageBuffer = ByteBuffer.wrap(bitmapData.pixelData); + ByteBuffer imageBuffer = frameData.map(0, numPixels * 4, MapFlags.none()); if (imageBuffer.capacity() <= 0) { callback.call(new TextDetectionResult[0]); return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index 2f573f618..a786a45 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -106,6 +106,7 @@ import org.chromium.printing.PrintingControllerImpl; import org.chromium.ui.base.LocalizationUtils; import org.chromium.ui.base.PageTransition; +import org.chromium.ui.base.ViewAndroidDelegate; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.mojom.WindowOpenDisposition; @@ -375,6 +376,26 @@ private class TabContentViewClient extends ContentViewClient { @Override + public void onBackgroundColorChanged(int color) { + Tab.this.onBackgroundColorChanged(color); + } + + @Override + public void onTopControlsChanged(float topControlsOffsetY, float topContentOffsetY) { + super.onTopControlsChanged(topControlsOffsetY, topContentOffsetY); + onOffsetsChanged(topControlsOffsetY, mPreviousBottomControlsOffsetY, + topContentOffsetY, isShowingSadTab()); + } + + @Override + public void onBottomControlsChanged(float bottomControlsOffsetY, + float bottomContentOffsetY) { + super.onBottomControlsChanged(bottomControlsOffsetY, bottomContentOffsetY); + onOffsetsChanged(mPreviousTopControlsOffsetY, bottomControlsOffsetY, + mPreviousContentOffsetY, isShowingSadTab()); + } + + @Override public void onImeEvent() { // Some text was set in the page. Don't reuse it if a tab is // open from the same external application, we might lose some @@ -389,6 +410,33 @@ } @Override + public int getSystemWindowInsetLeft() { + ChromeActivity activity = getActivity(); + if (activity != null && activity.getInsetObserverView() != null) { + return activity.getInsetObserverView().getSystemWindowInsetsLeft(); + } + return 0; + } + + @Override + public int getSystemWindowInsetTop() { + ChromeActivity activity = getActivity(); + if (activity != null && activity.getInsetObserverView() != null) { + return activity.getInsetObserverView().getSystemWindowInsetsTop(); + } + return 0; + } + + @Override + public int getSystemWindowInsetRight() { + ChromeActivity activity = getActivity(); + if (activity != null && activity.getInsetObserverView() != null) { + return activity.getInsetObserverView().getSystemWindowInsetsRight(); + } + return 0; + } + + @Override public int getSystemWindowInsetBottom() { ChromeActivity activity = getActivity(); if (activity != null && activity.getInsetObserverView() != null) { @@ -1594,7 +1642,7 @@ ContentView cv = ContentView.createContentView(mThemedApplicationContext, cvc); cv.setContentDescription(mThemedApplicationContext.getResources().getString( R.string.accessibility_content_view)); - cvc.initialize(new TabViewAndroidDelegate(this, cv), cv, webContents, + cvc.initialize(ViewAndroidDelegate.createBasicDelegate(cv), cv, webContents, getWindowAndroid()); ChromeActionModeCallback actionModeCallback = new ChromeActionModeCallback( mThemedApplicationContext, this, cvc.getActionModeCallbackHelper()); @@ -2173,7 +2221,7 @@ * Called when the background color for the content changes. * @param color The current for the background. */ - void onBackgroundColorChanged(int color) { + protected void onBackgroundColorChanged(int color) { for (TabObserver observer : mObservers) observer.onBackgroundColorChanged(this, color); } @@ -2473,21 +2521,19 @@ * Called when offset values related with fullscreen functionality has been changed by the * compositor. * @param topControlsOffsetY The Y offset of the top controls in physical pixels. - * {@code Float.NaN} if the value is invalid and the cached value should be used. * @param bottomControlsOffsetY The Y offset of the bottom controls in physical pixels. - * {@code Float.NaN} if the value is invalid and the cached value should be used. * @param contentOffsetY The Y offset of the content in physical pixels. + * @param isNonFullscreenPage Whether a current page is non-fullscreen page or not. */ - void onOffsetsChanged( - float topControlsOffsetY, float bottomControlsOffsetY, float contentOffsetY) { - if (!Float.isNaN(topControlsOffsetY)) mPreviousTopControlsOffsetY = topControlsOffsetY; - if (!Float.isNaN(bottomControlsOffsetY)) { - mPreviousBottomControlsOffsetY = bottomControlsOffsetY; - } + private void onOffsetsChanged( + float topControlsOffsetY, float bottomControlsOffsetY, float contentOffsetY, + boolean isNonFullscreenPage) { + mPreviousTopControlsOffsetY = topControlsOffsetY; + mPreviousBottomControlsOffsetY = bottomControlsOffsetY; mPreviousContentOffsetY = contentOffsetY; if (mFullscreenManager == null) return; - if (isShowingSadTab() || isNativePage()) { + if (isNonFullscreenPage || isNativePage()) { mFullscreenManager.setPositionsForTabToNonFullscreen(); } else { mFullscreenManager.setPositionsForTab(topControlsOffsetY, bottomControlsOffsetY,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java deleted file mode 100644 index e4689e0e..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java +++ /dev/null
@@ -1,59 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.chrome.browser.tab; - -import android.content.ActivityNotFoundException; -import android.content.Intent; -import android.view.ViewGroup; - -import org.chromium.base.Log; -import org.chromium.base.metrics.RecordUserAction; -import org.chromium.ui.base.ViewAndroidDelegate; - -/** - * Implementation of the abstract class {@link ViewAndroidDelegate} for Chrome. - */ -class TabViewAndroidDelegate extends ViewAndroidDelegate { - /** Used for logging. */ - private static final String TAG = "TabVAD"; - - private final Tab mTab; - private final ViewGroup mContainerView; - - TabViewAndroidDelegate(Tab tab, ViewGroup containerView) { - mTab = tab; - mContainerView = containerView; - } - - @Override - public void onBackgroundColorChanged(int color) { - mTab.onBackgroundColorChanged(color); - } - - @Override - public void onTopControlsChanged(float topControlsOffsetY, float topContentOffsetY) { - mTab.onOffsetsChanged(topControlsOffsetY, Float.NaN, topContentOffsetY); - } - - @Override - public void onBottomControlsChanged(float bottomControlsOffsetY, float bottomContentOffsetY) { - mTab.onOffsetsChanged(Float.NaN, bottomControlsOffsetY, Float.NaN); - } - - @Override - public void startContentIntent(Intent intent, String intentUrl, boolean isMainFrame) { - try { - RecordUserAction.record("Android.ContentDetectorActivated"); - mContainerView.getContext().startActivity(intent); - } catch (ActivityNotFoundException ex) { - Log.w(TAG, "No application can handle %s", intentUrl); - } - } - - @Override - public ViewGroup getContainerView() { - return mContainerView; - } -}
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index a7ee4e5b..87fb0bc 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -960,7 +960,6 @@ "java/src/org/chromium/chrome/browser/tab/TabRedirectHandler.java", "java/src/org/chromium/chrome/browser/tab/TabStateBrowserControlsVisibilityDelegate.java", "java/src/org/chromium/chrome/browser/tab/TabUma.java", - "java/src/org/chromium/chrome/browser/tab/TabViewAndroidDelegate.java", "java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroid.java", "java/src/org/chromium/chrome/browser/tab/TabWebContentsObserver.java", "java/src/org/chromium/chrome/browser/tabmodel/AsyncTabParams.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassinTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassinTest.java index ead2316a..a5a3b43 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassinTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassinTest.java
@@ -16,6 +16,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.AdvancedMockContext; import org.chromium.base.test.util.CallbackHelper; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.browser.TabState; import org.chromium.chrome.browser.tab.Tab; @@ -179,7 +180,9 @@ } /** Tests the full pathway. */ - @MediumTest + // Flaky, see http://crbug/666815. + // @MediumTest + @DisabledTest public void testFullMigration() throws Exception { final CallbackHelper copyStartedCallback = new CallbackHelper(); final CallbackHelper copyCallback = new CallbackHelper();
diff --git a/chrome/browser/android/logo_service.cc b/chrome/browser/android/logo_service.cc index 54b8b78..ae0796a 100644 --- a/chrome/browser/android/logo_service.cc +++ b/chrome/browser/android/logo_service.cc
@@ -6,6 +6,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/image_decoder.h" #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/android/metrics/uma_session_stats.cc b/chrome/browser/android/metrics/uma_session_stats.cc index c318ddb..854f9fc 100644 --- a/chrome/browser/android/metrics/uma_session_stats.cc +++ b/chrome/browser/android/metrics/uma_session_stats.cc
@@ -9,6 +9,7 @@ #include "base/command_line.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/time/time.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
diff --git a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc index 992702b6..81af5aed 100644 --- a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc +++ b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/sequenced_task_runner.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/android/offline_pages/background_loader_offliner.h" #include "chrome/browser/android/offline_pages/background_scheduler_bridge.h" #include "chrome/browser/android/offline_pages/downloads/offline_page_notification_bridge.h"
diff --git a/chrome/browser/android/offline_pages/offline_page_model_factory.cc b/chrome/browser/android/offline_pages/offline_page_model_factory.cc index 2201011..089b558 100644 --- a/chrome/browser/android/offline_pages/offline_page_model_factory.cc +++ b/chrome/browser/android/offline_pages/offline_page_model_factory.cc
@@ -9,6 +9,7 @@ #include "base/files/file_path.h" #include "base/memory/singleton.h" #include "base/sequenced_task_runner.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_constants.h"
diff --git a/chrome/browser/android/offline_pages/offline_page_request_job.cc b/chrome/browser/android/offline_pages/offline_page_request_job.cc index d327a5ae4..f7a9535b 100644 --- a/chrome/browser/android/offline_pages/offline_page_request_job.cc +++ b/chrome/browser/android/offline_pages/offline_page_request_job.cc
@@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" #include "chrome/browser/android/offline_pages/offline_page_tab_helper.h"
diff --git a/chrome/browser/android/offline_pages/request_coordinator_factory.cc b/chrome/browser/android/offline_pages/request_coordinator_factory.cc index d1d1141..2648078e 100644 --- a/chrome/browser/android/offline_pages/request_coordinator_factory.cc +++ b/chrome/browser/android/offline_pages/request_coordinator_factory.cc
@@ -9,6 +9,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/singleton.h" #include "base/sequenced_task_runner.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/android/offline_pages/background_loader_offliner.h" #include "chrome/browser/android/offline_pages/background_scheduler_bridge.h" #include "chrome/browser/android/offline_pages/downloads/offline_page_notification_bridge.h"
diff --git a/chrome/browser/android/shortcut_helper.cc b/chrome/browser/android/shortcut_helper.cc index dfa0aefc..aa309f6 100644 --- a/chrome/browser/android/shortcut_helper.cc +++ b/chrome/browser/android/shortcut_helper.cc
@@ -15,6 +15,7 @@ #include "base/command_line.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/android/webapk/chrome_webapk_host.h" #include "chrome/browser/android/webapk/webapk_install_service.h" #include "chrome/browser/manifest/manifest_icon_downloader.h"
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc index 9f7d15a..1b2078a 100644 --- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc +++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/location.h" #include "base/strings/string16.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/android/offline_pages/offline_page_utils.h" #include "chrome/browser/android/shortcut_helper.h" #include "chrome/browser/android/webapk/webapk_web_manifest_checker.h"
diff --git a/chrome/browser/android/webapps/add_to_homescreen_manager.cc b/chrome/browser/android/webapps/add_to_homescreen_manager.cc index 9d4dc4f..45b0459e 100644 --- a/chrome/browser/android/webapps/add_to_homescreen_manager.cc +++ b/chrome/browser/android/webapps/add_to_homescreen_manager.cc
@@ -11,6 +11,7 @@ #include "base/memory/ptr_util.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/android/banners/app_banner_infobar_delegate_android.h" #include "chrome/browser/android/shortcut_helper.h" #include "chrome/browser/android/webapk/chrome_webapk_host.h"
diff --git a/chrome/browser/chromeos/accessibility/accessibility_highlight_manager_interactive_uitest.cc b/chrome/browser/chromeos/accessibility/accessibility_highlight_manager_interactive_uitest.cc index 806d059..5511e7ea 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_highlight_manager_interactive_uitest.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_highlight_manager_interactive_uitest.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/run_loop.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/chromeos/ui/accessibility_focus_ring_controller.h" #include "chrome/test/base/in_process_browser_test.h" #include "chromeos/chromeos_switches.h"
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc index ec64b6c8..fde4eed4 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager.cc
@@ -19,6 +19,7 @@ #include "base/strings/stringprintf.h" #include "base/sys_info.h" #include "base/task_scheduler/post_task.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/version.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/app_mode/app_session.h"
diff --git a/chrome/browser/chromeos/arc/arc_service_launcher.cc b/chrome/browser/chromeos/arc/arc_service_launcher.cc index 782625e..52541dbe 100644 --- a/chrome/browser/chromeos/arc/arc_service_launcher.cc +++ b/chrome/browser/chromeos/arc/arc_service_launcher.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_service.h" #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h" #include "chrome/browser/chromeos/arc/arc_auth_service.h"
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc index 426b51307..401d439 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader.cc
@@ -8,6 +8,7 @@ #include <unistd.h> #include "base/files/file.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_restrictions.h" #include "chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_util.h" #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/chromeos/arc/process/arc_process_service.cc b/chrome/browser/chromeos/arc/process/arc_process_service.cc index 9de7760..ec6e417 100644 --- a/chrome/browser/chromeos/arc/process/arc_process_service.cc +++ b/chrome/browser/chromeos/arc/process/arc_process_service.cc
@@ -21,6 +21,7 @@ #include "base/process/process.h" #include "base/process/process_iterator.h" #include "base/task_runner_util.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/trace_event/trace_event.h" #include "components/arc/arc_bridge_service.h" #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/chromeos/base/file_flusher_unittest.cc b/chrome/browser/chromeos/base/file_flusher_unittest.cc index a038cea..361d489 100644 --- a/chrome/browser/chromeos/base/file_flusher_unittest.cc +++ b/chrome/browser/chromeos/base/file_flusher_unittest.cc
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" +#include "base/threading/sequenced_worker_pool.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/chromeos/customization/customization_wallpaper_downloader.cc b/chrome/browser/chromeos/customization/customization_wallpaper_downloader.cc index 180f529..7fcbf30 100644 --- a/chrome/browser/chromeos/customization/customization_wallpaper_downloader.cc +++ b/chrome/browser/chromeos/customization/customization_wallpaper_downloader.cc
@@ -9,6 +9,7 @@ #include <utility> #include "base/files/file_util.h" +#include "base/threading/sequenced_worker_pool.h" #include "content/public/browser/browser_thread.h" #include "net/base/load_flags.h" #include "net/http/http_status_code.h"
diff --git a/chrome/browser/chromeos/external_metrics.cc b/chrome/browser/chromeos/external_metrics.cc index 78f071e1..5ca83bc 100644 --- a/chrome/browser/chromeos/external_metrics.cc +++ b/chrome/browser/chromeos/external_metrics.cc
@@ -13,6 +13,7 @@ #include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" #include "base/metrics/statistics_recorder.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/metrics/chromeos_metrics_provider.h" #include "components/metrics/metrics_service.h"
diff --git a/chrome/browser/chromeos/file_manager/snapshot_manager.cc b/chrome/browser/chromeos/file_manager/snapshot_manager.cc index f33fdfdf9..03c11a75 100644 --- a/chrome/browser/chromeos/file_manager/snapshot_manager.cc +++ b/chrome/browser/chromeos/file_manager/snapshot_manager.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/sys_info.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/chromeos/file_manager/app_id.h" #include "chrome/browser/chromeos/file_manager/fileapi_util.h" #include "chrome/browser/profiles/profile.h"
diff --git a/chrome/browser/chromeos/input_method/input_method_syncer.cc b/chrome/browser/chromeos/input_method/input_method_syncer.cc index 0140796a..d27002a 100644 --- a/chrome/browser/chromeos/input_method/input_method_syncer.cc +++ b/chrome/browser/chromeos/input_method/input_method_syncer.cc
@@ -13,6 +13,7 @@ #include "base/strings/string_util.h" #include "base/task_runner.h" #include "base/task_runner_util.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/browser_process.h" #include "chrome/common/pref_names.h" #include "components/pref_registry/pref_registry_syncable.h"
diff --git a/chrome/browser/chromeos/login/login_browsertest.cc b/chrome/browser/chromeos/login/login_browsertest.cc index f7d9206a..b1dd99b5 100644 --- a/chrome/browser/chromeos/login/login_browsertest.cc +++ b/chrome/browser/chromeos/login/login_browsertest.cc
@@ -254,7 +254,8 @@ CrosSettings::Get()->SetBoolean(kAccountsPrefShowUserNamesOnSignIn, false); } -IN_PROC_BROWSER_TEST_F(LoginTest, GaiaAuthOffline) { +// Flaky, see http://crbug/692364. +IN_PROC_BROWSER_TEST_F(LoginTest, DISABLED_GaiaAuthOffline) { PrepareOfflineLogin(); content::WindowedNotificationObserver session_start_waiter( chrome::NOTIFICATION_SESSION_STARTED,
diff --git a/chrome/browser/chromeos/login/screenshot_testing/screenshot_tester.cc b/chrome/browser/chromeos/login/screenshot_testing/screenshot_tester.cc index 92dc8336..448d48a3 100644 --- a/chrome/browser/chromeos/login/screenshot_testing/screenshot_tester.cc +++ b/chrome/browser/chromeos/login/screenshot_testing/screenshot_tester.cc
@@ -11,6 +11,7 @@ #include "base/command_line.h" #include "base/files/file_util.h" #include "base/run_loop.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric.h" #include "chrome/browser/chromeos/login/screenshot_testing/SkImageDiffer.h" #include "chrome/browser/chromeos/login/screenshot_testing/SkPMetric.h"
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index 8d7eee48..8e5aca8 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -21,6 +21,7 @@ #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h"
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc index fcf6a66..3d9977d 100644 --- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc +++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
@@ -16,6 +16,7 @@ #include "base/callback.h" #include "base/command_line.h" #include "base/memory/ptr_util.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/threading/thread_checker.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h"
diff --git a/chrome/browser/chromeos/policy/device_status_collector.cc b/chrome/browser/chromeos/policy/device_status_collector.cc index c0b5512..77638a0 100644 --- a/chrome/browser/chromeos/policy/device_status_collector.cc +++ b/chrome/browser/chromeos/policy/device_status_collector.cc
@@ -27,6 +27,7 @@ #include "base/sys_info.h" #include "base/task_runner_util.h" #include "base/threading/sequenced_task_runner_handle.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/values.h" #include "base/version.h" #include "chrome/browser/browser_process.h"
diff --git a/chrome/browser/chromeos/policy/dm_token_storage.cc b/chrome/browser/chromeos/policy/dm_token_storage.cc index b3baeeb..99a4acb 100644 --- a/chrome/browser/chromeos/policy/dm_token_storage.cc +++ b/chrome/browser/chromeos/policy/dm_token_storage.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/chromeos/policy/dm_token_storage.h" #include "base/bind.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/chromeos/settings/token_encryptor.h" #include "chrome/common/pref_names.h" #include "chromeos/cryptohome/system_salt_getter.h"
diff --git a/chrome/browser/chromeos/policy/system_log_uploader.cc b/chrome/browser/chromeos/policy/system_log_uploader.cc index 8f53545..f472a2e4 100644 --- a/chrome/browser/chromeos/policy/system_log_uploader.cc +++ b/chrome/browser/chromeos/policy/system_log_uploader.cc
@@ -13,6 +13,7 @@ #include "base/strings/stringprintf.h" #include "base/syslog_logging.h" #include "base/task_runner_util.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/policy/upload_job_impl.h" #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
diff --git a/chrome/browser/chromeos/system_logs/debug_log_writer.cc b/chrome/browser/chromeos/system_logs/debug_log_writer.cc index 4ac2f6c2..9c8a2271 100644 --- a/chrome/browser/chromeos/system_logs/debug_log_writer.cc +++ b/chrome/browser/chromeos/system_logs/debug_log_writer.cc
@@ -16,6 +16,7 @@ #include "base/message_loop/message_loop.h" #include "base/process/kill.h" #include "base/process/launch.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/common/logging_chrome.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/debug_daemon_client.h"
diff --git a/chrome/browser/chromeos/system_logs/touch_log_source_ozone.cc b/chrome/browser/chromeos/system_logs/touch_log_source_ozone.cc index b2e04b2..6a76479 100644 --- a/chrome/browser/chromeos/system_logs/touch_log_source_ozone.cc +++ b/chrome/browser/chromeos/system_logs/touch_log_source_ozone.cc
@@ -17,6 +17,7 @@ #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "base/process/launch.h" +#include "base/threading/sequenced_worker_pool.h" #include "components/feedback/feedback_util.h" #include "content/public/browser/browser_thread.h" #include "ui/ozone/public/input_controller.h"
diff --git a/chrome/browser/extensions/api/messaging/native_message_process_host.cc b/chrome/browser/extensions/api/messaging/native_message_process_host.cc index 7d4304e..bf2c37c 100644 --- a/chrome/browser/extensions/api/messaging/native_message_process_host.cc +++ b/chrome/browser/extensions/api/messaging/native_message_process_host.cc
@@ -12,6 +12,7 @@ #include "base/files/file_path.h" #include "base/logging.h" #include "base/process/kill.h" +#include "base/task_scheduler/post_task.h" #include "base/threading/sequenced_worker_pool.h" #include "build/build_config.h" #include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest.h" @@ -70,8 +71,9 @@ // On OSX base::EnsureProcessTerminated() may block, so we have to post a // task on the blocking pool. #if defined(OS_MACOSX) - content::BrowserThread::PostBlockingPoolTask( - FROM_HERE, + base::PostTaskWithTraits( + FROM_HERE, base::TaskTraits().MayBlock().WithPriority( + base::TaskPriority::BACKGROUND), base::Bind(&base::EnsureProcessTerminated, Passed(&process_))); #else base::EnsureProcessTerminated(std::move(process_));
diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc index 05dc3ab..21d28b5 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
@@ -16,6 +16,7 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/task_runner_util.h" +#include "base/threading/sequenced_worker_pool.h" #include "base/values.h" #include "chrome/browser/chromeos/arc/arc_support_host.h" #include "chrome/browser/extensions/extension_service.h"
diff --git a/chrome/browser/ui/ash/ash_init.cc b/chrome/browser/ui/ash/ash_init.cc index be79194e..b29a791 100644 --- a/chrome/browser/ui/ash/ash_init.cc +++ b/chrome/browser/ui/ash/ash_init.cc
@@ -15,6 +15,7 @@ #include "ash/shell_init_params.h" #include "base/command_line.h" #include "base/sys_info.h" +#include "base/threading/sequenced_worker_pool.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h"
diff --git a/chrome/browser/ui/ash/chrome_screenshot_grabber.cc b/chrome/browser/ui/ash/chrome_screenshot_grabber.cc index 9ba9b8a..cc3cbb0 100644 --- a/chrome/browser/ui/ash/chrome_screenshot_grabber.cc +++ b/chrome/browser/ui/ash/chrome_screenshot_grabber.cc
@@ -17,6 +17,7 @@ #include "base/macros.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/sequenced_worker_pool.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/drive/file_system_util.h"
diff --git a/chrome/browser/ui/libgtkui/BUILD.gn b/chrome/browser/ui/libgtkui/BUILD.gn index 849f289..9b50cbc 100644 --- a/chrome/browser/ui/libgtkui/BUILD.gn +++ b/chrome/browser/ui/libgtkui/BUILD.gn
@@ -140,26 +140,26 @@ } } -libgtkui("libgtk2ui") { - sources = [ - "native_theme_gtk2.cc", - "native_theme_gtk2.h", - ] - deps = [ - "//build/config/linux/gtk2", - "//build/config/linux/gtk2:gtkprint2", - ] -} - -# This is compiled with "all" even when it's not referenced to ensure that -# GTK3 continues to build. GTK3 is explicitly specified by some distros. -libgtkui("libgtk3ui") { - sources = [ - "native_theme_gtk3.cc", - "native_theme_gtk3.h", - ] - deps = [ - "//build/config/linux/gtk3", - "//build/config/linux/gtk3:gtkprint3", - ] +if (use_gtk3) { + libgtkui("libgtk3ui") { + sources = [ + "native_theme_gtk3.cc", + "native_theme_gtk3.h", + ] + deps = [ + "//build/config/linux/gtk3", + "//build/config/linux/gtk3:gtkprint3", + ] + } +} else { + libgtkui("libgtk2ui") { + sources = [ + "native_theme_gtk2.cc", + "native_theme_gtk2.h", + ] + deps = [ + "//build/config/linux/gtk2", + "//build/config/linux/gtk2:gtkprint2", + ] + } }
diff --git a/chrome/renderer/extensions/cast_streaming_native_handler.h b/chrome/renderer/extensions/cast_streaming_native_handler.h index 25cc556..946099fd 100644 --- a/chrome/renderer/extensions/cast_streaming_native_handler.h +++ b/chrome/renderer/extensions/cast_streaming_native_handler.h
@@ -17,8 +17,9 @@ class CastUdpTransport; namespace base { -class BinaryValue; class DictionaryValue; +class Value; +using BinaryValue = Value; } namespace net {
diff --git a/chrome/renderer/media/cast_rtp_stream.h b/chrome/renderer/media/cast_rtp_stream.h index d03d313..d867c73 100644 --- a/chrome/renderer/media/cast_rtp_stream.h +++ b/chrome/renderer/media/cast_rtp_stream.h
@@ -18,8 +18,9 @@ #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" namespace base { -class BinaryValue; class DictionaryValue; +class Value; +using BinaryValue = Value; } class CastAudioSink;
diff --git a/chrome/renderer/media/cast_session.h b/chrome/renderer/media/cast_session.h index d1bfdec..132af169 100644 --- a/chrome/renderer/media/cast_session.h +++ b/chrome/renderer/media/cast_session.h
@@ -15,9 +15,10 @@ #include "net/base/ip_endpoint.h" namespace base { -class BinaryValue; class DictionaryValue; class SingleThreadTaskRunner; +class Value; +using BinaryValue = Value; } // namespace base namespace media {
diff --git a/chrome/renderer/media/cast_session_delegate.cc b/chrome/renderer/media/cast_session_delegate.cc index b76f34c..1216f2a 100644 --- a/chrome/renderer/media/cast_session_delegate.cc +++ b/chrome/renderer/media/cast_session_delegate.cc
@@ -6,6 +6,7 @@ #include <memory> #include <utility> +#include <vector> #include "base/callback_helpers.h" #include "base/lazy_instance.h" @@ -207,14 +208,14 @@ DCHECK(io_task_runner_->BelongsToCurrentThread()); if (!event_subscribers_.get()) { - callback.Run(base::MakeUnique<base::BinaryValue>()); + callback.Run(base::MakeUnique<base::Value>(base::Value::Type::BINARY)); return; } media::cast::EncodingEventSubscriber* subscriber = event_subscribers_->GetEncodingEventSubscriber(is_audio); if (!subscriber) { - callback.Run(base::MakeUnique<base::BinaryValue>()); + callback.Run(base::MakeUnique<base::Value>(base::Value::Type::BINARY)); return; } @@ -245,14 +246,14 @@ if (!success) { DVLOG(2) << "Failed to serialize event log."; - callback.Run(base::MakeUnique<base::BinaryValue>()); + callback.Run(base::MakeUnique<base::Value>(base::Value::Type::BINARY)); return; } DVLOG(2) << "Serialized log length: " << output_bytes; - std::unique_ptr<base::BinaryValue> blob( - new base::BinaryValue(std::move(serialized_log), output_bytes)); + auto blob = base::MakeUnique<base::BinaryValue>(std::vector<char>( + serialized_log.get(), serialized_log.get() + output_bytes)); callback.Run(std::move(blob)); }
diff --git a/chrome/renderer/media/cast_session_delegate.h b/chrome/renderer/media/cast_session_delegate.h index 9d2434f..56c4b6e 100644 --- a/chrome/renderer/media/cast_session_delegate.h +++ b/chrome/renderer/media/cast_session_delegate.h
@@ -20,9 +20,10 @@ #include "media/cast/logging/logging_defines.h" namespace base { -class BinaryValue; class DictionaryValue; class SingleThreadTaskRunner; +class Value; +using BinaryValue = Value; } // namespace base namespace media {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 604ce853..1d4129d 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1037,35 +1037,41 @@ "data/webui/print_preview.js", "data/webui/print_preview_destination_search_test.js", "data/webui/sandboxstatus_browsertest.js", - "data/webui/settings/advanced_page_browsertest.js", - "data/webui/settings/animation_browsertest.js", - "data/webui/settings/basic_page_browsertest.js", - "data/webui/settings/cr_settings_browsertest.js", - "data/webui/settings/easy_unlock_browsertest_chromeos.js", - "data/webui/settings/help_page_browsertest.js", - "data/webui/settings/languages_page_browsertest.js", - "data/webui/settings/on_startup_browsertest.js", - "data/webui/settings/passwords_and_autofill_fake_data.js", - "data/webui/settings/passwords_and_forms_browsertest.js", - "data/webui/settings/settings_autofill_section_browsertest.js", - "data/webui/settings/settings_idle_render_browsertest.js", - "data/webui/settings/settings_page_browsertest.js", - "data/webui/settings/settings_passwords_section_browsertest.js", - "data/webui/settings/settings_subpage_browsertest.js", - "data/webui/settings/settings_ui_browsertest.js", - "data/webui/settings/site_settings_page_browsertest.js", "data/webui/text_defaults_browsertest.js", "data/webui/webui_resource_async_browsertest.js", ] + + if (!is_asan) { + sources += [ + "data/webui/settings/advanced_page_browsertest.js", + "data/webui/settings/animation_browsertest.js", + "data/webui/settings/basic_page_browsertest.js", + "data/webui/settings/cr_settings_browsertest.js", + "data/webui/settings/help_page_browsertest.js", + "data/webui/settings/languages_page_browsertest.js", + "data/webui/settings/on_startup_browsertest.js", + "data/webui/settings/passwords_and_autofill_fake_data.js", + "data/webui/settings/passwords_and_forms_browsertest.js", + "data/webui/settings/settings_autofill_section_browsertest.js", + "data/webui/settings/settings_idle_render_browsertest.js", + "data/webui/settings/settings_page_browsertest.js", + "data/webui/settings/settings_passwords_section_browsertest.js", + "data/webui/settings/settings_subpage_browsertest.js", + "data/webui/settings/settings_ui_browsertest.js", + "data/webui/settings/site_settings_page_browsertest.js", + ] + + if (is_chromeos) { + sources += [ "data/webui/settings/easy_unlock_browsertest_chromeos.js" ] + } + } + if (is_chrome_branded) { # crbug.com/230471 sources -= [ "data/webui/accessibility_audit_browsertest.js" ] } if (!is_chromeos) { - sources -= [ - "data/webui/certificate_viewer_dialog_test.js", - "data/webui/settings/easy_unlock_browsertest_chromeos.js", - ] + sources -= [ "data/webui/certificate_viewer_dialog_test.js" ] } else { sources -= [ "data/webui/md_user_manager/user_manager_browsertest.js" ] }
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index 1453a78c3..d8880c32 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -1003,13 +1003,6 @@ mocha.run(); }); -// Hangs on ASAN builder for unknown reasons. TODO(michaelpg): Find reason. -GEN('#if defined(ADDRESS_SANITIZER)'); -GEN('#define MAYBE_All DISABLED_All'); -GEN('#else'); -GEN('#define MAYBE_All All'); -GEN('#endif'); - /** * @constructor * @extends {SettingsPageBrowserTest} @@ -1026,7 +1019,7 @@ runAccessibilityChecks: false, }; -TEST_F('CrSettingsRouteDynamicParametersTest', 'MAYBE_All', function() { +TEST_F('CrSettingsRouteDynamicParametersTest', 'All', function() { suite('DynamicParameters', function() { test('get parameters from URL and navigation', function(done) { assertEquals(settings.Route.PEOPLE, settings.getCurrentRoute());
diff --git a/chromecast/base/serializers_unittest.cc b/chromecast/base/serializers_unittest.cc index d5c4189a..8dc9b07 100644 --- a/chromecast/base/serializers_unittest.cc +++ b/chromecast/base/serializers_unittest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <vector> + #include "base/files/file_util.h" #include "base/values.h" #include "chromecast/base/scoped_temp_file.h" @@ -53,7 +55,7 @@ } TEST(SerializeToJson, BadValue) { - base::BinaryValue value(std::unique_ptr<char[]>(new char[12]), 12); + base::BinaryValue value(std::vector<char>(12)); std::unique_ptr<std::string> str = SerializeToJson(value); EXPECT_EQ(nullptr, str.get()); } @@ -116,7 +118,7 @@ TEST(SerializeJsonToFile, BadValue) { ScopedTempFile temp; - base::BinaryValue value(std::unique_ptr<char[]>(new char[12]), 12); + base::BinaryValue value(std::vector<char>(12)); ASSERT_FALSE(SerializeJsonToFile(temp.path(), value)); std::string str(temp.Read()); EXPECT_TRUE(str.empty());
diff --git a/chromeos/login/auth/login_performer.h b/chromeos/login/auth/login_performer.h index 633f540..21c46ca 100644 --- a/chromeos/login/auth/login_performer.h +++ b/chromeos/login/auth/login_performer.h
@@ -20,6 +20,10 @@ class AccountId; +namespace base { +class TaskRunner; +} + namespace net { class URLRequestContextGetter; }
diff --git a/chromeos/tpm/tpm_token_info_getter.cc b/chromeos/tpm/tpm_token_info_getter.cc index dc772487..1e7918d 100644 --- a/chromeos/tpm/tpm_token_info_getter.cc +++ b/chromeos/tpm/tpm_token_info_getter.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/location.h" +#include "base/task_runner.h" #include "chromeos/cryptohome/cryptohome_parameters.h" #include "chromeos/dbus/cryptohome_client.h"
diff --git a/chromeos/tpm/tpm_token_loader.h b/chromeos/tpm/tpm_token_loader.h index be32d38c..bf2f8e7d 100644 --- a/chromeos/tpm/tpm_token_loader.h +++ b/chromeos/tpm/tpm_token_loader.h
@@ -9,6 +9,7 @@ #include <string> #include <vector> +#include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h"
diff --git a/components/ntp_tiles/BUILD.gn b/components/ntp_tiles/BUILD.gn index 1e1a20b..050f8a5d 100644 --- a/components/ntp_tiles/BUILD.gn +++ b/components/ntp_tiles/BUILD.gn
@@ -53,10 +53,12 @@ "//components/pref_registry", "//components/prefs", "//components/rappor/public", + "//components/resources", "//components/search_engines", "//components/url_formatter", "//components/variations", "//components/variations/service", + "//ui/base", ] if (is_android) {
diff --git a/components/ntp_tiles/DEPS b/components/ntp_tiles/DEPS index c5cd18d..2296e56f 100644 --- a/components/ntp_tiles/DEPS +++ b/components/ntp_tiles/DEPS
@@ -3,6 +3,7 @@ "+components/favicon", "+components/favicon_base", "+components/google/core/browser", + "+components/grit", "+components/image_fetcher", "+components/history/core/browser", "+components/pref_registry", @@ -16,4 +17,5 @@ "+jni", "+net", "+ui/gfx", + "+ui/base/resource", ]
diff --git a/components/ntp_tiles/most_visited_sites.cc b/components/ntp_tiles/most_visited_sites.cc index 6df20e3..f3695c9 100644 --- a/components/ntp_tiles/most_visited_sites.cc +++ b/components/ntp_tiles/most_visited_sites.cc
@@ -337,7 +337,8 @@ size_t num_popular_sites_tiles = num_sites_ - num_tiles; NTPTilesVector popular_sites_tiles; - if (num_popular_sites_tiles > 0 && popular_sites_) { + if (num_popular_sites_tiles > 0 && popular_sites_ && + ShouldShowPopularSites()) { std::set<std::string> hosts; for (const auto& tile : personal_tiles) hosts.insert(tile.url.host()); @@ -417,9 +418,6 @@ LOG(WARNING) << "Download of popular sites failed"; return; } - - // Re-build the tile list. Once done, this will notify the observer. - BuildCurrentTiles(); } void MostVisitedSites::OnIconMadeAvailable(const GURL& site_url,
diff --git a/components/ntp_tiles/most_visited_sites_unittest.cc b/components/ntp_tiles/most_visited_sites_unittest.cc index 9c16609..a4c0406 100644 --- a/components/ntp_tiles/most_visited_sites_unittest.cc +++ b/components/ntp_tiles/most_visited_sites_unittest.cc
@@ -207,9 +207,8 @@ url_request_context_(new net::TestURLRequestContextGetter( base::ThreadTaskRunnerHandle::Get())), worker_pool_owner_(/*max_threads=*/2, "PopularSitesFactoryForTest.") { + PopularSitesImpl::RegisterProfilePrefs(pref_service->registry()); if (enabled) { - PopularSitesImpl::RegisterProfilePrefs(pref_service->registry()); - prefs_->SetString(prefs::kPopularSitesOverrideCountry, "IN"); prefs_->SetString(prefs::kPopularSitesOverrideVersion, "7");
diff --git a/components/ntp_tiles/popular_sites_impl.cc b/components/ntp_tiles/popular_sites_impl.cc index ce69227f..44c2982 100644 --- a/components/ntp_tiles/popular_sites_impl.cc +++ b/components/ntp_tiles/popular_sites_impl.cc
@@ -19,6 +19,7 @@ #include "components/data_use_measurement/core/data_use_user_data.h" #include "components/google/core/browser/google_util.h" #include "components/ntp_tiles/constants.h" +#include "components/ntp_tiles/field_trial.h" #include "components/ntp_tiles/pref_names.h" #include "components/ntp_tiles/switches.h" #include "components/pref_registry/pref_registry_syncable.h" @@ -30,6 +31,12 @@ #include "net/base/load_flags.h" #include "net/http/http_status_code.h" +#if defined(OS_ANDROID) || defined(OS_IOS) +#include "base/json/json_reader.h" +#include "components/grit/components_resources.h" +#include "ui/base/resource/resource_bundle.h" +#endif + #if defined(OS_IOS) #include "components/ntp_tiles/country_code_ios.h" #endif @@ -125,6 +132,19 @@ return sites; } +// Creates the list of popular sites based on a snapshot available for mobile. +std::unique_ptr<base::ListValue> DefaultPopularSites() { +#if defined(OS_ANDROID) || defined(OS_IOS) + std::unique_ptr<base::ListValue> sites = + base::ListValue::From(base::JSONReader().ReadToValue( + ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_DEFAULT_POPULAR_SITES_JSON))); + DCHECK(sites); + return sites; +#endif + return base::MakeUnique<base::ListValue>(); +} + } // namespace PopularSites::Site::Site(const base::string16& title, @@ -158,6 +178,7 @@ download_context_(download_context), parse_json_(std::move(parse_json)), is_fallback_(false), + sites_(ParseSiteList(*prefs->GetList(kPopularSitesJsonPref))), weak_ptr_factory_(this) { // If valid path provided, remove local files created by older versions. if (!directory.empty() && blocking_runner_) { @@ -194,17 +215,7 @@ FetchPopularSites(); return true; } - - const base::ListValue* json = prefs_->GetList(kPopularSitesJsonPref); - if (!json) { - // Cache didn't exist. - FetchPopularSites(); - return true; - } else { - // Note that we don't run the callback. - sites_ = ParseSiteList(*json); - return false; - } + return false; } const PopularSites::SitesVector& PopularSitesImpl::sites() const { @@ -289,7 +300,8 @@ user_prefs->RegisterInt64Pref(kPopularSitesLastDownloadPref, 0); user_prefs->RegisterStringPref(kPopularSitesURLPref, std::string()); - user_prefs->RegisterListPref(kPopularSitesJsonPref); + user_prefs->RegisterListPref(kPopularSitesJsonPref, + DefaultPopularSites().release()); } void PopularSitesImpl::FetchPopularSites() {
diff --git a/components/ntp_tiles/popular_sites_impl_unittest.cc b/components/ntp_tiles/popular_sites_impl_unittest.cc index 86fbfde2..6732e27 100644 --- a/components/ntp_tiles/popular_sites_impl_unittest.cc +++ b/components/ntp_tiles/popular_sites_impl_unittest.cc
@@ -10,6 +10,7 @@ #include <vector> #include "base/bind.h" +#include "base/command_line.h" #include "base/files/file_util.h" #include "base/files/important_file_writer.h" #include "base/files/scoped_temp_dir.h" @@ -22,6 +23,7 @@ #include "base/values.h" #include "components/ntp_tiles/json_unsafe_parser.h" #include "components/ntp_tiles/pref_names.h" +#include "components/ntp_tiles/switches.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "net/http/http_status_code.h" @@ -53,6 +55,14 @@ return ::testing::Eq(GURL(s)); } +size_t GetNumberOfDefaultPopularSitesForPlatform() { +#if defined(OS_ANDROID) || defined(OS_IOS) + return 8ul; +#else + return 0; +#endif +} + class PopularSitesTest : public ::testing::Test { protected: PopularSitesTest() @@ -73,6 +83,8 @@ }, worker_pool_owner_(2, "PopularSitesTest."), url_fetcher_factory_(nullptr) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableNTPPopularSites); PopularSitesImpl::RegisterProfilePrefs(prefs_.registry()); CHECK(scoped_cache_dir_.CreateUniqueTempDir()); cache_dir_ = scoped_cache_dir_.GetPath(); @@ -117,15 +129,12 @@ scoped_refptr<net::TestURLRequestContextGetter> url_request_context( new net::TestURLRequestContextGetter( base::ThreadTaskRunnerHandle::Get())); - PopularSitesImpl popular_sites(worker_pool_owner_.pool().get(), &prefs_, - /*template_url_service=*/nullptr, - /*variations_service=*/nullptr, - url_request_context.get(), cache_dir_, - base::Bind(JsonUnsafeParser::Parse)); + std::unique_ptr<PopularSites> popular_sites = + CreatePopularSites(url_request_context.get()); base::RunLoop loop; base::Optional<bool> save_success; - if (popular_sites.MaybeStartFetch( + if (popular_sites->MaybeStartFetch( force_download, base::Bind( [](base::Optional<bool>* save_success, base::RunLoop* loop, bool success) { @@ -135,10 +144,19 @@ &save_success, &loop))) { loop.Run(); } - *sites = popular_sites.sites(); + *sites = popular_sites->sites(); return save_success; } + std::unique_ptr<PopularSites> CreatePopularSites( + net::URLRequestContextGetter* context) { + return base::MakeUnique<PopularSitesImpl>( + worker_pool_owner_.pool().get(), &prefs_, + /*template_url_service=*/nullptr, + /*variations_service=*/nullptr, context, cache_dir_, + base::Bind(JsonUnsafeParser::Parse)); + } + const TestPopularSite kWikipedia; const TestPopularSite kYouTube; const TestPopularSite kChromium; @@ -169,6 +187,15 @@ EXPECT_THAT(sites[0].favicon_url, URLEq("")); } +TEST_F(PopularSitesTest, ContainsDefaultTilesRightAfterConstruction) { + scoped_refptr<net::TestURLRequestContextGetter> url_request_context( + new net::TestURLRequestContextGetter( + base::ThreadTaskRunnerHandle::Get())); + + EXPECT_THAT(CreatePopularSites(url_request_context.get())->sites().size(), + Eq(GetNumberOfDefaultPopularSitesForPlatform())); +} + TEST_F(PopularSitesTest, Fallback) { SetCountryAndVersion("ZZ", "9"); RespondWith404( @@ -194,7 +221,7 @@ URLEq("https://www.chromium.org/favicon.ico")); } -TEST_F(PopularSitesTest, Failure) { +TEST_F(PopularSitesTest, PopulatesWithDefaultResoucesOnFailure) { SetCountryAndVersion("ZZ", "9"); RespondWith404( "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json"); @@ -204,7 +231,43 @@ PopularSites::SitesVector sites; EXPECT_THAT(FetchPopularSites(/*force_download=*/false, &sites), Eq(base::Optional<bool>(false))); - ASSERT_THAT(sites, IsEmpty()); + EXPECT_THAT(sites.size(), Eq(GetNumberOfDefaultPopularSitesForPlatform())); +} + +TEST_F(PopularSitesTest, ProvidesDefaultSitesUntilCallbackReturns) { + SetCountryAndVersion("ZZ", "9"); + RespondWithJSON( + "https://www.gstatic.com/chrome/ntp/suggested_sites_ZZ_9.json", + {kWikipedia}); + scoped_refptr<net::TestURLRequestContextGetter> url_request_context( + new net::TestURLRequestContextGetter( + base::ThreadTaskRunnerHandle::Get())); + std::unique_ptr<PopularSites> popular_sites = + CreatePopularSites(url_request_context.get()); + + base::RunLoop loop; + base::Optional<bool> save_success = false; + + bool callback_was_scheduled = popular_sites->MaybeStartFetch( + /*force_download=*/true, base::Bind( + [](base::Optional<bool>* save_success, + base::RunLoop* loop, bool success) { + save_success->emplace(success); + loop->Quit(); + }, + &save_success, &loop)); + + // Assert that callback was scheduled so we can wait for its completion. + ASSERT_TRUE(callback_was_scheduled); + // There should be 8 default sites as nothing was fetched yet. + EXPECT_THAT(popular_sites->sites().size(), + Eq(GetNumberOfDefaultPopularSitesForPlatform())); + + loop.Run(); // Wait for the fetch to finish and the callback to return. + + EXPECT_TRUE(save_success.value()); + // The 1 fetched site should replace the default sites. + EXPECT_THAT(popular_sites->sites().size(), Eq(1ul)); } TEST_F(PopularSitesTest, ClearsCacheFileFromOldVersions) {
diff --git a/components/ntp_tiles/resources/default_popular_sites.json b/components/ntp_tiles/resources/default_popular_sites.json new file mode 100644 index 0000000..9e14a78 --- /dev/null +++ b/components/ntp_tiles/resources/default_popular_sites.json
@@ -0,0 +1,42 @@ +[ + { + "title": "Facebook - Log In or Sign Up", + "url": "https://m.facebook.com/", + "large_icon_url": "https://static.xx.fbcdn.net/rsrc.php/v3/ya/r/O2aKM2iSbOw.png" + }, + { + "title": "YouTube", + "url": "https://m.youtube.com/", + "large_icon_url": "https://s.ytimg.com/yts/mobile/img/apple-touch-icon-144x144-precomposed-vflwq-hLZ.png" + }, + { + "title": "Amazon.com: Online Shopping for Electronics, Apparel, Computers, Books, DVDs \u0026 more", + "url": "https://www.amazon.com/", + "large_icon_url": "https://images-na.ssl-images-amazon.com/images/G/01/anywhere/a_smile_196x196._CB368246573_.png" + }, + { + "title": "Wikipedia, the free encyclopedia", + "url": "https://en.m.wikipedia.org/", + "large_icon_url": "https://en.m.wikipedia.org/static/apple-touch/wikipedia.png" + }, + { + "title": "ESPN: The Worldwide Leader in Sports", + "url": "http://www.espn.com/", + "large_icon_url": "http://a.espncdn.com/wireless/mw5/r1/images/bookmark-icons/espn_icon-152x152.min.png" + }, + { + "title": "Yahoo", + "url": "https://www.yahoo.com/", + "large_icon_url": "https://s.yimg.com/dh/ap/default/130909/y_200_a.png" + }, + { + "title": "Instagram", + "url": "https://www.instagram.com/", + "large_icon_url": "https://instagramstatic-a.akamaihd.net/h1/images/ico/favicon-192.png/b407fa101800.png" + }, + { + "title": "Electronics, Cars, Fashion, Collectibles, Coupons and More | eBay", + "url": "http://m.ebay.com/", + "large_icon_url": "http://ir.ebaystatic.com/pictures/aw/pics/mobile/images/apple-touch-icon.png" + } +]
diff --git a/components/proximity_auth/webui/proximity_auth_ui.cc b/components/proximity_auth/webui/proximity_auth_ui.cc index 89b2d2f..ce56260d 100644 --- a/components/proximity_auth/webui/proximity_auth_ui.cc +++ b/components/proximity_auth/webui/proximity_auth_ui.cc
@@ -21,33 +21,14 @@ : content::WebUIController(web_ui) { content::WebUIDataSource* source = content::WebUIDataSource::Create(kChromeUIProximityAuthHost); - source->SetDefaultResource(IDR_PROXIMITY_AUTH_UI_HTML); - source->AddResourcePath("proximity_auth.css", IDR_PROXIMITY_AUTH_UI_CSS); - source->AddResourcePath("content-panel.html", - IDR_PROXIMITY_AUTH_CONTENT_PANEL_HTML); - source->AddResourcePath("content-panel.js", - IDR_PROXIMITY_AUTH_CONTENT_PANEL_JS); - source->AddResourcePath("log-panel.html", IDR_PROXIMITY_AUTH_LOG_PANEL_HTML); - source->AddResourcePath("log-panel.js", IDR_PROXIMITY_AUTH_LOG_PANEL_JS); - source->AddResourcePath("local-state.html", - IDR_PROXIMITY_AUTH_LOCAL_STATE_HTML); - source->AddResourcePath("local-state.js", IDR_PROXIMITY_AUTH_LOCAL_STATE_JS); - source->AddResourcePath("device-list.html", - IDR_PROXIMITY_AUTH_DEVICE_LIST_HTML); - source->AddResourcePath("device-list.js", IDR_PROXIMITY_AUTH_DEVICE_LIST_JS); - source->AddResourcePath("log-buffer.html", - IDR_PROXIMITY_AUTH_LOG_BUFFER_HTML); - source->AddResourcePath("log-buffer.js", IDR_PROXIMITY_AUTH_LOG_BUFFER_JS); - source->AddResourcePath("eligible-devices.html", - IDR_PROXIMITY_AUTH_ELIGIBLE_DEVICES_HTML); - source->AddResourcePath("eligible-devices.js", - IDR_PROXIMITY_AUTH_ELIGIBLE_DEVICES_JS); - source->AddResourcePath("reachable-devices.html", - IDR_PROXIMITY_AUTH_REACHABLE_DEVICES_HTML); - source->AddResourcePath("reachable-devices.js", - IDR_PROXIMITY_AUTH_REACHABLE_DEVICES_JS); - source->AddResourcePath("cryptauth_interface.js", - IDR_PROXIMITY_AUTH_CRYPTAUTH_INTERFACE_JS); + source->SetDefaultResource(IDR_PROXIMITY_AUTH_POLLUX_DEBUG_HTML); + source->AddResourcePath("pollux_debug.css", + IDR_PROXIMITY_AUTH_POLLUX_DEBUG_CSS); + source->AddResourcePath("pollux_debug.js", + IDR_PROXIMITY_AUTH_POLLUX_DEBUG_JS); + source->AddResourcePath("webui.js", IDR_PROXIMITY_AUTH_POLLUX_WEBUI_JS); + source->AddResourcePath("logs_controller.js", + IDR_PROXIMITY_AUTH_POLLUX_LOGS_CONTROLLER_JS); content::BrowserContext* browser_context = web_ui->GetWebContents()->GetBrowserContext();
diff --git a/components/proximity_auth/webui/resources/pollux/logs_controller.js b/components/proximity_auth/webui/resources/pollux/logs_controller.js new file mode 100644 index 0000000..edbd5b7 --- /dev/null +++ b/components/proximity_auth/webui/resources/pollux/logs_controller.js
@@ -0,0 +1,124 @@ +/* Copyright 2017 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +Logs = { + controller_: null, + + /** + * Initializes the logs UI. + */ + init: function() { + Logs.controller_ = new LogsListController(); + + var clearLogsButton = document.getElementById('clear-logs-button'); + clearLogsButton.onclick = function() { + WebUI.clearLogs(); + }; + + WebUI.getLogMessages(); + }, +}; + +/** + * Interface with the native WebUI component for LogBuffer events. The functions + * contained in this object will be invoked by the browser for each operation + * performed on the native LogBuffer. + */ +LogBufferInterface = { + /** + * Called when a new log message is added. + */ + onLogMessageAdded: function(log) { + if (Logs.controller_) { + Logs.controller_.add(log); + } + }, + + /** + * Called when the log buffer is cleared. + */ + onLogBufferCleared: function() { + if (Logs.controller_) { + Logs.controller_.clear(); + } + }, + + /** + * Called in response to chrome.send('getLogMessages') with the log messages + * currently in the buffer. + */ + onGotLogMessages: function(messages) { + if (Logs.controller_) { + Logs.controller_.set(messages); + } + }, +}; + +/** + * Controller for the logs list UI, updating it based on user input and logs + * received from native code. + * + */ +class LogsListController { + constructor() { + this.logsList_ = document.getElementById('logs-list'); + this.itemTemplate_ = document.getElementById('item-template'); + this.shouldSnapToBottom_ = true; + + this.logsList_.onscroll = this.onScroll_.bind(this); + } + + /** + * Listener for scroll event of the logs list element, used for snap to bottom + * logic. + */ + onScroll_() { + const list = this.logsList_; + this.shouldSnapToBottom_ = + list.scrollTop + list.offsetHeight == list.scrollHeight; + } + + /** + * Clears all log items from the logs list. + */ + clear() { + var items = this.logsList_.querySelectorAll('.log-item'); + for (var i = 0; i < items.length; ++i) { + items[i].remove(); + } + this.shouldSnapToBottom_ = true; + } + + /** + * Adds a log to the logs list. + */ + add(log) { + var directories = log.file.split('/'); + var source = directories[directories.length - 1] + ':' + log.line; + + var t = this.itemTemplate_.content; + console.log(t.querySelector('.log-item').attributes); + t.querySelector('.log-item').attributes.severity.value = log.severity; + t.querySelector('.item-time').textContent = log.time; + t.querySelector('.item-source').textContent = source; + t.querySelector('.item-text').textContent = log.text; + + var newLogItem = document.importNode(this.itemTemplate_.content, true); + this.logsList_.appendChild(newLogItem); + if (this.shouldSnapToBottom_) { + this.logsList_.scrollTop = this.logsList_.scrollHeight; + } + } + + /** + * Initializes the log list from an array of logs. + */ + set(logs) { + this.clear(); + for (var i = 0; i < logs.length; ++i) { + this.add(logs[i]); + } + } +}
diff --git a/components/proximity_auth/webui/resources/pollux/pollux_debug.css b/components/proximity_auth/webui/resources/pollux/pollux_debug.css new file mode 100644 index 0000000..c54ac13 --- /dev/null +++ b/components/proximity_auth/webui/resources/pollux/pollux_debug.css
@@ -0,0 +1,161 @@ +/* Copyright 2017 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +html, body { + width: 100%; + height: 100%; + margin: 0; + padding: 0; + overflow: hidden; + font-family: "Roboto", sans-serif; + display: flex; +} + +header { + min-height: 50px; + font-size: 24px; + background-color: #069BDE; + display: flex; + padding: 0 20px; + color: #f4f4f4; + text-align: center; + align-items: center; + border-bottom: 1px solid rgba(0,0,0,0.12); +} + + +/** CSS for controls panel */ +#controls { + width: 60%; + display: flex; + flex-direction: column; + overflow-y: auto; +} + +.logo { + font-size: 40px; + margin-right: 12px; +} + +#controls-panel { + padding: 40px; +} + +.control { + margin-bottom: 60px; +} + +.control-title { + font-size: 16px; + font-weight: bold; + margin-bottom: 5px; +} + +.input-row { + display: flex; + align-items: center; + margin-bottom: 5px; + padding-left: 12px; +} + +.input-row button { + border: 1px solid rgba(0,0,0,0.12); + color: #fff; + background-color: #7496c8; + border: none; + cursor: pointer; + font-size: 14px; + height: 24px; + width: 80px; +} + +.input-row button:hover { + background-color: #446392; +} + +.input-row button:active { + background-color: #37496d; +} + +.input-name { + font-size: 14px; + width: 100px; +} + +.textinput { + min-width: 200px; + font-family: monospace; + margin: 0 5px; + font-size: 16px; +} + + +/** CSS for logs panel */ +#logs-panel { + width: 40%; + display: flex; + flex-direction: column; + border-left: 1px solid rgba(0,0,0,0.12); +} + +#logs-panel > header { + flex-direction: row-reverse; +} + +#clear-logs-button { + cursor: pointer; + background-color: rgba(0,0,0,0); + border: none; + font-size: 30px; + height: 100%; + color: #fff; +} + +#clear-logs-button:hover { + cursor: pointer; + color: #535553; +} + +#clear-logs-button:focus { + outline: 0; +} + +#logs-list { + display: flex; + flex-direction: column; + overflow-y: auto; +} + +.log-item { + border-bottom: 1px solid rgba(0, 0, 0, 0.12); + font-family: monospace; + font-size: 12px; + padding: 15px 30px; +} + +.log-item[severity="1"] { + background-color: #fffcef; + color: #312200; +} + +.log-item[severity="2"] { + background-color: #fff1f1; + color: #ef0000; +} + +.item-metadata { + color: #888888; + font-size: 10px; + display: flex; +} + +.item-metadata > .flex { + flex: 1; +} + +.item-text { + margin: 0; + display: inline-block; +}
diff --git a/components/proximity_auth/webui/resources/pollux/pollux_debug.html b/components/proximity_auth/webui/resources/pollux/pollux_debug.html new file mode 100644 index 0000000..55de707d --- /dev/null +++ b/components/proximity_auth/webui/resources/pollux/pollux_debug.html
@@ -0,0 +1,82 @@ +<!DOCTYPE HTML> +<html> + +<head> + <meta charset="utf-8"> + + <link href="chrome://resources/css/roboto.css" rel="stylesheet"> + <link href="pollux_debug.css" rel='stylesheet'> + + <script src='webui.js' type='text/javascript'></script> + <script src='logs_controller.js' type='text/javascript'></script> + <script src='pollux_debug.js' type='text/javascript'></script> +</head> + +<body> + <!-- Panel for debug controls. --> + <section id='controls'> + <header> + <div class='logo'>✧</div> + <div class='title'>POLLUX DEBUG</div> + </header> + + <div id='controls-panel'> + <!-- Controls for server simulation --> + <div class='control'> + <div class='control-title'>SERVER</div> + <div class='input-row'> + <div class='input-name'>MASTER_KEY:</div> + <input class='textinput' type='text' value='F3DA234A14'></input> + </div> + <div class='input-row'><button>Challenge</button></div> + </div> + + <!-- Controls for testing getAssertion() --> + <div class='control'> + <div class='control-title'>GET ASSERTION</div> + <div class='input-row'> + <div class='input-name'>CHALLENGE:</div> + <input class='textinput' type='text' value='A3DA234A14'></input> + </div> + <div class='input-row'> + <div class='input-name'>EID:</div> + <input class='textinput' type='text' value='A3DA234A14'></input> + </div> + <div class='input-row'> + <div class='input-name'>SESSION_KEY:</div> + <input class='textinput' type='text' value='A3DA234A14'></input> + </div> + <div class='input-row'><button>Start</button></div> + </div> + + <!-- Controls for the state of the remote device (AKA Authenticator) --> + <div class='control'> + <div class='control-title'>AUTHENTICATOR STATE</div> + <div class='input-row'> + <div class='input-name'>NOT STARTED</div> + </div> + </div> + </div> + </section> + + <!-- Panel for logs list. --> + <section id='logs-panel'> + <header> + <button id='clear-logs-button'>∅</button> + </header> + <div id='logs-list'> + <template id='item-template'> + <div class='log-item' severity='0'> + <div class="item-metadata"> + <div class='item-time'></div> + <div class="flex"></div> + <div class='item-source'></div> + </div> + <pre class="item-text flex">This is an error.</pre> + </div> + </template> + </div> + </section> +</body> + +</html>
diff --git a/components/proximity_auth/webui/resources/pollux/pollux_debug.js b/components/proximity_auth/webui/resources/pollux/pollux_debug.js new file mode 100644 index 0000000..29af6bfe --- /dev/null +++ b/components/proximity_auth/webui/resources/pollux/pollux_debug.js
@@ -0,0 +1,8 @@ +/* Copyright 2017 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +document.addEventListener('DOMContentLoaded', function() { + Logs.init(); +});
diff --git a/components/proximity_auth/webui/resources/pollux/webui.js b/components/proximity_auth/webui/resources/pollux/webui.js new file mode 100644 index 0000000..1525c66d --- /dev/null +++ b/components/proximity_auth/webui/resources/pollux/webui.js
@@ -0,0 +1,25 @@ +/* Copyright 2017 The Chromium Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * JavaScript hooks into the native WebUI handler. + */ +WebUI = { + getLogMessages: function() { + chrome.send('getLogMessages'); + }, + + clearLogs: function() { + chrome.send('clearLogBuffer'); + }, + + generateChallenge: function() { + chrome.send('generateChallenge'); + }, + + getAssertion: function() { + chrome.send('getAssertion'); + } +};
diff --git a/components/resources/ntp_tiles_resources.grdp b/components/resources/ntp_tiles_resources.grdp index 37999984..e42d4ea 100644 --- a/components/resources/ntp_tiles_resources.grdp +++ b/components/resources/ntp_tiles_resources.grdp
@@ -4,6 +4,7 @@ <include name="IDR_POPULAR_SITES_INTERNALS_HTML" file="../ntp_tiles/webui/resources/popular_sites_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_POPULAR_SITES_INTERNALS_JS" file="../ntp_tiles/webui/resources/popular_sites_internals.js" type="BINDATA" /> <include name="IDR_POPULAR_SITES_INTERNALS_CSS" file="../ntp_tiles/webui/resources/popular_sites_internals.css" type="BINDATA" /> + <include name="IDR_DEFAULT_POPULAR_SITES_JSON" file="../ntp_tiles/resources/default_popular_sites.json" type="BINDATA" /> </if> <include name="IDR_NTP_TILES_INTERNALS_HTML" file="../ntp_tiles/webui/resources/ntp_tiles_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_NTP_TILES_INTERNALS_JS" file="../ntp_tiles/webui/resources/ntp_tiles_internals.js" type="BINDATA" />
diff --git a/components/resources/proximity_auth_resources.grdp b/components/resources/proximity_auth_resources.grdp index 0c71d06..6798b6c 100644 --- a/components/resources/proximity_auth_resources.grdp +++ b/components/resources/proximity_auth_resources.grdp
@@ -32,4 +32,16 @@ file="../proximity_auth/webui/resources/reachable-devices.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_PROXIMITY_AUTH_CRYPTAUTH_INTERFACE_JS" file="../proximity_auth/webui/resources/cryptauth_interface.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> + + <!-- Resources for Pollux debug page. --> + <include name="IDR_PROXIMITY_AUTH_POLLUX_DEBUG_HTML" + file="../proximity_auth/webui/resources/pollux/pollux_debug.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_PROXIMITY_AUTH_POLLUX_DEBUG_CSS" + file="../proximity_auth/webui/resources/pollux/pollux_debug.css" type="BINDATA" /> + <include name="IDR_PROXIMITY_AUTH_POLLUX_DEBUG_JS" + file="../proximity_auth/webui/resources/pollux/pollux_debug.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_PROXIMITY_AUTH_POLLUX_LOGS_CONTROLLER_JS" + file="../proximity_auth/webui/resources/pollux/logs_controller.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_PROXIMITY_AUTH_POLLUX_WEBUI_JS" + file="../proximity_auth/webui/resources/pollux/webui.js" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> </grit-part>
diff --git a/components/search_engines/default_search_policy_handler_unittest.cc b/components/search_engines/default_search_policy_handler_unittest.cc index 93f7eaf..6db8390 100644 --- a/components/search_engines/default_search_policy_handler_unittest.cc +++ b/components/search_engines/default_search_policy_handler_unittest.cc
@@ -179,7 +179,8 @@ // Try changing policy param to BinaryValue and check that policy becomes // invalid. policy.Set(policy_name, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, - POLICY_SOURCE_CLOUD, base::WrapUnique(new base::BinaryValue()), + POLICY_SOURCE_CLOUD, + base::MakeUnique<base::Value>(base::Value::Type::BINARY), nullptr); UpdateProviderPolicy(policy);
diff --git a/content/app/BUILD.gn b/content/app/BUILD.gn index 21d91f9..2480465 100644 --- a/content/app/BUILD.gn +++ b/content/app/BUILD.gn
@@ -55,7 +55,6 @@ "//device/geolocation", "//device/power_save_blocker", "//device/sensors", - "//device/time_zone_monitor", "//device/usb", "//device/vibration", "//gpu",
diff --git a/content/app/DEPS b/content/app/DEPS index d001ffa1..76c9bee 100644 --- a/content/app/DEPS +++ b/content/app/DEPS
@@ -8,7 +8,6 @@ "+device/geolocation", "+device/power_save_blocker", "+device/sensors", - "+device/time_zone_monitor", "+device/usb", "+device/vibration", # For loading V8's initial snapshot from external files.
diff --git a/content/app/android/library_loader_hooks.cc b/content/app/android/library_loader_hooks.cc index 77a7111b..8d16801 100644 --- a/content/app/android/library_loader_hooks.cc +++ b/content/app/android/library_loader_hooks.cc
@@ -31,7 +31,6 @@ #include "device/generic_sensor/android/sensors_jni_registrar.h" #include "device/geolocation/android/geolocation_jni_registrar.h" #include "device/sensors/android/device_sensor_jni_registrar.h" -#include "device/time_zone_monitor/android/time_zone_monitor_jni_registrar.h" #include "device/usb/android/usb_jni_registrar.h" #include "media/base/android/media_jni_registrar.h" #include "media/capture/content/android/screen_capture_jni_registrar.h" @@ -95,9 +94,6 @@ if (!device::android::RegisterSensorsJni(env)) return false; - if (!device::android::RegisterTimeZoneMonitorJni(env)) - return false; - if (!device::android::RegisterUsbJni(env)) return false;
diff --git a/content/browser/DEPS b/content/browser/DEPS index b3a770a..af18f2d 100644 --- a/content/browser/DEPS +++ b/content/browser/DEPS
@@ -78,6 +78,7 @@ "+third_party/WebKit/public/platform/WebReferrerPolicy.h", "+third_party/WebKit/public/platform/WebScreenInfo.h", "+third_party/WebKit/public/platform/WebSecurityStyle.h", + "+third_party/WebKit/public/platform/WebString.h", "+third_party/WebKit/public/platform/WebTouchEvent.h", "+third_party/WebKit/public/platform/WebTextInputType.h", "+third_party/WebKit/public/platform/mime_registry.mojom.h",
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc index 4cfea45b..41f7930 100644 --- a/content/browser/android/content_view_core_impl.cc +++ b/content/browser/android/content_view_core_impl.cc
@@ -418,6 +418,8 @@ const gfx::SizeF& viewport_size, const float top_controls_height, const float top_controls_shown_ratio, + const float bottom_controls_height, + const float bottom_controls_shown_ratio, bool is_mobile_optimized_hint, const gfx::SelectionBound& selection_start) { JNIEnv* env = AttachCurrentThread(); @@ -447,11 +449,20 @@ page_scale_factor_limits.x(), page_scale_factor_limits.y(), content_size.width(), content_size.height(), viewport_size.width(), viewport_size.height(), top_controls_height, top_controls_shown_ratio, + bottom_controls_height, bottom_controls_shown_ratio, is_mobile_optimized_hint, has_insertion_marker, is_insertion_marker_visible, insertion_marker_horizontal, insertion_marker_top, insertion_marker_bottom); } +void ContentViewCoreImpl::OnBackgroundColorChanged(SkColor color) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); + if (obj.is_null()) + return; + Java_ContentViewCore_onBackgroundColorChanged(env, obj, color); +} + void ContentViewCoreImpl::ShowSelectPopupMenu( RenderFrameHost* frame, const gfx::Rect& bounds, @@ -641,6 +652,18 @@ y_dip); } +void ContentViewCoreImpl::StartContentIntent(const GURL& content_url, + bool is_main_frame) { + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jobject> j_obj = java_ref_.get(env); + if (j_obj.is_null()) + return; + ScopedJavaLocalRef<jstring> jcontent_url = + ConvertUTF8ToJavaString(env, content_url.spec()); + Java_ContentViewCore_startContentIntent(env, j_obj, jcontent_url, + is_main_frame); +} + void ContentViewCoreImpl::ShowDisambiguationPopup( const gfx::Rect& rect_pixels, const SkBitmap& zoomed_bitmap) {
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h index 7973a15..603fd441 100644 --- a/content/browser/android/content_view_core_impl.h +++ b/content/browser/android/content_view_core_impl.h
@@ -307,6 +307,8 @@ const gfx::SizeF& viewport_size, const float top_controls_height, const float top_controls_shown_ratio, + const float bottom_controls_height, + const float bottom_controls_shown_ratio, bool is_mobile_optimized_hint, const gfx::SelectionBound& selection_start); @@ -322,6 +324,7 @@ int composition_end, bool show_ime_if_needed, bool reply_to_request); + void OnBackgroundColorChanged(SkColor color); bool HasFocus(); void RequestDisallowInterceptTouchEvent(); @@ -333,6 +336,8 @@ const gfx::PointF& selection_anchor, const gfx::RectF& selection_rect); + void StartContentIntent(const GURL& content_url, bool is_main_frame); + // Shows the disambiguation popup // |rect_pixels| --> window coordinates which |zoomed_bitmap| represents // |zoomed_bitmap| --> magnified image of potential touch targets
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 9f1db28..02d54e8 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -400,10 +400,6 @@ display_compositor::GLHelper::SCALER_QUALITY_GOOD); } -bool FloatEquals(float a, float b) { - return std::abs(a - b) < FLT_EPSILON; -} - } // namespace void RenderWidgetHostViewAndroid::OnContextLost() { @@ -439,8 +435,6 @@ synchronous_compositor_client_(nullptr), frame_evictor_(new DelegatedFrameEvictor(this)), observing_root_window_(false), - prev_top_shown_pix_(0.f), - prev_bottom_shown_pix_(0.f), weak_ptr_factory_(this) { // Set the layer which will hold the content layer for this view. The content // layer is managed by the DelegatedFrameHost. @@ -796,7 +790,8 @@ if (delegated_frame_host_) delegated_frame_host_->UpdateBackgroundColor(color); - view_.OnBackgroundColorChanged(color); + if (content_view_core_) + content_view_core_->OnBackgroundColorChanged(color); } void RenderWidgetHostViewAndroid::SetNeedsBeginFrames(bool needs_begin_frames) { @@ -810,7 +805,8 @@ void RenderWidgetHostViewAndroid::OnStartContentIntent( const GURL& content_url, bool is_main_frame) { - view_.StartContentIntent(content_url, is_main_frame); + if (content_view_core_) + content_view_core_->StartContentIntent(content_url, is_main_frame); } bool RenderWidgetHostViewAndroid::OnTouchEvent( @@ -1278,28 +1274,6 @@ frame_metadata.top_controls_height * frame_metadata.top_controls_shown_ratio)); - float dip_scale = ui::GetScaleFactorForNativeView(GetNativeView()); - float top_controls_pix = frame_metadata.top_controls_height * dip_scale; - float top_shown_pix = top_controls_pix - * frame_metadata.top_controls_shown_ratio; - bool top_changed = !FloatEquals(top_shown_pix, prev_top_shown_pix_); - - float bottom_controls_pix = frame_metadata.bottom_controls_height * dip_scale; - float bottom_shown_pix = bottom_controls_pix - * frame_metadata.bottom_controls_shown_ratio; - bool bottom_changed = !FloatEquals(bottom_shown_pix, prev_bottom_shown_pix_); - - if (top_changed) { - float translate = top_shown_pix - top_controls_pix; - view_.OnTopControlsChanged(translate, top_shown_pix); - prev_top_shown_pix_ = top_shown_pix; - } - if (bottom_changed) { - float translate = bottom_controls_pix - bottom_shown_pix; - view_.OnBottomControlsChanged(translate, bottom_shown_pix); - prev_bottom_shown_pix_ = bottom_shown_pix; - } - // All offsets and sizes are in CSS pixels. content_view_core_->UpdateFrameInfo( frame_metadata.root_scroll_offset, @@ -1310,6 +1284,8 @@ frame_metadata.scrollable_viewport_size, frame_metadata.top_controls_height, frame_metadata.top_controls_shown_ratio, + frame_metadata.bottom_controls_height, + frame_metadata.bottom_controls_shown_ratio, is_mobile_optimized, frame_metadata.selection.start); }
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index 05064919..a52a7a1 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -376,9 +376,6 @@ // The last scroll offset of the view. gfx::Vector2dF last_scroll_offset_; - float prev_top_shown_pix_; - float prev_bottom_shown_pix_; - base::WeakPtrFactory<RenderWidgetHostViewAndroid> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAndroid);
diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/shared_worker/shared_worker_service_impl.cc index 4524fd5..924582cd2 100644 --- a/content/browser/shared_worker/shared_worker_service_impl.cc +++ b/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -12,7 +12,6 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "base/memory/ref_counted.h" #include "base/stl_util.h" #include "content/browser/devtools/shared_worker_devtools_manager.h" #include "content/browser/renderer_host/render_process_host_impl.h" @@ -38,6 +37,78 @@ namespace { +// A helper to request a renderer process allocation for a shared worker to the +// UI thread from the IO thread. +class SharedWorkerReserver { + public: + ~SharedWorkerReserver() = default; + + using ResolverCallback = base::Callback<void(int worker_process_id, + int worker_route_id, + bool is_new_worker, + bool pause_on_start)>; + + // Tries to reserve a renderer process for a shared worker. This should be + // called on the IO thread and given callbacks are also invoked on the IO + // thread on completion. + static void TryReserve(int worker_process_id, + int worker_route_id, + bool is_new_worker, + const SharedWorkerInstance& instance, + const ResolverCallback& success_cb, + const ResolverCallback& failure_cb, + bool (*try_increment_worker_ref_count)(int)) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + std::unique_ptr<SharedWorkerReserver> reserver(new SharedWorkerReserver( + worker_process_id, worker_route_id, is_new_worker, instance)); + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&SharedWorkerReserver::TryReserveOnUI, std::move(reserver), + success_cb, failure_cb, try_increment_worker_ref_count)); + } + + private: + SharedWorkerReserver(int worker_process_id, + int worker_route_id, + bool is_new_worker, + const SharedWorkerInstance& instance) + : worker_process_id_(worker_process_id), + worker_route_id_(worker_route_id), + is_new_worker_(is_new_worker), + instance_(instance) {} + + void TryReserveOnUI(const ResolverCallback& success_cb, + const ResolverCallback& failure_cb, + bool (*try_increment_worker_ref_count)(int)) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + bool pause_on_start = false; + if (!try_increment_worker_ref_count(worker_process_id_)) { + DidTryReserveOnUI(failure_cb, pause_on_start); + return; + } + if (is_new_worker_) { + pause_on_start = + SharedWorkerDevToolsManager::GetInstance()->WorkerCreated( + worker_process_id_, worker_route_id_, instance_); + } + DidTryReserveOnUI(success_cb, pause_on_start); + } + + void DidTryReserveOnUI(const ResolverCallback& callback, + bool pause_on_start) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(callback, worker_process_id_, worker_route_id_, + is_new_worker_, pause_on_start)); + } + + const int worker_process_id_; + const int worker_route_id_; + const bool is_new_worker_; + const SharedWorkerInstance instance_; +}; + class ScopedWorkerDependencyChecker { public: explicit ScopedWorkerDependencyChecker(SharedWorkerServiceImpl* service) @@ -194,47 +265,6 @@ DISALLOW_COPY_AND_ASSIGN(SharedWorkerPendingInstance); }; -class SharedWorkerServiceImpl::SharedWorkerReserver - : public base::RefCountedThreadSafe<SharedWorkerReserver> { - public: - SharedWorkerReserver(int pending_instance_id, - int worker_process_id, - int worker_route_id, - bool is_new_worker, - const SharedWorkerInstance& instance) - : worker_process_id_(worker_process_id), - worker_route_id_(worker_route_id), - is_new_worker_(is_new_worker), - instance_(instance) {} - - void TryReserve(const base::Callback<void(bool)>& success_cb, - const base::Closure& failure_cb, - bool (*try_increment_worker_ref_count)(int)) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!try_increment_worker_ref_count(worker_process_id_)) { - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, failure_cb); - return; - } - bool pause_on_start = false; - if (is_new_worker_) { - pause_on_start = - SharedWorkerDevToolsManager::GetInstance()->WorkerCreated( - worker_process_id_, worker_route_id_, instance_); - } - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, base::Bind(success_cb, pause_on_start)); - } - - private: - friend class base::RefCountedThreadSafe<SharedWorkerReserver>; - ~SharedWorkerReserver() {} - - const int worker_process_id_; - const int worker_route_id_; - const bool is_new_worker_; - const SharedWorkerInstance instance_; -}; - // static bool (*SharedWorkerServiceImpl::s_try_increment_worker_ref_count_)(int) = TryIncrementWorkerRefCount; @@ -513,32 +543,14 @@ } const int pending_instance_id = next_pending_instance_id_++; - scoped_refptr<SharedWorkerReserver> reserver( - new SharedWorkerReserver(pending_instance_id, - worker_process_id, - worker_route_id, - is_new_worker, - *pending_instance->instance())); - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind( - &SharedWorkerReserver::TryReserve, - reserver, - base::Bind(&SharedWorkerServiceImpl::RenderProcessReservedCallback, - base::Unretained(this), - pending_instance_id, - worker_process_id, - worker_route_id, - is_new_worker), - base::Bind( - &SharedWorkerServiceImpl::RenderProcessReserveFailedCallback, - base::Unretained(this), - pending_instance_id, - worker_process_id, - worker_route_id, - is_new_worker), - s_try_increment_worker_ref_count_)); + SharedWorkerReserver::TryReserve( + worker_process_id, worker_route_id, is_new_worker, + *pending_instance->instance(), + base::Bind(&SharedWorkerServiceImpl::RenderProcessReservedCallback, + base::Unretained(this), pending_instance_id), + base::Bind(&SharedWorkerServiceImpl::RenderProcessReserveFailedCallback, + base::Unretained(this), pending_instance_id), + s_try_increment_worker_ref_count_); pending_instances_[pending_instance_id] = std::move(pending_instance); return creation_error; } @@ -603,7 +615,9 @@ int pending_instance_id, int worker_process_id, int worker_route_id, - bool is_new_worker) { + bool is_new_worker, + bool pause_on_start) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); worker_hosts_.erase(std::make_pair(worker_process_id, worker_route_id)); if (!base::ContainsKey(pending_instances_, pending_instance_id)) return;
diff --git a/content/browser/shared_worker/shared_worker_service_impl.h b/content/browser/shared_worker/shared_worker_service_impl.h index ca351d1..e6383c8 100644 --- a/content/browser/shared_worker/shared_worker_service_impl.h +++ b/content/browser/shared_worker/shared_worker_service_impl.h
@@ -104,7 +104,6 @@ private: class SharedWorkerPendingInstance; - class SharedWorkerReserver; friend struct base::DefaultSingletonTraits<SharedWorkerServiceImpl>; friend class SharedWorkerServiceImplTest; @@ -146,7 +145,8 @@ void RenderProcessReserveFailedCallback(int pending_instance_id, int worker_process_id, int worker_route_id, - bool is_new_worker); + bool is_new_worker, + bool pause_on_start); // Returns nullptr if there is no host for given ids. SharedWorkerHost* FindSharedWorkerHost(int render_process_id,
diff --git a/content/child/v8_value_converter_impl.cc b/content/child/v8_value_converter_impl.cc index dd36788..86554c33 100644 --- a/content/child/v8_value_converter_impl.cc +++ b/content/child/v8_value_converter_impl.cc
@@ -11,6 +11,7 @@ #include <memory> #include <string> #include <utility> +#include <vector> #include "base/bind.h" #include "base/bind_helpers.h" @@ -268,9 +269,7 @@ static_cast<const base::DictionaryValue*>(value)); case base::Value::Type::BINARY: - return ToArrayBuffer(isolate, - creation_context, - static_cast<const base::BinaryValue*>(value)); + return ToArrayBuffer(isolate, creation_context, value); default: LOG(ERROR) << "Unexpected value type: " << value->GetType(); @@ -501,9 +500,9 @@ } else if (val->IsArrayBufferView()) { v8::Local<v8::ArrayBufferView> view = val.As<v8::ArrayBufferView>(); size_t byte_length = view->ByteLength(); - auto buffer = base::MakeUnique<char[]>(byte_length); - view->CopyContents(buffer.get(), byte_length); - return base::MakeUnique<base::BinaryValue>(std::move(buffer), byte_length); + std::vector<char> buffer(byte_length); + view->CopyContents(buffer.data(), buffer.size()); + return base::MakeUnique<base::BinaryValue>(std::move(buffer)); } else { NOTREACHED() << "Only ArrayBuffer and ArrayBufferView should get here."; return nullptr;
diff --git a/content/child/v8_value_converter_impl.h b/content/child/v8_value_converter_impl.h index 4b4c00a..0cc996e4 100644 --- a/content/child/v8_value_converter_impl.h +++ b/content/child/v8_value_converter_impl.h
@@ -13,10 +13,10 @@ #include "content/public/child/v8_value_converter.h" namespace base { -class BinaryValue; class DictionaryValue; class ListValue; class Value; +using BinaryValue = Value; } namespace content {
diff --git a/content/common/DEPS b/content/common/DEPS index 1ef8e94..3c8ba65 100644 --- a/content/common/DEPS +++ b/content/common/DEPS
@@ -11,6 +11,7 @@ # header-only types, and some selected common code. "-third_party/WebKit", "+third_party/WebKit/public/platform/WebAddressSpace.h", + "+third_party/WebKit/public/platform/WebCString.h", "+third_party/WebKit/public/platform/WebDisplayMode.h", "+third_party/WebKit/public/platform/WebDragOperation.h", "+third_party/WebKit/public/platform/WebFeaturePolicy.h", @@ -64,6 +65,7 @@ "+third_party/WebKit/public/web/WebDeviceEmulationParams.h", "+third_party/WebKit/public/web/WebDragStatus.h", "+third_party/WebKit/public/web/WebFindOptions.h", + "+third_party/WebKit/public/web/WebFrameOwnerProperties.h", "+third_party/WebKit/public/web/WebFrameSerializerCacheControlPolicy.h", "+third_party/WebKit/public/web/WebMediaPlayerAction.h", "+third_party/WebKit/public/web/WebPluginAction.h", @@ -73,6 +75,7 @@ "+third_party/WebKit/public/web/WebSharedWorkerCreationErrors.h", "+third_party/WebKit/public/web/WebTextDirection.h", "+third_party/WebKit/public/web/WebTreeScopeType.h", + "+third_party/WebKit/public/web/WebWindowFeatures.h", "+third_party/WebKit/public/web/mac/WebScrollbarTheme.h", "+third_party/WebKit/public/web/win/WebFontRendering.h" ]
diff --git a/content/common/android/gin_java_bridge_value.cc b/content/common/android/gin_java_bridge_value.cc index 5961461..ed3fd7e 100644 --- a/content/common/android/gin_java_bridge_value.cc +++ b/content/common/android/gin_java_bridge_value.cc
@@ -57,11 +57,9 @@ bool GinJavaBridgeValue::ContainsGinJavaBridgeValue(const base::Value* value) { if (!value->IsType(base::Value::Type::BINARY)) return false; - const base::BinaryValue* binary_value = - reinterpret_cast<const base::BinaryValue*>(value); - if (binary_value->GetSize() < sizeof(Header)) + if (value->GetSize() < sizeof(Header)) return false; - base::Pickle pickle(binary_value->GetBuffer(), binary_value->GetSize()); + base::Pickle pickle(value->GetBuffer(), value->GetSize()); // Broken binary value: payload or header size is wrong if (!pickle.data() || pickle.size() - pickle.payload_size() != sizeof(Header)) return false; @@ -74,10 +72,8 @@ std::unique_ptr<const GinJavaBridgeValue> GinJavaBridgeValue::FromValue( const base::Value* value) { return std::unique_ptr<const GinJavaBridgeValue>( - value->IsType(base::Value::Type::BINARY) - ? new GinJavaBridgeValue( - reinterpret_cast<const base::BinaryValue*>(value)) - : NULL); + value->IsType(base::Value::Type::BINARY) ? new GinJavaBridgeValue(value) + : NULL); } GinJavaBridgeValue::Type GinJavaBridgeValue::GetType() const {
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index d8a1896..b0ed4d2 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -44,7 +44,6 @@ "//device/nfc/android:java", "//device/power_save_blocker:java", "//device/sensors:java", - "//device/time_zone_monitor:java", "//device/usb:java", "//device/vibration:mojo_bindings_java", "//device/vibration/android:vibration_manager_java", @@ -56,10 +55,10 @@ "//mojo/public/java:bindings_java", "//mojo/public/java:system_java", "//net/android:net_java", + "//services/device:java", "//services/service_manager/public/interfaces:interfaces_java", "//services/service_manager/public/java:service_manager_java", "//services/shape_detection/public/interfaces:interfaces_java", - "//skia/public/interfaces:interfaces_java", "//third_party/WebKit/public:blink_headers_java", "//third_party/WebKit/public:mojo_bindings_java", "//third_party/android_tools:android_support_annotations_java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java index 6ef25210..be561324 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewClient.java
@@ -4,8 +4,14 @@ package org.chromium.content.browser; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; import android.view.KeyEvent; +import org.chromium.base.Log; +import org.chromium.base.metrics.RecordUserAction; + /** * Main callback class used by ContentView. * @@ -14,21 +20,103 @@ * The memory and reference ownership of this class is unusual - see the .cc file and ContentView * for more details. * + * TODO(mkosiba): Rid this class of default implementations. This class is used by both WebView and + * the browser and we don't want a the browser-specific default implementation to accidentally leak + * over to WebView. + * * WARNING: ConteViewClient is going away. Do not add new stuff in this class. */ public class ContentViewClient { + // Tag used for logging. + private static final String TAG = "cr_ContentViewClient"; + + private static final String GEO_SCHEME = "geo"; + private static final String TEL_SCHEME = "tel"; + private static final String MAILTO_SCHEME = "mailto"; + + /** + * Called whenever the background color of the page changes as notified by WebKit. + * @param color The new ARGB color of the page background. + */ + public void onBackgroundColorChanged(int color) { + } + + /** + * Notifies the client of the position of the top controls. + * @param topControlsOffsetY The Y offset of the top controls in physical pixels. + * @param topContentOffsetY The Y offset of the content in physical pixels. + */ + public void onTopControlsChanged(float browserControlsOffsetY, float topContentOffsetY) {} + + /** + * Notifies the client of the position of the bottom controls. + * @param bottomControlsOffsetY The Y offset of the bottom controls in physical pixels. + * @param bottomContentOffsetY The Y offset of the content in physical pixels. + */ + public void onBottomControlsChanged(float bottomControlsOffsetY, float bottomContentOffsetY) { } + + public boolean shouldOverrideKeyEvent(KeyEvent event) { + int keyCode = event.getKeyCode(); + + if (!shouldPropagateKey(keyCode)) return true; + + return false; + } + /** * Called when an ImeEvent is sent to the page. Can be used to know when some text is entered * in a page. */ - public void onImeEvent() {} + public void onImeEvent() { + } /** * Notified when the editability of the focused node changes. * * @param editable Whether the focused node is editable. */ - public void onFocusedNodeEditabilityChanged(boolean editable) {} + public void onFocusedNodeEditabilityChanged(boolean editable) { + } + + /** + * Check whether the given scheme is one of the acceptable schemes for onStartContentIntent. + * + * @param scheme The scheme to check. + * @return true if the scheme is okay, false if it should be blocked. + */ + protected boolean isAcceptableContentIntentScheme(String scheme) { + return GEO_SCHEME.equals(scheme) || TEL_SCHEME.equals(scheme) + || MAILTO_SCHEME.equals(scheme); + } + + /** + * Called when a new content intent is requested to be started. + */ + public void onStartContentIntent(Context context, String intentUrl, boolean isMainFrame) { + Intent intent; + // Perform generic parsing of the URI to turn it into an Intent. + try { + intent = Intent.parseUri(intentUrl, Intent.URI_INTENT_SCHEME); + + String scheme = intent.getScheme(); + if (!isAcceptableContentIntentScheme(scheme)) { + Log.w(TAG, "Invalid scheme for URI %s", intentUrl); + return; + } + + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } catch (Exception ex) { + Log.w(TAG, "Bad URI %s", intentUrl, ex); + return; + } + + try { + RecordUserAction.record("Android.ContentDetectorActivated"); + context.startActivity(intent); + } catch (ActivityNotFoundException ex) { + Log.w(TAG, "No application can handle %s", intentUrl); + } + } /** * Check whether a key should be propagated to the embedder or not. @@ -59,10 +147,33 @@ } /** - * @see {@link #shouldPropagateKey(int) + * Returns the left system window inset in pixels. The system window inset represents the area + * of a full-screen window that is partially or fully obscured by the status bar, navigation + * bar, IME or other system windows. + * @return The left system window inset. */ - public boolean shouldOverrideKeyEvent(KeyEvent event) { - return !shouldPropagateKey(event.getKeyCode()); + public int getSystemWindowInsetLeft() { + return 0; + } + + /** + * Returns the top system window inset in pixels. The system window inset represents the area of + * a full-screen window that is partially or fully obscured by the status bar, navigation bar, + * IME or other system windows. + * @return The top system window inset. + */ + public int getSystemWindowInsetTop() { + return 0; + } + + /** + * Returns the right system window inset in pixels. The system window inset represents the area + * of a full-screen window that is partially or fully obscured by the status bar, navigation + * bar, IME or other system windows. + * @return The right system window inset. + */ + public int getSystemWindowInsetRight() { + return 0; } /**
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java index 16e8dfb..f8cbb86 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -819,6 +819,11 @@ return mContentViewClient; } + @CalledByNative + private void onBackgroundColorChanged(int color) { + getContentViewClient().onBackgroundColorChanged(color); + } + /** * @return Viewport width in physical pixels as set from onSizeChanged. */ @@ -1790,6 +1795,7 @@ float minPageScaleFactor, float maxPageScaleFactor, float contentWidth, float contentHeight, float viewportWidth, float viewportHeight, float browserControlsHeightDp, float browserControlsShownRatio, + float bottomControlsHeightDp, float bottomControlsShownRatio, boolean isMobileOptimizedHint, boolean hasInsertionMarker, boolean isInsertionMarkerVisible, float insertionMarkerHorizontal, float insertionMarkerTop, float insertionMarkerBottom) { @@ -1804,6 +1810,8 @@ mViewportHeightPix / (deviceScale * pageScaleFactor)); final float topBarShownPix = browserControlsHeightDp * deviceScale * browserControlsShownRatio; + final float bottomBarShownPix = bottomControlsHeightDp * deviceScale + * bottomControlsShownRatio; final boolean contentSizeChanged = contentWidth != mRenderCoordinates.getContentWidthCss() @@ -1819,6 +1827,8 @@ || scrollOffsetY != mRenderCoordinates.getScrollY(); final boolean topBarChanged = Float.compare(topBarShownPix, mRenderCoordinates.getContentOffsetYPix()) != 0; + final boolean bottomBarChanged = Float.compare(bottomBarShownPix, mRenderCoordinates + .getContentOffsetYPixBottom()) != 0; final boolean needHidePopupZoomer = contentSizeChanged || scrollChanged; @@ -1837,7 +1847,7 @@ contentWidth, contentHeight, viewportWidth, viewportHeight, pageScaleFactor, minPageScaleFactor, maxPageScaleFactor, - topBarShownPix); + topBarShownPix, bottomBarShownPix); if (scrollChanged || topBarChanged) { for (mGestureStateListenersIterator.rewind(); @@ -1856,6 +1866,15 @@ } } + if (topBarChanged) { + float topBarTranslate = topBarShownPix - browserControlsHeightDp * deviceScale; + getContentViewClient().onTopControlsChanged(topBarTranslate, topBarShownPix); + } + if (bottomBarChanged) { + float bottomBarTranslate = bottomControlsHeightDp * deviceScale - bottomBarShownPix; + getContentViewClient().onBottomControlsChanged(bottomBarTranslate, bottomBarShownPix); + } + if (mBrowserAccessibilityManager != null) { mBrowserAccessibilityManager.notifyFrameInfoInitialized(); } @@ -2275,6 +2294,11 @@ return mRenderCoordinates.getPageScaleFactor(); } + @CalledByNative + private void startContentIntent(String contentUrl, boolean isMainFrame) { + getContentViewClient().onStartContentIntent(getContext(), contentUrl, isMainFrame); + } + @Override public void onAccessibilityStateChanged(boolean enabled) { setAccessibilityState(enabled);
diff --git a/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java b/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java index d4bd795..fcce242 100644 --- a/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java +++ b/content/public/android/java/src/org/chromium/content/browser/RenderCoordinates.java
@@ -46,6 +46,7 @@ private float mWheelScrollFactor; private float mTopContentOffsetYPix; + private float mBottomContentOffsetYPix; private boolean mHasFrameInfo; @@ -86,13 +87,14 @@ float contentWidthCss, float contentHeightCss, float viewportWidthCss, float viewportHeightCss, float pageScaleFactor, float minPageScaleFactor, float maxPageScaleFactor, - float contentOffsetYPix) { + float contentOffsetYPix, float contentOffsetYPixBottom) { mScrollXCss = scrollXCss; mScrollYCss = scrollYCss; mPageScaleFactor = pageScaleFactor; mMinPageScaleFactor = minPageScaleFactor; mMaxPageScaleFactor = maxPageScaleFactor; mTopContentOffsetYPix = contentOffsetYPix; + mBottomContentOffsetYPix = contentOffsetYPixBottom; updateContentSizeCss(contentWidthCss, contentHeightCss); mLastFrameViewportWidthCss = viewportWidthCss; @@ -331,6 +333,13 @@ } /** + * @return The Physical on-screen Y offset amount below the bottom controls. + */ + public float getContentOffsetYPixBottom() { + return mBottomContentOffsetYPix; + } + + /** * @return Current page scale factor (maps CSS pixels to DIP pixels). */ public float getPageScaleFactor() {
diff --git a/content/public/android/java/src/org/chromium/content/browser/shapedetection/FaceDetectionImpl.java b/content/public/android/java/src/org/chromium/content/browser/shapedetection/FaceDetectionImpl.java index 50bc619..17ff5506 100644 --- a/content/public/android/java/src/org/chromium/content/browser/shapedetection/FaceDetectionImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/shapedetection/FaceDetectionImpl.java
@@ -12,10 +12,11 @@ import org.chromium.base.Log; import org.chromium.gfx.mojom.RectF; import org.chromium.mojo.system.MojoException; +import org.chromium.mojo.system.SharedBufferHandle; +import org.chromium.mojo.system.SharedBufferHandle.MapFlags; import org.chromium.shape_detection.mojom.FaceDetection; import org.chromium.shape_detection.mojom.FaceDetectionResult; import org.chromium.shape_detection.mojom.FaceDetectorOptions; -import org.chromium.skia.mojom.ColorType; import java.nio.ByteBuffer; @@ -35,42 +36,29 @@ } @Override - public void detect(org.chromium.skia.mojom.Bitmap bitmapData, DetectResponse callback) { - int width = bitmapData.width; - int height = bitmapData.height; + public void detect( + SharedBufferHandle frameData, int width, int height, DetectResponse callback) { final long numPixels = (long) width * height; // TODO(xianglu): https://crbug.com/670028 homogeneize overflow checking. - if (bitmapData.pixelData == null || width <= 0 || height <= 0 - || numPixels > (Long.MAX_VALUE / 4)) { + if (!frameData.isValid() || width <= 0 || height <= 0 || numPixels > (Long.MAX_VALUE / 4)) { Log.d(TAG, "Invalid argument(s)."); callback.call(new FaceDetectionResult()); return; } - // TODO(junwei.fu): Consider supporting other bitmap pixel formats, - // https://crbug.com/684921. - if (bitmapData.colorType != ColorType.RGBA_8888 - && bitmapData.colorType != ColorType.BGRA_8888) { - Log.e(TAG, "Unsupported bitmap pixel format"); - callback.call(new FaceDetectionResult()); - return; - } - - ByteBuffer imageBuffer = ByteBuffer.wrap(bitmapData.pixelData); + ByteBuffer imageBuffer = frameData.map(0, numPixels * 4, MapFlags.none()); if (imageBuffer.capacity() <= 0) { - Log.d(TAG, "Failed to wrap from Bitmap."); + Log.d(TAG, "Failed to map from SharedBufferHandle."); callback.call(new FaceDetectionResult()); return; } - // TODO(junwei.fu): Use |bitmapData| directly for |unPremultipliedBitmap| to spare a copy - // if the bitmap pixel format is RGB_565, the ARGB_8888 Bitmap doesn't need to be created - // in this case, https://crbug.com/684930. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); // An int array is needed to construct a Bitmap. However the Bytebuffer - // we get from |bitmapData| is directly allocated and does not have a supporting array. - // Therefore we need to copy from |imageBuffer| to create this intermediate Bitmap. + // we get from |sharedBufferHandle| is directly allocated and does not + // have a supporting array. Therefore we need to copy from |imageBuffer| + // to create this intermediate Bitmap. // TODO(xianglu): Consider worker pool as appropriate threads. // http://crbug.com/655814 bitmap.copyPixelsFromBuffer(imageBuffer);
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java index 9144b56..3ecf1a2 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java
@@ -6,15 +6,13 @@ import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; -import android.app.Activity; import android.net.Uri; -import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.UrlUtils; import org.chromium.content.browser.test.util.DOMUtils; import org.chromium.content.browser.test.util.TestCallbackHelperContainer; import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnPageFinishedHelper; -import org.chromium.content_shell.ShellViewAndroidDelegate.ContentIntentHandler; +import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnStartContentIntentHelper; import org.chromium.content_shell_apk.ContentShellTestBase; import java.util.concurrent.TimeUnit; @@ -27,41 +25,6 @@ private static final long WAIT_TIMEOUT_SECONDS = scaleTimeout(10); private TestCallbackHelperContainer mCallbackHelper; - private TestContentIntentHandler mContentIntentHandler; - - /** - * CallbackHelper for OnStartContentIntent. - */ - private static class OnStartContentIntentHelper extends CallbackHelper { - private String mIntentUrl; - public void notifyCalled(String intentUrl) { - mIntentUrl = intentUrl; - notifyCalled(); - } - public String getIntentUrl() { - assert getCallCount() > 0; - return mIntentUrl; - } - } - - /** - * ContentIntentHandler impl to test content detection. - */ - private static class TestContentIntentHandler implements ContentIntentHandler { - private OnStartContentIntentHelper mOnStartContentIntentHelper; - - public OnStartContentIntentHelper getOnStartContentIntentHelper() { - if (mOnStartContentIntentHelper == null) { - mOnStartContentIntentHelper = new OnStartContentIntentHelper(); - } - return mOnStartContentIntentHelper; - } - - @Override - public void onIntentUrlReceived(String intentUrl) { - mOnStartContentIntentHelper.notifyCalled(intentUrl); - } - } /** * Returns the TestCallbackHelperContainer associated with this ContentView, @@ -74,25 +37,12 @@ return mCallbackHelper; } - @Override - protected void setUp() throws Exception { - super.setUp(); - mContentIntentHandler = new TestContentIntentHandler(); - } - - @Override - protected void setActivity(Activity activity) { - super.setActivity(activity); - getActivity().getShellManager().getActiveShell().getViewAndroidDelegate() - .setContentIntentHandler(mContentIntentHandler); - } - /** * Encodes the provided content string into an escaped url as intents do. * @param content Content to escape into a url. * @return Escaped url. */ - protected static String urlForContent(String content) { + protected String urlForContent(String content) { return Uri.encode(content).replaceAll("%20", "+"); } @@ -112,8 +62,9 @@ * @return The content url of the received intent or null if none. */ protected String scrollAndTapExpectingIntent(String id) throws Throwable { + TestCallbackHelperContainer callbackHelperContainer = getTestCallbackHelperContainer(); OnStartContentIntentHelper onStartContentIntentHelper = - mContentIntentHandler.getOnStartContentIntentHelper(); + callbackHelperContainer.getOnStartContentIntentHelper(); int currentCallCount = onStartContentIntentHelper.getCallCount(); DOMUtils.clickNode(this, getContentViewCore(), id); @@ -142,4 +93,4 @@ TimeUnit.SECONDS); getInstrumentation().waitForIdleSync(); } -} \ No newline at end of file +}
diff --git a/content/public/test/android/BUILD.gn b/content/public/test/android/BUILD.gn index 2d1af8a..a2bd7c8 100644 --- a/content/public/test/android/BUILD.gn +++ b/content/public/test/android/BUILD.gn
@@ -38,6 +38,7 @@ "javatests/src/org/chromium/content/browser/test/util/KeyUtils.java", "javatests/src/org/chromium/content/browser/test/util/RenderProcessLimit.java", "javatests/src/org/chromium/content/browser/test/util/TestCallbackHelperContainer.java", + "javatests/src/org/chromium/content/browser/test/util/TestContentViewClient.java", "javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java", "javatests/src/org/chromium/content/browser/test/util/TestTouchUtils.java", "javatests/src/org/chromium/content/browser/test/util/TestWebContentsObserver.java",
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestCallbackHelperContainer.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestCallbackHelperContainer.java index 701106e..c06fa6c 100644 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestCallbackHelperContainer.java +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestCallbackHelperContainer.java
@@ -17,9 +17,12 @@ * This class is used to provide callback hooks for tests and related classes. */ public class TestCallbackHelperContainer { + private final TestContentViewClient mTestContentViewClient; private TestWebContentsObserver mTestWebContentsObserver; public TestCallbackHelperContainer(final ContentViewCore contentViewCore) { + mTestContentViewClient = new TestContentViewClient(); + contentViewCore.setContentViewClient(mTestContentViewClient); // TODO(yfriedman): Change callers to be executed on the UI thread. Unfortunately this is // super convenient as the caller is nearly always on the test thread which is fine to block // and it's cumbersome to keep bouncing to the UI thread. @@ -32,6 +35,12 @@ }); } + protected TestCallbackHelperContainer( + TestContentViewClient viewClient, TestWebContentsObserver contentsObserver) { + mTestContentViewClient = viewClient; + mTestWebContentsObserver = contentsObserver; + } + /** * CallbackHelper for OnPageCommitVisible. */ @@ -172,6 +181,21 @@ } } + /** + * CallbackHelper for OnStartContentIntent. + */ + public static class OnStartContentIntentHelper extends CallbackHelper { + private String mIntentUrl; + public void notifyCalled(String intentUrl) { + mIntentUrl = intentUrl; + notifyCalled(); + } + public String getIntentUrl() { + assert getCallCount() > 0; + return mIntentUrl; + } + } + public OnPageStartedHelper getOnPageStartedHelper() { return mTestWebContentsObserver.getOnPageStartedHelper(); } @@ -183,4 +207,8 @@ public OnReceivedErrorHelper getOnReceivedErrorHelper() { return mTestWebContentsObserver.getOnReceivedErrorHelper(); } + + public OnStartContentIntentHelper getOnStartContentIntentHelper() { + return mTestContentViewClient.getOnStartContentIntentHelper(); + } }
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestContentViewClient.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestContentViewClient.java new file mode 100644 index 0000000..7fda5207b --- /dev/null +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestContentViewClient.java
@@ -0,0 +1,41 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.content.browser.test.util; + +import android.content.Context; + +import org.chromium.content.browser.ContentViewClient; +import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnStartContentIntentHelper; + +/** + * The default ContentViewClient used by ContentView tests. + * <p> + * Tests that need to supply their own ContentViewClient should do that + * by extending this one. + */ +public class TestContentViewClient extends ContentViewClient { + + private final OnStartContentIntentHelper mOnStartContentIntentHelper; + + public TestContentViewClient() { + mOnStartContentIntentHelper = new OnStartContentIntentHelper(); + } + + public OnStartContentIntentHelper getOnStartContentIntentHelper() { + return mOnStartContentIntentHelper; + } + + /** + * ATTENTION!: When overriding the following method, be sure to call + * the corresponding method in the super class. Otherwise + * {@link CallbackHelper#waitForCallback()} methods will + * stop working! + */ + + @Override + public void onStartContentIntent(Context context, String contentUrl, boolean isMainFrame) { + mOnStartContentIntentHelper.notifyCalled(contentUrl); + } +}
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn index 278ab5f..3eed8d5 100644 --- a/content/shell/android/BUILD.gn +++ b/content/shell/android/BUILD.gn
@@ -55,7 +55,6 @@ "java/src/org/chromium/content_shell/Shell.java", "java/src/org/chromium/content_shell/ShellLayoutTestUtils.java", "java/src/org/chromium/content_shell/ShellManager.java", - "java/src/org/chromium/content_shell/ShellViewAndroidDelegate.java", ] }
diff --git a/content/shell/android/java/src/org/chromium/content_shell/Shell.java b/content/shell/android/java/src/org/chromium/content_shell/Shell.java index 6215bf40..e2f82e34 100644 --- a/content/shell/android/java/src/org/chromium/content_shell/Shell.java +++ b/content/shell/android/java/src/org/chromium/content_shell/Shell.java
@@ -36,6 +36,7 @@ import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.WebContents; +import org.chromium.ui.base.ViewAndroidDelegate; import org.chromium.ui.base.WindowAndroid; /** @@ -67,7 +68,6 @@ private long mNativeShell; private ContentViewRenderView mContentViewRenderView; private WindowAndroid mWindow; - private ShellViewAndroidDelegate mViewAndroidDelegate; private boolean mLoading; private boolean mIsFullscreen; @@ -286,10 +286,6 @@ } } - public ShellViewAndroidDelegate getViewAndroidDelegate() { - return mViewAndroidDelegate; - } - /** * Initializes the ContentView based on the native tab contents pointer passed in. * @param webContents A {@link WebContents} object. @@ -300,8 +296,8 @@ Context context = getContext(); mContentViewCore = new ContentViewCore(context, ""); ContentView cv = ContentView.createContentView(context, mContentViewCore); - mViewAndroidDelegate = new ShellViewAndroidDelegate(cv); - mContentViewCore.initialize(mViewAndroidDelegate, cv, webContents, mWindow); + mContentViewCore.initialize(ViewAndroidDelegate.createBasicDelegate(cv), cv, + webContents, mWindow); mContentViewCore.setActionModeCallback(defaultActionCallback()); mContentViewCore.setContentViewClient(mContentViewClient); mWebContents = mContentViewCore.getWebContents();
diff --git a/content/shell/android/java/src/org/chromium/content_shell/ShellViewAndroidDelegate.java b/content/shell/android/java/src/org/chromium/content_shell/ShellViewAndroidDelegate.java deleted file mode 100644 index b1102b3..0000000 --- a/content/shell/android/java/src/org/chromium/content_shell/ShellViewAndroidDelegate.java +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.content_shell; - -import android.content.Intent; -import android.view.ViewGroup; - -import org.chromium.ui.base.ViewAndroidDelegate; - -/** - * Implementation of the abstract class {@link ViewAndroidDelegate} for content shell. - * Extended for testing. - */ -public class ShellViewAndroidDelegate extends ViewAndroidDelegate { - private final ViewGroup mContainerView; - private ContentIntentHandler mContentIntentHandler; - - /** - * Interface used to define/modify what {@link #startContentIntent} does. - */ - public interface ContentIntentHandler { - /** - * Called when intent url from content is received. - * @param intentUrl intent url. - */ - void onIntentUrlReceived(String intentUrl); - } - - public ShellViewAndroidDelegate(ViewGroup containerView) { - mContainerView = containerView; - } - - /** - * Set the {@link ContentIntentHandler} for {@link #starContentIntent}. - * @param handler Handler to inject to {@link #startContentIntent}. - */ - public void setContentIntentHandler(ContentIntentHandler handler) { - mContentIntentHandler = handler; - } - - @Override - public void startContentIntent(Intent intent, String intentUrl, boolean isMainFrame) { - if (mContentIntentHandler != null) mContentIntentHandler.onIntentUrlReceived(intentUrl); - } - - @Override - public ViewGroup getContainerView() { - return mContainerView; - } -}
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py index 2bc0e42..640c34e 100755 --- a/content/test/gpu/generate_buildbot_json.py +++ b/content/test/gpu/generate_buildbot_json.py
@@ -1258,6 +1258,8 @@ ], 'test': 'gles2_conform_test', }, + # Face and barcode detection unit tests, which currently only run on + # Mac OS, and require physical hardware. 'service_unittests': { 'tester_configs': [ { @@ -1266,6 +1268,16 @@ 'os_types': ['mac'], }, ], + 'disabled_tester_configs': [ + { + 'swarming_dimension_sets': [ + # These tests fail on the Mac Pros. + { + 'gpu': '1002:679e', + }, + ], + }, + ], 'args': [ '--gtest_filter=*Detection*', '--use-gpu-in-tests'
diff --git a/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.h b/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.h deleted file mode 100644 index 1581cd19..0000000 --- a/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.h +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef DEVICE_TIME_ZONE_MONITOR_ANDROID_TIME_ZONE_MONITOR_JNI_REGISTRAR_H_ -#define DEVICE_TIME_ZONE_MONITOR_ANDROID_TIME_ZONE_MONITOR_JNI_REGISTRAR_H_ - -#include <jni.h> - -#include "device/time_zone_monitor/time_zone_monitor_export.h" - -namespace device { -namespace android { - -bool DEVICE_TIME_ZONE_MONITOR_EXPORT RegisterTimeZoneMonitorJni(JNIEnv* env); - -} // namespace android -} // namespace device - -#endif // DEVICE_TIME_ZONE_MONITOR_ANDROID_TIME_ZONE_MONITOR_JNI_REGISTRAR_H_
diff --git a/device/time_zone_monitor/public/interfaces/BUILD.gn b/device/time_zone_monitor/public/interfaces/BUILD.gn deleted file mode 100644 index 52ca0ce..0000000 --- a/device/time_zone_monitor/public/interfaces/BUILD.gn +++ /dev/null
@@ -1,11 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import("//mojo/public/tools/bindings/mojom.gni") - -mojom("interfaces") { - sources = [ - "time_zone_monitor.mojom", - ] -}
diff --git a/device/time_zone_monitor/public/interfaces/OWNERS b/device/time_zone_monitor/public/interfaces/OWNERS deleted file mode 100644 index 5e4aaef..0000000 --- a/device/time_zone_monitor/public/interfaces/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -# Changes to Mojo interfaces require a security review to avoid -# introducing new sandbox escapes. -per-file *.mojom=set noparent -per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/device/time_zone_monitor/time_zone_monitor_export.h b/device/time_zone_monitor/time_zone_monitor_export.h deleted file mode 100644 index 7889326..0000000 --- a/device/time_zone_monitor/time_zone_monitor_export.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef DEVICE_TIME_ZONE_MONITOR_DEVICE_TIME_ZONE_MONITOR_EXPORT_H_ -#define DEVICE_TIME_ZONE_MONITOR_DEVICE_TIME_ZONE_MONITOR_EXPORT_H_ - -#if defined(COMPONENT_BUILD) -#if defined(WIN32) - -#if defined(DEVICE_TIME_ZONE_MONITOR_IMPLEMENTATION) -#define DEVICE_TIME_ZONE_MONITOR_EXPORT __declspec(dllexport) -#else -#define DEVICE_TIME_ZONE_MONITOR_EXPORT __declspec(dllimport) -#endif // defined(DEVICE_TIME_ZONE_MONITOR_IMPLEMENTATION) - -#else // defined(WIN32) -#if defined(DEVICE_TIME_ZONE_MONITOR_IMPLEMENTATION) -#define DEVICE_TIME_ZONE_MONITOR_EXPORT __attribute__((visibility("default"))) -#else -#define DEVICE_TIME_ZONE_MONITOR_EXPORT -#endif -#endif - -#else // defined(COMPONENT_BUILD) -#define DEVICE_TIME_ZONE_MONITOR_EXPORT -#endif - -#endif // DEVICE_TIME_ZONE_MONITOR_DEVICE_TIME_ZONE_MONITOR_EXPORT_H_
diff --git a/extensions/browser/api/cast_channel/cast_channel_api.cc b/extensions/browser/api/cast_channel/cast_channel_api.cc index 29e111c..4355e0e 100644 --- a/extensions/browser/api/cast_channel/cast_channel_api.cc +++ b/extensions/browser/api/cast_channel/cast_channel_api.cc
@@ -11,6 +11,7 @@ #include <memory> #include <string> #include <utility> +#include <vector> #include "base/json/json_writer.h" #include "base/lazy_instance.h"
diff --git a/extensions/browser/api/cast_channel/cast_message_util.cc b/extensions/browser/api/cast_channel/cast_message_util.cc index 3726efd..7cdf1c5 100644 --- a/extensions/browser/api/cast_channel/cast_message_util.cc +++ b/extensions/browser/api/cast_channel/cast_message_util.cc
@@ -37,7 +37,6 @@ // Determine the type of the base::Value and set the message payload // appropriately. std::string data; - base::BinaryValue* real_value; switch (message.data->GetType()) { // JS string case base::Value::Type::STRING: @@ -48,12 +47,9 @@ break; // JS ArrayBuffer case base::Value::Type::BINARY: - real_value = static_cast<base::BinaryValue*>(message.data.get()); - if (real_value->GetBuffer()) { - message_proto->set_payload_type(CastMessage_PayloadType_BINARY); - message_proto->set_payload_binary(real_value->GetBuffer(), - real_value->GetSize()); - } + message_proto->set_payload_type(CastMessage_PayloadType_BINARY); + message_proto->set_payload_binary(message.data->GetBuffer(), + message.data->GetSize()); break; default: // Unknown value type. message_proto will remain uninitialized because
diff --git a/extensions/browser/api/socket/socket_api.cc b/extensions/browser/api/socket/socket_api.cc index cbc8019..8a8f484 100644 --- a/extensions/browser/api/socket/socket_api.cc +++ b/extensions/browser/api/socket/socket_api.cc
@@ -523,7 +523,7 @@ base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(), bytes_read)); } else { - result->Set(kDataKey, new base::BinaryValue()); + result->Set(kDataKey, new base::Value(base::Value::Type::BINARY)); } SetResult(std::move(result)); @@ -601,7 +601,7 @@ base::BinaryValue::CreateWithCopiedBuffer(io_buffer->data(), bytes_read)); } else { - result->Set(kDataKey, new base::BinaryValue()); + result->Set(kDataKey, new base::Value(base::Value::Type::BINARY)); } result->SetString(kAddressKey, address); result->SetInteger(kPortKey, port);
diff --git a/extensions/browser/api/usb/usb_api.cc b/extensions/browser/api/usb/usb_api.cc index d0373f9..e8f0a8a 100644 --- a/extensions/browser/api/usb/usb_api.cc +++ b/extensions/browser/api/usb/usb_api.cc
@@ -468,7 +468,7 @@ transfer_info->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer( data->data(), length)); } else { - transfer_info->Set(kDataKey, new base::BinaryValue()); + transfer_info->Set(kDataKey, new base::Value(base::Value::Type::BINARY)); } if (status == device::USB_TRANSFER_COMPLETED) { @@ -1241,8 +1241,8 @@ std::unique_ptr<base::DictionaryValue> transfer_info( new base::DictionaryValue()); transfer_info->SetInteger(kResultCodeKey, status); - transfer_info->Set(kDataKey, - new base::BinaryValue(std::move(buffer), length)); + transfer_info->Set(kDataKey, new base::BinaryValue(std::vector<char>( + buffer.get(), buffer.get() + length))); if (status == device::USB_TRANSFER_COMPLETED) { Respond(OneArgument(std::move(transfer_info))); } else {
diff --git a/extensions/renderer/argument_spec_unittest.cc b/extensions/renderer/argument_spec_unittest.cc index 45de50c..4b94b84 100644 --- a/extensions/renderer/argument_spec_unittest.cc +++ b/extensions/renderer/argument_spec_unittest.cc
@@ -262,7 +262,8 @@ const char kBinarySpec[] = "{ 'type': 'binary' }"; ArgumentSpec spec(*ValueFromString(kBinarySpec)); // Simple case: empty ArrayBuffer -> empty BinaryValue. - ExpectSuccess(spec, "(new ArrayBuffer())", base::BinaryValue()); + ExpectSuccess(spec, "(new ArrayBuffer())", + base::Value(base::Value::Type::BINARY)); { // A non-empty (but zero-filled) ArrayBufferView. const char kBuffer[] = {0, 0, 0, 0};
diff --git a/gpu/config/software_rendering_list_json.cc b/gpu/config/software_rendering_list_json.cc index b9786b0..293566a 100644 --- a/gpu/config/software_rendering_list_json.cc +++ b/gpu/config/software_rendering_list_json.cc
@@ -18,7 +18,7 @@ { "name": "software rendering list", // Please update the version number whenever you change this file. - "version": "12.12", + "version": "12.13", "entries": [ { "id": 1, @@ -1070,6 +1070,7 @@ }, "vendor_id": "0x8086", "device_id": ["0x0116", "0x0126"], + "multi_gpu_category": "any", "features": [ "all" ] @@ -1441,6 +1442,7 @@ }, "vendor_id": "0x10de", "device_id": ["0x0407", "0x0647", "0x0863"], + "multi_gpu_category": "any", "features": [ "all" ]
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm index 8d01bd16..8e017f53 100644 --- a/ios/chrome/browser/tabs/tab.mm +++ b/ios/chrome/browser/tabs/tab.mm
@@ -132,6 +132,7 @@ #include "ios/web/public/interstitials/web_interstitial.h" #import "ios/web/public/navigation_manager.h" #include "ios/web/public/referrer.h" +#import "ios/web/public/serializable_user_data_manager.h" #include "ios/web/public/ssl_status.h" #include "ios/web/public/url_scheme_util.h" #include "ios/web/public/url_util.h" @@ -175,6 +176,10 @@ class FaviconDriverObserverBridge; class TabInfoBarObserver; +// The key under which the Tab ID is stored in the WebState's serializable user +// data. +NSString* const kTabIDKey = @"TabID"; + // Name of histogram for recording the state of the tab when the renderer is // terminated. const char kRendererTerminationStateHistogram[] = @@ -780,8 +785,15 @@ } - (NSString*)tabId { - DCHECK([self navigationManager]); - return [[self navigationManager]->GetSessionController() tabId]; + DCHECK(self.webState); + web::SerializableUserDataManager* userDataManager = + web::SerializableUserDataManager::FromWebState(self.webState); + id<NSCoding> tabID = userDataManager->GetValueForSerializationKey(kTabIDKey); + if (!tabID) { + tabID = [[NSUUID UUID] UUIDString]; + userDataManager->AddSerializableData(tabID, kTabIDKey); + } + return base::mac::ObjCCastStrict<NSString>(tabID); } - (web::WebState*)webState {
diff --git a/ios/web/navigation/crw_session_controller.h b/ios/web/navigation/crw_session_controller.h index 19e8f8a9..d2ef342 100644 --- a/ios/web/navigation/crw_session_controller.h +++ b/ios/web/navigation/crw_session_controller.h
@@ -30,7 +30,6 @@ // TODO(crbug.com/454984): Remove this class. @interface CRWSessionController : NSObject<NSCopying> -@property(nonatomic, readonly, copy) NSString* tabId; @property(nonatomic, readonly, assign) NSInteger currentNavigationIndex; @property(nonatomic, readonly, assign) NSInteger previousNavigationIndex; // The index of the pending item if it is in |items|, or -1 if |pendingItem|
diff --git a/ios/web/navigation/crw_session_controller.mm b/ios/web/navigation/crw_session_controller.mm index aa98921e..2afdc55 100644 --- a/ios/web/navigation/crw_session_controller.mm +++ b/ios/web/navigation/crw_session_controller.mm
@@ -37,7 +37,6 @@ // the incremental merging of the two classes. web::NavigationManagerImpl* _navigationManager; - NSString* _tabId; // Unique id of the tab. NSString* _openerId; // Id of tab who opened this tab, empty/nil if none. // Navigation index of the tab which opened this tab. Do not rely on the // value of this member variable to indicate whether or not this tab has @@ -92,7 +91,6 @@ // TODO(rohitrao): These properties must be redefined readwrite to work around a // clang bug. crbug.com/228650 -@property(nonatomic, readwrite, copy) NSString* tabId; @property(nonatomic, readwrite, strong) NSArray* entries; @property(nonatomic, readwrite, strong) CRWSessionCertificatePolicyManager* sessionCertificatePolicyManager; @@ -105,7 +103,6 @@ @property(nonatomic, readwrite, assign) NSInteger openerNavigationIndex; @property(nonatomic, readwrite, assign) NSInteger previousNavigationIndex; -- (NSString*)uniqueID; // Removes all entries after currentNavigationIndex_. - (void)clearForwardItems; // Discards the transient entry, if any. @@ -125,7 +122,6 @@ @implementation CRWSessionController -@synthesize tabId = _tabId; @synthesize currentNavigationIndex = _currentNavigationIndex; @synthesize previousNavigationIndex = _previousNavigationIndex; @synthesize pendingItemIndex = _pendingItemIndex; @@ -145,7 +141,6 @@ self = [super init]; if (self) { self.windowName = windowName; - _tabId = [[self uniqueID] copy]; _openerId = [openerId copy]; _openedByDOM = openedByDOM; _openerNavigationIndex = openerIndex; @@ -167,7 +162,6 @@ browserState:(web::BrowserState*)browserState { self = [super init]; if (self) { - _tabId = [[self uniqueID] copy]; _openerId = nil; _browserState = browserState; @@ -197,7 +191,6 @@ - (id)copyWithZone:(NSZone*)zone { CRWSessionController* copy = [[[self class] alloc] init]; - copy->_tabId = [_tabId copy]; copy->_openerId = [_openerId copy]; copy->_openedByDOM = _openedByDOM; copy->_openerNavigationIndex = _openerNavigationIndex; @@ -251,13 +244,14 @@ - (NSString*)description { return [NSString - stringWithFormat: - @"id: %@\nname: %@\nlast visit: %f\ncurrent index: %" PRIdNS - @"\nprevious index: %" PRIdNS @"\npending index: %" PRIdNS - @"\n%@\npending: %@\ntransient: %@\n", - _tabId, self.windowName, _lastVisitedTimestamp, - _currentNavigationIndex, _previousNavigationIndex, _pendingItemIndex, - _entries, _pendingEntry.get(), _transientEntry.get()]; + stringWithFormat:@"name: %@\nlast visit: %f\ncurrent index: %" PRIdNS + @"\nprevious index: %" PRIdNS + @"\npending index: %" PRIdNS + @"\n%@\npending: %@\ntransient: %@\n", + self.windowName, _lastVisitedTimestamp, + _currentNavigationIndex, _previousNavigationIndex, + _pendingItemIndex, _entries, _pendingEntry.get(), + _transientEntry.get()]; } - (web::NavigationItemList)items { @@ -698,17 +692,6 @@ #pragma mark - #pragma mark Private methods -- (NSString*)uniqueID { - CFUUIDRef uuidRef = CFUUIDCreate(NULL); - CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef); - CFRelease(uuidRef); - - NSString* uuid = - [NSString stringWithString:base::mac::ObjCCastStrict<NSString>( - CFBridgingRelease(uuidStringRef))]; - return uuid; -} - - (CRWSessionEntry*)sessionEntryWithURL:(const GURL&)url referrer:(const web::Referrer&)referrer transition:(ui::PageTransition)transition
diff --git a/ios/web/navigation/serializable_user_data_manager_impl.h b/ios/web/navigation/serializable_user_data_manager_impl.h index 38fa1fb1..f29dc1f 100644 --- a/ios/web/navigation/serializable_user_data_manager_impl.h +++ b/ios/web/navigation/serializable_user_data_manager_impl.h
@@ -26,9 +26,20 @@ NSDictionary* data() { return data_; }; private: + // Decodes the values that were previously encoded using CRWSessionStorage's + // NSCoding implementation and returns an NSDictionary using the new + // serialization keys. + // TODO(crbug.com/691800): Remove legacy support. + NSDictionary* GetDecodedLegacyValues(NSCoder* coder); + // The dictionary passed on initialization. After calling Decode(), this will // contain the data that is decoded from the NSCoder. base::scoped_nsobject<NSDictionary> data_; + // Some values that were previously persisted directly in CRWSessionStorage + // are now serialized using SerializableUserData, and this dictionary is used + // to decode these values. The keys are the legacy encoding keys, and the + // values are their corresponding serializable user data keys. + base::scoped_nsobject<NSDictionary> legacy_key_conversions_; }; class SerializableUserDataManagerImpl : public SerializableUserDataManager {
diff --git a/ios/web/navigation/serializable_user_data_manager_impl.mm b/ios/web/navigation/serializable_user_data_manager_impl.mm index e3dd717..b35e6f7 100644 --- a/ios/web/navigation/serializable_user_data_manager_impl.mm +++ b/ios/web/navigation/serializable_user_data_manager_impl.mm
@@ -59,7 +59,8 @@ } SerializableUserDataImpl::SerializableUserDataImpl() - : data_([[NSDictionary alloc] init]) {} + : data_([[NSDictionary alloc] init]), + legacy_key_conversions_(@{@"tabId" : @"TabID"}) {} SerializableUserDataImpl::~SerializableUserDataImpl() {} @@ -71,9 +72,20 @@ } void SerializableUserDataImpl::Decode(NSCoder* coder) { - NSDictionary* data = base::mac::ObjCCastStrict<NSDictionary>( - [coder decodeObjectForKey:kSerializedUserDataKey]); - data_.reset([data mutableCopy]); + NSMutableDictionary* data = + [[coder decodeObjectForKey:kSerializedUserDataKey] mutableCopy]; + [data addEntriesFromDictionary:GetDecodedLegacyValues(coder)]; + data_.reset([data copy]); +} + +NSDictionary* SerializableUserDataImpl::GetDecodedLegacyValues(NSCoder* coder) { + NSMutableDictionary* legacy_values = [[NSMutableDictionary alloc] init]; + for (NSString* legacy_key in [legacy_key_conversions_ allKeys]) { + id<NSCoding> value = [coder decodeObjectForKey:legacy_key]; + NSString* new_key = [legacy_key_conversions_ objectForKey:legacy_key]; + legacy_values[new_key] = value; + } + return legacy_values; } // static
diff --git a/ios/web/navigation/session_storage_builder.mm b/ios/web/navigation/session_storage_builder.mm index ca9c3b1..e2dcc432 100644 --- a/ios/web/navigation/session_storage_builder.mm +++ b/ios/web/navigation/session_storage_builder.mm
@@ -42,7 +42,6 @@ [[CRWSessionStorage alloc] init]; CRWSessionController* session_controller = navigation_manager->GetSessionController(); - serialized_navigation_manager.tabID = session_controller.tabId; serialized_navigation_manager.openerID = session_controller.openerId; serialized_navigation_manager.openedByDOM = session_controller.openedByDOM; serialized_navigation_manager.openerNavigationIndex = @@ -89,7 +88,6 @@ [[CRWSessionController alloc] initWithNavigationItems:std::move(items) currentIndex:current_index browserState:nullptr]); - [session_controller setTabId:storage.tabID]; [session_controller setOpenerId:storage.openerID]; [session_controller setOpenedByDOM:storage.openedByDOM]; [session_controller setOpenerNavigationIndex:storage.openerNavigationIndex];
diff --git a/ios/web/public/crw_session_storage.h b/ios/web/public/crw_session_storage.h index fa74465..97d6948 100644 --- a/ios/web/public/crw_session_storage.h +++ b/ios/web/public/crw_session_storage.h
@@ -18,7 +18,6 @@ // TODO(crbug.com/685388): Investigate using code from the sessions component. @interface CRWSessionStorage : NSObject<NSCoding> -@property(nonatomic, copy) NSString* tabID; @property(nonatomic, copy) NSString* openerID; @property(nonatomic, getter=isOpenedByDOM) BOOL openedByDOM; @property(nonatomic, assign) NSInteger openerNavigationIndex;
diff --git a/ios/web/public/crw_session_storage.mm b/ios/web/public/crw_session_storage.mm index 7351a852..8c5b2254 100644 --- a/ios/web/public/crw_session_storage.mm +++ b/ios/web/public/crw_session_storage.mm
@@ -21,7 +21,6 @@ NSString* const kOpenedByDOMKey = @"openedByDOM"; NSString* const kOpenerNavigationIndexKey = @"openerNavigationIndex"; NSString* const kPreviousNavigationIndexKey = @"previousNavigationIndex"; -NSString* const kTabIDKey = @"tabId"; NSString* const kWindowNameKey = @"windowName"; } @@ -34,7 +33,6 @@ @implementation CRWSessionStorage -@synthesize tabID = _tabID; @synthesize openerID = _openerID; @synthesize openedByDOM = _openedByDOM; @synthesize openerNavigationIndex = _openerNavigationIndex; @@ -61,7 +59,6 @@ - (instancetype)initWithCoder:(nonnull NSCoder*)decoder { self = [super init]; if (self) { - _tabID = [[decoder decodeObjectForKey:kTabIDKey] copy]; _windowName = [[decoder decodeObjectForKey:kWindowNameKey] copy]; _openerID = [[decoder decodeObjectForKey:kOpenerIDKey] copy]; _openedByDOM = [decoder decodeBoolForKey:kOpenedByDOMKey]; @@ -91,7 +88,6 @@ } - (void)encodeWithCoder:(NSCoder*)coder { - [coder encodeObject:self.tabID forKey:kTabIDKey]; [coder encodeObject:self.openerID forKey:kOpenerIDKey]; [coder encodeBool:self.openedByDOM forKey:kOpenedByDOMKey]; [coder encodeInt:self.openerNavigationIndex forKey:kOpenerNavigationIndexKey];
diff --git a/ipc/ipc_message_utils.cc b/ipc/ipc_message_utils.cc index fb45218b..e7d8747 100644 --- a/ipc/ipc_message_utils.cc +++ b/ipc/ipc_message_utils.cc
@@ -110,9 +110,7 @@ break; } case base::Value::Type::BINARY: { - const base::BinaryValue* binary = - static_cast<const base::BinaryValue*>(value); - sizer->AddData(static_cast<int>(binary->GetSize())); + sizer->AddData(static_cast<int>(value->GetSize())); break; } case base::Value::Type::DICTIONARY: { @@ -180,9 +178,7 @@ break; } case base::Value::Type::BINARY: { - const base::BinaryValue* binary = - static_cast<const base::BinaryValue*>(value); - m->WriteData(binary->GetBuffer(), static_cast<int>(binary->GetSize())); + m->WriteData(value->GetBuffer(), static_cast<int>(value->GetSize())); break; } case base::Value::Type::DICTIONARY: {
diff --git a/media/base/android/media_drm_bridge.h b/media/base/android/media_drm_bridge.h index dbb868b7..6daa240 100644 --- a/media/base/android/media_drm_bridge.h +++ b/media/base/android/media_drm_bridge.h
@@ -17,6 +17,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/sequenced_task_runner_helpers.h" #include "media/base/android/media_drm_bridge_cdm_context.h" #include "media/base/cdm_promise.h" #include "media/base/cdm_promise_adapter.h"
diff --git a/media/base/video_frame_metadata.cc b/media/base/video_frame_metadata.cc index 3bc1086..0ce0b2cd 100644 --- a/media/base/video_frame_metadata.cc +++ b/media/base/video_frame_metadata.cc
@@ -171,7 +171,7 @@ if (dictionary_.GetWithoutPathExpansion(ToInternalKey(key), &internal_value) && internal_value->GetType() == base::Value::Type::BINARY) { - return static_cast<const base::BinaryValue*>(internal_value); + return internal_value; } return nullptr; }
diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc index dea106b..cb1bed9 100644 --- a/media/gpu/video_decode_accelerator_unittest.cc +++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -821,10 +821,7 @@ // Flush decoder after all BitstreamBuffers are processed. if (encoded_data_next_pos_to_decode_ == encoded_data_.size()) { - // TODO(owenlin): We should not have to check the number of - // |outstanding_decodes_|. |decoder_| should be able to accept Flush() - // before it's done with outstanding decodes. (crbug.com/528183) - if (outstanding_decodes_ == 0) { + if (state_ != CS_FLUSHING) { decoder_->Flush(); SetState(CS_FLUSHING); }
diff --git a/mojo/public/cpp/bindings/BUILD.gn b/mojo/public/cpp/bindings/BUILD.gn index c831ada..cbc20046 100644 --- a/mojo/public/cpp/bindings/BUILD.gn +++ b/mojo/public/cpp/bindings/BUILD.gn
@@ -124,6 +124,7 @@ "pipe_control_message_handler.h", "pipe_control_message_handler_delegate.h", "pipe_control_message_proxy.h", + "raw_ptr_impl_ref_traits.h", "scoped_interface_endpoint_handle.h", "string_data_view.h", "string_traits.h", @@ -132,6 +133,7 @@ "string_traits_string_piece.h", "strong_associated_binding.h", "strong_binding.h", + "strong_binding_set.h", "struct_ptr.h", "sync_call_restrictions.h", "sync_handle_registry.h", @@ -139,6 +141,7 @@ "thread_safe_interface_ptr.h", "type_converter.h", "union_traits.h", + "unique_ptr_impl_ref_traits.h", ] public_deps = [
diff --git a/mojo/public/cpp/bindings/associated_binding_set.h b/mojo/public/cpp/bindings/associated_binding_set.h index 34ab88d6e..59600c6 100644 --- a/mojo/public/cpp/bindings/associated_binding_set.h +++ b/mojo/public/cpp/bindings/associated_binding_set.h
@@ -12,10 +12,12 @@ namespace mojo { -template <typename Interface> -struct BindingSetTraits<AssociatedBinding<Interface>> { +template <typename Interface, typename ImplRefTraits> +struct BindingSetTraits<AssociatedBinding<Interface, ImplRefTraits>> { using ProxyType = AssociatedInterfacePtr<Interface>; using RequestType = AssociatedInterfaceRequest<Interface>; + using BindingType = AssociatedBinding<Interface, ImplRefTraits>; + using ImplPointerType = typename BindingType::ImplPointerType; }; template <typename Interface, typename ContextType = void>
diff --git a/mojo/public/cpp/bindings/binding_set.h b/mojo/public/cpp/bindings/binding_set.h index 5156995..919f9c0 100644 --- a/mojo/public/cpp/bindings/binding_set.h +++ b/mojo/public/cpp/bindings/binding_set.h
@@ -23,10 +23,12 @@ template <typename BindingType> struct BindingSetTraits; -template <typename Interface> -struct BindingSetTraits<Binding<Interface>> { +template <typename Interface, typename ImplRefTraits> +struct BindingSetTraits<Binding<Interface, ImplRefTraits>> { using ProxyType = InterfacePtr<Interface>; using RequestType = InterfaceRequest<Interface>; + using BindingType = Binding<Interface, ImplRefTraits>; + using ImplPointerType = typename BindingType::ImplPointerType; static RequestType MakeRequest(ProxyType* proxy) { return mojo::MakeRequest(proxy); @@ -67,6 +69,7 @@ using Traits = BindingSetTraits<BindingType>; using ProxyType = typename Traits::ProxyType; using RequestType = typename Traits::RequestType; + using ImplPointerType = typename Traits::ImplPointerType; BindingSetBase() {} @@ -92,17 +95,20 @@ // Adds a new binding to the set which binds |request| to |impl| with no // additional context. - BindingId AddBinding(Interface* impl, RequestType request) { + BindingId AddBinding(ImplPointerType impl, RequestType request) { static_assert(!ContextTraits::SupportsContext(), "Context value required for non-void context type."); - return AddBindingImpl(impl, std::move(request), false); + return AddBindingImpl(std::move(impl), std::move(request), false); } // Adds a new binding associated with |context|. - BindingId AddBinding(Interface* impl, RequestType request, Context context) { + BindingId AddBinding(ImplPointerType impl, + RequestType request, + Context context) { static_assert(ContextTraits::SupportsContext(), "Context value unsupported for void context type."); - return AddBindingImpl(impl, std::move(request), std::move(context)); + return AddBindingImpl(std::move(impl), std::move(request), + std::move(context)); } // Removes a binding from the set. Note that this is safe to call even if the @@ -120,10 +126,10 @@ // Returns a proxy bound to one end of a pipe whose other end is bound to // |this|. If |id_storage| is not null, |*id_storage| will be set to the ID // of the added binding. - ProxyType CreateInterfacePtrAndBind(Interface* impl, + ProxyType CreateInterfacePtrAndBind(ImplPointerType impl, BindingId* id_storage = nullptr) { ProxyType proxy; - BindingId id = AddBinding(impl, Traits::MakeRequest(&proxy)); + BindingId id = AddBinding(std::move(impl), Traits::MakeRequest(&proxy)); if (id_storage) *id_storage = id; return proxy; @@ -154,12 +160,12 @@ class Entry { public: - Entry(Interface* impl, + Entry(ImplPointerType impl, RequestType request, BindingSetBase* binding_set, BindingId binding_id, Context context) - : binding_(impl, std::move(request)), + : binding_(std::move(impl), std::move(request)), binding_set_(binding_set), binding_id_(binding_id), context_(std::move(context)) { @@ -216,13 +222,13 @@ pre_dispatch_handler_.Run(*context); } - BindingId AddBindingImpl(Interface* impl, + BindingId AddBindingImpl(ImplPointerType impl, RequestType request, Context context) { BindingId id = next_binding_id_++; DCHECK_GE(next_binding_id_, 0u); - auto entry = base::MakeUnique<Entry>( - impl, std::move(request), this, id, std::move(context)); + auto entry = base::MakeUnique<Entry>(std::move(impl), std::move(request), + this, id, std::move(context)); bindings_.insert(std::make_pair(id, std::move(entry))); return id; }
diff --git a/mojo/public/cpp/bindings/strong_binding_set.h b/mojo/public/cpp/bindings/strong_binding_set.h new file mode 100644 index 0000000..f6bcd52 --- /dev/null +++ b/mojo/public/cpp/bindings/strong_binding_set.h
@@ -0,0 +1,26 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_SET_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_SET_H_ + +#include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/bindings/unique_ptr_impl_ref_traits.h" + +namespace mojo { + +// This class manages a set of bindings. When the pipe a binding is bound to is +// disconnected, the binding is automatically destroyed and removed from the +// set, and the interface implementation is deleted. When the StrongBindingSet +// is destructed, all outstanding bindings in the set are destroyed and all the +// bound interface implementations are automatically deleted. +template <typename Interface, typename ContextType = void> +using StrongBindingSet = + BindingSetBase<Interface, + Binding<Interface, UniquePtrImplRefTraits<Interface>>, + ContextType>; + +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_STRONG_BINDING_SET_H_
diff --git a/mojo/public/cpp/bindings/tests/binding_set_unittest.cc b/mojo/public/cpp/bindings/tests/binding_set_unittest.cc index 790671a..b7f55b1a 100644 --- a/mojo/public/cpp/bindings/tests/binding_set_unittest.cc +++ b/mojo/public/cpp/bindings/tests/binding_set_unittest.cc
@@ -9,6 +9,7 @@ #include "base/run_loop.h" #include "mojo/public/cpp/bindings/associated_binding_set.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/bindings/strong_binding_set.h" #include "mojo/public/interfaces/bindings/tests/ping_service.mojom.h" #include "mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom.h" #include "testing/gtest/include/gtest/gtest.h" @@ -349,6 +350,67 @@ run_loop.Run(); } +class PingInstanceCounter : public PingService { + public: + PingInstanceCounter() { ++instance_count; } + ~PingInstanceCounter() override { --instance_count; } + + void Ping(const PingCallback& callback) override {} + + static int instance_count; +}; +int PingInstanceCounter::instance_count = 0; + +TEST_F(BindingSetTest, StrongBinding_Destructor) { + PingServicePtr ping_a, ping_b; + auto bindings = base::MakeUnique<StrongBindingSet<PingService>>(); + + bindings->AddBinding(base::MakeUnique<PingInstanceCounter>(), + mojo::MakeRequest(&ping_a)); + EXPECT_EQ(1, PingInstanceCounter::instance_count); + + bindings->AddBinding(base::MakeUnique<PingInstanceCounter>(), + mojo::MakeRequest(&ping_b)); + EXPECT_EQ(2, PingInstanceCounter::instance_count); + + bindings.reset(); + EXPECT_EQ(0, PingInstanceCounter::instance_count); +} + +TEST_F(BindingSetTest, StrongBinding_ConnectionError) { + PingServicePtr ping_a, ping_b; + StrongBindingSet<PingService> bindings; + bindings.AddBinding(base::MakeUnique<PingInstanceCounter>(), + mojo::MakeRequest(&ping_a)); + bindings.AddBinding(base::MakeUnique<PingInstanceCounter>(), + mojo::MakeRequest(&ping_b)); + EXPECT_EQ(2, PingInstanceCounter::instance_count); + + ping_a.reset(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, PingInstanceCounter::instance_count); + + ping_b.reset(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0, PingInstanceCounter::instance_count); +} + +TEST_F(BindingSetTest, StrongBinding_RemoveBinding) { + PingServicePtr ping_a, ping_b; + StrongBindingSet<PingService> bindings; + BindingId binding_id_a = bindings.AddBinding( + base::MakeUnique<PingInstanceCounter>(), mojo::MakeRequest(&ping_a)); + BindingId binding_id_b = bindings.AddBinding( + base::MakeUnique<PingInstanceCounter>(), mojo::MakeRequest(&ping_b)); + EXPECT_EQ(2, PingInstanceCounter::instance_count); + + EXPECT_TRUE(bindings.RemoveBinding(binding_id_a)); + EXPECT_EQ(1, PingInstanceCounter::instance_count); + + EXPECT_TRUE(bindings.RemoveBinding(binding_id_b)); + EXPECT_EQ(0, PingInstanceCounter::instance_count); +} + } // namespace } // namespace test } // namespace mojo
diff --git a/mojo/public/cpp/bindings/unique_ptr_impl_ref_traits.h b/mojo/public/cpp/bindings/unique_ptr_impl_ref_traits.h new file mode 100644 index 0000000..f1ac097 --- /dev/null +++ b/mojo/public/cpp/bindings/unique_ptr_impl_ref_traits.h
@@ -0,0 +1,22 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MOJO_PUBLIC_CPP_BINDINGS_UNIQUE_PTR_IMPL_REF_TRAITS_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_UNIQUE_PTR_IMPL_REF_TRAITS_H_ + +namespace mojo { + +// Traits for a binding's implementation reference type. +// This corresponds to a unique_ptr reference type. +template <typename Interface> +struct UniquePtrImplRefTraits { + using PointerType = std::unique_ptr<Interface>; + + static bool IsNull(const PointerType& ptr) { return !ptr; } + static Interface* GetRawPointer(PointerType* ptr) { return ptr->get(); } +}; + +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_UNIQUE_PTR_IMPL_REF_TRAITS_H_
diff --git a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc index 4a16385..e69aecc 100644 --- a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc +++ b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.cc
@@ -64,10 +64,8 @@ return StringVar::StringToPPVar(val); } case base::Value::Type::BINARY: { - const base::BinaryValue* binary = - static_cast<const base::BinaryValue*>(value); - uint32_t size = static_cast<uint32_t>(binary->GetSize()); - const char* buffer = binary->GetBuffer(); + uint32_t size = static_cast<uint32_t>(value->GetSize()); + const char* buffer = value->GetBuffer(); PP_Var array_buffer = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(size, buffer);
diff --git a/services/device/BUILD.gn b/services/device/BUILD.gn index 44681f24..1fbbf47 100644 --- a/services/device/BUILD.gn +++ b/services/device/BUILD.gn
@@ -5,6 +5,10 @@ import("//services/service_manager/public/cpp/service.gni") import("//services/service_manager/public/service_manifest.gni") +if (is_android) { + import("//build/config/android/rules.gni") +} + source_set("lib") { sources = [ "device_service.cc", @@ -13,17 +17,17 @@ deps = [ "//base", - "//device/time_zone_monitor", "//services/device/power_monitor", + "//services/device/time_zone_monitor", "//services/service_manager/public/cpp", ] - public_deps = [ - # TODO(blundell): This dep shouldn't be necessary at all, - # but content_shell fails to link in the component build if - # this isn't here as a public_dep. - "//device/time_zone_monitor/public/interfaces", - ] + if (is_android) { + sources += [ + "//services/device/android/register_jni.cc", + "//services/device/android/register_jni.h", + ] + } } source_set("tests") { @@ -48,3 +52,12 @@ name = "device" source = "manifest.json" } + +if (is_android) { + android_library("java") { + java_files = [ "time_zone_monitor/android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java" ] + deps = [ + "//base:base_java", + ] + } +}
diff --git a/services/device/android/register_jni.cc b/services/device/android/register_jni.cc new file mode 100644 index 0000000..345a8699 --- /dev/null +++ b/services/device/android/register_jni.cc
@@ -0,0 +1,27 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/device/android/register_jni.h" + +#include "base/android/jni_android.h" +#include "services/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.h" + +namespace device { + +bool EnsureJniRegistered() { + static bool g_jni_init_done = false; + + if (!g_jni_init_done) { + JNIEnv* env = base::android::AttachCurrentThread(); + + if (!android::RegisterTimeZoneMonitorJni(env)) + return false; + + g_jni_init_done = true; + } + + return true; +} + +} // namespace device
diff --git a/services/device/android/register_jni.h b/services/device/android/register_jni.h new file mode 100644 index 0000000..5874503 --- /dev/null +++ b/services/device/android/register_jni.h
@@ -0,0 +1,16 @@ +// Copyright (c) 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_DEVICE_ANDROID_REGISTER_JNI_H_ +#define SERVICES_DEVICE_ANDROID_REGISTER_JNI_H_ + +namespace device { + +// Register all JNI bindings necessary for device service. +// Is expected to be called on initialization of device service. +bool EnsureJniRegistered(); + +} // namespace device + +#endif // SERVICES_DEVICE_ANDROID_REGISTER_JNI_H_
diff --git a/services/device/device_service.cc b/services/device/device_service.cc index 4cf73987..7a225c4 100644 --- a/services/device/device_service.cc +++ b/services/device/device_service.cc
@@ -8,15 +8,26 @@ #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread_task_runner_handle.h" -#include "device/time_zone_monitor/time_zone_monitor.h" #include "services/device/power_monitor/power_monitor_message_broadcaster.h" +#include "services/device/time_zone_monitor/time_zone_monitor.h" #include "services/service_manager/public/cpp/connection.h" #include "services/service_manager/public/cpp/interface_registry.h" +#if defined(OS_ANDROID) +#include "services/device/android/register_jni.h" +#endif + namespace device { std::unique_ptr<service_manager::Service> CreateDeviceService( scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) { +#if defined(OS_ANDROID) + if (!EnsureJniRegistered()) { + DLOG(ERROR) << "Failed to register JNI for Device Service"; + return nullptr; + } +#endif + return base::MakeUnique<DeviceService>(std::move(file_task_runner)); }
diff --git a/services/device/device_service.h b/services/device/device_service.h index bb5fe94..a8ef5070 100644 --- a/services/device/device_service.h +++ b/services/device/device_service.h
@@ -6,9 +6,9 @@ #define SERVICES_DEVICE_DEVICE_SERVICE_H_ #include "base/memory/ref_counted.h" -#include "device/time_zone_monitor/public/interfaces/time_zone_monitor.mojom.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "services/device/public/interfaces/power_monitor.mojom.h" +#include "services/device/public/interfaces/time_zone_monitor.mojom.h" #include "services/service_manager/public/cpp/interface_factory.h" #include "services/service_manager/public/cpp/service.h"
diff --git a/services/device/public/interfaces/BUILD.gn b/services/device/public/interfaces/BUILD.gn index f207c69..5ef17d7 100644 --- a/services/device/public/interfaces/BUILD.gn +++ b/services/device/public/interfaces/BUILD.gn
@@ -7,6 +7,7 @@ mojom("interfaces") { sources = [ "power_monitor.mojom", + "time_zone_monitor.mojom", ] public_deps = [
diff --git a/device/time_zone_monitor/public/interfaces/time_zone_monitor.mojom b/services/device/public/interfaces/time_zone_monitor.mojom similarity index 100% rename from device/time_zone_monitor/public/interfaces/time_zone_monitor.mojom rename to services/device/public/interfaces/time_zone_monitor.mojom
diff --git a/device/time_zone_monitor/BUILD.gn b/services/device/time_zone_monitor/BUILD.gn similarity index 71% rename from device/time_zone_monitor/BUILD.gn rename to services/device/time_zone_monitor/BUILD.gn index 9369844..ecef1fc3 100644 --- a/device/time_zone_monitor/BUILD.gn +++ b/services/device/time_zone_monitor/BUILD.gn
@@ -8,23 +8,20 @@ import("//build/config/android/rules.gni") # For generate_jni(). } -component("time_zone_monitor") { +source_set("time_zone_monitor") { + visibility = [ "//services/device:lib" ] + sources = [ - "android/time_zone_monitor_jni_registrar.cc", - "android/time_zone_monitor_jni_registrar.h", "time_zone_monitor.cc", "time_zone_monitor.h", "time_zone_monitor_android.cc", "time_zone_monitor_android.h", "time_zone_monitor_chromeos.cc", - "time_zone_monitor_export.h", "time_zone_monitor_linux.cc", "time_zone_monitor_mac.mm", "time_zone_monitor_win.cc", ] - defines = [ "DEVICE_TIME_ZONE_MONITOR_IMPLEMENTATION" ] - deps = [ "//base", "//mojo/public/cpp/bindings", @@ -32,10 +29,14 @@ ] public_deps = [ - "//device/time_zone_monitor/public/interfaces", + "//services/device/public/interfaces", ] if (is_android) { + sources += [ + "android/time_zone_monitor_jni_registrar.cc", + "android/time_zone_monitor_jni_registrar.h", + ] deps += [ ":time_zone_monitor_jni_headers" ] } @@ -54,16 +55,10 @@ if (is_android) { generate_jni("time_zone_monitor_jni_headers") { + visibility = [ ":time_zone_monitor" ] sources = [ "android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java", ] jni_package = "time_zone_monitor" } - - android_library("java") { - java_files = [ "android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java" ] - deps = [ - "//base:base_java", - ] - } }
diff --git a/device/time_zone_monitor/DEPS b/services/device/time_zone_monitor/DEPS similarity index 100% rename from device/time_zone_monitor/DEPS rename to services/device/time_zone_monitor/DEPS
diff --git a/device/time_zone_monitor/OWNERS b/services/device/time_zone_monitor/OWNERS similarity index 100% rename from device/time_zone_monitor/OWNERS rename to services/device/time_zone_monitor/OWNERS
diff --git a/device/time_zone_monitor/android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java b/services/device/time_zone_monitor/android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java similarity index 100% rename from device/time_zone_monitor/android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java rename to services/device/time_zone_monitor/android/java/src/org/chromium/device/time_zone_monitor/TimeZoneMonitor.java
diff --git a/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.cc b/services/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.cc similarity index 80% rename from device/time_zone_monitor/android/time_zone_monitor_jni_registrar.cc rename to services/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.cc index 55ab5d5a..6385d4f 100644 --- a/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.cc +++ b/services/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.cc
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "device/time_zone_monitor/android/time_zone_monitor_jni_registrar.h" +#include "services/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.h" #include "base/android/jni_android.h" #include "base/android/jni_registrar.h" -#include "device/time_zone_monitor/time_zone_monitor_android.h" +#include "services/device/time_zone_monitor/time_zone_monitor_android.h" namespace device { namespace android {
diff --git a/services/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.h b/services/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.h new file mode 100644 index 0000000..e6442ee --- /dev/null +++ b/services/device/time_zone_monitor/android/time_zone_monitor_jni_registrar.h
@@ -0,0 +1,18 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_DEVICE_TIME_ZONE_MONITOR_ANDROID_TIME_ZONE_MONITOR_JNI_REGISTRAR_H_ +#define SERVICES_DEVICE_TIME_ZONE_MONITOR_ANDROID_TIME_ZONE_MONITOR_JNI_REGISTRAR_H_ + +#include <jni.h> + +namespace device { +namespace android { + +bool RegisterTimeZoneMonitorJni(JNIEnv* env); + +} // namespace android +} // namespace device + +#endif // SERVICES_DEVICE_TIME_ZONE_MONITOR_ANDROID_TIME_ZONE_MONITOR_JNI_REGISTRAR_H_
diff --git a/device/time_zone_monitor/time_zone_monitor.cc b/services/device/time_zone_monitor/time_zone_monitor.cc similarity index 96% rename from device/time_zone_monitor/time_zone_monitor.cc rename to services/device/time_zone_monitor/time_zone_monitor.cc index 0e671b4..52e2a52 100644 --- a/device/time_zone_monitor/time_zone_monitor.cc +++ b/services/device/time_zone_monitor/time_zone_monitor.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "device/time_zone_monitor/time_zone_monitor.h" +#include "services/device/time_zone_monitor/time_zone_monitor.h" #include "base/logging.h" #include "build/build_config.h"
diff --git a/device/time_zone_monitor/time_zone_monitor.h b/services/device/time_zone_monitor/time_zone_monitor.h similarity index 81% rename from device/time_zone_monitor/time_zone_monitor.h rename to services/device/time_zone_monitor/time_zone_monitor.h index f79f94a..730aa5d0 100644 --- a/device/time_zone_monitor/time_zone_monitor.h +++ b/services/device/time_zone_monitor/time_zone_monitor.h
@@ -2,17 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_TIME_ZONE_MONITOR_H_ -#define CONTENT_BROWSER_TIME_ZONE_MONITOR_H_ +#ifndef SERVICES_DEVICE_TIME_ZONE_MONITOR_TIME_ZONE_MONITOR_H_ +#define SERVICES_DEVICE_TIME_ZONE_MONITOR_TIME_ZONE_MONITOR_H_ #include <memory> #include "base/macros.h" #include "base/threading/thread_checker.h" -#include "device/time_zone_monitor/public/interfaces/time_zone_monitor.mojom.h" -#include "device/time_zone_monitor/time_zone_monitor_export.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h" +#include "services/device/public/interfaces/time_zone_monitor.mojom.h" template <class T> class scoped_refptr; @@ -45,13 +44,12 @@ // Returns a new TimeZoneMonitor object (likely a subclass) specific to the // platform. Inject |file_task_runner| to enable running blocking file // operations on it when necessary. - DEVICE_TIME_ZONE_MONITOR_EXPORT static std::unique_ptr<TimeZoneMonitor> - Create(scoped_refptr<base::SequencedTaskRunner> file_task_runner); + static std::unique_ptr<TimeZoneMonitor> Create( + scoped_refptr<base::SequencedTaskRunner> file_task_runner); ~TimeZoneMonitor() override; - DEVICE_TIME_ZONE_MONITOR_EXPORT void Bind( - device::mojom::TimeZoneMonitorRequest request); + void Bind(device::mojom::TimeZoneMonitorRequest request); protected: TimeZoneMonitor(); @@ -72,4 +70,4 @@ } // namespace device -#endif // CONTENT_BROWSER_TIME_ZONE_MONITOR_H_ +#endif // SERVICES_DEVICE_TIME_ZONE_MONITOR_TIME_ZONE_MONITOR_H_
diff --git a/device/time_zone_monitor/time_zone_monitor_android.cc b/services/device/time_zone_monitor/time_zone_monitor_android.cc similarity index 94% rename from device/time_zone_monitor/time_zone_monitor_android.cc rename to services/device/time_zone_monitor/time_zone_monitor_android.cc index 0d1ea625..b15a90c 100644 --- a/device/time_zone_monitor/time_zone_monitor_android.cc +++ b/services/device/time_zone_monitor/time_zone_monitor_android.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "device/time_zone_monitor/time_zone_monitor_android.h" +#include "services/device/time_zone_monitor/time_zone_monitor_android.h" #include "base/android/context_utils.h" #include "base/android/jni_android.h"
diff --git a/device/time_zone_monitor/time_zone_monitor_android.h b/services/device/time_zone_monitor/time_zone_monitor_android.h similarity index 75% rename from device/time_zone_monitor/time_zone_monitor_android.h rename to services/device/time_zone_monitor/time_zone_monitor_android.h index 576b227..76cc17d 100644 --- a/device/time_zone_monitor/time_zone_monitor_android.h +++ b/services/device/time_zone_monitor/time_zone_monitor_android.h
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_TIME_ZONE_MONITOR_ANDROID_H_ -#define CONTENT_BROWSER_TIME_ZONE_MONITOR_ANDROID_H_ +#ifndef SERVICES_DEVICE_TIME_ZONE_MONITOR_TIME_ZONE_MONITOR_ANDROID_H_ +#define SERVICES_DEVICE_TIME_ZONE_MONITOR_TIME_ZONE_MONITOR_ANDROID_H_ -#include "device/time_zone_monitor/time_zone_monitor.h" +#include "services/device/time_zone_monitor/time_zone_monitor.h" #include <jni.h> @@ -36,4 +36,4 @@ } // namespace device -#endif // CONTENT_BROWSER_TIME_ZONE_MONITOR_ANDROID_H_ +#endif // SERVICES_DEVICE_TIME_ZONE_MONITOR_TIME_ZONE_MONITOR_ANDROID_H_
diff --git a/device/time_zone_monitor/time_zone_monitor_chromeos.cc b/services/device/time_zone_monitor/time_zone_monitor_chromeos.cc similarity index 94% rename from device/time_zone_monitor/time_zone_monitor_chromeos.cc rename to services/device/time_zone_monitor/time_zone_monitor_chromeos.cc index 0c59b44..b1b7c010d 100644 --- a/device/time_zone_monitor/time_zone_monitor_chromeos.cc +++ b/services/device/time_zone_monitor/time_zone_monitor_chromeos.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "device/time_zone_monitor/time_zone_monitor.h" +#include "services/device/time_zone_monitor/time_zone_monitor.h" #include "base/macros.h" #include "chromeos/settings/timezone_settings.h"
diff --git a/device/time_zone_monitor/time_zone_monitor_linux.cc b/services/device/time_zone_monitor/time_zone_monitor_linux.cc similarity index 97% rename from device/time_zone_monitor/time_zone_monitor_linux.cc rename to services/device/time_zone_monitor/time_zone_monitor_linux.cc index 9aee0b2..22ab258b 100644 --- a/device/time_zone_monitor/time_zone_monitor_linux.cc +++ b/services/device/time_zone_monitor/time_zone_monitor_linux.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "device/time_zone_monitor/time_zone_monitor.h" +#include "services/device/time_zone_monitor/time_zone_monitor.h" #include <stddef.h> #include <stdlib.h> @@ -76,9 +76,7 @@ private: friend class base::RefCountedThreadSafe<TimeZoneMonitorLinuxImpl>; - ~TimeZoneMonitorLinuxImpl() { - DCHECK(!owner_); - } + ~TimeZoneMonitorLinuxImpl() { DCHECK(!owner_); } void StartWatchingOnFileThread() { base::ThreadRestrictions::AssertIOAllowed();
diff --git a/device/time_zone_monitor/time_zone_monitor_mac.mm b/services/device/time_zone_monitor/time_zone_monitor_mac.mm similarity index 94% rename from device/time_zone_monitor/time_zone_monitor_mac.mm rename to services/device/time_zone_monitor/time_zone_monitor_mac.mm index 8cccb41..761bc1f1 100644 --- a/device/time_zone_monitor/time_zone_monitor_mac.mm +++ b/services/device/time_zone_monitor/time_zone_monitor_mac.mm
@@ -5,7 +5,7 @@ #import <Foundation/Foundation.h> #include "base/macros.h" -#include "device/time_zone_monitor/time_zone_monitor.h" +#include "services/device/time_zone_monitor/time_zone_monitor.h" namespace device {
diff --git a/device/time_zone_monitor/time_zone_monitor_win.cc b/services/device/time_zone_monitor/time_zone_monitor_win.cc similarity index 94% rename from device/time_zone_monitor/time_zone_monitor_win.cc rename to services/device/time_zone_monitor/time_zone_monitor_win.cc index d698911d..b4a2695 100644 --- a/device/time_zone_monitor/time_zone_monitor_win.cc +++ b/services/device/time_zone_monitor/time_zone_monitor_win.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "device/time_zone_monitor/time_zone_monitor.h" +#include "services/device/time_zone_monitor/time_zone_monitor.h" #include <windows.h>
diff --git a/services/shape_detection/DEPS b/services/shape_detection/DEPS index 1987787..a2872a2 100644 --- a/services/shape_detection/DEPS +++ b/services/shape_detection/DEPS
@@ -1,6 +1,5 @@ include_rules = [ "+media/capture/video/scoped_result_callback.h", - "+skia/ext/skia_utils_mac.h", "+third_party/skia/include", "+ui/gfx/codec", "+ui/gl/gl_switches.h"
diff --git a/services/shape_detection/barcode_detection_impl_mac.h b/services/shape_detection/barcode_detection_impl_mac.h index 6a5609a..a7779897 100644 --- a/services/shape_detection/barcode_detection_impl_mac.h +++ b/services/shape_detection/barcode_detection_impl_mac.h
@@ -7,7 +7,6 @@ #include "base/mac/scoped_nsobject.h" #include "services/shape_detection/public/interfaces/barcodedetection.mojom.h" -#include "third_party/skia/include/core/SkBitmap.h" @class CIDetector; @@ -19,7 +18,9 @@ BarcodeDetectionImplMac(); ~BarcodeDetectionImplMac() override; - void Detect(const SkBitmap& bitmap, + void Detect(mojo::ScopedSharedBufferHandle frame_data, + uint32_t width, + uint32_t height, const shape_detection::mojom::BarcodeDetection::DetectCallback& callback) override;
diff --git a/services/shape_detection/barcode_detection_impl_mac.mm b/services/shape_detection/barcode_detection_impl_mac.mm index 2abbc03..ec0ac0b 100644 --- a/services/shape_detection/barcode_detection_impl_mac.mm +++ b/services/shape_detection/barcode_detection_impl_mac.mm
@@ -50,20 +50,22 @@ BarcodeDetectionImplMac::~BarcodeDetectionImplMac() {} -void BarcodeDetectionImplMac::Detect(const SkBitmap& bitmap, +void BarcodeDetectionImplMac::Detect(mojo::ScopedSharedBufferHandle frame_data, + uint32_t width, + uint32_t height, const DetectCallback& callback) { media::ScopedResultCallback<DetectCallback> scoped_callback( base::Bind(&RunCallbackWithBarcodes, callback), base::Bind(&RunCallbackWithNoBarcodes)); - base::scoped_nsobject<CIImage> ci_image = CreateCIImageFromSkBitmap(bitmap); + base::scoped_nsobject<CIImage> ci_image = + CreateCIImageFromSharedMemory(std::move(frame_data), width, height); if (!ci_image) return; NSArray* const features = [detector_ featuresInImage:ci_image]; std::vector<mojom::BarcodeDetectionResultPtr> results; - const int height = bitmap.height(); for (CIQRCodeFeature* const f in features) { shape_detection::mojom::BarcodeDetectionResultPtr result = shape_detection::mojom::BarcodeDetectionResult::New();
diff --git a/services/shape_detection/barcode_detection_impl_mac_unittest.mm b/services/shape_detection/barcode_detection_impl_mac_unittest.mm index d3c305c..55c2cd27 100644 --- a/services/shape_detection/barcode_detection_impl_mac_unittest.mm +++ b/services/shape_detection/barcode_detection_impl_mac_unittest.mm
@@ -12,7 +12,6 @@ #include "base/run_loop.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/utils/mac/SkCGUtils.h" #include "ui/gl/gl_switches.h" namespace shape_detection { @@ -65,6 +64,7 @@ const gfx::Size size([qr_code_image extent].size.width, [qr_code_image extent].size.height); + const int num_bytes = size.GetArea() * 4 /* bytes per pixel */; base::scoped_nsobject<CIContext> context([[CIContext alloc] init]); @@ -73,16 +73,30 @@ EXPECT_EQ(static_cast<size_t>(size.width()), CGImageGetWidth(cg_image)); EXPECT_EQ(static_cast<size_t>(size.height()), CGImageGetHeight(cg_image)); - SkBitmap bitmap; - ASSERT_TRUE(SkCreateBitmapFromCGImage(&bitmap, cg_image)); + base::ScopedCFTypeRef<CFDataRef> raw_cg_image_data( + CGDataProviderCopyData(CGImageGetDataProvider(cg_image))); + EXPECT_TRUE(CFDataGetBytePtr(raw_cg_image_data)); + EXPECT_EQ(num_bytes, CFDataGetLength(raw_cg_image_data)); + + // Generate a new ScopedSharedBufferHandle of the aproppriate size, map it and + // copy the generated qr code image pixels into it. + mojo::ScopedSharedBufferHandle handle = + mojo::SharedBufferHandle::Create(num_bytes); + ASSERT_TRUE(handle->is_valid()); + + mojo::ScopedSharedBufferMapping mapping = handle->Map(num_bytes); + ASSERT_TRUE(mapping); + + memcpy(mapping.get(), CFDataGetBytePtr(raw_cg_image_data), num_bytes); base::RunLoop run_loop; base::Closure quit_closure = run_loop.QuitClosure(); // Send the image Detect() and expect the response in callback. EXPECT_CALL(*this, Detection(1, kInfoString)) .WillOnce(RunClosure(quit_closure)); - impl_.Detect(bitmap, base::Bind(&BarcodeDetectionImplMacTest::DetectCallback, - base::Unretained(this))); + impl_.Detect(std::move(handle), size.width(), size.height(), + base::Bind(&BarcodeDetectionImplMacTest::DetectCallback, + base::Unretained(this))); run_loop.Run(); }
diff --git a/services/shape_detection/detection_utils_mac.h b/services/shape_detection/detection_utils_mac.h index 69e46426..98e3c0f 100644 --- a/services/shape_detection/detection_utils_mac.h +++ b/services/shape_detection/detection_utils_mac.h
@@ -9,14 +9,15 @@ #include "base/mac/scoped_nsobject.h" #include "services/shape_detection/public/interfaces/barcodedetection.mojom.h" -#include "third_party/skia/include/core/SkBitmap.h" namespace shape_detection { // Takes a ScopedSharedBufferHandle with dimensions and produces a new CIImage // with the same contents, or a null scoped_nsobject is something goes wrong. -base::scoped_nsobject<CIImage> CreateCIImageFromSkBitmap( - const SkBitmap& bitmap); +base::scoped_nsobject<CIImage> CreateCIImageFromSharedMemory( + mojo::ScopedSharedBufferHandle frame_data, + uint32_t width, + uint32_t height); } // namespace shape_detection
diff --git a/services/shape_detection/detection_utils_mac.mm b/services/shape_detection/detection_utils_mac.mm index 554cd7e5..4e87812e99 100644 --- a/services/shape_detection/detection_utils_mac.mm +++ b/services/shape_detection/detection_utils_mac.mm
@@ -9,31 +9,61 @@ #include "base/memory/shared_memory.h" #include "mojo/public/cpp/system/platform_handle.h" #include "services/shape_detection/barcode_detection_impl.h" -#include "skia/ext/skia_utils_mac.h" -#include "third_party/skia/include/utils/mac/SkCGUtils.h" namespace shape_detection { -base::scoped_nsobject<CIImage> CreateCIImageFromSkBitmap( - const SkBitmap& bitmap) { +// These formats are available but not public until Mac 10.11. +#if !defined(MAC_OS_X_VERSION_10_11) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_11 +const int kCIFormatRGBA8 = 24; +#else +//static_assert(kCIFormatRGBA8 == 24, "RGBA8 format enum index."); +#endif + +base::scoped_nsobject<CIImage> CreateCIImageFromSharedMemory( + mojo::ScopedSharedBufferHandle frame_data, + uint32_t width, + uint32_t height) { base::CheckedNumeric<uint32_t> num_pixels = - base::CheckedNumeric<uint32_t>(bitmap.width()) * bitmap.height(); + base::CheckedNumeric<uint32_t>(width) * height; base::CheckedNumeric<uint32_t> num_bytes = num_pixels * 4; if (!num_bytes.IsValid()) { DLOG(ERROR) << "Data overflow"; return base::scoped_nsobject<CIImage>(); } - // First convert SkBitmap to CGImageRef. - base::ScopedCFTypeRef<CGImageRef> cg_image( - SkCreateCGImageRefWithColorspace(bitmap, NULL)); - if (!cg_image) { - DLOG(ERROR) << "Failed to create CGImageRef"; + base::SharedMemoryHandle memory_handle; + size_t memory_size = 0; + bool read_only_flag = false; + const MojoResult result = mojo::UnwrapSharedMemoryHandle( + std::move(frame_data), &memory_handle, &memory_size, &read_only_flag); + DCHECK_EQ(MOJO_RESULT_OK, result) << "Failed to unwrap SharedBufferHandle"; + if (!memory_size || memory_size != num_bytes.ValueOrDie()) { + DLOG(ERROR) << "Invalid image size"; return base::scoped_nsobject<CIImage>(); } - base::scoped_nsobject<CIImage> ci_image( - [[CIImage alloc] initWithCGImage:cg_image]); + auto shared_memory = + base::MakeUnique<base::SharedMemory>(memory_handle, true /* read_only */); + if (!shared_memory->Map(memory_size)) { + DLOG(ERROR) << "Failed to map bytes from shared memory"; + return base::scoped_nsobject<CIImage>(); + } + + NSData* byte_data = [NSData dataWithBytesNoCopy:shared_memory->memory() + length:num_bytes.ValueOrDie() + freeWhenDone:NO]; + + base::ScopedCFTypeRef<CGColorSpaceRef> colorspace( + CGColorSpaceCreateWithName(kCGColorSpaceSRGB)); + + // CIImage will return nil if RGBA8 is not supported in a certain version. + base::scoped_nsobject<CIImage> ci_image([[CIImage alloc] + initWithBitmapData:byte_data + bytesPerRow:width * 4 + size:CGSizeMake(width, height) + format:kCIFormatRGBA8 + colorSpace:colorspace]); if (!ci_image) { DLOG(ERROR) << "Failed to create CIImage"; return base::scoped_nsobject<CIImage>();
diff --git a/services/shape_detection/face_detection_impl_mac.h b/services/shape_detection/face_detection_impl_mac.h index 459ffa7..fb978c7 100644 --- a/services/shape_detection/face_detection_impl_mac.h +++ b/services/shape_detection/face_detection_impl_mac.h
@@ -7,7 +7,6 @@ #include "base/mac/scoped_nsobject.h" #include "services/shape_detection/public/interfaces/facedetection.mojom.h" -#include "third_party/skia/include/core/SkBitmap.h" @class CIDetector; @@ -19,7 +18,9 @@ shape_detection::mojom::FaceDetectorOptionsPtr options); ~FaceDetectionImplMac() override; - void Detect(const SkBitmap& bitmap, + void Detect(mojo::ScopedSharedBufferHandle frame_data, + uint32_t width, + uint32_t height, const shape_detection::mojom::FaceDetection::DetectCallback& callback) override;
diff --git a/services/shape_detection/face_detection_impl_mac.mm b/services/shape_detection/face_detection_impl_mac.mm index 8bece619..151e0a7c 100644 --- a/services/shape_detection/face_detection_impl_mac.mm +++ b/services/shape_detection/face_detection_impl_mac.mm
@@ -47,19 +47,21 @@ FaceDetectionImplMac::~FaceDetectionImplMac() {} -void FaceDetectionImplMac::Detect(const SkBitmap& bitmap, +void FaceDetectionImplMac::Detect(mojo::ScopedSharedBufferHandle frame_data, + uint32_t width, + uint32_t height, const DetectCallback& callback) { media::ScopedResultCallback<DetectCallback> scoped_callback( base::Bind(&RunCallbackWithFaces, callback), base::Bind(&RunCallbackWithNoFaces)); - base::scoped_nsobject<CIImage> ci_image = CreateCIImageFromSkBitmap(bitmap); + base::scoped_nsobject<CIImage> ci_image = + CreateCIImageFromSharedMemory(std::move(frame_data), width, height); if (!ci_image) return; NSArray* const features = [detector_ featuresInImage:ci_image]; - const int height = bitmap.height(); shape_detection::mojom::FaceDetectionResultPtr faces = shape_detection::mojom::FaceDetectionResult::New(); for (CIFaceFeature* const f in features) {
diff --git a/services/shape_detection/face_detection_impl_mac_unittest.mm b/services/shape_detection/face_detection_impl_mac_unittest.mm index 9b9c569..e07f700f 100644 --- a/services/shape_detection/face_detection_impl_mac_unittest.mm +++ b/services/shape_detection/face_detection_impl_mac_unittest.mm
@@ -76,12 +76,24 @@ const int num_bytes = size.GetArea() * 4 /* bytes per pixel */; ASSERT_EQ(num_bytes, image->computeSize64()); + // Generate a new ScopedSharedBufferHandle of the aproppriate size, map it and + // copy the image pixels into it. + mojo::ScopedSharedBufferHandle handle = + mojo::SharedBufferHandle::Create(num_bytes); + ASSERT_TRUE(handle->is_valid()); + + mojo::ScopedSharedBufferMapping mapping = handle->Map(num_bytes); + ASSERT_TRUE(mapping); + + memcpy(mapping.get(), image->getPixels(), num_bytes); + base::RunLoop run_loop; base::Closure quit_closure = run_loop.QuitClosure(); // Send the image to Detect() and expect the response in callback. EXPECT_CALL(*this, Detection(1)).WillOnce(RunClosure(quit_closure)); - impl_->Detect(*image, base::Bind(&FaceDetectionImplMacTest::DetectCallback, - base::Unretained(this))); + impl_->Detect(std::move(handle), size.width(), size.height(), + base::Bind(&FaceDetectionImplMacTest::DetectCallback, + base::Unretained(this))); run_loop.Run(); }
diff --git a/services/shape_detection/public/interfaces/BUILD.gn b/services/shape_detection/public/interfaces/BUILD.gn index 44522415..953742864 100644 --- a/services/shape_detection/public/interfaces/BUILD.gn +++ b/services/shape_detection/public/interfaces/BUILD.gn
@@ -14,7 +14,6 @@ ] public_deps = [ - "//skia/public/interfaces", "//ui/gfx/geometry/mojo", ] }
diff --git a/services/shape_detection/public/interfaces/barcodedetection.mojom b/services/shape_detection/public/interfaces/barcodedetection.mojom index 5ae9aef5..27f95ecd 100644 --- a/services/shape_detection/public/interfaces/barcodedetection.mojom +++ b/services/shape_detection/public/interfaces/barcodedetection.mojom
@@ -6,7 +6,6 @@ module shape_detection.mojom; -import "skia/public/interfaces/bitmap.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; struct BarcodeDetectionResult { @@ -18,7 +17,9 @@ }; interface BarcodeDetection { - // |bitmap_data| contains tightly packed image pixels in row-major order. - Detect(skia.mojom.Bitmap bitmap_data) + // |frame_data| contains tightly packed image pixels in ARGB32 format, + // row-major order. + // TODO(mcasas): Consider using mojo::Bitmap here, https://crbug.com/665488. + Detect(handle<shared_buffer> frame_data, uint32 width, uint32 height) => (array<BarcodeDetectionResult> results); };
diff --git a/services/shape_detection/public/interfaces/facedetection.mojom b/services/shape_detection/public/interfaces/facedetection.mojom index 0ee1390..38102f8 100644 --- a/services/shape_detection/public/interfaces/facedetection.mojom +++ b/services/shape_detection/public/interfaces/facedetection.mojom
@@ -6,7 +6,6 @@ module shape_detection.mojom; -import "skia/public/interfaces/bitmap.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; // Since "//ui/gfx/geometry/mojo" is not exposed to blink, we need to declare @@ -22,7 +21,9 @@ }; interface FaceDetection { - // |bitmap_data| contains tightly packed image pixels in row-major order. - Detect(skia.mojom.Bitmap bitmap_data) + // |frame_data| contains tightly packed image pixels in ARGB32 format, + // row-major order. + // TODO(mcasas): Consider using mojo::Bitmap here, https://crbug.com/665488. + Detect(handle<shared_buffer> frame_data, uint32 width, uint32 height) => (FaceDetectionResult result); };
diff --git a/services/shape_detection/public/interfaces/textdetection.mojom b/services/shape_detection/public/interfaces/textdetection.mojom index 7a0fed5..6e8bb01 100644 --- a/services/shape_detection/public/interfaces/textdetection.mojom +++ b/services/shape_detection/public/interfaces/textdetection.mojom
@@ -4,7 +4,6 @@ module shape_detection.mojom; -import "skia/public/interfaces/bitmap.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; struct TextDetectionResult { @@ -13,7 +12,8 @@ }; interface TextDetection { - // |bitmap_data| contains tightly packed image pixels in row-major order. - Detect(skia.mojom.Bitmap bitmap_data) + // |frame_data| contains tightly packed image pixels in ARGB32 format, + // row-major order. + Detect(handle<shared_buffer> frame_data, uint32 width, uint32 height) => (array<TextDetectionResult> results); };
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index fd8bb9b..4796d08 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -7121,23 +7121,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--gtest_filter=*Detection*", - "--use-gpu-in-tests" - ], - "swarming": { - "can_use_on_swarming_builders": false, - "dimension_sets": [ - { - "gpu": "1002:679e", - "os": "Mac-10.10" - } - ] - }, - "test": "service_unittests", - "use_xvfb": false } ], "isolated_scripts": [ @@ -7482,23 +7465,6 @@ }, "test": "gles2_conform_test", "use_xvfb": false - }, - { - "args": [ - "--gtest_filter=*Detection*", - "--use-gpu-in-tests" - ], - "swarming": { - "can_use_on_swarming_builders": false, - "dimension_sets": [ - { - "gpu": "1002:679e", - "os": "Mac-10.10" - } - ] - }, - "test": "service_unittests", - "use_xvfb": false } ], "isolated_scripts": [
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 856ab253..60d4c493 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -751,6 +751,7 @@ # future, as foolip@ is in the process of performing a significant fullscreen # refactor. See [crbug.com/676432] for a minimized repro. crbug.com/676432 fullscreen/full-screen-iframe-zIndex.html [ Skip ] +crbug.com/676432 virtual/android/fullscreen/full-screen-iframe-zIndex.html [ Skip ] # TODO(xiaochengh): We should either convert the following tests with # spellcheck_test, or remove if they become redundant or inapplicable.
diff --git a/third_party/WebKit/LayoutTests/animations/underlying-background-position-edge.html b/third_party/WebKit/LayoutTests/animations/underlying-background-position-edge.html new file mode 100644 index 0000000..e1268c743 --- /dev/null +++ b/third_party/WebKit/LayoutTests/animations/underlying-background-position-edge.html
@@ -0,0 +1,10 @@ +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<div id="target"></div> +<script> +test(() => { + target.style.backgroundPosition = 'right 20px bottom 20px'; + target.animate({backgroundPosition: 'left 20px top 20px'}, {iterationStart: 0.5, fill: 'forwards'}); + assert_equals(getComputedStyle(target).backgroundPosition, '50% 50%'); +}, 'Don\'t ignore the specified edge of the underlying background-position value in animations'); +</script>
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/format-block-multiple-paragraphs-expected.txt b/third_party/WebKit/LayoutTests/editing/execCommand/format-block-multiple-paragraphs-expected.txt deleted file mode 100644 index 0bafcd05..0000000 --- a/third_party/WebKit/LayoutTests/editing/execCommand/format-block-multiple-paragraphs-expected.txt +++ /dev/null
@@ -1,232 +0,0 @@ -This tests ensures formatBlock do not make multiple elements when formatting multiple paragraphs. - -Formatting: -| " -" -| <div> -| "<#selection-anchor>hello" -| <div> -| "world" -| <div> -| "WebKit<#selection-focus>" -| " -" - -by p yields: -| " -" -| <p> -| "<#selection-anchor>hello" -| <br> -| "world" -| <br> -| "WebKit<#selection-focus>" -| " -" - -Formatting: -| " -" -| <p> -| "<#selection-anchor>hello" -| <p> -| "world<#selection-focus>" -| " -" - -by blockquote yields: -| " -" -| <blockquote> -| "<#selection-anchor>hello" -| <br> -| "world<#selection-focus>" -| " -" - -Formatting: -| " -" -| <div> -| "<#selection-anchor>hello" -| <pre> -| "world<#selection-focus>" -| " -" - -by p yields: -| " -" -| <p> -| "<#selection-anchor>hello" -| <br> -| "world<#selection-focus>" -| " -" - -Formatting: -| " -" -| <h1> -| "<#selection-anchor>hello" -| <div> -| <h2> -| "world" -| <h3> -| "WebKit<#selection-focus>" -| " -" - -by pre yields: -| " -" -| <pre> -| "<#selection-anchor>hello" -| <br> -| "world" -| <br> -| "WebKit<#selection-focus>" -| " -" - -Formatting: -| " -" -| <div> -| "hello" -| <p> -| "<#selection-anchor>world" -| "webki<#selection-focus>t" -| " -" - -by h1 yields: -| " -" -| <div> -| "hello" -| <h1> -| "<#selection-anchor>world" -| <br> -| "webkit<#selection-focus>" -| " -" - -Formatting: -| " -" -| <pre> -| "<#selection-anchor>hello -world<#selection-focus> -webkit -" -| " -" - -by blockquote yields: -| " -" -| <pre> -| <blockquote> -| "<#selection-anchor>hello" -| <br> -| "world<#selection-focus>" -| "webkit -" -| " -" - -Formatting: -| " -" -| <pre> -| "hello -<#selection-anchor>world -webki<#selection-focus>t -" -| " -" - -by blockquote yields: -| " -" -| <pre> -| "hello -" -| <blockquote> -| "<#selection-anchor>world" -| <br> -| "webki<#selection-focus>t" -| " -" - -Formatting: -| " -<#selection-anchor>hello" -| <p> -| "world<#selection-focus>" -| <p> -| "webkit" -| " - -" - -by pre yields: -| <pre> -| "<#selection-anchor> -hello" -| <br> -| "worl<#selection-focus>d" -| <p> -| "webkit" -| " - -" - -Formatting: -| " -" -| <div> -| "hello" -| <div> -| "<#selection-anchor>world" -| <div> -| "webki<#selection-focus>t" -| " -" - -by pre yields: -| " -" -| <div> -| "hello" -| <pre> -| "<#selection-anchor>world" -| <br> -| "webki<#selection-focus>t" -| " -" - -Formatting: -| " -" -| <ul> -| <li> -| "<#selection-anchor>hello" -| <li> -| "world<#selection-focus>" -| " -" - -by blockquote yields: -| " -" -| <blockquote> -| <ul> -| <li> -| "<#selection-anchor>hello" -| <ul> -| <li> -| "world<#selection-focus>" -| " -"
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/format-block-multiple-paragraphs.html b/third_party/WebKit/LayoutTests/editing/execCommand/format-block-multiple-paragraphs.html index 12c1798..761140c0 100644 --- a/third_party/WebKit/LayoutTests/editing/execCommand/format-block-multiple-paragraphs.html +++ b/third_party/WebKit/LayoutTests/editing/execCommand/format-block-multiple-paragraphs.html
@@ -1,82 +1,137 @@ -<!DOCTYPE html> -<html> -<body> -<script src="../../resources/dump-as-markup.js"></script> -<div id="test0" contenteditable> -<div>hello</div><div>world</div><div>WebKit</div> -</div> -<div id="test1" contenteditable> -<p>hello</p><p>world</p> -</div> -<div id="test2" contenteditable> -<div>hello<pre>world</pre></div> -</div> -<div id="test3" contenteditable> -<h1>hello</h1><div><h2>world</h2><h3>WebKit</h3></div> -</div> -<div id="test4" contenteditable> -<div>hello<p>world</p>webkit</div> -</div> -<div id="test5" contenteditable> -<pre>hello -world -webkit -</pre> -</div> -<div id="test6" contenteditable> -<pre>hello -world -webkit -</pre> -</div> -<div id="test7" contenteditable> -hello<p>world</p><p>webkit</p> -</pre> -</div> -<div id="test8" contenteditable> -<div>hello</div><div>world</div><div>webkit</div> -</div> -<div id="test9" contenteditable> -<ul><li>hello</li><li>world</li></ul> -</div> +<!doctype html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../assert_selection.js"></script> <script> +test(() => assert_selection( + [ + '<div contenteditable>', + '^<div>hello</div><div>world</div><div>Blink</div>|', + '</div>', + ].join(''), + 'formatBlock P', + [ + '<div contenteditable>', + '<p>^hello<br>world<br>Blink|</p>', + '</div>', + ].join('')), '0 select all children with P'); -Markup.description('This tests ensures formatBlock do not make multiple elements when formatting multiple paragraphs.') +test(() => assert_selection( + [ + '<div contenteditable>', + '^<p>hello</p><p>world</p>|', + '</div>', + ].join(''), + 'formatBlock blockquote', + [ + '<div contenteditable>', + '<blockquote>hello<br>world|</blockquote>', + '</div>', + ].join('')), '1 select all children BLOCKQUOTE'); -function testIndentation(containerId, selector, value) { - var container = document.getElementById(containerId); - selector(container); - Markup.dump(container, 'Formatting'); - document.execCommand('FormatBlock', false, value); - Markup.dump(container, 'by ' + value + ' yields'); -} +test(() => assert_selection( + [ + '<div contenteditable>', + '^<div>hello<pre>world</pre></div>|', + '</div>', + ].join(''), + 'formatBlock blockquote', + [ + '<div contenteditable>', + '<blockquote>^hello<br>world|</blockquote>', + '</div>', + ].join('')), '2 select all children P'); -function selectAll(container) { - window.getSelection().selectAllChildren(container); -} +test(() => assert_selection( + [ + '<div contenteditable>', + '^<h1>hello</h1><div><h2>world</h2><h3>Blink</h3></div>|', + '</div>', + ].join(''), + 'formatBlock blockquote', + [ + '<div contenteditable>', + '<blockquote>hello<br>world<br>Blink|</blockquote>', + '</div>', + ].join('')), '3 select all children PRE'); -function selectorForLines(first, last) { - return function (container) { - window.getSelection().collapse(container, 0); - for (var i = 0; i < first - 1; i++) - window.getSelection().modify('move', 'forward', 'line'); - for (var i = 0; i < Math.abs(last - first, 0) + 1; i++) - window.getSelection().modify('extend', 'forward', 'line'); - window.getSelection().modify('extend', 'backward', 'character'); - } -} +test(() => assert_selection( + [ + '<div contenteditable>', + '<div>hello<p>^world</p>Blin|k</div>', + '</div>', + ].join(''), + 'formatBlock H1', + [ + '<div contenteditable>', + 'hello<h1>^world<br>Blink|</h1>', + '</div>', + ].join('')), '4 select for lines 2, 3 with H1'); -testIndentation('test0', selectAll, 'p'); -testIndentation('test1', selectAll, 'blockquote'); -testIndentation('test2', selectAll, 'p'); -testIndentation('test3', selectAll, 'pre'); -testIndentation('test4', selectorForLines(2, 3), 'h1'); -testIndentation('test5', selectorForLines(1, 2), 'blockquote'); -testIndentation('test6', selectorForLines(2, 3), 'blockquote'); -testIndentation('test7', selectorForLines(1, 2), 'pre'); -testIndentation('test8', selectorForLines(2, 3), 'pre'); -testIndentation('test9', selectAll, 'blockquote'); +test(() => assert_selection( + [ + '<div contenteditable>', + '<pre>^hello\nworld|\nBlink\n</pre>', + '</div>', + ].join(''), + 'formatBlock BLOCKQUOTE', + [ + '<div contenteditable>', + '<pre><blockquote>^hello<br>world|</blockquote>Blink\n</pre>', + '</div>', + ].join('')), '5 select for lines 1, 2 with BLOCKQUOTE'); +test(() => assert_selection( + [ + '<div contenteditable>', + '<pre>hello\n^world\nBlin|k\n</pre>', + '</div>', + ].join(''), + 'formatBlock BLOCKQUOTE', + [ + '<div contenteditable>', + '<pre>hello\n<blockquote>^world<br>Blin|k</blockquote></pre>', + '</div>', + ].join('')), '6 select for lines 2, 3 with BLOCKQUOTE'); + +test(() => assert_selection( + [ + '<div contenteditable>', + '^hello<p>world|</p><p>webkit</p>', + '</div>', + ].join(''), + 'formatBlock PRE', + [ + '<div contenteditable>', + '<pre>^hello<br>world|</pre><p>webkit</p>', + '</div>', + ].join('')), '7 select for lines 2, 3 with PRE'); + +test(() => assert_selection( + [ + '<div contenteditable>', + '<div>hello</div><div>^world</div><div>blin|k</div>', + '</div>', + ].join(''), + 'formatBlock PRE', + [ + '<div contenteditable>', + '<div>hello</div><pre>^world<br>blin|k</pre>', + '</div>', + ].join('')), '8 select for lines 2, 3 with PRE'); + +test(() => assert_selection( + [ + '<div contenteditable>', + '^<ul><li>hello</li><li>world</li></ul>|', + '</div>', + ].join(''), + 'formatBlock BLOCKQUOTE', + [ + '<div contenteditable>', + '<blockquote>', + '<ul><li>^hello</li></ul><ul><li>world|</li></ul>', + '</blockquote>', + '</div>', + ].join('')), '9 select all children with BLOCKQUOTE'); </script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/format-block-table-expected.txt b/third_party/WebKit/LayoutTests/editing/execCommand/format-block-table-expected.txt deleted file mode 100644 index 7f6ddde..0000000 --- a/third_party/WebKit/LayoutTests/editing/execCommand/format-block-table-expected.txt +++ /dev/null
@@ -1,124 +0,0 @@ - -Formatting: -| " -" -| <table> -| <tbody> -| <tr> -| <td> -| "hello" -| <td> -| "world" -| " -" - -by p yields: -| " -" -| <p> -| <#selection-anchor> -| <table> -| <tbody> -| <tr> -| <td> -| "hello" -| <td> -| "world" -| <#selection-focus> -| " -" - -Formatting: -| " -" -| <table> -| <tbody> -| <tr> -| <td> -| "<#selection-anchor>hello<#selection-focus>" -| <td> -| "world" -| " -" - -by blockquote yields: -| " -" -| <table> -| <tbody> -| <tr> -| <td> -| <blockquote> -| "<#selection-anchor>hello<#selection-focus>" -| <td> -| "world" -| " -" - -Formatting: -| " -" -| <table> -| <tbody> -| <tr> -| <td> -| <p> -| "<#selection-anchor>hello" -| <div> -| "world<#selection-focus>" -| <td> -| "WebKit" -| " -" - -by h3 yields: -| " -" -| <table> -| <tbody> -| <tr> -| <td> -| <h3> -| "<#selection-anchor>hello" -| <br> -| "world<#selection-focus>" -| <td> -| "WebKit" -| " -" - -Formatting: -| " -" -| <table> -| <tbody> -| <tr> -| <td> -| <ul> -| <li> -| "<#selection-anchor>hello" -| <li> -| "world<#selection-focus>" -| <td> -| "WebKit" -| " -" - -by address yields: -| " -" -| <table> -| <tbody> -| <tr> -| <td> -| <address> -| <ul> -| <li> -| "<#selection-anchor>hello" -| <ul> -| <li> -| "world<#selection-focus>" -| <td> -| "WebKit" -| " -"
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/format-block-table.html b/third_party/WebKit/LayoutTests/editing/execCommand/format-block-table.html index 28ba100..d5e6d21 100644 --- a/third_party/WebKit/LayoutTests/editing/execCommand/format-block-table.html +++ b/third_party/WebKit/LayoutTests/editing/execCommand/format-block-table.html
@@ -1,42 +1,70 @@ -<!DOCTYPE html> -<html> -<body> -<script src="../../resources/dump-as-markup.js"></script> -<div id="test0" contenteditable> -<table><tr><td>hello</td><td>world</td></tr></table> -</div> -<div id="test1" contenteditable> -<table><tr><td>hello</td><td>world</td></tr></table> -</div> -<div id="test2" contenteditable> -<table><tr><td><p>hello</p><div>world</div></td><td>WebKit</td></tr></table> -</div> -<div id="test3" contenteditable> -<table><tr><td><ul><li>hello</li><li>world</li></ul></td><td>WebKit</td></tr></table> -</div> +<!doctype html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../assert_selection.js"></script> <script> +test(() => assert_selection( + [ + '<div contenteditable>', + '^<table><tr><td>hello</td><td>world</td></tr></table>|', + '</div>', + ].join(''), + 'formatBlock P', + [ + '<div contenteditable>', + '<p>^<table><tbody><tr><td>hello</td><td>world</td></tr></tbody></table>|</p>', + '</div>', + ].join('')), '0 select all children with P'); -function testIndentation(containerId, selector, value) { - var container = document.getElementById(containerId); - selector(container); - Markup.dump(container, 'Formatting'); - document.execCommand('FormatBlock', false, value); - Markup.dump(container, 'by ' + value + ' yields'); -} +test(() => assert_selection( + [ + '<div contenteditable>', + '<table><tr><td>^hello|</td><td>world</td></tr></table>', + '</div>', + ].join(''), + 'formatBlock P', + [ + '<div contenteditable>', + '<table><tbody><tr>', + '<td><p>^hello|</p></td><td>world</td>', + '</tr></tbody></table>', + '</div>', + ].join('')), '1 select first cell with BLOCKQUOTE'); -function selectAll(container) { - window.getSelection().selectAllChildren(container); -} +test(() => assert_selection( + [ + '<div contenteditable>', + '<table><tr>', + '<td>^<p>hello</p>|<div>world</div></td><td>Blink</td>', + '</tr></table>', + '</div>', + ].join(''), + 'formatBlock BLOCKQUOTE', + [ + '<div contenteditable>', + '<table><tbody><tr>', + '<td><blockquote>^hello|</blockquote><div>world</div></td><td>Blink</td>', + '</tr></tbody></table>', + '</div>', + ].join('')), '2 select first cell with BLOCKQUOTE'); -function selectFirstCell(container) { - window.getSelection().selectAllChildren(container.getElementsByTagName('td')[0]); -} - -testIndentation('test0', selectAll, 'p'); -testIndentation('test1', selectFirstCell, 'blockquote'); -testIndentation('test2', selectFirstCell, 'h3'); -testIndentation('test3', selectFirstCell, 'address'); - +test(() => assert_selection( + [ + '<div contenteditable>', + '<table><tr>', + '<td>^<ul><li>hello</li><li>world</li></ul>|</td><td>Blink</td>', + '</tr></table>', + '</div>', + ].join(''), + 'formatBlock ADDRESS', + [ + '<div contenteditable>', + '<table><tbody><tr>', + '<td><address>', + '<ul><li>^hello</li></ul><ul><li>world|</li></ul>', + '</address></td>', + '<td>Blink</td>', + '</tr></tbody></table>', + '</div>', + ].join('')), '3 select first cell with ADDRESS'); </script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/format-block-with-block-expected.txt b/third_party/WebKit/LayoutTests/editing/execCommand/format-block-with-block-expected.txt deleted file mode 100644 index fa2537c..0000000 --- a/third_party/WebKit/LayoutTests/editing/execCommand/format-block-with-block-expected.txt +++ /dev/null
@@ -1,56 +0,0 @@ -This test verifies that formatBlock adds the containing block element's inline style to the block-style element that replaces it. - -Before FormatBlock: -| " -" -| <div> -| style="color: green" -| "<#selection-anchor>hello<#selection-focus>" -| " -" - -After FormatBlock: -| " -" -| <h1> -| style="color: green" -| "<#selection-anchor>hello<#selection-focus>" -| " -" - -Before FormatBlock: -| " -" -| <div> -| style="color: green" -| <#selection-caret> -| <br> -| " -" - -After FormatBlock: -| " -" -| <h1> -| style="color: green" -| <#selection-caret> -| <br> -| " -" - -Before FormatBlock: -| " -" -| <span> -| style="color: green" -| "<#selection-anchor>hello<#selection-focus>" -| " -" - -After FormatBlock: -| " -" -| <h1> -| <span> -| style="color: green" -| "<#selection-anchor>hello<#selection-focus>"
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/format-block-with-block.html b/third_party/WebKit/LayoutTests/editing/execCommand/format-block-with-block.html index c1713f8..dddbf1a 100644 --- a/third_party/WebKit/LayoutTests/editing/execCommand/format-block-with-block.html +++ b/third_party/WebKit/LayoutTests/editing/execCommand/format-block-with-block.html
@@ -1,32 +1,44 @@ -<!DOCTYPE html> -<html> -<body> -<script src="../../resources/dump-as-markup.js"></script> -<div id="testBlock" contenteditable> -<div style="color: green">hello</div> -</div> -<div id="testBlockWithBR" contenteditable> -<div style="color: green"><br></div> -</div> -<div id="testInline" contenteditable> -<span style="color: green">hello</span> -</div> +<!doctype html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../assert_selection.js"></script> <script> -function verify(id) -{ - var testElement = document.getElementById(id); - window.getSelection().selectAllChildren(testElement); +test(() => assert_selection( + [ + '<div contenteditable>', + '^<div style="color: green">hello</div>|', + '</div>', + ].join(''), + 'formatBlock h1', + [ + '<div contenteditable>', + '<h1 style="color: green">^hello|</h1>', + '</div>', + ].join('')), 'Block'); - Markup.dump(testElement, 'Before FormatBlock'); - document.execCommand('FormatBlock', false, 'h1'); - Markup.dump(testElement, 'After FormatBlock'); -} -Markup.description("This test verifies that formatBlock adds the containing block element's inline style to the block-style element that replaces it."); +test(() => assert_selection( + [ + '<div contenteditable>', + '^<div style="color: green"><br></div>|', + '</div>', + ].join(''), + 'formatBlock h1', + [ + '<div contenteditable>', + '<h1 style="color: green">|<br></h1>', + '</div>', + ].join('')), 'Block with BR'); -verify("testBlock"); -verify("testBlockWithBR"); -verify("testInline"); - +test(() => assert_selection( + [ + '<div contenteditable>', + '^<span style="color: green">hello</span>|', + '</div>', + ].join(''), + 'formatBlock h1', + [ + '<div contenteditable>', + '<h1><span style="color: green">^hello|</span></h1>', + '</div>', + ].join('')), 'Inline'); </script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre-paragraphs-expected.txt b/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre-paragraphs-expected.txt deleted file mode 100644 index b8f93239..0000000 --- a/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre-paragraphs-expected.txt +++ /dev/null
@@ -1,154 +0,0 @@ - -Indenting: -| " -" -| <pre> -| "<#selection-anchor>hello<#selection-focus>" -| " -" - -yields: -| " -" -| <blockquote> -| style="margin: 0 0 0 40px; border: none; padding: 0px;" -| <pre> -| "<#selection-anchor>hello<#selection-focus>" -| " -" - -Indenting: -| " -" -| <pre> -| "<#selection-anchor>hello - -world - -webkit<#selection-focus> -" -| " -" - -yields: -| " -" -| <blockquote> -| style="margin: 0 0 0 40px; border: none; padding: 0px;" -| <pre> -| "<#selection-anchor>hello" -| <pre> -| " -" -| <pre> -| "world" -| <pre> -| " -" -| <pre> -| "webkit<#selection-focus>" -| " -" - -Indenting: -| " -" -| <pre> -| "<#selection-anchor>hello -world -webkit<#selection-focus> -" -| " -" - -yields: -| " -" -| <blockquote> -| style="margin: 0 0 0 40px; border: none; padding: 0px;" -| <pre> -| "<#selection-anchor>hello" -| <pre> -| "world" -| <pre> -| "webkit<#selection-focus>" -| " -" - -Indenting: -| " -" -| <pre> -| "<#selection-anchor>hello<#selection-focus> - -world -" -| " -" - -yields: -| " -" -| <blockquote> -| style="margin: 0 0 0 40px; border: none; padding: 0px;" -| <pre> -| "<#selection-anchor>hello<#selection-focus>" -| <pre> -| " -world -" -| " -" - -Indenting: -| " -" -| <pre> -| "hello -<#selection-caret> -world -" -| " -" - -yields: -| " -" -| <pre> -| "hello<#selection-caret> -" -| <blockquote> -| style="margin: 0 0 0 40px; border: none; padding: 0px;" -| <pre> -| " -" -| <pre> -| "world -" -| " -" - -Indenting: -| " -" -| <pre> -| "hello - -<#selection-anchor>worl<#selection-focus>d -" -| " -" - -yields: -| " -" -| <pre> -| "hello -<#selection-anchor> -" -| <blockquote> -| style="margin: 0 0 0 40px; border: none; padding: 0px;" -| <pre> -| "worl<#selection-focus>d" -| " -"
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre-paragraphs.html b/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre-paragraphs.html index c9228e5..dc29c31 100644 --- a/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre-paragraphs.html +++ b/third_party/WebKit/LayoutTests/editing/execCommand/indent-pre-paragraphs.html
@@ -1,83 +1,100 @@ -<!DOCTYPE html> -<html> -<body> -<script src="../../resources/dump-as-markup.js"></script> -<div id="test0" contenteditable> -<pre>hello</pre> -</div> - -<div id="test1" contenteditable> -<pre> -hello - -world - -webkit -</pre> -</div> - -<div id="test2" contenteditable> -<pre> -hello -world -webkit -</pre> -</div> - -<div id="test3" contenteditable> -<pre> -hello - -world -</pre> -</div> - -<div id="test4" contenteditable> -<pre> -hello - -world -</pre> -</div> - -<div id="test5" contenteditable> -<pre> -hello - -world -</pre> -</div> +<!doctype html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../assert_selection.js"></script> <script> +test(() => assert_selection( + [ + '<div contenteditable>', + '^<pre>hello</pre>|', + '</div>', + ].join(''), + 'indent', + [ + '<div contenteditable>', + '<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">', + '<pre>^hello|</pre>', + '</blockquote>', + '</div>', + ].join('')), '0 select all children'); -function testIndentation(containerId, selector) { - var container = document.getElementById(containerId); - selector(container); - Markup.dump(container, 'Indenting'); - document.execCommand('indent', false, null); - Markup.dump(container, 'yields'); -} +test(() => assert_selection( + [ + '<div contenteditable>', + '^<pre>\nhello\n\nworld\n\nblink\n</pre>|', + '</div>', + ].join(''), + 'indent', + [ + '<div contenteditable>', + '<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">', + '<pre>^hello</pre>', + '<pre>\n</pre><pre>world</pre><pre>\n</pre><pre>blink|</pre>', + '</blockquote>', + '</div>', + ].join('')), '1 select all children with blank lines'); -function selectAll(container) { - window.getSelection().selectAllChildren(container); -} +test(() => assert_selection( + [ + '<div contenteditable>', + '^<pre>\nhello\nworld\nblink\n</pre>|', + '</div>', + ].join(''), + 'indent', + [ + '<div contenteditable>', + '<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">', + '<pre>^hello</pre><pre>world</pre><pre>blink|</pre>', + '</blockquote>', + '</div>', + ].join('')), '2 select all children with newlines'); -function selectorForLineN(line) { - return function (container) { - window.getSelection().collapse(container, 0); - for (var i = 0; i < line - 1; i++) - window.getSelection().modify('move', 'forward', 'line'); - window.getSelection().modify('extend', 'forward', 'line'); - window.getSelection().modify('extend', 'backward', 'character'); - } -} +test(() => assert_selection( + [ + '<div contenteditable>', + '<pre>\n^hello|\n\nworld\n</pre>', + '</div>', + ].join(''), + 'indent', + [ + '<div contenteditable>', + '<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">', + '<pre>^hello|</pre>', + '</blockquote>', + '<pre>\nworld\n</pre>', + '</div>', + ].join('')), '3 select line 1'); -testIndentation('test0', selectAll); -testIndentation('test1', selectAll); -testIndentation('test2', selectAll); -testIndentation('test3', selectorForLineN(1)); -testIndentation('test4', selectorForLineN(2)); -testIndentation('test5', selectorForLineN(3)); +test(() => assert_selection( + [ + '<div contenteditable>', + '<pre>\nhello\n|\nworld\n</pre>', + '</div>', + ].join(''), + 'indent', + [ + '<div contenteditable>', + '<pre>hello|\n</pre>', + '<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">', + '<pre>\n</pre>', + '</blockquote>', + '<pre>world\n</pre>', + '</div>', + ].join('')), '4 select line 2'); +test(() => assert_selection( + [ + '<div contenteditable>', + '<pre>\nhello\n\n^worl|d\n</pre>', + '</div>', + ].join(''), + 'indent', + [ + '<div contenteditable>', + '<pre>hello\n^\n</pre>', + '<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;">', + '<pre>worl|d</pre>', + '</blockquote>', + '</div>', + ].join('')), '5 select line 3'); </script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/editing/selection/setBaseAndExtent-revert-selection-expected.txt b/third_party/WebKit/LayoutTests/editing/selection/setBaseAndExtent-revert-selection-expected.txt deleted file mode 100644 index 3c6a5a21..0000000 --- a/third_party/WebKit/LayoutTests/editing/selection/setBaseAndExtent-revert-selection-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -Test for bug 20117: setBaseAndExtent fails to reverse the current selection. - -Div X -Div Y -Div Z -PASS
diff --git a/third_party/WebKit/LayoutTests/editing/selection/setBaseAndExtent-revert-selection.html b/third_party/WebKit/LayoutTests/editing/selection/setBaseAndExtent-revert-selection.html index 5bb90445..b3e719e 100644 --- a/third_party/WebKit/LayoutTests/editing/selection/setBaseAndExtent-revert-selection.html +++ b/third_party/WebKit/LayoutTests/editing/selection/setBaseAndExtent-revert-selection.html
@@ -1,33 +1,40 @@ -<html> - <head> - <script> - var output = ''; - - function selectNodes(a, b) { - window.getSelection().setBaseAndExtent(a, 1, b, 1); - output += window.getSelection().anchorNode.parentNode.id + ' '; - } +<!doctype html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../assert_selection.js"></script> +<script> +// Test for https://bugs.webkit.org/show_bug.cgi?id=20117 +test(() => assert_selection( + [ + '<div id="x">Div X</div>', + '<div id="y">Div Y</div>', + '<div id="z">Div Z</div>', + ].join(''), + selection => { + const x = selection.document.getElementById('x'); + const y = selection.document.getElementById('y'); + selection.setBaseAndExtent(x, 1, y, 1); + }, + [ + '<div id="x">Div X^</div>', + '<div id="y">Div Y|</div>', + '<div id="z">Div Z</div>', + ].join('')), 'anchor < focus'); - if (window.testRunner) - testRunner.dumpAsText(); - - function doIt() { - try { - var x = document.getElementById('x'); - var y = document.getElementById('y'); - selectNodes(x, y); - selectNodes(y, x); - document.getElementById('result').innerHTML = (output == "x y " ? "PASS" : ("FAIL: " + output)); - } catch (e) { alert(e); } - } - </script> - </head> - <body onload="doIt()"> - <p>Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=20117">bug 20117</a>: - setBaseAndExtent fails to reverse the current selection.</p> - <div id='x'>Div X</div> - <div id='y'>Div Y</div> - <div id='z'>Div Z</div> - <div id='result'>FAIL (script didn't run)</div> - </body> -</html> +test(() => assert_selection( + [ + '<div id="x">Div X</div>', + '<div id="y">Div Y</div>', + '<div id="z">Div Z</div>', + ].join(''), + selection => { + const x = selection.document.getElementById('x'); + const y = selection.document.getElementById('y'); + selection.setBaseAndExtent(y, 1, x, 1); + }, + [ + '<div id="x">Div X|</div>', + '<div id="y">Div Y^</div>', + '<div id="z">Div Z</div>', + ].join('')), 'anchor > focus'); +</script>
diff --git a/third_party/WebKit/LayoutTests/shapedetection/resources/mock-barcodedetection.js b/third_party/WebKit/LayoutTests/shapedetection/resources/mock-barcodedetection.js index 129c660ee..1f6a479 100644 --- a/third_party/WebKit/LayoutTests/shapedetection/resources/mock-barcodedetection.js +++ b/third_party/WebKit/LayoutTests/shapedetection/resources/mock-barcodedetection.js
@@ -18,8 +18,8 @@ handle => this.bindingSet_.addBinding(this, handle)); } - detect(bitmap_data) { - let receivedStruct = new Uint8Array(bitmap_data.pixel_data); + detect(frame_data, width, height) { + let receivedStruct = mojo.mapBuffer(frame_data, 0, width*height*4, 0); this.buffer_data_ = new Uint32Array(receivedStruct.buffer); return Promise.resolve({ results: [ @@ -45,6 +45,7 @@ }, ], }); + mojo.unmapBuffer(receivedStruct.buffer); } getFrameData() {
diff --git a/third_party/WebKit/LayoutTests/shapedetection/resources/mock-facedetection.js b/third_party/WebKit/LayoutTests/shapedetection/resources/mock-facedetection.js index c02fda2..1faf89f 100644 --- a/third_party/WebKit/LayoutTests/shapedetection/resources/mock-facedetection.js +++ b/third_party/WebKit/LayoutTests/shapedetection/resources/mock-facedetection.js
@@ -44,8 +44,8 @@ request); } - detect(bitmap_data) { - let receivedStruct = new Uint8Array(bitmap_data.pixel_data); + detect(frame_data, width, height) { + let receivedStruct = mojo.mapBuffer(frame_data, 0, width*height*4, 0); this.buffer_data_ = new Uint32Array(receivedStruct.buffer); return Promise.resolve({ result: { @@ -56,6 +56,7 @@ ] } }); + mojo.unmapBuffer(receivedStruct.buffer); } } return new MockFaceDetectionProvider();
diff --git a/third_party/WebKit/LayoutTests/shapedetection/resources/mock-textdetection.js b/third_party/WebKit/LayoutTests/shapedetection/resources/mock-textdetection.js index a622605..08195c9 100644 --- a/third_party/WebKit/LayoutTests/shapedetection/resources/mock-textdetection.js +++ b/third_party/WebKit/LayoutTests/shapedetection/resources/mock-textdetection.js
@@ -17,8 +17,8 @@ handle => this.bindingSet_.addBinding(this, handle)); } - detect(bitmap_data) { - let receivedStruct = new Uint8Array(bitmap_data.pixel_data); + detect(frame_data, width, height) { + let receivedStruct = mojo.mapBuffer(frame_data, 0, width*height*4, 0); this.buffer_data_ = new Uint32Array(receivedStruct.buffer); return Promise.resolve({ results: [ @@ -32,6 +32,7 @@ }, ], }); + mojo.unmapBuffer(receivedStruct.buffer); } getFrameData() {
diff --git a/third_party/WebKit/PerformanceTests/Skipped b/third_party/WebKit/PerformanceTests/Skipped index bea9be16..88a88cc 100644 --- a/third_party/WebKit/PerformanceTests/Skipped +++ b/third_party/WebKit/PerformanceTests/Skipped
@@ -50,9 +50,3 @@ # Assumes window.eventSender is always supported; it only is for "content-shell" performance runs. DOM/click_webkit_user_select_none.html - -# Times out on reference build - crbug.com/579107 -ShadowDOM/SlotDistibutedNextPrevious.html -ShadowDOM/v1-distribution.html -ShadowDOM/v1-host-child-append.html -ShadowDOM/v1-slot-append.html
diff --git a/third_party/WebKit/Source/core/animation/LengthListPropertyFunctions.cpp b/third_party/WebKit/Source/core/animation/LengthListPropertyFunctions.cpp index ba7c629..6f65bbf 100644 --- a/third_party/WebKit/Source/core/animation/LengthListPropertyFunctions.cpp +++ b/third_party/WebKit/Source/core/animation/LengthListPropertyFunctions.cpp
@@ -41,15 +41,12 @@ struct FillLayerMethods { FillLayerMethods(CSSPropertyID property) { - isSet = nullptr; - getLength = nullptr; - setLength = nullptr; - clear = nullptr; switch (property) { case CSSPropertyBackgroundPositionX: case CSSPropertyWebkitMaskPositionX: isSet = &FillLayer::isXPositionSet; getLength = &FillLayer::xPosition; + getEdge = &FillLayer::backgroundXOrigin; setLength = &FillLayer::setXPosition; clear = &FillLayer::clearXPosition; break; @@ -57,6 +54,7 @@ case CSSPropertyWebkitMaskPositionY: isSet = &FillLayer::isYPositionSet; getLength = &FillLayer::yPosition; + getEdge = &FillLayer::backgroundYOrigin; setLength = &FillLayer::setYPosition; clear = &FillLayer::clearYPosition; break; @@ -66,10 +64,11 @@ } } - bool (FillLayer::*isSet)() const; - const Length& (FillLayer::*getLength)() const; - void (FillLayer::*setLength)(const Length&); - void (FillLayer::*clear)(); + bool (FillLayer::*isSet)() const = nullptr; + const Length& (FillLayer::*getLength)() const = nullptr; + BackgroundEdgeOrigin (FillLayer::*getEdge)() const = nullptr; + void (FillLayer::*setLength)(const Length&) = nullptr; + void (FillLayer::*clear)() = nullptr; }; } // namespace @@ -164,6 +163,14 @@ FillLayerMethods fillLayerMethods(property); while (fillLayer && (fillLayer->*fillLayerMethods.isSet)()) { result.push_back((fillLayer->*fillLayerMethods.getLength)()); + switch ((fillLayer->*fillLayerMethods.getEdge)()) { + case RightEdge: + case BottomEdge: + result.back() = result.back().subtractFromOneHundredPercent(); + break; + default: + break; + } fillLayer = fillLayer->next(); } return true;
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp index 5471152..96fe94d 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerClipper.cpp
@@ -444,7 +444,6 @@ const ClipRectsContext& context, bool isForeground) const { DCHECK(m_geometryMapper); - LayoutRect source(LayoutRect::infiniteIntRect()); const auto* properties = m_layer.layoutObject()->paintProperties(); // TODO(chrishtr): fix the underlying bug that causes this situation. DCHECK(properties && properties->localBorderBoxProperties()); @@ -476,8 +475,8 @@ } FloatClipRect clippedRectInRootLayerSpace = - m_geometryMapper->sourceToDestinationVisualRect( - FloatRect(source), propertyTreeState, destinationPropertyTreeState); + m_geometryMapper->sourceToDestinationClipRect( + propertyTreeState, destinationPropertyTreeState); ClipRect clipRect(LayoutRect(clippedRectInRootLayerSpace.rect())); if (clippedRectInRootLayerSpace.hasRadius()) clipRect.setHasRadius(true);
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerClipperTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerClipperTest.cpp index 241735cd..b612cff 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerClipperTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerClipperTest.cpp
@@ -33,7 +33,8 @@ } bool geometryMapperCacheEmpty(const PaintLayerClipper& clipper) { - return clipper.m_geometryMapper->m_data.isEmpty(); + return clipper.m_geometryMapper->m_transformCache.isEmpty() && + clipper.m_geometryMapper->m_clipCache.isEmpty(); } };
diff --git a/third_party/WebKit/Source/modules/shapedetection/BUILD.gn b/third_party/WebKit/Source/modules/shapedetection/BUILD.gn index 663f27599..8102c764 100644 --- a/third_party/WebKit/Source/modules/shapedetection/BUILD.gn +++ b/third_party/WebKit/Source/modules/shapedetection/BUILD.gn
@@ -24,6 +24,5 @@ public_deps = [ "//services/shape_detection/public/interfaces:interfaces_blink", - "//skia/public/interfaces:interfaces_blink", ] }
diff --git a/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.cpp index 7dce489..9f8beca 100644 --- a/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.cpp +++ b/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.cpp
@@ -26,8 +26,11 @@ wrapWeakPersistent(this)))); } -ScriptPromise BarcodeDetector::doDetect(ScriptPromiseResolver* resolver, - skia::mojom::blink::BitmapPtr bitmap) { +ScriptPromise BarcodeDetector::doDetect( + ScriptPromiseResolver* resolver, + mojo::ScopedSharedBufferHandle sharedBufferHandle, + int imageWidth, + int imageHeight) { ScriptPromise promise = resolver->promise(); if (!m_barcodeService) { resolver->reject(DOMException::create( @@ -36,9 +39,10 @@ } m_barcodeServiceRequests.insert(resolver); m_barcodeService->Detect( - std::move(bitmap), convertToBaseCallback(WTF::bind( - &BarcodeDetector::onDetectBarcodes, - wrapPersistent(this), wrapPersistent(resolver)))); + std::move(sharedBufferHandle), imageWidth, imageHeight, + convertToBaseCallback(WTF::bind(&BarcodeDetector::onDetectBarcodes, + wrapPersistent(this), + wrapPersistent(resolver)))); return promise; }
diff --git a/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.h b/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.h index 7e3fa4af8..2d0e598 100644 --- a/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.h +++ b/third_party/WebKit/Source/modules/shapedetection/BarcodeDetector.h
@@ -29,7 +29,9 @@ ~BarcodeDetector() override = default; ScriptPromise doDetect(ScriptPromiseResolver*, - skia::mojom::blink::BitmapPtr) override; + mojo::ScopedSharedBufferHandle, + int imageWidth, + int imageHeight) override; void onDetectBarcodes( ScriptPromiseResolver*, Vector<shape_detection::mojom::blink::BarcodeDetectionResultPtr>);
diff --git a/third_party/WebKit/Source/modules/shapedetection/DEPS b/third_party/WebKit/Source/modules/shapedetection/DEPS index 76ba38ac..372894a 100644 --- a/third_party/WebKit/Source/modules/shapedetection/DEPS +++ b/third_party/WebKit/Source/modules/shapedetection/DEPS
@@ -10,7 +10,6 @@ "+platform", "+public/platform", "+services/shape_detection", - "+skia/public/interfaces/bitmap.mojom-blink.h", "+third_party/skia/include/core/SkImage.h", "+third_party/skia/include/core/SkImageInfo.h", "+ui/gfx/geometry",
diff --git a/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp index ce92d34..ccda92a 100644 --- a/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp +++ b/third_party/WebKit/Source/modules/shapedetection/FaceDetector.cpp
@@ -35,8 +35,11 @@ &FaceDetector::onFaceServiceConnectionError, wrapWeakPersistent(this)))); } -ScriptPromise FaceDetector::doDetect(ScriptPromiseResolver* resolver, - skia::mojom::blink::BitmapPtr bitmap) { +ScriptPromise FaceDetector::doDetect( + ScriptPromiseResolver* resolver, + mojo::ScopedSharedBufferHandle sharedBufferHandle, + int imageWidth, + int imageHeight) { ScriptPromise promise = resolver->promise(); if (!m_faceService) { resolver->reject(DOMException::create( @@ -44,7 +47,7 @@ return promise; } m_faceServiceRequests.insert(resolver); - m_faceService->Detect(std::move(bitmap), + m_faceService->Detect(std::move(sharedBufferHandle), imageWidth, imageHeight, convertToBaseCallback(WTF::bind( &FaceDetector::onDetectFaces, wrapPersistent(this), wrapPersistent(resolver))));
diff --git a/third_party/WebKit/Source/modules/shapedetection/FaceDetector.h b/third_party/WebKit/Source/modules/shapedetection/FaceDetector.h index 2047879c..84f6b9f 100644 --- a/third_party/WebKit/Source/modules/shapedetection/FaceDetector.h +++ b/third_party/WebKit/Source/modules/shapedetection/FaceDetector.h
@@ -31,7 +31,9 @@ ~FaceDetector() override = default; ScriptPromise doDetect(ScriptPromiseResolver*, - skia::mojom::blink::BitmapPtr) override; + mojo::ScopedSharedBufferHandle, + int imageWidth, + int imageHeight) override; void onDetectFaces(ScriptPromiseResolver*, shape_detection::mojom::blink::FaceDetectionResultPtr); void onFaceServiceConnectionError();
diff --git a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp index ec32288..2fc9609 100644 --- a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp +++ b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.cpp
@@ -22,19 +22,28 @@ namespace { -skia::mojom::blink::BitmapPtr createBitmapFromData(int width, - int height, - Vector<uint8_t> bitmapData) { - skia::mojom::blink::BitmapPtr bitmap = skia::mojom::blink::Bitmap::New(); +mojo::ScopedSharedBufferHandle getSharedBufferOnData( + ScriptPromiseResolver* resolver, + uint8_t* data, + int size) { + DCHECK(data); + DCHECK(size); + ScriptPromise promise = resolver->promise(); - bitmap->color_type = (kN32_SkColorType == kRGBA_8888_SkColorType) - ? skia::mojom::ColorType::RGBA_8888 - : skia::mojom::ColorType::BGRA_8888; - bitmap->width = width; - bitmap->height = height; - bitmap->pixel_data = std::move(bitmapData); + mojo::ScopedSharedBufferHandle sharedBufferHandle = + mojo::SharedBufferHandle::Create(size); + if (!sharedBufferHandle->is_valid()) { + resolver->reject( + DOMException::create(InvalidStateError, "Internal allocation error")); + return sharedBufferHandle; + } - return bitmap; + const mojo::ScopedSharedBufferMapping mappedBuffer = + sharedBufferHandle->Map(size); + DCHECK(mappedBuffer.get()); + memcpy(mappedBuffer.get(), data, size); + + return sharedBufferHandle; } } // anonymous namespace @@ -127,13 +136,13 @@ return promise; } - WTF::Vector<uint8_t> bitmapData; - bitmapData.append(pixelDataPtr, - static_cast<int>(allocationSize.ValueOrDefault(0))); + mojo::ScopedSharedBufferHandle sharedBufferHandle = getSharedBufferOnData( + resolver, pixelDataPtr, allocationSize.ValueOrDefault(0)); + if (!sharedBufferHandle->is_valid()) + return promise; - return doDetect(resolver, - createBitmapFromData(image->width(), image->height(), - std::move(bitmapData))); + return doDetect(resolver, std::move(sharedBufferHandle), image->width(), + image->height()); } ScriptPromise ShapeDetector::detectShapesOnImageData( @@ -148,12 +157,14 @@ uint8_t* const data = imageData->data()->data(); WTF::CheckedNumeric<int> allocationSize = imageData->size().area() * 4; - WTF::Vector<uint8_t> bitmapData; - bitmapData.append(data, static_cast<int>(allocationSize.ValueOrDefault(0))); - return doDetect(resolver, - createBitmapFromData(imageData->width(), imageData->height(), - std::move(bitmapData))); + mojo::ScopedSharedBufferHandle sharedBufferHandle = + getSharedBufferOnData(resolver, data, allocationSize.ValueOrDefault(0)); + if (!sharedBufferHandle->is_valid()) + return promise; + + return doDetect(resolver, std::move(sharedBufferHandle), imageData->width(), + imageData->height()); } ScriptPromise ShapeDetector::detectShapesOnImageElement( @@ -194,10 +205,26 @@ const SkImageInfo skiaInfo = SkImageInfo::MakeN32(image->width(), image->height(), image->alphaType()); - size_t rowBytes = skiaInfo.minRowBytes(); - Vector<uint8_t> bitmapData(skiaInfo.getSafeSize(rowBytes)); - const SkPixmap pixmap(skiaInfo, bitmapData.data(), rowBytes); + const uint32_t allocationSize = skiaInfo.getSafeSize(skiaInfo.minRowBytes()); + + mojo::ScopedSharedBufferHandle sharedBufferHandle = + mojo::SharedBufferHandle::Create(allocationSize); + if (!sharedBufferHandle.is_valid()) { + DLOG(ERROR) << "Requested allocation : " << allocationSize + << "B, larger than |mojo::edk::kMaxSharedBufferSize| == 16MB "; + // TODO(xianglu): For now we reject the promise if the image is too large. + // But consider resizing the image to remove restriction on the user side. + // Also, add LayoutTests for this case later. + resolver->reject( + DOMException::create(InvalidStateError, "Image exceeds size limit.")); + return promise; + } + + const mojo::ScopedSharedBufferMapping mappedBuffer = + sharedBufferHandle->Map(allocationSize); + + const SkPixmap pixmap(skiaInfo, mappedBuffer.get(), skiaInfo.minRowBytes()); if (!image->readPixels(pixmap, 0, 0)) { resolver->reject(DOMException::create( InvalidStateError, @@ -205,9 +232,8 @@ return promise; } - return doDetect( - resolver, createBitmapFromData(img->naturalWidth(), img->naturalHeight(), - std::move(bitmapData))); + return doDetect(resolver, std::move(sharedBufferHandle), img->naturalWidth(), + img->naturalHeight()); } } // namespace blink
diff --git a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.h b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.h index cd55e5cc..74b8e70e 100644 --- a/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.h +++ b/third_party/WebKit/Source/modules/shapedetection/ShapeDetector.h
@@ -10,7 +10,6 @@ #include "core/imagebitmap/ImageBitmapFactories.h" #include "modules/ModulesExport.h" #include "modules/canvas2d/CanvasRenderingContext2D.h" -#include "skia/public/interfaces/bitmap.mojom-blink.h" namespace blink { @@ -28,7 +27,9 @@ const HTMLImageElement*); virtual ScriptPromise doDetect(ScriptPromiseResolver*, - skia::mojom::blink::BitmapPtr) = 0; + mojo::ScopedSharedBufferHandle, + int imageWidth, + int imageHeight) = 0; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/shapedetection/TextDetector.cpp b/third_party/WebKit/Source/modules/shapedetection/TextDetector.cpp index e53f3c53..d887f9db 100644 --- a/third_party/WebKit/Source/modules/shapedetection/TextDetector.cpp +++ b/third_party/WebKit/Source/modules/shapedetection/TextDetector.cpp
@@ -24,8 +24,11 @@ &TextDetector::onTextServiceConnectionError, wrapWeakPersistent(this)))); } -ScriptPromise TextDetector::doDetect(ScriptPromiseResolver* resolver, - skia::mojom::blink::BitmapPtr bitmap) { +ScriptPromise TextDetector::doDetect( + ScriptPromiseResolver* resolver, + mojo::ScopedSharedBufferHandle sharedBufferHandle, + int imageWidth, + int imageHeight) { ScriptPromise promise = resolver->promise(); if (!m_textService) { resolver->reject(DOMException::create( @@ -33,7 +36,7 @@ return promise; } m_textServiceRequests.insert(resolver); - m_textService->Detect(std::move(bitmap), + m_textService->Detect(std::move(sharedBufferHandle), imageWidth, imageHeight, convertToBaseCallback(WTF::bind( &TextDetector::onDetectText, wrapPersistent(this), wrapPersistent(resolver))));
diff --git a/third_party/WebKit/Source/modules/shapedetection/TextDetector.h b/third_party/WebKit/Source/modules/shapedetection/TextDetector.h index 800893c..64791e3 100644 --- a/third_party/WebKit/Source/modules/shapedetection/TextDetector.h +++ b/third_party/WebKit/Source/modules/shapedetection/TextDetector.h
@@ -29,7 +29,9 @@ ~TextDetector() override = default; ScriptPromise doDetect(ScriptPromiseResolver*, - skia::mojom::blink::BitmapPtr) override; + mojo::ScopedSharedBufferHandle, + int imageWidth, + int imageHeight) override; void onDetectText( ScriptPromiseResolver*, Vector<shape_detection::mojom::blink::TextDetectionResultPtr>);
diff --git a/third_party/WebKit/Source/modules/time_zone_monitor/BUILD.gn b/third_party/WebKit/Source/modules/time_zone_monitor/BUILD.gn index efda79be..fcc3811 100644 --- a/third_party/WebKit/Source/modules/time_zone_monitor/BUILD.gn +++ b/third_party/WebKit/Source/modules/time_zone_monitor/BUILD.gn
@@ -11,7 +11,6 @@ ] deps = [ - "//device/time_zone_monitor/public/interfaces:interfaces_blink", "//mojo/public/cpp/bindings", "//services/device/public/interfaces:interfaces_blink", "//services/service_manager/public/interfaces:interfaces_blink",
diff --git a/third_party/WebKit/Source/modules/time_zone_monitor/DEPS b/third_party/WebKit/Source/modules/time_zone_monitor/DEPS index 212c63f5..11c33b2f 100644 --- a/third_party/WebKit/Source/modules/time_zone_monitor/DEPS +++ b/third_party/WebKit/Source/modules/time_zone_monitor/DEPS
@@ -1,6 +1,6 @@ include_rules = [ - "+device/time_zone_monitor/public/interfaces/time_zone_monitor.mojom-blink.h", "+mojo/public/cpp/bindings/binding.h", "+services/device/public/interfaces/constants.mojom-blink.h", + "+services/device/public/interfaces/time_zone_monitor.mojom-blink.h", "+third_party/icu/source/i18n/unicode/timezone.h", ]
diff --git a/third_party/WebKit/Source/modules/time_zone_monitor/TimeZoneMonitorClient.h b/third_party/WebKit/Source/modules/time_zone_monitor/TimeZoneMonitorClient.h index 0dced07b..5b60daa 100644 --- a/third_party/WebKit/Source/modules/time_zone_monitor/TimeZoneMonitorClient.h +++ b/third_party/WebKit/Source/modules/time_zone_monitor/TimeZoneMonitorClient.h
@@ -5,8 +5,8 @@ #ifndef TimeZoneMonitorClient_h #define TimeZoneMonitorClient_h -#include "device/time_zone_monitor/public/interfaces/time_zone_monitor.mojom-blink.h" #include "mojo/public/cpp/bindings/binding.h" +#include "services/device/public/interfaces/time_zone_monitor.mojom-blink.h" namespace blink {
diff --git a/third_party/WebKit/Source/platform/graphics/paint/FloatClipRect.h b/third_party/WebKit/Source/platform/graphics/paint/FloatClipRect.h index c135f236..bb09206 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/FloatClipRect.h +++ b/third_party/WebKit/Source/platform/graphics/paint/FloatClipRect.h
@@ -6,6 +6,7 @@ #define FloatClipRect_h #include "platform/geometry/FloatRect.h" +#include "platform/geometry/LayoutRect.h" #include "wtf/Allocator.h" namespace blink { @@ -14,24 +15,52 @@ USING_FAST_MALLOC(FloatClipRect); public: - FloatClipRect() : m_hasRadius(false) {} + FloatClipRect() + : m_rect(FloatRect(LayoutRect::infiniteIntRect())), + m_hasRadius(false), + m_isInfinite(true) {} - FloatClipRect(const FloatRect& rect) : m_rect(rect), m_hasRadius(false) {} + FloatClipRect(const FloatRect& rect) + : m_rect(rect), m_hasRadius(false), m_isInfinite(false) {} const FloatRect& rect() const { return m_rect; } - void intersect(const FloatRect& other) { m_rect.intersect(other); } + void intersect(const FloatRect& other) { + if (m_isInfinite) { + m_rect = other; + m_isInfinite = false; + } else { + m_rect.intersect(other); + } + } bool hasRadius() const { return m_hasRadius; } - void setHasRadius(bool hasRadius) { m_hasRadius = hasRadius; } + void setHasRadius(bool hasRadius) { + m_hasRadius = hasRadius; + m_isInfinite = false; + } - void setRect(const FloatRect& rect) { m_rect = rect; } + void setRect(const FloatRect& rect) { + m_rect = rect; + m_isInfinite = false; + } + + bool isInfinite() const { return m_isInfinite; } private: FloatRect m_rect; - bool m_hasRadius; + bool m_hasRadius : 1; + bool m_isInfinite : 1; }; +inline bool operator==(const FloatClipRect& a, const FloatClipRect& b) { + if (a.isInfinite() && b.isInfinite()) + return true; + if (!a.isInfinite() && !b.isInfinite()) + return a.rect() == b.rect() && a.hasRadius() == b.hasRadius(); + return false; +} + } // namespace blink #endif // FloatClipRect_h
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp index 7b39445..a74c867 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp
@@ -46,9 +46,11 @@ localToAncestorVisualRectInternal(rect, sourceState, lcaState, success); if (!success) return result; - FloatRect final = ancestorToLocalRect(result.rect(), lcaTransform, - destinationState.transform()); - result.setRect(final); + if (!result.isInfinite()) { + FloatRect final = ancestorToLocalRect(result.rect(), lcaTransform, + destinationState.transform()); + result.setRect(final); + } return result; } @@ -107,7 +109,8 @@ FloatRect mappedRect = transformMatrix.mapRect(rect); FloatClipRect clipRect = - localToAncestorClipRectInternal(localState, ancestorState, success); + localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(), + ancestorState.transform(), success); if (success) { clipRect.intersect(mappedRect); @@ -208,29 +211,29 @@ return transformMatrix.inverse().mapRect(rect); } -PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor( - const TransformPaintPropertyNode* transform) { - auto addResult = m_data.insert(transform, nullptr); +GeometryMapper::TransformCache& GeometryMapper::getTransformCache( + const TransformPaintPropertyNode* ancestor) { + auto addResult = m_transformCache.insert(ancestor, nullptr); if (addResult.isNewEntry) - addResult.storedValue->value = PrecomputedDataForAncestor::create(); + addResult.storedValue->value = WTF::wrapUnique(new TransformCache); return *addResult.storedValue->value; } -TransformCache& GeometryMapper::getTransformCache( - const TransformPaintPropertyNode* node) { - return getPrecomputedDataForAncestor(node).toAncestorTransforms; -} +GeometryMapper::ClipCache& GeometryMapper::getClipCache( + const ClipPaintPropertyNode* ancestorClip, + const TransformPaintPropertyNode* ancestorTransform) { + auto addResultTransform = m_clipCache.insert(ancestorClip, nullptr); + if (addResultTransform.isNewEntry) { + addResultTransform.storedValue->value = + WTF::wrapUnique(new TransformToClip); + } -ClipCache& GeometryMapper::getClipCache( - const TransformPaintPropertyNode* transform, - const ClipPaintPropertyNode* clip) { - PrecomputedDataForAncestor& precomputedData = - getPrecomputedDataForAncestor(transform); + auto addResultClip = + addResultTransform.storedValue->value->insert(ancestorTransform, nullptr); + if (addResultClip.isNewEntry) + addResultClip.storedValue->value = WTF::wrapUnique(new ClipCache); - auto addResult = precomputedData.precomputedClips.insert(clip, nullptr); - if (addResult.isNewEntry) - addResult.storedValue->value = WTF::makeUnique<ClipCache>(); - return *addResult.storedValue->value; + return *addResultClip.storedValue->value; } FloatClipRect GeometryMapper::localToAncestorClipRect( @@ -238,29 +241,88 @@ const PropertyTreeState& ancestorState) { bool success = false; FloatClipRect result = - localToAncestorClipRectInternal(localState, ancestorState, success); + localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(), + ancestorState.transform(), success); + DCHECK(success); + + return result; +} + +FloatClipRect GeometryMapper::sourceToDestinationClipRect( + const PropertyTreeState& sourceState, + const PropertyTreeState& destinationState) { + bool success = false; + FloatClipRect result = sourceToDestinationClipRectInternal( + sourceState, destinationState, success); + DCHECK(success); + + return result; +} + +FloatClipRect GeometryMapper::sourceToDestinationClipRectInternal( + const PropertyTreeState& sourceState, + const PropertyTreeState& destinationState, + bool& success) { + FloatClipRect result = localToAncestorClipRectInternal( + sourceState.clip(), destinationState.clip(), destinationState.transform(), + success); + // Success if destinationState is an ancestor state. + if (success) + return result; + + // Otherwise first map to the lowest common ancestor, then map to destination. + const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor( + sourceState.transform(), destinationState.transform()); + DCHECK(lcaTransform); + + // Assume that the clip of destinationState is an ancestor of the clip of + // sourceState and is under the space of lcaTransform. Otherwise + // localToAncestorClipRectInternal() will fail. + PropertyTreeState lcaState = destinationState; + lcaState.setTransform(lcaTransform); + + result = localToAncestorClipRectInternal(sourceState.clip(), lcaState.clip(), + lcaState.transform(), success); + if (!success) { + if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { + // On SPv1 we may fail when the paint invalidation container creates an + // overflow clip (in ancestorState) which is not in localState of an + // out-of-flow positioned descendant. See crbug.com/513108 and layout test + // compositing/overflow/handle-non-ancestor-clip-parent.html (run with + // --enable-prefer-compositing-to-lcd-text) for details. + // Ignore it for SPv1 for now. + success = true; + } + return result; + } + if (!result.isInfinite()) { + FloatRect final = ancestorToLocalRect(result.rect(), lcaTransform, + destinationState.transform()); + result.setRect(final); + } return result; } FloatClipRect GeometryMapper::localToAncestorClipRectInternal( - const PropertyTreeState& localState, - const PropertyTreeState& ancestorState, + const ClipPaintPropertyNode* descendant, + const ClipPaintPropertyNode* ancestorClip, + const TransformPaintPropertyNode* ancestorTransform, bool& success) { - FloatClipRect clip(LayoutRect::infiniteIntRect()); - if (localState.clip() == ancestorState.clip()) { + FloatClipRect clip; + if (descendant == ancestorClip) { success = true; + // Return an infinite clip. return clip; } - ClipCache& clipCache = - getClipCache(ancestorState.transform(), ancestorState.clip()); - const ClipPaintPropertyNode* clipNode = localState.clip(); + ClipCache& clipCache = getClipCache(ancestorClip, ancestorTransform); + const ClipPaintPropertyNode* clipNode = descendant; Vector<const ClipPaintPropertyNode*> intermediateNodes; // Iterate over the path from localState.clip to ancestorState.clip. Stop if // we've found a memoized (precomputed) clip for any particular node. - while (clipNode && clipNode != ancestorState.clip()) { + while (clipNode && clipNode != ancestorClip) { auto it = clipCache.find(clipNode); if (it != clipCache.end()) { clip = it->value; @@ -280,7 +342,7 @@ ++it) { success = false; const TransformationMatrix& transformMatrix = localToAncestorMatrixInternal( - (*it)->localTransformSpace(), ancestorState.transform(), success); + (*it)->localTransformSpace(), ancestorTransform, success); if (!success) return clip; FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect()); @@ -291,7 +353,7 @@ } success = true; - return clipCache.find(localState.clip())->value; + return clipCache.find(descendant)->value; } const TransformationMatrix& GeometryMapper::localToAncestorMatrix( @@ -350,7 +412,8 @@ } void GeometryMapper::clearCache() { - m_data.clear(); + m_transformCache.clear(); + m_clipCache.clear(); } namespace {
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h index 6ed23d31..0551407 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h
@@ -12,34 +12,6 @@ namespace blink { -// Maps from a descendant clip node to its equivalent "clip visual rect" in -// the space of the ancestor. The clip visual rect is defined as the -// intersection of all clips between the descendant and the ancestor (*not* -// including the ancestor) in the clip tree, individually transformed from -// their localTransformSpace into the ancestor's localTransformSpace. -// If one of the clip that contributes to it has a border radius, the -// hasRadius() field is set to true. -typedef HashMap<const ClipPaintPropertyNode*, FloatClipRect> ClipCache; - -// Maps from a transform node that is a descendant of the ancestor to the -// combined transform between the descendant's and the ancestor's coordinate -typedef HashMap<const TransformPaintPropertyNode*, TransformationMatrix> - TransformCache; - -struct PrecomputedDataForAncestor { - TransformCache toAncestorTransforms; - - // There can be multiple clips within the same transform space. This - // maps from the desired destination clip within the same transform - // space to its corresponding ClipCache. - HashMap<const ClipPaintPropertyNode*, std::unique_ptr<ClipCache>> - precomputedClips; - - static std::unique_ptr<PrecomputedDataForAncestor> create() { - return WTF::makeUnique<PrecomputedDataForAncestor>(); - } -}; - // GeometryMapper is a helper class for fast computations of transformed and // visual rects in different PropertyTreeStates. The design document has a // number of details on use cases, algorithmic definitions, and running times. @@ -139,6 +111,12 @@ const PropertyTreeState& localTransformState, const PropertyTreeState& ancestorState); + // Like localToAncestorClipRect, except it can handle destination transform + // spaces which are not direct ancestors of the source transform space. + FloatClipRect sourceToDestinationClipRect( + const PropertyTreeState& sourceState, + const PropertyTreeState& destinationState); + // Returns the lowest common ancestor in the paint property tree. template <typename NodeType> static PLATFORM_EXPORT const NodeType* lowestCommonAncestor(const NodeType*, @@ -179,8 +157,14 @@ bool& success); FloatClipRect localToAncestorClipRectInternal( - const PropertyTreeState& localTransformState, - const PropertyTreeState& ancestorState, + const ClipPaintPropertyNode* descendant, + const ClipPaintPropertyNode* ancestorClip, + const TransformPaintPropertyNode* ancestorTransform, + bool& success); + + FloatClipRect sourceToDestinationClipRectInternal( + const PropertyTreeState& sourceState, + const PropertyTreeState& destinationState, bool& success); FloatClipRect slowLocalToAncestorVisualRectWithEffects( @@ -189,24 +173,43 @@ const PropertyTreeState& ancestorState, bool& success); - // Returns the precomputed data if already set, or adds and memoizes a new - // PrecomputedDataForAncestor otherwise. - PrecomputedDataForAncestor& getPrecomputedDataForAncestor( - const TransformPaintPropertyNode*); + // Maps from a transform node that is a descendant of the implied ancestor + // transform node to the combined transform between the descendant's and the + // ancestor's coordinate space. + // The "implied ancestor" is the key of the m_transformCache object for which + // this TransformCache is a value. + using TransformCache = + HashMap<const TransformPaintPropertyNode*, TransformationMatrix>; // Returns the transform cache for the given ancestor transform node. - TransformCache& getTransformCache(const TransformPaintPropertyNode*); + TransformCache& getTransformCache(const TransformPaintPropertyNode* ancestor); - // Returns the clip cache for the given ancestor clip node. - ClipCache& getClipCache(const TransformPaintPropertyNode*, - const ClipPaintPropertyNode*); + // Maps from a descendant clip node to its equivalent "clip visual rect" in + // the local transform space of the implied ancestor clip node. The clip + // visual rect is defined as the intersection of all clips between the + // descendant and the ancestor (*not* including the ancestor) in the clip + // tree, individually transformed from their localTransformSpace into the + // ancestor's localTransformSpace. If one of the clips that contributes to it + // has a border radius, the hasRadius() field is set to true. + // The "implied ancestor" is the key of the TransformToClip cachefor which + // this ClipCache is a value. + using ClipCache = HashMap<const ClipPaintPropertyNode*, FloatClipRect>; + + using TransformToClip = + HashMap<const TransformPaintPropertyNode*, std::unique_ptr<ClipCache>>; + + // Returns the clip cache for the given transform space relative to the + // given ancestor clip node. + ClipCache& getClipCache(const ClipPaintPropertyNode* ancestorClip, + const TransformPaintPropertyNode* ancestorTransform); friend class GeometryMapperTest; friend class PaintLayerClipperTest; - HashMap<const TransformPaintPropertyNode*, - std::unique_ptr<PrecomputedDataForAncestor>> - m_data; + HashMap<const TransformPaintPropertyNode*, std::unique_ptr<TransformCache>> + m_transformCache; + HashMap<const ClipPaintPropertyNode*, std::unique_ptr<TransformToClip>> + m_clipCache; const TransformationMatrix m_identity;
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp index c18e722c..f4a913e 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp
@@ -31,14 +31,15 @@ return state; } - TransformCache& getTransformCache( + GeometryMapper::TransformCache& getTransformCache( const PropertyTreeState& propertyTreeState) { return geometryMapper->getTransformCache(propertyTreeState.transform()); } - ClipCache& getClipCache(const PropertyTreeState& propertyTreeState) { - return geometryMapper->getClipCache(propertyTreeState.transform(), - propertyTreeState.clip()); + GeometryMapper::ClipCache& getClipCache( + const PropertyTreeState& propertyTreeState) { + return geometryMapper->getClipCache(propertyTreeState.clip(), + propertyTreeState.transform()); } const TransformPaintPropertyNode* lowestCommonAncestor( @@ -105,6 +106,13 @@ << ", expected: " << expected.height(); \ } while (false) +#define EXPECT_CLIP_RECT_EQ(expected, actual) \ + do { \ + EXPECT_EQ(expected.isInfinite(), actual.isInfinite()); \ + if (!expected.isInfinite()) \ + EXPECT_RECT_EQ(expected.rect(), actual.rect()); \ + } while (false) + #define CHECK_MAPPINGS(inputRect, expectedVisualRect, expectedTransformedRect, \ expectedTransformToAncestor, \ expectedClipInAncestorSpace, localPropertyTreeState, \ @@ -117,7 +125,7 @@ clipRect = geometryMapper->localToAncestorClipRect( \ localPropertyTreeState, ancestorPropertyTreeState); \ EXPECT_EQ(hasRadius, clipRect.hasRadius()); \ - EXPECT_RECT_EQ(expectedClipInAncestorSpace, clipRect.rect()); \ + EXPECT_CLIP_RECT_EQ(expectedClipInAncestorSpace, clipRect); \ clipRect = geometryMapper->sourceToDestinationVisualRect( \ inputRect, localPropertyTreeState, ancestorPropertyTreeState); \ EXPECT_EQ(hasRadius, clipRect.hasRadius()); \ @@ -139,8 +147,12 @@ if (ancestorPropertyTreeState.clip() != localPropertyTreeState.clip()) { \ EXPECT_EQ(expectedClipInAncestorSpace, \ getClipCache(ancestorPropertyTreeState) \ - .get(localPropertyTreeState.clip()) \ - .rect()); \ + .get(localPropertyTreeState.clip())) \ + << expectedClipInAncestorSpace.rect().toString() << " " \ + << getClipCache(ancestorPropertyTreeState) \ + .get(localPropertyTreeState.clip()) \ + .rect() \ + .toString(); \ } \ } while (false) @@ -149,8 +161,7 @@ bool hasRadius = false; CHECK_MAPPINGS(input, input, input, - TransformPaintPropertyNode::root()->matrix(), - ClipPaintPropertyNode::root()->clipRect().rect(), + TransformPaintPropertyNode::root()->matrix(), FloatClipRect(), rootPropertyTreeState(), rootPropertyTreeState(), hasRadius); } @@ -165,9 +176,8 @@ FloatRect input(0, 0, 100, 100); bool hasRadius = false; - CHECK_MAPPINGS(input, input, input, transform->matrix(), - ClipPaintPropertyNode::root()->clipRect().rect(), localState, - rootPropertyTreeState(), hasRadius); + CHECK_MAPPINGS(input, input, input, transform->matrix(), FloatClipRect(), + localState, rootPropertyTreeState(), hasRadius); } TEST_F(GeometryMapperTest, TranslationTransform) { @@ -183,9 +193,8 @@ FloatRect output = transformMatrix.mapRect(input); bool hasRadius = false; - CHECK_MAPPINGS(input, output, output, transform->matrix(), - ClipPaintPropertyNode::root()->clipRect().rect(), localState, - rootPropertyTreeState(), hasRadius); + CHECK_MAPPINGS(input, output, output, transform->matrix(), FloatClipRect(), + localState, rootPropertyTreeState(), hasRadius); EXPECT_RECT_EQ(input, geometryMapper->ancestorToLocalRect( output, rootPropertyTreeState().transform(), @@ -207,9 +216,8 @@ FloatRect output = transformMatrix.mapRect(input); bool hasRadius = false; - CHECK_MAPPINGS(input, output, output, transformMatrix, - ClipPaintPropertyNode::root()->clipRect().rect(), localState, - rootPropertyTreeState(), hasRadius); + CHECK_MAPPINGS(input, output, output, transformMatrix, FloatClipRect(), + localState, rootPropertyTreeState(), hasRadius); } TEST_F(GeometryMapperTest, RotationAndScaleTransformWithTransformOrigin) { @@ -228,9 +236,8 @@ FloatRect output = transformMatrix.mapRect(input); bool hasRadius = false; - CHECK_MAPPINGS(input, output, output, transformMatrix, - ClipPaintPropertyNode::root()->clipRect().rect(), localState, - rootPropertyTreeState(), hasRadius); + CHECK_MAPPINGS(input, output, output, transformMatrix, FloatClipRect(), + localState, rootPropertyTreeState(), hasRadius); } TEST_F(GeometryMapperTest, NestedTransforms) { @@ -254,8 +261,7 @@ FloatRect output = final.mapRect(input); bool hasRadius = false; - CHECK_MAPPINGS(input, output, output, final, - ClipPaintPropertyNode::root()->clipRect().rect(), localState, + CHECK_MAPPINGS(input, output, output, final, FloatClipRect(), localState, rootPropertyTreeState(), hasRadius); // Check the cached matrix for the intermediate transform. @@ -286,8 +292,7 @@ FloatRect output = final.mapRect(input); bool hasRadius = false; - CHECK_MAPPINGS(input, output, output, final, - ClipPaintPropertyNode::root()->clipRect().rect(), localState, + CHECK_MAPPINGS(input, output, output, final, FloatClipRect(), localState, rootPropertyTreeState(), hasRadius); // Check the cached matrix for the intermediate transform. @@ -319,9 +324,8 @@ FloatRect output = scaleTransform.mapRect(input); bool hasRadius = false; - CHECK_MAPPINGS(input, output, output, scaleTransform, - ClipPaintPropertyNode::root()->clipRect().rect(), localState, - intermediateState, hasRadius); + CHECK_MAPPINGS(input, output, output, scaleTransform, FloatClipRect(), + localState, intermediateState, hasRadius); } TEST_F(GeometryMapperTest, SimpleClip) { @@ -340,8 +344,9 @@ output, // Visual rect input, // Transformed rect (not clipped). TransformPaintPropertyNode::root() - ->matrix(), // Transform matrix to ancestor space - clip->clipRect().rect(), // Clip rect in ancestor space + ->matrix(), // Transform matrix to ancestor space + FloatClipRect(clip->clipRect().rect()), // Clip rect in + // ancestor space localState, rootPropertyTreeState(), hasRadius); } @@ -359,13 +364,16 @@ FloatRect input(0, 0, 100, 100); FloatRect output(10, 10, 50, 50); + FloatClipRect expectedClip(clip->clipRect().rect()); + expectedClip.setHasRadius(true); + bool hasRadius = true; CHECK_MAPPINGS(input, // Input output, // Visual rect input, // Transformed rect (not clipped). TransformPaintPropertyNode::root() - ->matrix(), // Transform matrix to ancestor space - clip->clipRect().rect(), // Clip rect in ancestor space + ->matrix(), // Transform matrix to ancestor space + expectedClip, // Clip rect in ancestor space localState, rootPropertyTreeState(), hasRadius); } @@ -391,26 +399,81 @@ FloatRect input(0, 0, 100, 100); FloatRect output1(10, 10, 30, 40); + FloatClipRect clipRect(clip1->clipRect().rect()); + clipRect.setHasRadius(true); + bool hasRadius = true; CHECK_MAPPINGS(input, // Input output1, // Visual rect input, // Transformed rect (not clipped). TransformPaintPropertyNode::root() ->matrix(), // Transform matrix to ancestor space - clip1->clipRect().rect(), // Clip rect in ancestor space + clipRect, // Clip rect in ancestor space localState, ancestorState, hasRadius); ancestorState.setClip(clip1.get()); FloatRect output2(10, 10, 50, 50); + clipRect.setRect(clip2->clipRect().rect()); + hasRadius = false; CHECK_MAPPINGS(input, // Input output2, // Visual rect input, // Transformed rect (not clipped). TransformPaintPropertyNode::root() ->matrix(), // Transform matrix to ancestor space - clip2->clipRect().rect(), // Clip rect in ancestor space + clipRect, // Clip rect in ancestor space + localState, + ancestorState, hasRadius); +} + +TEST_F(GeometryMapperTest, TwoClipsTransformAbove) { + RefPtr<TransformPaintPropertyNode> transform = + TransformPaintPropertyNode::create(rootPropertyTreeState().transform(), + TransformationMatrix(), + FloatPoint3D()); + + FloatRoundedRect clipRect1( + FloatRect(10, 10, 50, 50), + FloatRoundedRect::Radii(FloatSize(1, 1), FloatSize(), FloatSize(), + FloatSize())); + + RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create( + ClipPaintPropertyNode::root(), transform.get(), clipRect1); + + RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create( + clip1, transform.get(), FloatRoundedRect(10, 10, 30, 40)); + + PropertyTreeState localState = rootPropertyTreeState(); + PropertyTreeState ancestorState = rootPropertyTreeState(); + localState.setClip(clip2.get()); + + FloatRect input(0, 0, 100, 100); + FloatRect output1(10, 10, 30, 40); + + FloatClipRect expectedClip(clip2->clipRect().rect()); + expectedClip.setHasRadius(true); + + bool hasRadius = true; + CHECK_MAPPINGS(input, // Input + output1, // Visual rect + input, // Transformed rect (not clipped). + TransformPaintPropertyNode::root() + ->matrix(), // Transform matrix to ancestor space + expectedClip, // Clip rect in ancestor space + localState, + ancestorState, hasRadius); + + expectedClip.setRect(clip1->clipRect().rect()); + localState.setClip(clip1.get()); + FloatRect output2(10, 10, 50, 50); + CHECK_MAPPINGS(input, // Input + output2, // Visual rect + input, // Transformed rect (not clipped). + TransformPaintPropertyNode::root() + ->matrix(), // Transform matrix to ancestor space + expectedClip, // Clip rect in ancestor space localState, ancestorState, hasRadius); } @@ -441,8 +504,8 @@ output, // Visual rect rotateTransform.mapRect(input), // Transformed rect (not clipped). rotateTransform, // Transform matrix to ancestor space - rotateTransform.mapRect( - clip->clipRect().rect()), // Clip rect in ancestor space + FloatClipRect(rotateTransform.mapRect( + clip->clipRect().rect())), // Clip rect in ancestor space localState, rootPropertyTreeState(), hasRadius); } @@ -473,7 +536,7 @@ output, // Visual rect rotateTransform.mapRect(input), // Transformed rect (not clipped) rotateTransform, // Transform matrix to ancestor space - clip->clipRect().rect(), // Clip rect in ancestor space + FloatClipRect(clip->clipRect().rect()), // Clip rect in ancestor space localState, rootPropertyTreeState(), hasRadius); } @@ -508,7 +571,7 @@ output, // Visual rect rotateTransform.mapRect(input), // Transformed rect (not clipped) rotateTransform, // Transform matrix to ancestor space - clip1->clipRect().rect(), // Clip rect in ancestor space + FloatClipRect(clip1->clipRect().rect()), // Clip rect in ancestor space localState, rootPropertyTreeState(), hasRadius); } @@ -534,7 +597,7 @@ output, // Visual rect rotateTransform.mapRect(input), // Transformed rect (not clipped) rotateTransform, // Transform matrix to ancestor space - mappedClip, // Clip rect in ancestor space + FloatClipRect(mappedClip), // Clip rect in ancestor space localState, rootPropertyTreeState(), hasRadius); } } @@ -747,8 +810,8 @@ CHECK_MAPPINGS( input, output, FloatRect(0, 0, 300, 300), transformAboveEffect->matrix() * transformBelowEffect->matrix(), - FloatRect(30, 30, 270, 270), localState, rootPropertyTreeState(), - hasRadius); + FloatClipRect(FloatRect(30, 30, 270, 270)), localState, + rootPropertyTreeState(), hasRadius); } TEST_F(GeometryMapperTest, ReflectionWithPaintOffset) { @@ -768,9 +831,8 @@ FloatRect output(50, 100, 100, 50); bool hasRadius = false; - CHECK_MAPPINGS(input, output, input, TransformationMatrix(), - ClipPaintPropertyNode::root()->clipRect().rect(), localState, - rootPropertyTreeState(), hasRadius); + CHECK_MAPPINGS(input, output, input, TransformationMatrix(), FloatClipRect(), + localState, rootPropertyTreeState(), hasRadius); } } // namespace blink
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py index 73311ca6..dc1ece7d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/controllers/manager.py
@@ -96,16 +96,31 @@ self._printer.write_update("Collecting tests ...") running_all_tests = False try: - paths, test_names, running_all_tests = self._collect_tests(args) + paths, all_test_names, running_all_tests = self._collect_tests(args) except IOError: # This is raised if --test-list doesn't exist return test_run_results.RunDetails(exit_code=test_run_results.NO_TESTS_EXIT_STATUS) + # Create a sorted list of test files so the subset chunk, + # if used, contains alphabetically consecutive tests. + if self._options.order == 'natural': + all_test_names.sort(key=self._port.test_key) + elif self._options.order == 'random': + all_test_names.sort() + random.Random(self._options.seed).shuffle(all_test_names) + + test_names, tests_in_other_chunks = self._finder.split_into_chunks(all_test_names) + self._printer.write_update("Parsing expectations ...") self._expectations = test_expectations.TestExpectations(self._port, test_names) tests_to_run, tests_to_skip = self._prepare_lists(paths, test_names) - self._printer.print_found(len(test_names), len(tests_to_run), self._options.repeat_each, self._options.iterations) + + self._expectations.remove_tests(tests_in_other_chunks) + + self._printer.print_found( + len(all_test_names), len(test_names), len(tests_to_run), + self._options.repeat_each, self._options.iterations) # Check to make sure we're not skipping every test. if not tests_to_run: @@ -242,21 +257,6 @@ tests_to_skip = self._finder.skip_tests(paths, test_names, self._expectations, self._http_tests(test_names)) tests_to_run = [test for test in test_names if test not in tests_to_skip] - if not tests_to_run: - return tests_to_run, tests_to_skip - - # Create a sorted list of test files so the subset chunk, - # if used, contains alphabetically consecutive tests. - if self._options.order == 'natural': - tests_to_run.sort(key=self._port.test_key) - elif self._options.order == 'random': - tests_to_run.sort() - random.Random(self._options.seed).shuffle(tests_to_run) - - tests_to_run, tests_in_other_chunks = self._finder.split_into_chunks(tests_to_run) - self._expectations.add_extra_skipped_tests(tests_in_other_chunks) - tests_to_skip.update(tests_in_other_chunks) - return tests_to_run, tests_to_skip def _test_input_for_file(self, test_file):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py index 6d1aee2..38d7593 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py
@@ -1174,6 +1174,11 @@ model.add_expectation_line(expectation_line) self._model.merge_model(model) + def remove_tests(self, tests_to_remove): + for test in self._expectations: + if test.name and test.name in tests_to_remove: + self.remove_expectation_line(test) + def add_expectations_from_bot(self): # FIXME: With mode 'very-flaky' and 'maybe-flaky', this will show the expectations entry in the flakiness # dashboard rows for each test to be whatever the bot thinks they should be. Is this a good thing?
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/printing.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/printing.py index 3170b040..3f281ba 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/printing.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/printing.py
@@ -101,11 +101,14 @@ self._print_default('Command line: ' + ' '.join(self._port.driver_cmd_line())) self._print_default('') - def print_found(self, num_all_test_files, num_to_run, repeat_each, iterations): - found_str = 'Found %s; running %d' % (grammar.pluralize('test', num_all_test_files), num_to_run) + def print_found(self, num_all_test_files, num_shard_test_files, num_to_run, repeat_each, iterations): + found_str = 'Found %s' % grammar.pluralize('test', num_shard_test_files) + if num_all_test_files != num_shard_test_files: + found_str += ' (total %d)' % num_all_test_files + found_str += '; running %d' % num_to_run if repeat_each * iterations > 1: found_str += ' (%d times each: --repeat-each=%d --iterations=%d)' % (repeat_each * iterations, repeat_each, iterations) - found_str += ', skipping %d' % (num_all_test_files - num_to_run) + found_str += ', skipping %d' % (num_shard_test_files - num_to_run) self._print_default(found_str + '.') def print_expected(self, run_results, tests_with_result_type_callback):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/printing_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/printing_unittest.py index 58a05d5..d0343cb 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/printing_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/layout_tests/views/printing_unittest.py
@@ -232,11 +232,16 @@ def test_print_found(self): printer, err = self.get_printer() - printer.print_found(100, 10, 1, 1) + self.reset(err) + printer.print_found(100, 100, 10, 1, 1) self.assertWritten(err, ["Found 100 tests; running 10, skipping 90.\n"]) self.reset(err) - printer.print_found(100, 10, 2, 3) + printer.print_found(100, 20, 10, 1, 1) + self.assertWritten(err, ["Found 20 tests (total 100); running 10, skipping 10.\n"]) + + self.reset(err) + printer.print_found(100, 100, 10, 2, 3) self.assertWritten(err, ["Found 100 tests; running 10 (6 times each: --repeat-each=2 --iterations=3), skipping 90.\n"]) def test_debug_rwt_logging_is_throttled(self):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/chromium_commit.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/chromium_commit.py index aba9101..efc1e57 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/chromium_commit.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/chromium_commit.py
@@ -20,6 +20,8 @@ 'refs/heads/master@{#431915}' """ self.host = host + self.absolute_chromium_dir = absolute_chromium_dir(host) + self.absolute_chromium_wpt_dir = absolute_chromium_wpt_dir(host) assert sha or position, 'requires sha or position' assert not (sha and position), 'cannot accept both sha and position' @@ -34,9 +36,6 @@ self.sha = sha self.position = position - self.absolute_chromium_dir = absolute_chromium_dir(host) - self.absolute_chromium_wpt_dir = absolute_chromium_wpt_dir(host) - def num_behind_master(self): """Returns the number of commits this commit is behind origin/master. It is inclusive of this commit and of the latest commit. @@ -48,7 +47,7 @@ def position_to_sha(self, commit_position): return self.host.executive.run_command([ 'git', 'crrev-parse', commit_position - ], cwd=absolute_chromium_dir).strip() + ], cwd=self.absolute_chromium_dir).strip() def subject(self): return self.host.executive.run_command([ @@ -58,7 +57,7 @@ def body(self): return self.host.executive.run_command([ 'git', 'show', '--format=%b', '--no-patch', self.sha - ], cwd=absolute_chromium_dir) + ], cwd=self.absolute_chromium_dir) def author(self): return self.host.executive.run_command([
diff --git a/tools/json_schema_compiler/test/error_generation_unittest.cc b/tools/json_schema_compiler/test/error_generation_unittest.cc index 5c3f1b8..73fcfdc 100644 --- a/tools/json_schema_compiler/test/error_generation_unittest.cc +++ b/tools/json_schema_compiler/test/error_generation_unittest.cc
@@ -5,6 +5,7 @@ #include "tools/json_schema_compiler/test/error_generation.h" #include "base/json/json_writer.h" +#include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "testing/gtest/include/gtest/gtest.h" #include "tools/json_schema_compiler/test/test_util.h" @@ -39,7 +40,7 @@ EXPECT_TRUE(EqualsUtf16("", GetPopulateError<TestType>(*value))); } { - std::unique_ptr<base::BinaryValue> value(new base::BinaryValue()); + auto value = base::MakeUnique<base::Value>(base::Value::Type::BINARY); EXPECT_TRUE(EqualsUtf16("expected dictionary, got binary", GetPopulateError<TestType>(*value))); } @@ -52,7 +53,7 @@ GetPopulateError<ChoiceType::Integers>(*value))); } { - std::unique_ptr<base::BinaryValue> value(new base::BinaryValue()); + auto value = base::MakeUnique<base::Value>(base::Value::Type::BINARY); EXPECT_TRUE(EqualsUtf16("expected integers or integer, got binary", GetPopulateError<ChoiceType::Integers>(*value))); } @@ -178,7 +179,7 @@ TEST(JsonSchemaCompilerErrorTest, BinaryTypeExpected) { { std::unique_ptr<base::DictionaryValue> value = - Dictionary("data", new base::BinaryValue()); + Dictionary("data", new base::Value(base::Value::Type::BINARY)); EXPECT_TRUE(EqualsUtf16("", GetPopulateError<BinaryData>(*value))); } { @@ -244,7 +245,7 @@ TEST(JsonSchemaCompilerErrorTest, OptionalBinaryTypeFailure) { { std::unique_ptr<base::DictionaryValue> value = - Dictionary("data", new base::BinaryValue()); + Dictionary("data", new base::Value(base::Value::Type::BINARY)); EXPECT_TRUE(EqualsUtf16("", GetPopulateError<OptionalBinaryData>(*value))); } {
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index 6e5631b..bc9223a5 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -65,7 +65,6 @@ "//ui/display", "//ui/gfx", "//ui/gfx/geometry", - "//url", ] }
diff --git a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java index 97c1e48..9a9d89b 100644 --- a/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java +++ b/ui/android/java/src/org/chromium/ui/base/ViewAndroidDelegate.java
@@ -5,7 +5,6 @@ package org.chromium.ui.base; import android.content.ClipData; -import android.content.Intent; import android.graphics.Bitmap; import android.os.Build; import android.view.View; @@ -14,27 +13,18 @@ import android.widget.ImageView; import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; -import java.net.URISyntaxException; - /** * Class to acquire, position, and remove anchor views from the implementing View. */ @JNINamespace("ui") public abstract class ViewAndroidDelegate { - private static final String TAG = "ViewAndroidDelegate"; - // TODO(hush): use View#DRAG_FLAG_GLOBAL when Chromium starts to build with API 24. private static final int DRAG_FLAG_GLOBAL = 1 << 8; - private static final String GEO_SCHEME = "geo"; - private static final String TEL_SCHEME = "tel"; - private static final String MAILTO_SCHEME = "mailto"; - /** * @return An anchor view that can be used to anchor decoration views like Autofill popup. */ @@ -115,57 +105,6 @@ } /** - * Called whenever the background color of the page changes as notified by Blink. - * @param color The new ARGB color of the page background. - */ - @CalledByNative - public void onBackgroundColorChanged(int color) {} - - /** - * Notify the client of the position of the top controls. - * @param topControlsOffsetY The Y offset of the top controls in physical pixels. - * @param topContentOffsetY The Y offset of the content in physical pixels. - */ - @CalledByNative - public void onTopControlsChanged(float topControlsOffsetY, float topContentOffsetY) {} - - /** - * Notify the client of the position of the bottom controls. - * @param bottomControlsOffsetY The Y offset of the bottom controls in physical pixels. - * @param bottomContentOffsetY The Y offset of the content in physical pixels. - */ - @CalledByNative - public void onBottomControlsChanged(float bottomControlsOffsetY, float bottomContentOffsetY) {} - - /** - * Called when a new content intent is requested to be started. - * Invokes {@link #startContentIntent(Intent, String, boolean)} only if the parsed - * intent is valid and the scheme is acceptable. - */ - @CalledByNative - private void onStartContentIntent(String intentUrl, boolean isMainFrame) { - Intent intent; - try { - intent = Intent.parseUri(intentUrl, Intent.URI_INTENT_SCHEME); - } catch (URISyntaxException e) { - Log.d(TAG, "Bad URI %s", intentUrl, e); - return; - } - String scheme = intent.getScheme(); - if (!(GEO_SCHEME.equals(scheme) || TEL_SCHEME.equals(scheme) - || MAILTO_SCHEME.equals(scheme))) { - Log.d(TAG, "Invalid scheme for URI %s", intentUrl); - return; - } - startContentIntent(intent, intentUrl, isMainFrame); - } - - /** - * Start a new content intent. - */ - public void startContentIntent(Intent intent, String intentUrl, boolean isMainFrame) {} - - /** * @return container view that the anchor views are added to. May be null. */ @CalledByNative
diff --git a/ui/android/view_android.cc b/ui/android/view_android.cc index e1716c14..43f084f 100644 --- a/ui/android/view_android.cc +++ b/ui/android/view_android.cc
@@ -7,17 +7,14 @@ #include <algorithm> #include "base/android/jni_android.h" -#include "base/android/jni_string.h" #include "cc/layers/layer.h" #include "jni/ViewAndroidDelegate_jni.h" #include "ui/android/window_android.h" #include "ui/display/display.h" #include "ui/display/screen.h" -#include "url/gurl.h" namespace ui { -using base::android::ConvertUTF8ToJavaString; using base::android::JavaRef; using base::android::ScopedJavaLocalRef; @@ -218,9 +215,7 @@ if (delegate.is_null()) return false; JNIEnv* env = base::android::AttachCurrentThread(); - return Java_ViewAndroidDelegate_startDragAndDrop(env, - delegate, - jtext, + return Java_ViewAndroidDelegate_startDragAndDrop(env, delegate, jtext, jimage); } @@ -246,52 +241,4 @@ return false; } -void ViewAndroid::OnBackgroundColorChanged(unsigned int color) { - ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); - if (delegate.is_null()) - return; - JNIEnv* env = base::android::AttachCurrentThread(); - Java_ViewAndroidDelegate_onBackgroundColorChanged(env, - delegate, - color); -} - -void ViewAndroid::OnTopControlsChanged(float top_controls_offset, - float top_content_offset) { - ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); - if (delegate.is_null()) - return; - JNIEnv* env = base::android::AttachCurrentThread(); - Java_ViewAndroidDelegate_onTopControlsChanged(env, - delegate, - top_controls_offset, - top_content_offset); -} - -void ViewAndroid::OnBottomControlsChanged(float bottom_controls_offset, - float bottom_content_offset) { - ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); - if (delegate.is_null()) - return; - JNIEnv* env = base::android::AttachCurrentThread(); - Java_ViewAndroidDelegate_onBottomControlsChanged(env, - delegate, - bottom_controls_offset, - bottom_content_offset); -} - -void ViewAndroid::StartContentIntent(const GURL& content_url, - bool is_main_frame) { - ScopedJavaLocalRef<jobject> delegate(GetViewAndroidDelegate()); - if (delegate.is_null()) - return; - JNIEnv* env = base::android::AttachCurrentThread(); - ScopedJavaLocalRef<jstring> jcontent_url = - ConvertUTF8ToJavaString(env, content_url.spec()); - Java_ViewAndroidDelegate_onStartContentIntent(env, - delegate, - jcontent_url, - is_main_frame); - -} } // namespace ui
diff --git a/ui/android/view_android.h b/ui/android/view_android.h index 22780e6b..e446048 100644 --- a/ui/android/view_android.h +++ b/ui/android/view_android.h
@@ -13,8 +13,6 @@ #include "ui/android/view_client.h" #include "ui/gfx/geometry/rect_f.h" -class GURL; - namespace cc { class Layer; } @@ -104,14 +102,6 @@ bool StartDragAndDrop(const base::android::JavaRef<jstring>& jtext, const base::android::JavaRef<jobject>& jimage); - void OnBackgroundColorChanged(unsigned int color); - void OnTopControlsChanged(float top_controls_offset, - float top_content_offset); - void OnBottomControlsChanged(float bottom_controls_offset, - float bottom_content_offset); - void StartContentIntent(const GURL& content_url, - bool is_main_frame); - ScopedAnchorView AcquireAnchorView(); void SetAnchorRect(const base::android::JavaRef<jobject>& anchor, const gfx::RectF& bounds);
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index c748054..b0b8e8ae8 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -170,6 +170,8 @@ "shadow_value.h", "skbitmap_operations.cc", "skbitmap_operations.h", + "skia_color_space_util.cc", + "skia_color_space_util.h", "skia_util.cc", "skia_util.h", "switches.cc",
diff --git a/ui/gfx/color_space.cc b/ui/gfx/color_space.cc index e0eb7b94..0f5a42b 100644 --- a/ui/gfx/color_space.cc +++ b/ui/gfx/color_space.cc
@@ -10,30 +10,11 @@ #include "base/synchronization/lock.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "ui/gfx/icc_profile.h" +#include "ui/gfx/skia_color_space_util.h" #include "ui/gfx/transform.h" namespace gfx { -namespace { - -SkColorSpaceTransferFn InvertTransferFn(SkColorSpaceTransferFn fn) { - SkColorSpaceTransferFn fn_inv = {0}; - if (fn.fA > 0 && fn.fG > 0) { - double a_to_the_g = pow(fn.fA, fn.fG); - fn_inv.fA = 1.f / a_to_the_g; - fn_inv.fB = -fn.fE / a_to_the_g; - fn_inv.fG = 1.f / fn.fG; - } - fn_inv.fD = fn.fC * fn.fD + fn.fF; - fn_inv.fE = -fn.fB / fn.fA; - if (fn.fC != 0) { - fn_inv.fC = 1.f / fn.fC; - fn_inv.fF = -fn.fF / fn.fC; - } - return fn_inv; -} -}; - ColorSpace::PrimaryID ColorSpace::PrimaryIDFromInt(int primary_id) { if (primary_id < 0 || primary_id > static_cast<int>(PrimaryID::LAST)) return PrimaryID::UNKNOWN; @@ -486,7 +467,7 @@ bool ColorSpace::GetInverseTransferFunction(SkColorSpaceTransferFn* fn) const { if (!GetTransferFunction(fn)) return false; - *fn = InvertTransferFn(*fn); + *fn = SkTransferFnInverse(*fn); return true; }
diff --git a/ui/gfx/color_space.h b/ui/gfx/color_space.h index d0fe36e8..798b9305a 100644 --- a/ui/gfx/color_space.h +++ b/ui/gfx/color_space.h
@@ -21,7 +21,6 @@ namespace gfx { class ICCProfile; -class ColorSpaceToColorSpaceTransform; // Used to represet a color space for the purpose of color conversion. // This is designed to be safe and compact enough to send over IPC @@ -207,7 +206,8 @@ sk_sp<SkColorSpace> icc_profile_sk_color_space_; friend class ICCProfile; - friend class ColorSpaceToColorSpaceTransform; + friend class ColorTransform; + friend class ColorTransformInternal; friend class ColorSpaceWin; friend struct IPC::ParamTraits<gfx::ColorSpace>; FRIEND_TEST_ALL_PREFIXES(SimpleColorSpace, GetColorSpace);
diff --git a/ui/gfx/color_transform.cc b/ui/gfx/color_transform.cc index ecc8aaf2..49a3026 100644 --- a/ui/gfx/color_transform.cc +++ b/ui/gfx/color_transform.cc
@@ -5,14 +5,17 @@ #include "ui/gfx/color_transform.h" #include <algorithm> -#include <vector> +#include <cmath> +#include <list> +#include <memory> #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "third_party/qcms/src/qcms.h" #include "ui/gfx/color_space.h" #include "ui/gfx/icc_profile.h" +#include "ui/gfx/skia_color_space_util.h" #include "ui/gfx/transform.h" -#include "third_party/qcms/src/qcms.h" #ifndef THIS_MUST_BE_INCLUDED_AFTER_QCMS_H extern "C" { @@ -20,15 +23,26 @@ }; #endif +using std::exp; +using std::log; +using std::max; +using std::min; +using std::pow; +using std::sqrt; + namespace gfx { -float EvalSkTransferFn(const SkColorSpaceTransferFn& fn, float x) { - if (x < 0) - return 0; - if (x < fn.fD) - return fn.fC * x + fn.fF; - return powf(fn.fA * x + fn.fB, fn.fG) + fn.fE; -} +namespace { + +// Helper for scoped QCMS profiles. +struct QcmsProfileDeleter { + void operator()(qcms_profile* p) { + if (p) { + qcms_profile_release(p); + } + } +}; +using ScopedQcmsProfile = std::unique_ptr<qcms_profile, QcmsProfileDeleter>; Transform Invert(const Transform& t) { Transform ret = t; @@ -58,11 +72,11 @@ float a = 1.099296826809442f; float b = 0.018053968510807f; if (v < -b) { - return -a * powf(-v, 0.45f) + (a - 1.0f); + return -a * pow(-v, 0.45f) + (a - 1.0f); } else if (v <= b) { return 4.5f * v; } else { - return a * powf(v, 0.45f) - (a - 1.0f); + return a * pow(v, 0.45f) - (a - 1.0f); } } @@ -71,24 +85,24 @@ float b = 0.018f; float l = 0.0045f; if (v < -l) { - return -(a * powf(-4.0f * v, 0.45f) + (a - 1.0f)) / 4.0f; + return -(a * pow(-4.0f * v, 0.45f) + (a - 1.0f)) / 4.0f; } else if (v <= b) { return 4.5f * v; } else { - return a * powf(v, 0.45f) - (a - 1.0f); + return a * pow(v, 0.45f) - (a - 1.0f); } } case ColorSpace::TransferID::SMPTEST2084: { // Go from scRGB levels to 0-1. v *= 80.0f / 10000.0f; - v = fmax(0.0f, v); + v = max(0.0f, v); float m1 = (2610.0f / 4096.0f) / 4.0f; float m2 = (2523.0f / 4096.0f) * 128.0f; float c1 = 3424.0f / 4096.0f; float c2 = (2413.0f / 4096.0f) * 32.0f; float c3 = (2392.0f / 4096.0f) * 32.0f; - return powf((c1 + c2 * powf(v, m1)) / (1.0f + c3 * powf(v, m1)), m2); + return pow((c1 + c2 * pow(v, m1)) / (1.0f + c3 * pow(v, m1)), m2); } // Spec: http://www.arib.or.jp/english/html/overview/doc/2-STD-B67v1_0.pdf @@ -96,9 +110,9 @@ const float a = 0.17883277f; const float b = 0.28466892f; const float c = 0.55991073f; - v = fmax(0.0f, v); + v = max(0.0f, v); if (v <= 1) - return 0.5f * sqrtf(v); + return 0.5f * sqrt(v); else return a * log(v - b) + c; } @@ -116,22 +130,22 @@ case ColorSpace::TransferID::LOG: if (v < 0.0f) return 0.0f; - return powf(10.0f, (v - 1.0f) * 2.0f); + return pow(10.0f, (v - 1.0f) * 2.0f); case ColorSpace::TransferID::LOG_SQRT: if (v < 0.0f) return 0.0f; - return powf(10.0f, (v - 1.0f) * 2.5f); + return pow(10.0f, (v - 1.0f) * 2.5f); case ColorSpace::TransferID::IEC61966_2_4: { float a = 1.099296826809442f; float b = 0.018053968510807f; if (v < FromLinear(ColorSpace::TransferID::IEC61966_2_4, -a)) { - return -powf((a - 1.0f - v) / a, 1.0f / 0.45f); + return -pow((a - 1.0f - v) / a, 1.0f / 0.45f); } else if (v <= FromLinear(ColorSpace::TransferID::IEC61966_2_4, b)) { return v / 4.5f; } else { - return powf((v + a - 1.0f) / a, 1.0f / 0.45f); + return pow((v + a - 1.0f) / a, 1.0f / 0.45f); } } @@ -140,24 +154,23 @@ float b = 0.018f; float l = 0.0045f; if (v < FromLinear(ColorSpace::TransferID::BT1361_ECG, -l)) { - return -powf((1.0f - a - v * 4.0f) / a, 1.0f / 0.45f) / 4.0f; + return -pow((1.0f - a - v * 4.0f) / a, 1.0f / 0.45f) / 4.0f; } else if (v <= FromLinear(ColorSpace::TransferID::BT1361_ECG, b)) { return v / 4.5f; } else { - return powf((v + a - 1.0f) / a, 1.0f / 0.45f); + return pow((v + a - 1.0f) / a, 1.0f / 0.45f); } } case ColorSpace::TransferID::SMPTEST2084: { - v = fmax(0.0f, v); + v = max(0.0f, v); float m1 = (2610.0f / 4096.0f) / 4.0f; float m2 = (2523.0f / 4096.0f) * 128.0f; float c1 = 3424.0f / 4096.0f; float c2 = (2413.0f / 4096.0f) * 32.0f; float c3 = (2392.0f / 4096.0f) * 32.0f; - v = powf( - fmax(powf(v, 1.0f / m2) - c1, 0) / (c2 - c3 * powf(v, 1.0f / m2)), - 1.0f / m1); + v = pow(max(pow(v, 1.0f / m2) - c1, 0.0f) / (c2 - c3 * pow(v, 1.0f / m2)), + 1.0f / m1); // This matches the scRGB definition that 1.0 means 80 nits. // TODO(hubbe): It would be *nice* if 1.0 meant more than that, but // that might be difficult to do right now. @@ -166,12 +179,12 @@ } case ColorSpace::TransferID::SMPTEST2084_NON_HDR: - v = fmax(0.0f, v); - return fmin(2.3f * pow(v, 2.8f), v / 5.0f + 0.8f); + v = max(0.0f, v); + return min(2.3f * pow(v, 2.8f), v / 5.0f + 0.8f); // Spec: http://www.arib.or.jp/english/html/overview/doc/2-STD-B67v1_0.pdf case ColorSpace::TransferID::ARIB_STD_B67: { - v = fmax(0.0f, v); + v = max(0.0f, v); const float a = 0.17883277f; const float b = 0.28466892f; const float c = 0.55991073f; @@ -204,79 +217,105 @@ return Transform(range_adjust_matrix); } +Transform GetPrimaryTransform(const gfx::ColorSpace& color_space) { + SkMatrix44 primary_matrix; + color_space.GetPrimaryMatrix(&primary_matrix); + return Transform(primary_matrix); +} + +} // namespace + class ColorTransformMatrix; -class ColorTransformToLinear; class ColorTransformFromLinear; class ColorTransformToBT2020CL; class ColorTransformFromBT2020CL; class ColorTransformNull; +class QCMSColorTransform; -class ColorTransformInternal : public ColorTransform { +class ColorTransformStep { public: - // Visitor pattern, Prepend() calls return prev->Join(this). - virtual bool Prepend(ColorTransformInternal* prev) = 0; + ColorTransformStep() {} + virtual ~ColorTransformStep() {} + virtual ColorTransformFromLinear* GetFromLinear() { return nullptr; } + virtual ColorTransformToBT2020CL* GetToBT2020CL() { return nullptr; } + virtual ColorTransformFromBT2020CL* GetFromBT2020CL() { return nullptr; } + virtual ColorTransformMatrix* GetMatrix() { return nullptr; } + virtual ColorTransformNull* GetNull() { return nullptr; } + virtual QCMSColorTransform* GetQCMS() { return nullptr; } // Join methods, returns true if the |next| transform was successfully // assimilated into |this|. // If Join() returns true, |next| is no longer needed and can be deleted. - virtual bool Join(const ColorTransformToLinear& next) { return false; } - virtual bool Join(const ColorTransformFromLinear& next) { return false; } - virtual bool Join(const ColorTransformToBT2020CL& next) { return false; } - virtual bool Join(const ColorTransformFromBT2020CL& next) { return false; } - virtual bool Join(const ColorTransformMatrix& next) { return false; } - virtual bool Join(const ColorTransformNull& next) { return true; } + virtual bool Join(ColorTransformStep* next) { return false; } // Return true if this is a null transform. virtual bool IsNull() { return false; } + + virtual void Transform(ColorTransform::TriStim* color, size_t num) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(ColorTransformStep); }; -class ColorTransformNull : public ColorTransformInternal { +class ColorTransformInternal : public ColorTransform { public: - bool Prepend(ColorTransformInternal* prev) override { - return prev->Join(*this); + ColorTransformInternal(const ColorSpace& from, + const ColorSpace& to, + Intent intent); + ~ColorTransformInternal() override; + + // Perform transformation of colors, |colors| is both input and output. + void Transform(TriStim* colors, size_t num) override { + for (const auto& step : steps_) + step->Transform(colors, num); } + size_t NumberOfStepsForTesting() const override { return steps_.size(); } + + private: + void AppendColorSpaceToColorSpaceTransform(ColorSpace from, + const ColorSpace& to, + ColorTransform::Intent intent); + void Simplify(); + + std::list<std::unique_ptr<ColorTransformStep>> steps_; +}; + +class ColorTransformNull : public ColorTransformStep { + public: + ColorTransformNull* GetNull() override { return this; } bool IsNull() override { return true; } - void transform(ColorTransform::TriStim* color, size_t num) override {} + void Transform(ColorTransform::TriStim* color, size_t num) override {} }; -class ColorTransformMatrix : public ColorTransformInternal { +class ColorTransformMatrix : public ColorTransformStep { public: - explicit ColorTransformMatrix(const Transform& matrix) : matrix_(matrix) {} - - bool Prepend(ColorTransformInternal* prev) override { - return prev->Join(*this); - } - - bool Join(const ColorTransformMatrix& next) override { - Transform tmp = next.matrix_; + explicit ColorTransformMatrix(const class Transform& matrix) + : matrix_(matrix) {} + ColorTransformMatrix* GetMatrix() override { return this; } + bool Join(ColorTransformStep* next_untyped) override { + ColorTransformMatrix* next = next_untyped->GetMatrix(); + if (!next) + return false; + class Transform tmp = next->matrix_; tmp *= matrix_; matrix_ = tmp; return true; } bool IsNull() override { - // Returns true if we're very close to an identity matrix. - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - float expected = i == j ? 1.0f : 0.0f; - if (fabs(matrix_.matrix().get(i, j) - expected) > 0.00001f) { - return false; - } - } - } - return true; + return SkMatrixIsApproximatelyIdentity(matrix_.matrix()); } - void transform(ColorTransform::TriStim* colors, size_t num) override { + void Transform(ColorTransform::TriStim* colors, size_t num) override { for (size_t i = 0; i < num; i++) matrix_.TransformPoint(colors + i); } private: - Transform matrix_; + class Transform matrix_; }; -class ColorTransformFromLinear : public ColorTransformInternal { +class ColorTransformFromLinear : public ColorTransformStep { public: explicit ColorTransformFromLinear(ColorSpace::TransferID transfer, const SkColorSpaceTransferFn& fn, @@ -285,13 +324,9 @@ if (transfer_ == ColorSpace::TransferID::LINEAR_HDR) transfer_ = ColorSpace::TransferID::LINEAR; } - bool Prepend(ColorTransformInternal* prev) override { - return prev->Join(*this); - } - + ColorTransformFromLinear* GetFromLinear() override { return this; } bool IsNull() override { return transfer_ == ColorSpace::TransferID::LINEAR; } - - void transform(ColorTransform::TriStim* colors, size_t num) override { + void Transform(ColorTransform::TriStim* colors, size_t num) override { if (fn_valid_) { for (size_t i = 0; i < num; i++) { colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); @@ -314,7 +349,7 @@ bool fn_valid_ = false; }; -class ColorTransformToLinear : public ColorTransformInternal { +class ColorTransformToLinear : public ColorTransformStep { public: explicit ColorTransformToLinear(ColorSpace::TransferID transfer, const SkColorSpaceTransferFn& fn, @@ -324,10 +359,6 @@ transfer_ = ColorSpace::TransferID::LINEAR; } - bool Prepend(ColorTransformInternal* prev) override { - return prev->Join(*this); - } - static bool IsGamma22(ColorSpace::TransferID transfer) { switch (transfer) { // We don't need to check BT709 here because it's been translated into @@ -341,9 +372,15 @@ } } - bool Join(const ColorTransformFromLinear& next) override { - if (transfer_ == next.transfer_ || - (IsGamma22(transfer_) && IsGamma22(next.transfer_))) { + bool Join(ColorTransformStep* next_untyped) override { + ColorTransformFromLinear* next = next_untyped->GetFromLinear(); + if (!next) + return false; + // TODO(ccameron): Use SkTransferFnsApproximatelyCancel and + // SkTransferFnIsApproximatelyIdentity to merge parametric transfer + // functions. + if (transfer_ == next->transfer_ || + (IsGamma22(transfer_) && IsGamma22(next->transfer_))) { transfer_ = ColorSpace::TransferID::LINEAR; return true; } @@ -358,7 +395,7 @@ } ColorTransform::TriStim ClipToWhite(ColorTransform::TriStim& c) { - float maximum = std::max(std::max(c.x(), c.y()), c.z()); + float maximum = max(max(c.x(), c.y()), c.z()); if (maximum > 1.0f) { float l = Luma(c); c.Scale(1.0f / maximum); @@ -370,7 +407,7 @@ return c; } - void transform(ColorTransform::TriStim* colors, size_t num) override { + void Transform(ColorTransform::TriStim* colors, size_t num) override { if (fn_valid_) { for (size_t i = 0; i < num; i++) { colors[i].set_x(EvalSkTransferFn(fn_, colors[i].x())); @@ -420,13 +457,12 @@ // Then we run the transfer function like normal, and finally // this class is inserted as an extra step which takes calculates // the U and V values. -class ColorTransformToBT2020CL : public ColorTransformInternal { +class ColorTransformToBT2020CL : public ColorTransformStep { public: - bool Prepend(ColorTransformInternal* prev) override { - return prev->Join(*this); - } - - bool Join(const ColorTransformFromBT2020CL& next) override { + bool Join(ColorTransformStep* next_untyped) override { + ColorTransformFromBT2020CL* next = next_untyped->GetFromBT2020CL(); + if (!next) + return false; if (null_) return false; null_ = true; @@ -435,7 +471,7 @@ bool IsNull() override { return null_; } - void transform(ColorTransform::TriStim* RYB, size_t num) override { + void Transform(ColorTransform::TriStim* RYB, size_t num) override { for (size_t i = 0; i < num; i++) { float U, V; float B_Y = RYB[i].z() - RYB[i].y(); @@ -459,13 +495,12 @@ }; // Inverse of ColorTransformToBT2020CL, see comment above for more info. -class ColorTransformFromBT2020CL : public ColorTransformInternal { +class ColorTransformFromBT2020CL : public ColorTransformStep { public: - bool Prepend(ColorTransformInternal* prev) override { - return prev->Join(*this); - } - - bool Join(const ColorTransformToBT2020CL& next) override { + bool Join(ColorTransformStep* next_untyped) override { + ColorTransformToBT2020CL* next = next_untyped->GetToBT2020CL(); + if (!next) + return false; if (null_) return false; null_ = true; @@ -474,7 +509,7 @@ bool IsNull() override { return null_; } - void transform(ColorTransform::TriStim* YUV, size_t num) override { + void Transform(ColorTransform::TriStim* YUV, size_t num) override { if (null_) return; for (size_t i = 0; i < num; i++) { @@ -501,188 +536,133 @@ bool null_ = false; }; -class ChainColorTransform : public ColorTransform { - public: - ChainColorTransform(std::unique_ptr<ColorTransform> a, - std::unique_ptr<ColorTransform> b) - : a_(std::move(a)), b_(std::move(b)) {} - - private: - void transform(TriStim* colors, size_t num) override { - a_->transform(colors, num); - b_->transform(colors, num); - } - std::unique_ptr<ColorTransform> a_; - std::unique_ptr<ColorTransform> b_; -}; - -class TransformBuilder { - public: - void Append(std::unique_ptr<ColorTransformInternal> transform) { - if (!disable_optimizations_ && transform->IsNull()) - return; // Null transform - transforms_.push_back(std::move(transform)); - if (disable_optimizations_) - return; - while (transforms_.size() >= 2 && - transforms_.back()->Prepend( - transforms_[transforms_.size() - 2].get())) { - transforms_.pop_back(); - if (transforms_.back()->IsNull()) { - transforms_.pop_back(); +void ColorTransformInternal::AppendColorSpaceToColorSpaceTransform( + ColorSpace from, + const ColorSpace& to, + ColorTransform::Intent intent) { + if (intent == ColorTransform::Intent::INTENT_PERCEPTUAL) { + switch (from.transfer_) { + case ColorSpace::TransferID::UNSPECIFIED: + case ColorSpace::TransferID::BT709: + case ColorSpace::TransferID::SMPTE170M: + // SMPTE 1886 suggests that we should be using gamma 2.4 for BT709 + // content. However, most displays actually use a gamma of 2.2, and + // user studies shows that users don't really care. Using the same + // gamma as the display will let us optimize a lot more, so lets stick + // with using the SRGB transfer function. + from.transfer_ = ColorSpace::TransferID::IEC61966_2_1; break; - } + + case ColorSpace::TransferID::SMPTEST2084: + if (!to.IsHDR()) { + // We don't have an HDR display, so replace SMPTE 2084 with + // something that returns ranges more or less suitable for a normal + // display. + from.transfer_ = ColorSpace::TransferID::SMPTEST2084_NON_HDR; + } + break; + + case ColorSpace::TransferID::ARIB_STD_B67: + if (!to.IsHDR()) { + // Interpreting HLG using a gamma 2.4 works reasonably well for SDR + // displays. + from.transfer_ = ColorSpace::TransferID::GAMMA24; + } + break; + + default: // Do nothing + break; } + + // TODO(hubbe): shrink gamuts here (never stretch gamuts) } - std::unique_ptr<ColorTransform> GetTransform() { - if (transforms_.empty()) - return base::MakeUnique<ColorTransformNull>(); - std::unique_ptr<ColorTransform> ret(std::move(transforms_.back())); - transforms_.pop_back(); + steps_.push_back( + base::MakeUnique<ColorTransformMatrix>(GetRangeAdjustMatrix(from))); - while (!transforms_.empty()) { - ret = std::unique_ptr<ColorTransform>(new ChainColorTransform( - std::move(transforms_.back()), std::move(ret))); - transforms_.pop_back(); - } + steps_.push_back( + base::MakeUnique<ColorTransformMatrix>(Invert(GetTransferMatrix(from)))); - return ret; + SkColorSpaceTransferFn to_linear_fn; + bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); + steps_.push_back(base::MakeUnique<ColorTransformToLinear>( + from.transfer_, to_linear_fn, to_linear_fn_valid)); + + if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) { + // BT2020 CL is a special case. + steps_.push_back(base::MakeUnique<ColorTransformFromBT2020CL>()); + } + steps_.push_back( + base::MakeUnique<ColorTransformMatrix>(GetPrimaryTransform(from))); + + steps_.push_back( + base::MakeUnique<ColorTransformMatrix>(Invert(GetPrimaryTransform(to)))); + if (to.matrix_ == ColorSpace::MatrixID::BT2020_CL) { + // BT2020 CL is a special case. + steps_.push_back(base::MakeUnique<ColorTransformToBT2020CL>()); } - void disable_optimizations() { disable_optimizations_ = true; } + SkColorSpaceTransferFn from_linear_fn; + bool from_linear_fn_valid = to.GetInverseTransferFunction(&from_linear_fn); + steps_.push_back(base::MakeUnique<ColorTransformFromLinear>( + to.transfer_, from_linear_fn, from_linear_fn_valid)); - private: - bool disable_optimizations_ = false; - std::vector<std::unique_ptr<ColorTransformInternal>> transforms_; -}; + steps_.push_back( + base::MakeUnique<ColorTransformMatrix>(GetTransferMatrix(to))); -class ColorSpaceToColorSpaceTransform { - public: - static Transform GetPrimaryTransform(const ColorSpace& c) { - SkMatrix44 sk_matrix; - c.GetPrimaryMatrix(&sk_matrix); - return Transform(sk_matrix); - } + steps_.push_back( + base::MakeUnique<ColorTransformMatrix>(Invert(GetRangeAdjustMatrix(to)))); +} - static void ColorSpaceToColorSpace(ColorSpace from, - ColorSpace to, - ColorTransform::Intent intent, - TransformBuilder* builder) { - if (intent == ColorTransform::Intent::INTENT_PERCEPTUAL) { - switch (from.transfer_) { - case ColorSpace::TransferID::UNSPECIFIED: - case ColorSpace::TransferID::BT709: - case ColorSpace::TransferID::SMPTE170M: - // SMPTE 1886 suggests that we should be using gamma 2.4 for BT709 - // content. However, most displays actually use a gamma of 2.2, and - // user studies shows that users don't really care. Using the same - // gamma as the display will let us optimize a lot more, so lets stick - // with using the SRGB transfer function. - from.transfer_ = ColorSpace::TransferID::IEC61966_2_1; - break; - - case ColorSpace::TransferID::SMPTEST2084: - if (!to.IsHDR()) { - // We don't have an HDR display, so replace SMPTE 2084 with - // something that returns ranges more or less suitable for a normal - // display. - from.transfer_ = ColorSpace::TransferID::SMPTEST2084_NON_HDR; - } - break; - - case ColorSpace::TransferID::ARIB_STD_B67: - if (!to.IsHDR()) { - // Interpreting HLG using a gamma 2.4 works reasonably well for SDR - // displays. - from.transfer_ = ColorSpace::TransferID::GAMMA24; - } - break; - - default: // Do nothing - break; - } - - // TODO(hubbe): shrink gamuts here (never stretch gamuts) - } - - builder->Append(base::MakeUnique<ColorTransformMatrix>( - GetRangeAdjustMatrix(from))); - - builder->Append(base::MakeUnique<ColorTransformMatrix>( - Invert(GetTransferMatrix(from)))); - - SkColorSpaceTransferFn to_linear_fn; - bool to_linear_fn_valid = from.GetTransferFunction(&to_linear_fn); - builder->Append(base::MakeUnique<ColorTransformToLinear>( - from.transfer_, to_linear_fn, to_linear_fn_valid)); - - if (from.matrix_ == ColorSpace::MatrixID::BT2020_CL) { - // BT2020 CL is a special case. - builder->Append(base::MakeUnique<ColorTransformFromBT2020CL>()); - } - builder->Append( - base::MakeUnique<ColorTransformMatrix>(GetPrimaryTransform(from))); - - builder->Append(base::MakeUnique<ColorTransformMatrix>( - Invert(GetPrimaryTransform(to)))); - if (to.matrix_ == ColorSpace::MatrixID::BT2020_CL) { - // BT2020 CL is a special case. - builder->Append(base::MakeUnique<ColorTransformToBT2020CL>()); - } - - SkColorSpaceTransferFn from_linear_fn; - bool from_linear_fn_valid = to.GetInverseTransferFunction(&from_linear_fn); - builder->Append(base::MakeUnique<ColorTransformFromLinear>( - to.transfer_, from_linear_fn, from_linear_fn_valid)); - - builder->Append( - base::MakeUnique<ColorTransformMatrix>(GetTransferMatrix(to))); - - builder->Append(base::MakeUnique<ColorTransformMatrix>( - Invert(GetRangeAdjustMatrix(to)))); - } -}; - -class QCMSColorTransform : public ColorTransformInternal { +class QCMSColorTransform : public ColorTransformStep { public: // Takes ownership of the profiles - QCMSColorTransform(qcms_profile* from, qcms_profile* to) - : from_(from), to_(to) {} - ~QCMSColorTransform() override { - qcms_profile_release(from_); - qcms_profile_release(to_); - } - bool Prepend(ColorTransformInternal* prev) override { - // Not currently optimizable. + QCMSColorTransform(ScopedQcmsProfile from, ScopedQcmsProfile to) + : from_(std::move(from)), to_(std::move(to)) {} + ~QCMSColorTransform() override {} + QCMSColorTransform* GetQCMS() override { return this; } + bool Join(ColorTransformStep* next_untyped) override { + QCMSColorTransform* next = next_untyped->GetQCMS(); + if (!next) + return false; + if (qcms_profile_match(to_.get(), next->from_.get())) { + to_ = std::move(next->to_); + return true; + } return false; } - bool IsNull() override { return from_ == to_; } - void transform(TriStim* colors, size_t num) override { - CHECK(sizeof(TriStim) == sizeof(float[3])); + bool IsNull() override { + if (qcms_profile_match(from_.get(), to_.get())) + return true; + return false; + } + void Transform(ColorTransform::TriStim* colors, size_t num) override { + CHECK(sizeof(ColorTransform::TriStim) == sizeof(float[3])); // QCMS doesn't like numbers outside 0..1 for (size_t i = 0; i < num; i++) { - colors[i].set_x(fmin(1.0f, fmax(0.0f, colors[i].x()))); - colors[i].set_y(fmin(1.0f, fmax(0.0f, colors[i].y()))); - colors[i].set_z(fmin(1.0f, fmax(0.0f, colors[i].z()))); + colors[i].set_x(min(1.0f, max(0.0f, colors[i].x()))); + colors[i].set_y(min(1.0f, max(0.0f, colors[i].y()))); + colors[i].set_z(min(1.0f, max(0.0f, colors[i].z()))); } - qcms_chain_transform(from_, to_, reinterpret_cast<float*>(colors), + qcms_chain_transform(from_.get(), to_.get(), + reinterpret_cast<float*>(colors), reinterpret_cast<float*>(colors), num * 3); } private: - qcms_profile *from_, *to_; + ScopedQcmsProfile from_; + ScopedQcmsProfile to_; }; -qcms_profile* GetQCMSProfileIfAvailable(const ColorSpace& color_space) { +ScopedQcmsProfile GetQCMSProfileIfAvailable(const ColorSpace& color_space) { ICCProfile icc_profile = ICCProfile::FromColorSpace(color_space); if (icc_profile.GetData().empty()) return nullptr; - return qcms_profile_from_memory(icc_profile.GetData().data(), - icc_profile.GetData().size()); + return ScopedQcmsProfile(qcms_profile_from_memory( + icc_profile.GetData().data(), icc_profile.GetData().size())); } -qcms_profile* GetXYZD50Profile() { +ScopedQcmsProfile GetXYZD50Profile() { // QCMS is trixy, it has a datatype called qcms_CIE_xyY, but what it expects // is in fact not xyY color coordinates, it just wants the x/y values of the // primaries with Y equal to 1.0. @@ -700,67 +680,78 @@ w.x = 0.34567f; w.y = 0.35850f; w.Y = 1.0f; - return qcms_profile_create_rgb_with_gamma(w, xyz, 1.0f); + return ScopedQcmsProfile(qcms_profile_create_rgb_with_gamma(w, xyz, 1.0f)); } +ColorTransformInternal::ColorTransformInternal(const ColorSpace& from, + const ColorSpace& to, + Intent intent) { + ScopedQcmsProfile from_profile = GetQCMSProfileIfAvailable(from); + ScopedQcmsProfile to_profile = GetQCMSProfileIfAvailable(to); + bool has_from_profile = !!from_profile; + bool has_to_profile = !!to_profile; + + if (from_profile) { + steps_.push_back(base::MakeUnique<QCMSColorTransform>( + std::move(from_profile), GetXYZD50Profile())); + } + + AppendColorSpaceToColorSpaceTransform( + has_from_profile ? ColorSpace::CreateXYZD50() : from, + has_to_profile ? ColorSpace::CreateXYZD50() : to, intent); + + if (to_profile) { + steps_.push_back(base::MakeUnique<QCMSColorTransform>( + GetXYZD50Profile(), std::move(to_profile))); + } + + if (intent != Intent::TEST_NO_OPT) + Simplify(); +} + +ColorTransformInternal::~ColorTransformInternal() {} + +void ColorTransformInternal::Simplify() { + for (auto iter = steps_.begin(); iter != steps_.end();) { + std::unique_ptr<ColorTransformStep>& this_step = *iter; + + // Try to Join |next_step| into |this_step|. If successful, re-visit the + // step before |this_step|. + auto iter_next = iter; + iter_next++; + if (iter_next != steps_.end()) { + std::unique_ptr<ColorTransformStep>& next_step = *iter_next; + if (this_step->Join(next_step.get())) { + steps_.erase(iter_next); + if (iter != steps_.begin()) + --iter; + continue; + } + } + + // If |this_step| step is a no-op, remove it, and re-visit the step before + // |this_step|. + if (this_step->IsNull()) { + iter = steps_.erase(iter); + if (iter != steps_.begin()) + --iter; + continue; + } + + ++iter; + } +} + +// static std::unique_ptr<ColorTransform> ColorTransform::NewColorTransform( const ColorSpace& from, const ColorSpace& to, Intent intent) { - TransformBuilder builder; - if (intent == Intent::TEST_NO_OPT) { - builder.disable_optimizations(); - } - - qcms_profile* from_profile = GetQCMSProfileIfAvailable(from); - qcms_profile* to_profile = GetQCMSProfileIfAvailable(to); - - if (from_profile && to_profile) { - return std::unique_ptr<ColorTransform>( - new QCMSColorTransform(from_profile, to_profile)); - } - if (from_profile) { - builder.Append(std::unique_ptr<ColorTransformInternal>( - new QCMSColorTransform(from_profile, GetXYZD50Profile()))); - } - ColorSpaceToColorSpaceTransform::ColorSpaceToColorSpace( - from_profile ? ColorSpace::CreateXYZD50() : from, - to_profile ? ColorSpace::CreateXYZD50() : to, intent, &builder); - if (to_profile) { - builder.Append(std::unique_ptr<ColorTransformInternal>( - new QCMSColorTransform(GetXYZD50Profile(), to_profile))); - } - - return builder.GetTransform(); + return std::unique_ptr<ColorTransform>( + new ColorTransformInternal(from, to, intent)); } -// static -float ColorTransform::ToLinearForTesting(ColorSpace::TransferID transfer, - float v) { - ColorSpace space(ColorSpace::PrimaryID::BT709, transfer, - ColorSpace::MatrixID::RGB, ColorSpace::RangeID::FULL); - SkColorSpaceTransferFn to_linear_fn; - bool to_linear_fn_valid = space.GetTransferFunction(&to_linear_fn); - ColorTransformToLinear to_linear_transform(transfer, to_linear_fn, - to_linear_fn_valid); - TriStim color(v, v, v); - to_linear_transform.transform(&color, 1); - return color.x(); -} - -// static -float ColorTransform::FromLinearForTesting(ColorSpace::TransferID transfer, - float v) { - ColorSpace space(ColorSpace::PrimaryID::BT709, transfer, - ColorSpace::MatrixID::RGB, ColorSpace::RangeID::FULL); - SkColorSpaceTransferFn from_linear_fn; - bool from_linear_fn_valid = space.GetInverseTransferFunction(&from_linear_fn); - - ColorTransformFromLinear from_linear_transform(transfer, from_linear_fn, - from_linear_fn_valid); - TriStim color(v, v, v); - from_linear_transform.transform(&color, 1); - return color.x(); -} +ColorTransform::ColorTransform() {} +ColorTransform::~ColorTransform() {} } // namespace gfx
diff --git a/ui/gfx/color_transform.h b/ui/gfx/color_transform.h index 1d99617..5368b7a 100644 --- a/ui/gfx/color_transform.h +++ b/ui/gfx/color_transform.h
@@ -5,10 +5,7 @@ #ifndef UI_GFX_COLOR_TRANSFORM_H_ #define UI_GFX_COLOR_TRANSFORM_H_ -#include <memory> -#include <stdint.h> - -#include "build/build_config.h" +#include "base/macros.h" #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/point3_f.h" #include "ui/gfx/gfx_export.h" @@ -23,19 +20,23 @@ // Channel order is XYZ, RGB or YUV. typedef Point3F TriStim; - virtual ~ColorTransform() {} + ColorTransform(); + virtual ~ColorTransform(); // Perform transformation of colors, |colors| is both input and output. - virtual void transform(TriStim* colors, size_t num) = 0; + virtual void Transform(TriStim* colors, size_t num) = 0; + + virtual size_t NumberOfStepsForTesting() const = 0; static std::unique_ptr<ColorTransform> NewColorTransform( const ColorSpace& from, const ColorSpace& to, Intent intent); - static float ToLinearForTesting(ColorSpace::TransferID id, float v); - static float FromLinearForTesting(ColorSpace::TransferID id, float v); + private: + DISALLOW_COPY_AND_ASSIGN(ColorTransform); }; + } // namespace gfx #endif // UI_GFX_COLOR_TRANSFORM_H_
diff --git a/ui/gfx/color_transform_fuzzer.cc b/ui/gfx/color_transform_fuzzer.cc index bc226149..8a769fd 100644 --- a/ui/gfx/color_transform_fuzzer.cc +++ b/ui/gfx/color_transform_fuzzer.cc
@@ -19,6 +19,6 @@ bt709, icc.GetColorSpace(), gfx::ColorTransform::Intent::INTENT_ABSOLUTE)); gfx::ColorTransform::TriStim tmp(16.0f / 255.0f, 0.5f, 0.5f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); return 0; }
diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc index 3fc43c2..5a888267 100644 --- a/ui/gfx/color_transform_unittest.cc +++ b/ui/gfx/color_transform_unittest.cc
@@ -66,24 +66,71 @@ bt709, sRGB, ColorTransform::Intent::INTENT_ABSOLUTE)); ColorTransform::TriStim tmp(16.0f / 255.0f, 0.5f, 0.5f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_NEAR(tmp.x(), 0.0f, 0.001f); EXPECT_NEAR(tmp.y(), 0.0f, 0.001f); EXPECT_NEAR(tmp.z(), 0.0f, 0.001f); tmp = ColorTransform::TriStim(235.0f / 255.0f, 0.5f, 0.5f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_NEAR(tmp.x(), 1.0f, 0.001f); EXPECT_NEAR(tmp.y(), 1.0f, 0.001f); EXPECT_NEAR(tmp.z(), 1.0f, 0.001f); // Test a blue color tmp = ColorTransform::TriStim(128.0f / 255.0f, 240.0f / 255.0f, 0.5f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_GT(tmp.z(), tmp.x()); EXPECT_GT(tmp.z(), tmp.y()); } +TEST(SimpleColorSpace, SRGBFromICCAndNotICC) { + float kEpsilon = 0.001f; + ColorTransform::TriStim value_fromicc; + ColorTransform::TriStim value_default; + + ICCProfile srgb_icc_profile = ICCProfileForTestingSRGB(); + ColorSpace srgb_fromicc = srgb_icc_profile.GetColorSpace(); + ColorSpace srgb_default = gfx::ColorSpace::CreateSRGB(); + ColorSpace xyzd50 = gfx::ColorSpace::CreateXYZD50(); + + value_fromicc = value_default = ColorTransform::TriStim(0.1f, 0.5f, 0.9f); + + std::unique_ptr<ColorTransform> toxyzd50_fromicc( + ColorTransform::NewColorTransform( + srgb_fromicc, xyzd50, ColorTransform::Intent::INTENT_ABSOLUTE)); + // This will have 1 step, namely, the QCMS transform. + EXPECT_EQ(toxyzd50_fromicc->NumberOfStepsForTesting(), 1u); + toxyzd50_fromicc->Transform(&value_fromicc, 1); + + std::unique_ptr<ColorTransform> toxyzd50_default( + ColorTransform::NewColorTransform( + srgb_default, xyzd50, ColorTransform::Intent::INTENT_ABSOLUTE)); + // This will have a transfer function and then linear transform. + EXPECT_EQ(toxyzd50_default->NumberOfStepsForTesting(), 2u); + toxyzd50_default->Transform(&value_default, 1); + + EXPECT_NEAR(value_fromicc.x(), value_default.x(), kEpsilon); + EXPECT_NEAR(value_fromicc.y(), value_default.y(), kEpsilon); + EXPECT_NEAR(value_fromicc.z(), value_default.z(), kEpsilon); + + value_fromicc = value_default = ColorTransform::TriStim(0.1f, 0.5f, 0.9f); + + std::unique_ptr<ColorTransform> fromxyzd50_fromicc( + ColorTransform::NewColorTransform( + xyzd50, srgb_fromicc, ColorTransform::Intent::INTENT_ABSOLUTE)); + fromxyzd50_fromicc->Transform(&value_fromicc, 1); + + std::unique_ptr<ColorTransform> fromxyzd50_default( + ColorTransform::NewColorTransform( + xyzd50, srgb_default, ColorTransform::Intent::INTENT_ABSOLUTE)); + fromxyzd50_default->Transform(&value_default, 1); + + EXPECT_NEAR(value_fromicc.x(), value_default.x(), kEpsilon); + EXPECT_NEAR(value_fromicc.y(), value_default.y(), kEpsilon); + EXPECT_NEAR(value_fromicc.z(), value_default.z(), kEpsilon); +} + TEST(SimpleColorSpace, BT709toSRGBICC) { ICCProfile srgb_icc = ICCProfileForTestingSRGB(); ColorSpace bt709 = ColorSpace::CreateREC709(); @@ -92,20 +139,20 @@ bt709, sRGB, ColorTransform::Intent::INTENT_ABSOLUTE)); ColorTransform::TriStim tmp(16.0f / 255.0f, 0.5f, 0.5f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_NEAR(tmp.x(), 0.0f, 0.001f); EXPECT_NEAR(tmp.y(), 0.0f, 0.001f); EXPECT_NEAR(tmp.z(), 0.0f, 0.001f); tmp = ColorTransform::TriStim(235.0f / 255.0f, 0.5f, 0.5f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_NEAR(tmp.x(), 1.0f, 0.001f); EXPECT_NEAR(tmp.y(), 1.0f, 0.001f); EXPECT_NEAR(tmp.z(), 1.0f, 0.001f); // Test a blue color tmp = ColorTransform::TriStim(128.0f / 255.0f, 240.0f / 255.0f, 0.5f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_GT(tmp.z(), tmp.x()); EXPECT_GT(tmp.z(), tmp.y()); } @@ -123,25 +170,25 @@ sRGB, sRGB2, ColorTransform::Intent::INTENT_ABSOLUTE)); ColorTransform::TriStim tmp(1.0f, 1.0f, 1.0f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_NEAR(tmp.x(), 1.0f, kEpsilon); EXPECT_NEAR(tmp.y(), 1.0f, kEpsilon); EXPECT_NEAR(tmp.z(), 1.0f, kEpsilon); tmp = ColorTransform::TriStim(1.0f, 0.0f, 0.0f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_NEAR(tmp.x(), 1.0f, kEpsilon); EXPECT_NEAR(tmp.y(), 0.0f, kEpsilon); EXPECT_NEAR(tmp.z(), 0.0f, kEpsilon); tmp = ColorTransform::TriStim(0.0f, 1.0f, 0.0f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_NEAR(tmp.x(), 0.0f, kEpsilon); EXPECT_NEAR(tmp.y(), 1.0f, kEpsilon); EXPECT_NEAR(tmp.z(), 0.0f, kEpsilon); tmp = ColorTransform::TriStim(0.0f, 0.0f, 1.0f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_NEAR(tmp.x(), 0.0f, kEpsilon); EXPECT_NEAR(tmp.y(), 0.0f, kEpsilon); EXPECT_NEAR(tmp.z(), 1.0f, kEpsilon); @@ -154,20 +201,20 @@ unknown, sRGB, ColorTransform::Intent::INTENT_PERCEPTUAL)); ColorTransform::TriStim tmp(16.0f / 255.0f, 0.5f, 0.5f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_NEAR(tmp.x(), 0.0f, 0.001f); EXPECT_NEAR(tmp.y(), 0.0f, 0.001f); EXPECT_NEAR(tmp.z(), 0.0f, 0.001f); tmp = ColorTransform::TriStim(235.0f / 255.0f, 0.5f, 0.5f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_NEAR(tmp.x(), 1.0f, 0.001f); EXPECT_NEAR(tmp.y(), 1.0f, 0.001f); EXPECT_NEAR(tmp.z(), 1.0f, 0.001f); // Test a blue color tmp = ColorTransform::TriStim(128.0f / 255.0f, 240.0f / 255.0f, 0.5f); - t->transform(&tmp, 1); + t->Transform(&tmp, 1); EXPECT_GT(tmp.z(), tmp.x()); EXPECT_GT(tmp.z(), tmp.y()); } @@ -175,10 +222,33 @@ class TransferTest : public testing::TestWithParam<ColorSpace::TransferID> {}; TEST_P(TransferTest, basicTest) { + gfx::ColorSpace space_with_transfer(ColorSpace::PrimaryID::BT709, GetParam(), + ColorSpace::MatrixID::RGB, + ColorSpace::RangeID::FULL); + gfx::ColorSpace space_linear( + ColorSpace::PrimaryID::BT709, ColorSpace::TransferID::LINEAR, + ColorSpace::MatrixID::RGB, ColorSpace::RangeID::FULL); + + std::unique_ptr<ColorTransform> to_linear(ColorTransform::NewColorTransform( + space_with_transfer, space_linear, + ColorTransform::Intent::INTENT_ABSOLUTE)); + + std::unique_ptr<ColorTransform> from_linear(ColorTransform::NewColorTransform( + space_linear, space_with_transfer, + ColorTransform::Intent::INTENT_ABSOLUTE)); + + // The transforms will ahve 1 or 0 steps (0 for linear). + size_t expected_steps = 1u; + if (GetParam() == ColorSpace::TransferID::LINEAR) + expected_steps = 0u; + EXPECT_EQ(to_linear->NumberOfStepsForTesting(), expected_steps); + EXPECT_EQ(from_linear->NumberOfStepsForTesting(), expected_steps); + for (float x = 0.0f; x <= 1.0f; x += 1.0f / 128.0f) { - float linear = ColorTransform::ToLinearForTesting(GetParam(), x); - float x2 = ColorTransform::FromLinearForTesting(GetParam(), linear); - EXPECT_NEAR(x, x2, 0.001f); + ColorTransform::TriStim tristim(x, x, x); + to_linear->Transform(&tristim, 1); + from_linear->Transform(&tristim, 1); + EXPECT_NEAR(x, tristim.x(), 0.001f); } } @@ -211,7 +281,7 @@ std::unique_ptr<ColorTransform> t( ColorTransform::NewColorTransform(color_space_, color_space_, intent_)); ColorTransform::TriStim tristim(0.4f, 0.5f, 0.6f); - t->transform(&tristim, 1); + t->Transform(&tristim, 1); EXPECT_NEAR(tristim.x(), 0.4f, 0.001f); EXPECT_NEAR(tristim.y(), 0.5f, 0.001f); EXPECT_NEAR(tristim.z(), 0.6f, 0.001f); @@ -223,8 +293,8 @@ std::unique_ptr<ColorTransform> t2(ColorTransform::NewColorTransform( ColorSpace::CreateXYZD50(), color_space_, intent_)); ColorTransform::TriStim tristim(0.4f, 0.5f, 0.6f); - t1->transform(&tristim, 1); - t2->transform(&tristim, 1); + t1->Transform(&tristim, 1); + t2->Transform(&tristim, 1); EXPECT_NEAR(tristim.x(), 0.4f, 0.001f); EXPECT_NEAR(tristim.y(), 0.5f, 0.001f); EXPECT_NEAR(tristim.z(), 0.6f, 0.001f);
diff --git a/ui/gfx/skia_color_space_util.cc b/ui/gfx/skia_color_space_util.cc new file mode 100644 index 0000000..60617e76 --- /dev/null +++ b/ui/gfx/skia_color_space_util.cc
@@ -0,0 +1,54 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/gfx/skia_color_space_util.h" + +#include <algorithm> +#include <cmath> + +namespace gfx { + +namespace { + +const float kEpsilon = 1.f / 256.f; +} + +float EvalSkTransferFn(const SkColorSpaceTransferFn& fn, float x) { + if (x < 0.f) + return 0.f; + if (x < fn.fD) + return fn.fC * x + fn.fF; + return std::pow(fn.fA * x + fn.fB, fn.fG) + fn.fE; +} + +SkColorSpaceTransferFn SkTransferFnInverse(const SkColorSpaceTransferFn& fn) { + SkColorSpaceTransferFn fn_inv = {0}; + if (fn.fA > 0 && fn.fG > 0) { + double a_to_the_g = std::pow(fn.fA, fn.fG); + fn_inv.fA = 1.f / a_to_the_g; + fn_inv.fB = -fn.fE / a_to_the_g; + fn_inv.fG = 1.f / fn.fG; + } + fn_inv.fD = fn.fC * fn.fD + fn.fF; + fn_inv.fE = -fn.fB / fn.fA; + if (fn.fC != 0) { + fn_inv.fC = 1.f / fn.fC; + fn_inv.fF = -fn.fF / fn.fC; + } + return fn_inv; +} + +bool SkMatrixIsApproximatelyIdentity(const SkMatrix44& m) { + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + float identity_value = i == j ? 1 : 0; + float value = m.get(i, j); + if (std::abs(identity_value - value) > kEpsilon) + return false; + } + } + return true; +} + +} // namespace gfx
diff --git a/ui/gfx/skia_color_space_util.h b/ui/gfx/skia_color_space_util.h new file mode 100644 index 0000000..29dbb00b --- /dev/null +++ b/ui/gfx/skia_color_space_util.h
@@ -0,0 +1,22 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_SKIA_COLOR_SPACE_UTIL_H_ +#define UI_GFX_SKIA_COLOR_SPACE_UTIL_H_ + +#include "third_party/skia/include/core/SkColorSpace.h" +#include "ui/gfx/gfx_export.h" + +namespace gfx { + +float GFX_EXPORT EvalSkTransferFn(const SkColorSpaceTransferFn& fn, float x); + +SkColorSpaceTransferFn GFX_EXPORT +SkTransferFnInverse(const SkColorSpaceTransferFn& fn); + +bool GFX_EXPORT SkMatrixIsApproximatelyIdentity(const SkMatrix44& m); + +} // namespace gfx + +#endif // UI_GFX_SKIA_COLOR_SPACE_UTIL_H_