Skip to content

Commit

Permalink
Separate user switching check from SystemTray.
Browse files Browse the repository at this point in the history
On active user switching, a dialog is shown to confirm the user wants to
stop screen sharing sessions.

It was implemented in SystemTray, but the logic is not directly related
to SystemTray. Also, it doesn't work with UnifiedSystemTray
(--enable-features=SystemTrayUnified) which will replace old SystemTray
class.

This CL splits the dialog management to ScreenSwitchCheckController
which will be owned by ash::Shell.

Previously it was in chrome/browser/. https://crrev.com/c/665938

TEST=CanSwitchUserTest
BUG=837507

Change-Id: I50d27f079e627a212209e1a10a6c23590623624b
Reviewed-on: https://chromium-review.googlesource.com/1032453
Reviewed-by: James Cook <jamescook@chromium.org>
Reviewed-by: Evan Stade <estade@chromium.org>
Commit-Queue: Tetsui Ohkubo <tetsui@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557418}
  • Loading branch information
Tetsui Ohkubo authored and Commit Bot committed May 10, 2018
1 parent b7dcce4 commit 54d5022
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 98 deletions.
2 changes: 2 additions & 0 deletions ash/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,8 @@ component("ash") {
"system/screen_security/screen_share_observer.h",
"system/screen_security/screen_share_tray_item.cc",
"system/screen_security/screen_share_tray_item.h",
"system/screen_security/screen_switch_check_controller.cc",
"system/screen_security/screen_switch_check_controller.h",
"system/screen_security/screen_tray_item.cc",
"system/screen_security/screen_tray_item.h",
"system/session/logout_button_tray.cc",
Expand Down
7 changes: 4 additions & 3 deletions ash/session/session_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "ash/session/teleport_warning_dialog.h"
#include "ash/shell.h"
#include "ash/system/power/power_event_observer.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/screen_security/screen_switch_check_controller.h"
#include "ash/wm/lock_state_controller.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "ash/wm/window_state.h"
Expand Down Expand Up @@ -417,8 +417,9 @@ void SessionController::CanSwitchActiveUser(
if (controller->IsSelecting())
controller->ToggleOverview();

ash::Shell::Get()->GetPrimarySystemTray()->CanSwitchAwayFromActiveUser(
std::move(callback));
ash::Shell::Get()
->screen_switch_check_controller()
->CanSwitchAwayFromActiveUser(std::move(callback));
}

void SessionController::ShowMultiprofilesIntroDialog(
Expand Down
32 changes: 15 additions & 17 deletions ash/session/session_controller_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "ash/shell.h"
#include "ash/system/message_center/notification_tray.h"
#include "ash/system/screen_security/screen_tray_item.h"
#include "ash/system/tray/system_tray.h"
#include "ash/system/tray/system_tray_notifier.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "ash/wm/window_util.h"
Expand Down Expand Up @@ -559,11 +559,6 @@ class CanSwitchUserTest : public AshTestBase {

void SetUp() override {
AshTestBase::SetUp();
SystemTray* system_tray = GetPrimarySystemTray();
share_item_ = system_tray->GetScreenShareItem();
capture_item_ = system_tray->GetScreenCaptureItem();
EXPECT_TRUE(share_item_);
EXPECT_TRUE(capture_item_);
NotificationTray::DisableAnimationsForTest(true);
}

Expand All @@ -576,25 +571,33 @@ class CanSwitchUserTest : public AshTestBase {
// Accessing the capture session functionality.
// Simulates a screen capture session start.
void StartCaptureSession() {
capture_item_->Start(base::Bind(&CanSwitchUserTest::StopCaptureCallback,
base::Unretained(this)));
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStart(
base::BindRepeating(&CanSwitchUserTest::StopCaptureCallback,
base::Unretained(this)),
base::EmptyString16());
}

// The callback which gets called when the screen capture gets stopped.
void StopCaptureSession() { capture_item_->Stop(); }
void StopCaptureSession() {
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStop();
}

// Simulates a screen capture session stop.
void StopCaptureCallback() { stop_capture_callback_hit_count_++; }

// Accessing the share session functionality.
// Simulate a Screen share session start.
void StartShareSession() {
share_item_->Start(base::Bind(&CanSwitchUserTest::StopShareCallback,
base::Unretained(this)));
Shell::Get()->system_tray_notifier()->NotifyScreenShareStart(
base::BindRepeating(&CanSwitchUserTest::StopShareCallback,
base::Unretained(this)),
base::EmptyString16());
}

// Simulates a screen share session stop.
void StopShareSession() { share_item_->Stop(); }
void StopShareSession() {
Shell::Get()->system_tray_notifier()->NotifyScreenShareStop();
}

// The callback which gets called when the screen share gets stopped.
void StopShareCallback() { stop_share_callback_hit_count_++; }
Expand Down Expand Up @@ -657,11 +660,6 @@ class CanSwitchUserTest : public AshTestBase {
}
}

// The two items from the SystemTray for the screen capture / share
// functionality.
ScreenTrayItem* capture_item_ = nullptr;
ScreenTrayItem* share_item_ = nullptr;

// Various counters to query for.
int stop_capture_callback_hit_count_ = 0;
int stop_share_callback_hit_count_ = 0;
Expand Down
5 changes: 5 additions & 0 deletions ash/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
#include "ash/system/power/power_status.h"
#include "ash/system/power/video_activity_notifier.h"
#include "ash/system/screen_layout_observer.h"
#include "ash/system/screen_security/screen_switch_check_controller.h"
#include "ash/system/session/logout_button_tray.h"
#include "ash/system/session/logout_confirmation_controller.h"
#include "ash/system/status_area_widget.h"
Expand Down Expand Up @@ -862,6 +863,8 @@ Shell::~Shell() {
voice_interaction_controller_.reset();
key_accessibility_enabler_.reset();

screen_switch_check_controller_.reset();

// This also deletes all RootWindows. Note that we invoke Shutdown() on
// WindowTreeHostManager before resetting |window_tree_host_manager_|, since
// destruction of its owned RootWindowControllers relies on the value.
Expand Down Expand Up @@ -963,6 +966,8 @@ void Shell::Init(ui::ContextFactory* context_factory,
detachable_base_notification_controller_ =
std::make_unique<DetachableBaseNotificationController>(
detachable_base_handler_.get());
screen_switch_check_controller_ =
std::make_unique<ScreenSwitchCheckController>();
// Connector can be null in tests.
if (shell_delegate_->GetShellConnector() &&
base::FeatureList::IsEnabled(
Expand Down
5 changes: 5 additions & 0 deletions ash/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ class ScreenOrientationController;
class ScreenshotController;
class ScreenPinningController;
class ScreenPositionController;
class ScreenSwitchCheckController;
class SessionController;
class ShelfController;
class ShelfModel;
Expand Down Expand Up @@ -479,6 +480,9 @@ class ASH_EXPORT Shell : public SessionObserver,
ScreenPinningController* screen_pinning_controller() {
return screen_pinning_controller_.get();
}
ScreenSwitchCheckController* screen_switch_check_controller() {
return screen_switch_check_controller_.get();
}
SessionController* session_controller() { return session_controller_.get(); }
::wm::ShadowController* shadow_controller() {
return shadow_controller_.get();
Expand Down Expand Up @@ -746,6 +750,7 @@ class ASH_EXPORT Shell : public SessionObserver,
std::unique_ptr<SessionController> session_controller_;
std::unique_ptr<NightLightController> night_light_controller_;
std::unique_ptr<NoteTakingController> note_taking_controller_;
std::unique_ptr<ScreenSwitchCheckController> screen_switch_check_controller_;
std::unique_ptr<ShelfController> shelf_controller_;
std::unique_ptr<ShelfWindowWatcher> shelf_window_watcher_;
std::unique_ptr<ShellDelegate> shell_delegate_;
Expand Down
112 changes: 112 additions & 0 deletions ash/system/screen_security/screen_switch_check_controller.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/system/screen_security/screen_switch_check_controller.h"

#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/tray/system_tray_notifier.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/controls/message_box_view.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/window/dialog_delegate.h"

namespace ash {

namespace {

// Dialog that confirms the user wants to stop screen share/cast. Calls a
// callback with the result.
class CancelCastingDialog : public views::DialogDelegateView {
public:
CancelCastingDialog(base::OnceCallback<void(bool)> callback)
: callback_(std::move(callback)) {
AddChildView(new views::MessageBoxView(views::MessageBoxView::InitParams(
l10n_util::GetStringUTF16(IDS_DESKTOP_CASTING_ACTIVE_MESSAGE))));
SetLayoutManager(std::make_unique<views::FillLayout>());
}
~CancelCastingDialog() override = default;

base::string16 GetWindowTitle() const override {
return l10n_util::GetStringUTF16(IDS_DESKTOP_CASTING_ACTIVE_TITLE);
}

int GetDialogButtons() const override {
return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
}

bool Cancel() override {
std::move(callback_).Run(false);
return true;
}

bool Accept() override {
// Stop screen sharing and capturing. When notified, all capture sessions or
// all share sessions will be stopped.
// Currently, the logic is in ScreenSecurityNotificationController.
Shell::Get()->system_tray_notifier()->NotifyScreenCaptureStop();
Shell::Get()->system_tray_notifier()->NotifyScreenShareStop();

std::move(callback_).Run(true);
return true;
}

private:
base::OnceCallback<void(bool)> callback_;

DISALLOW_COPY_AND_ASSIGN(CancelCastingDialog);
};

} // namespace

ScreenSwitchCheckController::ScreenSwitchCheckController() {
Shell::Get()->system_tray_notifier()->AddScreenCaptureObserver(this);
Shell::Get()->system_tray_notifier()->AddScreenShareObserver(this);
}

ScreenSwitchCheckController::~ScreenSwitchCheckController() {
Shell::Get()->system_tray_notifier()->RemoveScreenShareObserver(this);
Shell::Get()->system_tray_notifier()->RemoveScreenCaptureObserver(this);
}

void ScreenSwitchCheckController::CanSwitchAwayFromActiveUser(
base::OnceCallback<void(bool)> callback) {
// If neither screen sharing nor capturing is going on we can immediately
// switch users.
if (!has_capture_ && !has_share_) {
std::move(callback).Run(true);
return;
}

views::DialogDelegate::CreateDialogWidget(
new CancelCastingDialog(std::move(callback)),
Shell::GetPrimaryRootWindow(), nullptr)
->Show();
}

void ScreenSwitchCheckController::OnScreenCaptureStart(
const base::Closure& stop_callback,
const base::string16& screen_capture_status) {
has_capture_ = true;
}

void ScreenSwitchCheckController::OnScreenCaptureStop() {
// Multiple screen capture sessions can exist, but they are stopped at once
// for simplicity.
has_capture_ = false;
}

void ScreenSwitchCheckController::OnScreenShareStart(
const base::Closure& stop_callback,
const base::string16& helper_name) {
has_share_ = true;
}

void ScreenSwitchCheckController::OnScreenShareStop() {
// Multiple screen share sessions can exist, but they are stopped at once for
// simplicity.
has_share_ = false;
}

} // namespace ash
46 changes: 46 additions & 0 deletions ash/system/screen_security/screen_switch_check_controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ASH_SYSTEM_SCREEN_SECURITY_SCREEN_SWITCH_CHECK_CONTROLLER_H_
#define ASH_SYSTEM_SCREEN_SECURITY_SCREEN_SWITCH_CHECK_CONTROLLER_H_

#include "ash/system/screen_security/screen_capture_observer.h"
#include "ash/system/screen_security/screen_share_observer.h"

namespace ash {

// Controller of a dialog that confirms the user wants to stop screen share/cast
// on user profile switching.
class ScreenSwitchCheckController : public ScreenCaptureObserver,
public ScreenShareObserver {
public:
ScreenSwitchCheckController();
~ScreenSwitchCheckController() override;

// Determines if it's ok to switch away from the currently active user. Screen
// casting may block this (or at least throw up a confirmation dialog). Calls
// |callback| with the result.
void CanSwitchAwayFromActiveUser(base::OnceCallback<void(bool)> callback);

private:
// ScreenCaptureObserver:
void OnScreenCaptureStart(
const base::Closure& stop_callback,
const base::string16& screen_capture_status) override;
void OnScreenCaptureStop() override;

// ScreenShareObserver:
void OnScreenShareStart(const base::Closure& stop_callback,
const base::string16& helper_name) override;
void OnScreenShareStop() override;

bool has_capture_ = false;
bool has_share_ = false;

DISALLOW_COPY_AND_ASSIGN(ScreenSwitchCheckController);
};

} // namespace ash

#endif // ASH_SYSTEM_SCREEN_SECURITY_SCREEN_SWITCH_CHECK_CONTROLLER_H_
Loading

0 comments on commit 54d5022

Please sign in to comment.