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

Side by Side 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 Created 4 years, 2 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/certificate_provider/pin_dialog_manager.h"
6
7 #include "ash/shell.h"
8 #include "base/strings/string16.h"
9 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
10 #include "chrome/browser/profiles/profile_manager.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/browser_finder.h"
13 #include "chrome/browser/ui/browser_window.h"
14 #include "ui/aura/window.h"
15 #include "ui/gfx/native_widget_types.h"
16 #include "ui/views/window/dialog_client_view.h"
17 #include "ui/views/window/dialog_delegate.h"
18
19 namespace {
20
21 gfx::NativeWindow GetBrowserParentWindow() {
22 if (chromeos::LoginDisplayHost::default_host()) {
23 return chromeos::LoginDisplayHost::default_host()->GetNativeWindow();
24 }
25
26 Browser* browser =
27 chrome::FindTabbedBrowser(ProfileManager::GetPrimaryUserProfile(), true);
Devlin 2016/10/20 21:20:44 GetPrimaryUserProfile sounds like it might not be
igorcov 2016/10/25 16:38:35 The code is the same as the one used in wifi dialo
28 if (browser) {
29 return browser->window()->GetNativeWindow();
30 }
31
32 return nullptr;
33 }
34
35 } // namespace
36
37 namespace chromeos {
38
39 // Define timeout for issued sign_request_id.
40 const int SIGN_REQUEST_ID_TIMEOUT_MINS = 10;
41
42 PinDialogManager::PinDialogManager() : weak_factory_(this) {}
43
44 PinDialogManager::~PinDialogManager() {
45 // Close the active dialog if present to avoid leaking callbacks.
46 if (active_pin_dialog_) {
47 CloseDialog(active_dialog_extension_id_);
48 }
49 }
50
51 void PinDialogManager::AddSignRequestId(const std::string& extension_id,
52 int sign_request_id) {
53 ExtensionNameRequestIdPair key(extension_id, sign_request_id);
54 // Cache the ID with current timestamp.
55 base::Time current_time = base::Time::Now();
56 sign_request_times_[key] = current_time;
57 }
58
59 PinDialogManager::RequestPinResponse PinDialogManager::ShowPinDialog(
60 const std::string& extension_id,
61 const std::string& extension_name,
62 int sign_request_id,
63 RequestPinView::RequestPinCodeType code_type,
64 RequestPinView::RequestPinErrorType error_type,
65 int attempts_left,
66 const RequestPinView::RequestPinCallback& callback) {
67 bool accept_input = (attempts_left != 0);
68 // If active dialog exists already, we need to make sure it belongs to the
69 // same extension and the user submitted some input.
70 if (active_pin_dialog_ != nullptr) {
71 DCHECK(!active_dialog_extension_id_.empty());
72 if (extension_id != active_dialog_extension_id_) {
73 return OTHER_FLOW_IN_PROGRESS;
74 }
75
76 // Extension requests a PIN without having received any input from its
77 // previous request. Reject the new request.
78 if (!active_pin_dialog_->IsLocked()) {
79 return DIALOG_DISPLAYED_ALREADY;
80 }
81
82 // Set the new callback to be used by the view.
83 active_pin_dialog_->SetCallback(callback);
84 active_pin_dialog_->SetDialogParameters(code_type, error_type,
85 attempts_left, accept_input);
86 active_pin_dialog_->GetDialogClientView()->UpdateDialogButtons();
87 return SUCCESS;
88 }
89
90 // Check the validity of sign_request_id
91 ExtensionNameRequestIdPair key(extension_id, sign_request_id);
92 if (sign_request_times_.find(key) == sign_request_times_.end()) {
93 return INVALID_ID;
94 }
95
96 base::Time current_time = base::Time::Now();
97 if ((current_time - sign_request_times_[key]).InMinutes() >
98 SIGN_REQUEST_ID_TIMEOUT_MINS) {
99 return INVALID_ID;
100 }
101
102 active_dialog_extension_id_ = extension_id;
103 active_pin_dialog_ = new RequestPinView(extension_name, code_type,
104 attempts_left, callback, this);
105
106 gfx::NativeWindow parent = GetBrowserParentWindow();
107 gfx::NativeWindow context =
108 parent ? nullptr : ash::Shell::GetPrimaryRootWindow();
109 active_window_ = views::DialogDelegate::CreateDialogWidget(active_pin_dialog_,
110 context, parent);
111 active_window_->Show();
112
113 return SUCCESS;
114 }
115
116 void PinDialogManager::OnPinDialogInput() {
117 last_response_closed_[active_dialog_extension_id_] = false;
118 }
119
120 void PinDialogManager::OnPinDialogClosed() {
121 last_response_closed_[active_dialog_extension_id_] = true;
122 // |active_pin_dialog_| is managed by |active_window_|. This local copy of
123 // the pointer is reset here to allow a new dialog to be created when a new
124 // request comes.
125 active_pin_dialog_ = nullptr;
126 }
127
128 bool PinDialogManager::UpdatePinDialog(
129 const std::string& extension_id,
130 RequestPinView::RequestPinErrorType error_type,
131 bool accept_input,
132 const RequestPinView::RequestPinCallback& callback) {
133 if (active_pin_dialog_ == nullptr ||
134 extension_id != active_dialog_extension_id_ ||
135 !active_pin_dialog_->IsLocked()) {
136 return false;
137 }
138
139 active_pin_dialog_->SetCallback(callback);
140 active_pin_dialog_->SetDialogParameters(
141 RequestPinView::RequestPinCodeType::UNCHANGED, error_type, -1,
142 accept_input);
143 active_pin_dialog_->GetDialogClientView()->UpdateDialogButtons();
144 return true;
145 }
146
147 bool PinDialogManager::LastPinDialogClosed(const std::string& extension_id) {
148 return last_response_closed_[extension_id];
149 }
150
151 bool PinDialogManager::CloseDialog(const std::string& extension_id) {
152 if (extension_id != active_dialog_extension_id_ ||
153 active_pin_dialog_ == nullptr) {
154 LOG(ERROR) << "StopPinRequest called by unexpected extension: "
155 << extension_id;
156 return false;
157 }
158
159 // Close the window. |active_pin_dialog_| gets deleted inside Close().
160 active_window_->Close();
161 active_pin_dialog_ = nullptr;
162
163 return true;
164 }
165
166 void PinDialogManager::ExtensionUnloaded(const std::string& extension_id) {
167 if (active_pin_dialog_ && active_dialog_extension_id_ == extension_id) {
168 CloseDialog(extension_id);
169 }
170
171 last_response_closed_[extension_id] = false;
172
173 for (auto it = sign_request_times_.cbegin();
174 it != sign_request_times_.cend();) {
175 if (it->first.first == extension_id) {
176 sign_request_times_.erase(it++);
177 } else {
178 ++it;
179 }
180 }
181 }
182
183 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698