1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
media / cdm / library_cdm / clear_key_cdm / clear_key_persistent_session_cdm.h [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_CDM_LIBRARY_CDM_CLEAR_KEY_CDM_CLEAR_KEY_PERSISTENT_SESSION_CDM_H_
#define MEDIA_CDM_LIBRARY_CDM_CLEAR_KEY_CDM_CLEAR_KEY_PERSISTENT_SESSION_CDM_H_
#include <stdint.h>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "media/base/content_decryption_module.h"
#include "media/cdm/aes_decryptor.h"
#include "media/cdm/library_cdm/cdm_host_proxy.h"
#include "media/cdm/library_cdm/clear_key_cdm/cdm_file_adapter.h"
namespace media {
// This class is a wrapper on top of AesDecryptor that supports persistent
// sessions. LoadSession(), UpdateSession(), and RemoveSession() have
// special handling.
class ClearKeyPersistentSessionCdm : public ContentDecryptionModule {
public:
ClearKeyPersistentSessionCdm(
CdmHostProxy* cdm_host_proxy,
const SessionMessageCB& session_message_cb,
const SessionClosedCB& session_closed_cb,
const SessionKeysChangeCB& session_keys_change_cb,
const SessionExpirationUpdateCB& session_expiration_update_cb);
ClearKeyPersistentSessionCdm(const ClearKeyPersistentSessionCdm&) = delete;
ClearKeyPersistentSessionCdm& operator=(const ClearKeyPersistentSessionCdm&) =
delete;
// ContentDecryptionModule implementation.
void SetServerCertificate(const std::vector<uint8_t>& certificate,
std::unique_ptr<SimpleCdmPromise> promise) override;
void CreateSessionAndGenerateRequest(
CdmSessionType session_type,
EmeInitDataType init_data_type,
const std::vector<uint8_t>& init_data,
std::unique_ptr<NewSessionCdmPromise> promise) override;
void LoadSession(CdmSessionType session_type,
const std::string& session_id,
std::unique_ptr<NewSessionCdmPromise> promise) override;
void UpdateSession(const std::string& session_id,
const std::vector<uint8_t>& response,
std::unique_ptr<SimpleCdmPromise> promise) override;
void CloseSession(const std::string& session_id,
std::unique_ptr<SimpleCdmPromise> promise) override;
void RemoveSession(const std::string& session_id,
std::unique_ptr<SimpleCdmPromise> promise) override;
CdmContext* GetCdmContext() override;
private:
~ClearKeyPersistentSessionCdm() override;
// When LoadSession() is called, first open and read the session state.
// Then call |cdm_| to create the session with the state provided.
void OnFileOpenedForLoadSession(const std::string& session_id,
std::unique_ptr<CdmFileAdapter> file,
std::unique_ptr<NewSessionCdmPromise> promise,
CdmFileAdapter::Status status);
void OnFileReadForLoadSession(const std::string& session_id,
std::unique_ptr<CdmFileAdapter> file,
std::unique_ptr<NewSessionCdmPromise> promise,
bool success,
const std::vector<uint8_t>& data);
// When UpdateSession() is called (on a persistent session), save the
// current session state after it's been updated.
void OnFileOpenedForUpdateSession(const std::string& session_id,
bool key_added,
std::unique_ptr<CdmFileAdapter> file,
std::unique_ptr<SimpleCdmPromise> promise,
CdmFileAdapter::Status status);
void OnFileWrittenForUpdateSession(const std::string& session_id,
bool key_added,
std::unique_ptr<CdmFileAdapter> file,
std::unique_ptr<SimpleCdmPromise> promise,
bool success);
// When RemoveSession() is called (on a persistent session), delete the
// file (by writing 0 bytes) and then call |cdm_| to actually remove the
// session from memory.
void OnFileOpenedForRemoveSession(const std::string& session_id,
std::unique_ptr<CdmFileAdapter> file,
std::unique_ptr<SimpleCdmPromise> promise,
CdmFileAdapter::Status status);
void OnFileWrittenForRemoveSession(const std::string& session_id,
std::unique_ptr<CdmFileAdapter> file,
std::unique_ptr<SimpleCdmPromise> promise,
bool success);
// Add |session_id| to the list of open persistent sessions.
void AddPersistentSession(const std::string& session_id);
// When the session is closed, remove it from the list of open persistent
// sessions if it was a persistent session.
void OnSessionClosed(const std::string& session_id,
CdmSessionClosedReason reason);
void OnSessionMessage(const std::string& session_id,
CdmMessageType message_type,
const std::vector<uint8_t>& message);
scoped_refptr<AesDecryptor> cdm_;
const raw_ptr<CdmHostProxy> cdm_host_proxy_ = nullptr;
// Callbacks for firing session events. Other events aren't intercepted.
SessionMessageCB session_message_cb_;
SessionClosedCB session_closed_cb_;
// Keep track of current open persistent sessions.
std::set<std::string> persistent_sessions_;
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<ClearKeyPersistentSessionCdm> weak_factory_{this};
};
} // namespace media
#endif // MEDIA_CDM_LIBRARY_CDM_CLEAR_KEY_CDM_CLEAR_KEY_PERSISTENT_SESSION_CDM_H_