1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_MEDIA_KEYS_H_
6#define CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_MEDIA_KEYS_H_
7
8#include <map>
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/containers/hash_tables.h"
13#include "base/containers/scoped_ptr_hash_map.h"
14#include "media/base/cdm_promise.h"
15#include "media/base/media_keys.h"
16
17class GURL;
18
19namespace content {
20
21class RendererCdmManager;
22
23// A MediaKeys proxy that wraps the EME part of RendererCdmManager.
24class ProxyMediaKeys : public media::MediaKeys {
25 public:
26  static scoped_ptr<ProxyMediaKeys> Create(
27      const std::string& key_system,
28      const GURL& security_origin,
29      RendererCdmManager* manager,
30      const media::SessionMessageCB& session_message_cb,
31      const media::SessionReadyCB& session_ready_cb,
32      const media::SessionClosedCB& session_closed_cb,
33      const media::SessionErrorCB& session_error_cb,
34      const media::SessionKeysChangeCB& session_keys_change_cb,
35      const media::SessionExpirationUpdateCB& session_expiration_update_cb);
36
37  virtual ~ProxyMediaKeys();
38
39  // MediaKeys implementation.
40  virtual void SetServerCertificate(
41      const uint8* certificate_data,
42      int certificate_data_length,
43      scoped_ptr<media::SimpleCdmPromise> promise) OVERRIDE;
44  virtual void CreateSession(
45      const std::string& init_data_type,
46      const uint8* init_data,
47      int init_data_length,
48      SessionType session_type,
49      scoped_ptr<media::NewSessionCdmPromise> promise) OVERRIDE;
50  virtual void LoadSession(
51      const std::string& web_session_id,
52      scoped_ptr<media::NewSessionCdmPromise> promise) OVERRIDE;
53  virtual void UpdateSession(
54      const std::string& web_session_id,
55      const uint8* response,
56      int response_length,
57      scoped_ptr<media::SimpleCdmPromise> promise) OVERRIDE;
58  virtual void CloseSession(
59      const std::string& web_session_id,
60      scoped_ptr<media::SimpleCdmPromise> promise) OVERRIDE;
61  virtual void RemoveSession(
62      const std::string& web_session_id,
63      scoped_ptr<media::SimpleCdmPromise> promise) OVERRIDE;
64  virtual void GetUsableKeyIds(
65      const std::string& web_session_id,
66      scoped_ptr<media::KeyIdsPromise> promise) OVERRIDE;
67
68  // Callbacks.
69  void OnSessionCreated(uint32 session_id, const std::string& web_session_id);
70  void OnSessionMessage(uint32 session_id,
71                        const std::vector<uint8>& message,
72                        const GURL& destination_url);
73  void OnSessionReady(uint32 session_id);
74  void OnSessionClosed(uint32 session_id);
75  void OnSessionError(uint32 session_id,
76                      media::MediaKeys::KeyError error_code,
77                      uint32 system_code);
78
79  int GetCdmId() const;
80
81 private:
82  // The Android-specific code that handles sessions uses integer session ids
83  // (basically a reference id), but media::MediaKeys bases everything on
84  // web_session_id (a string representing the actual session id as generated
85  // by the CDM). SessionIdMap is used to map between the web_session_id and
86  // the session_id used by the Android-specific code.
87  typedef base::hash_map<std::string, uint32_t> SessionIdMap;
88
89  // The following types keep track of Promises. The index is the
90  // Android-specific session_id, so that returning results can be matched to
91  // the corresponding promise.
92  typedef base::ScopedPtrHashMap<uint32_t, media::CdmPromise> PromiseMap;
93
94  ProxyMediaKeys(RendererCdmManager* manager,
95                 const media::SessionMessageCB& session_message_cb,
96                 const media::SessionReadyCB& session_ready_cb,
97                 const media::SessionClosedCB& session_closed_cb,
98                 const media::SessionErrorCB& session_error_cb);
99
100  void InitializeCdm(const std::string& key_system,
101                     const GURL& security_origin);
102
103  // These functions keep track of Android-specific session_ids <->
104  // web_session_ids mappings.
105  // TODO(jrummell): Remove this once the Android-specific code changes to
106  // support string web session ids.
107  uint32_t CreateSessionId();
108  void AssignWebSessionId(uint32_t session_id,
109                          const std::string& web_session_id);
110  uint32_t LookupSessionId(const std::string& web_session_id) const;
111  std::string LookupWebSessionId(uint32_t session_id) const;
112  void DropWebSessionId(const std::string& web_session_id);
113
114  // Helper function to keep track of promises. Adding takes ownership of the
115  // promise, transferred back to caller on take.
116  void SavePromise(uint32_t session_id, scoped_ptr<media::CdmPromise> promise);
117  scoped_ptr<media::CdmPromise> TakePromise(uint32_t session_id);
118
119  RendererCdmManager* manager_;
120  int cdm_id_;
121
122  media::SessionMessageCB session_message_cb_;
123  media::SessionReadyCB session_ready_cb_;
124  media::SessionClosedCB session_closed_cb_;
125  media::SessionErrorCB session_error_cb_;
126
127  // Android-specific. See comment above CreateSessionId().
128  uint32_t next_session_id_;
129  SessionIdMap web_session_to_session_id_map_;
130
131  // Keep track of outstanding promises. This map owns the promise object.
132  PromiseMap session_id_to_promise_map_;
133
134  DISALLOW_COPY_AND_ASSIGN(ProxyMediaKeys);
135};
136
137}  // namespace content
138
139#endif  // CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_MEDIA_KEYS_H_
140