Skip to content

Commit d8665b5

Browse files
author
Ryan Hansberry
committed
[CrOS MultiDevice] Only start up Instant Tethering when enabled.
This CL updates TetherService and TetherHostFetcher to use the MultiDeviceSetupClient's GetFeatureState() function to determine whether the feature should be active or not. This fixes a few edge cases: (1) If the Instant Tethering user preference is enabled, but the Better Together suite is disabled, we should not start up the feature. (2) If the preference is enabled, but the host device does not support Instant Tethering, we should not start up the feature. This CL eliminates the MULTIDEVICE_HOST_UNVERIFIED metrics enum since an unverified host results in NO_AVAILABLE_HOSTS; it replaces that enum value with BETTER_TOGETHER_SUITE_DISABLED, which can occur in practice. Note that because the old metric value has not yet been pushed to users, it is okay to replace it with a new value instead of deprecating it. [email protected] (cherry picked from commit 7bddbb1) Bug: 875502, 824568 Change-Id: Ia85f0ba31871c94ed9eb0cb2ef3c4699bb0000dd Reviewed-on: https://chromium-review.googlesource.com/1196172 Reviewed-by: Zentaro Kavanagh <[email protected]> Commit-Queue: Kyle Horimoto <[email protected]> Cr-Original-Commit-Position: refs/heads/master@{#587894} Reviewed-on: https://chromium-review.googlesource.com/1208139 Reviewed-by: Ryan Hansberry <[email protected]> Cr-Commit-Position: refs/branch-heads/3538@{#68} Cr-Branched-From: 79f7c91-refs/heads/master@{#587811}
1 parent 590bda6 commit d8665b5

File tree

10 files changed

+177
-68
lines changed

10 files changed

+177
-68
lines changed

