| Index: components/password_manager/content/renderer/credential_manager_client.cc
|
| diff --git a/components/password_manager/content/renderer/credential_manager_client.cc b/components/password_manager/content/renderer/credential_manager_client.cc
|
| index 6c071a2f7ba298631e24267d47d259a990e67262..a7bf758ce4080fe0f656464381282bf0da90db04 100644
|
| --- a/components/password_manager/content/renderer/credential_manager_client.cc
|
| +++ b/components/password_manager/content/renderer/credential_manager_client.cc
|
| @@ -6,10 +6,14 @@
|
|
|
| #include <stddef.h>
|
|
|
| -#include "components/password_manager/content/common/credential_manager_content_utils.h"
|
| -#include "components/password_manager/content/common/credential_manager_messages.h"
|
| +#include "base/bind.h"
|
| +#include "base/logging.h"
|
| +#include "components/password_manager/content/public/cpp/type_converters.h"
|
| #include "components/password_manager/core/common/credential_manager_types.h"
|
| +#include "content/public/common/service_registry.h"
|
| +#include "content/public/renderer/render_frame.h"
|
| #include "content/public/renderer/render_view.h"
|
| +#include "mojo/common/url_type_converters.h"
|
| #include "third_party/WebKit/public/platform/WebCredential.h"
|
| #include "third_party/WebKit/public/platform/WebCredentialManagerError.h"
|
| #include "third_party/WebKit/public/platform/WebFederatedCredential.h"
|
| @@ -21,104 +25,165 @@ namespace password_manager {
|
|
|
| namespace {
|
|
|
| -template <typename T>
|
| -void ClearCallbacksMapWithErrors(T* callbacks_map) {
|
| - typename T::iterator iter(callbacks_map);
|
| - while (!iter.IsAtEnd()) {
|
| - iter.GetCurrentValue()->onError(blink::WebCredentialManagerUnknownError);
|
| - callbacks_map->Remove(iter.GetCurrentKey());
|
| - iter.Advance();
|
| +blink::WebCredentialManagerError GetWebCredentialManagerErrorFromMojo(
|
| + mojom::CredentialManagerError error) {
|
| + switch (error) {
|
| + case mojom::CredentialManagerError::DISABLED:
|
| + return blink::WebCredentialManagerError::
|
| + WebCredentialManagerDisabledError;
|
| + case mojom::CredentialManagerError::PENDINGREQUEST:
|
| + return blink::WebCredentialManagerError::
|
| + WebCredentialManagerPendingRequestError;
|
| + case mojom::CredentialManagerError::PASSWORDSTOREUNAVAILABLE:
|
| + return blink::WebCredentialManagerError::
|
| + WebCredentialManagerPasswordStoreUnavailableError;
|
| + case mojom::CredentialManagerError::UNKNOWN:
|
| + return blink::WebCredentialManagerError::WebCredentialManagerUnknownError;
|
| + case mojom::CredentialManagerError::SUCCESS:
|
| + NOTREACHED();
|
| + break;
|
| }
|
| +
|
| + NOTREACHED();
|
| + return blink::WebCredentialManagerError::WebCredentialManagerUnknownError;
|
| }
|
|
|
| -} // namespace
|
| +// Takes ownership of blink::WebCredentialManagerClient::NotificationCallbacks
|
| +// pointer. When the wrapper is destroyed, if |callbacks| is still alive
|
| +// its onError() will get called.
|
| +class NotificationCallbacksWrapper {
|
| + public:
|
| + explicit NotificationCallbacksWrapper(
|
| + blink::WebCredentialManagerClient::NotificationCallbacks* callbacks);
|
|
|
| -CredentialManagerClient::CredentialManagerClient(
|
| - content::RenderView* render_view)
|
| - : content::RenderViewObserver(render_view) {
|
| - render_view->GetWebView()->setCredentialManagerClient(this);
|
| + ~NotificationCallbacksWrapper();
|
| +
|
| + void NotifySuccess();
|
| +
|
| + private:
|
| + std::unique_ptr<blink::WebCredentialManagerClient::NotificationCallbacks>
|
| + callbacks_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(NotificationCallbacksWrapper);
|
| +};
|
| +
|
| +NotificationCallbacksWrapper::NotificationCallbacksWrapper(
|
| + blink::WebCredentialManagerClient::NotificationCallbacks* callbacks)
|
| + : callbacks_(callbacks) {}
|
| +
|
| +NotificationCallbacksWrapper::~NotificationCallbacksWrapper() {
|
| + if (callbacks_)
|
| + callbacks_->onError(blink::WebCredentialManagerUnknownError);
|
| }
|
|
|
| -CredentialManagerClient::~CredentialManagerClient() {
|
| - ClearCallbacksMapWithErrors(&store_callbacks_);
|
| - ClearCallbacksMapWithErrors(&require_user_mediation_callbacks_);
|
| - ClearCallbacksMapWithErrors(&get_callbacks_);
|
| +void NotificationCallbacksWrapper::NotifySuccess() {
|
| + // Call onSuccess() and reset callbacks to avoid calling onError() in
|
| + // destructor.
|
| + if (callbacks_) {
|
| + callbacks_->onSuccess();
|
| + callbacks_.reset();
|
| + }
|
| }
|
|
|
| -// -----------------------------------------------------------------------------
|
| -// Handle messages from the browser.
|
| -
|
| -bool CredentialManagerClient::OnMessageReceived(const IPC::Message& message) {
|
| - bool handled = true;
|
| - IPC_BEGIN_MESSAGE_MAP(CredentialManagerClient, message)
|
| - IPC_MESSAGE_HANDLER(CredentialManagerMsg_AcknowledgeStore,
|
| - OnAcknowledgeStore)
|
| - IPC_MESSAGE_HANDLER(CredentialManagerMsg_AcknowledgeRequireUserMediation,
|
| - OnAcknowledgeRequireUserMediation)
|
| - IPC_MESSAGE_HANDLER(CredentialManagerMsg_SendCredential, OnSendCredential)
|
| - IPC_MESSAGE_HANDLER(CredentialManagerMsg_RejectCredentialRequest,
|
| - OnRejectCredentialRequest)
|
| - IPC_MESSAGE_UNHANDLED(handled = false)
|
| - IPC_END_MESSAGE_MAP()
|
| - return handled;
|
| +// Takes ownership of blink::WebCredentialManagerClient::RequestCallbacks
|
| +// pointer. When the wrapper is destroied, if |callbacks| is still alive
|
| +// its onError() will get called.
|
| +class RequestCallbacksWrapper {
|
| + public:
|
| + explicit RequestCallbacksWrapper(
|
| + blink::WebCredentialManagerClient::RequestCallbacks* callbacks);
|
| +
|
| + ~RequestCallbacksWrapper();
|
| +
|
| + void NotifySuccess(mojom::CredentialInfoPtr info);
|
| +
|
| + void NotifyError(mojom::CredentialManagerError error);
|
| +
|
| + private:
|
| + std::unique_ptr<blink::WebCredentialManagerClient::RequestCallbacks>
|
| + callbacks_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(RequestCallbacksWrapper);
|
| +};
|
| +
|
| +RequestCallbacksWrapper::RequestCallbacksWrapper(
|
| + blink::WebCredentialManagerClient::RequestCallbacks* callbacks)
|
| + : callbacks_(callbacks) {}
|
| +
|
| +RequestCallbacksWrapper::~RequestCallbacksWrapper() {
|
| + if (callbacks_)
|
| + callbacks_->onError(blink::WebCredentialManagerUnknownError);
|
| }
|
|
|
| -void CredentialManagerClient::OnAcknowledgeStore(int request_id) {
|
| - RespondToNotificationCallback(request_id, &store_callbacks_);
|
| +void RequestCallbacksWrapper::NotifySuccess(mojom::CredentialInfoPtr info) {
|
| + // Call onSuccess() and reset callbacks to avoid calling onError() in
|
| + // destructor.
|
| + if (callbacks_) {
|
| + std::unique_ptr<blink::WebCredential> credential =
|
| + info.To<std::unique_ptr<blink::WebCredential>>();
|
| + callbacks_->onSuccess(adoptWebPtr(credential.release()));
|
| + callbacks_.reset();
|
| + }
|
| }
|
|
|
| -void CredentialManagerClient::OnAcknowledgeRequireUserMediation(
|
| - int request_id) {
|
| - RespondToNotificationCallback(request_id, &require_user_mediation_callbacks_);
|
| +void RequestCallbacksWrapper::NotifyError(mojom::CredentialManagerError error) {
|
| + if (callbacks_) {
|
| + callbacks_->onError(GetWebCredentialManagerErrorFromMojo(error));
|
| + callbacks_.reset();
|
| + }
|
| }
|
|
|
| -void CredentialManagerClient::OnSendCredential(int request_id,
|
| - const CredentialInfo& info) {
|
| - RequestCallbacks* callbacks = get_callbacks_.Lookup(request_id);
|
| - DCHECK(callbacks);
|
| - std::unique_ptr<blink::WebCredential> credential = nullptr;
|
| - switch (info.type) {
|
| - case CredentialType::CREDENTIAL_TYPE_FEDERATED:
|
| - credential.reset(new blink::WebFederatedCredential(
|
| - info.id, info.federation, info.name, info.icon));
|
| - break;
|
| - case CredentialType::CREDENTIAL_TYPE_PASSWORD:
|
| - credential.reset(new blink::WebPasswordCredential(
|
| - info.id, info.password, info.name, info.icon));
|
| - break;
|
| - case CredentialType::CREDENTIAL_TYPE_EMPTY:
|
| - // Intentionally empty; we'll send nullptr to the onSuccess call below.
|
| - break;
|
| +void RespondToNotificationCallback(
|
| + NotificationCallbacksWrapper* callbacks_wrapper) {
|
| + callbacks_wrapper->NotifySuccess();
|
| +}
|
| +
|
| +void RespondToRequestCallback(RequestCallbacksWrapper* callbacks_wrapper,
|
| + mojom::CredentialManagerError error,
|
| + mojom::CredentialInfoPtr info) {
|
| + if (error == mojom::CredentialManagerError::SUCCESS) {
|
| + DCHECK(!info.is_null());
|
| + callbacks_wrapper->NotifySuccess(std::move(info));
|
| + } else {
|
| + DCHECK(info.is_null());
|
| + callbacks_wrapper->NotifyError(error);
|
| }
|
| - callbacks->onSuccess(adoptWebPtr(credential.release()));
|
| - get_callbacks_.Remove(request_id);
|
| }
|
|
|
| -void CredentialManagerClient::OnRejectCredentialRequest(
|
| - int request_id,
|
| - blink::WebCredentialManagerError error) {
|
| - RequestCallbacks* callbacks = get_callbacks_.Lookup(request_id);
|
| - DCHECK(callbacks);
|
| - callbacks->onError(error);
|
| - get_callbacks_.Remove(request_id);
|
| +} // namespace
|
| +
|
| +CredentialManagerClient::CredentialManagerClient(
|
| + content::RenderView* render_view)
|
| + : content::RenderViewObserver(render_view) {
|
| + render_view->GetWebView()->setCredentialManagerClient(this);
|
| }
|
|
|
| +CredentialManagerClient::~CredentialManagerClient() {}
|
| +
|
| // -----------------------------------------------------------------------------
|
| -// Dispatch messages from the renderer to the browser.
|
| +// Access mojo CredentialManagerService.
|
|
|
| void CredentialManagerClient::dispatchStore(
|
| const blink::WebCredential& credential,
|
| blink::WebCredentialManagerClient::NotificationCallbacks* callbacks) {
|
| - int request_id = store_callbacks_.Add(callbacks);
|
| - CredentialInfo info(WebCredentialToCredentialInfo(credential));
|
| - Send(new CredentialManagerHostMsg_Store(routing_id(), request_id, info));
|
| + DCHECK(callbacks);
|
| + ConnectToMojoCMIfNeeded();
|
| +
|
| + mojom::CredentialInfoPtr info = mojom::CredentialInfo::From(credential);
|
| + mojo_cm_service_->Store(
|
| + std::move(info),
|
| + base::Bind(&RespondToNotificationCallback,
|
| + base::Owned(new NotificationCallbacksWrapper(callbacks))));
|
| }
|
|
|
| void CredentialManagerClient::dispatchRequireUserMediation(
|
| - NotificationCallbacks* callbacks) {
|
| - int request_id = require_user_mediation_callbacks_.Add(callbacks);
|
| - Send(new CredentialManagerHostMsg_RequireUserMediation(routing_id(),
|
| - request_id));
|
| + blink::WebCredentialManagerClient::NotificationCallbacks* callbacks) {
|
| + DCHECK(callbacks);
|
| + ConnectToMojoCMIfNeeded();
|
| +
|
| + mojo_cm_service_->RequireUserMediation(
|
| + base::Bind(&RespondToNotificationCallback,
|
| + base::Owned(new NotificationCallbacksWrapper(callbacks))));
|
| }
|
|
|
| void CredentialManagerClient::dispatchGet(
|
| @@ -126,23 +191,27 @@ void CredentialManagerClient::dispatchGet(
|
| bool include_passwords,
|
| const blink::WebVector<blink::WebURL>& federations,
|
| RequestCallbacks* callbacks) {
|
| - int request_id = get_callbacks_.Add(callbacks);
|
| + DCHECK(callbacks);
|
| + ConnectToMojoCMIfNeeded();
|
| +
|
| std::vector<GURL> federation_vector;
|
| for (size_t i = 0; i < std::min(federations.size(), kMaxFederations); ++i)
|
| federation_vector.push_back(federations[i]);
|
| - Send(new CredentialManagerHostMsg_RequestCredential(
|
| - routing_id(), request_id, zero_click_only, include_passwords,
|
| - federation_vector));
|
| +
|
| + mojo_cm_service_->Get(
|
| + zero_click_only, include_passwords,
|
| + mojo::Array<mojo::String>::From(federation_vector),
|
| + base::Bind(&RespondToRequestCallback,
|
| + base::Owned(new RequestCallbacksWrapper(callbacks))));
|
| }
|
|
|
| -void CredentialManagerClient::RespondToNotificationCallback(
|
| - int request_id,
|
| - CredentialManagerClient::NotificationCallbacksMap* map) {
|
| - blink::WebCredentialManagerClient::NotificationCallbacks* callbacks =
|
| - map->Lookup(request_id);
|
| - DCHECK(callbacks);
|
| - callbacks->onSuccess();
|
| - map->Remove(request_id);
|
| +void CredentialManagerClient::ConnectToMojoCMIfNeeded() {
|
| + if (mojo_cm_service_)
|
| + return;
|
| +
|
| + content::RenderFrame* main_frame = render_view()->GetMainRenderFrame();
|
| + main_frame->GetServiceRegistry()->ConnectToRemoteService(
|
| + mojo::GetProxy(&mojo_cm_service_));
|
| }
|
|
|
| } // namespace password_manager
|
|
|