Commit c9a597b9 authored by Willie Koomson's avatar Willie Koomson Committed by Commit Bot

Add throttle observer for ARC PIP

This change adds a throttle observer that activates when
an ARC window is added to the PipContainer, and deactivates when
an ARC window is removed. This has the effect of unthrottling
ARC when an ARC PIP window is visible.

unthrottled when a YouTube app PIP window is visible.

Bug: b:142365466
Test: Unit tests; build/flash/run and check that container is
Change-Id: I496e5a6ba67e433891e98601cec50f7079addd13
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1902523
Commit-Queue: Willie Koomson <wvk@google.com>
Reviewed-by: default avatarYury Khmel <khmel@chromium.org>
Reviewed-by: default avatarYusuke Sato <yusukes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#714658}
parent acdee337
...@@ -578,6 +578,8 @@ source_set("chromeos") { ...@@ -578,6 +578,8 @@ source_set("chromeos") {
"arc/instance_throttle/arc_boot_phase_throttle_observer.h", "arc/instance_throttle/arc_boot_phase_throttle_observer.h",
"arc/instance_throttle/arc_instance_throttle.cc", "arc/instance_throttle/arc_instance_throttle.cc",
"arc/instance_throttle/arc_instance_throttle.h", "arc/instance_throttle/arc_instance_throttle.h",
"arc/instance_throttle/arc_pip_window_throttle_observer.cc",
"arc/instance_throttle/arc_pip_window_throttle_observer.h",
"arc/intent_helper/arc_external_protocol_dialog.cc", "arc/intent_helper/arc_external_protocol_dialog.cc",
"arc/intent_helper/arc_external_protocol_dialog.h", "arc/intent_helper/arc_external_protocol_dialog.h",
"arc/intent_helper/arc_intent_picker_app_fetcher.cc", "arc/intent_helper/arc_intent_picker_app_fetcher.cc",
...@@ -2539,6 +2541,7 @@ source_set("unit_tests") { ...@@ -2539,6 +2541,7 @@ source_set("unit_tests") {
"arc/instance_throttle/arc_app_launch_throttle_observer_unittest.cc", "arc/instance_throttle/arc_app_launch_throttle_observer_unittest.cc",
"arc/instance_throttle/arc_boot_phase_throttle_observer_unittest.cc", "arc/instance_throttle/arc_boot_phase_throttle_observer_unittest.cc",
"arc/instance_throttle/arc_instance_throttle_unittest.cc", "arc/instance_throttle/arc_instance_throttle_unittest.cc",
"arc/instance_throttle/arc_pip_window_throttle_observer_unittest.cc",
"arc/intent_helper/arc_external_protocol_dialog_unittest.cc", "arc/intent_helper/arc_external_protocol_dialog_unittest.cc",
"arc/intent_helper/arc_intent_picker_app_fetcher_unittest.cc", "arc/intent_helper/arc_intent_picker_app_fetcher_unittest.cc",
"arc/intent_helper/arc_settings_service_unittest.cc", "arc/intent_helper/arc_settings_service_unittest.cc",
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "chrome/browser/chromeos/arc/instance_throttle/arc_active_window_throttle_observer.h" #include "chrome/browser/chromeos/arc/instance_throttle/arc_active_window_throttle_observer.h"
#include "chrome/browser/chromeos/arc/instance_throttle/arc_app_launch_throttle_observer.h" #include "chrome/browser/chromeos/arc/instance_throttle/arc_app_launch_throttle_observer.h"
#include "chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer.h" #include "chrome/browser/chromeos/arc/instance_throttle/arc_boot_phase_throttle_observer.h"
#include "chrome/browser/chromeos/arc/instance_throttle/arc_pip_window_throttle_observer.h"
#include "components/arc/arc_browser_context_keyed_service_factory_base.h" #include "components/arc/arc_browser_context_keyed_service_factory_base.h"
#include "components/arc/arc_util.h" #include "components/arc/arc_util.h"
...@@ -78,8 +79,9 @@ ArcInstanceThrottle::ArcInstanceThrottle(content::BrowserContext* context, ...@@ -78,8 +79,9 @@ ArcInstanceThrottle::ArcInstanceThrottle(content::BrowserContext* context,
: ThrottleService(context), : ThrottleService(context),
delegate_(std::make_unique<DefaultDelegateImpl>()) { delegate_(std::make_unique<DefaultDelegateImpl>()) {
AddObserver(std::make_unique<ArcActiveWindowThrottleObserver>()); AddObserver(std::make_unique<ArcActiveWindowThrottleObserver>());
AddObserver(std::make_unique<ArcBootPhaseThrottleObserver>());
AddObserver(std::make_unique<ArcAppLaunchThrottleObserver>()); AddObserver(std::make_unique<ArcAppLaunchThrottleObserver>());
AddObserver(std::make_unique<ArcBootPhaseThrottleObserver>());
AddObserver(std::make_unique<ArcPipWindowThrottleObserver>());
StartObservers(); StartObservers();
} }
......
// Copyright 2019 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 "chrome/browser/chromeos/arc/instance_throttle/arc_pip_window_throttle_observer.h"
#include <algorithm>
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_properties.h"
#include "base/logging.h"
#include "components/arc/arc_util.h"
#include "components/exo/wm_helper.h"
#include "ui/aura/window.h"
namespace arc {
namespace {
aura::Window* GetPipContainer() {
if (!exo::WMHelper::HasInstance())
return nullptr;
auto* const wm_helper = exo::WMHelper::GetInstance();
DCHECK(wm_helper);
aura::Window* const pip_container =
wm_helper->GetPrimaryDisplayContainer(ash::kShellWindowId_PipContainer);
DCHECK(pip_container);
return pip_container;
}
} // namespace
ArcPipWindowThrottleObserver::ArcPipWindowThrottleObserver()
: ThrottleObserver(ThrottleObserver::PriorityLevel::IMPORTANT,
"ArcPipWindowIsVisible") {}
void ArcPipWindowThrottleObserver::StartObserving(
content::BrowserContext* context,
const ObserverStateChangedCallback& callback) {
ThrottleObserver::StartObserving(context, callback);
auto* const container = GetPipContainer();
if (!container) // for testing
return;
container->AddObserver(this);
}
void ArcPipWindowThrottleObserver::StopObserving() {
auto* const container = GetPipContainer();
if (!container) // for testing
return;
container->RemoveObserver(this);
ThrottleObserver::StopObserving();
}
void ArcPipWindowThrottleObserver::OnWindowAdded(aura::Window* window) {
if (IsArcAppWindow(window))
SetActive(true);
}
void ArcPipWindowThrottleObserver::OnWindowRemoved(aura::Window* window) {
// Check if there are any ARC windows left in the PipContainer. An old PIP
// window may be removed after a new one is added.
auto* const container = GetPipContainer();
if (std::none_of(container->children().begin(), container->children().end(),
&IsArcAppWindow)) {
SetActive(false);
}
}
} // namespace arc
// Copyright 2019 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 CHROME_BROWSER_CHROMEOS_ARC_INSTANCE_THROTTLE_ARC_PIP_WINDOW_THROTTLE_OBSERVER_H_
#define CHROME_BROWSER_CHROMEOS_ARC_INSTANCE_THROTTLE_ARC_PIP_WINDOW_THROTTLE_OBSERVER_H_
#include "chrome/browser/chromeos/throttle_observer.h"
#include "ui/aura/window_observer.h"
namespace content {
class BrowserContext;
}
namespace arc {
// This class observes the PIP window container and sets the state to active if
// an ARC PIP window is currently visible.
class ArcPipWindowThrottleObserver : public chromeos::ThrottleObserver,
public aura::WindowObserver {
public:
ArcPipWindowThrottleObserver();
~ArcPipWindowThrottleObserver() override = default;
ArcPipWindowThrottleObserver(const ArcPipWindowThrottleObserver&) = delete;
ArcPipWindowThrottleObserver& operator=(const ArcPipWindowThrottleObserver&) =
delete;
// chromeos::ThrottleObserver:
void StartObserving(content::BrowserContext*,
const ObserverStateChangedCallback& callback) override;
void StopObserving() override;
// aura::WindowObserver:
void OnWindowAdded(aura::Window* window) override;
void OnWindowRemoved(aura::Window* window) override;
};
} // namespace arc
#endif // CHROME_BROWSER_CHROMEOS_ARC_INSTANCE_THROTTLE_ARC_PIP_WINDOW_THROTTLE_OBSERVER_H_
// Copyright 2019 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 "chrome/browser/chromeos/arc/instance_throttle/arc_pip_window_throttle_observer.h"
#include <map>
#include "ash/public/cpp/app_types.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_properties.h"
#include "base/macros.h"
#include "base/test/task_environment.h"
#include "chrome/test/base/testing_profile.h"
#include "components/exo/wm_helper.h"
#include "components/exo/wm_helper_chromeos.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/test/test_windows.h"
namespace arc {
namespace {
class FakeWMHelper : public exo::WMHelperChromeOS {
public:
FakeWMHelper() = default;
~FakeWMHelper() override = default;
FakeWMHelper(const FakeWMHelper&) = delete;
FakeWMHelper& operator=(const FakeWMHelper&) = delete;
aura::Window* GetPrimaryDisplayContainer(int container_id) override {
return map_[container_id];
}
void SetPrimaryDisplayContainer(int container_id, aura::Window* window) {
map_[container_id] = window;
}
private:
std::map<int, aura::Window*> map_;
};
} // namespace
class ArcPipWindowThrottleObserverTest : public testing::Test {
public:
ArcPipWindowThrottleObserverTest()
: task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {}
ArcPipWindowThrottleObserverTest(const ArcPipWindowThrottleObserverTest&) =
delete;
ArcPipWindowThrottleObserverTest& operator=(
const ArcPipWindowThrottleObserverTest&) = delete;
void SetUp() override {
// Set up PipContainer
pip_container_ = aura::test::CreateTestWindowWithDelegate(
&dummy_delegate_, ash::kShellWindowId_PipContainer, gfx::Rect(),
nullptr);
wm_helper()->SetPrimaryDisplayContainer(ash::kShellWindowId_PipContainer,
pip_container_);
exo::WMHelper::SetInstance(wm_helper());
// Set up PIP windows
arc_window_ = aura::test::CreateTestWindowWithDelegate(
&dummy_delegate_, 1, gfx::Rect(), nullptr);
chrome_window_ = aura::test::CreateTestWindowWithDelegate(
&dummy_delegate_, 2, gfx::Rect(), nullptr);
arc_window_->SetProperty(aura::client::kAppType,
static_cast<int>(ash::AppType::ARC_APP));
chrome_window_->SetProperty(aura::client::kAppType,
static_cast<int>(ash::AppType::BROWSER));
}
void TearDown() override { exo::WMHelper::SetInstance(nullptr); }
protected:
ArcPipWindowThrottleObserver* observer() { return &pip_observer_; }
FakeWMHelper* wm_helper() { return &wm_helper_; }
aura::Window* pip_container() { return pip_container_; }
aura::Window* arc_window() { return arc_window_; }
aura::Window* chrome_window() { return chrome_window_; }
public:
content::BrowserTaskEnvironment task_environment_;
ArcPipWindowThrottleObserver pip_observer_;
FakeWMHelper wm_helper_;
aura::test::TestWindowDelegate dummy_delegate_;
aura::Window* pip_container_;
aura::Window* arc_window_;
aura::Window* chrome_window_;
};
TEST_F(ArcPipWindowThrottleObserverTest, TestConstructDestruct) {}
TEST_F(ArcPipWindowThrottleObserverTest, TestActiveWhileArcPipVisible) {
TestingProfile profile;
observer()->StartObserving(
&profile, ArcPipWindowThrottleObserver::ObserverStateChangedCallback());
EXPECT_FALSE(observer()->active());
// Test that observer does not activate for Chrome PIP, only for ARC PIP
pip_container()->AddChild(chrome_window());
EXPECT_FALSE(observer()->active());
pip_container()->AddChild(arc_window());
EXPECT_TRUE(observer()->active());
pip_container()->RemoveChild(chrome_window());
EXPECT_TRUE(observer()->active());
pip_container()->RemoveChild(arc_window());
EXPECT_FALSE(observer()->active());
observer()->StopObserving();
}
} // namespace arc
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