Chromium Code Reviews| 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 749b429e53015d297953ea39c88bbca22b417a01..496ef78158864172708b28b19d93d2c313d5c982 100644 |
| --- a/components/password_manager/content/renderer/credential_manager_client.cc |
| +++ b/components/password_manager/content/renderer/credential_manager_client.cc |
| @@ -6,10 +6,15 @@ |
| #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 "base/memory/scoped_ptr.h" |
| +#include "components/password_manager/content/public/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 +26,167 @@ 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: |
| + scoped_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: |
| + scoped_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 RequestCallbacksWrapper::NotifySuccess(mojom::CredentialInfoPtr info) { |
| + // Call onSuccess() and reset callbacks to avoid calling onError() in |
| + // destructor. |
| + if (callbacks_) { |
| + scoped_ptr<blink::WebCredential> credential = |
| + info.To<scoped_ptr<blink::WebCredential>>(); |
| + callbacks_->onSuccess(adoptWebPtr(credential.release())); |
| + callbacks_.reset(); |
| + } |
| } |
| -void CredentialManagerClient::OnAcknowledgeStore(int request_id) { |
| - RespondToNotificationCallback(request_id, &store_callbacks_); |
| +void RequestCallbacksWrapper::NotifyError(mojom::CredentialManagerError error) { |
| + if (callbacks_) { |
| + callbacks_->onError(GetWebCredentialManagerErrorFromMojo(error)); |
| + callbacks_.reset(); |
| + } |
| } |
| -void CredentialManagerClient::OnAcknowledgeRequireUserMediation( |
| - int request_id) { |
| - RespondToNotificationCallback(request_id, &require_user_mediation_callbacks_); |
| +void RespondToNotificationCallback( |
| + scoped_ptr<NotificationCallbacksWrapper> callbacks_wrapper) { |
| + callbacks_wrapper->NotifySuccess(); |
| } |
| -void CredentialManagerClient::OnSendCredential(int request_id, |
| - const CredentialInfo& info) { |
| - RequestCallbacks* callbacks = get_callbacks_.Lookup(request_id); |
| - DCHECK(callbacks); |
| - scoped_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 RespondToRequestCallback( |
| + scoped_ptr<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::Passed(make_scoped_ptr( |
|
Anand Mistry (off Chromium)
2016/03/18 01:24:13
base::Owned does what you need.
leonhsl(Using Gerrit)
2016/03/18 10:02:16
Done.
|
| + 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::Passed( |
| + make_scoped_ptr(new NotificationCallbacksWrapper(callbacks))))); |
| } |
| void CredentialManagerClient::dispatchGet( |
| @@ -126,23 +194,29 @@ 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::Passed( |
| + make_scoped_ptr(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; |
| + |
| + // Connect via the service registry of the main render frame. |
| + content::RenderFrame* main_frame = render_view()->GetMainRenderFrame(); |
| + main_frame->GetServiceRegistry()->ConnectToRemoteService( |
| + mojo::GetProxy(&mojo_cm_service_)); |
| } |
| } // namespace password_manager |