summaryrefslogtreecommitdiffstats
path: root/content/browser/media/cdm/browser_cdm_manager.h
blob: e3a986a6f7fc0ba3882b275091266ff7660a0669 (plain)
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
// Copyright 2014 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 CONTENT_BROWSER_MEDIA_CDM_BROWSER_CDM_MANAGER_H_
#define CONTENT_BROWSER_MEDIA_CDM_BROWSER_CDM_MANAGER_H_

#include <stdint.h>

#include <map>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "content/common/media/cdm_messages.h"
#include "content/common/media/cdm_messages_enums.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/common/permission_status.mojom.h"
#include "ipc/ipc_message.h"
#include "media/base/cdm_promise.h"
#include "media/base/eme_constants.h"
#include "media/base/media_keys.h"
#include "url/gurl.h"

struct CdmHostMsg_CreateSessionAndGenerateRequest_Params;

namespace media {
class CdmFactory;
}

namespace content {

// This class manages all CDM objects. It receives control operations from the
// the render process, and forwards them to corresponding CDM object. Callbacks
// from CDM objects are converted to IPCs and then sent to the render process.
class CONTENT_EXPORT BrowserCdmManager : public BrowserMessageFilter {
 public:
  // Returns the BrowserCdmManager associated with the |render_process_id|.
  // Returns NULL if no BrowserCdmManager is associated.
  static BrowserCdmManager* FromProcess(int render_process_id);

  // Constructs the BrowserCdmManager for |render_process_id| which runs on
  // |task_runner|.
  // If |task_runner| is not NULL, all CDM messages are posted to it. Otherwise,
  // all messages are posted to the browser UI thread.
  BrowserCdmManager(int render_process_id,
                    const scoped_refptr<base::TaskRunner>& task_runner);

  // BrowserMessageFilter implementations.
  void OnDestruct() const override;
  base::TaskRunner* OverrideTaskRunnerForMessage(
      const IPC::Message& message) override;
  bool OnMessageReceived(const IPC::Message& message) override;

  // Returns the CDM associated with |render_frame_id| and |cdm_id|. Returns
  // null if no such CDM exists.
  scoped_refptr<media::MediaKeys> GetCdm(int render_frame_id, int cdm_id) const;

  // Notifies that the render frame has been deleted so that all CDMs belongs
  // to this render frame needs to be destroyed as well. This is needed because
  // in some cases (e.g. fast termination of the renderer), the message to
  // destroy the CDM will not be received.
  void RenderFrameDeleted(int render_frame_id);

  // Promise handlers.
  void ResolvePromise(int render_frame_id, int cdm_id, uint32_t promise_id);
  void ResolvePromiseWithSession(int render_frame_id,
                                 int cdm_id,
                                 uint32_t promise_id,
                                 const std::string& session_id);
  void RejectPromise(int render_frame_id,
                     int cdm_id,
                     uint32_t promise_id,
                     media::MediaKeys::Exception exception,
                     uint32_t system_code,
                     const std::string& error_message);

 protected:
  friend class base::RefCountedThreadSafe<BrowserCdmManager>;
  friend class base::DeleteHelper<BrowserCdmManager>;
  ~BrowserCdmManager() override;

 private:
  // Returns the CdmFactory that can be used to create CDMs. Returns null if
  // CDM is not supported.
  media::CdmFactory* GetCdmFactory();

  // CDM callbacks.
  void OnSessionMessage(int render_frame_id,
                        int cdm_id,
                        const std::string& session_id,
                        media::MediaKeys::MessageType message_type,
                        const std::vector<uint8_t>& message,
                        const GURL& legacy_destination_url);
  void OnSessionClosed(int render_frame_id,
                       int cdm_id,
                       const std::string& session_id);
  void OnLegacySessionError(int render_frame_id,
                            int cdm_id,
                            const std::string& session_id,
                            media::MediaKeys::Exception exception_code,
                            uint32_t system_code,
                            const std::string& error_message);
  void OnSessionKeysChange(int render_frame_id,
                           int cdm_id,
                           const std::string& session_id,
                           bool has_additional_usable_key,
                           media::CdmKeysInfo keys_info);
  void OnSessionExpirationUpdate(int render_frame_id,
                                 int cdm_id,
                                 const std::string& session_id,
                                 const base::Time& new_expiry_time);

