[go: nahoru, domu]

blob: 7a6b915bd1364768169448c9aaeed7970ce58806 [file] [log] [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_THROTTLE_SERVICE_H_
#define CHROME_BROWSER_ASH_THROTTLE_SERVICE_H_
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "chrome/browser/ash/throttle_observer.h"
namespace content {
class BrowserContext;
}
namespace ash {
// This class is the base for different throttle services on Chrome OS.
// The class holds a number of ThrottleObservers which watch for several
// conditions. When the observers change from active to inactive or vice-versa,
// OnObserverStateChanged checks if there is an active observer and calls
// ThrottleInstance accordingly.
class ThrottleService {
public:
class ServiceObserver : public base::CheckedObserver {
public:
// Notifies that throttling has been changed. If the target is now
// throttled, the function is called with true. It is called with
// false otherwise.
virtual void OnThrottle(bool throttled) = 0;
};
explicit ThrottleService(content::BrowserContext* context);
ThrottleService(const ThrottleService&) = delete;
ThrottleService& operator=(const ThrottleService&) = delete;
virtual ~ThrottleService();
void AddServiceObserver(ServiceObserver* observer);
void RemoveServiceObserver(ServiceObserver* observer);
// Returns an observer whose name is |name|. Returns nullptr otherwise.
ThrottleObserver* GetObserverByName(const std::string& name);
// Functions for testing
void NotifyObserverStateChangedForTesting();
void SetObserversForTesting(
std::vector<std::unique_ptr<ThrottleObserver>> observers);
bool HasServiceObserverForTesting(ServiceObserver* candidate);
bool should_throttle() const {
// When `should_throttle_` hasn't been initialized, return true to throttle
// the target (which is a safer bet for Chrome.)
return !should_throttle_ || *should_throttle_;
}
void reset_should_throttle_for_testing() { should_throttle_.reset(); }
const std::vector<std::unique_ptr<ThrottleObserver>>& observers_for_testing()
const {
return observers_;
}
protected:
void AddObserver(std::unique_ptr<ThrottleObserver> observer);
void StartObservers();
void StopObservers();
void OnObserverStateChanged(const ThrottleObserver* changed_observer);
// This function is called whenever the target should be throttled or
// unthrottled. Derived classes should implement ThrottleInstance to adjust
// the throttling state of their relevant target.
virtual void ThrottleInstance(bool should_throttle) = 0;
// Whenever there is a change in the effective observer, this function is
// called with the name of the previously effective observer and the duration
// it was effective. Derived classes can implement this function to record UMA
// metrics.
virtual void RecordCpuRestrictionDisabledUMA(const std::string& observer_name,
base::TimeDelta delta) {}
const std::vector<std::unique_ptr<ThrottleObserver>>& observers() const {
return observers_;
}
content::BrowserContext* context() const { return context_; }
private:
const raw_ptr<content::BrowserContext> context_;
std::vector<std::unique_ptr<ThrottleObserver>> observers_;
// True when the target should be throttled. Use optional<> to make sure this
// service always calls ThrottleInstance() when one of the observers has
// changed for the first time.
std::optional<bool> should_throttle_;
raw_ptr<ThrottleObserver> last_effective_observer_{nullptr};
base::TimeTicks last_throttle_transition_;
base::ObserverList<ServiceObserver> service_observers_;
base::WeakPtrFactory<ThrottleService> weak_ptr_factory_{this};
};
} // namespace ash
#endif // CHROME_BROWSER_ASH_THROTTLE_SERVICE_H_