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

Side by Side Diff: components/proximity_auth/messenger_impl.cc

Issue 1372283002: Hook up ProximityAuthSystem in EasyUnlockService. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bluetooth_connection
Patch Set: remove log Created 5 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/proximity_auth/messenger_impl.h" 5 #include "components/proximity_auth/messenger_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/location.h"
11 #include "base/thread_task_runner_handle.h"
10 #include "base/values.h" 12 #include "base/values.h"
11 #include "components/proximity_auth/connection.h" 13 #include "components/proximity_auth/connection.h"
12 #include "components/proximity_auth/cryptauth/base64url.h" 14 #include "components/proximity_auth/cryptauth/base64url.h"
13 #include "components/proximity_auth/logging/logging.h" 15 #include "components/proximity_auth/logging/logging.h"
14 #include "components/proximity_auth/messenger_observer.h" 16 #include "components/proximity_auth/messenger_observer.h"
15 #include "components/proximity_auth/remote_status_update.h" 17 #include "components/proximity_auth/remote_status_update.h"
16 #include "components/proximity_auth/secure_context.h" 18 #include "components/proximity_auth/secure_context.h"
17 #include "components/proximity_auth/wire_message.h" 19 #include "components/proximity_auth/wire_message.h"
18 20
19 namespace proximity_auth { 21 namespace proximity_auth {
20 namespace { 22 namespace {
21 23
22 // The key names of JSON fields for messages sent between the devices. 24 // The key names of JSON fields for messages sent between the devices.
23 const char kTypeKey[] = "type"; 25 const char kTypeKey[] = "type";
24 const char kNameKey[] = "name"; 26 const char kNameKey[] = "name";
25 const char kDataKey[] = "data"; 27 const char kDataKey[] = "data";
26 const char kEncryptedDataKey[] = "encrypted_data"; 28 const char kEncryptedDataKey[] = "encrypted_data";
27 29
28 // The types of messages that can be sent and received. 30 // The types of messages that can be sent and received.
29 const char kMessageTypeLocalEvent[] = "event"; 31 const char kMessageTypeLocalEvent[] = "event";
30 const char kMessageTypeRemoteStatusUpdate[] = "status_update"; 32 const char kMessageTypeRemoteStatusUpdate[] = "status_update";
31 const char kMessageTypeDecryptRequest[] = "decrypt_request"; 33 const char kMessageTypeDecryptRequest[] = "decrypt_request";
32 const char kMessageTypeDecryptResponse[] = "decrypt_response"; 34 const char kMessageTypeDecryptResponse[] = "decrypt_response";
33 const char kMessageTypeUnlockRequest[] = "unlock_request"; 35 const char kMessageTypeUnlockRequest[] = "unlock_request";
34 const char kMessageTypeUnlockResponse[] = "unlock_response"; 36 const char kMessageTypeUnlockResponse[] = "unlock_response";
35 37
36 // The name for an unlock event originating from the local device. 38 // The name for an unlock event originating from the local device.
37 const char kUnlockEventName[] = "easy_unlock"; 39 const char kUnlockEventName[] = "easy_unlock";
38 40
41 // Messages sent and received from the iOS app when polling for it's lock screen
42 // status.
43 // TODO(tengs): Unify the iOS status update protocol with the existing Android
44 // protocol, so we don't have this special case.
45 const char kPollScreenState[] = "PollScreenState";
46 const char kScreenUnlocked[] = "Screen Unlocked";
47 const char kScreenLocked[] = "Screen Locked";
48 const int kIOSPollingIntervalSeconds = 5;
49
39 // Serializes the |value| to a JSON string and returns the result. 50 // Serializes the |value| to a JSON string and returns the result.
40 std::string SerializeValueToJson(const base::Value& value) { 51 std::string SerializeValueToJson(const base::Value& value) {
41 std::string json; 52 std::string json;
42 base::JSONWriter::Write(value, &json); 53 base::JSONWriter::Write(value, &json);
43 return json; 54 return json;
44 } 55 }
45 56
46 // Returns the message type represented by the |message|. This is a convenience 57 // Returns the message type represented by the |message|. This is a convenience
47 // wrapper that should only be called when the |message| is known to specify its 58 // wrapper that should only be called when the |message| is known to specify its
48 // message type, i.e. this should not be called for untrusted input. 59 // message type, i.e. this should not be called for untrusted input.
49 std::string GetMessageType(const base::DictionaryValue& message) { 60 std::string GetMessageType(const base::DictionaryValue& message) {
50 std::string type; 61 std::string type;
51 message.GetString(kTypeKey, &type); 62 message.GetString(kTypeKey, &type);
52 return type; 63 return type;
53 } 64 }
54 65
55 } // namespace 66 } // namespace
56 67
57 MessengerImpl::MessengerImpl(scoped_ptr<Connection> connection, 68 MessengerImpl::MessengerImpl(scoped_ptr<Connection> connection,
58 scoped_ptr<SecureContext> secure_context) 69 scoped_ptr<SecureContext> secure_context)
59 : connection_(connection.Pass()), 70 : connection_(connection.Pass()),
60 secure_context_(secure_context.Pass()), 71 secure_context_(secure_context.Pass()),
61 weak_ptr_factory_(this) { 72 weak_ptr_factory_(this) {
62 DCHECK(connection_->IsConnected()); 73 DCHECK(connection_->IsConnected());
63 connection_->AddObserver(this); 74 connection_->AddObserver(this);
75
76 // TODO(tengs): We need CryptAuth to report if the phone runs iOS or Android,
77 // rather than relying on this heuristic.
78 if (connection_->remote_device().bluetooth_type == RemoteDevice::BLUETOOTH_LE)
79 PollScreenStateForIOS();
64 } 80 }
65 81
66 MessengerImpl::~MessengerImpl() { 82 MessengerImpl::~MessengerImpl() {
67 if (connection_) 83 if (connection_)
68 connection_->RemoveObserver(this); 84 connection_->RemoveObserver(this);
69 } 85 }
70 86
71 void MessengerImpl::AddObserver(MessengerObserver* observer) { 87 void MessengerImpl::AddObserver(MessengerObserver* observer) {
72 observers_.AddObserver(observer); 88 observers_.AddObserver(observer);
73 } 89 }
74 90
75 void MessengerImpl::RemoveObserver(MessengerObserver* observer) { 91 void MessengerImpl::RemoveObserver(MessengerObserver* observer) {
76 observers_.RemoveObserver(observer); 92 observers_.RemoveObserver(observer);
77 } 93 }
78 94
79 bool MessengerImpl::SupportsSignIn() const { 95 bool MessengerImpl::SupportsSignIn() const {
96 // TODO(tengs): Support sign-in for Bluetooth LE protocol.
80 return (secure_context_->GetProtocolVersion() == 97 return (secure_context_->GetProtocolVersion() ==
81 SecureContext::PROTOCOL_VERSION_THREE_ONE); 98 SecureContext::PROTOCOL_VERSION_THREE_ONE) &&
99 connection_->remote_device().bluetooth_type !=
100 RemoteDevice::BLUETOOTH_LE;
82 } 101 }
83 102
84 void MessengerImpl::DispatchUnlockEvent() { 103 void MessengerImpl::DispatchUnlockEvent() {
85 base::DictionaryValue message; 104 base::DictionaryValue message;
86 message.SetString(kTypeKey, kMessageTypeLocalEvent); 105 message.SetString(kTypeKey, kMessageTypeLocalEvent);
87 message.SetString(kNameKey, kUnlockEventName); 106 message.SetString(kNameKey, kUnlockEventName);
88 queued_messages_.push_back(PendingMessage(message)); 107 queued_messages_.push_back(PendingMessage(message));
89 ProcessMessageQueue(); 108 ProcessMessageQueue();
90 } 109 }
91 110
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 ProcessMessageQueue(); 143 ProcessMessageQueue();
125 } 144 }
126 145
127 MessengerImpl::PendingMessage::PendingMessage() {} 146 MessengerImpl::PendingMessage::PendingMessage() {}
128 147
129 MessengerImpl::PendingMessage::PendingMessage( 148 MessengerImpl::PendingMessage::PendingMessage(
130 const base::DictionaryValue& message) 149 const base::DictionaryValue& message)
131 : json_message(SerializeValueToJson(message)), 150 : json_message(SerializeValueToJson(message)),
132 type(GetMessageType(message)) {} 151 type(GetMessageType(message)) {}
133 152
153 MessengerImpl::PendingMessage::PendingMessage(const std::string& message)
154 : json_message(message), type(std::string()) {}
155
134 MessengerImpl::PendingMessage::~PendingMessage() {} 156 MessengerImpl::PendingMessage::~PendingMessage() {}
135 157
136 void MessengerImpl::ProcessMessageQueue() { 158 void MessengerImpl::ProcessMessageQueue() {
137 if (pending_message_ || queued_messages_.empty() || 159 if (pending_message_ || queued_messages_.empty() ||
138 connection_->is_sending_message()) 160 connection_->is_sending_message())
139 return; 161 return;
140 162
141 pending_message_.reset(new PendingMessage(queued_messages_.front())); 163 pending_message_.reset(new PendingMessage(queued_messages_.front()));
142 queued_messages_.pop_front(); 164 queued_messages_.pop_front();
143 165
144 secure_context_->Encode(pending_message_->json_message, 166 secure_context_->Encode(pending_message_->json_message,
145 base::Bind(&MessengerImpl::OnMessageEncoded, 167 base::Bind(&MessengerImpl::OnMessageEncoded,
146 weak_ptr_factory_.GetWeakPtr())); 168 weak_ptr_factory_.GetWeakPtr()));
147 } 169 }
148 170
149 void MessengerImpl::OnMessageEncoded(const std::string& encoded_message) { 171 void MessengerImpl::OnMessageEncoded(const std::string& encoded_message) {
150 connection_->SendMessage(make_scoped_ptr(new WireMessage(encoded_message))); 172 connection_->SendMessage(make_scoped_ptr(new WireMessage(encoded_message)));
151 } 173 }
152 174
153 void MessengerImpl::OnMessageDecoded(const std::string& decoded_message) { 175 void MessengerImpl::OnMessageDecoded(const std::string& decoded_message) {
176 // TODO(tengs): Unify the iOS status update protocol with the existing Android
177 // protocol, so we don't have this special case.
178 if (decoded_message == kScreenUnlocked || decoded_message == kScreenLocked) {
179 RemoteStatusUpdate update;
180 update.user_presence =
181 (decoded_message == kScreenUnlocked ? USER_PRESENT : USER_ABSENT);
182 update.secure_screen_lock_state = SECURE_SCREEN_LOCK_ENABLED;
183 update.trust_agent_state = TRUST_AGENT_ENABLED;
184 FOR_EACH_OBSERVER(MessengerObserver, observers_,
185 OnRemoteStatusUpdate(update));
186 pending_message_.reset();
187 ProcessMessageQueue();
188 return;
189 }
190
154 // The decoded message should be a JSON string. 191 // The decoded message should be a JSON string.
155 scoped_ptr<base::Value> message_value = 192 scoped_ptr<base::Value> message_value =
156 base::JSONReader::Read(decoded_message); 193 base::JSONReader::Read(decoded_message);
157 if (!message_value || !message_value->IsType(base::Value::TYPE_DICTIONARY)) { 194 if (!message_value || !message_value->IsType(base::Value::TYPE_DICTIONARY)) {
158 PA_LOG(ERROR) << "Unable to parse message as JSON:\n" << decoded_message; 195 PA_LOG(ERROR) << "Unable to parse message as JSON:\n" << decoded_message;
159 return; 196 return;
160 } 197 }
161 198
162 base::DictionaryValue* message; 199 base::DictionaryValue* message;
163 bool success = message_value->GetAsDictionary(&message); 200 bool success = message_value->GetAsDictionary(&message);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 } 273 }
237 FOR_EACH_OBSERVER(MessengerObserver, observers_, 274 FOR_EACH_OBSERVER(MessengerObserver, observers_,
238 OnDecryptResponse(response.Pass())); 275 OnDecryptResponse(response.Pass()));
239 } 276 }
240 277
241 void MessengerImpl::HandleUnlockResponseMessage( 278 void MessengerImpl::HandleUnlockResponseMessage(
242 const base::DictionaryValue& message) { 279 const base::DictionaryValue& message) {
243 FOR_EACH_OBSERVER(MessengerObserver, observers_, OnUnlockResponse(true)); 280 FOR_EACH_OBSERVER(MessengerObserver, observers_, OnUnlockResponse(true));
244 } 281 }
245 282
283 void MessengerImpl::PollScreenStateForIOS() {
284 if (!connection_->IsConnected())
285 return;
286
287 // Sends message requesting screen state.
288 queued_messages_.push_back(PendingMessage(std::string(kPollScreenState)));
289 ProcessMessageQueue();
290
291 // Schedules the next message in |kPollingIntervalSeconds|.
292 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
293 FROM_HERE, base::Bind(&MessengerImpl::PollScreenStateForIOS,
294 weak_ptr_factory_.GetWeakPtr()),
295 base::TimeDelta::FromSeconds(kIOSPollingIntervalSeconds));
296 }
297
246 void MessengerImpl::OnConnectionStatusChanged(Connection* connection, 298 void MessengerImpl::OnConnectionStatusChanged(Connection* connection,
247 Connection::Status old_status, 299 Connection::Status old_status,
248 Connection::Status new_status) { 300 Connection::Status new_status) {
249 DCHECK_EQ(connection, connection_.get()); 301 DCHECK_EQ(connection, connection_.get());
250 if (new_status == Connection::DISCONNECTED) { 302 if (new_status == Connection::DISCONNECTED) {
251 PA_LOG(INFO) << "Secure channel disconnected..."; 303 PA_LOG(INFO) << "Secure channel disconnected...";
252 connection_->RemoveObserver(this); 304 connection_->RemoveObserver(this);
253 connection_.reset();
254 FOR_EACH_OBSERVER(MessengerObserver, observers_, OnDisconnected()); 305 FOR_EACH_OBSERVER(MessengerObserver, observers_, OnDisconnected());
255 // TODO(isherman): Determine whether it's also necessary/appropriate to fire 306 // TODO(isherman): Determine whether it's also necessary/appropriate to fire
256 // this notification from the destructor. 307 // this notification from the destructor.
257 } 308 }
258 } 309 }
259 310
260 void MessengerImpl::OnMessageReceived(const Connection& connection, 311 void MessengerImpl::OnMessageReceived(const Connection& connection,
261 const WireMessage& wire_message) { 312 const WireMessage& wire_message) {
262 secure_context_->Decode(wire_message.payload(), 313 secure_context_->Decode(wire_message.payload(),
263 base::Bind(&MessengerImpl::OnMessageDecoded, 314 base::Bind(&MessengerImpl::OnMessageDecoded,
(...skipping 29 matching lines...) Expand all
293 } else { 344 } else {
294 PA_LOG(ERROR) << "Message of unknown type '" << pending_message_->type 345 PA_LOG(ERROR) << "Message of unknown type '" << pending_message_->type
295 << "' sent."; 346 << "' sent.";
296 } 347 }
297 348
298 pending_message_.reset(); 349 pending_message_.reset();
299 ProcessMessageQueue(); 350 ProcessMessageQueue();
300 } 351 }
301 352
302 } // namespace proximity_auth 353 } // namespace proximity_auth
OLDNEW
« no previous file with comments | « components/proximity_auth/messenger_impl.h ('k') | components/proximity_auth/messenger_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698