Commit 8bc2e0de authored by Mounir Lamouri's avatar Mounir Lamouri Committed by Commit Bot

Media Capabilities: split decoding and encoding callbacks in preparation for future changes.

Encrypted media will require a different callback as there is a new attribute
in the returned type so a WebMediaCapabilitiesDecodingInfo will be introduced.
This change allows to cut a lot of boilerplate from the incoming CL.

Bug: 907909
Change-Id: I61f6296c4a35678b8d4054d3df703b74471b1afb
Reviewed-on: https://chromium-review.googlesource.com/c/1348258
Commit-Queue: Mounir Lamouri <mlamouri@chromium.org>
Reviewed-by: default avatarJochen Eisinger <jochen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#610682}
parent 167a3530
...@@ -37,7 +37,7 @@ using base::ToLowerASCII; ...@@ -37,7 +37,7 @@ using base::ToLowerASCII;
namespace content { namespace content {
using blink::WebMediaCapabilitiesQueryCallbacks; using blink::WebMediaCapabilitiesEncodingInfoCallbacks;
namespace { namespace {
...@@ -113,7 +113,7 @@ AudioTrackRecorder::CodecId AudioStringToCodecId( ...@@ -113,7 +113,7 @@ AudioTrackRecorder::CodecId AudioStringToCodecId(
} }
void OnEncodingInfoError( void OnEncodingInfoError(
std::unique_ptr<WebMediaCapabilitiesQueryCallbacks> callbacks) { std::unique_ptr<WebMediaCapabilitiesEncodingInfoCallbacks> callbacks) {
callbacks->OnError(); callbacks->OnError();
} }
...@@ -347,7 +347,8 @@ void MediaRecorderHandler::Resume() { ...@@ -347,7 +347,8 @@ void MediaRecorderHandler::Resume() {
void MediaRecorderHandler::EncodingInfo( void MediaRecorderHandler::EncodingInfo(
const blink::WebMediaConfiguration& configuration, const blink::WebMediaConfiguration& configuration,
std::unique_ptr<blink::WebMediaCapabilitiesQueryCallbacks> callbacks) { std::unique_ptr<blink::WebMediaCapabilitiesEncodingInfoCallbacks>
callbacks) {
DCHECK(main_render_thread_checker_.CalledOnValidThread()); DCHECK(main_render_thread_checker_.CalledOnValidThread());
DCHECK(configuration.video_configuration || DCHECK(configuration.video_configuration ||
configuration.audio_configuration); configuration.audio_configuration);
......
...@@ -66,7 +66,8 @@ class CONTENT_EXPORT MediaRecorderHandler final ...@@ -66,7 +66,8 @@ class CONTENT_EXPORT MediaRecorderHandler final
void Resume() override; void Resume() override;
void EncodingInfo( void EncodingInfo(
const blink::WebMediaConfiguration& configuration, const blink::WebMediaConfiguration& configuration,
std::unique_ptr<blink::WebMediaCapabilitiesQueryCallbacks> cb) override; std::unique_ptr<blink::WebMediaCapabilitiesEncodingInfoCallbacks> cb)
override;
blink::WebString ActualMimeType() override; blink::WebString ActualMimeType() override;
private: private:
......
...@@ -143,7 +143,7 @@ WebMediaCapabilitiesClientImpl::~WebMediaCapabilitiesClientImpl() = default; ...@@ -143,7 +143,7 @@ WebMediaCapabilitiesClientImpl::~WebMediaCapabilitiesClientImpl() = default;
namespace { namespace {
void VideoPerfInfoCallback( void VideoPerfInfoCallback(
blink::ScopedWebCallbacks<blink::WebMediaCapabilitiesQueryCallbacks> blink::ScopedWebCallbacks<blink::WebMediaCapabilitiesDecodingInfoCallbacks>
scoped_callbacks, scoped_callbacks,
std::unique_ptr<blink::WebMediaCapabilitiesInfo> info, std::unique_ptr<blink::WebMediaCapabilitiesInfo> info,
bool is_smooth, bool is_smooth,
...@@ -155,14 +155,16 @@ void VideoPerfInfoCallback( ...@@ -155,14 +155,16 @@ void VideoPerfInfoCallback(
} }
void OnGetPerfInfoError( void OnGetPerfInfoError(
std::unique_ptr<blink::WebMediaCapabilitiesQueryCallbacks> callbacks) { std::unique_ptr<blink::WebMediaCapabilitiesDecodingInfoCallbacks>
callbacks) {
callbacks->OnError(); callbacks->OnError();
} }
} // namespace } // namespace
void WebMediaCapabilitiesClientImpl::DecodingInfo( void WebMediaCapabilitiesClientImpl::DecodingInfo(
const blink::WebMediaConfiguration& configuration, const blink::WebMediaConfiguration& configuration,
std::unique_ptr<blink::WebMediaCapabilitiesQueryCallbacks> callbacks) { std::unique_ptr<blink::WebMediaCapabilitiesDecodingInfoCallbacks>
callbacks) {
std::unique_ptr<blink::WebMediaCapabilitiesInfo> info( std::unique_ptr<blink::WebMediaCapabilitiesInfo> info(
new blink::WebMediaCapabilitiesInfo()); new blink::WebMediaCapabilitiesInfo());
......
...@@ -22,7 +22,8 @@ class MEDIA_BLINK_EXPORT WebMediaCapabilitiesClientImpl ...@@ -22,7 +22,8 @@ class MEDIA_BLINK_EXPORT WebMediaCapabilitiesClientImpl
// Implementation of blink::WebMediaCapabilitiesClient. // Implementation of blink::WebMediaCapabilitiesClient.
void DecodingInfo( void DecodingInfo(
const blink::WebMediaConfiguration&, const blink::WebMediaConfiguration&,
std::unique_ptr<blink::WebMediaCapabilitiesQueryCallbacks>) override; std::unique_ptr<blink::WebMediaCapabilitiesDecodingInfoCallbacks>)
override;
void BindVideoDecodePerfHistoryForTests( void BindVideoDecodePerfHistoryForTests(
mojom::VideoDecodePerfHistoryPtr decode_history_ptr); mojom::VideoDecodePerfHistoryPtr decode_history_ptr);
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_info.h" #include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_callbacks.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_configuration.h" #include "third_party/blink/public/platform/modules/media_capabilities/web_media_configuration.h"
using ::testing::_; using ::testing::_;
...@@ -34,7 +34,7 @@ class MockVideoDecodePerfHistory : public mojom::VideoDecodePerfHistory { ...@@ -34,7 +34,7 @@ class MockVideoDecodePerfHistory : public mojom::VideoDecodePerfHistory {
}; };
class MockWebMediaCapabilitiesQueryCallbacks class MockWebMediaCapabilitiesQueryCallbacks
: public blink::WebMediaCapabilitiesQueryCallbacks { : public blink::WebMediaCapabilitiesDecodingInfoCallbacks {
public: public:
~MockWebMediaCapabilitiesQueryCallbacks() override = default; ~MockWebMediaCapabilitiesQueryCallbacks() override = default;
......
...@@ -143,7 +143,9 @@ source_set("blink_headers") { ...@@ -143,7 +143,9 @@ source_set("blink_headers") {
"platform/modules/installedapp/web_related_application.h", "platform/modules/installedapp/web_related_application.h",
"platform/modules/installedapp/web_related_apps_fetcher.h", "platform/modules/installedapp/web_related_apps_fetcher.h",
"platform/modules/media_capabilities/web_audio_configuration.h", "platform/modules/media_capabilities/web_audio_configuration.h",
"platform/modules/media_capabilities/web_media_capabilities_callbacks.h",
"platform/modules/media_capabilities/web_media_capabilities_client.h", "platform/modules/media_capabilities/web_media_capabilities_client.h",
"platform/modules/media_capabilities/web_media_capabilities_info.h",
"platform/modules/media_capabilities/web_media_configuration.h", "platform/modules/media_capabilities/web_media_configuration.h",
"platform/modules/media_capabilities/web_video_configuration.h", "platform/modules/media_capabilities/web_video_configuration.h",
"platform/modules/notifications/web_notification_action.h", "platform/modules/notifications/web_notification_action.h",
......
// 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_PUBLIC_PLATFORM_MODULES_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_CALLBACKS_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_CALLBACKS_H_
#include <memory>
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_info.h"
#include "third_party/blink/public/platform/web_callbacks.h"
namespace blink {
using WebMediaCapabilitiesDecodingInfoCallbacks =
WebCallbacks<std::unique_ptr<WebMediaCapabilitiesInfo>, void>;
using WebMediaCapabilitiesEncodingInfoCallbacks =
WebCallbacks<std::unique_ptr<WebMediaCapabilitiesInfo>, void>;
} // namespace blink
#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_CALLBACKS_H_
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include <memory> #include <memory>
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_info.h" #include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_callbacks.h"
namespace blink { namespace blink {
...@@ -20,7 +20,7 @@ class WebMediaCapabilitiesClient { ...@@ -20,7 +20,7 @@ class WebMediaCapabilitiesClient {
virtual void DecodingInfo( virtual void DecodingInfo(
const WebMediaConfiguration&, const WebMediaConfiguration&,
std::unique_ptr<WebMediaCapabilitiesQueryCallbacks>) = 0; std::unique_ptr<WebMediaCapabilitiesDecodingInfoCallbacks>) = 0;
}; };
} // namespace blink } // namespace blink
......
...@@ -5,10 +5,6 @@ ...@@ -5,10 +5,6 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_INFO_H_ #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_INFO_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_INFO_H_ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_INFO_H_
#include <memory>
#include "third_party/blink/public/platform/web_callbacks.h"
namespace blink { namespace blink {
// Represents a MediaCapabilitiesInfo dictionary to be used outside of Blink. // Represents a MediaCapabilitiesInfo dictionary to be used outside of Blink.
...@@ -19,9 +15,6 @@ struct WebMediaCapabilitiesInfo { ...@@ -19,9 +15,6 @@ struct WebMediaCapabilitiesInfo {
bool power_efficient = false; bool power_efficient = false;
}; };
using WebMediaCapabilitiesQueryCallbacks =
WebCallbacks<std::unique_ptr<WebMediaCapabilitiesInfo>, void>;
} // namespace blink } // namespace blink
#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_INFO_H_ #endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_MEDIA_CAPABILITIES_WEB_MEDIA_CAPABILITIES_INFO_H_
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include "third_party/blink/public/platform/web_common.h" #include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_info.h" #include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_callbacks.h"
#include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_string.h"
namespace blink { namespace blink {
...@@ -54,7 +54,7 @@ class BLINK_PLATFORM_EXPORT WebMediaRecorderHandler { ...@@ -54,7 +54,7 @@ class BLINK_PLATFORM_EXPORT WebMediaRecorderHandler {
// https://wicg.github.io/media-capabilities/#media-capabilities-interface // https://wicg.github.io/media-capabilities/#media-capabilities-interface
virtual void EncodingInfo( virtual void EncodingInfo(
const WebMediaConfiguration&, const WebMediaConfiguration&,
std::unique_ptr<blink::WebMediaCapabilitiesQueryCallbacks>) {} std::unique_ptr<blink::WebMediaCapabilitiesEncodingInfoCallbacks>) {}
}; };
} // namespace blink } // namespace blink
......
...@@ -8,8 +8,10 @@ blink_modules_sources("media_capabilities") { ...@@ -8,8 +8,10 @@ blink_modules_sources("media_capabilities") {
sources = [ sources = [
"media_capabilities.cc", "media_capabilities.cc",
"media_capabilities.h", "media_capabilities.h",
"media_capabilities_query_callbacks.cc", "media_capabilities_decoding_info_callbacks.cc",
"media_capabilities_query_callbacks.h", "media_capabilities_decoding_info_callbacks.h",
"media_capabilities_encoding_info_callbacks.cc",
"media_capabilities_encoding_info_callbacks.h",
"navigator_media_capabilities.cc", "navigator_media_capabilities.cc",
"navigator_media_capabilities.h", "navigator_media_capabilities.h",
] ]
......
...@@ -16,8 +16,9 @@ ...@@ -16,8 +16,9 @@
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_decoding_info_callbacks.h"
#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_encoding_info_callbacks.h"
#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.h" #include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.h"
#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_query_callbacks.h"
#include "third_party/blink/renderer/modules/media_capabilities/media_configuration.h" #include "third_party/blink/renderer/modules/media_capabilities/media_configuration.h"
#include "third_party/blink/renderer/modules/media_capabilities/media_decoding_configuration.h" #include "third_party/blink/renderer/modules/media_capabilities/media_decoding_configuration.h"
#include "third_party/blink/renderer/modules/media_capabilities/media_encoding_configuration.h" #include "third_party/blink/renderer/modules/media_capabilities/media_encoding_configuration.h"
...@@ -246,7 +247,7 @@ ScriptPromise MediaCapabilities::decodingInfo( ...@@ -246,7 +247,7 @@ ScriptPromise MediaCapabilities::decodingInfo(
Platform::Current()->MediaCapabilitiesClient()->DecodingInfo( Platform::Current()->MediaCapabilitiesClient()->DecodingInfo(
ToWebMediaConfiguration(configuration), ToWebMediaConfiguration(configuration),
std::make_unique<MediaCapabilitiesQueryCallbacks>(resolver)); std::make_unique<MediaCapabilitiesDecodingInfoCallbacks>(resolver));
return promise; return promise;
} }
...@@ -294,7 +295,7 @@ ScriptPromise MediaCapabilities::encodingInfo( ...@@ -294,7 +295,7 @@ ScriptPromise MediaCapabilities::encodingInfo(
handler->EncodingInfo( handler->EncodingInfo(
ToWebMediaConfiguration(configuration), ToWebMediaConfiguration(configuration),
std::make_unique<MediaCapabilitiesQueryCallbacks>(resolver)); std::make_unique<MediaCapabilitiesEncodingInfoCallbacks>(resolver));
return promise; return promise;
} }
......
...@@ -2,19 +2,20 @@ ...@@ -2,19 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_query_callbacks.h" #include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_decoding_info_callbacks.h"
#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.h" #include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.h"
namespace blink { namespace blink {
MediaCapabilitiesQueryCallbacks::MediaCapabilitiesQueryCallbacks( MediaCapabilitiesDecodingInfoCallbacks::MediaCapabilitiesDecodingInfoCallbacks(
ScriptPromiseResolver* resolver) ScriptPromiseResolver* resolver)
: resolver_(resolver) {} : resolver_(resolver) {}
MediaCapabilitiesQueryCallbacks::~MediaCapabilitiesQueryCallbacks() = default; MediaCapabilitiesDecodingInfoCallbacks::
~MediaCapabilitiesDecodingInfoCallbacks() = default;
void MediaCapabilitiesQueryCallbacks::OnSuccess( void MediaCapabilitiesDecodingInfoCallbacks::OnSuccess(
std::unique_ptr<WebMediaCapabilitiesInfo> result) { std::unique_ptr<WebMediaCapabilitiesInfo> result) {
if (!resolver_->GetExecutionContext() || if (!resolver_->GetExecutionContext() ||
resolver_->GetExecutionContext()->IsContextDestroyed()) { resolver_->GetExecutionContext()->IsContextDestroyed()) {
...@@ -29,7 +30,7 @@ void MediaCapabilitiesQueryCallbacks::OnSuccess( ...@@ -29,7 +30,7 @@ void MediaCapabilitiesQueryCallbacks::OnSuccess(
resolver_->Resolve(std::move(info)); resolver_->Resolve(std::move(info));
} }
void MediaCapabilitiesQueryCallbacks::OnError() { void MediaCapabilitiesDecodingInfoCallbacks::OnError() {
NOTREACHED(); NOTREACHED();
} }
......
...@@ -2,21 +2,22 @@ ...@@ -2,21 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CAPABILITIES_MEDIA_CAPABILITIES_QUERY_CALLBACKS_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CAPABILITIES_MEDIA_CAPABILITIES_DECODING_INFO_CALLBACKS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CAPABILITIES_MEDIA_CAPABILITIES_QUERY_CALLBACKS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CAPABILITIES_MEDIA_CAPABILITIES_DECODING_INFO_CALLBACKS_H_
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_info.h" #include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_callbacks.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/heap/persistent.h"
namespace blink { namespace blink {
class MediaCapabilitiesQueryCallbacks class MediaCapabilitiesDecodingInfoCallbacks
: public WebMediaCapabilitiesQueryCallbacks { : public WebMediaCapabilitiesDecodingInfoCallbacks {
public: public:
explicit MediaCapabilitiesQueryCallbacks(ScriptPromiseResolver* resolver); explicit MediaCapabilitiesDecodingInfoCallbacks(
ScriptPromiseResolver* resolver);
~MediaCapabilitiesQueryCallbacks() override; ~MediaCapabilitiesDecodingInfoCallbacks() override;
void OnSuccess(std::unique_ptr<WebMediaCapabilitiesInfo>) override; void OnSuccess(std::unique_ptr<WebMediaCapabilitiesInfo>) override;
void OnError() override; void OnError() override;
......
// 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/modules/media_capabilities/media_capabilities_encoding_info_callbacks.h"
#include "third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.h"
namespace blink {
MediaCapabilitiesEncodingInfoCallbacks::MediaCapabilitiesEncodingInfoCallbacks(
ScriptPromiseResolver* resolver)
: resolver_(resolver) {}
MediaCapabilitiesEncodingInfoCallbacks::
~MediaCapabilitiesEncodingInfoCallbacks() = default;
void MediaCapabilitiesEncodingInfoCallbacks::OnSuccess(
std::unique_ptr<WebMediaCapabilitiesInfo> result) {
if (!resolver_->GetExecutionContext() ||
resolver_->GetExecutionContext()->IsContextDestroyed()) {
return;
}
Persistent<MediaCapabilitiesInfo> info(MediaCapabilitiesInfo::Create());
info->setSupported(result->supported);
info->setSmooth(result->smooth);
info->setPowerEfficient(result->power_efficient);
resolver_->Resolve(std::move(info));
}
void MediaCapabilitiesEncodingInfoCallbacks::OnError() {
NOTREACHED();
}
} // namespace blink
// 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_MODULES_MEDIA_CAPABILITIES_MEDIA_CAPABILITIES_ENCODING_INFO_CALLBACKS_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CAPABILITIES_MEDIA_CAPABILITIES_ENCODING_INFO_CALLBACKS_H_
#include "third_party/blink/public/platform/modules/media_capabilities/web_media_capabilities_callbacks.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
namespace blink {
class MediaCapabilitiesEncodingInfoCallbacks
: public WebMediaCapabilitiesEncodingInfoCallbacks {
public:
explicit MediaCapabilitiesEncodingInfoCallbacks(
ScriptPromiseResolver* resolver);
~MediaCapabilitiesEncodingInfoCallbacks() override;
void OnSuccess(std::unique_ptr<WebMediaCapabilitiesInfo>) override;
void OnError() override;
private:
Persistent<ScriptPromiseResolver> resolver_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CAPABILITIES_MEDIA_CAPABILITIES_ENCODING_INFO_CALLBACKS_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment