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..61e587f91538edb1f94bbbb4bc22e6c7a206065b 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,144 @@ 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) { |
+ DCHECK(error != mojom::CredentialManagerError::SUCCESS); |
vabr (Chromium)
2016/03/09 16:26:30
nit: DCHECK_NE(mojom::CredentialManagerError::SUCC
leonhsl(Using Gerrit)
2016/03/10 06:42:42
Done. Moved the check into the switch sentence bel
|
+ 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; |
+ default: |
vabr (Chromium)
2016/03/09 16:26:29
Please drop the default clause if possible to have
leonhsl(Using Gerrit)
2016/03/10 06:42:42
Done.
|
+ NOTREACHED(); |
} |
+ |
+ return blink::WebCredentialManagerError::WebCredentialManagerUnknownError; |
} |
-} // namespace |
+// Takes ownership of blink::WebCredentialManagerClient::NotificationCallbacks |
+// pointer. When the wrapper is destroied, if callbacks is still alive |
vabr (Chromium)
2016/03/09 16:26:29
typo: destroyed
Also below.
vabr (Chromium)
2016/03/09 16:26:30
nit: Add || around "callbacks" to signal you mean
leonhsl(Using Gerrit)
2016/03/10 06:42:42
Done.
leonhsl(Using Gerrit)
2016/03/10 06:42:42
Done.
|
+// its onError() will get called. |
+class NotificationCallbacksWrapper { |
+ public: |
+ explicit NotificationCallbacksWrapper( |
+ blink::WebCredentialManagerClient::NotificationCallbacks* callbacks) |
+ : callbacks_(callbacks){}; |
vabr (Chromium)
2016/03/09 16:26:29
nit: There should be a space between {}, did you r
leonhsl(Using Gerrit)
2016/03/10 06:42:42
Done. Yes I did run 'git cl format', eh, but here
|
+ ~NotificationCallbacksWrapper() { |
vabr (Chromium)
2016/03/09 16:26:29
Please do not inline methods, the style forbids it
vabr (Chromium)
2016/03/09 16:26:30
nit: blank line above
leonhsl(Using Gerrit)
2016/03/10 06:42:42
Done.
leonhsl(Using Gerrit)
2016/03/10 06:42:42
Done.
|
+ // Force to call onError() for hanged callbacks. |
vabr (Chromium)
2016/03/09 16:26:29
nit: Just drop the comment, the code is clear with
leonhsl(Using Gerrit)
2016/03/10 06:42:42
Done.
|
+ if (callbacks_) |
+ callbacks_->onError(blink::WebCredentialManagerUnknownError); |
+ } |
-CredentialManagerClient::CredentialManagerClient( |
- content::RenderView* render_view) |
- : content::RenderViewObserver(render_view) { |
- render_view->GetWebView()->setCredentialManagerClient(this); |
-} |
+ void NotifySuccess() { |
+ // Call onSuccess() and reset callbacks to avoid calling onError() in |
+ // destructor. |
+ if (callbacks_) { |
+ callbacks_->onSuccess(); |
+ callbacks_.reset(); |
+ } |
+ } |
-CredentialManagerClient::~CredentialManagerClient() { |
- ClearCallbacksMapWithErrors(&store_callbacks_); |
- ClearCallbacksMapWithErrors(&require_user_mediation_callbacks_); |
- ClearCallbacksMapWithErrors(&get_callbacks_); |
-} |
+ private: |
+ scoped_ptr<blink::WebCredentialManagerClient::NotificationCallbacks> |
+ callbacks_; |
+}; |
vabr (Chromium)
2016/03/09 16:26:30
Did you consider DISALLOW_COPY_AND_ASSIGN for the
leonhsl(Using Gerrit)
2016/03/10 06:42:42
Done. Will keep in mind!
|
+ |
+// 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) |
+ : callbacks_(callbacks) {} |
+ ~RequestCallbacksWrapper() { |
vabr (Chromium)
2016/03/09 16:26:30
nit: blank line above
leonhsl(Using Gerrit)
2016/03/10 06:42:42
Done.
|
+ // Force to call onError() for hanged callbacks. |
vabr (Chromium)
2016/03/09 16:26:30
nit: Drop the comment.
leonhsl(Using Gerrit)
2016/03/10 06:42:42
Done.
|
+ if (callbacks_) |
+ callbacks_->onError(blink::WebCredentialManagerUnknownError); |
+ } |
-// ----------------------------------------------------------------------------- |
-// 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; |
-} |
+ void NotifySuccess(mojom::CredentialInfoPtr info) { |
+ // Call onSuccess() and reset callbacks to avoid calling onError() in |
+ // destructor. |
+ if (callbacks_) { |
+ BlinkWebCredentialPtr credential = info.To<BlinkWebCredentialPtr>(); |
+ callbacks_->onSuccess(adoptWebPtr(credential.release())); |
+ callbacks_.reset(); |
+ } |
+ } |
+ void NotifyError(mojom::CredentialManagerError error) { |
+ if (callbacks_) { |
+ callbacks_->onError(GetWebCredentialManagerErrorFromMojo(error)); |
+ callbacks_.reset(); |
+ } |
+ } |
-void CredentialManagerClient::OnAcknowledgeStore(int request_id) { |
- RespondToNotificationCallback(request_id, &store_callbacks_); |
-} |
+ private: |
+ scoped_ptr<blink::WebCredentialManagerClient::RequestCallbacks> callbacks_; |
+}; |
-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( |
+ 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 +171,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 |