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. 4 5 #include "chrome/browser/local_discovery/privetv3_setup_flow.h" 6 7 #include "base/logging.h" 8 #include "chrome/browser/local_discovery/gcd_registration_ticket_request.h" 9 10 namespace local_discovery { 11 12 namespace { 13 14 const char kSsidJsonKeyName[] = "wifi.ssid"; 15 const char kPasswordJsonKeyName[] = "wifi.passphrase"; 16 const char kTicketJsonKeyName[] = "registration.ticketID"; 17 const char kUserJsonKeyName[] = "registration.user"; 18 19 class SetupRequest : public PrivetV3Session::Request { 20 public: 21 explicit SetupRequest(PrivetV3SetupFlow* setup_flow); 22 virtual ~SetupRequest(); 23 24 virtual std::string GetName() OVERRIDE { return "/privet/v3/setup/start"; } 25 virtual const base::DictionaryValue& GetInput() OVERRIDE; 26 27 virtual void OnError(PrivetURLFetcher::ErrorType error) OVERRIDE; 28 virtual void OnParsedJson(const base::DictionaryValue& value, 29 bool has_error) OVERRIDE; 30 31 void SetWiFiCridentials(const std::string& ssid, const std::string& password); 32 33 void SetRegistrationTicket(const std::string& ticket_id, 34 const std::string& owner_email); 35 36 private: 37 base::DictionaryValue input_; 38 PrivetV3SetupFlow* setup_flow_; 39 }; 40 41 SetupRequest::SetupRequest(PrivetV3SetupFlow* setup_flow) 42 : setup_flow_(setup_flow) { 43 } 44 45 SetupRequest::~SetupRequest() { 46 } 47 48 const base::DictionaryValue& SetupRequest::GetInput() { 49 return input_; 50 } 51 52 void SetupRequest::OnError(PrivetURLFetcher::ErrorType error) { 53 setup_flow_->OnSetupError(); 54 } 55 56 void SetupRequest::OnParsedJson(const base::DictionaryValue& value, 57 bool has_error) { 58 if (has_error) 59 return setup_flow_->OnSetupError(); 60 setup_flow_->OnDeviceRegistered(); 61 } 62 63 void SetupRequest::SetWiFiCridentials(const std::string& ssid, 64 const std::string& password) { 65 DCHECK(!ssid.empty()); 66 DCHECK(!password.empty()); 67 input_.SetString(kSsidJsonKeyName, ssid); 68 input_.SetString(kPasswordJsonKeyName, password); 69 } 70 71 void SetupRequest::SetRegistrationTicket(const std::string& ticket_id, 72 const std::string& owner_email) { 73 DCHECK(!ticket_id.empty()); 74 DCHECK(!owner_email.empty()); 75 input_.SetString(kTicketJsonKeyName, ticket_id); 76 input_.SetString(kUserJsonKeyName, owner_email); 77 } 78 79 } // namespace 80 81 PrivetV3SetupFlow::Delegate::~Delegate() { 82 } 83 84 PrivetV3SetupFlow::PrivetV3SetupFlow(Delegate* delegate) 85 : delegate_(delegate), weak_ptr_factory_(this) { 86 } 87 88 PrivetV3SetupFlow::~PrivetV3SetupFlow() { 89 } 90 91 void PrivetV3SetupFlow::Register(const std::string& service_name) { 92 service_name_ = service_name; 93 ticket_request_ = delegate_->CreateApiFlow(); 94 if (!ticket_request_) { 95 OnSetupError(); 96 return; 97 } 98 scoped_ptr<GCDApiFlow::Request> ticket_request( 99 new GCDRegistrationTicketRequest( 100 base::Bind(&PrivetV3SetupFlow::OnTicketCreated, 101 weak_ptr_factory_.GetWeakPtr()))); 102 ticket_request_->Start(ticket_request.Pass()); 103 } 104 105 #if defined(ENABLE_WIFI_BOOTSTRAPPING) 106 void PrivetV3SetupFlow::SetupWifiAndRegister(const std::string& device_ssid) { 107 NOTIMPLEMENTED(); 108 } 109 #endif // ENABLE_WIFI_BOOTSTRAPPING 110 111 void PrivetV3SetupFlow::OnSetupConfirmationNeeded( 112 const std::string& confirmation_code, 113 extensions::api::gcd_private::ConfirmationType confirmation_type) { 114 delegate_->ConfirmSecurityCode(confirmation_code, 115 base::Bind(&PrivetV3SetupFlow::OnCodeConfirmed, 116 weak_ptr_factory_.GetWeakPtr(), 117 confirmation_code)); 118 } 119 120 void PrivetV3SetupFlow::OnSessionStatus( 121 extensions::api::gcd_private::Status status) { 122 if (status == extensions::api::gcd_private::STATUS_SUCCESS) { 123 DCHECK(setup_request_); 124 session_->StartRequest(setup_request_.get()); 125 } else { 126 OnSetupError(); 127 } 128 } 129 130 void PrivetV3SetupFlow::OnSetupError() { 131 delegate_->OnSetupError(); 132 } 133 134 void PrivetV3SetupFlow::OnDeviceRegistered() { 135 delegate_->OnSetupDone(); 136 } 137 138 void PrivetV3SetupFlow::OnTicketCreated(const std::string& ticket_id, 139 const std::string& device_id) { 140 if (ticket_id.empty() || device_id.empty()) { 141 OnSetupError(); 142 return; 143 } 144 // TODO(vitalybuka): Implement success check by polling status of device_id_. 145 device_id_ = device_id; 146 SetupRequest* setup_request = new SetupRequest(this); 147 setup_request_.reset(setup_request); 148 setup_request->SetRegistrationTicket(ticket_id, "me"); 149 delegate_->CreatePrivetV3Client( 150 service_name_, 151 base::Bind(&PrivetV3SetupFlow::OnPrivetClientCreated, 152 weak_ptr_factory_.GetWeakPtr())); 153 } 154 155 void PrivetV3SetupFlow::OnPrivetClientCreated( 156 scoped_ptr<PrivetHTTPClient> privet_http_client) { 157 if (!privet_http_client) { 158 OnSetupError(); 159 return; 160 } 161 session_.reset(new PrivetV3Session(privet_http_client.Pass(), this)); 162 session_->Start(); 163 } 164 165 void PrivetV3SetupFlow::OnCodeConfirmed(const std::string& code, bool success) { 166 if (!success) 167 return OnSetupError(); 168 session_->ConfirmCode(code); 169 } 170 171 } // namespace local_discovery 172