diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/platform/mojo')
40 files changed, 3472 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/platform/mojo/BUILD.gn b/chromium/third_party/blink/renderer/platform/mojo/BUILD.gn new file mode 100644 index 00000000000..c4f7e396124 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/BUILD.gn @@ -0,0 +1,15 @@ +# 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. + +source_set("geometry_struct_traits") { + sources = [ + "geometry_struct_traits.cc", + "geometry_struct_traits.h", + ] + public_deps = [ + "//third_party/blink/public:blink_headers", + "//ui/gfx/geometry", + "//ui/gfx/geometry/mojo:mojo_shared_cpp_sources", + ] +} diff --git a/chromium/third_party/blink/renderer/platform/mojo/DEPS b/chromium/third_party/blink/renderer/platform/mojo/DEPS new file mode 100644 index 00000000000..9278750b675 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/DEPS @@ -0,0 +1,16 @@ +include_rules = [ + # To whitelist base/ stuff Blink is allowed to include, we list up all + # directories and files instead of writing 'base/'. + "+base/callback.h", + "+base/containers/span.h", + "+base/message_loop/message_loop.h", + "+base/observer_list.h", + "+base/strings/string16.h", + "+mojo/common/big_string.mojom-blink.h", + "+mojo/common/test_common_custom_types.mojom-blink.h", + "+mojo/public/cpp/base/time_mojom_traits.h", + "+mojo/public/cpp/bindings/binding.h", + "+mojo/public/mojom/base/string16.mojom-blink.h", + "+services/network/public/mojom/fetch_api.mojom-blink.h", + "+skia/public/interfaces/bitmap_skbitmap_struct_traits.h" +] diff --git a/chromium/third_party/blink/renderer/platform/mojo/OWNERS b/chromium/third_party/blink/renderer/platform/mojo/OWNERS new file mode 100644 index 00000000000..591a6840fc2 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/OWNERS @@ -0,0 +1,6 @@ +per-file *_mojom_traits*.*=set noparent +per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS +per-file *_struct_traits*.*=set noparent +per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS +per-file *.typemap=set noparent +per-file *.typemap=file://ipc/SECURITY_OWNERS diff --git a/chromium/third_party/blink/renderer/platform/mojo/big_buffer.typemap b/chromium/third_party/blink/renderer/platform/mojo/big_buffer.typemap new file mode 100644 index 00000000000..32726d5a2ca --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/big_buffer.typemap @@ -0,0 +1,12 @@ +# 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. + +mojom = "//mojo/public/mojom/base/big_buffer.mojom" +public_headers = [ "//mojo/public/cpp/base/big_buffer.h" ] +traits_headers = [ "//mojo/public/cpp/base/big_buffer_mojom_traits.h" ] +public_deps = [ + "//mojo/public/cpp/base", + "//mojo/public/cpp/base:shared_typemap_traits", +] +type_mappings = [ "mojo_base.mojom.BigBuffer=mojo_base::BigBuffer[move_only]" ] diff --git a/chromium/third_party/blink/renderer/platform/mojo/big_string.typemap b/chromium/third_party/blink/renderer/platform/mojo/big_string.typemap new file mode 100644 index 00000000000..5837a5dc0c8 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/big_string.typemap @@ -0,0 +1,11 @@ +# Copyright 2018 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. + +mojom = "//mojo/public/mojom/base/big_string.mojom" +public_headers = + [ "//third_party/blink/renderer/platform/wtf/text/wtf_string.h" ] +traits_headers = + [ "//third_party/blink/renderer/platform/mojo/big_string_mojom_traits.h" ] +type_mappings = + [ "mojo_base.mojom.BigString=WTF::String[nullable_is_same_type]" ] diff --git a/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits.cc b/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits.cc new file mode 100644 index 00000000000..1090633ed22 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits.cc @@ -0,0 +1,45 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/mojo/big_string_mojom_traits.h" + +#include <cstring> + +#include "base/containers/span.h" +#include "mojo/public/cpp/base/big_buffer.h" +#include "mojo/public/cpp/base/big_buffer_mojom_traits.h" +#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" + +namespace mojo { + +// static +mojo_base::BigBuffer StructTraits<mojo_base::mojom::BigStringDataView, + WTF::String>::data(const WTF::String& input) { + WTF::StringUTF8Adaptor adaptor(input); + return mojo_base::BigBuffer( + base::make_span(reinterpret_cast<const uint8_t*>(adaptor.Data()), + adaptor.length() * sizeof(char))); +} + +// static +bool StructTraits<mojo_base::mojom::BigStringDataView, WTF::String>::Read( + mojo_base::mojom::BigStringDataView data, + WTF::String* out) { + mojo_base::BigBuffer buffer; + if (!data.ReadData(&buffer)) + return false; + size_t size = buffer.size(); + if (size % sizeof(char)) + return false; + // An empty |mojo_base::BigBuffer| may have a null |data()| if empty. + if (!size) { + *out = g_empty_string; + } else { + *out = WTF::String::FromUTF8(reinterpret_cast<const char*>(buffer.data()), + size / sizeof(char)); + } + return true; +} + +} // namespace mojo diff --git a/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits.h b/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits.h new file mode 100644 index 00000000000..4ea78d87f13 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits.h @@ -0,0 +1,30 @@ +// Copyright 2018 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BIG_STRING_MOJOM_TRAITS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BIG_STRING_MOJOM_TRAITS_H_ + +#include "mojo/public/cpp/bindings/struct_traits.h" +#include "mojo/public/mojom/base/big_string.mojom-blink.h" +#include "third_party/blink/renderer/platform/platform_export.h" + +namespace mojo_base { +class BigBuffer; +} + +namespace mojo { + +template <> +struct PLATFORM_EXPORT + StructTraits<mojo_base::mojom::BigStringDataView, WTF::String> { + static bool IsNull(const WTF::String& input) { return input.IsNull(); } + static void SetToNull(WTF::String* output) { *output = WTF::String(); } + + static mojo_base::BigBuffer data(const WTF::String& input); + static bool Read(mojo_base::mojom::BigStringDataView, WTF::String* out); +}; + +} // namespace mojo + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BIG_STRING_MOJOM_TRAITS_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits_test.cc b/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits_test.cc new file mode 100644 index 00000000000..4253e2fd899 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits_test.cc @@ -0,0 +1,70 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/rand_util.h" +#include "mojo/common/test_common_custom_types.mojom-blink.h" +#include "mojo/public/cpp/base/big_buffer_mojom_traits.h" +#include "mojo/public/cpp/test_support/test_utils.h" +#include "mojo/public/mojom/base/big_string.mojom-blink.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/mojo/big_string_mojom_traits.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +TEST(BigStringMojomTraitsTest, BigString_Null) { + String str; + String output; + + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojo_base::mojom::blink::BigString>( + &str, &output)); + ASSERT_EQ(str, output); +} + +TEST(BigStringMojomTraitsTest, BigString_Empty) { + String str = String::FromUTF8(""); + String output; + + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojo_base::mojom::blink::BigString>( + &str, &output)); + ASSERT_EQ(str, output); +} + +TEST(BigStringMojomTraitsTest, BigString_Short) { + String str = String::FromUTF8("hello world"); + ASSERT_TRUE(str.Is8Bit()); + String output; + + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojo_base::mojom::blink::BigString>( + &str, &output)); + ASSERT_EQ(str, output); + + // Replace the "o"s in "hello world" with "o"s with acute, so that |str| is + // 16-bit. + str = String::FromUTF8("hell\xC3\xB3 w\xC3\xB3rld"); + ASSERT_FALSE(str.Is8Bit()); + + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojo_base::mojom::blink::BigString>( + &str, &output)); + ASSERT_EQ(str, output); +} + +TEST(BigStringMojomTraitsTest, BigString_Long) { + WTF::Vector<char> random_latin1_string(1024 * 1024); + base::RandBytes(random_latin1_string.data(), random_latin1_string.size()); + + String str(random_latin1_string.data(), random_latin1_string.size()); + String output; + + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojo_base::mojom::blink::BigString>( + &str, &output)); + ASSERT_EQ(str, output); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni b/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni new file mode 100644 index 00000000000..6ae19f26328 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni @@ -0,0 +1,23 @@ +# 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. + +typemaps = [ + "//mojo/public/cpp/base/file_path.typemap", + "//mojo/common/values.typemap", + "//third_party/blink/renderer/core/messaging/blink_cloneable_message.typemap", + "//third_party/blink/renderer/core/messaging/blink_transferable_message.typemap", + "//third_party/blink/renderer/platform/blob/serialized_blob.typemap", + "//third_party/blink/renderer/platform/mojo/big_buffer.typemap", + "//third_party/blink/renderer/platform/mojo/big_string.typemap", + "//third_party/blink/renderer/platform/mojo/file.typemap", + "//third_party/blink/renderer/platform/mojo/geometry.typemap", + "//third_party/blink/renderer/platform/mojo/kurl.typemap", + "//third_party/blink/renderer/platform/mojo/referrer.typemap", + "//third_party/blink/renderer/platform/mojo/security_origin.typemap", + "//third_party/blink/renderer/platform/mojo/string.typemap", + "//third_party/blink/renderer/platform/mojo/time.typemap", + "//third_party/blink/public/platform/modules/bluetooth/bluetooth.typemap", + "//third_party/blink/public/platform/modules/fetch/fetch_api_request.typemap", + "//third_party/blink/public/platform/modules/notifications/notification_types.typemap", +] diff --git a/chromium/third_party/blink/renderer/platform/mojo/bluetooth_struct_traits.cc b/chromium/third_party/blink/renderer/platform/mojo/bluetooth_struct_traits.cc new file mode 100644 index 00000000000..f4fa2943088 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/bluetooth_struct_traits.cc @@ -0,0 +1,34 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/mojo/bluetooth_struct_traits.h" + +#include "mojo/public/cpp/bindings/string_traits_wtf.h" + +namespace mojo { + +// static +bool StructTraits<::blink::mojom::WebBluetoothDeviceIdDataView, WTF::String>:: + Read(::blink::mojom::WebBluetoothDeviceIdDataView data, + WTF::String* output) { + return data.ReadDeviceId(output); +} + +// static +bool StructTraits<bluetooth::mojom::UUIDDataView, WTF::String>::Read( + bluetooth::mojom::UUIDDataView data, + WTF::String* output) { + return data.ReadUuid(output); +} + +// static +void StructTraits<bluetooth::mojom::UUIDDataView, WTF::String>::SetToNull( + WTF::String* output) { + if (output->IsNull()) + return; + WTF::String result; + output->swap(result); +} + +} // namespace mojo diff --git a/chromium/third_party/blink/renderer/platform/mojo/bluetooth_struct_traits.h b/chromium/third_party/blink/renderer/platform/mojo/bluetooth_struct_traits.h new file mode 100644 index 00000000000..f58c52af0cc --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/bluetooth_struct_traits.h @@ -0,0 +1,37 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BLUETOOTH_STRUCT_TRAITS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BLUETOOTH_STRUCT_TRAITS_H_ + +#include "device/bluetooth/public/mojom/uuid.mojom-blink.h" +#include "third_party/blink/public/platform/modules/bluetooth/web_bluetooth.mojom-blink.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace mojo { + +template <> +struct StructTraits<::blink::mojom::WebBluetoothDeviceIdDataView, WTF::String> { + static const WTF::String& device_id(const WTF::String& input) { + return input; + } + + static bool Read(::blink::mojom::WebBluetoothDeviceIdDataView, + WTF::String* output); +}; + +template <> +struct StructTraits<bluetooth::mojom::UUIDDataView, WTF::String> { + static const WTF::String& uuid(const WTF::String& input) { return input; } + + static bool Read(bluetooth::mojom::UUIDDataView, WTF::String* output); + + static bool IsNull(const WTF::String& input) { return input.IsNull(); } + + static void SetToNull(WTF::String* output); +}; + +} // namespace mojo + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_BLUETOOTH_STRUCT_TRAITS_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.cc b/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.cc new file mode 100644 index 00000000000..1614f4f0b4a --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.cc @@ -0,0 +1,339 @@ +// 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 "third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h" + +#include "mojo/public/cpp/bindings/map_traits_wtf_hash_map.h" +#include "mojo/public/cpp/bindings/string_traits_wtf.h" +#include "services/network/public/mojom/fetch_api.mojom-blink.h" +#include "third_party/blink/public/platform/web_referrer_policy.h" +#include "third_party/blink/renderer/platform/blob/blob_data.h" +#include "third_party/blink/renderer/platform/mojo/kurl_struct_traits.h" +#include "third_party/blink/renderer/platform/mojo/referrer_struct_traits.h" +#include "third_party/blink/renderer/platform/weborigin/referrer.h" + +namespace mojo { + +using blink::mojom::RequestContextType; + +RequestContextType +EnumTraits<RequestContextType, blink::WebURLRequest::RequestContext>::ToMojom( + blink::WebURLRequest::RequestContext input) { + switch (input) { + case blink::WebURLRequest::kRequestContextUnspecified: + return RequestContextType::UNSPECIFIED; + case blink::WebURLRequest::kRequestContextAudio: + return RequestContextType::AUDIO; + case blink::WebURLRequest::kRequestContextBeacon: + return RequestContextType::BEACON; + case blink::WebURLRequest::kRequestContextCSPReport: + return RequestContextType::CSP_REPORT; + case blink::WebURLRequest::kRequestContextDownload: + return RequestContextType::DOWNLOAD; + case blink::WebURLRequest::kRequestContextEmbed: + return RequestContextType::EMBED; + case blink::WebURLRequest::kRequestContextEventSource: + return RequestContextType::EVENT_SOURCE; + case blink::WebURLRequest::kRequestContextFavicon: + return RequestContextType::FAVICON; + case blink::WebURLRequest::kRequestContextFetch: + return RequestContextType::FETCH; + case blink::WebURLRequest::kRequestContextFont: + return RequestContextType::FONT; + case blink::WebURLRequest::kRequestContextForm: + return RequestContextType::FORM; + case blink::WebURLRequest::kRequestContextFrame: + return RequestContextType::FRAME; + case blink::WebURLRequest::kRequestContextHyperlink: + return RequestContextType::HYPERLINK; + case blink::WebURLRequest::kRequestContextIframe: + return RequestContextType::IFRAME; + case blink::WebURLRequest::kRequestContextImage: + return RequestContextType::IMAGE; + case blink::WebURLRequest::kRequestContextImageSet: + return RequestContextType::IMAGE_SET; + case blink::WebURLRequest::kRequestContextImport: + return RequestContextType::IMPORT; + case blink::WebURLRequest::kRequestContextInternal: + return RequestContextType::INTERNAL; + case blink::WebURLRequest::kRequestContextLocation: + return RequestContextType::LOCATION; + case blink::WebURLRequest::kRequestContextManifest: + return RequestContextType::MANIFEST; + case blink::WebURLRequest::kRequestContextObject: + return RequestContextType::OBJECT; + case blink::WebURLRequest::kRequestContextPing: + return RequestContextType::PING; + case blink::WebURLRequest::kRequestContextPlugin: + return RequestContextType::PLUGIN; + case blink::WebURLRequest::kRequestContextPrefetch: + return RequestContextType::PREFETCH; + case blink::WebURLRequest::kRequestContextScript: + return RequestContextType::SCRIPT; + case blink::WebURLRequest::kRequestContextServiceWorker: + return RequestContextType::SERVICE_WORKER; + case blink::WebURLRequest::kRequestContextSharedWorker: + return RequestContextType::SHARED_WORKER; + case blink::WebURLRequest::kRequestContextSubresource: + return RequestContextType::SUBRESOURCE; + case blink::WebURLRequest::kRequestContextStyle: + return RequestContextType::STYLE; + case blink::WebURLRequest::kRequestContextTrack: + return RequestContextType::TRACK; + case blink::WebURLRequest::kRequestContextVideo: + return RequestContextType::VIDEO; + case blink::WebURLRequest::kRequestContextWorker: + return RequestContextType::WORKER; + case blink::WebURLRequest::kRequestContextXMLHttpRequest: + return RequestContextType::XML_HTTP_REQUEST; + case blink::WebURLRequest::kRequestContextXSLT: + return RequestContextType::XSLT; + } + + NOTREACHED(); + return RequestContextType::UNSPECIFIED; +} + +bool EnumTraits<RequestContextType, blink::WebURLRequest::RequestContext>:: + FromMojom(RequestContextType input, + blink::WebURLRequest::RequestContext* out) { + switch (input) { + case RequestContextType::UNSPECIFIED: + *out = blink::WebURLRequest::kRequestContextUnspecified; + return true; + case RequestContextType::AUDIO: + *out = blink::WebURLRequest::kRequestContextAudio; + return true; + case RequestContextType::BEACON: + *out = blink::WebURLRequest::kRequestContextBeacon; + return true; + case RequestContextType::CSP_REPORT: + *out = blink::WebURLRequest::kRequestContextCSPReport; + return true; + case RequestContextType::DOWNLOAD: + *out = blink::WebURLRequest::kRequestContextDownload; + return true; + case RequestContextType::EMBED: + *out = blink::WebURLRequest::kRequestContextEmbed; + return true; + case RequestContextType::EVENT_SOURCE: + *out = blink::WebURLRequest::kRequestContextEventSource; + return true; + case RequestContextType::FAVICON: + *out = blink::WebURLRequest::kRequestContextFavicon; + return true; + case RequestContextType::FETCH: + *out = blink::WebURLRequest::kRequestContextFetch; + return true; + case RequestContextType::FONT: + *out = blink::WebURLRequest::kRequestContextFont; + return true; + case RequestContextType::FORM: + *out = blink::WebURLRequest::kRequestContextForm; + return true; + case RequestContextType::FRAME: + *out = blink::WebURLRequest::kRequestContextFrame; + return true; + case RequestContextType::HYPERLINK: + *out = blink::WebURLRequest::kRequestContextHyperlink; + return true; + case RequestContextType::IFRAME: + *out = blink::WebURLRequest::kRequestContextIframe; + return true; + case RequestContextType::IMAGE: + *out = blink::WebURLRequest::kRequestContextImage; + return true; + case RequestContextType::IMAGE_SET: + *out = blink::WebURLRequest::kRequestContextImageSet; + return true; + case RequestContextType::IMPORT: + *out = blink::WebURLRequest::kRequestContextImport; + return true; + case RequestContextType::INTERNAL: + *out = blink::WebURLRequest::kRequestContextInternal; + return true; + case RequestContextType::LOCATION: + *out = blink::WebURLRequest::kRequestContextLocation; + return true; + case RequestContextType::MANIFEST: + *out = blink::WebURLRequest::kRequestContextManifest; + return true; + case RequestContextType::OBJECT: + *out = blink::WebURLRequest::kRequestContextObject; + return true; + case RequestContextType::PING: + *out = blink::WebURLRequest::kRequestContextPing; + return true; + case RequestContextType::PLUGIN: + *out = blink::WebURLRequest::kRequestContextPlugin; + return true; + case RequestContextType::PREFETCH: + *out = blink::WebURLRequest::kRequestContextPrefetch; + return true; + case RequestContextType::SCRIPT: + *out = blink::WebURLRequest::kRequestContextScript; + return true; + case RequestContextType::SERVICE_WORKER: + *out = blink::WebURLRequest::kRequestContextServiceWorker; + return true; + case RequestContextType::SHARED_WORKER: + *out = blink::WebURLRequest::kRequestContextSharedWorker; + return true; + case RequestContextType::SUBRESOURCE: + *out = blink::WebURLRequest::kRequestContextSubresource; + return true; + case RequestContextType::STYLE: + *out = blink::WebURLRequest::kRequestContextStyle; + return true; + case RequestContextType::TRACK: + *out = blink::WebURLRequest::kRequestContextTrack; + return true; + case RequestContextType::VIDEO: + *out = blink::WebURLRequest::kRequestContextVideo; + return true; + case RequestContextType::WORKER: + *out = blink::WebURLRequest::kRequestContextWorker; + return true; + case RequestContextType::XML_HTTP_REQUEST: + *out = blink::WebURLRequest::kRequestContextXMLHttpRequest; + return true; + case RequestContextType::XSLT: + *out = blink::WebURLRequest::kRequestContextXSLT; + return true; + } + + return false; +} + +// static +blink::KURL StructTraits<blink::mojom::FetchAPIRequestDataView, + blink::WebServiceWorkerRequest>:: + url(const blink::WebServiceWorkerRequest& request) { + return request.Url(); +} + +// static +WTF::String StructTraits<blink::mojom::FetchAPIRequestDataView, + blink::WebServiceWorkerRequest>:: + method(const blink::WebServiceWorkerRequest& request) { + return request.Method(); +} + +// static +WTF::HashMap<WTF::String, WTF::String> +StructTraits<blink::mojom::FetchAPIRequestDataView, + blink::WebServiceWorkerRequest>:: + headers(const blink::WebServiceWorkerRequest& request) { + WTF::HashMap<WTF::String, WTF::String> header_map; + for (const auto& pair : request.Headers()) + header_map.insert(pair.key, pair.value); + return header_map; +} + +// static +const blink::Referrer& StructTraits<blink::mojom::FetchAPIRequestDataView, + blink::WebServiceWorkerRequest>:: + referrer(const blink::WebServiceWorkerRequest& request) { + return request.GetReferrer(); +} + +// static +WTF::String StructTraits<blink::mojom::FetchAPIRequestDataView, + blink::WebServiceWorkerRequest>:: + blob_uuid(const blink::WebServiceWorkerRequest& request) { + if (request.GetBlobDataHandle()) + return request.GetBlobDataHandle()->Uuid(); + + return WTF::String(); +} + +// static +uint64_t StructTraits<blink::mojom::FetchAPIRequestDataView, + blink::WebServiceWorkerRequest>:: + blob_size(const blink::WebServiceWorkerRequest& request) { + if (request.GetBlobDataHandle()) + return request.GetBlobDataHandle()->size(); + + return 0; +} + +// static +blink::mojom::blink::BlobPtr StructTraits<blink::mojom::FetchAPIRequestDataView, + blink::WebServiceWorkerRequest>:: + blob(const blink::WebServiceWorkerRequest& request) { + if (request.GetBlobDataHandle()) { + blink::mojom::blink::BlobPtr result = + request.GetBlobDataHandle()->CloneBlobPtr(); + return result; + } + + return nullptr; +} + +// static +WTF::String StructTraits<blink::mojom::FetchAPIRequestDataView, + blink::WebServiceWorkerRequest>:: + integrity(const blink::WebServiceWorkerRequest& request) { + return request.Integrity(); +} + +// static +WTF::String StructTraits<blink::mojom::FetchAPIRequestDataView, + blink::WebServiceWorkerRequest>:: + client_id(const blink::WebServiceWorkerRequest& request) { + return request.ClientId(); +} + +// static +bool StructTraits<blink::mojom::FetchAPIRequestDataView, + blink::WebServiceWorkerRequest>:: + Read(blink::mojom::FetchAPIRequestDataView data, + blink::WebServiceWorkerRequest* out) { + network::mojom::FetchRequestMode mode; + blink::WebURLRequest::RequestContext requestContext; + network::mojom::RequestContextFrameType frameType; + blink::KURL url; + WTF::String method; + WTF::HashMap<WTF::String, WTF::String> headers; + WTF::String blobUuid; + blink::mojom::blink::BlobPtr blob; + blink::Referrer referrer; + network::mojom::FetchCredentialsMode credentialsMode; + network::mojom::FetchRedirectMode redirectMode; + WTF::String integrity; + WTF::String clientId; + + if (!data.ReadMode(&mode) || !data.ReadRequestContextType(&requestContext) || + !data.ReadFrameType(&frameType) || !data.ReadUrl(&url) || + !data.ReadMethod(&method) || !data.ReadHeaders(&headers) || + !data.ReadBlobUuid(&blobUuid) || !data.ReadReferrer(&referrer) || + !data.ReadCredentialsMode(&credentialsMode) || + !data.ReadRedirectMode(&redirectMode) || !data.ReadClientId(&clientId) || + !data.ReadIntegrity(&integrity)) { + return false; + } + + out->SetMode(mode); + out->SetIsMainResourceLoad(data.is_main_resource_load()); + out->SetRequestContext(requestContext); + out->SetFrameType(frameType); + out->SetURL(url); + out->SetMethod(method); + for (const auto& pair : headers) + out->SetHeader(pair.key, pair.value); + out->SetBlob(blobUuid, static_cast<long long>(data.blob_size()), + data.TakeBlob<blink::mojom::blink::BlobPtr>().PassInterface()); + out->SetReferrer(referrer.referrer, static_cast<blink::WebReferrerPolicy>( + referrer.referrer_policy)); + out->SetCredentialsMode(credentialsMode); + out->SetCacheMode(data.cache_mode()); + out->SetRedirectMode(redirectMode); + out->SetIntegrity(integrity); + out->SetKeepalive(data.keepalive()); + out->SetClientId(clientId); + out->SetIsReload(data.is_reload()); + return true; +} + +} // namespace mojo diff --git a/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h b/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h new file mode 100644 index 00000000000..0bfcd453764 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h @@ -0,0 +1,99 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_FETCH_API_REQUEST_STRUCT_TRAITS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_FETCH_API_REQUEST_STRUCT_TRAITS_H_ + +#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-blink.h" +#include "third_party/blink/public/platform/web_url_request.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { +class KURL; +} + +namespace mojo { + +template <> +struct EnumTraits<::blink::mojom::RequestContextType, + ::blink::WebURLRequest::RequestContext> { + static ::blink::mojom::RequestContextType ToMojom( + ::blink::WebURLRequest::RequestContext input); + + static bool FromMojom(::blink::mojom::RequestContextType input, + ::blink::WebURLRequest::RequestContext* out); +}; + +template <> +struct StructTraits<::blink::mojom::FetchAPIRequestDataView, + ::blink::WebServiceWorkerRequest> { + static ::network::mojom::FetchRequestMode mode( + const ::blink::WebServiceWorkerRequest& request) { + return request.Mode(); + } + + static bool is_main_resource_load( + const ::blink::WebServiceWorkerRequest& request) { + return request.IsMainResourceLoad(); + } + + static ::blink::WebURLRequest::RequestContext request_context_type( + const ::blink::WebServiceWorkerRequest& request) { + return request.GetRequestContext(); + } + + static ::network::mojom::RequestContextFrameType frame_type( + const ::blink::WebServiceWorkerRequest& request) { + return request.GetFrameType(); + } + + static ::blink::KURL url(const ::blink::WebServiceWorkerRequest&); + + static WTF::String method(const ::blink::WebServiceWorkerRequest&); + + static WTF::HashMap<WTF::String, WTF::String> headers( + const ::blink::WebServiceWorkerRequest&); + + static WTF::String blob_uuid(const ::blink::WebServiceWorkerRequest&); + + static uint64_t blob_size(const ::blink::WebServiceWorkerRequest&); + + static blink::mojom::blink::BlobPtr blob( + const ::blink::WebServiceWorkerRequest&); + + static const ::blink::Referrer& referrer( + const ::blink::WebServiceWorkerRequest&); + + static ::network::mojom::FetchCredentialsMode credentials_mode( + const ::blink::WebServiceWorkerRequest& request) { + return request.CredentialsMode(); + } + + static ::blink::mojom::FetchCacheMode cache_mode( + const ::blink::WebServiceWorkerRequest& request) { + return request.CacheMode(); + } + + static ::network::mojom::FetchRedirectMode redirect_mode( + const ::blink::WebServiceWorkerRequest& request) { + return request.RedirectMode(); + } + + static WTF::String integrity(const ::blink::WebServiceWorkerRequest&); + static bool keepalive(const ::blink::WebServiceWorkerRequest& request) { + return request.Keepalive(); + } + static WTF::String client_id(const ::blink::WebServiceWorkerRequest&); + + static bool is_reload(const ::blink::WebServiceWorkerRequest& request) { + return request.IsReload(); + } + + static bool Read(::blink::mojom::FetchAPIRequestDataView, + ::blink::WebServiceWorkerRequest* output); +}; + +} // namespace mojo + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_FETCH_API_REQUEST_STRUCT_TRAITS_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/file.typemap b/chromium/third_party/blink/renderer/platform/mojo/file.typemap new file mode 100644 index 00000000000..3a0759dc284 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/file.typemap @@ -0,0 +1,12 @@ +# 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. + +mojom = "//mojo/public/mojom/base/file.mojom" +public_headers = [ "//base/files/file.h" ] +traits_headers = [ "//mojo/public/cpp/base/file_mojom_traits.h" ] +deps = [ + "//mojo/public/mojom/base", +] +type_mappings = + [ "mojo_base.mojom.File=base::File[move_only,nullable_is_same_type]" ] diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry.typemap b/chromium/third_party/blink/renderer/platform/mojo/geometry.typemap new file mode 100644 index 00000000000..5a7f96cbd5d --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/geometry.typemap @@ -0,0 +1,32 @@ +# 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. + +mojom = "//ui/gfx/geometry/mojo/geometry.mojom" +public_headers = [ + "//third_party/blink/public/platform/web_float_rect.h", + "//third_party/blink/public/platform/web_float_point.h", + "//third_party/blink/public/platform/web_point.h", + "//third_party/blink/public/platform/web_rect.h", + "//third_party/blink/public/platform/web_size.h", +] +traits_headers = [ + "//third_party/blink/renderer/platform/mojo/geometry_struct_traits.h", + "//ui/gfx/geometry/mojo/geometry_struct_traits.h", +] + +# Note: consumers of this typemap must themselves depend on platform. +deps = [ + "//mojo/public/cpp/bindings", + "//third_party/blink/renderer/platform/mojo:geometry_struct_traits", +] + +# TODO(zqzhang): ideally, gfx.mojom.Size should be mapped into ::blink::IntSize. +# However that introduces an link issue on Windows. See https://crbug.com/653323 +type_mappings = [ + "gfx.mojom.Point=::blink::WebPoint", + "gfx.mojom.PointF=::blink::WebFloatPoint", + "gfx.mojom.RectF=::blink::WebFloatRect", + "gfx.mojom.Rect=::blink::WebRect", + "gfx.mojom.Size=::blink::WebSize", +] diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits.cc b/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits.cc new file mode 100644 index 00000000000..b721a83b93f --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits.cc @@ -0,0 +1,64 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/mojo/geometry_struct_traits.h" + +namespace mojo { + +// static +bool StructTraits<gfx::mojom::RectFDataView, ::blink::WebFloatRect>::Read( + gfx::mojom::RectFDataView data, + ::blink::WebFloatRect* out) { + if (data.width() < 0 || data.height() < 0) + return false; + out->x = data.x(); + out->y = data.y(); + out->width = data.width(); + out->height = data.height(); + return true; +} + +// static +bool StructTraits<gfx::mojom::RectDataView, ::blink::WebRect>::Read( + gfx::mojom::RectDataView data, + ::blink::WebRect* out) { + if (data.width() < 0 || data.height() < 0) + return false; + out->x = data.x(); + out->y = data.y(); + out->width = data.width(); + out->height = data.height(); + return true; +} + +// static +bool StructTraits<gfx::mojom::PointDataView, ::blink::WebPoint>::Read( + gfx::mojom::PointDataView data, + ::blink::WebPoint* out) { + out->x = data.x(); + out->y = data.y(); + return true; +} + +// static +bool StructTraits<gfx::mojom::PointFDataView, ::blink::WebFloatPoint>::Read( + gfx::mojom::PointFDataView data, + ::blink::WebFloatPoint* out) { + out->x = data.x(); + out->y = data.y(); + return true; +} + +// static +bool StructTraits<gfx::mojom::SizeDataView, ::blink::WebSize>::Read( + gfx::mojom::SizeDataView data, + ::blink::WebSize* out) { + if (data.width() < 0 || data.height() < 0) + return false; + out->width = data.width(); + out->height = data.height(); + return true; +} + +} // namespace mojo diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits.h b/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits.h new file mode 100644 index 00000000000..9dda7b831b4 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits.h @@ -0,0 +1,58 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_GEOMETRY_STRUCT_TRAITS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_GEOMETRY_STRUCT_TRAITS_H_ + +#include "third_party/blink/public/platform/web_float_point.h" +#include "third_party/blink/public/platform/web_float_rect.h" +#include "third_party/blink/public/platform/web_point.h" +#include "third_party/blink/public/platform/web_rect.h" +#include "third_party/blink/public/platform/web_size.h" +#include "ui/gfx/geometry/mojo/geometry.mojom-shared.h" + +namespace mojo { + +template <> +struct StructTraits<gfx::mojom::PointDataView, ::blink::WebPoint> { + static int x(const ::blink::WebPoint& point) { return point.x; } + static int y(const ::blink::WebPoint& point) { return point.y; } + static bool Read(gfx::mojom::PointDataView, ::blink::WebPoint* out); +}; + +template <> +struct StructTraits<gfx::mojom::PointFDataView, ::blink::WebFloatPoint> { + static float x(const ::blink::WebFloatPoint& point) { return point.x; } + static float y(const ::blink::WebFloatPoint& point) { return point.y; } + static bool Read(gfx::mojom::PointFDataView, ::blink::WebFloatPoint* out); +}; + +template <> +struct StructTraits<gfx::mojom::RectFDataView, ::blink::WebFloatRect> { + static float x(const ::blink::WebFloatRect& rect) { return rect.x; } + static float y(const ::blink::WebFloatRect& rect) { return rect.y; } + static float width(const ::blink::WebFloatRect& rect) { return rect.width; } + static float height(const ::blink::WebFloatRect& rect) { return rect.height; } + static bool Read(gfx::mojom::RectFDataView, ::blink::WebFloatRect* out); +}; + +template <> +struct StructTraits<gfx::mojom::RectDataView, ::blink::WebRect> { + static int x(const ::blink::WebRect& rect) { return rect.x; } + static int y(const ::blink::WebRect& rect) { return rect.y; } + static int width(const ::blink::WebRect& rect) { return rect.width; } + static int height(const ::blink::WebRect& rect) { return rect.height; } + static bool Read(gfx::mojom::RectDataView, ::blink::WebRect* out); +}; + +template <> +struct StructTraits<gfx::mojom::SizeDataView, ::blink::WebSize> { + static int width(const ::blink::WebSize& size) { return size.width; } + static int height(const ::blink::WebSize& size) { return size.height; } + static bool Read(gfx::mojom::SizeDataView, ::blink::WebSize* out); +}; + +} // namespace mojo + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_GEOMETRY_STRUCT_TRAITS_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits_test.cc b/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits_test.cc new file mode 100644 index 00000000000..fb7c72414df --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/geometry_struct_traits_test.cc @@ -0,0 +1,144 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <utility> + +#include "base/message_loop/message_loop.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/mojo/geometry_traits_test_service.mojom-blink.h" + +namespace blink { + +namespace { + +class GeometryStructTraitsTest + : public testing::Test, + public gfx::mojom::blink::GeometryTraitsTestService { + public: + GeometryStructTraitsTest() {} + + protected: + gfx::mojom::blink::GeometryTraitsTestServicePtr GetTraitsTestProxy() { + gfx::mojom::blink::GeometryTraitsTestServicePtr proxy; + traits_test_bindings_.AddBinding(this, mojo::MakeRequest(&proxy)); + return proxy; + } + + private: + // GeometryTraitsTestService: + void EchoPoint(const WebPoint& p, EchoPointCallback callback) override { + std::move(callback).Run(p); + } + + void EchoPointF(const WebFloatPoint& p, + EchoPointFCallback callback) override { + std::move(callback).Run(p); + } + + void EchoSize(const WebSize& s, EchoSizeCallback callback) override { + std::move(callback).Run(s); + } + + void EchoSizeF(gfx::mojom::blink::SizeFPtr, EchoSizeFCallback) override { + // The type map is not specified. + NOTREACHED(); + } + + void EchoRect(const WebRect& r, EchoRectCallback callback) override { + std::move(callback).Run(r); + } + + void EchoRectF(const WebFloatRect& r, EchoRectFCallback callback) override { + std::move(callback).Run(r); + } + + void EchoInsets(gfx::mojom::blink::InsetsPtr, EchoInsetsCallback) override { + // The type map is not specified. + NOTREACHED(); + } + + void EchoInsetsF(gfx::mojom::blink::InsetsFPtr, + EchoInsetsFCallback) override { + // The type map is not specified. + NOTREACHED(); + } + + void EchoVector2d(gfx::mojom::blink::Vector2dPtr, + EchoVector2dCallback) override { + // The type map is not specified. + NOTREACHED(); + } + + void EchoVector2dF(gfx::mojom::blink::Vector2dFPtr, + EchoVector2dFCallback) override { + // The type map is not specified. + NOTREACHED(); + } + + mojo::BindingSet<gfx::mojom::blink::GeometryTraitsTestService> + traits_test_bindings_; + + base::MessageLoop message_loop_; + + DISALLOW_COPY_AND_ASSIGN(GeometryStructTraitsTest); +}; + +} // namespace + +TEST_F(GeometryStructTraitsTest, Size) { + const int32_t kWidth = 1234; + const int32_t kHeight = 5678; + WebSize input(kWidth, kHeight); + gfx::mojom::blink::GeometryTraitsTestServicePtr proxy = GetTraitsTestProxy(); + WebSize output; + proxy->EchoSize(input, &output); + EXPECT_EQ(input, output); +} + +TEST_F(GeometryStructTraitsTest, Point) { + const float kX = 1234; + const float kY = 5678; + WebPoint input(kX, kY); + gfx::mojom::blink::GeometryTraitsTestServicePtr proxy = GetTraitsTestProxy(); + WebPoint output; + proxy->EchoPoint(input, &output); + EXPECT_EQ(input, output); +} + +TEST_F(GeometryStructTraitsTest, PointF) { + const float kX = 1.234; + const float kY = 5.678; + WebFloatPoint input(kX, kY); + gfx::mojom::blink::GeometryTraitsTestServicePtr proxy = GetTraitsTestProxy(); + WebFloatPoint output; + proxy->EchoPointF(input, &output); + EXPECT_EQ(input, output); +} + +TEST_F(GeometryStructTraitsTest, Rect) { + const float kX = 1; + const float kY = 2; + const float kWidth = 3; + const float kHeight = 4; + WebRect input(kX, kY, kWidth, kHeight); + gfx::mojom::blink::GeometryTraitsTestServicePtr proxy = GetTraitsTestProxy(); + WebRect output; + proxy->EchoRect(input, &output); + EXPECT_EQ(input, output); +} + +TEST_F(GeometryStructTraitsTest, RectF) { + const float kX = 1.234; + const float kY = 2.345; + const float kWidth = 3.456; + const float kHeight = 4.567; + WebFloatRect input(kX, kY, kWidth, kHeight); + gfx::mojom::blink::GeometryTraitsTestServicePtr proxy = GetTraitsTestProxy(); + WebFloatRect output; + proxy->EchoRectF(input, &output); + EXPECT_EQ(input, output); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator.cc b/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator.cc new file mode 100644 index 00000000000..126d0221c62 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator.cc @@ -0,0 +1,35 @@ +// Copyright 2018 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 "third_party/blink/renderer/platform/mojo/interface_invalidator.h" + +namespace blink { + +InterfaceInvalidator::InterfaceInvalidator() : weak_factory_(this) {} + +InterfaceInvalidator::~InterfaceInvalidator() { + weak_factory_.InvalidateWeakPtrs(); + NotifyInvalidate(); +} + +void InterfaceInvalidator::AddObserver(Observer* observer) { + DCHECK(observer); + observers_.AddObserver(observer); +} + +void InterfaceInvalidator::RemoveObserver(const Observer* observer) { + DCHECK(observer); + observers_.RemoveObserver(observer); +} + +base::WeakPtr<InterfaceInvalidator> InterfaceInvalidator::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + +void InterfaceInvalidator::NotifyInvalidate() { + for (auto& observer : observers_) + observer.OnInvalidate(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator.h b/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator.h new file mode 100644 index 00000000000..6a65fe2e8ca --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator.h @@ -0,0 +1,43 @@ +// Copyright 2018 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_INTERFACE_INVALIDATOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_INTERFACE_INVALIDATOR_H_ + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "third_party/blink/renderer/platform/platform_export.h" + +namespace blink { + +// Notifies weak interface bindings to be invalidated when this object is +// destroyed. +class PLATFORM_EXPORT InterfaceInvalidator { + public: + InterfaceInvalidator(); + ~InterfaceInvalidator(); + + class Observer { + public: + virtual void OnInvalidate() = 0; + }; + + void AddObserver(Observer*); + void RemoveObserver(const Observer*); + + base::WeakPtr<InterfaceInvalidator> GetWeakPtr(); + + private: + void NotifyInvalidate(); + + base::ObserverList<Observer> observers_; + base::WeakPtrFactory<InterfaceInvalidator> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(InterfaceInvalidator); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_INTERFACE_INVALIDATOR_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator_test.cc b/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator_test.cc new file mode 100644 index 00000000000..cc25bde800b --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/interface_invalidator_test.cc @@ -0,0 +1,614 @@ +// Copyright 2018 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 <memory> +#include <utility> + +#include "base/bind.h" +#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/test/bind_test_util.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/interface_ptr.h" +#include "mojo/public/interfaces/bindings/tests/ping_service.mojom-blink.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/mojo/interface_invalidator.h" +#include "third_party/blink/renderer/platform/mojo/revocable_binding.h" +#include "third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h" +#include "third_party/blink/renderer/platform/mojo/revocable_strong_binding.h" + +namespace blink { + +namespace { + +void DoSetFlag(bool* flag) { + *flag = true; +} + +class PingServiceImplBase : public mojo::test::blink::PingService { + public: + PingServiceImplBase(bool send_response = true) + : send_response_(send_response) {} + ~PingServiceImplBase() override {} + + // mojo::test::blink::PingService: + void Ping(const PingCallback& callback) override { + if (ping_handler_) + ping_handler_.Run(); + + if (send_response_) { + callback.Run(); + } else { + saved_callback_ = callback; + } + + if (post_ping_handler_) + post_ping_handler_.Run(); + } + + void set_ping_handler(const base::RepeatingClosure& handler) { + ping_handler_ = handler; + } + + void set_post_ping_handler(const base::RepeatingClosure& handler) { + post_ping_handler_ = handler; + } + + private: + bool send_response_; + PingCallback saved_callback_; + base::RepeatingClosure ping_handler_; + base::RepeatingClosure post_ping_handler_; + + DISALLOW_COPY_AND_ASSIGN(PingServiceImplBase); +}; + +class PingServiceImpl : public PingServiceImplBase { + public: + PingServiceImpl( + mojo::InterfaceRequest<mojo::test::blink::PingService> request, + bool send_response = true) + : PingServiceImplBase(send_response), + error_handler_called_(false), + binding_(this, std::move(request)) { + binding_.set_connection_error_handler( + base::BindOnce(DoSetFlag, &error_handler_called_)); + } + + ~PingServiceImpl() override {} + + bool error_handler_called() { return error_handler_called_; } + + mojo::Binding<mojo::test::blink::PingService>* binding() { return &binding_; } + + private: + bool error_handler_called_; + mojo::Binding<mojo::test::blink::PingService> binding_; + + DISALLOW_COPY_AND_ASSIGN(PingServiceImpl); +}; + +class InterfaceInvalidatorTest : public testing::Test { + public: + InterfaceInvalidatorTest() {} + ~InterfaceInvalidatorTest() override {} + + private: + base::MessageLoop message_loop_; + + DISALLOW_COPY_AND_ASSIGN(InterfaceInvalidatorTest); +}; + +class InterfaceInvalidatorObserver : public InterfaceInvalidator::Observer { + public: + InterfaceInvalidatorObserver(const base::RepeatingClosure& handler) { + invalidate_handler_ = handler; + } + ~InterfaceInvalidatorObserver() {} + + void OnInvalidate() override { invalidate_handler_.Run(); } + + private: + base::RepeatingClosure invalidate_handler_; + + DISALLOW_COPY_AND_ASSIGN(InterfaceInvalidatorObserver); +}; + +TEST_F(InterfaceInvalidatorTest, DestroyNotifiesObservers) { + int called = 0; + auto inc_called_cb = base::BindLambdaForTesting([&] { ++called; }); + InterfaceInvalidatorObserver observer1(inc_called_cb); + InterfaceInvalidatorObserver observer2(inc_called_cb); + { + InterfaceInvalidator invalidator; + invalidator.AddObserver(&observer1); + invalidator.AddObserver(&observer2); + EXPECT_EQ(called, 0); + } + EXPECT_EQ(called, 2); +} + +TEST_F(InterfaceInvalidatorTest, DestroyInvalidatesRevocableInterfacePtr) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); + + bool ping_called = false; + wptr->Ping(base::BindRepeating(DoSetFlag, &ping_called)); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(ping_called); + + bool error_handler_called = false; + wptr.set_connection_error_handler( + base::BindOnce(DoSetFlag, &error_handler_called)); + + invalidator.reset(); + impl.set_ping_handler(base::BindRepeating([] { FAIL(); })); + wptr->Ping(base::BindRepeating([] { FAIL(); })); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(error_handler_called); + EXPECT_TRUE(impl.error_handler_called()); + EXPECT_TRUE(wptr.encountered_error()); + EXPECT_TRUE(wptr); +} + +TEST_F(InterfaceInvalidatorTest, InvalidateAfterMessageSent) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); + + bool called = false; + impl.set_ping_handler(base::BindRepeating(DoSetFlag, &called)); + // The passed in callback will not be called as the interface is invalidated + // before a response can come back. + wptr->Ping(base::BindRepeating([] { FAIL(); })); + invalidator.reset(); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(called); + EXPECT_TRUE(impl.error_handler_called()); +} + +TEST_F(InterfaceInvalidatorTest, PassInterfaceThenInvalidate) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); + + bool impl_called = false; + impl.set_ping_handler(base::BindRepeating(DoSetFlag, &impl_called)); + wptr.set_connection_error_handler(base::BindOnce([] { FAIL(); })); + + mojo::test::blink::PingServicePtr ptr(wptr.PassInterface()); + invalidator.reset(); + bool ping_called = false; + ptr->Ping(base::BindRepeating(DoSetFlag, &ping_called)); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(ping_called); + EXPECT_TRUE(impl_called); + EXPECT_FALSE(impl.error_handler_called()); +} + +TEST_F(InterfaceInvalidatorTest, PassInterfaceOfInvalidatedPtr) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); + + impl.set_ping_handler(base::BindRepeating([] { FAIL(); })); + bool error_handler_called = false; + wptr.set_connection_error_handler( + base::BindOnce(DoSetFlag, &error_handler_called)); + + // This also destroys the original invalidator. + invalidator = std::make_unique<InterfaceInvalidator>(); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(error_handler_called); + ASSERT_TRUE(impl.error_handler_called()); + + mojo::test::blink::RevocablePingServicePtr wptr2(wptr.PassInterface(), + invalidator.get()); + wptr2->Ping(base::BindRepeating([] { FAIL(); })); + base::RunLoop().RunUntilIdle(); +} + +TEST_F(InterfaceInvalidatorTest, + PassInterfaceBeforeConnectionErrorNotification) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); + + impl.set_ping_handler(base::BindRepeating([] { FAIL(); })); + wptr.set_connection_error_handler(base::BindOnce([] { FAIL(); })); + + // This also destroys the original invalidator. + invalidator = std::make_unique<InterfaceInvalidator>(); + mojo::test::blink::RevocablePingServicePtr wptr2(wptr.PassInterface(), + invalidator.get()); + wptr2->Ping(base::BindRepeating([] { FAIL(); })); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(impl.error_handler_called()); +} + +TEST_F(InterfaceInvalidatorTest, InvalidateAfterReset) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); + wptr.set_connection_error_handler(base::BindOnce([] { FAIL(); })); + + wptr.reset(); + invalidator.reset(); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(wptr); +} + +TEST_F(InterfaceInvalidatorTest, ResetInvalidatedRevocableInterfacePtr) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); + wptr.set_connection_error_handler(base::BindOnce([] { FAIL(); })); + + invalidator.reset(); + wptr.reset(); + base::RunLoop().RunUntilIdle(); +} + +TEST_F(InterfaceInvalidatorTest, InvalidateErroredPtr) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); + + int called = 0; + wptr.set_connection_error_handler( + base::BindLambdaForTesting([&] { called++; })); + + impl.binding()->Close(); + base::RunLoop().RunUntilIdle(); + invalidator.reset(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(called, 1); + EXPECT_FALSE(impl.error_handler_called()); +} + +// InterfacePtrs do not set up a proxy until they are used for the first +// time. +TEST_F(InterfaceInvalidatorTest, InvalidateBeforeProxyConfigured) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); + + invalidator.reset(); + wptr->Ping(base::BindRepeating([] { FAIL(); })); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(impl.error_handler_called()); +} + +TEST_F(InterfaceInvalidatorTest, MoveChangesInvalidatorObserver) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); + + auto wptr2(std::move(wptr)); + bool called = false; + wptr2.set_connection_error_handler(base::BindOnce(DoSetFlag, &called)); + + invalidator.reset(); + wptr2->Ping(base::BindRepeating([] { FAIL(); })); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(called); + EXPECT_TRUE(impl.error_handler_called()); +} + +TEST_F(InterfaceInvalidatorTest, MoveInvalidatedPointer) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); + + invalidator.reset(); + auto wptr2(std::move(wptr)); + wptr2->Ping(base::BindRepeating([] { FAIL(); })); + base::RunLoop().RunUntilIdle(); +} + +TEST_F(InterfaceInvalidatorTest, InvalidateRevocableInterfacePtrDuringSyncIPC) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get())); + + impl.set_ping_handler( + base::BindLambdaForTesting([&]() { invalidator.reset(); })); + bool result = wptr->Ping(); + EXPECT_FALSE(result); +} + +TEST_F(InterfaceInvalidatorTest, + InvalidateRevocableInterfacePtrDuringSyncIPCWithoutResponse) { + mojo::test::blink::RevocablePingServicePtr wptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + PingServiceImpl impl(MakeRequest(&wptr, invalidator.get()), + false /* send_response */); + + impl.set_ping_handler( + base::BindLambdaForTesting([&]() { invalidator.reset(); })); + bool result = wptr->Ping(); + EXPECT_FALSE(result); +} + +class RevocablePingServiceImpl : public PingServiceImplBase { + public: + RevocablePingServiceImpl( + mojo::InterfaceRequest<mojo::test::blink::PingService> request, + InterfaceInvalidator* invalidator, + bool send_response = true) + : PingServiceImplBase(send_response), + error_handler_called_(false), + binding_(this, std::move(request), invalidator) { + binding_.set_connection_error_handler( + base::BindOnce(DoSetFlag, &error_handler_called_)); + } + + ~RevocablePingServiceImpl() override {} + + bool error_handler_called() { return error_handler_called_; } + + RevocableBinding<mojo::test::blink::PingService>* binding() { + return &binding_; + } + + private: + bool error_handler_called_; + RevocableBinding<mojo::test::blink::PingService> binding_; + + DISALLOW_COPY_AND_ASSIGN(RevocablePingServiceImpl); +}; + +TEST_F(InterfaceInvalidatorTest, DestroyInvalidatesRevocableBinding) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get()); + + bool ping_called = false; + ptr->Ping(base::BindRepeating(DoSetFlag, &ping_called)); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(ping_called); + + bool error_handler_called = false; + ptr.set_connection_error_handler( + base::BindOnce(DoSetFlag, &error_handler_called)); + + invalidator.reset(); + impl.set_ping_handler(base::BindRepeating([] { FAIL(); })); + ptr->Ping(base::BindRepeating([] { FAIL(); })); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(error_handler_called); + EXPECT_TRUE(impl.error_handler_called()); + EXPECT_TRUE(ptr.encountered_error()); + EXPECT_TRUE(ptr); + EXPECT_TRUE(*impl.binding()); +} + +TEST_F(InterfaceInvalidatorTest, InvalidateBindingBeforeResponse) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get()); + impl.set_ping_handler( + base::BindLambdaForTesting([&] { invalidator.reset(); })); + + bool ptr_error_handler_called = false; + ptr.set_connection_error_handler( + base::BindOnce(DoSetFlag, &ptr_error_handler_called)); + ptr->Ping(base::BindRepeating([] { FAIL(); })); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(ptr_error_handler_called); + EXPECT_TRUE(impl.error_handler_called()); + EXPECT_TRUE(*impl.binding()); +} + +TEST_F(InterfaceInvalidatorTest, InvalidateBindingAfterResponse) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get()); + impl.set_post_ping_handler(base::BindLambdaForTesting([&] { + invalidator.reset(); + impl.set_ping_handler(base::BindRepeating([] { FAIL(); })); + })); + + bool ptr_error_handler_called = false; + ptr.set_connection_error_handler( + base::BindOnce(DoSetFlag, &ptr_error_handler_called)); + bool ping_called = false; + ptr->Ping(base::BindRepeating(DoSetFlag, &ping_called)); + ptr->Ping(base::BindRepeating([] { FAIL(); })); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(ping_called); + EXPECT_TRUE(ptr_error_handler_called); + EXPECT_TRUE(impl.error_handler_called()); + EXPECT_TRUE(*impl.binding()); +} + +TEST_F(InterfaceInvalidatorTest, UnbindThenInvalidate) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get()); + ptr.set_connection_error_handler(base::BindOnce([] { FAIL(); })); + + PingServiceImpl impl2(impl.binding()->Unbind()); + invalidator.reset(); + bool ping_called = false; + ptr->Ping(base::BindRepeating(DoSetFlag, &ping_called)); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(ping_called); + EXPECT_FALSE(impl.error_handler_called()); +} + +TEST_F(InterfaceInvalidatorTest, UnbindInvalidatedRevocableBinding) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get()); + + bool ptr_error_handler_called = false; + ptr.set_connection_error_handler( + base::BindOnce(DoSetFlag, &ptr_error_handler_called)); + + invalidator.reset(); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(ptr_error_handler_called); + ASSERT_TRUE(impl.error_handler_called()); + + PingServiceImpl impl2(impl.binding()->Unbind()); + impl2.set_ping_handler(base::BindRepeating([] { FAIL(); })); + ptr->Ping(base::BindRepeating([] { FAIL(); })); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(impl2.error_handler_called()); +} + +TEST_F(InterfaceInvalidatorTest, UnbindBeforeConnectionErrorNotification) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get()); + + bool ptr_error_handler_called = false; + ptr.set_connection_error_handler( + base::BindOnce(DoSetFlag, &ptr_error_handler_called)); + + invalidator.reset(); + PingServiceImpl impl2(impl.binding()->Unbind()); + impl2.set_ping_handler(base::BindRepeating([] { FAIL(); })); + ptr->Ping(base::BindRepeating([] { FAIL(); })); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(impl.error_handler_called()); + EXPECT_TRUE(impl2.error_handler_called()); + EXPECT_TRUE(ptr_error_handler_called); +} + +TEST_F(InterfaceInvalidatorTest, InvalidateClosedRevocableBinding) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get()); + + impl.binding()->Close(); + invalidator.reset(); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(impl.error_handler_called()); + EXPECT_FALSE(*impl.binding()); +} + +TEST_F(InterfaceInvalidatorTest, CloseInvalidatedRevocableBinding) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get()); + + invalidator.reset(); + impl.binding()->Close(); + base::RunLoop().RunUntilIdle(); + + EXPECT_FALSE(impl.error_handler_called()); + EXPECT_FALSE(*impl.binding()); +} + +TEST_F(InterfaceInvalidatorTest, InvalidateErroredRevocableBinding) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get()); + + int called = 0; + impl.binding()->set_connection_error_handler( + base::BindLambdaForTesting([&] { called++; })); + + ptr.reset(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, called); + invalidator.reset(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, called); +} + +TEST_F(InterfaceInvalidatorTest, InvalidateWhileRevocableBindingPaused) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get()); + + impl.binding()->PauseIncomingMethodCallProcessing(); + invalidator.reset(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(impl.error_handler_called()); + impl.binding()->ResumeIncomingMethodCallProcessing(); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(impl.error_handler_called()); +} + +TEST_F(InterfaceInvalidatorTest, InvalidateRevocableBindingDuringSyncIPC) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get()); + + impl.set_ping_handler( + base::BindLambdaForTesting([&] { invalidator.reset(); })); + bool result = ptr->Ping(); + EXPECT_FALSE(result); +} + +TEST_F(InterfaceInvalidatorTest, + InvalidateRevocableBindingDuringSyncIPCWithoutResponse) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + RevocablePingServiceImpl impl(MakeRequest(&ptr), invalidator.get(), + false /* send_response */); + + impl.set_ping_handler( + base::BindLambdaForTesting([&] { invalidator.reset(); })); + bool result = ptr->Ping(); + EXPECT_FALSE(result); +} + +TEST_F(InterfaceInvalidatorTest, InvalidateStrongBinding) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + auto impl_ptr = + MakeRevocableStrongBinding(std::make_unique<PingServiceImplBase>(), + MakeRequest(&ptr), invalidator.get()); + auto* impl = reinterpret_cast<PingServiceImplBase*>(impl_ptr->impl()); + + bool impl_called = false; + impl->set_ping_handler(base::BindRepeating(DoSetFlag, &impl_called)); + bool ping_called = false; + ptr->Ping(base::BindRepeating(DoSetFlag, &ping_called)); + base::RunLoop().RunUntilIdle(); + ASSERT_TRUE(impl_called); + ASSERT_TRUE(ping_called); + + impl->set_ping_handler(base::BindRepeating([] { FAIL(); })); + invalidator.reset(); + ptr->Ping(base::BindRepeating([] { FAIL(); })); + base::RunLoop().RunUntilIdle(); + + ASSERT_FALSE(impl_ptr); +} + +TEST_F(InterfaceInvalidatorTest, InvalidateStrongBindingAfterError) { + mojo::test::blink::PingServicePtr ptr; + auto invalidator = std::make_unique<InterfaceInvalidator>(); + auto impl_ptr = + MakeRevocableStrongBinding(std::make_unique<PingServiceImplBase>(), + MakeRequest(&ptr), invalidator.get()); + ptr.set_connection_error_handler(base::BindOnce([] { FAIL(); })); + + ptr.reset(); + base::RunLoop().RunUntilIdle(); + invalidator.reset(); + base::RunLoop().RunUntilIdle(); + + ASSERT_FALSE(impl_ptr); +} + +} // namespace + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/mojo/kurl.typemap b/chromium/third_party/blink/renderer/platform/mojo/kurl.typemap new file mode 100644 index 00000000000..868ae80d716 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/kurl.typemap @@ -0,0 +1,15 @@ +# 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. + +mojom = "//url/mojom/url.mojom" +public_headers = [ "//third_party/blink/renderer/platform/weborigin/kurl.h" ] +traits_headers = + [ "//third_party/blink/renderer/platform/mojo/kurl_struct_traits.h" ] + +# Note: consumers of this typemap must themselves depend on platform. +deps = [ + "//mojo/public/cpp/bindings", + "//url", +] +type_mappings = [ "url.mojom.Url=::blink::KURL[force_serialize]" ] diff --git a/chromium/third_party/blink/renderer/platform/mojo/kurl_security_origin_test.cc b/chromium/third_party/blink/renderer/platform/mojo/kurl_security_origin_test.cc new file mode 100644 index 00000000000..e776e7040ad --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/kurl_security_origin_test.cc @@ -0,0 +1,89 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/mojom/url_test.mojom-blink.h" +#include "url/url_constants.h" + +namespace blink { +namespace { + +class UrlTestImpl : public url::mojom::blink::UrlTest { + public: + explicit UrlTestImpl(url::mojom::blink::UrlTestRequest request) + : binding_(this, std::move(request)) {} + + // UrlTest: + void BounceUrl(const KURL& in, BounceUrlCallback callback) override { + std::move(callback).Run(in); + } + + void BounceOrigin(const scoped_refptr<const SecurityOrigin>& in, + BounceOriginCallback callback) override { + std::move(callback).Run(in); + } + + private: + mojo::Binding<UrlTest> binding_; +}; + +} // namespace + +// Mojo version of chrome IPC test in url/ipc/url_param_traits_unittest.cc. +TEST(KURLSecurityOriginStructTraitsTest, Basic) { + base::MessageLoop message_loop; + + url::mojom::blink::UrlTestPtr proxy; + UrlTestImpl impl(MakeRequest(&proxy)); + + const char* serialize_cases[] = { + "http://www.google.com/", "http://user:pass@host.com:888/foo;bar?baz#nop", + }; + + for (const char* test_case : serialize_cases) { + KURL input(NullURL(), test_case); + KURL output; + EXPECT_TRUE(proxy->BounceUrl(input, &output)); + + // We want to test each component individually to make sure its range was + // correctly serialized and deserialized, not just the spec. + EXPECT_EQ(input.GetString(), output.GetString()); + EXPECT_EQ(input.IsValid(), output.IsValid()); + EXPECT_EQ(input.Protocol(), output.Protocol()); + EXPECT_EQ(input.User(), output.User()); + EXPECT_EQ(input.Pass(), output.Pass()); + EXPECT_EQ(input.Host(), output.Host()); + EXPECT_EQ(input.Port(), output.Port()); + EXPECT_EQ(input.GetPath(), output.GetPath()); + EXPECT_EQ(input.Query(), output.Query()); + EXPECT_EQ(input.FragmentIdentifier(), output.FragmentIdentifier()); + } + + // Test an excessively long GURL. + { + const std::string url = + std::string("http://example.org/").append(url::kMaxURLChars + 1, 'a'); + KURL input(NullURL(), url.c_str()); + KURL output; + EXPECT_TRUE(proxy->BounceUrl(input, &output)); + EXPECT_TRUE(output.IsEmpty()); + } + + // Test basic Origin serialization. + scoped_refptr<const SecurityOrigin> non_unique = + SecurityOrigin::Create("http", "www.google.com", 80); + scoped_refptr<const SecurityOrigin> output; + EXPECT_TRUE(proxy->BounceOrigin(non_unique, &output)); + EXPECT_TRUE(non_unique->IsSameSchemeHostPort(output.get())); + EXPECT_FALSE(output->IsUnique()); + + scoped_refptr<const SecurityOrigin> unique = SecurityOrigin::CreateUnique(); + EXPECT_TRUE(proxy->BounceOrigin(unique, &output)); + EXPECT_TRUE(output->IsUnique()); +} + +} // namespace url diff --git a/chromium/third_party/blink/renderer/platform/mojo/kurl_struct_traits.h b/chromium/third_party/blink/renderer/platform/mojo/kurl_struct_traits.h new file mode 100644 index 00000000000..f1b87901d35 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/kurl_struct_traits.h @@ -0,0 +1,42 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_KURL_STRUCT_TRAITS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_KURL_STRUCT_TRAITS_H_ + +#include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "url/mojom/url.mojom-blink.h" +#include "url/url_constants.h" + +namespace mojo { + +template <> +struct StructTraits<url::mojom::blink::Url::DataView, ::blink::KURL> { + static WTF::String url(const ::blink::KURL& blinkUrl) { + if (!blinkUrl.IsValid() || + blinkUrl.GetString().length() > url::kMaxURLChars) { + return g_empty_string; + } + + return blinkUrl.GetString(); + } + static bool Read(url::mojom::blink::Url::DataView data, ::blink::KURL* out) { + WTF::String urlString; + if (!data.ReadUrl(&urlString)) + return false; + + if (urlString.length() > url::kMaxURLChars) + return false; + + *out = ::blink::KURL(::blink::KURL(), urlString); + if (!urlString.IsEmpty() && !out->IsValid()) + return false; + + return true; + } +}; +} + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_KURL_STRUCT_TRAITS_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/mojo_helper.h b/chromium/third_party/blink/renderer/platform/mojo/mojo_helper.h new file mode 100644 index 00000000000..03f2d40ecea --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/mojo_helper.h @@ -0,0 +1,22 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_MOJO_HELPER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_MOJO_HELPER_H_ + +#include "base/message_loop/message_loop.h" + +namespace blink { + +// Used to get whether message loop is ready for current thread, to help +// blink::initialize() determining whether can initialize mojo stuff or not. +// TODO(leonhsl): http://crbug.com/660274 Remove this API by ensuring +// a message loop before calling blink::initialize(). +inline bool CanInitializeMojo() { + return base::MessageLoop::current(); +} + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_MOJO_HELPER_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.cc b/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.cc new file mode 100644 index 00000000000..5cd6623fa3a --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.cc @@ -0,0 +1,287 @@ +// 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 "third_party/blink/renderer/platform/mojo/notification_struct_traits.h" + +#include <iterator> + +namespace mojo { + +using blink::mojom::NotificationDirection; +using blink::mojom::NotificationActionType; + +// static +NotificationDirection +EnumTraits<NotificationDirection, blink::WebNotificationData::Direction>:: + ToMojom(blink::WebNotificationData::Direction input) { + switch (input) { + case blink::WebNotificationData::kDirectionLeftToRight: + return NotificationDirection::LEFT_TO_RIGHT; + case blink::WebNotificationData::kDirectionRightToLeft: + return NotificationDirection::RIGHT_TO_LEFT; + case blink::WebNotificationData::kDirectionAuto: + return NotificationDirection::AUTO; + } + + NOTREACHED(); + return NotificationDirection::AUTO; +} + +// static +bool EnumTraits<NotificationDirection, blink::WebNotificationData::Direction>:: + FromMojom(NotificationDirection input, + blink::WebNotificationData::Direction* out) { + switch (input) { + case NotificationDirection::LEFT_TO_RIGHT: + *out = blink::WebNotificationData::kDirectionLeftToRight; + return true; + case NotificationDirection::RIGHT_TO_LEFT: + *out = blink::WebNotificationData::kDirectionRightToLeft; + return true; + case NotificationDirection::AUTO: + *out = blink::WebNotificationData::kDirectionAuto; + return true; + } + + return false; +} + +// static +NotificationActionType +EnumTraits<NotificationActionType, blink::WebNotificationAction::Type>::ToMojom( + blink::WebNotificationAction::Type input) { + switch (input) { + case blink::WebNotificationAction::kButton: + return NotificationActionType::BUTTON; + case blink::WebNotificationAction::kText: + return NotificationActionType::TEXT; + } + + NOTREACHED(); + return NotificationActionType::BUTTON; +} + +// static +bool EnumTraits<NotificationActionType, blink::WebNotificationAction::Type>:: + FromMojom(NotificationActionType input, + blink::WebNotificationAction::Type* out) { + switch (input) { + case NotificationActionType::BUTTON: + *out = blink::WebNotificationAction::kButton; + return true; + case NotificationActionType::TEXT: + *out = blink::WebNotificationAction::kText; + return true; + } + + return false; +} + +// static +WTF::String StructTraits<blink::mojom::NotificationActionDataView, + blink::WebNotificationAction>:: + action(const blink::WebNotificationAction& action) { + return action.action; +} + +// static +WTF::String StructTraits<blink::mojom::NotificationActionDataView, + blink::WebNotificationAction>:: + title(const blink::WebNotificationAction& action) { + return action.title; +} + +// static +blink::KURL StructTraits<blink::mojom::NotificationActionDataView, + blink::WebNotificationAction>:: + icon(const blink::WebNotificationAction& action) { + return action.icon; +} + +// static +WTF::String StructTraits<blink::mojom::NotificationActionDataView, + blink::WebNotificationAction>:: + placeholder(const blink::WebNotificationAction& action) { + return action.placeholder; +} + +// static +bool StructTraits<blink::mojom::NotificationActionDataView, + blink::WebNotificationAction>:: + Read(blink::mojom::NotificationActionDataView notification_action, + blink::WebNotificationAction* out) { + WTF::String action; + WTF::String title; + blink::KURL icon; + WTF::String placeholder; + + if (!notification_action.ReadType(&out->type) || + !notification_action.ReadTitle(&title) || + !notification_action.ReadAction(&action) || + !notification_action.ReadIcon(&icon) || + !notification_action.ReadPlaceholder(&placeholder)) { + return false; + } + + out->action = action; + out->title = title; + out->icon = icon; + out->placeholder = placeholder; + return true; +} + +// static +WTF::String StructTraits< + blink::mojom::NotificationDataDataView, + blink::WebNotificationData>::title(const blink::WebNotificationData& data) { + return data.title; +} + +// static +WTF::String StructTraits< + blink::mojom::NotificationDataDataView, + blink::WebNotificationData>::lang(const blink::WebNotificationData& data) { + return data.lang; +} + +// static +WTF::String StructTraits< + blink::mojom::NotificationDataDataView, + blink::WebNotificationData>::body(const blink::WebNotificationData& data) { + return data.body; +} + +// static +WTF::String StructTraits< + blink::mojom::NotificationDataDataView, + blink::WebNotificationData>::tag(const blink::WebNotificationData& data) { + return data.tag; +} + +// static +blink::KURL StructTraits< + blink::mojom::NotificationDataDataView, + blink::WebNotificationData>::image(const blink::WebNotificationData& data) { + return data.image; +} + +// static +blink::KURL StructTraits< + blink::mojom::NotificationDataDataView, + blink::WebNotificationData>::icon(const blink::WebNotificationData& data) { + return data.icon; +} + +// static +blink::KURL StructTraits< + blink::mojom::NotificationDataDataView, + blink::WebNotificationData>::badge(const blink::WebNotificationData& data) { + return data.badge; +} + +// static +base::span<const int32_t> StructTraits<blink::mojom::NotificationDataDataView, + blink::WebNotificationData>:: + vibration_pattern(const blink::WebNotificationData& data) { + // TODO(https://crbug.com/798466): Align data types to avoid this cast. + return base::make_span(reinterpret_cast<const int32_t*>(data.vibrate.Data()), + data.vibrate.size()); +} + +// static +base::span<const blink::WebNotificationAction> StructTraits< + blink::mojom::NotificationDataDataView, + blink::WebNotificationData>::actions(const blink::WebNotificationData& + data) { + return base::make_span(data.actions.Data(), data.actions.size()); +} + +// static +base::span<const int8_t> StructTraits< + blink::mojom::NotificationDataDataView, + blink::WebNotificationData>::data(const blink::WebNotificationData& data) { + // TODO(https://crbug.com/798466): Align data types to avoid this cast. + return base::make_span(reinterpret_cast<const int8_t*>(data.data.Data()), + data.data.size()); +} + +// static +bool StructTraits<blink::mojom::NotificationDataDataView, + blink::WebNotificationData>:: + Read(blink::mojom::NotificationDataDataView notification_data, + blink::WebNotificationData* out) { + // We can't read these values to the |out| type directly because it relies + // on Web* types, whereas Mojo uses the regular WTF types. This will be + // solved when the Web* types are removed as part of the Onion Soup refactor. + WTF::String title; + WTF::String lang; + WTF::String body; + WTF::String tag; + + blink::KURL image; + blink::KURL icon; + blink::KURL badge; + Vector<int32_t> vibrate; + Vector<int8_t> data; + Vector<blink::WebNotificationAction> actions; + + if (!notification_data.ReadTitle(&title) || + !notification_data.ReadDirection(&out->direction) || + !notification_data.ReadLang(&lang) || + !notification_data.ReadBody(&body) || !notification_data.ReadTag(&tag) || + !notification_data.ReadImage(&image) || + !notification_data.ReadIcon(&icon) || + !notification_data.ReadBadge(&badge) || + !notification_data.ReadVibrationPattern(&vibrate) || + !notification_data.ReadData(&data) || + !notification_data.ReadActions(&actions)) { + return false; + } + + out->title = title; + out->lang = lang; + out->body = body; + out->tag = tag; + out->image = image; + out->icon = icon; + out->badge = badge; + out->vibrate = vibrate; + out->timestamp = notification_data.timestamp(); + out->renotify = notification_data.renotify(); + out->silent = notification_data.silent(); + out->require_interaction = notification_data.require_interaction(); + out->data = data; + out->actions = actions; + return true; +} + +// static +base::span<const SkBitmap> +StructTraits<blink::mojom::NotificationResourcesDataView, + blink::WebNotificationResources>:: + action_icons(const blink::WebNotificationResources& resources) { + return base::make_span(resources.action_icons.Data(), + resources.action_icons.size()); +} + +// static +bool StructTraits<blink::mojom::NotificationResourcesDataView, + blink::WebNotificationResources>:: + Read(blink::mojom::NotificationResourcesDataView notification_resources, + blink::WebNotificationResources* out) { + // Cannot read to |out| directly because it expects a WebVector (see above). + Vector<SkBitmap> action_icons; + + if (!notification_resources.ReadImage(&out->image) || + !notification_resources.ReadIcon(&out->icon) || + !notification_resources.ReadBadge(&out->badge) || + !notification_resources.ReadActionIcons(&action_icons)) { + return false; + } + + out->action_icons = action_icons; + return true; +} + +} // namespace mojo diff --git a/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.h b/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.h new file mode 100644 index 00000000000..ac67fd10220 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits.h @@ -0,0 +1,140 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_NOTIFICATION_STRUCT_TRAITS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_NOTIFICATION_STRUCT_TRAITS_H_ + +#include "base/containers/span.h" +#include "mojo/public/cpp/bindings/array_traits_wtf_vector.h" +#include "mojo/public/cpp/bindings/string_traits_wtf.h" +#include "skia/public/interfaces/bitmap_skbitmap_struct_traits.h" +#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h" +#include "third_party/blink/public/platform/modules/notifications/web_notification_action.h" +#include "third_party/blink/renderer/platform/mojo/kurl_struct_traits.h" +#include "third_party/blink/renderer/platform/mojo/string16_mojom_traits.h" +#include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/skia/include/core/SkBitmap.h" + +namespace mojo { + +template <> +struct PLATFORM_EXPORT EnumTraits<blink::mojom::NotificationDirection, + blink::WebNotificationData::Direction> { + static blink::mojom::NotificationDirection ToMojom( + blink::WebNotificationData::Direction input); + + static bool FromMojom(blink::mojom::NotificationDirection input, + blink::WebNotificationData::Direction* out); +}; + +template <> +struct PLATFORM_EXPORT EnumTraits<blink::mojom::NotificationActionType, + blink::WebNotificationAction::Type> { + static blink::mojom::NotificationActionType ToMojom( + blink::WebNotificationAction::Type input); + + static bool FromMojom(blink::mojom::NotificationActionType input, + blink::WebNotificationAction::Type* out); +}; + +template <> +struct PLATFORM_EXPORT StructTraits<blink::mojom::NotificationActionDataView, + blink::WebNotificationAction> { + static blink::WebNotificationAction::Type type( + const blink::WebNotificationAction& action) { + return action.type; + } + + static WTF::String action(const blink::WebNotificationAction&); + + static WTF::String title(const blink::WebNotificationAction&); + + static blink::KURL icon(const blink::WebNotificationAction&); + + static WTF::String placeholder(const blink::WebNotificationAction&); + + static bool Read(blink::mojom::NotificationActionDataView, + blink::WebNotificationAction* output); +}; + +template <> +struct PLATFORM_EXPORT StructTraits<blink::mojom::NotificationDataDataView, + blink::WebNotificationData> { + static WTF::String title(const blink::WebNotificationData&); + + static blink::WebNotificationData::Direction direction( + const blink::WebNotificationData& data) { + return data.direction; + } + + static WTF::String lang(const blink::WebNotificationData&); + + static WTF::String body(const blink::WebNotificationData&); + + static WTF::String tag(const blink::WebNotificationData&); + + static blink::KURL image(const blink::WebNotificationData&); + + static blink::KURL icon(const blink::WebNotificationData&); + + static blink::KURL badge(const blink::WebNotificationData&); + + static base::span<const int32_t> vibration_pattern( + const blink::WebNotificationData&); + + static double timestamp(const blink::WebNotificationData& data) { + return data.timestamp; + } + + static bool renotify(const blink::WebNotificationData& data) { + return data.renotify; + } + + static bool silent(const blink::WebNotificationData& data) { + return data.silent; + } + + static bool require_interaction(const blink::WebNotificationData& data) { + return data.require_interaction; + } + + static base::span<const int8_t> data(const blink::WebNotificationData&); + + static base::span<const blink::WebNotificationAction> actions( + const blink::WebNotificationData&); + + static bool Read(blink::mojom::NotificationDataDataView, + blink::WebNotificationData* output); +}; + +template <> +struct PLATFORM_EXPORT StructTraits<blink::mojom::NotificationResourcesDataView, + blink::WebNotificationResources> { + static const SkBitmap& image( + const blink::WebNotificationResources& resources) { + return resources.image; + } + + static const SkBitmap& icon( + const blink::WebNotificationResources& resources) { + return resources.icon; + } + + static const SkBitmap& badge( + const blink::WebNotificationResources& resources) { + return resources.badge; + } + + static base::span<const SkBitmap> action_icons( + const blink::WebNotificationResources&); + + static bool Read(blink::mojom::NotificationResourcesDataView, + blink::WebNotificationResources* output); +}; + +} // namespace mojo + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_NOTIFICATION_STRUCT_TRAITS_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits_test.cc b/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits_test.cc new file mode 100644 index 00000000000..6f02d86a1e4 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits_test.cc @@ -0,0 +1,175 @@ +// 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 "third_party/blink/renderer/platform/mojo/notification_struct_traits.h" + +#include <algorithm> + +#include "base/macros.h" +#include "base/strings/stringprintf.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h" +#include "third_party/blink/public/platform/modules/notifications/web_notification_data.h" +#include "third_party/blink/public/platform/modules/notifications/web_notification_resources.h" +#include "third_party/blink/public/platform/web_url.h" +#include "third_party/blink/public/platform/web_vector.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkColor.h" + +namespace blink { + +namespace { + +const char kNotificationBaseUrl[] = "https://example.com/directory/"; + +SkBitmap CreateBitmap(int width, int height, SkColor color) { + SkBitmap bitmap; + bitmap.allocN32Pixels(width, height); + bitmap.eraseColor(color); + return bitmap; +} + +// Returns true if |lhs| and |rhs| have the same width and height and the +// pixel at position (0, 0) is the same color in both. +bool ImagesShareDimensionsAndColor(const SkBitmap& lhs, const SkBitmap& rhs) { + return lhs.width() == rhs.width() && lhs.height() == rhs.height() && + lhs.getColor(0, 0) == rhs.getColor(0, 0); +} + +} // namespace + +TEST(NotificationStructTraitsTest, NotificationDataRoundtrip) { + WebNotificationData notification_data; + notification_data.title = "Notification Title"; + notification_data.direction = WebNotificationData::kDirectionRightToLeft; + notification_data.lang = "foo-lang"; + notification_data.body = "Notification body..."; + notification_data.tag = "notificationTag"; + + const KURL kBaseUrl(kNotificationBaseUrl); + notification_data.image = WebURL(KURL(kBaseUrl, "noti_img.png")); + notification_data.icon = WebURL(KURL(kBaseUrl, "noti_icon.png")); + notification_data.badge = WebURL(KURL(kBaseUrl, "noti_badge.png")); + + const int vibrate[] = {200, 100, 300}; + WebVector<char> vibrate_vector(vibrate, arraysize(vibrate)); + notification_data.vibrate = vibrate_vector; + + notification_data.timestamp = 1513963983000.; + notification_data.renotify = true; + notification_data.silent = true; + notification_data.require_interaction = true; + + const char data[] = "some binary data"; + WebVector<char> data_vector(data, arraysize(data)); + notification_data.data = data_vector; + + WebVector<blink::WebNotificationAction> actions(static_cast<size_t>(2)); + + actions[0].type = blink::WebNotificationAction::kButton; + actions[0].action = "my_button_click"; + actions[0].title = "Button Title"; + actions[0].icon = blink::WebURL(KURL(kBaseUrl, "button.png")); + + actions[1].type = blink::WebNotificationAction::kText; + actions[1].action = "on_reply"; + actions[1].title = "Reply"; + actions[1].icon = blink::WebURL(KURL(kBaseUrl, "replyButton.png")); + actions[1].placeholder = "placeholder..."; + + notification_data.actions = actions; + + WebNotificationData roundtrip_notification_data; + + ASSERT_TRUE(mojom::blink::NotificationData::Deserialize( + mojom::blink::NotificationData::Serialize(¬ification_data), + &roundtrip_notification_data)); + + EXPECT_EQ(notification_data.title, roundtrip_notification_data.title); + EXPECT_EQ(notification_data.direction, roundtrip_notification_data.direction); + EXPECT_EQ(notification_data.lang, roundtrip_notification_data.lang); + EXPECT_EQ(notification_data.tag, roundtrip_notification_data.tag); + EXPECT_EQ(notification_data.image, roundtrip_notification_data.image); + EXPECT_EQ(notification_data.icon, roundtrip_notification_data.icon); + EXPECT_EQ(notification_data.badge, roundtrip_notification_data.badge); + + ASSERT_EQ(notification_data.vibrate.size(), + roundtrip_notification_data.vibrate.size()); + EXPECT_TRUE(std::equal(notification_data.vibrate.begin(), + notification_data.vibrate.end(), + roundtrip_notification_data.vibrate.begin())); + + EXPECT_EQ(notification_data.timestamp, roundtrip_notification_data.timestamp); + EXPECT_EQ(notification_data.renotify, roundtrip_notification_data.renotify); + EXPECT_EQ(notification_data.silent, roundtrip_notification_data.silent); + EXPECT_EQ(notification_data.require_interaction, + roundtrip_notification_data.require_interaction); + + ASSERT_EQ(notification_data.data.size(), + roundtrip_notification_data.data.size()); + EXPECT_TRUE(std::equal(notification_data.data.begin(), + notification_data.data.end(), + roundtrip_notification_data.data.begin())); + + ASSERT_EQ(notification_data.actions.size(), + roundtrip_notification_data.actions.size()); + for (size_t i = 0; i < notification_data.actions.size(); ++i) { + SCOPED_TRACE(base::StringPrintf("Action index: %zd", i)); + EXPECT_EQ(notification_data.actions[i].type, + roundtrip_notification_data.actions[i].type); + EXPECT_EQ(notification_data.actions[i].action, + roundtrip_notification_data.actions[i].action); + EXPECT_EQ(notification_data.actions[i].title, + roundtrip_notification_data.actions[i].title); + EXPECT_EQ(notification_data.actions[i].icon, + roundtrip_notification_data.actions[i].icon); + EXPECT_EQ(notification_data.actions[i].placeholder, + roundtrip_notification_data.actions[i].placeholder); + } +} + +TEST(NotificationStructTraitsTest, NotificationResourcesRoundtrip) { + WebNotificationResources resources; + + resources.image = CreateBitmap(300, 100, SK_ColorCYAN); + resources.icon = CreateBitmap(80, 100, SK_ColorRED); + resources.badge = CreateBitmap(50, 40, SK_ColorGREEN); + + WebVector<SkBitmap> action_icons(static_cast<size_t>(2)); + action_icons[0] = CreateBitmap(10, 10, SK_ColorLTGRAY); + action_icons[1] = CreateBitmap(11, 11, SK_ColorDKGRAY); + + resources.action_icons = action_icons; + + WebNotificationResources roundtrip_resources; + + ASSERT_TRUE(mojom::blink::NotificationResources::Deserialize( + mojom::blink::NotificationResources::Serialize(&resources), + &roundtrip_resources)); + + ASSERT_FALSE(roundtrip_resources.image.empty()); + EXPECT_TRUE(ImagesShareDimensionsAndColor(resources.image, + roundtrip_resources.image)); + + ASSERT_FALSE(roundtrip_resources.icon.empty()); + EXPECT_TRUE( + ImagesShareDimensionsAndColor(resources.icon, roundtrip_resources.icon)); + + ASSERT_FALSE(roundtrip_resources.badge.empty()); + EXPECT_TRUE(ImagesShareDimensionsAndColor(resources.badge, + roundtrip_resources.badge)); + + ASSERT_EQ(resources.action_icons.size(), + roundtrip_resources.action_icons.size()); + + for (size_t i = 0; i < roundtrip_resources.action_icons.size(); ++i) { + SCOPED_TRACE(base::StringPrintf("Action icon index: %zd", i)); + + ASSERT_FALSE(roundtrip_resources.action_icons[i].empty()); + EXPECT_TRUE(ImagesShareDimensionsAndColor( + resources.action_icons[i], roundtrip_resources.action_icons[i])); + } +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/mojo/referrer.typemap b/chromium/third_party/blink/renderer/platform/mojo/referrer.typemap new file mode 100644 index 00000000000..f151339e76c --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/referrer.typemap @@ -0,0 +1,14 @@ +# 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. + +mojom = "//third_party/blink/public/platform/referrer.mojom" +public_headers = + [ "//third_party/blink/renderer/platform/weborigin/referrer.h" ] +traits_headers = + [ "//third_party/blink/renderer/platform/mojo/referrer_struct_traits.h" ] +deps = [ + "//mojo/public/cpp/bindings", + "//url", +] +type_mappings = [ "blink.mojom.Referrer=::blink::Referrer" ] diff --git a/chromium/third_party/blink/renderer/platform/mojo/referrer_struct_traits.h b/chromium/third_party/blink/renderer/platform/mojo/referrer_struct_traits.h new file mode 100644 index 00000000000..fa898aa3df1 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/referrer_struct_traits.h @@ -0,0 +1,47 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_REFERRER_STRUCT_TRAITS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_REFERRER_STRUCT_TRAITS_H_ + +#include "third_party/blink/public/platform/referrer_policy_enum_traits.h" +#include "third_party/blink/public/platform/web_referrer_policy.h" +#include "third_party/blink/renderer/platform/weborigin/referrer.h" +#include "third_party/blink/renderer/platform/weborigin/referrer_policy.h" +#include "third_party/blink/renderer/platform/wtf/assertions.h" + +namespace mojo { + +template <> +struct StructTraits<blink::mojom::ReferrerDataView, blink::Referrer> { + static blink::KURL url(const blink::Referrer& referrer) { + if (referrer.referrer == blink::Referrer::NoReferrer()) + return blink::KURL(); + + return blink::KURL(blink::KURL(), referrer.referrer); + } + + // Equality of values is asserted in //Source/web/AssertMatchingEnums.cpp. + static blink::WebReferrerPolicy policy(const blink::Referrer& referrer) { + return static_cast<blink::WebReferrerPolicy>(referrer.referrer_policy); + } + + static bool Read(blink::mojom::ReferrerDataView data, blink::Referrer* out) { + blink::KURL referrer; + blink::WebReferrerPolicy webReferrerPolicy; + if (!data.ReadUrl(&referrer) || !data.ReadPolicy(&webReferrerPolicy)) + return false; + + out->referrer_policy = + static_cast<blink::ReferrerPolicy>(webReferrerPolicy); + out->referrer = AtomicString(referrer.GetString()); + + // Mimics the DCHECK() done in the blink::Referrer constructor. + return referrer.IsValid() || out->referrer == blink::Referrer::NoReferrer(); + } +}; + +} // namespace mojo + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_REFERRER_STRUCT_TRAITS_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/revocable_binding.h b/chromium/third_party/blink/renderer/platform/mojo/revocable_binding.h new file mode 100644 index 00000000000..b8d287b06b0 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/revocable_binding.h @@ -0,0 +1,181 @@ +// Copyright 2018 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_REVOCABLE_BINDING_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_REVOCABLE_BINDING_H_ + +#include <utility> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/single_thread_task_runner.h" +#include "mojo/public/cpp/bindings/connection_error_callback.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "mojo/public/cpp/bindings/lib/binding_state.h" +#include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h" +#include "mojo/public/cpp/system/core.h" +#include "third_party/blink/renderer/platform/mojo/interface_invalidator.h" + +namespace blink { + +class MessageReceiver; + +// RevocableBinding is a wrapper around a Binding that has to be tied to an +// InterfaceInvalidator when bound to a message pipe. The underlying connection +// is automatically closed once the InterfaceInvalidator is destroyed, and the +// binding will behave as if its peer had closed the connection. This is useful +// for tying the lifetime of mojo interfaces to another object. +// +// TODO(austinct): Add set_connection_error_with_reason_handler(), +// CloseWithReason(), ReportBadMessage() and GetBadMessageCallback() methods if +// needed. Undesirable for now because of the std::string parameter. +template <typename Interface, + typename ImplRefTraits = mojo::RawPtrImplRefTraits<Interface>> +class RevocableBinding : public InterfaceInvalidator::Observer { + public: + using ImplPointerType = typename ImplRefTraits::PointerType; + + // Constructs an incomplete binding that will use the implementation |impl|. + // The binding may be completed with a subsequent call to the |Bind| method. + // Does not take ownership of |impl|, which must outlive the binding. + explicit RevocableBinding(ImplPointerType impl) : binding_(std::move(impl)) {} + + // Constructs a completed binding of |impl| to the message pipe endpoint in + // |request|, taking ownership of the endpoint. Does not take ownership of + // |impl|, which must outlive the binding. Ties the lifetime of the binding to + // |invalidator|. + RevocableBinding(ImplPointerType impl, + mojo::InterfaceRequest<Interface> request, + InterfaceInvalidator* invalidator, + scoped_refptr<base::SingleThreadTaskRunner> runner = nullptr) + : RevocableBinding(std::move(impl)) { + Bind(std::move(request), invalidator, std::move(runner)); + } + + // Tears down the binding, closing the message pipe and leaving the interface + // implementation unbound. + ~RevocableBinding() { SetInvalidator(nullptr); } + + // Completes a binding that was constructed with only an interface + // implementation by removing the message pipe endpoint from |request| and + // binding it to the previously specified implementation. Ties the lifetime of + // the binding to |invalidator|. + void Bind(mojo::InterfaceRequest<Interface> request, + InterfaceInvalidator* invalidator, + scoped_refptr<base::SingleThreadTaskRunner> runner = nullptr) { + DCHECK(invalidator); + binding_.Bind(std::move(request), std::move(runner)); + SetInvalidator(invalidator); + } + + // Adds a message filter to be notified of each incoming message before + // dispatch. If a filter returns |false| from Accept(), the message is not + // dispatched and the pipe is closed. Filters cannot be removed. + void AddFilter(std::unique_ptr<MessageReceiver> filter) { + binding_.AddFilter(std::move(filter)); + } + + // Whether there are any associated interfaces running on the pipe currently. + bool HasAssociatedInterfaces() const { + return binding_.HasAssociatedInterfaces(); + } + + // Stops processing incoming messages until + // ResumeIncomingMethodCallProcessing(). + // Outgoing messages are still sent. + // + // No errors are detected on the message pipe while paused. + // + // This method may only be called if the object has been bound to a message + // pipe and there are no associated interfaces running. + void PauseIncomingMethodCallProcessing() { + binding_.PauseIncomingMethodCallProcessing(); + } + void ResumeIncomingMethodCallProcessing() { + binding_.ResumeIncomingMethodCallProcessing(); + } + + // Closes the message pipe that was previously bound. Put this object into a + // state where it can be rebound to a new pipe. + void Close() { + SetInvalidator(nullptr); + binding_.Close(); + } + + // Unbinds the underlying pipe from this binding and returns it so it can be + // used in another context, such as on another sequence or with a different + // implementation. Put this object into a state where it can be rebound to a + // new pipe. + // + // This method may only be called if the object has been bound to a message + // pipe and there are no associated interfaces running. + // + // TODO(yzshen): For now, users need to make sure there is no one holding + // on to associated interface endpoint handles at both sides of the + // message pipe in order to call this method. We need a way to forcefully + // invalidate associated interface endpoint handles. + mojo::InterfaceRequest<Interface> Unbind() { + SetInvalidator(nullptr); + return binding_.Unbind(); + } + + // Sets an error handler that will be called if a connection error occurs on + // the bound message pipe. + // + // This method may only be called after this RevocableBinding has been bound + // to a message pipe. The error handler will be reset when this + // RevocableBinding is unbound, closed or invalidated. + void set_connection_error_handler(base::OnceClosure error_handler) { + binding_.set_connection_error_handler(std::move(error_handler)); + } + + // Returns the interface implementation that was previously specified. Caller + // does not take ownership. + Interface* impl() { return binding_.impl(); } + + // Indicates whether the binding has been completed (i.e., whether a message + // pipe has been bound to the implementation). + explicit operator bool() const { return static_cast<bool>(binding_); } + + // Sends a no-op message on the underlying message pipe and runs the current + // message loop until its response is received. This can be used in tests to + // verify that no message was sent on a message pipe in response to some + // stimulus. + void FlushForTesting() { binding_.FlushForTesting(); } + + private: + // InterfaceInvalidator::Observer + void OnInvalidate() override { + if (binding_) { + binding_.internal_state()->RaiseError(); + } + if (invalidator_) { + invalidator_->RemoveObserver(this); + } + invalidator_.reset(); + } + + // Replaces the existing invalidator with a new invalidator and changes the + // invalidator being observed. + void SetInvalidator(InterfaceInvalidator* invalidator) { + if (invalidator_) + invalidator_->RemoveObserver(this); + + invalidator_.reset(); + if (invalidator) { + invalidator_ = invalidator->GetWeakPtr(); + invalidator_->AddObserver(this); + } + } + + mojo::Binding<Interface, ImplRefTraits> binding_; + base::WeakPtr<InterfaceInvalidator> invalidator_; + + DISALLOW_COPY_AND_ASSIGN(RevocableBinding); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_REVOCABLE_BINDING_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h b/chromium/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h new file mode 100644 index 00000000000..32101602afd --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h @@ -0,0 +1,237 @@ +// Copyright 2018 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_REVOCABLE_INTERFACE_PTR_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_REVOCABLE_INTERFACE_PTR_H_ + +#include <stdint.h> + +#include <string> +#include <utility> + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/single_thread_task_runner.h" +#include "mojo/public/cpp/bindings/connection_error_callback.h" +#include "mojo/public/cpp/bindings/interface_ptr_info.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "mojo/public/cpp/bindings/lib/interface_ptr_state.h" +#include "third_party/blink/renderer/platform/mojo/interface_invalidator.h" + +namespace blink { + +// RevocableInterfacePtr is a wrapper around an InterfacePtr that has to be tied +// to an InterfaceInvalidator when bound to a message pipe. The underlying +// connection is closed once the InterfaceInvalidator is destroyed and the +// interface will behave as if its peer had closed the connection. This is +// useful for tying the lifetime of interface pointers to another object. +template <typename Interface> +class RevocableInterfacePtr : public InterfaceInvalidator::Observer { + public: + using PtrType = mojo::InterfacePtr<Interface>; + using PtrInfoType = mojo::InterfacePtrInfo<Interface>; + using Proxy = typename Interface::Proxy_; + + // Constructs an unbound RevocableInterfacePtr. + RevocableInterfacePtr() {} + RevocableInterfacePtr(std::nullptr_t) {} + + // Takes over the binding of another RevocableInterfacePtr. + RevocableInterfacePtr(RevocableInterfacePtr&& other) { + interface_ptr_ = std::move(other.interface_ptr_); + SetInvalidator(other.invalidator_.get()); + // Reset the other interface ptr to remove it as an observer of the + // invalidator. + other.reset(); + } + + RevocableInterfacePtr(PtrInfoType info, InterfaceInvalidator* invalidator) { + Bind(std::move(info), invalidator); + } + + // Takes over the binding of another RevocableInterfacePtr, and closes any + // message pipe already bound to this pointer. + RevocableInterfacePtr& operator=(RevocableInterfacePtr&& other) { + reset(); + interface_ptr_ = std::move(other.interface_ptr); + SetInvalidator(other.invalidator_.get()); + // Reset the other interface ptr to remove it as an observer of the + // invalidator. + other.reset(); + return *this; + } + + // Assigning nullptr to this class causes it to close the currently bound + // message pipe (if any) and returns the pointer to the unbound state. + RevocableInterfacePtr& operator=(decltype(nullptr)) { + reset(); + return *this; + } + + // Closes the bound message pipe (if any) on destruction. + ~RevocableInterfacePtr() { + if (invalidator_) { + invalidator_->RemoveObserver(this); + } + } + + // Binds the RevocableInterfacePtr to a remote implementation of Interface. + // + // Calling with an invalid |info| (containing an invalid message pipe handle) + // has the same effect as reset(). In this case, the InterfacePtr is not + // considered as bound. + // + // |runner| must belong to the same thread. It will be used to dispatch all + // callbacks and connection error notification. It is useful when you attach + // multiple task runners to a single thread for the purposes of task + // scheduling. + void Bind(PtrInfoType info, + InterfaceInvalidator* invalidator, + scoped_refptr<base::SingleThreadTaskRunner> runner = nullptr) { + DCHECK(invalidator); + reset(); + if (info.is_valid()) { + interface_ptr_.Bind(std::move(info), std::move(runner)); + invalidator_ = invalidator->GetWeakPtr(); + invalidator_->AddObserver(this); + } + } + + // Returns a raw pointer to the local proxy. Caller does not take ownership. + // Note that the local proxy is thread hostile, as stated above. + Proxy* get() const { return interface_ptr_.get(); } + + // Functions like a pointer to Interface. Must already be bound. + Proxy* operator->() const { return get(); } + Proxy& operator*() const { return *get(); } + + // Returns the version number of the interface that the remote side supports. + uint32_t version() const { return interface_ptr_.version(); } + + // Queries the max version that the remote side supports. On completion, the + // result will be returned as the input of |callback|. The version number of + // this interface pointer will also be updated. + void QueryVersion(const base::RepeatingCallback<void(uint32_t)>& callback) { + interface_ptr_.QueryVersion(callback); + } + + // If the remote side doesn't support the specified version, it will close its + // end of the message pipe asynchronously. This does nothing if it's already + // known that the remote side supports the specified version, i.e., if + // |version <= this->version()|. + // + // After calling RequireVersion() with a version not supported by the remote + // side, all subsequent calls to interface methods will be ignored. + void RequireVersion(uint32_t version) { + interface_ptr_.RequireVersion(version); + } + + // Sends a no-op message on the underlying message pipe and runs the current + // message loop until its response is received. This can be used in tests to + // verify that no message was sent on a message pipe in response to some + // stimulus. + void FlushForTesting() { interface_ptr_.FlushForTesting(); } + + // Closes the bound message pipe, if any. + void reset() { + interface_ptr_.reset(); + SetInvalidator(nullptr); + } + + // Similar to the method above, but also specifies a disconnect reason. + void ResetWithReason(uint32_t custom_reason, const std::string& description) { + interface_ptr_.ResetWithReason(custom_reason, description); + SetInvalidator(nullptr); + } + + // Whether there are any associated interfaces running on the pipe currently. + bool HasAssociatedInterfaces() const { + return interface_ptr_.HasAssociatedInterfaces(); + } + + // Indicates whether the message pipe has encountered an error. If true, + // method calls made on this interface will be dropped (and may already have + // been dropped). + bool encountered_error() const { return interface_ptr_.encountered_error(); } + + // Registers a handler to receive error notifications. The handler will be + // called from the sequence that owns this RevocableInterfacePtr. + // + // This method may only be called after the RevocableInterfacePtr has been + // bound to a message pipe. + void set_connection_error_handler(base::OnceClosure error_handler) { + interface_ptr_.set_connection_error_handler(std::move(error_handler)); + } + + void set_connection_error_with_reason_handler( + mojo::ConnectionErrorWithReasonCallback error_handler) { + interface_ptr_.set_connection_error_with_reason_handler( + std::move(error_handler)); + } + + // Unbinds the RevocableInterfacePtr and returns the information which could + // be used to setup a RevocableInterfacePtr again. See comments on + // InterfacePtr::PassInterface for details. + PtrInfoType PassInterface() { + SetInvalidator(nullptr); + return interface_ptr_.PassInterface(); + } + + bool operator==(const RevocableInterfacePtr& other) const { + if (this == &other) + return true; + + // Now that the two refer to different objects, they are equivalent if + // and only if they are both null. + return !(*this) && !other; + } + + // Allow RevocableInterfacePtr<> to be used in boolean expressions. + explicit operator bool() const { return static_cast<bool>(interface_ptr_); } + + private: + // InterfaceInvalidator::Observer + void OnInvalidate() override { + interface_ptr_.internal_state()->RaiseError(); + if (invalidator_) { + invalidator_->RemoveObserver(this); + } + invalidator_.reset(); + } + + // Replaces the existing invalidator with a new invalidator and changes the + // invalidator being observed. + void SetInvalidator(InterfaceInvalidator* invalidator) { + if (invalidator_) + invalidator_->RemoveObserver(this); + + invalidator_.reset(); + if (invalidator) { + invalidator_ = invalidator->GetWeakPtr(); + invalidator_->AddObserver(this); + } + } + + PtrType interface_ptr_; + base::WeakPtr<InterfaceInvalidator> invalidator_; + + DISALLOW_COPY_AND_ASSIGN(RevocableInterfacePtr); +}; + +template <typename Interface> +mojo::InterfaceRequest<Interface> MakeRequest( + RevocableInterfacePtr<Interface>* ptr, + InterfaceInvalidator* invalidator, + scoped_refptr<base::SingleThreadTaskRunner> runner = nullptr) { + mojo::MessagePipe pipe; + ptr->Bind(mojo::InterfacePtrInfo<Interface>(std::move(pipe.handle0), 0u), + invalidator, std::move(runner)); + return mojo::InterfaceRequest<Interface>(std::move(pipe.handle1)); +} + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_REVOCABLE_INTERFACE_PTR_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/revocable_strong_binding.h b/chromium/third_party/blink/renderer/platform/mojo/revocable_strong_binding.h new file mode 100644 index 00000000000..69d7b27ed58 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/revocable_strong_binding.h @@ -0,0 +1,135 @@ +// Copyright 2018 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_REVOCABLE_STRONG_BINDING_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_REVOCABLE_STRONG_BINDING_H_ + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "mojo/public/cpp/bindings/connection_error_callback.h" +#include "mojo/public/cpp/bindings/filter_chain.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "mojo/public/cpp/bindings/message_header_validator.h" +#include "mojo/public/cpp/system/core.h" +#include "third_party/blink/renderer/platform/mojo/revocable_binding.h" + +namespace blink { + +class InterfaceInvalidator; + +template <typename Interface> +class RevocableStrongBinding; + +template <typename Interface> +using RevocableStrongBindingPtr = + base::WeakPtr<RevocableStrongBinding<Interface>>; + +// This is a wrapper around a StrongBinding that binds it to an interface +// invalidator. When the invalidator is destroyed or a connection error is +// detected, the interface implementation is deleted. If the task runner that a +// RevocableStrongBinding is bound on is stopped, the connection error handler +// will not be invoked and the implementation will not be deleted. +// +// To use, call RevocableStrongBinding<T>::Create() (see below) or the helper +// MakeRevocableStrongBinding function: +// +// MakeRevocableStrongBinding(std::make_unique<FooImpl>(), +// std::move(foo_request)); +// +template <typename Interface> +class RevocableStrongBinding { + public: + // Create a new RevocableStrongBinding instance. The instance owns itself, + // cleaning up only in the event of a pipe connection error or invalidation. + // Returns a WeakPtr to the new RevocableStrongBinding instance. + static RevocableStrongBindingPtr<Interface> Create( + std::unique_ptr<Interface> impl, + mojo::InterfaceRequest<Interface> request, + InterfaceInvalidator* invalidator) { + RevocableStrongBinding* binding = new RevocableStrongBinding( + std::move(impl), std::move(request), invalidator); + return binding->weak_factory_.GetWeakPtr(); + } + + // Note: The error handler must not delete the interface implementation. + // + // This method may only be called after this RevocableStrongBinding has been + // bound to a message pipe. + void set_connection_error_handler(base::OnceClosure error_handler) { + DCHECK(binding_.is_bound()); + connection_error_handler_ = std::move(error_handler); + } + + // Stops processing incoming messages until + // ResumeIncomingMethodCallProcessing(). + // Outgoing messages are still sent. + // + // No errors are detected on the message pipe while paused. + // + // This method may only be called if the object has been bound to a message + // pipe and there are no associated interfaces running. + void PauseIncomingMethodCallProcessing() { + binding_.PauseIncomingMethodCallProcessing(); + } + void ResumeIncomingMethodCallProcessing() { + binding_.ResumeIncomingMethodCallProcessing(); + } + + // Forces the binding to close. This destroys the RevocableStrongBinding + // instance. + void Close() { delete this; } + + Interface* impl() { return impl_.get(); } + + // Sends a message on the underlying message pipe and runs the current + // message loop until its response is received. This can be used in tests to + // verify that no message was sent on a message pipe in response to some + // stimulus. + void FlushForTesting() { binding_.FlushForTesting(); } + + private: + RevocableStrongBinding(std::unique_ptr<Interface> impl, + mojo::InterfaceRequest<Interface> request, + InterfaceInvalidator* invalidator) + : impl_(std::move(impl)), + binding_(impl_.get(), std::move(request), invalidator), + weak_factory_(this) { + binding_.set_connection_error_handler(base::BindOnce( + &RevocableStrongBinding::OnConnectionError, base::Unretained(this))); + } + + ~RevocableStrongBinding() = default; + + void OnConnectionError() { + if (connection_error_handler_) { + std::move(connection_error_handler_).Run(); + } + Close(); + } + + std::unique_ptr<Interface> impl_; + base::OnceClosure connection_error_handler_; + RevocableBinding<Interface> binding_; + base::WeakPtrFactory<RevocableStrongBinding> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(RevocableStrongBinding); +}; + +template <typename Interface, typename Impl> +RevocableStrongBindingPtr<Interface> MakeRevocableStrongBinding( + std::unique_ptr<Impl> impl, + mojo::InterfaceRequest<Interface> request, + InterfaceInvalidator* invalidator) { + return RevocableStrongBinding<Interface>::Create( + std::move(impl), std::move(request), invalidator); +} + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_REVOCABLE_STRONG_BINDING_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/security_origin.typemap b/chromium/third_party/blink/renderer/platform/mojo/security_origin.typemap new file mode 100644 index 00000000000..3b2de4ac9b7 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/security_origin.typemap @@ -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. + +mojom = "//url/mojom/origin.mojom" +public_headers = + [ "//third_party/blink/renderer/platform/weborigin/security_origin.h" ] +traits_headers = [ + "//third_party/blink/renderer/platform/mojo/security_origin_struct_traits.h", +] + +# Note: consumers of this typemap must themselves depend on platform. +deps = [ + "//mojo/public/cpp/bindings", + "//url", +] +type_mappings = + [ "url.mojom.Origin=scoped_refptr<const ::blink::SecurityOrigin>" ] diff --git a/chromium/third_party/blink/renderer/platform/mojo/security_origin_struct_traits.h b/chromium/third_party/blink/renderer/platform/mojo/security_origin_struct_traits.h new file mode 100644 index 00000000000..5aeaa5fc872 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/security_origin_struct_traits.h @@ -0,0 +1,56 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_SECURITY_ORIGIN_STRUCT_TRAITS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_SECURITY_ORIGIN_STRUCT_TRAITS_H_ + +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "url/mojom/origin.mojom-blink.h" + +namespace mojo { + +template <> +struct StructTraits<url::mojom::blink::Origin::DataView, + scoped_refptr<const ::blink::SecurityOrigin>> { + static WTF::String scheme( + const scoped_refptr<const ::blink::SecurityOrigin>& origin) { + return origin->Protocol(); + } + static WTF::String host( + const scoped_refptr<const ::blink::SecurityOrigin>& origin) { + return origin->Host(); + } + static uint16_t port( + const scoped_refptr<const ::blink::SecurityOrigin>& origin) { + return origin->EffectivePort(); + } + static bool unique( + const scoped_refptr<const ::blink::SecurityOrigin>& origin) { + return origin->IsUnique(); + } + static bool Read(url::mojom::blink::Origin::DataView data, + scoped_refptr<const ::blink::SecurityOrigin>* out) { + if (data.unique()) { + *out = ::blink::SecurityOrigin::CreateUnique(); + } else { + WTF::String scheme; + WTF::String host; + if (!data.ReadScheme(&scheme) || !data.ReadHost(&host)) + return false; + + *out = ::blink::SecurityOrigin::Create(scheme, host, data.port()); + } + + // If a unique origin was created, but the unique flag wasn't set, then + // the values provided to 'create' were invalid. + if (!data.unique() && (*out)->IsUnique()) + return false; + + return true; + } +}; +} + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_SECURITY_ORIGIN_STRUCT_TRAITS_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/string.typemap b/chromium/third_party/blink/renderer/platform/mojo/string.typemap new file mode 100644 index 00000000000..df022b0e774 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/string.typemap @@ -0,0 +1,13 @@ +# 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. + +mojom = "//mojo/public/mojom/base/string16.mojom" +public_headers = + [ "//third_party/blink/renderer/platform/wtf/text/wtf_string.h" ] +traits_headers = + [ "//third_party/blink/renderer/platform/mojo/string16_mojom_traits.h" ] +type_mappings = [ + "mojo_base.mojom.BigString16=WTF::String[nullable_is_same_type,force_serialize]", + "mojo_base.mojom.String16=WTF::String[nullable_is_same_type,force_serialize]", +] diff --git a/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.cc b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.cc new file mode 100644 index 00000000000..ca4d5c3190a --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.cc @@ -0,0 +1,102 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/mojo/string16_mojom_traits.h" + +#include <cstring> + +#include "base/containers/span.h" +#include "mojo/public/cpp/base/big_buffer.h" +#include "mojo/public/cpp/base/big_buffer_mojom_traits.h" + +namespace mojo { + +// static +void* StructTraits<mojo_base::mojom::String16DataView, + WTF::String>::SetUpContext(const WTF::String& input) { + // If it is null (i.e., StructTraits<>::IsNull() returns true), this method is + // guaranteed not to be called. + DCHECK(!input.IsNull()); + + if (!input.Is8Bit()) + return nullptr; + + return new base::string16(input.Characters8(), + input.Characters8() + input.length()); +} + +// static +void StructTraits<mojo_base::mojom::String16DataView, + WTF::String>::TearDownContext(const WTF::String& input, + void* context) { + delete static_cast<base::string16*>(context); +} + +// static +base::span<const uint16_t> +StructTraits<mojo_base::mojom::String16DataView, WTF::String>::data( + const WTF::String& input, + void* context) { + auto contextObject = static_cast<base::string16*>(context); + DCHECK_EQ(input.Is8Bit(), !!contextObject); + + if (contextObject) { + return base::make_span( + reinterpret_cast<const uint16_t*>(contextObject->data()), + contextObject->size()); + } + + return base::make_span( + reinterpret_cast<const uint16_t*>(input.Characters16()), input.length()); +} + +// static +bool StructTraits<mojo_base::mojom::String16DataView, WTF::String>::Read( + mojo_base::mojom::String16DataView data, + WTF::String* out) { + ArrayDataView<uint16_t> view; + data.GetDataDataView(&view); + *out = WTF::String(reinterpret_cast<const UChar*>(view.data()), view.size()); + return true; +} + +// static +mojo_base::BigBuffer StructTraits<mojo_base::mojom::BigString16DataView, + WTF::String>::data(const WTF::String& input) { + if (input.Is8Bit()) { + base::string16 input16(input.Characters8(), + input.Characters8() + input.length()); + return mojo_base::BigBuffer( + base::make_span(reinterpret_cast<const uint8_t*>(input16.data()), + input16.size() * sizeof(UChar))); + } + + return mojo_base::BigBuffer( + base::make_span(reinterpret_cast<const uint8_t*>(input.Characters16()), + input.length() * sizeof(UChar))); +} + +// static +bool StructTraits<mojo_base::mojom::BigString16DataView, WTF::String>::Read( + mojo_base::mojom::BigString16DataView data, + WTF::String* out) { + mojo_base::BigBuffer buffer; + if (!data.ReadData(&buffer)) + return false; + size_t size = buffer.size(); + if (size % sizeof(UChar)) + return false; + + // An empty |mojo_base::BigBuffer| may have a null |data()| if empty. + if (!size) { + *out = g_empty_string; + } else { + *out = WTF::String(reinterpret_cast<const UChar*>(buffer.data()), + size / sizeof(UChar)); + } + + return true; +} + +} // namespace mojo diff --git a/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.h b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.h new file mode 100644 index 00000000000..101e3357edd --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.h @@ -0,0 +1,46 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_STRING16_MOJOM_TRAITS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_STRING16_MOJOM_TRAITS_H_ + +#include "base/containers/span.h" +#include "base/strings/string16.h" +#include "mojo/public/cpp/bindings/struct_traits.h" +#include "mojo/public/mojom/base/string16.mojom-blink.h" +#include "third_party/blink/renderer/platform/platform_export.h" + +namespace mojo_base { +class BigBuffer; +} + +namespace mojo { + +template <> +struct PLATFORM_EXPORT + StructTraits<mojo_base::mojom::String16DataView, WTF::String> { + static bool IsNull(const WTF::String& input) { return input.IsNull(); } + static void SetToNull(WTF::String* output) { *output = WTF::String(); } + + static void* SetUpContext(const WTF::String& input); + static void TearDownContext(const WTF::String& input, void* context); + + static base::span<const uint16_t> data(const WTF::String& input, + void* context); + static bool Read(mojo_base::mojom::String16DataView, WTF::String* out); +}; + +template <> +struct PLATFORM_EXPORT + StructTraits<mojo_base::mojom::BigString16DataView, WTF::String> { + static bool IsNull(const WTF::String& input) { return input.IsNull(); } + static void SetToNull(WTF::String* output) { *output = WTF::String(); } + + static mojo_base::BigBuffer data(const WTF::String& input); + static bool Read(mojo_base::mojom::BigString16DataView, WTF::String* out); +}; + +} // namespace mojo + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_STRING16_MOJOM_TRAITS_H_ diff --git a/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits_test.cc b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits_test.cc new file mode 100644 index 00000000000..8aa308d79c2 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits_test.cc @@ -0,0 +1,95 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <cstdint> + +#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "base/rand_util.h" +#include "mojo/common/test_common_custom_types.mojom-blink.h" +#include "mojo/public/cpp/base/big_buffer_mojom_traits.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/test_support/test_utils.h" +#include "mojo/public/mojom/base/string16.mojom-blink.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/mojo/string16_mojom_traits.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" + +namespace blink { + +TEST(String16MojomTraitsTest, String16) { + // |str| is 8-bit. + String str = String::FromUTF8("hello world"); + String output; + + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojo_base::mojom::blink::String16>( + &str, &output)); + ASSERT_EQ(str, output); + + // Replace the "o"s in "hello world" with "o"s with acute, so that |str| is + // 16-bit. + str = String::FromUTF8("hell\xC3\xB3 w\xC3\xB3rld"); + + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojo_base::mojom::blink::String16>( + &str, &output)); + ASSERT_EQ(str, output); +} + +TEST(String16MojomTraitsTest, EmptyString16) { + String str = String::FromUTF8(""); + String output; + + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojo_base::mojom::blink::String16>( + &str, &output)); + ASSERT_EQ(str, output); +} + +TEST(String16MojomTraitsTest, BigString16_Empty) { + String str = String::FromUTF8(""); + String output; + + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojo_base::mojom::blink::BigString16>( + &str, &output)); + ASSERT_EQ(str, output); +} + +TEST(String16MojomTraitsTest, BigString16_Short) { + String str = String::FromUTF8("hello world"); + ASSERT_TRUE(str.Is8Bit()); + String output; + + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojo_base::mojom::blink::BigString16>( + &str, &output)); + ASSERT_EQ(str, output); + + // Replace the "o"s in "hello world" with "o"s with acute, so that |str| is + // 16-bit. + str = String::FromUTF8("hell\xC3\xB3 w\xC3\xB3rld"); + + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojo_base::mojom::blink::BigString16>( + &str, &output)); + ASSERT_EQ(str, output); +} + +TEST(String16MojomTraitsTest, BigString16_Long) { + WTF::Vector<char> random_latin1_string(1024 * 1024); + base::RandBytes(random_latin1_string.data(), random_latin1_string.size()); + + String str(random_latin1_string.data(), random_latin1_string.size()); + String output; + + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojo_base::mojom::blink::BigString16>( + &str, &output)); + ASSERT_EQ(str, output); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/mojo/time.typemap b/chromium/third_party/blink/renderer/platform/mojo/time.typemap new file mode 100644 index 00000000000..c02526da6f2 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mojo/time.typemap @@ -0,0 +1,19 @@ +# 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. + +mojom = "//mojo/public/mojom/base/time.mojom" +public_headers = [ "//third_party/blink/renderer/platform/wtf/time.h" ] +traits_headers = [ + "//ipc/ipc_message_utils.h", + "//mojo/public/cpp/base/time_mojom_traits.h", +] +public_deps = [ + "//ipc", + "//mojo/public/mojom/base", +] + +type_mappings = [ + "mojo_base.mojom.Time=WTF::Time[copyable_pass_by_value]", + "mojo_base.mojom.TimeDelta=WTF::TimeDelta[copyable_pass_by_value]", +] |