Commit 6afad750 authored by Regan Hsu's avatar Regan Hsu Committed by Commit Bot

[CrOS PhoneHub] Add implementations to OnboardingUiTrackerImpl.

OnboardingUiTracker implementation that uses the
|kHasCompletedOnboardingBefore| pref to determine whether the
Onboarding UI should be shown. This class invokes
|show_multidevice_setup_dialog_callback| when the user proceeds with
the onboarding flow if Better Together is disabled. If Better Together
is enabled, but PhoneHub is disabled, this class enables the PhoneHub
feature via the MultiDeviceSetupClient instead.

Bug: 1106937
Change-Id: I9453754edf3a51a4056bfce16a7cf8c9c409d7b7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2437732
Commit-Queue: Regan Hsu <hsuregan@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812282}
parent 6c2e935f
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/chromeos/secure_channel/secure_channel_client_provider.h" #include "chrome/browser/chromeos/secure_channel/secure_channel_client_provider.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h"
#include "chromeos/components/phonehub/notification_access_manager_impl.h" #include "chromeos/components/phonehub/notification_access_manager_impl.h"
#include "chromeos/components/phonehub/onboarding_ui_tracker_impl.h"
#include "chromeos/components/phonehub/phone_hub_manager_impl.h" #include "chromeos/components/phonehub/phone_hub_manager_impl.h"
#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_features.h"
#include "chromeos/services/multidevice_setup/public/cpp/prefs.h" #include "chromeos/services/multidevice_setup/public/cpp/prefs.h"
...@@ -80,7 +82,8 @@ KeyedService* PhoneHubManagerFactory::BuildServiceInstanceFor( ...@@ -80,7 +82,8 @@ KeyedService* PhoneHubManagerFactory::BuildServiceInstanceFor(
profile->GetPrefs(), profile->GetPrefs(),
device_sync::DeviceSyncClientFactory::GetForProfile(profile), device_sync::DeviceSyncClientFactory::GetForProfile(profile),
multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(profile), multidevice_setup::MultiDeviceSetupClientFactory::GetForProfile(profile),
secure_channel::SecureChannelClientProvider::GetInstance()->GetClient()); secure_channel::SecureChannelClientProvider::GetInstance()->GetClient(),
base::BindRepeating(&multidevice_setup::MultiDeviceSetupDialog::Show));
// Provide |phone_hub_manager| to the system tray so that it can be used by // Provide |phone_hub_manager| to the system tray so that it can be used by
// the UI. // the UI.
...@@ -96,6 +99,7 @@ bool PhoneHubManagerFactory::ServiceIsCreatedWithBrowserContext() const { ...@@ -96,6 +99,7 @@ bool PhoneHubManagerFactory::ServiceIsCreatedWithBrowserContext() const {
void PhoneHubManagerFactory::RegisterProfilePrefs( void PhoneHubManagerFactory::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) { user_prefs::PrefRegistrySyncable* registry) {
NotificationAccessManagerImpl::RegisterPrefs(registry); NotificationAccessManagerImpl::RegisterPrefs(registry);
OnboardingUiTrackerImpl::RegisterPrefs(registry);
} }
} // namespace phonehub } // namespace phonehub
......
...@@ -28,5 +28,9 @@ void FakeOnboardingUiTracker::DismissSetupUi() { ...@@ -28,5 +28,9 @@ void FakeOnboardingUiTracker::DismissSetupUi() {
SetShouldShowOnboardingUi(false); SetShouldShowOnboardingUi(false);
} }
void FakeOnboardingUiTracker::HandleGetStarted() {
++handle_get_started_call_count_;
}
} // namespace phonehub } // namespace phonehub
} // namespace chromeos } // namespace chromeos
...@@ -17,12 +17,18 @@ class FakeOnboardingUiTracker : public OnboardingUiTracker { ...@@ -17,12 +17,18 @@ class FakeOnboardingUiTracker : public OnboardingUiTracker {
void SetShouldShowOnboardingUi(bool should_show_onboarding_ui); void SetShouldShowOnboardingUi(bool should_show_onboarding_ui);
size_t handle_get_started_call_count() {
return handle_get_started_call_count_;
}
private: private:
// OnboardingUiTracker: // OnboardingUiTracker:
bool ShouldShowOnboardingUi() const override; bool ShouldShowOnboardingUi() const override;
void DismissSetupUi() override; void DismissSetupUi() override;
void HandleGetStarted() override;
bool should_show_onboarding_ui_ = false; bool should_show_onboarding_ui_ = false;
size_t handle_get_started_call_count_ = 0;
}; };
} // namespace phonehub } // namespace phonehub
......
...@@ -42,6 +42,9 @@ class OnboardingUiTracker { ...@@ -42,6 +42,9 @@ class OnboardingUiTracker {
// device. // device.
virtual void DismissSetupUi() = 0; virtual void DismissSetupUi() = 0;
// Handle for when the user clicks the get started button.
virtual void HandleGetStarted() = 0;
void AddObserver(Observer* observer); void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer); void RemoveObserver(Observer* observer);
......
...@@ -3,22 +3,89 @@ ...@@ -3,22 +3,89 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "chromeos/components/phonehub/onboarding_ui_tracker_impl.h" #include "chromeos/components/phonehub/onboarding_ui_tracker_impl.h"
#include "chromeos/components/phonehub/feature_status.h"
#include "chromeos/components/phonehub/pref_names.h"
#include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
namespace chromeos { namespace chromeos {
namespace phonehub { namespace phonehub {
OnboardingUiTrackerImpl::OnboardingUiTrackerImpl() = default; void OnboardingUiTrackerImpl::RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterBooleanPref(prefs::kHasDismissedUiAfterCompletingOnboarding,
false);
}
OnboardingUiTrackerImpl::OnboardingUiTrackerImpl(
PrefService* pref_service,
FeatureStatusProvider* feature_status_provider,
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
const base::RepeatingClosure& show_multidevice_setup_dialog_callback)
: pref_service_(pref_service),
feature_status_provider_(feature_status_provider),
multidevice_setup_client_(multidevice_setup_client),
show_multidevice_setup_dialog_callback_(
std::move(show_multidevice_setup_dialog_callback)) {
feature_status_provider_->AddObserver(this);
should_show_onboarding_ui_ = ComputeShouldShowOnboardingUi();
}
OnboardingUiTrackerImpl::~OnboardingUiTrackerImpl() = default; OnboardingUiTrackerImpl::~OnboardingUiTrackerImpl() {
feature_status_provider_->RemoveObserver(this);
}
bool OnboardingUiTrackerImpl::ShouldShowOnboardingUi() const { bool OnboardingUiTrackerImpl::ShouldShowOnboardingUi() const {
// TODO(https://crbug.com/1106937): Return a real value. return should_show_onboarding_ui_;
return false;
} }
void OnboardingUiTrackerImpl::DismissSetupUi() { void OnboardingUiTrackerImpl::DismissSetupUi() {
// TODO(https://crbug.com/1106937): Store this in a pref so that we do not pref_service_->SetBoolean(prefs::kHasDismissedUiAfterCompletingOnboarding,
// show this UI to the user again. true);
UpdateShouldShowOnboardingUi();
}
void OnboardingUiTrackerImpl::HandleGetStarted() {
FeatureStatus status = feature_status_provider_->GetStatus();
// The user is not opted into Better Together yet.
if (status == FeatureStatus::kEligiblePhoneButNotSetUp) {
show_multidevice_setup_dialog_callback_.Run();
return;
}
// The user is already opted into Better Together, but not Phone Hub.
if (status == FeatureStatus::kDisabled) {
multidevice_setup_client_->SetFeatureEnabledState(
multidevice_setup::mojom::Feature::kPhoneHub,
/*enabled=*/true, /*auth_token=*/base::nullopt, base::DoNothing());
return;
}
LOG(ERROR)
<< "Cannot handle a GetStarted request because the current state is "
<< status;
}
void OnboardingUiTrackerImpl::OnFeatureStatusChanged() {
UpdateShouldShowOnboardingUi();
}
bool OnboardingUiTrackerImpl::ComputeShouldShowOnboardingUi() {
FeatureStatus status = feature_status_provider_->GetStatus();
if (status == FeatureStatus::kEligiblePhoneButNotSetUp ||
status == FeatureStatus::kDisabled) {
return !pref_service_->GetBoolean(
prefs::kHasDismissedUiAfterCompletingOnboarding);
}
return false;
}
void OnboardingUiTrackerImpl::UpdateShouldShowOnboardingUi() {
bool should_show_onboarding_ui = ComputeShouldShowOnboardingUi();
if (should_show_onboarding_ui_ == should_show_onboarding_ui)
return;
should_show_onboarding_ui_ = should_show_onboarding_ui;
NotifyShouldShowOnboardingUiChanged();
} }
} // namespace phonehub } // namespace phonehub
......
...@@ -5,21 +5,52 @@ ...@@ -5,21 +5,52 @@
#ifndef CHROMEOS_COMPONENTS_PHONEHUB_ONBOARDING_UI_TRACKER_IMPL_H_ #ifndef CHROMEOS_COMPONENTS_PHONEHUB_ONBOARDING_UI_TRACKER_IMPL_H_
#define CHROMEOS_COMPONENTS_PHONEHUB_ONBOARDING_UI_TRACKER_IMPL_H_ #define CHROMEOS_COMPONENTS_PHONEHUB_ONBOARDING_UI_TRACKER_IMPL_H_
#include "base/callback.h"
#include "chromeos/components/phonehub/feature_status_provider.h"
#include "chromeos/components/phonehub/onboarding_ui_tracker.h" #include "chromeos/components/phonehub/onboarding_ui_tracker.h"
#include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h"
class PrefRegistrySimple;
class PrefService;
namespace chromeos { namespace chromeos {
namespace phonehub { namespace phonehub {
// TODO(https://crbug.com/1106937): Add real implementation. // OnboardingUiTracker implementation that uses the
class OnboardingUiTrackerImpl : public OnboardingUiTracker { // |kHasDismissedUiAfterCompletingOnboarding| pref to determine whether the
// Onboarding UI should be shown. This class invokes
// |show_multidevice_setup_dialog_callback| when the user proceeds with the
// onboarding flow if Better Together is disabled. If Better Together is
// enabled, but PhoneHub is disabled, this class enables the PhoneHub feature
// via the MultiDeviceSetupClient instead.
class OnboardingUiTrackerImpl : public OnboardingUiTracker,
public FeatureStatusProvider::Observer {
public: public:
OnboardingUiTrackerImpl(); static void RegisterPrefs(PrefRegistrySimple* registry);
OnboardingUiTrackerImpl(
PrefService* pref_service,
FeatureStatusProvider* feature_status_provider,
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
const base::RepeatingClosure& show_multidevice_setup_dialog_callback);
~OnboardingUiTrackerImpl() override; ~OnboardingUiTrackerImpl() override;
private:
// OnboardingUiTracker: // OnboardingUiTracker:
bool ShouldShowOnboardingUi() const override; bool ShouldShowOnboardingUi() const override;
void DismissSetupUi() override; void DismissSetupUi() override;
void HandleGetStarted() override;
private:
// FeatureStatusProvider::Observer:
void OnFeatureStatusChanged() override;
bool ComputeShouldShowOnboardingUi();
void UpdateShouldShowOnboardingUi();
PrefService* pref_service_;
FeatureStatusProvider* feature_status_provider_;
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client_;
bool should_show_onboarding_ui_;
base::RepeatingClosure show_multidevice_setup_dialog_callback_;
}; };
} // namespace phonehub } // namespace phonehub
......
...@@ -6,12 +6,22 @@ ...@@ -6,12 +6,22 @@
#include <memory> #include <memory>
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "chromeos/components/phonehub/fake_feature_status_provider.h"
#include "chromeos/components/phonehub/feature_status.h"
#include "chromeos/components/phonehub/pref_names.h"
#include "chromeos/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace chromeos { namespace chromeos {
namespace phonehub { namespace phonehub {
namespace { namespace {
using multidevice_setup::mojom::Feature;
class FakeObserver : public OnboardingUiTracker::Observer { class FakeObserver : public OnboardingUiTracker::Observer {
public: public:
FakeObserver() = default; FakeObserver() = default;
...@@ -38,26 +48,115 @@ class OnboardingUiTrackerImplTest : public testing::Test { ...@@ -38,26 +48,115 @@ class OnboardingUiTrackerImplTest : public testing::Test {
// testing::Test: // testing::Test:
void SetUp() override { void SetUp() override {
controller_ = std::make_unique<OnboardingUiTrackerImpl>(); OnboardingUiTrackerImpl::RegisterPrefs(pref_service_.registry());
fake_feature_status_provider_ =
std::make_unique<FakeFeatureStatusProvider>();
controller_ = std::make_unique<OnboardingUiTrackerImpl>(
&pref_service_, fake_feature_status_provider_.get(),
&fake_multidevice_setup_client_,
base::BindRepeating(
&OnboardingUiTrackerImplTest::ShowMultideviceSetupDialog,
base::Unretained(this)));
controller_->AddObserver(&fake_observer_); controller_->AddObserver(&fake_observer_);
} }
void TearDown() override { controller_->RemoveObserver(&fake_observer_); } void TearDown() override { controller_->RemoveObserver(&fake_observer_); }
void ShowMultideviceSetupDialog() { ++setup_dialog_shown_count_; }
size_t setup_dialog_shown_count() { return setup_dialog_shown_count_; }
void SetStatus(FeatureStatus feature_status) {
fake_feature_status_provider_->SetStatus(feature_status);
}
void DismissSetupUi() { controller_->DismissSetupUi(); }
bool ShouldShowOnboardingUi() const { bool ShouldShowOnboardingUi() const {
return controller_->ShouldShowOnboardingUi(); return controller_->ShouldShowOnboardingUi();
} }
size_t GetNumObserverCalls() const { return fake_observer_.num_calls(); } size_t GetNumObserverCalls() const { return fake_observer_.num_calls(); }
void HandleGetStarted() { controller_->HandleGetStarted(); }
void InvokePendingSetFeatureEnabledStateCallback(bool expected_enabled) {
fake_multidevice_setup_client_.InvokePendingSetFeatureEnabledStateCallback(
Feature::kPhoneHub, expected_enabled, base::nullopt, true);
}
size_t GetOnShouldShowOnboardingUiChangedCallCount() {
return fake_observer_.num_calls();
}
private: private:
size_t setup_dialog_shown_count_ = 0;
TestingPrefServiceSimple pref_service_;
multidevice_setup::FakeMultiDeviceSetupClient fake_multidevice_setup_client_;
std::unique_ptr<FakeFeatureStatusProvider> fake_feature_status_provider_;
FakeObserver fake_observer_; FakeObserver fake_observer_;
std::unique_ptr<OnboardingUiTracker> controller_; std::unique_ptr<OnboardingUiTracker> controller_;
}; };
// TODO(https://crbug.com/1106937): Remove this test once we have real TEST_F(OnboardingUiTrackerImplTest, ShouldShowUiWhenEligiblePhoneButNotSetup) {
// functionality to test. SetStatus(FeatureStatus::kNotEligibleForFeature);
TEST_F(OnboardingUiTrackerImplTest, Initialize) { EXPECT_EQ(GetOnShouldShowOnboardingUiChangedCallCount(), 0U);
SetStatus(FeatureStatus::kEligiblePhoneButNotSetUp);
EXPECT_EQ(GetOnShouldShowOnboardingUiChangedCallCount(), 1U);
EXPECT_TRUE(ShouldShowOnboardingUi());
// User clicks get started button.
EXPECT_EQ(setup_dialog_shown_count(), 0U);
HandleGetStarted();
EXPECT_EQ(setup_dialog_shown_count(), 1U);
EXPECT_EQ(GetOnShouldShowOnboardingUiChangedCallCount(), 1U);
// User dismisses setup flow. After dismissal, ShouldShowOnboardingUi() should
// always be false.
DismissSetupUi();
EXPECT_EQ(GetOnShouldShowOnboardingUiChangedCallCount(), 2U);
EXPECT_FALSE(ShouldShowOnboardingUi());
// User clicks the get started button a second time; should still open.
EXPECT_EQ(setup_dialog_shown_count(), 1U);
HandleGetStarted();
EXPECT_EQ(setup_dialog_shown_count(), 2U);
EXPECT_EQ(GetOnShouldShowOnboardingUiChangedCallCount(), 2U);
// User dismisses setup flow a second time.
DismissSetupUi();
EXPECT_EQ(GetOnShouldShowOnboardingUiChangedCallCount(), 2U);
EXPECT_FALSE(ShouldShowOnboardingUi());
}
TEST_F(OnboardingUiTrackerImplTest, ShouldShowUiWhenDisabled) {
SetStatus(FeatureStatus::kNotEligibleForFeature);
EXPECT_EQ(GetOnShouldShowOnboardingUiChangedCallCount(), 0U);
SetStatus(FeatureStatus::kDisabled);
EXPECT_EQ(GetOnShouldShowOnboardingUiChangedCallCount(), 1U);
EXPECT_TRUE(ShouldShowOnboardingUi());
// User clicks get started button.
HandleGetStarted();
InvokePendingSetFeatureEnabledStateCallback(true);
EXPECT_EQ(GetOnShouldShowOnboardingUiChangedCallCount(), 1U);
// User dismisses setup flow. After dismissal, ShouldShowOnboardingUi() should
// always be false.
DismissSetupUi();
EXPECT_EQ(GetOnShouldShowOnboardingUiChangedCallCount(), 2U);
EXPECT_FALSE(ShouldShowOnboardingUi());
// User clicks the get started button a second time; should still open.
HandleGetStarted();
InvokePendingSetFeatureEnabledStateCallback(true);
EXPECT_EQ(GetOnShouldShowOnboardingUiChangedCallCount(), 2U);
// User dismisses setup flow a second time.
DismissSetupUi();
EXPECT_EQ(GetOnShouldShowOnboardingUiChangedCallCount(), 2U);
EXPECT_FALSE(ShouldShowOnboardingUi()); EXPECT_FALSE(ShouldShowOnboardingUi());
} }
......
...@@ -24,7 +24,8 @@ PhoneHubManagerImpl::PhoneHubManagerImpl( ...@@ -24,7 +24,8 @@ PhoneHubManagerImpl::PhoneHubManagerImpl(
PrefService* pref_service, PrefService* pref_service,
device_sync::DeviceSyncClient* device_sync_client, device_sync::DeviceSyncClient* device_sync_client,
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
chromeos::secure_channel::SecureChannelClient* secure_channel_client) chromeos::secure_channel::SecureChannelClient* secure_channel_client,
const base::RepeatingClosure& show_multidevice_setup_dialog_callback)
: do_not_disturb_controller_( : do_not_disturb_controller_(
std::make_unique<DoNotDisturbControllerImpl>()), std::make_unique<DoNotDisturbControllerImpl>()),
connection_manager_( connection_manager_(
...@@ -47,7 +48,11 @@ PhoneHubManagerImpl::PhoneHubManagerImpl( ...@@ -47,7 +48,11 @@ PhoneHubManagerImpl::PhoneHubManagerImpl(
notification_access_manager_( notification_access_manager_(
std::make_unique<NotificationAccessManagerImpl>(pref_service)), std::make_unique<NotificationAccessManagerImpl>(pref_service)),
notification_manager_(std::make_unique<NotificationManagerImpl>()), notification_manager_(std::make_unique<NotificationManagerImpl>()),
onboarding_ui_tracker_(std::make_unique<OnboardingUiTrackerImpl>()), onboarding_ui_tracker_(std::make_unique<OnboardingUiTrackerImpl>(
pref_service,
feature_status_provider_.get(),
multidevice_setup_client,
show_multidevice_setup_dialog_callback)),
phone_model_(std::make_unique<MutablePhoneModel>()), phone_model_(std::make_unique<MutablePhoneModel>()),
tether_controller_( tether_controller_(
std::make_unique<TetherControllerImpl>(multidevice_setup_client)) {} std::make_unique<TetherControllerImpl>(multidevice_setup_client)) {}
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include "base/callback.h"
#include "chromeos/components/phonehub/phone_hub_manager.h" #include "chromeos/components/phonehub/phone_hub_manager.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
...@@ -39,7 +40,8 @@ class PhoneHubManagerImpl : public PhoneHubManager, public KeyedService { ...@@ -39,7 +40,8 @@ class PhoneHubManagerImpl : public PhoneHubManager, public KeyedService {
PrefService* pref_service, PrefService* pref_service,
device_sync::DeviceSyncClient* device_sync_client, device_sync::DeviceSyncClient* device_sync_client,
multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client, multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client,
chromeos::secure_channel::SecureChannelClient* secure_channel_client); chromeos::secure_channel::SecureChannelClient* secure_channel_client,
const base::RepeatingClosure& show_multidevice_setup_dialog_callback);
~PhoneHubManagerImpl() override; ~PhoneHubManagerImpl() override;
// PhoneHubManager: // PhoneHubManager:
......
...@@ -12,6 +12,10 @@ namespace prefs { ...@@ -12,6 +12,10 @@ namespace prefs {
const char kNotificationAccessGranted[] = const char kNotificationAccessGranted[] =
"cros.phonehub.notification_access_granted"; "cros.phonehub.notification_access_granted";
// Whether user has completed onboarding and dismissed the UI before.
const char kHasDismissedUiAfterCompletingOnboarding[] =
"cros.phonehub.has_completed_onboarding_before";
} // namespace prefs } // namespace prefs
} // namespace phonehub } // namespace phonehub
} // namespace chromeos } // namespace chromeos
...@@ -10,6 +10,7 @@ namespace phonehub { ...@@ -10,6 +10,7 @@ namespace phonehub {
namespace prefs { namespace prefs {
extern const char kNotificationAccessGranted[]; extern const char kNotificationAccessGranted[];
extern const char kHasDismissedUiAfterCompletingOnboarding[];
} // namespace prefs } // namespace prefs
} // namespace phonehub } // namespace phonehub
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment