Commit 1def3a36 authored by Curt Clemens's avatar Curt Clemens Committed by Commit Bot

[NearbyShare] Implement NearbyShareDelegate

This delegate provides access to the NearbySharingService from //ash.
It will be used to implement a pod button in the system tray that
toggles high visibility mode.

Bug: 154866703
Test: unit_tests
Change-Id: Icc6b84b6af0ba350d01a0a92e844f4dd2249600f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2405439
Commit-Queue: Curt Clemens <cclem@google.com>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Reviewed-by: default avatarJames Vecore <vecore@google.com>
Cr-Commit-Position: refs/heads/master@{#809017}
parent a1ed9449
......@@ -23,15 +23,14 @@ class ASH_PUBLIC_EXPORT NearbyShareDelegate {
virtual ~NearbyShareDelegate() = default;
// Used by the pod button to determine whether it should be visible.
virtual bool IsPodButtonVisible() const = 0;
virtual bool IsPodButtonVisible() = 0;
// Gets the current high visibility state from the NearbySharingService.
virtual bool IsHighVisibilityOn() const = 0;
virtual bool IsHighVisibilityOn() = 0;
// If high visibility is on, returns the remaining duration until the delegate
// will turn it off, or nullopt if high visibility is off.
virtual base::Optional<base::TimeDelta> RemainingHighVisibilityTime()
const = 0;
virtual base::Optional<base::TimeDelta> RemainingHighVisibilityTime() = 0;
// Request high visibility be turned on. If Nearby Share is disabled in prefs,
// this will instead redirect the user to onboarding.
......
......@@ -10,16 +10,16 @@ TestNearbyShareDelegate::TestNearbyShareDelegate() = default;
TestNearbyShareDelegate::~TestNearbyShareDelegate() = default;
bool TestNearbyShareDelegate::IsPodButtonVisible() const {
bool TestNearbyShareDelegate::IsPodButtonVisible() {
return false;
}
bool TestNearbyShareDelegate::IsHighVisibilityOn() const {
bool TestNearbyShareDelegate::IsHighVisibilityOn() {
return false;
}
base::Optional<base::TimeDelta>
TestNearbyShareDelegate::RemainingHighVisibilityTime() const {
TestNearbyShareDelegate::RemainingHighVisibilityTime() {
return base::nullopt;
}
......
......@@ -20,9 +20,9 @@ class ASH_PUBLIC_EXPORT TestNearbyShareDelegate : public NearbyShareDelegate {
TestNearbyShareDelegate& operator=(TestNearbyShareDelegate&) = delete;
// NearbyShareDelegate
bool IsPodButtonVisible() const override;
bool IsHighVisibilityOn() const override;
base::Optional<base::TimeDelta> RemainingHighVisibilityTime() const override;
bool IsPodButtonVisible() override;
bool IsHighVisibilityOn() override;
base::Optional<base::TimeDelta> RemainingHighVisibilityTime() override;
void EnableHighVisibility() override;
void DisableHighVisibility() override;
void ShowNearbyShareSettings() const override;
......
......@@ -804,6 +804,11 @@ Shell::~Shell() {
// Similarly for PrivacyScreenController.
privacy_screen_controller_ = nullptr;
// NearbyShareDelegateImpl must be destroyed before SessionController and
// NearbyShareControllerImpl.
nearby_share_delegate_.reset();
nearby_share_controller_.reset();
// Stop observing window activation changes before closing all windows.
focus_controller_->RemoveObserver(this);
......@@ -1157,8 +1162,9 @@ void Shell::Init(
// to initialize itself.
shelf_config_->Init();
nearby_share_delegate_ = shell_delegate_->CreateNearbyShareDelegate();
nearby_share_controller_ = std::make_unique<NearbyShareControllerImpl>();
nearby_share_delegate_ = shell_delegate_->CreateNearbyShareDelegate(
nearby_share_controller_.get());
system_notification_controller_ =
std::make_unique<SystemNotificationController>();
......
......@@ -34,6 +34,7 @@ class CaptureModeDelegate;
class ScreenshotDelegate;
class BackGestureContextualNudgeDelegate;
class BackGestureContextualNudgeController;
class NearbyShareController;
class NearbyShareDelegate;
// Delegate of the Shell.
......@@ -61,8 +62,8 @@ class ASH_EXPORT ShellDelegate {
CreateBackGestureContextualNudgeDelegate(
BackGestureContextualNudgeController* controller) = 0;
virtual std::unique_ptr<ash::NearbyShareDelegate> CreateNearbyShareDelegate()
const = 0;
virtual std::unique_ptr<NearbyShareDelegate> CreateNearbyShareDelegate(
NearbyShareController* controller) const = 0;
// Check whether the current tab of the browser window can go back.
virtual bool CanGoBack(gfx::NativeWindow window) const = 0;
......
......@@ -72,7 +72,8 @@ void TestShellDelegate::SetShouldWaitForTouchAck(
}
std::unique_ptr<NearbyShareDelegate>
TestShellDelegate::CreateNearbyShareDelegate() const {
TestShellDelegate::CreateNearbyShareDelegate(
NearbyShareController* controller) const {
return std::make_unique<TestNearbyShareDelegate>();
}
......
......@@ -47,8 +47,8 @@ class TestShellDelegate : public ShellDelegate {
mojo::PendingReceiver<
chromeos::multidevice_setup::mojom::MultiDeviceSetup> receiver)
override;
std::unique_ptr<NearbyShareDelegate> CreateNearbyShareDelegate()
const override;
std::unique_ptr<NearbyShareDelegate> CreateNearbyShareDelegate(
NearbyShareController* controller) const override;
void SetCanGoBack(bool can_go_back);
void SetShouldWaitForTouchAck(bool should_wait_for_touch_ack);
......
......@@ -4,30 +4,66 @@
#include "chrome/browser/nearby_sharing/nearby_share_delegate_impl.h"
#include "ash/public/cpp/nearby_share_controller.h"
#include "ash/public/cpp/session/session_controller.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/time.h"
#include "chrome/browser/nearby_sharing/logging/logging.h"
#include "chrome/browser/nearby_sharing/nearby_sharing_service.h"
#include "chrome/browser/nearby_sharing/nearby_sharing_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/ash/session_util.h"
#include "chrome/browser/ui/settings_window_manager_chromeos.h"
#include "chrome/browser/ui/webui/settings/chromeos/constants/routes.mojom.h"
NearbyShareDelegateImpl::NearbyShareDelegateImpl() = default;
namespace {
NearbyShareDelegateImpl::~NearbyShareDelegateImpl() = default;
const char kStartReceivingQueryParam[] = "receive";
const char kStopReceivingQueryParam[] = "stop_receiving";
bool NearbyShareDelegateImpl::IsPodButtonVisible() const {
constexpr base::TimeDelta kShutoffTimeout = base::TimeDelta::FromMinutes(5);
constexpr base::TimeDelta kOnboardingWaitTimeout =
base::TimeDelta::FromMinutes(5);
constexpr base::TimeDelta kOneMinute = base::TimeDelta::FromSeconds(60);
constexpr base::TimeDelta kOneSecond = base::TimeDelta::FromSeconds(1);
std::string GetTimestampString() {
return base::NumberToString(
base::Time::Now().ToDeltaSinceWindowsEpoch().InMicroseconds());
}
} // namespace
NearbyShareDelegateImpl::NearbyShareDelegateImpl(
ash::NearbyShareController* nearby_share_controller)
: nearby_share_controller_(nearby_share_controller),
settings_opener_(std::make_unique<SettingsOpener>()),
shutoff_timer_(
FROM_HERE,
kShutoffTimeout,
base::BindRepeating(&NearbyShareDelegateImpl::OnShutoffTimerFired,
base::Unretained(this))),
onboarding_wait_timer_(FROM_HERE,
kOnboardingWaitTimeout,
base::BindRepeating([]() {})) {
ash::SessionController::Get()->AddObserver(this);
}
NearbyShareDelegateImpl::~NearbyShareDelegateImpl() {
ash::SessionController::Get()->RemoveObserver(this);
}
bool NearbyShareDelegateImpl::IsPodButtonVisible() {
return GetService() != nullptr;
}
bool NearbyShareDelegateImpl::IsHighVisibilityOn() const {
bool NearbyShareDelegateImpl::IsHighVisibilityOn() {
NearbySharingService* service = GetService();
return service && service->IsInHighVisibility();
}
base::Optional<base::TimeDelta>
NearbyShareDelegateImpl::RemainingHighVisibilityTime() const {
NearbyShareDelegateImpl::RemainingHighVisibilityTime() {
if (!IsHighVisibilityOn())
return base::nullopt;
......@@ -35,25 +71,114 @@ NearbyShareDelegateImpl::RemainingHighVisibilityTime() const {
}
void NearbyShareDelegateImpl::EnableHighVisibility() {
NOTIMPLEMENTED();
NearbySharingService* service = GetService();
if (!service)
return;
settings_opener_->ShowSettingsPage(kStartReceivingQueryParam);
if (!service->GetSettings()->GetEnabled()) {
onboarding_wait_timer_.Reset();
if (!settings_receiver_.is_bound()) {
service->GetSettings()->AddSettingsObserver(
settings_receiver_.BindNewPipeAndPassRemote());
}
}
}
void NearbyShareDelegateImpl::DisableHighVisibility() {
NOTIMPLEMENTED();
NearbySharingService* service = GetService();
if (!service)
return;
shutoff_timer_.Stop();
countdown_timer_.Stop();
settings_opener_->ShowSettingsPage(kStopReceivingQueryParam);
}
void NearbyShareDelegateImpl::OnLockStateChanged(bool locked) {
if (locked && IsHighVisibilityOn()) {
DisableHighVisibility();
}
}
NearbySharingService* NearbyShareDelegateImpl::GetService() const {
void NearbyShareDelegateImpl::OnEnabledChanged(bool enabled) {
if (enabled && onboarding_wait_timer_.IsRunning()) {
onboarding_wait_timer_.Stop();
EnableHighVisibility();
}
}
void NearbyShareDelegateImpl::OnHighVisibilityChanged(bool high_visibility_on) {
nearby_share_controller_->HighVisibilityEnabledChanged(high_visibility_on);
if (high_visibility_on) {
shutoff_time_ = base::TimeTicks::Now() + kShutoffTimeout;
shutoff_timer_.Reset();
countdown_timer_.Start(
FROM_HERE, kOneMinute,
base::BindRepeating(&NearbyShareDelegateImpl::OnCountdownTimerFired,
base::Unretained(this)));
OnCountdownTimerFired();
} else {
shutoff_timer_.Stop();
countdown_timer_.Stop();
}
}
void NearbyShareDelegateImpl::OnShutdown() {
settings_receiver_.reset();
}
void NearbyShareDelegateImpl::OnShutoffTimerFired() {
DisableHighVisibility();
}
void NearbyShareDelegateImpl::OnCountdownTimerFired() {
base::Optional<base::TimeDelta> remaining_time =
RemainingHighVisibilityTime();
if (!remaining_time)
return;
if (countdown_timer_.GetCurrentDelay() > kOneSecond &&
*remaining_time < kOneMinute) {
countdown_timer_.Stop();
countdown_timer_.Start(
FROM_HERE, kOneSecond,
base::BindRepeating(&NearbyShareDelegateImpl::OnCountdownTimerFired,
base::Unretained(this)));
}
nearby_share_controller_->HighVisibilityCountdownUpdate(*remaining_time);
}
NearbySharingService* NearbyShareDelegateImpl::GetService() {
if (nearby_share_service_for_test_) {
return nearby_share_service_for_test_;
}
return NearbySharingServiceFactory::GetForBrowserContext(
ProfileManager::GetPrimaryUserProfile());
}
void NearbyShareDelegateImpl::ShowNearbyShareSettings() const {
settings_opener_->ShowSettingsPage(
chromeos::settings::mojom::kNearbyShareSubpagePath);
settings_opener_->ShowSettingsPage("");
}
void NearbyShareDelegateImpl::SettingsOpener::ShowSettingsPage(
const std::string& sub_page) {
std::string query_string;
if (!sub_page.empty()) {
// Append a timestamp to make the url unique per-call. Otherwise, settings
// will not respond to successive calls if the url does not change.
query_string += "?" + sub_page + "&time=" + GetTimestampString();
}
chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(
ProfileManager::GetActiveUserProfile(), sub_page);
ProfileManager::GetPrimaryUserProfile(),
std::string(chromeos::settings::mojom::kNearbyShareSubpagePath) +
query_string);
}
......@@ -9,8 +9,15 @@
#include <string>
#include "ash/public/cpp/nearby_share_delegate.h"
#include "ash/public/cpp/session/session_observer.h"
#include "base/timer/timer.h"
#include "chrome/browser/nearby_sharing/nearby_sharing_service.h"
#include "chrome/browser/ui/webui/nearby_share/public/mojom/nearby_share_settings.mojom.h"
#include "mojo/public/cpp/bindings/receiver.h"
class NearbySharingService;
namespace ash {
class NearbyShareController;
} // namespace ash
namespace base {
class TimeDelta;
......@@ -20,7 +27,11 @@ class TimeTicks;
// Delegate injected into |ash::Shell| to provide a communication channel
// between the system tray and the |NearbyShareService|. Singleton owned by the
// Shell, lives on the UI thread.
class NearbyShareDelegateImpl : public ash::NearbyShareDelegate {
class NearbyShareDelegateImpl
: public ash::NearbyShareDelegate,
public ash::SessionObserver,
public nearby_share::mojom::NearbyShareSettingsObserver,
public ::NearbySharingService::Observer {
public:
// For testing. Allows overriding |ShowSettingsPage|.
class SettingsOpener {
......@@ -35,26 +46,73 @@ class NearbyShareDelegateImpl : public ash::NearbyShareDelegate {
virtual void ShowSettingsPage(const std::string& sub_page);
};
NearbyShareDelegateImpl();
explicit NearbyShareDelegateImpl(
ash::NearbyShareController* nearby_share_controller);
NearbyShareDelegateImpl(NearbyShareDelegateImpl&) = delete;
NearbyShareDelegateImpl& operator=(NearbyShareDelegateImpl&) = delete;
~NearbyShareDelegateImpl() override;
// ash::NearbyShareDelegate
bool IsPodButtonVisible() const override;
bool IsHighVisibilityOn() const override;
base::Optional<base::TimeDelta> RemainingHighVisibilityTime() const override;
bool IsPodButtonVisible() override;
bool IsHighVisibilityOn() override;
base::Optional<base::TimeDelta> RemainingHighVisibilityTime() override;
void EnableHighVisibility() override;
void DisableHighVisibility() override;
void ShowNearbyShareSettings() const override;
// ash::SessionObserver
void OnLockStateChanged(bool locked) override;
// nearby_share::mojom::NearbyShareSettingsObserver
void OnEnabledChanged(bool enabled) override;
void OnDeviceNameChanged(const std::string& device_name) override {}
void OnDataUsageChanged(nearby_share::mojom::DataUsage data_usage) override {}
void OnVisibilityChanged(
nearby_share::mojom::Visibility visibility) override {}
void OnAllowedContactsChanged(
const std::vector<std::string>& visible_contact_ids) override {}
// NearbyShareService::Observer
void OnHighVisibilityChanged(bool high_visibility_on) override;
void OnShutdown() override;
void set_nearby_share_service_for_test(NearbySharingService* service) {
nearby_share_service_for_test_ = service;
}
void set_settings_opener_for_test(
std::unique_ptr<SettingsOpener> settings_opener) {
settings_opener_ = std::move(settings_opener);
}
private:
NearbySharingService* GetService() const;
void OnShutoffTimerFired();
void OnCountdownTimerFired();
// Fetch the NearbySharingService using the primary profile. Will return null
// if the service does not exist yet, which may be the case since the delegate
// is constructed before the service.
NearbySharingService* GetService();
ash::NearbyShareController* const nearby_share_controller_;
NearbySharingService* nearby_share_service_for_test_ = nullptr;
std::unique_ptr<SettingsOpener> settings_opener_;
base::RetainingOneShotTimer shutoff_timer_;
base::RepeatingTimer countdown_timer_;
// If Nearby Share is not enabled when |EnableHighVisibility| is called, then
// onboarding will be opened instead. If Nearby Share is enabled within a
// time window after |EnableHighVisibility| is called, then high visibility
// will be enabled. This tracks whether we are currently in that window.
base::RetainingOneShotTimer onboarding_wait_timer_;
// The time when high visibility is scheduled to be shut off.
base::TimeTicks shutoff_time_;
mojo::Receiver<nearby_share::mojom::NearbyShareSettingsObserver>
settings_receiver_{this};
};
#endif // CHROME_BROWSER_NEARBY_SHARING_NEARBY_SHARE_DELEGATE_IMPL_H_
......@@ -8,6 +8,7 @@
#include "ash/public/cpp/session/session_controller.h"
#include "base/time/clock.h"
#include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h"
#include "chrome/browser/nearby_sharing/local_device_data/fake_nearby_share_local_device_data_manager.h"
#include "chrome/browser/nearby_sharing/mock_nearby_sharing_service.h"
#include "chrome/browser/nearby_sharing/nearby_share_settings.h"
#include "chrome/browser/ui/ash/test_session_controller.h"
......@@ -15,6 +16,11 @@
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::_;
using ::testing::AtLeast;
using ::testing::Return;
using ::testing::ReturnPointee;
class MockSettingsOpener : public NearbyShareDelegateImpl::SettingsOpener {
public:
MOCK_METHOD(void, ShowSettingsPage, (const std::string&), (override));
......@@ -33,7 +39,18 @@ class MockNearbyShareController : public ash::NearbyShareController {
class NearbyShareDelegateImplTest : public ::testing::Test {
public:
NearbyShareDelegateImplTest()
: task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
: task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
settings_(&test_pref_service_, &test_local_device_data_),
delegate_(&controller_) {
RegisterNearbySharingPrefs(test_pref_service_.registry());
delegate_.set_nearby_share_service_for_test(&nearby_share_service_);
std::unique_ptr<MockSettingsOpener> settings_opener =
std::make_unique<MockSettingsOpener>();
settings_opener_ = settings_opener.get();
delegate_.set_settings_opener_for_test(std::move(settings_opener));
}
~NearbyShareDelegateImplTest() override = default;
......@@ -44,34 +61,132 @@ class NearbyShareDelegateImplTest : public ::testing::Test {
task_environment_.FastForwardBy(delta);
}
void SetHighVisibilityOn(bool high_visibility_on) {
if (high_visibility_on_ != high_visibility_on) {
high_visibility_on_ = high_visibility_on;
delegate_.OnHighVisibilityChanged(high_visibility_on);
}
}
void SetUp() override {
settings_.SetEnabled(false);
EXPECT_CALL(nearby_share_service_, GetSettings())
.WillRepeatedly(Return(&settings_));
EXPECT_CALL(nearby_share_service_, IsInHighVisibility())
.WillRepeatedly(ReturnPointee(&high_visibility_on_));
}
protected:
content::BrowserTaskEnvironment task_environment_;
MockNearbySharingService nearby_share_service_;
TestSessionController session_controller_;
sync_preferences::TestingPrefServiceSyncable test_pref_service_;
FakeNearbyShareLocalDeviceDataManager test_local_device_data_;
NearbyShareSettings settings_;
MockSettingsOpener* settings_opener_;
MockNearbyShareController controller_;
NearbyShareDelegateImpl delegate_;
bool high_visibility_on_ = false;
};
TEST_F(NearbyShareDelegateImplTest, StartHighVisibilityAndTimeout) {
// TODO(cclem)
settings_.SetEnabled(true);
EXPECT_CALL(*settings_opener_, ShowSettingsPage(_));
EXPECT_CALL(controller_, HighVisibilityEnabledChanged(true));
EXPECT_CALL(controller_, HighVisibilityCountdownUpdate(_)).Times(AtLeast(1));
delegate_.EnableHighVisibility();
SetHighVisibilityOn(true);
EXPECT_CALL(*settings_opener_, ShowSettingsPage(_));
EXPECT_CALL(controller_, HighVisibilityEnabledChanged(false));
// DisableHighVisibility will be called automatically after the timer fires.
FastForward(base::TimeDelta::FromMinutes(10));
SetHighVisibilityOn(false);
}
TEST_F(NearbyShareDelegateImplTest, StartStopHighVisibility) {
// TODO(cclem)
settings_.SetEnabled(true);
EXPECT_CALL(*settings_opener_, ShowSettingsPage(_));
EXPECT_CALL(controller_, HighVisibilityEnabledChanged(true));
EXPECT_CALL(controller_, HighVisibilityCountdownUpdate(_)).Times(AtLeast(1));
delegate_.EnableHighVisibility();
SetHighVisibilityOn(true);
EXPECT_CALL(*settings_opener_, ShowSettingsPage(_));
EXPECT_CALL(controller_, HighVisibilityEnabledChanged(false));
delegate_.DisableHighVisibility();
SetHighVisibilityOn(false);
}
TEST_F(NearbyShareDelegateImplTest, ShowOnboardingAndTurnOnHighVisibility) {
// TODO(cclem)
settings_.SetEnabled(false);
// Called once to start onboarding, once to enter high visibility, and once to
// exit high visibility.
EXPECT_CALL(*settings_opener_, ShowSettingsPage(_)).Times(3);
delegate_.EnableHighVisibility();
EXPECT_CALL(controller_, HighVisibilityEnabledChanged(true));
// Delegate will observe Nearby Share enabled within onboarding wait period
// and will turn on high visibility.
settings_.SetEnabled(true);
SetHighVisibilityOn(true);
EXPECT_CALL(controller_, HighVisibilityEnabledChanged(false));
// DisableHighVisibility will be called automatically after the timer fires.
FastForward(base::TimeDelta::FromMinutes(10));
SetHighVisibilityOn(false);
}
TEST_F(NearbyShareDelegateImplTest, ShowOnboardingAndTimeout) {
// TODO(cclem)
settings_.SetEnabled(false);
EXPECT_CALL(nearby_share_service_, GetSettings())
.WillRepeatedly(Return(&settings_));
EXPECT_CALL(*settings_opener_, ShowSettingsPage(_));
delegate_.EnableHighVisibility();
EXPECT_CALL(controller_, HighVisibilityEnabledChanged(_)).Times(0);
// Wait for longer than the onboarding wait period.
FastForward(base::TimeDelta::FromMinutes(10));
// Delegate will observe Nearby Share enabled outside of onboarding wait
// period and will not turn on high visibility.
settings_.SetEnabled(true);
}
TEST_F(NearbyShareDelegateImplTest, StopHighVisibilityOnScreenLock) {
// TODO(cclem)
settings_.SetEnabled(true);
EXPECT_CALL(controller_, HighVisibilityEnabledChanged(true));
EXPECT_CALL(controller_, HighVisibilityCountdownUpdate(_)).Times(AtLeast(1));
EXPECT_CALL(*settings_opener_, ShowSettingsPage(_));
delegate_.EnableHighVisibility();
SetHighVisibilityOn(true);
EXPECT_CALL(controller_, HighVisibilityEnabledChanged(false));
EXPECT_CALL(*settings_opener_, ShowSettingsPage(_));
// DisableHighVisibility will be called when the screen locks.
delegate_.OnLockStateChanged(/*locked=*/true);
SetHighVisibilityOn(false);
}
TEST_F(NearbyShareDelegateImplTest, ShowNearbyShareSettings) {
// TODO(cclem)
EXPECT_CALL(*settings_opener_, ShowSettingsPage(_));
delegate_.ShowNearbyShareSettings();
}
......@@ -202,6 +202,7 @@ ChromeShellDelegate::CreateBackGestureContextualNudgeDelegate(
}
std::unique_ptr<ash::NearbyShareDelegate>
ChromeShellDelegate::CreateNearbyShareDelegate() const {
return std::make_unique<NearbyShareDelegateImpl>();
ChromeShellDelegate::CreateNearbyShareDelegate(
ash::NearbyShareController* controller) const {
return std::make_unique<NearbyShareDelegateImpl>(controller);
}
......@@ -45,8 +45,8 @@ class ChromeShellDelegate : public ash::ShellDelegate {
chromeos::multidevice_setup::mojom::MultiDeviceSetup> receiver)
override;
media_session::mojom::MediaSessionService* GetMediaSessionService() override;
std::unique_ptr<ash::NearbyShareDelegate> CreateNearbyShareDelegate()
const override;
std::unique_ptr<ash::NearbyShareDelegate> CreateNearbyShareDelegate(
ash::NearbyShareController* controller) const override;
private:
DISALLOW_COPY_AND_ASSIGN(ChromeShellDelegate);
......
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