1 // Copyright 2014 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.
5 #include "chrome/browser/chromeos/login/screens/controller_pairing_screen.h"
7 #include "base/command_line.h"
8 #include "base/values.h"
9 #include "chrome/browser/chromeos/login/wizard_controller.h"
10 #include "google_apis/gaia/gaia_auth_util.h"
12 using namespace chromeos::controller_pairing
;
13 using namespace pairing_chromeos
;
17 ControllerPairingScreen::ControllerPairingScreen(
18 BaseScreenDelegate
* base_screen_delegate
,
20 ControllerPairingScreenActor
* actor
,
21 ControllerPairingController
* shark_controller
)
22 : BaseScreen(base_screen_delegate
),
25 shark_controller_(shark_controller
),
26 current_stage_(ControllerPairingController::STAGE_NONE
),
27 device_preselected_(false) {
28 actor_
->SetDelegate(this);
29 shark_controller_
->AddObserver(this);
32 ControllerPairingScreen::~ControllerPairingScreen() {
34 actor_
->SetDelegate(NULL
);
35 shark_controller_
->RemoveObserver(this);
38 void ControllerPairingScreen::CommitContextChanges() {
39 if (!context_
.HasChanges())
41 base::DictionaryValue diff
;
42 context_
.GetChangesAndReset(&diff
);
44 actor_
->OnContextChanged(diff
);
47 bool ControllerPairingScreen::ExpectStageIs(Stage stage
) const {
48 DCHECK(stage
== current_stage_
);
49 if (current_stage_
!= stage
)
50 LOG(ERROR
) << "Incorrect stage. Expected: " << stage
51 << ", current stage: " << current_stage_
;
52 return stage
== current_stage_
;
55 void ControllerPairingScreen::PrepareToShow() {
58 void ControllerPairingScreen::Show() {
61 shark_controller_
->StartPairing();
64 void ControllerPairingScreen::Hide() {
69 std::string
ControllerPairingScreen::GetName() const {
70 return WizardController::kControllerPairingScreenName
;
73 void ControllerPairingScreen::PairingStageChanged(Stage new_stage
) {
74 DCHECK(new_stage
!= current_stage_
);
76 std::string desired_page
;
78 case ControllerPairingController::STAGE_DEVICES_DISCOVERY
: {
79 desired_page
= kPageDevicesDiscovery
;
80 context_
.SetStringList(kContextKeyDevices
, ::login::StringList());
81 context_
.SetString(kContextKeySelectedDevice
, std::string());
82 device_preselected_
= false;
85 case ControllerPairingController::STAGE_DEVICE_NOT_FOUND
: {
86 desired_page
= kPageDeviceNotFound
;
89 case ControllerPairingController::STAGE_ESTABLISHING_CONNECTION
: {
90 desired_page
= kPageEstablishingConnection
;
93 case ControllerPairingController::STAGE_ESTABLISHING_CONNECTION_ERROR
: {
94 desired_page
= kPageEstablishingConnectionError
;
97 case ControllerPairingController::STAGE_WAITING_FOR_CODE_CONFIRMATION
: {
98 desired_page
= kPageCodeConfirmation
;
99 context_
.SetString(kContextKeyConfirmationCode
,
100 shark_controller_
->GetConfirmationCode());
103 case ControllerPairingController::STAGE_PAIRING_DONE
: {
105 delegate_
->SetHostConfiguration();
108 case ControllerPairingController::STAGE_HOST_UPDATE_IN_PROGRESS
: {
109 desired_page
= kPageHostUpdate
;
112 case ControllerPairingController::STAGE_HOST_CONNECTION_LOST
: {
113 desired_page
= kPageHostConnectionLost
;
116 case ControllerPairingController::STAGE_WAITING_FOR_CREDENTIALS
: {
117 shark_controller_
->RemoveObserver(this);
118 Finish(WizardController::CONTROLLER_PAIRING_FINISHED
);
119 desired_page
= kPageEnrollmentIntroduction
;
122 case ControllerPairingController::STAGE_INITIALIZATION_ERROR
: {
123 // TODO(achuith, dzhioev, zork): Handle this better.
124 LOG(WARNING
) << "Bluetooth initialization error";
130 current_stage_
= new_stage
;
131 context_
.SetString(kContextKeyPage
, desired_page
);
132 context_
.SetBoolean(kContextKeyControlsDisabled
, false);
133 CommitContextChanges();
134 VLOG(1) << "PairingStageChanged " << desired_page
135 << ", current stage " << current_stage_
;
138 void ControllerPairingScreen::DiscoveredDevicesListChanged() {
139 if (!ExpectStageIs(ControllerPairingController::STAGE_DEVICES_DISCOVERY
))
141 ControllerPairingController::DeviceIdList devices
=
142 shark_controller_
->GetDiscoveredDevices();
143 std::sort(devices
.begin(), devices
.end());
144 context_
.SetStringList(kContextKeyDevices
, devices
);
147 devices
.empty() ? kPageDevicesDiscovery
: kPageDeviceSelect
);
148 std::string selected_device
= context_
.GetString(kContextKeySelectedDevice
);
149 if (std::find(devices
.begin(), devices
.end(), selected_device
) ==
151 selected_device
.clear();
153 if (devices
.empty()) {
154 device_preselected_
= false;
155 } else if (!device_preselected_
) {
156 selected_device
= devices
.front();
157 device_preselected_
= true;
159 context_
.SetString(kContextKeySelectedDevice
, selected_device
);
160 context_
.SetBoolean(kContextKeyControlsDisabled
, selected_device
.empty());
161 CommitContextChanges();
164 void ControllerPairingScreen::OnActorDestroyed(
165 ControllerPairingScreenActor
* actor
) {
170 // Overridden from ControllerPairingView::Delegate:
171 void ControllerPairingScreen::OnUserActed(const std::string
& action
) {
172 if (context_
.GetBoolean(kContextKeyControlsDisabled
)) {
173 LOG(WARNING
) << "User acted, but controls are disabled. Ignoring.";
176 bool disable_controls
= true;
177 if (action
== kActionChooseDevice
) {
178 std::string selectedDevice
= context_
.GetString(kContextKeySelectedDevice
);
179 if (selectedDevice
.empty())
180 LOG(ERROR
) << "Device was not selected.";
182 shark_controller_
->ChooseDeviceForPairing(selectedDevice
);
183 } else if (action
== kActionRepeatDiscovery
) {
184 shark_controller_
->RepeatDiscovery();
185 } else if (action
== kActionAcceptCode
) {
186 shark_controller_
->SetConfirmationCodeIsCorrect(true);
187 } else if (action
== kActionRejectCode
) {
188 shark_controller_
->SetConfirmationCodeIsCorrect(false);
189 } else if (action
== kActionProceedToAuthentication
) {
190 context_
.SetString(kContextKeyPage
, kPageAuthentication
);
191 disable_controls
= false;
192 } else if (action
== kActionEnroll
) {
193 const std::string account_id
=
194 gaia::SanitizeEmail(context_
.GetString(kContextKeyAccountId
));
195 const std::string
domain(gaia::ExtractDomainName(account_id
));
196 context_
.SetString(kContextKeyEnrollmentDomain
, domain
);
197 } else if (action
== kActionStartSession
) {
198 shark_controller_
->StartSession();
200 context_
.SetBoolean(kContextKeyControlsDisabled
, disable_controls
);
201 CommitContextChanges();
204 void ControllerPairingScreen::OnScreenContextChanged(
205 const base::DictionaryValue
& diff
) {
206 std::vector
<std::string
> changedKeys
;
207 context_
.ApplyChanges(diff
, &changedKeys
);
208 for (std::vector
<std::string
>::const_iterator key
= changedKeys
.begin();
209 key
!= changedKeys
.end();
211 if (*key
== kContextKeySelectedDevice
) {
212 context_
.SetBoolean(kContextKeyControlsDisabled
,
213 context_
.GetString(*key
).empty());
214 CommitContextChanges();
219 } // namespace chromeos