OLD | NEW |
---|---|
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_address.empty()) | |
sacomoto
2015/09/29 18:45:57
Please use the RemoteDevice::bluetooth_type field.
Tim Song
2015/09/30 00:05:04
Done.
| |
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 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
236 } | 252 } |
237 FOR_EACH_OBSERVER(MessengerObserver, observers_, | 253 FOR_EACH_OBSERVER(MessengerObserver, observers_, |
238 OnDecryptResponse(response.Pass())); | 254 OnDecryptResponse(response.Pass())); |
239 } | 255 } |
240 | 256 |
241 void MessengerImpl::HandleUnlockResponseMessage( | 257 void MessengerImpl::HandleUnlockResponseMessage( |
242 const base::DictionaryValue& message) { | 258 const base::DictionaryValue& message) { |
243 FOR_EACH_OBSERVER(MessengerObserver, observers_, OnUnlockResponse(true)); | 259 FOR_EACH_OBSERVER(MessengerObserver, observers_, OnUnlockResponse(true)); |
244 } | 260 } |
245 | 261 |
262 void MessengerImpl::PollScreenStateForIOS() { | |
263 if (!connection_->IsConnected()) | |
264 return; | |
265 | |
266 // Sends message requesting screen state. | |
267 connection_->SendMessage(make_scoped_ptr(new WireMessage(kPollScreenState))); | |
268 | |
269 // Schedules the next message in |kPollingIntervalSeconds|. | |
270 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
271 FROM_HERE, base::Bind(&MessengerImpl::PollScreenStateForIOS, | |
272 weak_ptr_factory_.GetWeakPtr()), | |
273 base::TimeDelta::FromSeconds(kIOSPollingIntervalSeconds)); | |
274 } | |
275 | |
246 void MessengerImpl::OnConnectionStatusChanged(Connection* connection, | 276 void MessengerImpl::OnConnectionStatusChanged(Connection* connection, |
247 Connection::Status old_status, | 277 Connection::Status old_status, |
248 Connection::Status new_status) { | 278 Connection::Status new_status) { |
249 DCHECK_EQ(connection, connection_.get()); | 279 DCHECK_EQ(connection, connection_.get()); |
250 if (new_status == Connection::DISCONNECTED) { | 280 if (new_status == Connection::DISCONNECTED) { |
251 PA_LOG(INFO) << "Secure channel disconnected..."; | 281 PA_LOG(INFO) << "Secure channel disconnected..."; |
252 connection_->RemoveObserver(this); | 282 connection_->RemoveObserver(this); |
253 connection_.reset(); | 283 connection_.reset(); |
254 FOR_EACH_OBSERVER(MessengerObserver, observers_, OnDisconnected()); | 284 FOR_EACH_OBSERVER(MessengerObserver, observers_, OnDisconnected()); |
255 // TODO(isherman): Determine whether it's also necessary/appropriate to fire | 285 // TODO(isherman): Determine whether it's also necessary/appropriate to fire |
256 // this notification from the destructor. | 286 // this notification from the destructor. |
257 } | 287 } |
258 } | 288 } |
259 | 289 |
260 void MessengerImpl::OnMessageReceived(const Connection& connection, | 290 void MessengerImpl::OnMessageReceived(const Connection& connection, |
261 const WireMessage& wire_message) { | 291 const WireMessage& wire_message) { |
292 // TODO(tengs): Unify the iOS status update protocol with the existing Android | |
293 // protocol, so we don't have this special case. | |
294 std::string payload = wire_message.payload(); | |
295 if (payload == kScreenUnlocked || payload == kScreenLocked) { | |
296 RemoteStatusUpdate update; | |
297 update.user_presence = | |
298 (payload == kScreenUnlocked ? USER_PRESENT : USER_ABSENT); | |
299 update.secure_screen_lock_state = SECURE_SCREEN_LOCK_ENABLED; | |
300 update.trust_agent_state = TRUST_AGENT_ENABLED; | |
301 FOR_EACH_OBSERVER(MessengerObserver, observers_, | |
302 OnRemoteStatusUpdate(update)); | |
303 return; | |
304 } | |
305 | |
262 secure_context_->Decode(wire_message.payload(), | 306 secure_context_->Decode(wire_message.payload(), |
263 base::Bind(&MessengerImpl::OnMessageDecoded, | 307 base::Bind(&MessengerImpl::OnMessageDecoded, |
264 weak_ptr_factory_.GetWeakPtr())); | 308 weak_ptr_factory_.GetWeakPtr())); |
265 } | 309 } |
266 | 310 |
267 void MessengerImpl::OnSendCompleted(const Connection& connection, | 311 void MessengerImpl::OnSendCompleted(const Connection& connection, |
268 const WireMessage& wire_message, | 312 const WireMessage& wire_message, |
269 bool success) { | 313 bool success) { |
270 if (!pending_message_) { | 314 if (!pending_message_) { |
271 PA_LOG(ERROR) << "Unexpected message sent."; | 315 PA_LOG(ERROR) << "Unexpected message sent."; |
(...skipping 21 matching lines...) Expand all Loading... | |
293 } else { | 337 } else { |
294 PA_LOG(ERROR) << "Message of unknown type '" << pending_message_->type | 338 PA_LOG(ERROR) << "Message of unknown type '" << pending_message_->type |
295 << "' sent."; | 339 << "' sent."; |
296 } | 340 } |
297 | 341 |
298 pending_message_.reset(); | 342 pending_message_.reset(); |
299 ProcessMessageQueue(); | 343 ProcessMessageQueue(); |
300 } | 344 } |
301 | 345 |
302 } // namespace proximity_auth | 346 } // namespace proximity_auth |
OLD | NEW |