chrome/browser/chromeos/tether/tether_service.cc

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ std::string TetherService::TetherFeatureStateToString(
110110
return "[Wi-Fi is not present on the device]";
111111
case (TetherFeatureState::SUSPENDED):
112112
return "[Suspended]";
113-
case (TetherFeatureState::MULTIDEVICE_HOST_UNVERIFIED):
114-
return "[MultiDevice host unverified]";
113+
case (TetherFeatureState::BETTER_TOGETHER_SUITE_DISABLED):
114+
return "[Better Together suite is disabled]";
115115
case (TetherFeatureState::TETHER_FEATURE_STATE_MAX):
116116
// |previous_feature_state_| is initialized to TETHER_FEATURE_STATE_MAX,
117117
// and this value is never actually used in practice.
@@ -267,10 +267,17 @@ void TetherService::StopTetherIfNecessary() {
267267
shutdown_reason = chromeos::tether::TetherComponent::ShutdownReason::
268268
BLUETOOTH_CONTROLLER_DISAPPEARED;
269269
break;
270-
case MULTIDEVICE_HOST_UNVERIFIED:
270+
case NO_AVAILABLE_HOSTS:
271+
// If |tether_component_| was previously active but now has been shut down
272+
// due to no longer having a host, this means that the host became
273+
// unverified.
271274
shutdown_reason = chromeos::tether::TetherComponent::ShutdownReason::
272275
MULTIDEVICE_HOST_UNVERIFIED;
273276
break;
277+
case BETTER_TOGETHER_SUITE_DISABLED:
278+
shutdown_reason = chromeos::tether::TetherComponent::ShutdownReason::
279+
BETTER_TOGETHER_SUITE_DISABLED;
280+
break;
274281
default:
275282
PA_LOG(ERROR) << "Unexpected shutdown reason. FeatureState is "
276283
<< GetTetherFeatureState() << ".";
@@ -422,17 +429,15 @@ void TetherService::OnReady() {
422429

423430
if (base::FeatureList::IsEnabled(
424431
chromeos::features::kEnableUnifiedMultiDeviceSetup)) {
425-
OnHostStatusChanged(multidevice_setup_client_->GetHostStatus());
432+
OnFeatureStatesChanged(multidevice_setup_client_->GetFeatureStates());
426433
} else {
427434
GetBluetoothAdapter();
428435
}
429436
}
430437

431-
void TetherService::OnHostStatusChanged(
432-
const chromeos::multidevice_setup::MultiDeviceSetupClient::
433-
HostStatusWithDevice& host_status_with_device) {
434-
host_status_ = host_status_with_device.first;
435-
438+
void TetherService::OnFeatureStatesChanged(
439+
const chromeos::multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap&
440+
feature_states_map) {
436441
if (adapter_)
437442
UpdateTetherTechnologyState();
438443
else
@@ -494,7 +499,7 @@ TetherService::GetTetherTechnologyState() {
494499
case WIFI_NOT_PRESENT:
495500
case NO_AVAILABLE_HOSTS:
496501
case CELLULAR_DISABLED:
497-
case MULTIDEVICE_HOST_UNVERIFIED:
502+
case BETTER_TOGETHER_SUITE_DISABLED:
498503
return chromeos::NetworkStateHandler::TechnologyState::
499504
TECHNOLOGY_UNAVAILABLE;
500505

@@ -649,23 +654,52 @@ TetherService::TetherFeatureState TetherService::GetTetherFeatureState() {
649654
if (IsCellularAvailableButNotEnabled())
650655
return CELLULAR_DISABLED;
651656

652-
if (!IsAllowedByPolicy())
653-
return PROHIBITED;
654-
655657
if (!IsBluetoothPowered())
656658
return BLUETOOTH_DISABLED;
657659

658-
if (!IsEnabledByPreference())
659-
return USER_PREFERENCE_DISABLED;
660-
660+
// For the cases below, the state is computed differently depending on whether
661+
// the MultiDeviceSetup service is active.
661662
if (base::FeatureList::IsEnabled(chromeos::features::kMultiDeviceApi) &&
662663
base::FeatureList::IsEnabled(
663-
chromeos::features::kEnableUnifiedMultiDeviceSetup) &&
664-
host_status_ !=
665-
chromeos::multidevice_setup::mojom::HostStatus::kHostVerified) {
666-
return MULTIDEVICE_HOST_UNVERIFIED;
664+
chromeos::features::kEnableUnifiedMultiDeviceSetup)) {
665+
chromeos::multidevice_setup::mojom::FeatureState tether_multidevice_state =
666+
multidevice_setup_client_->GetFeatureState(
667+
chromeos::multidevice_setup::mojom::Feature::kInstantTethering);
668+
switch (tether_multidevice_state) {
669+
case chromeos::multidevice_setup::mojom::FeatureState::
670+
kProhibitedByPolicy:
671+
return PROHIBITED;
672+
case chromeos::multidevice_setup::mojom::FeatureState::kDisabledByUser:
673+
return USER_PREFERENCE_DISABLED;
674+
case chromeos::multidevice_setup::mojom::FeatureState::kEnabledByUser:
675+
return ENABLED;
676+
case chromeos::multidevice_setup::mojom::FeatureState::
677+
kUnavailableSuiteDisabled:
678+
return BETTER_TOGETHER_SUITE_DISABLED;
679+
case chromeos::multidevice_setup::mojom::FeatureState::
680+
kNotSupportedByPhone:
681+
FALLTHROUGH;
682+
case chromeos::multidevice_setup::mojom::FeatureState::
683+
kUnavailableNoVerifiedHost:
684+
no_available_hosts_false_positive_encountered_ = true;
685+
return NO_AVAILABLE_HOSTS;
686+
default:
687+
// Other FeatureStates:
688+
// *kNotSupportedByChromebook: Would result in TetherService not being
689+
// created at all.
690+
// *kUnavailableInsufficientSecurity: Should never occur.
691+
PA_LOG(ERROR) << "Invalid MultiDevice FeatureState: "
692+
<< tether_multidevice_state;
693+
NOTREACHED();
694+
}
667695
}
668696

697+
if (!IsAllowedByPolicy())
698+
return PROHIBITED;
699+
700+
if (!IsEnabledByPreference())
701+
return USER_PREFERENCE_DISABLED;
702+
669703
return ENABLED;
670704
}
671705

chrome/browser/chromeos/tether/tether_service.h

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ class TetherService
124124
void OnReady() override;
125125

126126
// chromeos::multidevice_setup::MultiDeviceSetupClient::Observer:
127-
void OnHostStatusChanged(
127+
void OnFeatureStatesChanged(
128128
const chromeos::multidevice_setup::MultiDeviceSetupClient::
129-
HostStatusWithDevice& host_status_with_device) override;
129+
FeatureStatesMap& feature_states_map) override;
130130

131131
// Callback when the controlling pref changes.
132132
void OnPrefsChanged();
@@ -154,6 +154,10 @@ class TetherService
154154
TestMultiDeviceSetupClientInitiallyHasNoVerifiedHost);
155155
FRIEND_TEST_ALL_PREFIXES(TetherServiceTest,
156156
TestMultiDeviceSetupClientLosesVerifiedHost);
157+
FRIEND_TEST_ALL_PREFIXES(TetherServiceTest,
158+
TestBetterTogetherSuiteInitiallyDisabled);
159+
FRIEND_TEST_ALL_PREFIXES(TetherServiceTest,
160+
TestBetterTogetherSuiteBecomesDisabled);
157161
FRIEND_TEST_ALL_PREFIXES(TetherServiceTest, TestBleAdvertisingNotSupported);
158162
FRIEND_TEST_ALL_PREFIXES(
159163
TetherServiceTest,
@@ -183,8 +187,7 @@ class TetherService
183187
FRIEND_TEST_ALL_PREFIXES(TetherServiceTest, TestMetricsFalsePositives);
184188
FRIEND_TEST_ALL_PREFIXES(TetherServiceTest, TestWifiNotPresent);
185189

186-
// Reflects InstantTethering_TechnologyStateAndReason enum in enums.xml. Do
187-
// not rearrange.
190+
// Reflects InstantTethering_FeatureState enum in enums.xml. Do not rearrange.
188191
enum TetherFeatureState {
189192
// Note: Value 0 was previously OTHER_OR_UNKNOWN, but this was a vague
190193
// description.
@@ -201,18 +204,14 @@ class TetherService
201204
BLE_NOT_PRESENT = 9,
202205
WIFI_NOT_PRESENT = 10,
203206
SUSPENDED = 11,
204-
MULTIDEVICE_HOST_UNVERIFIED = 12,
207+
BETTER_TOGETHER_SUITE_DISABLED = 12,
205208
TETHER_FEATURE_STATE_MAX
206209
};
207210

208211
// For debug logs.
209212
static std::string TetherFeatureStateToString(
210213
const TetherFeatureState& state);
211214

212-
void OnHostStatusReceived(
213-
chromeos::multidevice_setup::mojom::HostStatus host_status,
214-
const base::Optional<cryptauth::RemoteDeviceRef>& host_device);
215-
216215
void GetBluetoothAdapter();
217216
void OnBluetoothAdapterFetched(
218217
scoped_refptr<device::BluetoothAdapter> adapter);

chrome/browser/chromeos/tether/tether_service_unittest.cc

Lines changed: 86 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,8 @@ class TetherServiceTest : public chromeos::NetworkStateTest {
368368
chromeos::multidevice_setup::MultiDeviceSetupClientImpl::Factory::
369369
SetInstanceForTesting(
370370
fake_multidevice_setup_client_impl_factory_.get());
371-
initial_host_status_ =
372-
chromeos::multidevice_setup::mojom::HostStatus::kHostVerified;
373-
initial_host_device_ = test_devices_[0];
371+
initial_feature_state_ =
372+
chromeos::multidevice_setup::mojom::FeatureState::kEnabledByUser;
374373

375374
fake_cryptauth_service_ =
376375
std::make_unique<cryptauth::FakeCryptAuthService>();
@@ -453,8 +452,9 @@ class TetherServiceTest : public chromeos::NetworkStateTest {
453452
}
454453

455454
void CreateTetherService() {
456-
fake_multidevice_setup_client_->SetHostStatusWithDevice(
457-
std::make_pair(initial_host_status_, initial_host_device_));
455+
fake_multidevice_setup_client_->SetFeatureState(
456+
chromeos::multidevice_setup::mojom::Feature::kInstantTethering,
457+
initial_feature_state_);
458458

459459
tether_service_ = base::WrapUnique(new TestTetherService(
460460
profile_.get(), fake_power_manager_client_.get(),
@@ -589,8 +589,7 @@ class TetherServiceTest : public chromeos::NetworkStateTest {
589589
std::unique_ptr<cryptauth::FakeCryptAuthEnrollmentManager>
590590
fake_enrollment_manager_;
591591

592-
chromeos::multidevice_setup::mojom::HostStatus initial_host_status_;
593-
base::Optional<cryptauth::RemoteDeviceRef> initial_host_device_;
592+
chromeos::multidevice_setup::mojom::FeatureState initial_feature_state_;
594593

595594
scoped_refptr<MockExtendedBluetoothAdapter> mock_adapter_;
596595
bool is_adapter_present_;
@@ -723,9 +722,8 @@ TEST_F(TetherServiceTest,
723722
kEnableUnifiedMultiDeviceSetup} /* enabled_features */,
724723
{} /* disabled_features */);
725724

726-
initial_host_status_ =
727-
chromeos::multidevice_setup::mojom::HostStatus::kNoEligibleHosts;
728-
initial_host_device_ = base::nullopt;
725+
initial_feature_state_ = chromeos::multidevice_setup::mojom::FeatureState::
726+
kUnavailableNoVerifiedHost;
729727

730728
CreateTetherService();
731729

@@ -735,10 +733,9 @@ TEST_F(TetherServiceTest,
735733
chromeos::NetworkTypePattern::Tether()));
736734
VerifyTetherActiveStatus(false /* expected_active */);
737735

738-
fake_multidevice_setup_client_->SetHostStatusWithDevice(std::make_pair(
739-
chromeos::multidevice_setup::mojom::HostStatus::kHostVerified,
740-
test_devices_[0]));
741-
base::RunLoop().RunUntilIdle();
736+
fake_multidevice_setup_client_->SetFeatureState(
737+
chromeos::multidevice_setup::mojom::Feature::kInstantTethering,
738+
chromeos::multidevice_setup::mojom::FeatureState::kEnabledByUser);
742739

743740
EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
744741
network_state_handler()->GetTechnologyState(
@@ -765,9 +762,10 @@ TEST_F(TetherServiceTest, TestMultiDeviceSetupClientLosesVerifiedHost) {
765762
chromeos::NetworkTypePattern::Tether()));
766763
VerifyTetherActiveStatus(true /* expected_active */);
767764

768-
fake_multidevice_setup_client_->SetHostStatusWithDevice(std::make_pair(
769-
chromeos::multidevice_setup::mojom::HostStatus::kNoEligibleHosts,
770-
base::nullopt));
765+
fake_multidevice_setup_client_->SetFeatureState(
766+
chromeos::multidevice_setup::mojom::Feature::kInstantTethering,
767+
chromeos::multidevice_setup::mojom::FeatureState::
768+
kUnavailableNoVerifiedHost);
771769

772770
EXPECT_EQ(
773771
chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
@@ -777,12 +775,79 @@ TEST_F(TetherServiceTest, TestMultiDeviceSetupClientLosesVerifiedHost) {
777775

778776
ShutdownTetherService();
779777
VerifyTetherFeatureStateRecorded(
780-
TetherService::TetherFeatureState::MULTIDEVICE_HOST_UNVERIFIED,
778+
TetherService::TetherFeatureState::NO_AVAILABLE_HOSTS,
781779
1 /* expected_count */);
782780
VerifyLastShutdownReason(chromeos::tether::TetherComponent::ShutdownReason::
783781
MULTIDEVICE_HOST_UNVERIFIED);
784782
}
785783

784+
TEST_F(TetherServiceTest, TestBetterTogetherSuiteInitiallyDisabled) {
785+
base::test::ScopedFeatureList feature_list;
786+
feature_list.InitWithFeatures(
787+
{chromeos::features::kMultiDeviceApi,
788+
chromeos::features::
789+
kEnableUnifiedMultiDeviceSetup} /* enabled_features */,
790+
{} /* disabled_features */);
791+
792+
initial_feature_state_ = chromeos::multidevice_setup::mojom::FeatureState::
793+
kUnavailableSuiteDisabled;
794+
795+
CreateTetherService();
796+
797+
EXPECT_EQ(
798+
chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
799+
network_state_handler()->GetTechnologyState(
800+
chromeos::NetworkTypePattern::Tether()));
801+
VerifyTetherActiveStatus(false /* expected_active */);
802+
803+
fake_multidevice_setup_client_->SetFeatureState(
804+
chromeos::multidevice_setup::mojom::Feature::kInstantTethering,
805+
chromeos::multidevice_setup::mojom::FeatureState::kEnabledByUser);
806+
807+
EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
808+
network_state_handler()->GetTechnologyState(
809+
chromeos::NetworkTypePattern::Tether()));
810+
VerifyTetherActiveStatus(true /* expected_active */);
811+
812+
ShutdownTetherService();
813+
VerifyLastShutdownReason(
814+
chromeos::tether::TetherComponent::ShutdownReason::USER_LOGGED_OUT);
815+
}
816+
817+
TEST_F(TetherServiceTest, TestBetterTogetherSuiteBecomesDisabled) {
818+
base::test::ScopedFeatureList feature_list;
819+
feature_list.InitWithFeatures(
820+
{chromeos::features::kMultiDeviceApi,
821+
chromeos::features::
822+
kEnableUnifiedMultiDeviceSetup} /* enabled_features */,
823+
{} /* disabled_features */);
824+
825+
CreateTetherService();
826+
827+
EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
828+
network_state_handler()->GetTechnologyState(
829+
chromeos::NetworkTypePattern::Tether()));
830+
VerifyTetherActiveStatus(true /* expected_active */);
831+
832+
fake_multidevice_setup_client_->SetFeatureState(
833+
chromeos::multidevice_setup::mojom::Feature::kInstantTethering,
834+
chromeos::multidevice_setup::mojom::FeatureState::
835+
kUnavailableSuiteDisabled);
836+
837+
EXPECT_EQ(
838+
chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
839+
network_state_handler()->GetTechnologyState(
840+
chromeos::NetworkTypePattern::Tether()));
841+
VerifyTetherActiveStatus(false /* expected_active */);
842+
843+
ShutdownTetherService();
844+
VerifyTetherFeatureStateRecorded(
845+
TetherService::TetherFeatureState::BETTER_TOGETHER_SUITE_DISABLED,
846+
1 /* expected_count */);
847+
VerifyLastShutdownReason(chromeos::tether::TetherComponent::ShutdownReason::
848+
BETTER_TOGETHER_SUITE_DISABLED);
849+
}
850+
786851
TEST_F(TetherServiceTest, TestBleAdvertisingNotSupported) {
787852
mock_adapter_->set_is_ble_advertising_supported(false);
788853

@@ -960,9 +1025,9 @@ TEST_F(
9601025
ASSERT_TRUE(tether_service);
9611026

9621027
fake_multidevice_setup_client_impl_factory_->fake_multidevice_setup_client()
963-
->SetHostStatusWithDevice(std::make_pair(
964-
chromeos::multidevice_setup::mojom::HostStatus::kHostVerified,
965-
test_devices_[0]));
1028+
->SetFeatureState(
1029+
chromeos::multidevice_setup::mojom::Feature::kInstantTethering,
1030+
chromeos::multidevice_setup::mojom::FeatureState::kEnabledByUser);
9661031

9671032
base::RunLoop().RunUntilIdle();
9681033
tether_service->Shutdown();

chromeos/components/tether/tether_component.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ class TetherComponent {
3333
BLUETOOTH_DISABLED = 6,
3434
CELLULAR_DISABLED = 7,
3535
BLUETOOTH_CONTROLLER_DISAPPEARED = 8,
36-
MULTIDEVICE_HOST_UNVERIFIED = 9
36+
MULTIDEVICE_HOST_UNVERIFIED = 9,
37+
BETTER_TOGETHER_SUITE_DISABLED = 10
3738
};
3839

3940
TetherComponent();

chromeos/components/tether/tether_component_impl.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ GetSessionCompletionReasonFromShutdownReason(
5858
case TetherComponent::ShutdownReason::MULTIDEVICE_HOST_UNVERIFIED:
5959
return TetherSessionCompletionLogger::SessionCompletionReason::
6060
MULTIDEVICE_HOST_UNVERIFIED;
61+
case TetherComponent::ShutdownReason::BETTER_TOGETHER_SUITE_DISABLED:
62+
return TetherSessionCompletionLogger::SessionCompletionReason::
63+
BETTER_TOGETHER_SUITE_DISABLED;
6164
default:
6265
break;
6366
}

0 commit comments

Comments
 (0)