Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1056)

Unified Diff: chrome/browser/chromeos/certificate_provider/pin_dialog_manager.cc

Issue 2094333002: Implementation for chrome.certificateProvider.requestPin/stopPinRequest (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed review comments and merged Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/chromeos/certificate_provider/pin_dialog_manager.cc
diff --git a/chrome/browser/chromeos/certificate_provider/pin_dialog_manager.cc b/chrome/browser/chromeos/certificate_provider/pin_dialog_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ff60f8caf4f9ca73fd4a0e9e189388b0e2b87b84
--- /dev/null
+++ b/chrome/browser/chromeos/certificate_provider/pin_dialog_manager.cc
@@ -0,0 +1,180 @@
+// Copyright 2016 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 "chrome/browser/chromeos/certificate_provider/pin_dialog_manager.h"
+
+#include "ash/shell.h"
+#include "base/strings/string16.h"
+#include "chrome/browser/chromeos/login/ui/login_display_host.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "ui/views/window/dialog_client_view.h"
+
+gfx::NativeWindow GetBrowserParentWindow() {
emaxx 2016/09/19 14:01:43 nit: #include "ui/gfx/native_widget_types.h"
emaxx 2016/09/19 14:01:43 nit: Move the function into an anonymous namespace
igorcov 2016/09/19 15:42:36 Done.
igorcov 2016/09/19 15:42:36 Done.
+ if (chromeos::LoginDisplayHost::default_host()) {
+ return chromeos::LoginDisplayHost::default_host()->GetNativeWindow();
+ } else {
emaxx 2016/09/19 14:01:43 nit: Reformat the code to remove the "else" block.
igorcov 2016/09/19 15:42:36 Done.
+ Browser* browser = chrome::FindTabbedBrowser(
emaxx 2016/09/19 14:01:43 nit: #include "chrome/browser/ui/browser.h"
igorcov 2016/09/19 15:42:36 Done.
+ ProfileManager::GetPrimaryUserProfile(), true);
+ if (browser) {
+ return browser->window()->GetNativeWindow();
+ }
+ }
+
+ return nullptr;
+}
+
+namespace chromeos {
+
+// Define timeout for issued sign_request_id.
+const int SIGN_REQUEST_ID_TIMEOUT_MINS = 10;
+
+PinDialogManager::PinDialogManager() : weak_factory_(this) {}
+
+PinDialogManager::~PinDialogManager() {
+ // Close the active dialog if present to avoid leaking callbacks.
+ if (active_pin_dialog_) {
+ CloseDialog(active_dialog_extension_id_);
+ }
+}
+
+bool PinDialogManager::AddSignRequestId(const std::string& extension_id,
+ int sign_request_id) {
+ ExtensionNameRequestIdPair key(extension_id, sign_request_id);
+ if (sign_request_times_.find(key) != sign_request_times_.end()) {
+ return false;
+ }
+ // Cache the ID with current timestamp.
+ base::Time current_time = base::Time::Now();
+ sign_request_times_[key] = current_time;
+
+ return true;
+}
+
+PinDialogManager::RequestPinResponse PinDialogManager::ShowPinDialog(
+ const std::string& extension_id,
+ const std::string& extension_name,
+ int sign_request_id,
+ RequestPinView::RequestPinCodeType code_type,
+ RequestPinView::RequestPinErrorType error_type,
+ int attempts_left,
+ const RequestPinView::RequestPinCallback& callback) {
+ bool accept_input = (attempts_left != 0);
+ // If active dialog exists already, we need to make sure it belongs to the
+ // same extension and the user submitted some input.
+ if (active_pin_dialog_ != nullptr) {
+ DCHECK(!active_dialog_extension_id_.empty());
+ if (extension_id != active_dialog_extension_id_) {
+ return RequestPinResponse::OTHER_FLOW_IN_PROGRESS;
emaxx 2016/09/19 14:01:43 nit: I don't known whether you use this "RequestPi
igorcov 2016/09/19 15:42:36 Done.
+ }
+
+ // Extension requests a PIN without having received any input from its
+ // previous request. Reject the new request.
+ if (!active_pin_dialog_->IsLocked()) {
+ return RequestPinResponse::DIALOG_DISPLAYED_ALREADY;
+ }
+
+ // Set the new callback to be used by the view.
+ active_pin_dialog_->SetCallback(callback);
+ active_pin_dialog_->SetDialogParameters(code_type, error_type,
+ attempts_left, accept_input);
+ active_pin_dialog_->GetDialogClientView()->UpdateDialogButtons();
+ return RequestPinResponse::SUCCESS;
+ }
+
+ // Check the validity of sign_request_id
+ ExtensionNameRequestIdPair key(extension_id, sign_request_id);
+ if (sign_request_times_.find(key) == sign_request_times_.end()) {
+ return RequestPinResponse::INVALID_ID;
+ }
+
+ base::Time current_time = base::Time::Now();
+ if ((current_time - sign_request_times_[key]).InMinutes() >
+ SIGN_REQUEST_ID_TIMEOUT_MINS) {
+ return RequestPinResponse::INVALID_ID;
+ }
+
+ active_dialog_extension_id_ = extension_id;
+ active_pin_dialog_ = new chromeos::RequestPinView(
emaxx 2016/09/19 14:01:43 nit: "chromeos::" is not required here.
igorcov 2016/09/19 15:42:36 Done.
+ extension_name, code_type, attempts_left, callback, this);
+
+ gfx::NativeWindow parent = GetBrowserParentWindow();
+ gfx::NativeWindow context =
+ parent ? nullptr : ash::Shell::GetPrimaryRootWindow();
emaxx 2016/09/19 14:01:43 nit: #include "ui/aura/window.h"
igorcov 2016/09/19 15:42:36 Done.
+ active_window_ = views::DialogDelegate::CreateDialogWidget(active_pin_dialog_,
emaxx 2016/09/19 14:01:43 nit: #include "ui/views/window/dialog_delegate.h"
igorcov 2016/09/19 15:42:36 Done.
+ context, parent);
+ active_window_->Show();
+
+ return RequestPinResponse::SUCCESS;
+}
+
+void PinDialogManager::OnPinDialogInput() {
+ last_response_closed_[active_dialog_extension_id_] = false;
+}
+
+void PinDialogManager::OnPinDialogClosed() {
+ last_response_closed_[active_dialog_extension_id_] = true;
+ // |active_pin_dialog_| is managed by |active_window_|. This local copy of
+ // the pointer is reset here to allow a new dialog to be created when a new
+ // request comes.
+ active_pin_dialog_ = nullptr;
+}
+
+bool PinDialogManager::UpdatePinDialog(
+ const std::string& extension_id,
+ RequestPinView::RequestPinErrorType error_type,
+ bool accept_input,
+ const RequestPinView::RequestPinCallback& callback) {
+ if (active_pin_dialog_ == nullptr ||
+ extension_id != active_dialog_extension_id_ ||
+ !active_pin_dialog_->IsLocked()) {
+ return false;
+ }
+
+ active_pin_dialog_->SetCallback(callback);
+ active_pin_dialog_->SetDialogParameters(
+ RequestPinView::RequestPinCodeType::UNCHANGED, error_type, -1,
+ accept_input);
+ active_pin_dialog_->GetDialogClientView()->UpdateDialogButtons();
+ return true;
+}
+
+bool PinDialogManager::LastPinDialogClosed(const std::string& extension_id) {
+ return last_response_closed_[extension_id];
+}
+
+bool PinDialogManager::CloseDialog(const std::string& extension_id) {
+ if (extension_id != active_dialog_extension_id_ ||
+ active_pin_dialog_ == nullptr) {
+ LOG(ERROR) << "StopPinRequest called by unexpected extension: "
+ << extension_id;
+ return false;
+ }
+
+ // Close the window. |active_pin_dialog_| gets deleted inside Close().
+ active_window_->Close();
+ active_pin_dialog_ = nullptr;
+
+ return true;
+}
+
+void PinDialogManager::ExtensionUnloaded(const std::string& extension_id) {
+ if (active_pin_dialog_ && active_dialog_extension_id_ == extension_id) {
+ CloseDialog(extension_id);
+ }
+
+ last_response_closed_[extension_id] = false;
+
+ for (auto it = sign_request_times_.cbegin();
+ it != sign_request_times_.cend();) {
+ if (it->first.first == extension_id) {
+ sign_request_times_.erase(it++);
+ } else {
+ ++it;
+ }
+ }
+}
+
+} // namespace chromeos

Powered by Google App Engine
This is Rietveld 408576698