| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "chromeos/components/tether/tether_connector.h" | 5 #include "chromeos/components/tether/tether_connector.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "chromeos/components/tether/connect_tethering_operation.h" | 9 #include "chromeos/components/tether/connect_tethering_operation.h" |
| 10 #include "chromeos/components/tether/device_id_tether_network_guid_map.h" | 10 #include "chromeos/components/tether/device_id_tether_network_guid_map.h" |
| 11 #include "chromeos/components/tether/fake_active_host.h" | 11 #include "chromeos/components/tether/fake_active_host.h" |
| 12 #include "chromeos/components/tether/fake_ble_connection_manager.h" | 12 #include "chromeos/components/tether/fake_ble_connection_manager.h" |
| 13 #include "chromeos/components/tether/fake_host_scan_cache.h" |
| 14 #include "chromeos/components/tether/fake_notification_presenter.h" |
| 13 #include "chromeos/components/tether/fake_tether_host_fetcher.h" | 15 #include "chromeos/components/tether/fake_tether_host_fetcher.h" |
| 14 #include "chromeos/components/tether/fake_wifi_hotspot_connector.h" | 16 #include "chromeos/components/tether/fake_wifi_hotspot_connector.h" |
| 15 #include "chromeos/components/tether/mock_tether_host_response_recorder.h" | 17 #include "chromeos/components/tether/mock_tether_host_response_recorder.h" |
| 16 #include "chromeos/components/tether/tether_connector.h" | 18 #include "chromeos/components/tether/tether_connector.h" |
| 17 #include "chromeos/dbus/dbus_thread_manager.h" | 19 #include "chromeos/dbus/dbus_thread_manager.h" |
| 18 #include "chromeos/network/network_connection_handler.h" | 20 #include "chromeos/network/network_connection_handler.h" |
| 19 #include "chromeos/network/network_state.h" | 21 #include "chromeos/network/network_state.h" |
| 20 #include "chromeos/network/network_state_handler.h" | 22 #include "chromeos/network/network_state_handler.h" |
| 21 #include "chromeos/network/network_state_test.h" | 23 #include "chromeos/network/network_state_test.h" |
| 22 #include "components/cryptauth/remote_device.h" | 24 #include "components/cryptauth/remote_device.h" |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 fake_wifi_hotspot_connector_ = | 126 fake_wifi_hotspot_connector_ = |
| 125 base::MakeUnique<FakeWifiHotspotConnector>(network_state_handler()); | 127 base::MakeUnique<FakeWifiHotspotConnector>(network_state_handler()); |
| 126 fake_active_host_ = base::MakeUnique<FakeActiveHost>(); | 128 fake_active_host_ = base::MakeUnique<FakeActiveHost>(); |
| 127 fake_tether_host_fetcher_ = base::MakeUnique<FakeTetherHostFetcher>( | 129 fake_tether_host_fetcher_ = base::MakeUnique<FakeTetherHostFetcher>( |
| 128 test_devices_, false /* synchronously_reply_with_results */); | 130 test_devices_, false /* synchronously_reply_with_results */); |
| 129 fake_ble_connection_manager_ = base::MakeUnique<FakeBleConnectionManager>(); | 131 fake_ble_connection_manager_ = base::MakeUnique<FakeBleConnectionManager>(); |
| 130 mock_tether_host_response_recorder_ = | 132 mock_tether_host_response_recorder_ = |
| 131 base::MakeUnique<MockTetherHostResponseRecorder>(); | 133 base::MakeUnique<MockTetherHostResponseRecorder>(); |
| 132 device_id_tether_network_guid_map_ = | 134 device_id_tether_network_guid_map_ = |
| 133 base::MakeUnique<DeviceIdTetherNetworkGuidMap>(); | 135 base::MakeUnique<DeviceIdTetherNetworkGuidMap>(); |
| 136 fake_host_scan_cache_ = base::MakeUnique<FakeHostScanCache>(); |
| 137 fake_notification_presenter_ = |
| 138 base::MakeUnique<FakeNotificationPresenter>(); |
| 134 | 139 |
| 135 result_.clear(); | 140 result_.clear(); |
| 136 | 141 |
| 137 tether_connector_ = base::WrapUnique(new TetherConnector( | 142 tether_connector_ = base::WrapUnique(new TetherConnector( |
| 138 network_state_handler(), fake_wifi_hotspot_connector_.get(), | 143 network_state_handler(), fake_wifi_hotspot_connector_.get(), |
| 139 fake_active_host_.get(), fake_tether_host_fetcher_.get(), | 144 fake_active_host_.get(), fake_tether_host_fetcher_.get(), |
| 140 fake_ble_connection_manager_.get(), | 145 fake_ble_connection_manager_.get(), |
| 141 mock_tether_host_response_recorder_.get(), | 146 mock_tether_host_response_recorder_.get(), |
| 142 device_id_tether_network_guid_map_.get())); | 147 device_id_tether_network_guid_map_.get(), fake_host_scan_cache_.get(), |
| 148 fake_notification_presenter_.get())); |
| 143 | 149 |
| 144 SetUpTetherNetworks(); | 150 SetUpTetherNetworks(); |
| 145 } | 151 } |
| 146 | 152 |
| 147 void TearDown() override { | 153 void TearDown() override { |
| 148 // Must delete |fake_wifi_hotspot_connector_| before NetworkStateHandler is | 154 // Must delete |fake_wifi_hotspot_connector_| before NetworkStateHandler is |
| 149 // destroyed to ensure that NetworkStateHandler has zero observers by the | 155 // destroyed to ensure that NetworkStateHandler has zero observers by the |
| 150 // time it reaches its destructor. | 156 // time it reaches its destructor. |
| 151 fake_wifi_hotspot_connector_.reset(); | 157 fake_wifi_hotspot_connector_.reset(); |
| 152 | 158 |
| 153 ShutdownNetworkState(); | 159 ShutdownNetworkState(); |
| 154 NetworkStateTest::TearDown(); | 160 NetworkStateTest::TearDown(); |
| 155 DBusThreadManager::Shutdown(); | 161 DBusThreadManager::Shutdown(); |
| 156 } | 162 } |
| 157 | 163 |
| 158 std::string GetTetherNetworkGuid(const std::string& device_id) { | 164 std::string GetTetherNetworkGuid(const std::string& device_id) { |
| 159 return device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId( | 165 return device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId( |
| 160 device_id); | 166 device_id); |
| 161 } | 167 } |
| 162 | 168 |
| 163 void SetUpTetherNetworks() { | 169 void SetUpTetherNetworks() { |
| 164 // Add a tether network corresponding to both of the test devices. These | 170 // Add a tether network corresponding to both of the test devices. These |
| 165 // networks are expected to be added already before | 171 // networks are expected to be added already before |
| 166 // TetherConnector::ConnectToNetwork is called. | 172 // TetherConnector::ConnectToNetwork is called. |
| 173 AddTetherNetwork(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| 174 "TetherNetworkName1", "TetherNetworkCarrier1", |
| 175 85 /* battery_percentage */, 75 /* signal_strength */, |
| 176 true /* has_connected_to_host */, |
| 177 false /* setup_required */); |
| 178 AddTetherNetwork(GetTetherNetworkGuid(test_devices_[1].GetDeviceId()), |
| 179 "TetherNetworkName2", "TetherNetworkCarrier2", |
| 180 90 /* battery_percentage */, 50 /* signal_strength */, |
| 181 true /* has_connected_to_host */, |
| 182 true /* setup_required */); |
| 183 } |
| 184 |
| 185 virtual void AddTetherNetwork(const std::string& tether_network_guid, |
| 186 const std::string& device_name, |
| 187 const std::string& carrier, |
| 188 int battery_percentage, |
| 189 int signal_strength, |
| 190 bool has_connected_to_host, |
| 191 bool setup_required) { |
| 167 network_state_handler()->AddTetherNetworkState( | 192 network_state_handler()->AddTetherNetworkState( |
| 168 GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), | 193 tether_network_guid, device_name, carrier, battery_percentage, |
| 169 "TetherNetworkName1", "TetherNetworkCarrier1", | 194 signal_strength, has_connected_to_host); |
| 170 85 /* battery_percentage */, 75 /* signal_strength */, | 195 fake_host_scan_cache_->SetHostScanResult(tether_network_guid, device_name, |
| 171 true /* has_connected_to_host */); | 196 carrier, battery_percentage, |
| 172 network_state_handler()->AddTetherNetworkState( | 197 signal_strength, setup_required); |
| 173 GetTetherNetworkGuid(test_devices_[1].GetDeviceId()), | |
| 174 "TetherNetworkName2", "TetherNetworkCarrier2", | |
| 175 90 /* battery_percentage */, 50 /* signal_strength */, | |
| 176 true /* has_connected_to_host */); | |
| 177 } | 198 } |
| 178 | 199 |
| 179 void SuccessfullyJoinWifiNetwork() { | 200 void SuccessfullyJoinWifiNetwork() { |
| 180 ConfigureService(CreateWifiConfigurationJsonString()); | 201 ConfigureService(CreateWifiConfigurationJsonString()); |
| 181 fake_wifi_hotspot_connector_->CallMostRecentCallback(kWifiNetworkGuid); | 202 fake_wifi_hotspot_connector_->CallMostRecentCallback(kWifiNetworkGuid); |
| 182 } | 203 } |
| 183 | 204 |
| 184 void SuccessCallback() { result_ = kSuccessResult; } | 205 void SuccessCallback() { result_ = kSuccessResult; } |
| 185 | 206 |
| 186 void ErrorCallback(const std::string& error_name) { result_ = error_name; } | 207 void ErrorCallback(const std::string& error_name) { result_ = error_name; } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 206 std::unique_ptr<FakeConnectTetheringOperationFactory> fake_operation_factory_; | 227 std::unique_ptr<FakeConnectTetheringOperationFactory> fake_operation_factory_; |
| 207 std::unique_ptr<FakeWifiHotspotConnector> fake_wifi_hotspot_connector_; | 228 std::unique_ptr<FakeWifiHotspotConnector> fake_wifi_hotspot_connector_; |
| 208 std::unique_ptr<FakeActiveHost> fake_active_host_; | 229 std::unique_ptr<FakeActiveHost> fake_active_host_; |
| 209 std::unique_ptr<FakeTetherHostFetcher> fake_tether_host_fetcher_; | 230 std::unique_ptr<FakeTetherHostFetcher> fake_tether_host_fetcher_; |
| 210 std::unique_ptr<FakeBleConnectionManager> fake_ble_connection_manager_; | 231 std::unique_ptr<FakeBleConnectionManager> fake_ble_connection_manager_; |
| 211 std::unique_ptr<MockTetherHostResponseRecorder> | 232 std::unique_ptr<MockTetherHostResponseRecorder> |
| 212 mock_tether_host_response_recorder_; | 233 mock_tether_host_response_recorder_; |
| 213 // TODO(hansberry): Use a fake for this when a real mapping scheme is created. | 234 // TODO(hansberry): Use a fake for this when a real mapping scheme is created. |
| 214 std::unique_ptr<DeviceIdTetherNetworkGuidMap> | 235 std::unique_ptr<DeviceIdTetherNetworkGuidMap> |
| 215 device_id_tether_network_guid_map_; | 236 device_id_tether_network_guid_map_; |
| 237 std::unique_ptr<FakeHostScanCache> fake_host_scan_cache_; |
| 238 std::unique_ptr<FakeNotificationPresenter> fake_notification_presenter_; |
| 216 | 239 |
| 217 std::string result_; | 240 std::string result_; |
| 218 | 241 |
| 219 std::unique_ptr<TetherConnector> tether_connector_; | 242 std::unique_ptr<TetherConnector> tether_connector_; |
| 220 | 243 |
| 221 private: | 244 private: |
| 222 DISALLOW_COPY_AND_ASSIGN(TetherConnectorTest); | 245 DISALLOW_COPY_AND_ASSIGN(TetherConnectorTest); |
| 223 }; | 246 }; |
| 224 | 247 |
| 225 TEST_F(TetherConnectorTest, TestCannotFetchDevice) { | 248 TEST_F(TetherConnectorTest, TestCannotFetchDevice) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 fake_operation_factory_->created_operations()[0]->SendFailedResponse( | 308 fake_operation_factory_->created_operations()[0]->SendFailedResponse( |
| 286 ConnectTetheringResponse_ResponseCode:: | 309 ConnectTetheringResponse_ResponseCode:: |
| 287 ConnectTetheringResponse_ResponseCode_UNKNOWN_ERROR); | 310 ConnectTetheringResponse_ResponseCode_UNKNOWN_ERROR); |
| 288 | 311 |
| 289 // The failure should have resulted in the host being disconnected. | 312 // The failure should have resulted in the host being disconnected. |
| 290 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, | 313 EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED, |
| 291 fake_active_host_->GetActiveHostStatus()); | 314 fake_active_host_->GetActiveHostStatus()); |
| 292 EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset()); | 315 EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset()); |
| 293 } | 316 } |
| 294 | 317 |
| 318 TEST_F(TetherConnectorTest, TestConnectTetheringOperationFails_SetupRequired) { |
| 319 EXPECT_FALSE( |
| 320 fake_notification_presenter_->is_setup_required_notification_shown()); |
| 321 |
| 322 CallConnect(GetTetherNetworkGuid(test_devices_[1].GetDeviceId())); |
| 323 |
| 324 EXPECT_TRUE( |
| 325 fake_notification_presenter_->is_setup_required_notification_shown()); |
| 326 |
| 327 fake_tether_host_fetcher_->InvokePendingCallbacks(); |
| 328 |
| 329 EXPECT_TRUE( |
| 330 fake_notification_presenter_->is_setup_required_notification_shown()); |
| 331 |
| 332 fake_operation_factory_->created_operations()[0]->SendFailedResponse( |
| 333 ConnectTetheringResponse_ResponseCode:: |
| 334 ConnectTetheringResponse_ResponseCode_UNKNOWN_ERROR); |
| 335 |
| 336 EXPECT_FALSE( |
| 337 fake_notification_presenter_->is_setup_required_notification_shown()); |
| 338 |
| 339 EXPECT_EQ(NetworkConnectionHandler::kErrorConnectFailed, GetResultAndReset()); |
| 340 } |
| 341 |
| 295 TEST_F(TetherConnectorTest, TestConnectingToWifiFails) { | 342 TEST_F(TetherConnectorTest, TestConnectingToWifiFails) { |
| 296 CallConnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | 343 CallConnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 297 EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, | 344 EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, |
| 298 fake_active_host_->GetActiveHostStatus()); | 345 fake_active_host_->GetActiveHostStatus()); |
| 299 EXPECT_EQ(test_devices_[0].GetDeviceId(), | 346 EXPECT_EQ(test_devices_[0].GetDeviceId(), |
| 300 fake_active_host_->GetActiveHostDeviceId()); | 347 fake_active_host_->GetActiveHostDeviceId()); |
| 301 EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), | 348 EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| 302 fake_active_host_->GetTetherNetworkGuid()); | 349 fake_active_host_->GetTetherNetworkGuid()); |
| 303 EXPECT_TRUE(fake_active_host_->GetWifiNetworkGuid().empty()); | 350 EXPECT_TRUE(fake_active_host_->GetWifiNetworkGuid().empty()); |
| 304 | 351 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 | 403 |
| 357 TEST_F(TetherConnectorTest, TestSuccessfulConnection) { | 404 TEST_F(TetherConnectorTest, TestSuccessfulConnection) { |
| 358 CallConnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | 405 CallConnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 359 EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, | 406 EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, |
| 360 fake_active_host_->GetActiveHostStatus()); | 407 fake_active_host_->GetActiveHostStatus()); |
| 361 EXPECT_EQ(test_devices_[0].GetDeviceId(), | 408 EXPECT_EQ(test_devices_[0].GetDeviceId(), |
| 362 fake_active_host_->GetActiveHostDeviceId()); | 409 fake_active_host_->GetActiveHostDeviceId()); |
| 363 EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), | 410 EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| 364 fake_active_host_->GetTetherNetworkGuid()); | 411 fake_active_host_->GetTetherNetworkGuid()); |
| 365 EXPECT_TRUE(fake_active_host_->GetWifiNetworkGuid().empty()); | 412 EXPECT_TRUE(fake_active_host_->GetWifiNetworkGuid().empty()); |
| 413 EXPECT_FALSE( |
| 414 fake_notification_presenter_->is_setup_required_notification_shown()); |
| 366 | 415 |
| 367 fake_tether_host_fetcher_->InvokePendingCallbacks(); | 416 fake_tether_host_fetcher_->InvokePendingCallbacks(); |
| 368 | 417 |
| 369 // Receive a successful response. We should still be connecting. | 418 // Receive a successful response. We should still be connecting. |
| 370 EXPECT_EQ(1u, fake_operation_factory_->created_operations().size()); | 419 EXPECT_EQ(1u, fake_operation_factory_->created_operations().size()); |
| 371 fake_operation_factory_->created_operations()[0]->SendSuccessfulResponse( | 420 fake_operation_factory_->created_operations()[0]->SendSuccessfulResponse( |
| 372 kSsid, kPassword); | 421 kSsid, kPassword); |
| 373 EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, | 422 EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTING, |
| 374 fake_active_host_->GetActiveHostStatus()); | 423 fake_active_host_->GetActiveHostStatus()); |
| 375 | 424 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 387 fake_active_host_->GetActiveHostStatus()); | 436 fake_active_host_->GetActiveHostStatus()); |
| 388 EXPECT_EQ(test_devices_[0].GetDeviceId(), | 437 EXPECT_EQ(test_devices_[0].GetDeviceId(), |
| 389 fake_active_host_->GetActiveHostDeviceId()); | 438 fake_active_host_->GetActiveHostDeviceId()); |
| 390 EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), | 439 EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), |
| 391 fake_active_host_->GetTetherNetworkGuid()); | 440 fake_active_host_->GetTetherNetworkGuid()); |
| 392 EXPECT_EQ(kWifiNetworkGuid, fake_active_host_->GetWifiNetworkGuid()); | 441 EXPECT_EQ(kWifiNetworkGuid, fake_active_host_->GetWifiNetworkGuid()); |
| 393 | 442 |
| 394 EXPECT_EQ(kSuccessResult, GetResultAndReset()); | 443 EXPECT_EQ(kSuccessResult, GetResultAndReset()); |
| 395 } | 444 } |
| 396 | 445 |
| 446 TEST_F(TetherConnectorTest, TestSuccessfulConnection_SetupRequired) { |
| 447 EXPECT_FALSE( |
| 448 fake_notification_presenter_->is_setup_required_notification_shown()); |
| 449 |
| 450 CallConnect(GetTetherNetworkGuid(test_devices_[1].GetDeviceId())); |
| 451 |
| 452 EXPECT_TRUE( |
| 453 fake_notification_presenter_->is_setup_required_notification_shown()); |
| 454 |
| 455 fake_tether_host_fetcher_->InvokePendingCallbacks(); |
| 456 |
| 457 EXPECT_TRUE( |
| 458 fake_notification_presenter_->is_setup_required_notification_shown()); |
| 459 |
| 460 fake_operation_factory_->created_operations()[0]->SendSuccessfulResponse( |
| 461 kSsid, kPassword); |
| 462 |
| 463 EXPECT_TRUE( |
| 464 fake_notification_presenter_->is_setup_required_notification_shown()); |
| 465 |
| 466 SuccessfullyJoinWifiNetwork(); |
| 467 |
| 468 EXPECT_FALSE( |
| 469 fake_notification_presenter_->is_setup_required_notification_shown()); |
| 470 |
| 471 EXPECT_EQ(kSuccessResult, GetResultAndReset()); |
| 472 } |
| 473 |
| 397 TEST_F(TetherConnectorTest, | 474 TEST_F(TetherConnectorTest, |
| 398 TestNewConnectionAttemptDuringFetch_DifferentDevice) { | 475 TestNewConnectionAttemptDuringFetch_DifferentDevice) { |
| 399 CallConnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); | 476 CallConnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId())); |
| 400 | 477 |
| 401 // Instead of invoking the pending callbacks on |fake_tether_host_fetcher_|, | 478 // Instead of invoking the pending callbacks on |fake_tether_host_fetcher_|, |
| 402 // attempt another connection attempt, this time to another device. | 479 // attempt another connection attempt, this time to another device. |
| 403 CallConnect(GetTetherNetworkGuid(test_devices_[1].GetDeviceId())); | 480 CallConnect(GetTetherNetworkGuid(test_devices_[1].GetDeviceId())); |
| 404 // The first connection attempt should have resulted in a connect canceled | 481 // The first connection attempt should have resulted in a connect canceled |
| 405 // error. | 482 // error. |
| 406 EXPECT_EQ(NetworkConnectionHandler::kErrorConnectCanceled, | 483 EXPECT_EQ(NetworkConnectionHandler::kErrorConnectCanceled, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 EXPECT_EQ(test_devices_[1].GetDeviceId(), | 581 EXPECT_EQ(test_devices_[1].GetDeviceId(), |
| 505 fake_active_host_->GetActiveHostDeviceId()); | 582 fake_active_host_->GetActiveHostDeviceId()); |
| 506 EXPECT_EQ(GetTetherNetworkGuid(test_devices_[1].GetDeviceId()), | 583 EXPECT_EQ(GetTetherNetworkGuid(test_devices_[1].GetDeviceId()), |
| 507 fake_active_host_->GetTetherNetworkGuid()); | 584 fake_active_host_->GetTetherNetworkGuid()); |
| 508 EXPECT_TRUE(fake_active_host_->GetWifiNetworkGuid().empty()); | 585 EXPECT_TRUE(fake_active_host_->GetWifiNetworkGuid().empty()); |
| 509 } | 586 } |
| 510 | 587 |
| 511 } // namespace tether | 588 } // namespace tether |
| 512 | 589 |
| 513 } // namespace chromeos | 590 } // namespace chromeos |
| OLD | NEW |