Remove obsolete entries from .gitignore.
[chromium-blink-merge.git] / components / proximity_auth / remote_device_life_cycle_impl.cc
blob5a9709a285c594489ff54a05cb8c19056643dc24
1 // Copyright 2015 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 "components/proximity_auth/remote_device_life_cycle_impl.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/thread_task_runner_handle.h"
10 #include "base/time/default_tick_clock.h"
11 #include "components/proximity_auth/ble/bluetooth_low_energy_connection.h"
12 #include "components/proximity_auth/ble/bluetooth_low_energy_connection_finder.h"
13 #include "components/proximity_auth/bluetooth_connection.h"
14 #include "components/proximity_auth/bluetooth_connection_finder.h"
15 #include "components/proximity_auth/bluetooth_throttler_impl.h"
16 #include "components/proximity_auth/cryptauth/secure_message_delegate.h"
17 #include "components/proximity_auth/device_to_device_authenticator.h"
18 #include "components/proximity_auth/logging/logging.h"
19 #include "components/proximity_auth/messenger_impl.h"
20 #include "components/proximity_auth/proximity_auth_client.h"
21 #include "components/proximity_auth/secure_context.h"
23 namespace proximity_auth {
25 namespace {
27 // The UUID of the Smart Lock classic Bluetooth service.
28 const char kClassicBluetoothServiceUUID[] =
29 "704EE561-3782-405A-A14B-2D47A2DDCDDF";
31 // The UUID of the Bluetooth Low Energy service.
32 const char kBLESmartLockServiceUUID[] = "b3b7e28e-a000-3e17-bd86-6e97b9e28c11";
34 // The time to wait, in seconds, after authentication fails, before retrying
35 // another connection.
36 const int kAuthenticationRecoveryTimeSeconds = 10;
38 } // namespace
40 RemoteDeviceLifeCycleImpl::RemoteDeviceLifeCycleImpl(
41 const RemoteDevice& remote_device,
42 ProximityAuthClient* proximity_auth_client)
43 : remote_device_(remote_device),
44 proximity_auth_client_(proximity_auth_client),
45 state_(RemoteDeviceLifeCycle::State::STOPPED),
46 bluetooth_throttler_(new BluetoothThrottlerImpl(
47 make_scoped_ptr(new base::DefaultTickClock()))),
48 weak_ptr_factory_(this) {}
50 RemoteDeviceLifeCycleImpl::~RemoteDeviceLifeCycleImpl() {}
52 void RemoteDeviceLifeCycleImpl::Start() {
53 PA_LOG(INFO) << "Life cycle started.";
54 DCHECK(state_ == RemoteDeviceLifeCycle::State::STOPPED);
55 FindConnection();
58 RemoteDeviceLifeCycle::State RemoteDeviceLifeCycleImpl::GetState() const {
59 return state_;
62 Messenger* RemoteDeviceLifeCycleImpl::GetMessenger() {
63 return messenger_.get();
66 void RemoteDeviceLifeCycleImpl::AddObserver(Observer* observer) {
67 observers_.AddObserver(observer);
70 void RemoteDeviceLifeCycleImpl::RemoveObserver(Observer* observer) {
71 observers_.RemoveObserver(observer);
74 scoped_ptr<ConnectionFinder>
75 RemoteDeviceLifeCycleImpl::CreateConnectionFinder() {
76 // TODO(tengs): We should not rely on the assumption that an empty Bluetooth
77 // address means that the device is BLE.
78 if (remote_device_.bluetooth_address.empty()) {
79 return make_scoped_ptr(new BluetoothLowEnergyConnectionFinder(
80 remote_device_, kBLESmartLockServiceUUID,
81 BluetoothLowEnergyConnectionFinder::FinderStrategy::FIND_PAIRED_DEVICE,
82 nullptr, bluetooth_throttler_.get(), 3));
83 } else {
84 return make_scoped_ptr(new BluetoothConnectionFinder(
85 remote_device_, device::BluetoothUUID(kClassicBluetoothServiceUUID),
86 base::TimeDelta::FromSeconds(3)));
90 scoped_ptr<Authenticator> RemoteDeviceLifeCycleImpl::CreateAuthenticator() {
91 return make_scoped_ptr(new DeviceToDeviceAuthenticator(
92 connection_.get(), proximity_auth_client_->GetAccountId(),
93 proximity_auth_client_->CreateSecureMessageDelegate()));
96 void RemoteDeviceLifeCycleImpl::TransitionToState(
97 RemoteDeviceLifeCycle::State new_state) {
98 RemoteDeviceLifeCycle::State old_state = state_;
99 state_ = new_state;
100 FOR_EACH_OBSERVER(Observer, observers_,
101 OnLifeCycleStateChanged(old_state, new_state));
104 void RemoteDeviceLifeCycleImpl::FindConnection() {
105 connection_finder_ = CreateConnectionFinder();
106 connection_finder_->Find(
107 base::Bind(&RemoteDeviceLifeCycleImpl::OnConnectionFound,
108 weak_ptr_factory_.GetWeakPtr()));
109 TransitionToState(RemoteDeviceLifeCycle::State::FINDING_CONNECTION);
112 void RemoteDeviceLifeCycleImpl::OnConnectionFound(
113 scoped_ptr<Connection> connection) {
114 DCHECK(state_ == RemoteDeviceLifeCycle::State::FINDING_CONNECTION);
115 connection_ = connection.Pass();
116 authenticator_ = CreateAuthenticator();
117 authenticator_->Authenticate(
118 base::Bind(&RemoteDeviceLifeCycleImpl::OnAuthenticationResult,
119 weak_ptr_factory_.GetWeakPtr()));
120 TransitionToState(RemoteDeviceLifeCycle::State::AUTHENTICATING);
123 void RemoteDeviceLifeCycleImpl::OnAuthenticationResult(
124 Authenticator::Result result,
125 scoped_ptr<SecureContext> secure_context) {
126 DCHECK(state_ == RemoteDeviceLifeCycle::State::AUTHENTICATING);
127 if (result != Authenticator::Result::SUCCESS) {
128 PA_LOG(WARNING) << "Waiting " << kAuthenticationRecoveryTimeSeconds
129 << " seconds to retry after authentication failure.";
130 connection_->Disconnect();
131 authentication_recovery_timer_.Start(
132 FROM_HERE,
133 base::TimeDelta::FromSeconds(kAuthenticationRecoveryTimeSeconds), this,
134 &RemoteDeviceLifeCycleImpl::FindConnection);
135 TransitionToState(RemoteDeviceLifeCycle::State::AUTHENTICATION_FAILED);
136 return;
139 // Create the MessengerImpl asynchronously. |messenger_| registers itself as
140 // an
141 // observer of |connection_|, so creating it synchronously would
142 // trigger |OnSendComplete()| as an observer call for |messenger_|.
143 secure_context_ = secure_context.Pass();
144 base::ThreadTaskRunnerHandle::Get()->PostTask(
145 FROM_HERE, base::Bind(&RemoteDeviceLifeCycleImpl::CreateMessenger,
146 weak_ptr_factory_.GetWeakPtr()));
149 void RemoteDeviceLifeCycleImpl::CreateMessenger() {
150 DCHECK(state_ == RemoteDeviceLifeCycle::State::AUTHENTICATING);
151 DCHECK(secure_context_);
152 messenger_.reset(
153 new MessengerImpl(connection_.Pass(), secure_context_.Pass()));
154 messenger_->AddObserver(this);
156 TransitionToState(RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
159 void RemoteDeviceLifeCycleImpl::OnDisconnected() {
160 DCHECK(state_ == RemoteDeviceLifeCycle::State::SECURE_CHANNEL_ESTABLISHED);
161 FindConnection();
164 } // namespace proximity_auth