#ifndef UI_DISPLAY_MANAGER_CONTENT_PROTECTION_MANAGER_H_
#define UI_DISPLAY_MANAGER_CONTENT_PROTECTION_MANAGER_H_
#include <cstdint>
#include <memory>
#include <optional>
#include "base/containers/flat_map.h"
#include "base/containers/queue.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/timer/timer.h"
#include "ui/display/manager/content_protection_key_manager.h"
#include "ui/display/manager/display_configurator.h"
#include "ui/display/manager/display_manager_export.h"
namespace display {
class DisplayLayoutManager;
class DisplaySnapshot;
class NativeDisplayDelegate;
namespace test {
class ContentProtectionManagerTest;
}
class DISPLAY_MANAGER_EXPORT ContentProtectionManager
: public DisplayConfigurator::Observer {
public:
using QueryContentProtectionCallback = base::OnceCallback<
void(bool success, uint32_t connection_mask, uint32_t protection_mask)>;
using ApplyContentProtectionCallback = base::OnceCallback<void(bool success)>;
using ContentProtections =
base::flat_map<int64_t , uint32_t >;
struct Task {
enum class Status { KILLED, FAILURE, SUCCESS };
virtual ~Task() = default;
virtual void Run() = 0;
};
class Observer : public base::CheckedObserver {
public:
~Observer() override = default;
virtual void OnDisplaySecurityMaybeChanged(int64_t display_id,
bool secure) = 0;
};
using ConfigurationDisabledCallback = base::RepeatingCallback<bool()>;
ContentProtectionManager(DisplayLayoutManager*,
ConfigurationDisabledCallback);
ContentProtectionManager(const ContentProtectionManager&) = delete;
ContentProtectionManager& operator=(const ContentProtectionManager&) = delete;
~ContentProtectionManager() override;
void set_native_display_delegate(NativeDisplayDelegate* delegate) {
native_display_delegate_ = delegate;
hdcp_key_manager_.set_native_display_delegate(delegate);
}
using ClientId = std::optional<uint64_t>;
ClientId RegisterClient();
void UnregisterClient(ClientId client_id);
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
void QueryContentProtection(ClientId client_id,
int64_t display_id,
QueryContentProtectionCallback callback);
void ApplyContentProtection(ClientId client_id,
int64_t display_id,
uint32_t protection_mask,
ApplyContentProtectionCallback callback);
void SetProvisionedKeyRequest(
ContentProtectionKeyManager::ProvisionedKeyRequest request) {
hdcp_key_manager_.set_provisioned_key_request(request);
}
private:
friend class test::ContentProtectionManagerTest;
bool disabled() const {
return !native_display_delegate_ || config_disabled_callback_.Run();
}
const DisplaySnapshot* GetDisplay(int64_t display_id) const;
ContentProtections AggregateContentProtections() const;
ContentProtections* GetContentProtections(ClientId client_id);
void QueueTask(std::unique_ptr<Task> task);
void DequeueTask();
void KillTasks();
void OnContentProtectionQueried(QueryContentProtectionCallback callback,
ClientId client_id,
int64_t display_id,
Task::Status status,
uint32_t connection_mask,
uint32_t protection_mask);
void OnContentProtectionApplied(ApplyContentProtectionCallback callback,
ClientId client_id,
Task::Status status);
void OnDisplayConfigurationChanged(
const DisplayConfigurator::DisplayStateList&) override;
void OnDisplayConfigurationChangeFailed(
const DisplayConfigurator::DisplayStateList&,
MultipleDisplayState) override;
bool HasExternalDisplaysWithContentProtection() const;
void ToggleDisplaySecurityPolling();
bool TriggerDisplaySecurityTimeoutForTesting();
void QueueDisplaySecurityQueries();
void OnDisplaySecurityQueried(int64_t display_id,
Task::Status status,
uint32_t connection_mask,
uint32_t protection_mask);
void QueueContentProtectionTask(ApplyContentProtectionCallback callback,
ClientId client_id,
bool is_key_set);
const raw_ptr<DisplayLayoutManager> layout_manager_;
raw_ptr<NativeDisplayDelegate> native_display_delegate_ =
nullptr;
const ConfigurationDisabledCallback config_disabled_callback_;
uint64_t next_client_id_ = 0;
base::flat_map<uint64_t, ContentProtections> requests_;
base::queue<std::unique_ptr<Task>> tasks_;
base::ObserverList<Observer> observers_;
base::RepeatingTimer security_timer_;
ContentProtectionKeyManager hdcp_key_manager_;
base::WeakPtrFactory<ContentProtectionManager> weak_ptr_factory_{this};
};
}
#endif