Commit 21e9fed9 authored by Julie Jeongeun Kim's avatar Julie Jeongeun Kim Committed by Commit Bot

Convert trial_comparison_cert_verifier.mojom to new Mojo types

This CL converts TrialComparisonCertVerifierConfigClient
and TrialComparisonCertVerifierReportClient from
trial_comparison_cert_verifier.mojom using PendingReceiver,
PendingRemote, Remote, RemoteSet, Receiver, and ReceiverSet.

Bug: 955171
Change-Id: Ib2c97b143d2ee0a631531ee24e66007b91e80b16
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1847411
Commit-Queue: Julie Kim <jkim@igalia.com>
Reviewed-by: default avatarMaksim Orlovich <morlovich@chromium.org>
Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Reviewed-by: default avatarOksana Zhuravlova <oksamyt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704978}
parent 195aa76f
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "content/public/common/content_features.h" #include "content/public/common/content_features.h"
#include "content/public/common/service_names.mojom.h" #include "content/public/common/service_names.mojom.h"
#include "content/public/common/url_constants.h" #include "content/public/common/url_constants.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/base/features.h" #include "net/base/features.h"
#include "net/http/http_auth_preferences.h" #include "net/http/http_auth_preferences.h"
#include "net/http/http_util.h" #include "net/http/http_util.h"
...@@ -502,8 +503,10 @@ ProfileNetworkContextService::CreateNetworkContextParams( ...@@ -502,8 +503,10 @@ ProfileNetworkContextService::CreateNetworkContextParams(
#if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED) #if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED)
if (!in_memory && !network_context_params->use_builtin_cert_verifier && if (!in_memory && !network_context_params->use_builtin_cert_verifier &&
TrialComparisonCertVerifierController::MaybeAllowedForProfile(profile_)) { TrialComparisonCertVerifierController::MaybeAllowedForProfile(profile_)) {
network::mojom::TrialComparisonCertVerifierConfigClientPtr config_client; mojo::PendingRemote<network::mojom::TrialComparisonCertVerifierConfigClient>
auto config_client_request = mojo::MakeRequest(&config_client); config_client;
auto config_client_receiver =
config_client.InitWithNewPipeAndPassReceiver();
network_context_params->trial_comparison_cert_verifier_params = network_context_params->trial_comparison_cert_verifier_params =
network::mojom::TrialComparisonCertVerifierParams::New(); network::mojom::TrialComparisonCertVerifierParams::New();
...@@ -514,14 +517,13 @@ ProfileNetworkContextService::CreateNetworkContextParams( ...@@ -514,14 +517,13 @@ ProfileNetworkContextService::CreateNetworkContextParams(
} }
trial_comparison_cert_verifier_controller_->AddClient( trial_comparison_cert_verifier_controller_->AddClient(
std::move(config_client), std::move(config_client),
mojo::MakeRequest( network_context_params->trial_comparison_cert_verifier_params
&network_context_params->trial_comparison_cert_verifier_params ->report_client.InitWithNewPipeAndPassReceiver());
->report_client));
network_context_params->trial_comparison_cert_verifier_params network_context_params->trial_comparison_cert_verifier_params
->initial_allowed = ->initial_allowed =
trial_comparison_cert_verifier_controller_->IsAllowed(); trial_comparison_cert_verifier_controller_->IsAllowed();
network_context_params->trial_comparison_cert_verifier_params network_context_params->trial_comparison_cert_verifier_params
->config_client_request = std::move(config_client_request); ->config_client_receiver = std::move(config_client_receiver);
} }
#endif #endif
......
...@@ -76,11 +76,13 @@ bool TrialComparisonCertVerifierController::MaybeAllowedForProfile( ...@@ -76,11 +76,13 @@ bool TrialComparisonCertVerifierController::MaybeAllowedForProfile(
} }
void TrialComparisonCertVerifierController::AddClient( void TrialComparisonCertVerifierController::AddClient(
network::mojom::TrialComparisonCertVerifierConfigClientPtr config_client, mojo::PendingRemote<network::mojom::TrialComparisonCertVerifierConfigClient>
network::mojom::TrialComparisonCertVerifierReportClientRequest config_client,
report_client_request) { mojo::PendingReceiver<
binding_set_.AddBinding(this, std::move(report_client_request)); network::mojom::TrialComparisonCertVerifierReportClient>
config_client_set_.AddPtr(std::move(config_client)); report_client_receiver) {
receiver_set_.Add(this, std::move(report_client_receiver));
config_client_set_.Add(std::move(config_client));
} }
bool TrialComparisonCertVerifierController::IsAllowed() const { bool TrialComparisonCertVerifierController::IsAllowed() const {
...@@ -138,9 +140,6 @@ void TrialComparisonCertVerifierController::SetFakeOfficialBuildForTesting( ...@@ -138,9 +140,6 @@ void TrialComparisonCertVerifierController::SetFakeOfficialBuildForTesting(
void TrialComparisonCertVerifierController::RefreshState() { void TrialComparisonCertVerifierController::RefreshState() {
const bool is_allowed = IsAllowed(); const bool is_allowed = IsAllowed();
config_client_set_.ForAllPtrs( for (auto& client : config_client_set_)
[is_allowed]( client->OnTrialConfigUpdated(is_allowed);
network::mojom::TrialComparisonCertVerifierConfigClient* client) {
client->OnTrialConfigUpdated(is_allowed);
});
} }
...@@ -15,8 +15,10 @@ ...@@ -15,8 +15,10 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_change_registrar.h"
#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/interface_ptr_set.h" #include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/remote_set.h"
#include "net/base/net_export.h" #include "net/base/net_export.h"
#include "net/cert/cert_verifier.h" #include "net/cert/cert_verifier.h"
#include "services/network/public/mojom/trial_comparison_cert_verifier.mojom.h" #include "services/network/public/mojom/trial_comparison_cert_verifier.mojom.h"
...@@ -36,11 +38,13 @@ class TrialComparisonCertVerifierController ...@@ -36,11 +38,13 @@ class TrialComparisonCertVerifierController
static bool MaybeAllowedForProfile(Profile* profile); static bool MaybeAllowedForProfile(Profile* profile);
// Adds a client to the controller, sending trial configuration updates to // Adds a client to the controller, sending trial configuration updates to
// |config_client|, and receiving trial reports from |report_client_request|. // |config_client|, and receiving trial reports from |report_client_receiver|.
void AddClient( void AddClient(mojo::PendingRemote<
network::mojom::TrialComparisonCertVerifierConfigClientPtr config_client, network::mojom::TrialComparisonCertVerifierConfigClient>
network::mojom::TrialComparisonCertVerifierReportClientRequest config_client,
report_client_request); mojo::PendingReceiver<
network::mojom::TrialComparisonCertVerifierReportClient>
report_client_receiver);
// Returns true if the trial is enabled and SBER flag is set for this // Returns true if the trial is enabled and SBER flag is set for this
// profile. // profile.
...@@ -66,10 +70,10 @@ class TrialComparisonCertVerifierController ...@@ -66,10 +70,10 @@ class TrialComparisonCertVerifierController
Profile* profile_; Profile* profile_;
PrefChangeRegistrar pref_change_registrar_; PrefChangeRegistrar pref_change_registrar_;
mojo::BindingSet<network::mojom::TrialComparisonCertVerifierReportClient> mojo::ReceiverSet<network::mojom::TrialComparisonCertVerifierReportClient>
binding_set_; receiver_set_;
mojo::InterfacePtrSet<network::mojom::TrialComparisonCertVerifierConfigClient> mojo::RemoteSet<network::mojom::TrialComparisonCertVerifierConfigClient>
config_client_set_; config_client_set_;
DISALLOW_COPY_AND_ASSIGN(TrialComparisonCertVerifierController); DISALLOW_COPY_AND_ASSIGN(TrialComparisonCertVerifierController);
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_task_traits.h"
#include "content/public/test/browser_task_environment.h" #include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_utils.h" #include "content/public/test/test_utils.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/cert/cert_verify_result.h" #include "net/cert/cert_verify_result.h"
#include "net/cert/x509_certificate.h" #include "net/cert/x509_certificate.h"
...@@ -84,15 +86,16 @@ class MockTrialComparisonCertVerifierConfigClient ...@@ -84,15 +86,16 @@ class MockTrialComparisonCertVerifierConfigClient
: public network::mojom::TrialComparisonCertVerifierConfigClient { : public network::mojom::TrialComparisonCertVerifierConfigClient {
public: public:
MockTrialComparisonCertVerifierConfigClient( MockTrialComparisonCertVerifierConfigClient(
network::mojom::TrialComparisonCertVerifierConfigClientRequest mojo::PendingReceiver<
config_client_request) network::mojom::TrialComparisonCertVerifierConfigClient>
: binding_(this, std::move(config_client_request)) {} config_client_receiver)
: receiver_(this, std::move(config_client_receiver)) {}
MOCK_METHOD1(OnTrialConfigUpdated, void(bool allowed)); MOCK_METHOD1(OnTrialConfigUpdated, void(bool allowed));
private: private:
mojo::Binding<network::mojom::TrialComparisonCertVerifierConfigClient> mojo::Receiver<network::mojom::TrialComparisonCertVerifierConfigClient>
binding_; receiver_;
}; };
class TrialComparisonCertVerifierControllerTest : public testing::Test { class TrialComparisonCertVerifierControllerTest : public testing::Test {
...@@ -145,17 +148,19 @@ class TrialComparisonCertVerifierControllerTest : public testing::Test { ...@@ -145,17 +148,19 @@ class TrialComparisonCertVerifierControllerTest : public testing::Test {
} }
void CreateController(Profile* profile) { void CreateController(Profile* profile) {
network::mojom::TrialComparisonCertVerifierConfigClientPtr config_client; mojo::PendingRemote<network::mojom::TrialComparisonCertVerifierConfigClient>
auto config_client_request = mojo::MakeRequest(&config_client); config_client;
auto config_client_receiver =
config_client.InitWithNewPipeAndPassReceiver();
trial_controller_ = trial_controller_ =
std::make_unique<TrialComparisonCertVerifierController>(profile); std::make_unique<TrialComparisonCertVerifierController>(profile);
trial_controller_->AddClient(std::move(config_client), trial_controller_->AddClient(std::move(config_client),
mojo::MakeRequest(&report_client_)); report_client_.BindNewPipeAndPassReceiver());
mock_config_client_ = std::make_unique< mock_config_client_ = std::make_unique<
StrictMock<MockTrialComparisonCertVerifierConfigClient>>( StrictMock<MockTrialComparisonCertVerifierConfigClient>>(
std::move(config_client_request)); std::move(config_client_receiver));
} }
void CreateController() { CreateController(profile()); } void CreateController() { CreateController(profile()); }
...@@ -183,8 +188,8 @@ class TrialComparisonCertVerifierControllerTest : public testing::Test { ...@@ -183,8 +188,8 @@ class TrialComparisonCertVerifierControllerTest : public testing::Test {
TrialComparisonCertVerifierController& trial_controller() { TrialComparisonCertVerifierController& trial_controller() {
return *trial_controller_; return *trial_controller_;
} }
network::mojom::TrialComparisonCertVerifierReportClientPtr& report_client() { network::mojom::TrialComparisonCertVerifierReportClient* report_client() {
return report_client_; return report_client_.get();
} }
MockTrialComparisonCertVerifierConfigClient& mock_config_client() { MockTrialComparisonCertVerifierConfigClient& mock_config_client() {
return *mock_config_client_; return *mock_config_client_;
...@@ -213,7 +218,8 @@ class TrialComparisonCertVerifierControllerTest : public testing::Test { ...@@ -213,7 +218,8 @@ class TrialComparisonCertVerifierControllerTest : public testing::Test {
std::unique_ptr<TestingProfileManager> profile_manager_; std::unique_ptr<TestingProfileManager> profile_manager_;
TestingProfile* profile_; TestingProfile* profile_;
network::mojom::TrialComparisonCertVerifierReportClientPtr report_client_; mojo::Remote<network::mojom::TrialComparisonCertVerifierReportClient>
report_client_;
std::unique_ptr<TrialComparisonCertVerifierController> trial_controller_; std::unique_ptr<TrialComparisonCertVerifierController> trial_controller_;
std::unique_ptr<StrictMock<MockTrialComparisonCertVerifierConfigClient>> std::unique_ptr<StrictMock<MockTrialComparisonCertVerifierConfigClient>>
mock_config_client_; mock_config_client_;
...@@ -386,16 +392,19 @@ TEST_F(TrialComparisonCertVerifierControllerTest, ...@@ -386,16 +392,19 @@ TEST_F(TrialComparisonCertVerifierControllerTest,
features::kCertDualVerificationTrialFeature); features::kCertDualVerificationTrialFeature);
CreateController(); CreateController();
network::mojom::TrialComparisonCertVerifierReportClientPtr report_client_2; mojo::Remote<network::mojom::TrialComparisonCertVerifierReportClient>
report_client_2;
network::mojom::TrialComparisonCertVerifierConfigClientPtr config_client_2; mojo::PendingRemote<network::mojom::TrialComparisonCertVerifierConfigClient>
auto config_client_2_request = mojo::MakeRequest(&config_client_2); config_client_2;
auto config_client_2_receiver =
config_client_2.InitWithNewPipeAndPassReceiver();
trial_controller().AddClient(std::move(config_client_2), trial_controller().AddClient(std::move(config_client_2),
mojo::MakeRequest(&report_client_2)); report_client_2.BindNewPipeAndPassReceiver());
StrictMock<MockTrialComparisonCertVerifierConfigClient> mock_config_client_2( StrictMock<MockTrialComparisonCertVerifierConfigClient> mock_config_client_2(
std::move(config_client_2_request)); std::move(config_client_2_receiver));
EXPECT_FALSE(trial_controller().IsAllowed()); EXPECT_FALSE(trial_controller().IsAllowed());
......
...@@ -1554,7 +1554,7 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext() { ...@@ -1554,7 +1554,7 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext() {
params_->trial_comparison_cert_verifier_params params_->trial_comparison_cert_verifier_params
->initial_allowed, ->initial_allowed,
std::move(params_->trial_comparison_cert_verifier_params std::move(params_->trial_comparison_cert_verifier_params
->config_client_request), ->config_client_receiver),
std::move(params_->trial_comparison_cert_verifier_params std::move(params_->trial_comparison_cert_verifier_params
->report_client), ->report_client),
net::CertVerifyProc::CreateSystemVerifyProc( net::CertVerifyProc::CreateSystemVerifyProc(
......
...@@ -43,11 +43,12 @@ interface TrialComparisonCertVerifierReportClient { ...@@ -43,11 +43,12 @@ interface TrialComparisonCertVerifierReportClient {
// Parameters for initializing the cert verification trial. // Parameters for initializing the cert verification trial.
// |initial_allowed| is the initial setting for whether the trial is allowed. // |initial_allowed| is the initial setting for whether the trial is allowed.
// |config_client_request| is the Mojo pipe over which trial configuration // |config_client_receiver| is the Mojo pipe over which trial configuration
// updates are received. // updates are received.
// |report_client| is the Mojo pipe used to send trial reports. // |report_client| is the Mojo pipe used to send trial reports.
struct TrialComparisonCertVerifierParams { struct TrialComparisonCertVerifierParams {
bool initial_allowed = false; bool initial_allowed = false;
TrialComparisonCertVerifierConfigClient&? config_client_request; pending_receiver<TrialComparisonCertVerifierConfigClient>?
TrialComparisonCertVerifierReportClient? report_client; config_client_receiver;
pending_remote<TrialComparisonCertVerifierReportClient>? report_client;
}; };
...@@ -21,11 +21,13 @@ namespace network { ...@@ -21,11 +21,13 @@ namespace network {
TrialComparisonCertVerifierMojo::TrialComparisonCertVerifierMojo( TrialComparisonCertVerifierMojo::TrialComparisonCertVerifierMojo(
bool initial_allowed, bool initial_allowed,
mojom::TrialComparisonCertVerifierConfigClientRequest config_client_request, mojo::PendingReceiver<mojom::TrialComparisonCertVerifierConfigClient>
mojom::TrialComparisonCertVerifierReportClientPtrInfo report_client, config_client_receiver,
mojo::PendingRemote<mojom::TrialComparisonCertVerifierReportClient>
report_client,
scoped_refptr<net::CertVerifyProc> primary_verify_proc, scoped_refptr<net::CertVerifyProc> primary_verify_proc,
scoped_refptr<net::CertVerifyProc> trial_verify_proc) scoped_refptr<net::CertVerifyProc> trial_verify_proc)
: binding_(this, std::move(config_client_request)), : receiver_(this, std::move(config_client_receiver)),
report_client_(std::move(report_client)) { report_client_(std::move(report_client)) {
trial_comparison_cert_verifier_ = trial_comparison_cert_verifier_ =
std::make_unique<net::TrialComparisonCertVerifier>( std::make_unique<net::TrialComparisonCertVerifier>(
......
...@@ -11,7 +11,10 @@ ...@@ -11,7 +11,10 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "base/optional.h" #include "base/optional.h"
#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/cert/cert_verifier.h" #include "net/cert/cert_verifier.h"
#include "services/network/public/mojom/trial_comparison_cert_verifier.mojom.h" #include "services/network/public/mojom/trial_comparison_cert_verifier.mojom.h"
...@@ -32,16 +35,17 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) TrialComparisonCertVerifierMojo ...@@ -32,16 +35,17 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) TrialComparisonCertVerifierMojo
public mojom::TrialComparisonCertVerifierConfigClient { public mojom::TrialComparisonCertVerifierConfigClient {
public: public:
// |initial_allowed| is the initial setting for whether the trial is allowed. // |initial_allowed| is the initial setting for whether the trial is allowed.
// |config_client_request| is the Mojo pipe over which trial configuration // |config_client_receiver| is the Mojo pipe over which trial configuration
// updates are received. // updates are received.
// |report_client| is the Mojo pipe used to send trial reports. // |report_client| is the Mojo pipe used to send trial reports.
// |primary_verify_proc| and |trial_verify_proc| are the CertVerifyProc // |primary_verify_proc| and |trial_verify_proc| are the CertVerifyProc
// implementations to compare. // implementations to compare.
TrialComparisonCertVerifierMojo( TrialComparisonCertVerifierMojo(
bool initial_allowed, bool initial_allowed,
mojom::TrialComparisonCertVerifierConfigClientRequest mojo::PendingReceiver<mojom::TrialComparisonCertVerifierConfigClient>
config_client_request, config_client_receiver,
mojom::TrialComparisonCertVerifierReportClientPtrInfo report_client, mojo::PendingRemote<mojom::TrialComparisonCertVerifierReportClient>
report_client,
scoped_refptr<net::CertVerifyProc> primary_verify_proc, scoped_refptr<net::CertVerifyProc> primary_verify_proc,
scoped_refptr<net::CertVerifyProc> trial_verify_proc); scoped_refptr<net::CertVerifyProc> trial_verify_proc);
~TrialComparisonCertVerifierMojo() override; ~TrialComparisonCertVerifierMojo() override;
...@@ -71,9 +75,9 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) TrialComparisonCertVerifierMojo ...@@ -71,9 +75,9 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) TrialComparisonCertVerifierMojo
const net::CertVerifyResult& primary_result, const net::CertVerifyResult& primary_result,
const net::CertVerifyResult& trial_result); const net::CertVerifyResult& trial_result);
mojo::Binding<mojom::TrialComparisonCertVerifierConfigClient> binding_; mojo::Receiver<mojom::TrialComparisonCertVerifierConfigClient> receiver_;
mojom::TrialComparisonCertVerifierReportClientPtr report_client_; mojo::Remote<mojom::TrialComparisonCertVerifierReportClient> report_client_;
std::unique_ptr<net::TrialComparisonCertVerifier> std::unique_ptr<net::TrialComparisonCertVerifier>
trial_comparison_cert_verifier_; trial_comparison_cert_verifier_;
......
...@@ -34,9 +34,10 @@ class FakeReportClient ...@@ -34,9 +34,10 @@ class FakeReportClient
: public network::mojom::TrialComparisonCertVerifierReportClient { : public network::mojom::TrialComparisonCertVerifierReportClient {
public: public:
explicit FakeReportClient( explicit FakeReportClient(
network::mojom::TrialComparisonCertVerifierReportClientRequest mojo::PendingReceiver<
report_client_request) network::mojom::TrialComparisonCertVerifierReportClient>
: binding_(this, std::move(report_client_request)) {} report_client_receiver)
: receiver_(this, std::move(report_client_receiver)) {}
// TrialComparisonCertVerifierReportClient implementation: // TrialComparisonCertVerifierReportClient implementation:
void SendTrialReport( void SendTrialReport(
...@@ -70,8 +71,8 @@ class FakeReportClient ...@@ -70,8 +71,8 @@ class FakeReportClient
void WaitForReport() { run_loop_.Run(); } void WaitForReport() { run_loop_.Run(); }
private: private:
mojo::Binding<network::mojom::TrialComparisonCertVerifierReportClient> mojo::Receiver<network::mojom::TrialComparisonCertVerifierReportClient>
binding_; receiver_;
std::vector<ReceivedReport> reports_; std::vector<ReceivedReport> reports_;
base::RunLoop run_loop_; base::RunLoop run_loop_;
...@@ -114,11 +115,12 @@ TEST(TrialComparisonCertVerifierMojoTest, SendReportDebugInfo) { ...@@ -114,11 +115,12 @@ TEST(TrialComparisonCertVerifierMojoTest, SendReportDebugInfo) {
net::CertVerifyProcBuiltinResultDebugData::Create(&trial_result, time, net::CertVerifyProcBuiltinResultDebugData::Create(&trial_result, time,
der_time); der_time);
network::mojom::TrialComparisonCertVerifierReportClientPtrInfo mojo::PendingRemote<network::mojom::TrialComparisonCertVerifierReportClient>
report_client_ptr; report_client_remote;
FakeReportClient report_client(mojo::MakeRequest(&report_client_ptr)); FakeReportClient report_client(
report_client_remote.InitWithNewPipeAndPassReceiver());
network::TrialComparisonCertVerifierMojo tccvm( network::TrialComparisonCertVerifierMojo tccvm(
true, {}, std::move(report_client_ptr), nullptr, nullptr); true, {}, std::move(report_client_remote), nullptr, nullptr);
tccvm.OnSendTrialReport("example.com", unverified_cert, false, false, false, tccvm.OnSendTrialReport("example.com", unverified_cert, false, false, false,
false, primary_result, trial_result); false, primary_result, trial_result);
......
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