[Lacros] Add ResourceManager crosapi
Add the ResourceManager crosapi to provide resource usage from Ash to Lacros. And add the Lacros memory pressure evaluator to trigger memory pressure events when receiving MemoryPressureObserver messages. Details of the ResourceManager crosapi: 1. Ash provides the ResourceManager interface for Lacros registering MemoryPressureObserver. 2. Lacros provides the MemoryPressureObserver interface for Ash sending memory pressure status. Bug: b/190130454 Change-Id: I42a281c6ada3ab407bf8e2fd11e26136d808d946 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2952547 Reviewed-by: Chris Hamilton <chrisha@chromium.org> Reviewed-by: Hidehiko Abe <hidehiko@chromium.org> Commit-Queue: Kuo-Hsin Yang <vovoy@chromium.org> Cr-Commit-Position: refs/heads/master@{#894027}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
baa09e5aeb
commit
dbcf8076a8
chrome
browser
BUILD.gn
ash
crosapi
lacros
chrome_browser_main_extra_parts_lacros.ccchrome_browser_main_extra_parts_lacros.hlacros_memory_pressure_evaluator.cclacros_memory_pressure_evaluator.hlacros_memory_pressure_evaluator_unittest.cc
resource_coordinator
test
chromeos
components/performance_manager
@ -4763,6 +4763,8 @@ static_library("browser") {
|
||||
"lacros/immersive_context_lacros.h",
|
||||
"lacros/lacros_chrome_service_delegate_impl.cc",
|
||||
"lacros/lacros_chrome_service_delegate_impl.h",
|
||||
"lacros/lacros_memory_pressure_evaluator.cc",
|
||||
"lacros/lacros_memory_pressure_evaluator.h",
|
||||
"lacros/lacros_prefs.cc",
|
||||
"lacros/lacros_prefs.h",
|
||||
"lacros/lacros_startup_infobar_delegate.cc",
|
||||
|
@ -71,6 +71,8 @@ source_set("crosapi") {
|
||||
"prefs_ash.h",
|
||||
"remoting_ash.cc",
|
||||
"remoting_ash.h",
|
||||
"resource_manager_ash.cc",
|
||||
"resource_manager_ash.h",
|
||||
"screen_manager_ash.cc",
|
||||
"screen_manager_ash.h",
|
||||
"select_file_ash.cc",
|
||||
@ -115,6 +117,7 @@ source_set("crosapi") {
|
||||
"//chromeos/crosapi/mojom",
|
||||
"//chromeos/cryptohome",
|
||||
"//chromeos/dbus/power",
|
||||
"//chromeos/dbus/resourced",
|
||||
"//chromeos/dbus/session_manager",
|
||||
"//chromeos/dbus/upstart",
|
||||
"//chromeos/dbus/userdataauth:userdataauth_proto",
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "base/version.h"
|
||||
#include "chrome/browser/ash/crosapi/idle_service_ash.h"
|
||||
#include "chrome/browser/ash/crosapi/native_theme_service_ash.h"
|
||||
#include "chrome/browser/ash/crosapi/resource_manager_ash.h"
|
||||
#include "chrome/browser/ash/profiles/profile_helper.h"
|
||||
#include "chrome/browser/ash/settings/device_settings_service.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
@ -256,6 +257,7 @@ constexpr InterfaceVersionEntry kInterfaceVersionEntries[] = {
|
||||
MakeInterfaceVersionEntry<crosapi::mojom::Power>(),
|
||||
MakeInterfaceVersionEntry<crosapi::mojom::Prefs>(),
|
||||
MakeInterfaceVersionEntry<crosapi::mojom::Remoting>(),
|
||||
MakeInterfaceVersionEntry<crosapi::mojom::ResourceManager>(),
|
||||
MakeInterfaceVersionEntry<crosapi::mojom::ScreenManager>(),
|
||||
MakeInterfaceVersionEntry<crosapi::mojom::SnapshotCapturer>(),
|
||||
MakeInterfaceVersionEntry<crosapi::mojom::SystemDisplay>(),
|
||||
@ -285,7 +287,7 @@ constexpr bool HasDuplicatedUuid() {
|
||||
}
|
||||
|
||||
static_assert(
|
||||
crosapi::mojom::Crosapi::Version_ == 35,
|
||||
crosapi::mojom::Crosapi::Version_ == 36,
|
||||
"if you add a new crosapi, please add it to kInterfaceVersionEntries");
|
||||
static_assert(!HasDuplicatedUuid(),
|
||||
"Each Crosapi Mojom interface should have unique UUID.");
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "chrome/browser/ash/crosapi/power_ash.h"
|
||||
#include "chrome/browser/ash/crosapi/prefs_ash.h"
|
||||
#include "chrome/browser/ash/crosapi/remoting_ash.h"
|
||||
#include "chrome/browser/ash/crosapi/resource_manager_ash.h"
|
||||
#include "chrome/browser/ash/crosapi/screen_manager_ash.h"
|
||||
#include "chrome/browser/ash/crosapi/select_file_ash.h"
|
||||
#include "chrome/browser/ash/crosapi/system_display_ash.h"
|
||||
@ -113,6 +114,7 @@ CrosapiAsh::CrosapiAsh()
|
||||
std::make_unique<PrefsAsh>(g_browser_process->profile_manager(),
|
||||
g_browser_process->local_state())),
|
||||
remoting_ash_(std::make_unique<RemotingAsh>()),
|
||||
resource_manager_ash_(std::make_unique<ResourceManagerAsh>()),
|
||||
screen_manager_ash_(std::make_unique<ScreenManagerAsh>()),
|
||||
select_file_ash_(std::make_unique<SelectFileAsh>()),
|
||||
system_display_ash_(std::make_unique<SystemDisplayAsh>()),
|
||||
@ -323,6 +325,11 @@ void CrosapiAsh::BindRemoting(mojo::PendingReceiver<mojom::Remoting> receiver) {
|
||||
remoting_ash_->BindReceiver(std::move(receiver));
|
||||
}
|
||||
|
||||
void CrosapiAsh::BindResourceManager(
|
||||
mojo::PendingReceiver<mojom::ResourceManager> receiver) {
|
||||
resource_manager_ash_->BindReceiver(std::move(receiver));
|
||||
}
|
||||
|
||||
void CrosapiAsh::BindUrlHandler(
|
||||
mojo::PendingReceiver<mojom::UrlHandler> receiver) {
|
||||
url_handler_ash_->BindReceiver(std::move(receiver));
|
||||
|
@ -38,6 +38,7 @@ class NativeThemeServiceAsh;
|
||||
class PowerAsh;
|
||||
class PrefsAsh;
|
||||
class RemotingAsh;
|
||||
class ResourceManagerAsh;
|
||||
class ScreenManagerAsh;
|
||||
class SelectFileAsh;
|
||||
class SystemDisplayAsh;
|
||||
@ -101,6 +102,8 @@ class CrosapiAsh : public mojom::Crosapi {
|
||||
void BindPower(mojo::PendingReceiver<mojom::Power> receiver) override;
|
||||
void BindPrefs(mojo::PendingReceiver<mojom::Prefs> receiver) override;
|
||||
void BindRemoting(mojo::PendingReceiver<mojom::Remoting> receiver) override;
|
||||
void BindResourceManager(
|
||||
mojo::PendingReceiver<mojom::ResourceManager> receiver) override;
|
||||
void BindScreenManager(
|
||||
mojo::PendingReceiver<mojom::ScreenManager> receiver) override;
|
||||
void BindSelectFile(
|
||||
@ -185,6 +188,7 @@ class CrosapiAsh : public mojom::Crosapi {
|
||||
std::unique_ptr<PowerAsh> power_ash_;
|
||||
std::unique_ptr<PrefsAsh> prefs_ash_;
|
||||
std::unique_ptr<RemotingAsh> remoting_ash_;
|
||||
std::unique_ptr<ResourceManagerAsh> resource_manager_ash_;
|
||||
std::unique_ptr<ScreenManagerAsh> screen_manager_ash_;
|
||||
std::unique_ptr<SelectFileAsh> select_file_ash_;
|
||||
std::unique_ptr<SystemDisplayAsh> system_display_ash_;
|
||||
|
47
chrome/browser/ash/crosapi/resource_manager_ash.cc
Normal file
47
chrome/browser/ash/crosapi/resource_manager_ash.cc
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2021 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/ash/crosapi/resource_manager_ash.h"
|
||||
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
|
||||
namespace crosapi {
|
||||
|
||||
// ResourceManagerAsh
|
||||
|
||||
ResourceManagerAsh::ResourceManagerAsh() {
|
||||
chromeos::ResourcedClient* client = chromeos::ResourcedClient::Get();
|
||||
if (client)
|
||||
client->AddObserver(this);
|
||||
}
|
||||
|
||||
ResourceManagerAsh::~ResourceManagerAsh() {
|
||||
chromeos::ResourcedClient* client = chromeos::ResourcedClient::Get();
|
||||
if (client)
|
||||
client->RemoveObserver(this);
|
||||
}
|
||||
|
||||
void ResourceManagerAsh::BindReceiver(
|
||||
mojo::PendingReceiver<mojom::ResourceManager> receiver) {
|
||||
receivers_.Add(this, std::move(receiver));
|
||||
}
|
||||
|
||||
void ResourceManagerAsh::OnMemoryPressure(
|
||||
chromeos::ResourcedClient::PressureLevel level,
|
||||
uint64_t reclaim_target_kb) {
|
||||
for (auto& observer : observers_) {
|
||||
mojom::MemoryPressurePtr pressure = mojom::MemoryPressure::New();
|
||||
pressure->level = static_cast<mojom::MemoryPressureLevel>(level);
|
||||
pressure->reclaim_target_kb = reclaim_target_kb;
|
||||
observer->MemoryPressure(std::move(pressure));
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceManagerAsh::AddMemoryPressureObserver(
|
||||
mojo::PendingRemote<mojom::MemoryPressureObserver> observer) {
|
||||
mojo::Remote<mojom::MemoryPressureObserver> remote(std::move(observer));
|
||||
observers_.Add(std::move(remote));
|
||||
}
|
||||
|
||||
} // namespace crosapi
|
47
chrome/browser/ash/crosapi/resource_manager_ash.h
Normal file
47
chrome/browser/ash/crosapi/resource_manager_ash.h
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2021 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_ASH_CROSAPI_RESOURCE_MANAGER_ASH_H_
|
||||
#define CHROME_BROWSER_ASH_CROSAPI_RESOURCE_MANAGER_ASH_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "chromeos/crosapi/mojom/resource_manager.mojom.h"
|
||||
#include "chromeos/dbus/resourced/resourced_client.h"
|
||||
#include "mojo/public/cpp/bindings/receiver_set.h"
|
||||
#include "mojo/public/cpp/bindings/remote_set.h"
|
||||
|
||||
namespace crosapi {
|
||||
|
||||
// The ash-chrome implementation of the ResourceManager crosapi interface.
|
||||
// This class must only be used from the main thread.
|
||||
class ResourceManagerAsh : public mojom::ResourceManager,
|
||||
public chromeos::ResourcedClient::Observer {
|
||||
public:
|
||||
ResourceManagerAsh();
|
||||
ResourceManagerAsh(const ResourceManagerAsh&) = delete;
|
||||
ResourceManagerAsh& operator=(const ResourceManagerAsh&) = delete;
|
||||
~ResourceManagerAsh() override;
|
||||
|
||||
void BindReceiver(mojo::PendingReceiver<mojom::ResourceManager> receiver);
|
||||
|
||||
// chromeos::ResourcedClient::Observer:
|
||||
void OnMemoryPressure(chromeos::ResourcedClient::PressureLevel level,
|
||||
uint64_t reclaim_target_kb) override;
|
||||
|
||||
// crosapi::mojom::ResourceManager:
|
||||
void AddMemoryPressureObserver(
|
||||
mojo::PendingRemote<mojom::MemoryPressureObserver> observer) override;
|
||||
|
||||
private:
|
||||
// Support any number of connections.
|
||||
mojo::ReceiverSet<mojom::ResourceManager> receivers_;
|
||||
|
||||
// Support any number of memory pressure observers.
|
||||
mojo::RemoteSet<mojom::MemoryPressureObserver> observers_;
|
||||
};
|
||||
|
||||
} // namespace crosapi
|
||||
|
||||
#endif // CHROME_BROWSER_ASH_CROSAPI_RESOURCE_MANAGER_ASH_H_
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "chrome/browser/lacros/automation_manager_lacros.h"
|
||||
#include "chrome/browser/lacros/download_controller_client_lacros.h"
|
||||
#include "chrome/browser/lacros/lacros_memory_pressure_evaluator.h"
|
||||
#include "chrome/browser/lacros/task_manager_lacros.h"
|
||||
#include "chrome/browser/lacros/web_page_info_lacros.h"
|
||||
|
||||
@ -21,4 +22,11 @@ void ChromeBrowserMainExtraPartsLacros::PostBrowserStart() {
|
||||
task_manager_provider_ = std::make_unique<crosapi::TaskManagerLacros>();
|
||||
web_page_info_provider_ =
|
||||
std::make_unique<crosapi::WebPageInfoProviderLacros>();
|
||||
|
||||
base::MemoryPressureMonitor* monitor = base::MemoryPressureMonitor::Get();
|
||||
if (monitor) {
|
||||
pressure_evaluator_ = std::make_unique<LacrosMemoryPressureEvaluator>(
|
||||
static_cast<util::MultiSourceMemoryPressureMonitor*>(monitor)
|
||||
->CreateVoter());
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
class AutomationManagerLacros;
|
||||
class DownloadControllerClientLacros;
|
||||
class LacrosMemoryPressureEvaluator;
|
||||
|
||||
namespace crosapi {
|
||||
class TaskManagerLacros;
|
||||
@ -41,6 +42,9 @@ class ChromeBrowserMainExtraPartsLacros : public ChromeBrowserMainExtraParts {
|
||||
|
||||
// Handles tab property requests from ash.
|
||||
std::unique_ptr<crosapi::WebPageInfoProviderLacros> web_page_info_provider_;
|
||||
|
||||
// Evaluates memory pressure level.
|
||||
std::unique_ptr<LacrosMemoryPressureEvaluator> pressure_evaluator_;
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_LACROS_CHROME_BROWSER_MAIN_EXTRA_PARTS_LACROS_H_
|
||||
|
103
chrome/browser/lacros/lacros_memory_pressure_evaluator.cc
Normal file
103
chrome/browser/lacros/lacros_memory_pressure_evaluator.cc
Normal file
@ -0,0 +1,103 @@
|
||||
// Copyright 2021 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/lacros/lacros_memory_pressure_evaluator.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
#include "chromeos/lacros/lacros_service.h"
|
||||
|
||||
namespace {
|
||||
// Pointer to the LacrosMemoryPressureEvaluator used by TabManagerDelegate for
|
||||
// chromeos to need to call into ScheduleEarlyCheck.
|
||||
LacrosMemoryPressureEvaluator* g_lacros_evaluator = nullptr;
|
||||
|
||||
// We try not to re-notify on moderate too frequently, this time
|
||||
// controls how frequently we will notify after our first notification.
|
||||
constexpr base::TimeDelta kModerateMemoryPressureCooldownTime =
|
||||
base::TimeDelta::FromSeconds(10);
|
||||
|
||||
} // namespace
|
||||
|
||||
LacrosMemoryPressureEvaluator::LacrosMemoryPressureEvaluator(
|
||||
std::unique_ptr<util::MemoryPressureVoter> voter)
|
||||
: util::SystemMemoryPressureEvaluator(std::move(voter)) {
|
||||
DCHECK(g_lacros_evaluator == nullptr);
|
||||
g_lacros_evaluator = this;
|
||||
|
||||
chromeos::LacrosService* service = chromeos::LacrosService::Get();
|
||||
// Check LacrosService availability to avoid crashing
|
||||
// lacros_chrome_browsertests.
|
||||
if (!service || !service->IsAvailable<crosapi::mojom::ResourceManager>()) {
|
||||
LOG(ERROR) << "ResourceManager is not available";
|
||||
return;
|
||||
}
|
||||
service->GetRemote<crosapi::mojom::ResourceManager>()
|
||||
->AddMemoryPressureObserver(receiver_.BindNewPipeAndPassRemote());
|
||||
}
|
||||
|
||||
LacrosMemoryPressureEvaluator::~LacrosMemoryPressureEvaluator() {
|
||||
DCHECK(g_lacros_evaluator == this);
|
||||
g_lacros_evaluator = nullptr;
|
||||
}
|
||||
|
||||
// static
|
||||
LacrosMemoryPressureEvaluator* LacrosMemoryPressureEvaluator::Get() {
|
||||
return g_lacros_evaluator;
|
||||
}
|
||||
|
||||
uint64_t LacrosMemoryPressureEvaluator::GetCachedReclaimTargetKB() {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
return cached_reclaim_target_kb_;
|
||||
}
|
||||
|
||||
bool LacrosMemoryPressureEvaluator::ShouldNotify(
|
||||
const base::MemoryPressureListener::MemoryPressureLevel old_vote,
|
||||
const base::MemoryPressureListener::MemoryPressureLevel new_vote) {
|
||||
switch (new_vote) {
|
||||
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
|
||||
return false;
|
||||
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: {
|
||||
// Moderate memory pressure notification advises modules to free buffers
|
||||
// that are cheap to re-allocate and not immediately needed. We may be in
|
||||
// this state for quite some time. Throttle the moderate notification to
|
||||
// avoid freeing unused buffers too often. Throttling is also necessary
|
||||
// when the vote is changed from critical or none to moderate.
|
||||
return last_moderate_notification_.is_null() ||
|
||||
(base::TimeTicks::Now() > last_moderate_notification_ +
|
||||
kModerateMemoryPressureCooldownTime);
|
||||
}
|
||||
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void LacrosMemoryPressureEvaluator::MemoryPressure(
|
||||
crosapi::mojom::MemoryPressurePtr pressure) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
|
||||
base::MemoryPressureListener::MemoryPressureLevel listener_level;
|
||||
if (pressure->level == crosapi::mojom::MemoryPressureLevel::kCritical) {
|
||||
listener_level =
|
||||
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL;
|
||||
cached_reclaim_target_kb_ = pressure->reclaim_target_kb;
|
||||
} else if (pressure->level ==
|
||||
crosapi::mojom::MemoryPressureLevel::kModerate) {
|
||||
listener_level =
|
||||
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE;
|
||||
cached_reclaim_target_kb_ = 0;
|
||||
} else {
|
||||
listener_level = base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE;
|
||||
cached_reclaim_target_kb_ = 0;
|
||||
}
|
||||
|
||||
bool notify = ShouldNotify(current_vote(), listener_level);
|
||||
if (notify &&
|
||||
current_vote() ==
|
||||
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE)
|
||||
last_moderate_notification_ = base::TimeTicks::Now();
|
||||
|
||||
SetCurrentVote(listener_level);
|
||||
SendCurrentVote(notify);
|
||||
}
|
59
chrome/browser/lacros/lacros_memory_pressure_evaluator.h
Normal file
59
chrome/browser/lacros/lacros_memory_pressure_evaluator.h
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright 2021 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_LACROS_LACROS_MEMORY_PRESSURE_EVALUATOR_H_
|
||||
#define CHROME_BROWSER_LACROS_LACROS_MEMORY_PRESSURE_EVALUATOR_H_
|
||||
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/util/memory_pressure/memory_pressure_voter.h"
|
||||
#include "base/util/memory_pressure/system_memory_pressure_evaluator.h"
|
||||
#include "chromeos/crosapi/mojom/resource_manager.mojom.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
|
||||
// LacrosMemoryPressureEvaluator handles the observation of our free memory. It
|
||||
// notifies the MemoryPressureListener of memory fill level changes, so that it
|
||||
// can take action to reduce memory resources accordingly.
|
||||
class LacrosMemoryPressureEvaluator
|
||||
: public util::SystemMemoryPressureEvaluator,
|
||||
public crosapi::mojom::MemoryPressureObserver {
|
||||
public:
|
||||
explicit LacrosMemoryPressureEvaluator(
|
||||
std::unique_ptr<util::MemoryPressureVoter> voter);
|
||||
~LacrosMemoryPressureEvaluator() override;
|
||||
|
||||
LacrosMemoryPressureEvaluator(const LacrosMemoryPressureEvaluator&) = delete;
|
||||
LacrosMemoryPressureEvaluator& operator=(
|
||||
const LacrosMemoryPressureEvaluator&) = delete;
|
||||
|
||||
// Returns the current system memory pressure evaluator.
|
||||
static LacrosMemoryPressureEvaluator* Get();
|
||||
|
||||
// Returns the cached amount of memory to reclaim.
|
||||
// TODO: Lacros tab manager delegate will use this value to determine how many
|
||||
// tabs to discard.
|
||||
uint64_t GetCachedReclaimTargetKB();
|
||||
|
||||
// Implements mojom::MemoryPressureObserver.
|
||||
void MemoryPressure(crosapi::mojom::MemoryPressurePtr pressure) override;
|
||||
|
||||
private:
|
||||
bool ShouldNotify(
|
||||
const base::MemoryPressureListener::MemoryPressureLevel old_vote,
|
||||
const base::MemoryPressureListener::MemoryPressureLevel current_vote);
|
||||
|
||||
uint64_t cached_reclaim_target_kb_{0};
|
||||
|
||||
// We keep track of how long it has been since we last notified at the
|
||||
// moderate level. It's initialized to a null value to indicate there is no
|
||||
// previous moderate notification.
|
||||
base::TimeTicks last_moderate_notification_;
|
||||
|
||||
mojo::Receiver<crosapi::mojom::MemoryPressureObserver> receiver_{this};
|
||||
|
||||
SEQUENCE_CHECKER(sequence_checker_);
|
||||
|
||||
base::WeakPtrFactory<LacrosMemoryPressureEvaluator> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
#endif // CHROME_BROWSER_LACROS_LACROS_MEMORY_PRESSURE_EVALUATOR_H_
|
@ -0,0 +1,92 @@
|
||||
// Copyright 2021 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/lacros/lacros_memory_pressure_evaluator.h"
|
||||
|
||||
#include "base/test/task_environment.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Processes PressureCallback calls by just storing the sequence of events so we
|
||||
// can validate that we received the expected pressure levels as the test runs.
|
||||
void PressureCallback(
|
||||
std::vector<base::MemoryPressureListener::MemoryPressureLevel>* history,
|
||||
base::MemoryPressureListener::MemoryPressureLevel level) {
|
||||
history->push_back(level);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(LacrosMemoryPressureEvaluatorTest, CheckMemoryPressure) {
|
||||
base::test::TaskEnvironment task_environment(
|
||||
base::test::TaskEnvironment::MainThreadType::UI);
|
||||
|
||||
// We will use a mock listener to keep track of our kernel notifications which
|
||||
// cause event to be fired. We can just examine the sequence of pressure
|
||||
// events when we're done to validate that the pressure events were as
|
||||
// expected.
|
||||
std::vector<base::MemoryPressureListener::MemoryPressureLevel>
|
||||
pressure_events;
|
||||
auto listener = std::make_unique<base::MemoryPressureListener>(
|
||||
FROM_HERE, base::BindRepeating(&PressureCallback, &pressure_events));
|
||||
|
||||
util::MultiSourceMemoryPressureMonitor monitor;
|
||||
monitor.ResetSystemEvaluatorForTesting();
|
||||
|
||||
auto evaluator =
|
||||
std::make_unique<LacrosMemoryPressureEvaluator>(monitor.CreateVoter());
|
||||
|
||||
// At this point we have no memory pressure.
|
||||
ASSERT_EQ(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
|
||||
evaluator->current_vote());
|
||||
|
||||
// Moderate Pressure.
|
||||
crosapi::mojom::MemoryPressurePtr pressure =
|
||||
crosapi::mojom::MemoryPressure::New();
|
||||
pressure->level = crosapi::mojom::MemoryPressureLevel::kModerate;
|
||||
pressure->reclaim_target_kb = 1000;
|
||||
evaluator->MemoryPressure(pressure->Clone());
|
||||
base::RunLoop().RunUntilIdle();
|
||||
ASSERT_EQ(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
|
||||
evaluator->current_vote());
|
||||
|
||||
// Critical Pressure.
|
||||
pressure->level = crosapi::mojom::MemoryPressureLevel::kCritical;
|
||||
evaluator->MemoryPressure(pressure->Clone());
|
||||
base::RunLoop().RunUntilIdle();
|
||||
ASSERT_EQ(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
|
||||
evaluator->current_vote());
|
||||
|
||||
// Moderate Pressure.
|
||||
pressure->level = crosapi::mojom::MemoryPressureLevel::kModerate;
|
||||
evaluator->MemoryPressure(pressure->Clone());
|
||||
base::RunLoop().RunUntilIdle();
|
||||
ASSERT_EQ(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
|
||||
evaluator->current_vote());
|
||||
|
||||
// No pressure, note: this will not cause any event.
|
||||
pressure->level = crosapi::mojom::MemoryPressureLevel::kNone;
|
||||
pressure->reclaim_target_kb = 0;
|
||||
evaluator->MemoryPressure(pressure->Clone());
|
||||
base::RunLoop().RunUntilIdle();
|
||||
ASSERT_EQ(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
|
||||
evaluator->current_vote());
|
||||
|
||||
// Back into moderate.
|
||||
pressure->level = crosapi::mojom::MemoryPressureLevel::kModerate;
|
||||
pressure->reclaim_target_kb = 1000;
|
||||
evaluator->MemoryPressure(pressure->Clone());
|
||||
base::RunLoop().RunUntilIdle();
|
||||
ASSERT_EQ(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
|
||||
evaluator->current_vote());
|
||||
|
||||
// Now our events should be MODERATE, CRITICAL, MODERATE.
|
||||
ASSERT_EQ(2u, pressure_events.size());
|
||||
ASSERT_EQ(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
|
||||
pressure_events[0]);
|
||||
ASSERT_EQ(base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
|
||||
pressure_events[1]);
|
||||
// Subsequent moderate notifications are throttled.
|
||||
}
|
@ -171,8 +171,7 @@ void TabManager::Start() {
|
||||
|
||||
// MemoryPressureMonitor is not implemented on Linux so far and tabs are never
|
||||
// discarded.
|
||||
#if defined(OS_WIN) || defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) || \
|
||||
BUILDFLAG(IS_CHROMEOS_LACROS)
|
||||
#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_CHROMEOS)
|
||||
// Don't handle memory pressure events here if this is done by
|
||||
// PerformanceManager.
|
||||
if (!base::FeatureList::IsEnabled(
|
||||
@ -255,7 +254,7 @@ void TabManager::DiscardTabFromMemoryPressure() {
|
||||
DCHECK(!base::FeatureList::IsEnabled(
|
||||
performance_manager::features::kUrgentDiscardingFromPerformanceManager));
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
#ifdef OS_CHROMEOS
|
||||
// Output a log with per-process memory usage and number of file descriptors,
|
||||
// as well as GPU memory details. Discard happens without waiting for the log
|
||||
// (https://crbug.com/850545) Per comment at
|
||||
@ -264,7 +263,7 @@ void TabManager::DiscardTabFromMemoryPressure() {
|
||||
// platforms since it is not used and data shows it can create IO thread hangs
|
||||
// (https://crbug.com/1040522).
|
||||
memory::OomMemoryDetails::Log("Tab Discards Memory details");
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
|
||||
#endif // OS_CHROMEOS
|
||||
|
||||
// Start handling memory pressure. Suppress further notifications before
|
||||
// completion in case a slow handler queues up multiple dispatches of this
|
||||
|
@ -6003,6 +6003,7 @@ test("unit_tests") {
|
||||
sources += [
|
||||
"../browser/lacros/client_cert_store_lacros_unittest.cc",
|
||||
"../browser/lacros/lacros_chrome_service_delegate_impl_unittest.cc",
|
||||
"../browser/lacros/lacros_memory_pressure_evaluator_unittest.cc",
|
||||
"../browser/lacros/metrics_reporting_observer_unittest.cc",
|
||||
"../browser/metrics/lacros_metrics_provider_unittest.cc",
|
||||
"../browser/notifications/notification_platform_bridge_lacros_unittest.cc",
|
||||
|
@ -33,6 +33,7 @@ mojom("mojom") {
|
||||
"power.mojom",
|
||||
"prefs.mojom",
|
||||
"remoting.mojom",
|
||||
"resource_manager.mojom",
|
||||
"screen_manager.mojom",
|
||||
"select_file.mojom",
|
||||
"system_display.mojom",
|
||||
|
@ -27,6 +27,7 @@ import "chromeos/crosapi/mojom/native_theme.mojom";
|
||||
import "chromeos/crosapi/mojom/power.mojom";
|
||||
import "chromeos/crosapi/mojom/prefs.mojom";
|
||||
import "chromeos/crosapi/mojom/remoting.mojom";
|
||||
import "chromeos/crosapi/mojom/resource_manager.mojom";
|
||||
import "chromeos/crosapi/mojom/screen_manager.mojom";
|
||||
import "chromeos/crosapi/mojom/select_file.mojom";
|
||||
import "chromeos/crosapi/mojom/system_display.mojom";
|
||||
@ -64,8 +65,8 @@ struct BrowserInfo {
|
||||
// please note the milestone when you added it, to help us reason about
|
||||
// compatibility between the client applications and older ash-chrome binaries.
|
||||
//
|
||||
// Next version: 36
|
||||
// Next method id: 41
|
||||
// Next version: 37
|
||||
// Next method id: 42
|
||||
[Stable, Uuid="8b79c34f-2bf8-4499-979a-b17cac522c1e",
|
||||
RenamedFrom="crosapi.mojom.AshChromeService"]
|
||||
interface Crosapi {
|
||||
@ -229,6 +230,11 @@ interface Crosapi {
|
||||
// Added in M93.
|
||||
[MinVersion=35] BindPower@40(pending_receiver<Power> receiver);
|
||||
|
||||
// Binds the Resource Manager interface for querying resource status.
|
||||
// Added in M93.
|
||||
[MinVersion=36] BindResourceManager@41(
|
||||
pending_receiver<ResourceManager> receiver);
|
||||
|
||||
// Binds the System Display interface for querying display info.
|
||||
// Added in M92.
|
||||
[MinVersion=24] BindSystemDisplay@29(
|
||||
|
38
chromeos/crosapi/mojom/resource_manager.mojom
Normal file
38
chromeos/crosapi/mojom/resource_manager.mojom
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
module crosapi.mojom;
|
||||
|
||||
// Memory pressure level corresponding to MemoryPressureLevel in
|
||||
// base/memory/memory_pressure_listener.h
|
||||
[Stable, Extensible]
|
||||
enum MemoryPressureLevel {
|
||||
kNone = 0,
|
||||
kModerate = 1,
|
||||
kCritical = 2,
|
||||
};
|
||||
|
||||
// Memory pressure status.
|
||||
[Stable]
|
||||
struct MemoryPressure {
|
||||
MemoryPressureLevel level@0;
|
||||
|
||||
// The amount of memory to reclaim to reduce the memory pressure level.
|
||||
uint64 reclaim_target_kb@1;
|
||||
};
|
||||
|
||||
// Interface for memory pressure observers. Implemented by lacros-chrome. Used
|
||||
// by ash-chrome to send memory pressure status.
|
||||
[Stable, Uuid="51b994bb-278f-4df3-9393-2732f2a0dcb3"]
|
||||
interface MemoryPressureObserver {
|
||||
// Called when memory pressure status changes.
|
||||
MemoryPressure@0(MemoryPressure pressure);
|
||||
};
|
||||
|
||||
// Interface to manage chrome resource, e.g. Memory. Implemented by ash-chrome.
|
||||
[Stable, Uuid="3908db1e-304d-4615-a331-f2f262745bc3"]
|
||||
interface ResourceManager {
|
||||
// Adds an observer for memory pressure status.
|
||||
AddMemoryPressureObserver@0(pending_remote<MemoryPressureObserver> observer);
|
||||
};
|
@ -34,6 +34,7 @@
|
||||
#include "chromeos/crosapi/mojom/power.mojom.h"
|
||||
#include "chromeos/crosapi/mojom/prefs.mojom.h"
|
||||
#include "chromeos/crosapi/mojom/remoting.mojom.h"
|
||||
#include "chromeos/crosapi/mojom/resource_manager.mojom.h"
|
||||
#include "chromeos/crosapi/mojom/screen_manager.mojom.h"
|
||||
#include "chromeos/crosapi/mojom/select_file.mojom.h"
|
||||
#include "chromeos/crosapi/mojom/system_display.mojom.h"
|
||||
@ -265,6 +266,9 @@ LacrosChromeServiceImpl::LacrosChromeServiceImpl(
|
||||
ConstructRemote<crosapi::mojom::Remoting,
|
||||
&crosapi::mojom::Crosapi::BindRemoting,
|
||||
Crosapi::MethodMinVersions::kBindRemotingMinVersion>();
|
||||
ConstructRemote<crosapi::mojom::ResourceManager,
|
||||
&crosapi::mojom::Crosapi::BindResourceManager,
|
||||
Crosapi::MethodMinVersions::kBindResourceManagerMinVersion>();
|
||||
ConstructRemote<crosapi::mojom::SelectFile,
|
||||
&crosapi::mojom::Crosapi::BindSelectFile,
|
||||
Crosapi::MethodMinVersions::kBindSelectFileMinVersion>();
|
||||
|
@ -54,7 +54,9 @@ const base::Feature kRunOnMainThread{"RunOnMainThread",
|
||||
#if !defined(OS_ANDROID)
|
||||
const base::Feature kUrgentDiscardingFromPerformanceManager {
|
||||
"UrgentDiscardingFromPerformanceManager",
|
||||
#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_LINUX)
|
||||
// Chrome OS uses memory pressure evaluator instead of performance manager to
|
||||
// discard tabs.
|
||||
#if defined(OS_CHROMEOS) || defined(OS_LINUX)
|
||||
base::FEATURE_DISABLED_BY_DEFAULT
|
||||
#else
|
||||
base::FEATURE_ENABLED_BY_DEFAULT
|
||||
|
Reference in New Issue
Block a user