Commit 67ae333f authored by Jia's avatar Jia Committed by Commit Bot

[On-device adaptive brightness] Create a BrightnessMonitor.

This is almost the same cl as
https://chromium-review.googlesource.com/c/chromium/src/+/1226715

The previous cl was reverted because it broke linux-chromeos-dbg due to missing
"=0" for a virtual method of an abstract class (incorrect gn config meant the
compiler didn't pick it up). It's added in this cl. This is
the only change from the previous cl.

Bug: 881215
Change-Id: Iaf5ab6e3ee98c11b593dcc9d759527c4fb3b2168
Reviewed-on: https://chromium-review.googlesource.com/1235262Reviewed-by: default avatarMichael Martis <martis@chromium.org>
Commit-Queue: Jia Meng <jiameng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#592698}
parent e04ce695
...@@ -1586,8 +1586,13 @@ source_set("chromeos") { ...@@ -1586,8 +1586,13 @@ source_set("chromeos") {
"power/auto_screen_brightness/als_reader.h", "power/auto_screen_brightness/als_reader.h",
"power/auto_screen_brightness/als_reader_impl.cc", "power/auto_screen_brightness/als_reader_impl.cc",
"power/auto_screen_brightness/als_reader_impl.h", "power/auto_screen_brightness/als_reader_impl.h",
"power/auto_screen_brightness/brightness_monitor.h",
"power/auto_screen_brightness/brightness_monitor_impl.cc",
"power/auto_screen_brightness/brightness_monitor_impl.h",
"power/auto_screen_brightness/fake_als_reader.cc", "power/auto_screen_brightness/fake_als_reader.cc",
"power/auto_screen_brightness/fake_als_reader.h", "power/auto_screen_brightness/fake_als_reader.h",
"power/auto_screen_brightness/fake_brightness_monitor.cc",
"power/auto_screen_brightness/fake_brightness_monitor.h",
"power/cpu_data_collector.cc", "power/cpu_data_collector.cc",
"power/cpu_data_collector.h", "power/cpu_data_collector.h",
"power/extension_event_observer.cc", "power/extension_event_observer.cc",
...@@ -2262,6 +2267,7 @@ source_set("unit_tests") { ...@@ -2262,6 +2267,7 @@ source_set("unit_tests") {
"policy/weekly_time/weekly_time_interval_unittest.cc", "policy/weekly_time/weekly_time_interval_unittest.cc",
"policy/weekly_time/weekly_time_unittest.cc", "policy/weekly_time/weekly_time_unittest.cc",
"power/auto_screen_brightness/als_reader_impl_unittest.cc", "power/auto_screen_brightness/als_reader_impl_unittest.cc",
"power/auto_screen_brightness/brightness_monitor_impl_unittest.cc",
"power/auto_screen_brightness/fake_als_reader_unittest.cc", "power/auto_screen_brightness/fake_als_reader_unittest.cc",
"power/cpu_data_collector_unittest.cc", "power/cpu_data_collector_unittest.cc",
"power/extension_event_observer_unittest.cc", "power/extension_event_observer_unittest.cc",
......
// 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 CHROME_BROWSER_CHROMEOS_POWER_AUTO_SCREEN_BRIGHTNESS_BRIGHTNESS_MONITOR_H_
#define CHROME_BROWSER_CHROMEOS_POWER_AUTO_SCREEN_BRIGHTNESS_BRIGHTNESS_MONITOR_H_
#include "base/observer_list_types.h"
namespace chromeos {
namespace power {
namespace auto_screen_brightness {
// Interface for monitoring the screen brightness.
class BrightnessMonitor {
public:
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class Status {
kInitializing = 0,
kSuccess = 1,
kDisabled = 2,
kMaxValue = kDisabled
};
class Observer : public base::CheckedObserver {
public:
Observer() = default;
~Observer() override = default;
// Called when BrightnessMonitor is initialized.
virtual void OnBrightnessMonitorInitialized(bool success) = 0;
// Called soon after the screen brightness is changed in response to a user
// request. Rapid changes are not reported; only the final change in a
// sequence will be sent. The |old_brightness_percent| is the brightness
// value just before user requested the change, and |new_brightness_percent|
// is the final/consolidated brightness value after the change.
virtual void OnUserBrightnessChanged(double old_brightness_percent,
double new_brightness_percent) = 0;
// Called for every user request, i.e. it's not consolidated like
// |OnUserBrightnessChanged|.
virtual void OnUserBrightnessChangeRequested() = 0;
private:
DISALLOW_COPY_AND_ASSIGN(Observer);
};
virtual ~BrightnessMonitor() = default;
// Adds or removes an observer.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
// An observer can call this method to check BrightnessMonitor's status.
virtual Status GetStatus() const = 0;
};
} // namespace auto_screen_brightness
} // namespace power
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_POWER_AUTO_SCREEN_BRIGHTNESS_BRIGHTNESS_MONITOR_H_
// 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 "chrome/browser/chromeos/power/auto_screen_brightness/brightness_monitor_impl.h"
#include <cmath>
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/task/post_task.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_manager/backlight.pb.h"
namespace chromeos {
namespace power {
namespace auto_screen_brightness {
constexpr base::TimeDelta BrightnessMonitorImpl::kBrightnessSampleDelay;
BrightnessMonitorImpl::BrightnessMonitorImpl(
chromeos::PowerManagerClient* const power_manager_client)
: BrightnessMonitorImpl(
power_manager_client,
base::CreateSequencedTaskRunnerWithTraits(
{base::TaskPriority::BEST_EFFORT, base::MayBlock(),
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) {}
BrightnessMonitorImpl::~BrightnessMonitorImpl() = default;
void BrightnessMonitorImpl::AddObserver(
BrightnessMonitor::Observer* const observer) {
DCHECK(observer);
observers_.AddObserver(observer);
}
void BrightnessMonitorImpl::RemoveObserver(
BrightnessMonitor::Observer* const observer) {
DCHECK(observer);
observers_.RemoveObserver(observer);
}
BrightnessMonitor::Status BrightnessMonitorImpl::GetStatus() const {
return brightness_monitor_status_;
}
void BrightnessMonitorImpl::ScreenBrightnessChanged(
const power_manager::BacklightBrightnessChange& change) {
if (brightness_monitor_status_ != Status::kSuccess) {
// Either
// (1). we're waiting for init brightness to come in from powerd, or
// (2). we've failed to get init brightness from powerd.
// In any case, we ignore this brightness change.
return;
}
if (change.cause() ==
power_manager::BacklightBrightnessChange_Cause_USER_REQUEST) {
// This is the only brightness change caused by explicit user selection.
NotifyUserBrightnessChangeRequested();
user_brightness_percent_ = base::Optional<double>(change.percent());
StartBrightnessSampleTimer();
return;
}
// We treat all the other causes as non-user-initiated.
if (user_brightness_percent_) {
// If we've received a user-selected brightness change, stop waiting and
// report the latest |user_brightness_percent_|.
brightness_sample_timer_.Stop();
NotifyUserBrightnessChanged();
}
stable_brightness_percent_ = base::Optional<double>(change.percent());
}
std::unique_ptr<BrightnessMonitorImpl> BrightnessMonitorImpl::CreateForTesting(
chromeos::PowerManagerClient* const power_manager_client,
const scoped_refptr<base::SequencedTaskRunner> task_runner) {
return base::WrapUnique(
new BrightnessMonitorImpl(power_manager_client, task_runner));
}
BrightnessMonitorImpl::BrightnessMonitorImpl(
chromeos::PowerManagerClient* const power_manager_client,
const scoped_refptr<base::SequencedTaskRunner> task_runner)
: power_manager_client_observer_(this),
power_manager_client_(power_manager_client),
brightness_task_runner_(task_runner),
weak_ptr_factory_(this) {
DCHECK(power_manager_client);
power_manager_client_observer_.Add(power_manager_client);
brightness_sample_timer_.SetTaskRunner(brightness_task_runner_);
power_manager_client_->WaitForServiceToBeAvailable(
base::BindOnce(&BrightnessMonitorImpl::OnPowerManagerServiceAvailable,
weak_ptr_factory_.GetWeakPtr()));
}
void BrightnessMonitorImpl::OnPowerManagerServiceAvailable(
const bool service_is_ready) {
if (!service_is_ready) {
brightness_monitor_status_ = Status::kDisabled;
OnInitializationComplete();
return;
}
power_manager_client_->GetScreenBrightnessPercent(
base::BindOnce(&BrightnessMonitorImpl::OnReceiveInitialBrightnessPercent,
weak_ptr_factory_.GetWeakPtr()));
}
void BrightnessMonitorImpl::OnReceiveInitialBrightnessPercent(
const base::Optional<double> brightness_percent) {
DCHECK_EQ(brightness_monitor_status_, Status::kInitializing);
if (brightness_percent) {
stable_brightness_percent_ = brightness_percent;
brightness_monitor_status_ = Status::kSuccess;
} else {
brightness_monitor_status_ = Status::kDisabled;
}
OnInitializationComplete();
}
void BrightnessMonitorImpl::OnInitializationComplete() {
DCHECK_NE(brightness_monitor_status_, Status::kInitializing);
const bool success = brightness_monitor_status_ == Status::kSuccess;
for (auto& observer : observers_)
observer.OnBrightnessMonitorInitialized(success);
}
void BrightnessMonitorImpl::StartBrightnessSampleTimer() {
// It's ok if the timer is already running, we simply wait a bit longer.
brightness_sample_timer_.Start(
FROM_HERE, kBrightnessSampleDelay, this,
&BrightnessMonitorImpl::NotifyUserBrightnessChanged);
}
void BrightnessMonitorImpl::NotifyUserBrightnessChanged() {
if (!user_brightness_percent_) {
NOTREACHED() << "User brightness adjustment missing on sample timeout";
return;
}
for (auto& observer : observers_) {
observer.OnUserBrightnessChanged(stable_brightness_percent_.value(),
user_brightness_percent_.value());
}
stable_brightness_percent_ = user_brightness_percent_;
user_brightness_percent_ = base::nullopt;
}
void BrightnessMonitorImpl::NotifyUserBrightnessChangeRequested() {
for (auto& observer : observers_)
observer.OnUserBrightnessChangeRequested();
}
} // namespace auto_screen_brightness
} // namespace power
} // namespace chromeos
// 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 CHROME_BROWSER_CHROMEOS_POWER_AUTO_SCREEN_BRIGHTNESS_BRIGHTNESS_MONITOR_IMPL_H_
#define CHROME_BROWSER_CHROMEOS_POWER_AUTO_SCREEN_BRIGHTNESS_BRIGHTNESS_MONITOR_IMPL_H_
#include <memory>
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/optional.h"
#include "base/scoped_observer.h"
#include "base/sequenced_task_runner.h"
#include "base/task_runner_util.h"
#include "base/timer/timer.h"
#include "chrome/browser/chromeos/power/auto_screen_brightness/brightness_monitor.h"
#include "chromeos/dbus/power_manager_client.h"
namespace chromeos {
namespace power {
namespace auto_screen_brightness {
// Real implementation of BrightnessMonitor.
// It monitors user brightness changes and records the stabilized brightness.
class BrightnessMonitorImpl : public BrightnessMonitor,
public PowerManagerClient::Observer {
public:
// Once a user brightness adjustment is received, we wait for
// |kBrightnessSampleDelay| to record the final brightness.
// TODO(jiameng): revise this delay.
static constexpr base::TimeDelta kBrightnessSampleDelay =
base::TimeDelta::FromSeconds(5);
// PowerManagerClient must outlive BrightnessMonitorImpl.
explicit BrightnessMonitorImpl(
chromeos::PowerManagerClient* power_manager_client);
~BrightnessMonitorImpl() override;
// BrightnessMonitor overrides:
void AddObserver(BrightnessMonitor::Observer* observer) override;
void RemoveObserver(BrightnessMonitor::Observer* observer) override;
Status GetStatus() const override;
// chromeos::PowerManagerClient::Observer overrides:
void ScreenBrightnessChanged(
const power_manager::BacklightBrightnessChange& change) override;
static std::unique_ptr<BrightnessMonitorImpl> CreateForTesting(
chromeos::PowerManagerClient* power_manager_client,
scoped_refptr<base::SequencedTaskRunner> task_runner);
private:
BrightnessMonitorImpl(chromeos::PowerManagerClient* power_manager_client,
scoped_refptr<base::SequencedTaskRunner> task_runner);
void OnPowerManagerServiceAvailable(bool service_is_ready);
// Sets initial brightness obtained from powerd. If nullopt is received from
// powerd, the monitor status will be set to kDisabled.
void OnReceiveInitialBrightnessPercent(
base::Optional<double> brightness_percent);
// Notifies its observers on the initialization status of the monitor.
void OnInitializationComplete();
// Called when a user-triggered brightness change signal is received. We start
// the |brightness_sample_timer_| to wait for brightness to stabilize and
// collect the final brightness.
void StartBrightnessSampleTimer();
// Called when |brightness_sample_timer_| times out or a non-user-initiated
// change is received while the timer is running. We take the final brightness
// stored in |user_brightness_percent_| as the final user selected brightness.
void NotifyUserBrightnessChanged();
// Called as soon as a user-triggered brightness event is received.
void NotifyUserBrightnessChangeRequested();
ScopedObserver<chromeos::PowerManagerClient,
chromeos::PowerManagerClient::Observer>
power_manager_client_observer_;
chromeos::PowerManagerClient* const power_manager_client_;
scoped_refptr<base::SequencedTaskRunner> brightness_task_runner_;
// This timer is started when we receive the 1st user-requested brightness
// change and times out after kBrightnessSampleDelay if there are no more
// user-requested changes. The timer is reset if there is another
// user-requested change before it times out. The timer stops immediately if a
// non-user-requested change is received.
base::OneShotTimer brightness_sample_timer_;
BrightnessMonitor::Status brightness_monitor_status_ =
BrightnessMonitor::Status::kInitializing;
// Current brightness. It is updated when brightness change is reported by
// powerd. If the change is user requested, it will store the
// final/consolidated brightness (i.e. ignoring intermediate values selected
// by the user). If the change is not user requested, it will simply be the
// new brightness value.
base::Optional<double> stable_brightness_percent_;
// Current user selected brightness. It is reset after we've collected
// final/stable user-requested brightness (i.e. after
// |brightness_sample_timer_| times out).
base::Optional<double> user_brightness_percent_;
base::ObserverList<BrightnessMonitor::Observer> observers_;
base::WeakPtrFactory<BrightnessMonitorImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BrightnessMonitorImpl);
};
} // namespace auto_screen_brightness
} // namespace power
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_POWER_AUTO_SCREEN_BRIGHTNESS_BRIGHTNESS_MONITOR_IMPL_H_
// 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 "chrome/browser/chromeos/power/auto_screen_brightness/fake_brightness_monitor.h"
namespace chromeos {
namespace power {
namespace auto_screen_brightness {
FakeBrightnessMonitor::FakeBrightnessMonitor() : weak_ptr_factory_(this) {}
FakeBrightnessMonitor::~FakeBrightnessMonitor() = default;
void FakeBrightnessMonitor::ReportBrightnessMonitorInitialized() const {
DCHECK_NE(brightness_monitor_status_, Status::kInitializing);
const bool success = brightness_monitor_status_ == Status::kSuccess;
for (auto& observer : observers_)
observer.OnBrightnessMonitorInitialized(success);
}
void FakeBrightnessMonitor::ReportUserBrightnessChanged(
const double old_brightness_percent,
const double new_brightness_percent) const {
for (auto& observer : observers_)
observer.OnUserBrightnessChanged(old_brightness_percent,
new_brightness_percent);
}
void FakeBrightnessMonitor::ReportUserBrightnessChangeRequested() const {
for (auto& observer : observers_)
observer.OnUserBrightnessChangeRequested();
}
void FakeBrightnessMonitor::AddObserver(Observer* const observer) {
DCHECK(observer);
observers_.AddObserver(observer);
}
void FakeBrightnessMonitor::RemoveObserver(Observer* const observer) {
DCHECK(observer);
observers_.RemoveObserver(observer);
}
BrightnessMonitor::Status FakeBrightnessMonitor::GetStatus() const {
return brightness_monitor_status_;
}
} // namespace auto_screen_brightness
} // namespace power
} // namespace chromeos
// 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 CHROME_BROWSER_CHROMEOS_POWER_AUTO_SCREEN_BRIGHTNESS_FAKE_BRIGHTNESS_MONITOR_H_
#define CHROME_BROWSER_CHROMEOS_POWER_AUTO_SCREEN_BRIGHTNESS_FAKE_BRIGHTNESS_MONITOR_H_
#include <memory>
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "chrome/browser/chromeos/power/auto_screen_brightness/brightness_monitor.h"
namespace chromeos {
namespace power {
namespace auto_screen_brightness {
// Fake BrightnessMonitor for testing only.
class FakeBrightnessMonitor : public BrightnessMonitor {
public:
FakeBrightnessMonitor();
~FakeBrightnessMonitor() override;
void set_status(const Status status) { brightness_monitor_status_ = status; }
// Calls its observers' OnBrightnessMonitorInitialized. Checks
// |brightness_monitor_status_| is not kInitializing. Reported |success| is
// true if |brightness_monitor_status_| is kSuccess, else it's false.
void ReportBrightnessMonitorInitialized() const;
// Calls its observers' OnUserBrightnessChanged.
void ReportUserBrightnessChanged(double old_brightness_percent,
double new_brightness_percent) const;
// Calls its observers' OnUserBrightnessChangeRequested.
void ReportUserBrightnessChangeRequested() const;
// BrightnessMonitor overrides:
void AddObserver(BrightnessMonitor::Observer* observer) override;
void RemoveObserver(BrightnessMonitor::Observer* observer) override;
Status GetStatus() const override;
private:
BrightnessMonitor::Status brightness_monitor_status_ =
BrightnessMonitor::Status::kInitializing;
base::ObserverList<BrightnessMonitor::Observer> observers_;
base::WeakPtrFactory<FakeBrightnessMonitor> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(FakeBrightnessMonitor);
};
} // namespace auto_screen_brightness
} // namespace power
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_POWER_AUTO_SCREEN_BRIGHTNESS_FAKE_BRIGHTNESS_MONITOR_H_
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