  // Message handlers.
  void OnInitializeCdm(int render_frame_id,
                       int cdm_id,
                       uint32_t promise_id,
                       const CdmHostMsg_InitializeCdm_Params& params);
  void OnSetServerCertificate(int render_frame_id,
                              int cdm_id,
                              uint32_t promise_id,
                              const std::vector<uint8_t>& certificate);
  void OnCreateSessionAndGenerateRequest(
      const CdmHostMsg_CreateSessionAndGenerateRequest_Params& params);
  void OnLoadSession(
      int render_frame_id,
      int cdm_id,
      uint32_t promise_id,
      media::MediaKeys::SessionType session_type,
      const std::string& session_id);
  void OnUpdateSession(int render_frame_id,
                       int cdm_id,
                       uint32_t promise_id,
                       const std::string& session_id,
                       const std::vector<uint8_t>& response);
  void OnCloseSession(int render_frame_id,
                      int cdm_id,
                      uint32_t promise_id,
                      const std::string& session_id);
  void OnRemoveSession(int render_frame_id,
                       int cdm_id,
                       uint32_t promise_id,
                       const std::string& session_id);
  void OnDestroyCdm(int render_frame_id, int cdm_id);

  // Callback for CDM creation.
  void OnCdmCreated(int render_frame_id,
                    int cdm_id,
                    const GURL& security_origin,
                    scoped_ptr<media::SimpleCdmPromise> promise,
                    const scoped_refptr<media::MediaKeys>& cdm,
                    const std::string& error_message);

  // Removes all CDMs associated with |render_frame_id|.
  void RemoveAllCdmForFrame(int render_frame_id);

  // Removes the CDM with the specified id.
  void RemoveCdm(uint64_t id);

  using PermissionStatusCB = base::Callback<void(bool)>;

  // Checks protected media identifier permission for the given
  // |render_frame_id| and |cdm_id|.
  void CheckPermissionStatus(int render_frame_id,
                             int cdm_id,
                             const PermissionStatusCB& permission_status_cb);

  // Checks permission status on Browser UI thread. Runs |permission_status_cb|
  // on the |task_runner_| with the permission status.
  void CheckPermissionStatusOnUIThread(
      int render_frame_id,
      const GURL& security_origin,
      const PermissionStatusCB& permission_status_cb);

  // Calls CreateSessionAndGenerateRequest() on the CDM if
  // |permission_was_allowed| is true. Otherwise rejects the |promise|.
  void CreateSessionAndGenerateRequestIfPermitted(
      int render_frame_id,
      int cdm_id,
      media::MediaKeys::SessionType session_type,
      media::EmeInitDataType init_data_type,
      const std::vector<uint8_t>& init_data,
      scoped_ptr<media::NewSessionCdmPromise> promise,
      bool permission_was_allowed);

  // Calls LoadSession() on the CDM if |permission_was_allowed| is true.
  // Otherwise rejects |promise|.
  void LoadSessionIfPermitted(int render_frame_id,
                              int cdm_id,
                              media::MediaKeys::SessionType session_type,
                              const std::string& session_id,
                              scoped_ptr<media::NewSessionCdmPromise> promise,
                              bool permission_was_allowed);

  const int render_process_id_;

  // TaskRunner to dispatch all CDM messages to. If it's NULL, all messages are
  // dispatched to the browser UI thread.
  scoped_refptr<base::TaskRunner> task_runner_;

  scoped_ptr<media::CdmFactory> cdm_factory_;

  // The key in the following maps is a combination of |render_frame_id| and
  // |cdm_id|.

  // Map of managed CDMs.
  typedef std::map<uint64_t, scoped_refptr<media::MediaKeys>> CdmMap;
  CdmMap cdm_map_;

  // Map of CDM's security origin.
  std::map<uint64_t, GURL> cdm_security_origin_map_;

  base::WeakPtrFactory<BrowserCdmManager> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(BrowserCdmManager);
};

}  // namespace content

#endif  // CONTENT_BROWSER_MEDIA_CDM_BROWSER_CDM_MANAGER_H_