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_CDM_SESSION_ADAPTER_H_
6#define CONTENT_RENDERER_MEDIA_CDM_SESSION_ADAPTER_H_
7
8#include <map>
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/containers/hash_tables.h"
13#include "base/memory/ref_counted.h"
14#include "base/memory/weak_ptr.h"
15#include "media/base/media_keys.h"
16#include "third_party/WebKit/public/platform/WebContentDecryptionModuleSession.h"
17
18#if defined(ENABLE_PEPPER_CDMS)
19#include "content/renderer/media/crypto/pepper_cdm_wrapper.h"
20#endif
21
22class GURL;
23
24namespace content {
25
26#if defined(ENABLE_BROWSER_CDMS)
27class RendererCdmManager;
28#endif
29
30class WebContentDecryptionModuleSessionImpl;
31
32// Owns the CDM instance and makes calls from session objects to the CDM.
33// Forwards the web session ID-based callbacks of the MediaKeys interface to the
34// appropriate session object. Callers should hold references to this class
35// as long as they need the CDM instance.
36class CdmSessionAdapter : public base::RefCounted<CdmSessionAdapter> {
37 public:
38  CdmSessionAdapter();
39
40  // Returns true on success.
41  bool Initialize(
42#if defined(ENABLE_PEPPER_CDMS)
43      const CreatePepperCdmCB& create_pepper_cdm_cb,
44#elif defined(ENABLE_BROWSER_CDMS)
45      RendererCdmManager* manager,
46#endif
47      const std::string& key_system,
48      const GURL& security_origin);
49
50  // Provides a server certificate to be used to encrypt messages to the
51  // license server.
52  void SetServerCertificate(const uint8* server_certificate,
53                            int server_certificate_length,
54                            scoped_ptr<media::SimpleCdmPromise> promise);
55
56  // Creates a new session and adds it to the internal map. The caller owns the
57  // created session. RemoveSession() must be called when destroying it, if
58  // RegisterSession() was called.
59  WebContentDecryptionModuleSessionImpl* CreateSession();
60
61  // Adds a session to the internal map. Called once the session is successfully
62  // initialized. Returns true if the session was registered, false if there is
63  // already an existing session with the same |web_session_id|.
64  bool RegisterSession(
65      const std::string& web_session_id,
66      base::WeakPtr<WebContentDecryptionModuleSessionImpl> session);
67
68  // Removes a session from the internal map.
69  void UnregisterSession(const std::string& web_session_id);
70
71  // Initializes a session with the |init_data_type|, |init_data| and
72  // |session_type| provided.
73  void InitializeNewSession(const std::string& init_data_type,
74                            const uint8* init_data,
75                            int init_data_length,
76                            media::MediaKeys::SessionType session_type,
77                            scoped_ptr<media::NewSessionCdmPromise> promise);
78
79  // Updates the session specified by |web_session_id| with |response|.
80  void UpdateSession(const std::string& web_session_id,
81                     const uint8* response,
82                     int response_length,
83                     scoped_ptr<media::SimpleCdmPromise> promise);
84
85  // Closes the session specified by |web_session_id|.
86  void CloseSession(const std::string& web_session_id,
87                    scoped_ptr<media::SimpleCdmPromise> promise);
88
89  // Removes stored session data associated with the session specified by
90  // |web_session_id|.
91  void RemoveSession(const std::string& web_session_id,
92                     scoped_ptr<media::SimpleCdmPromise> promise);
93
94  // Retrieves the key IDs for keys in the session that the CDM knows are
95  // currently usable to decrypt media data.
96  void GetUsableKeyIds(const std::string& web_session_id,
97                       scoped_ptr<media::KeyIdsPromise> promise);
98
99  // Returns the Decryptor associated with this CDM. May be NULL if no
100  // Decryptor is associated with the MediaKeys object.
101  // TODO(jrummell): Figure out lifetimes, as WMPI may still use the decryptor
102  // after WebContentDecryptionModule is freed. http://crbug.com/330324
103  media::Decryptor* GetDecryptor();
104
105  // Returns a prefix to use for UMAs.
106  const std::string& GetKeySystemUMAPrefix() const;
107
108#if defined(ENABLE_BROWSER_CDMS)
109  // Returns the CDM ID associated with the |media_keys_|. May be kInvalidCdmId
110  // if no CDM ID is associated.
111  int GetCdmId() const;
112#endif
113
114 private:
115  friend class base::RefCounted<CdmSessionAdapter>;
116  typedef base::hash_map<std::string,
117                         base::WeakPtr<WebContentDecryptionModuleSessionImpl> >
118      SessionMap;
119
120  ~CdmSessionAdapter();
121
122  // Callbacks for firing session events.
123  void OnSessionMessage(const std::string& web_session_id,
124                        const std::vector<uint8>& message,
125                        const GURL& destination_url);
126  void OnSessionKeysChange(const std::string& web_session_id,
127                           bool has_additional_usable_key);
128  void OnSessionExpirationUpdate(const std::string& web_session_id,
129                                 const base::Time& new_expiry_time);
130  void OnSessionReady(const std::string& web_session_id);
131  void OnSessionClosed(const std::string& web_session_id);
132  void OnSessionError(const std::string& web_session_id,
133                      media::MediaKeys::Exception exception_code,
134                      uint32 system_code,
135                      const std::string& error_message);
136
137  // Helper function of the callbacks.
138  WebContentDecryptionModuleSessionImpl* GetSession(
139      const std::string& web_session_id);
140
141  scoped_ptr<media::MediaKeys> media_keys_;
142
143  SessionMap sessions_;
144
145#if defined(ENABLE_BROWSER_CDMS)
146  int cdm_id_;
147#endif
148
149  std::string key_system_uma_prefix_;
150
151  // NOTE: Weak pointers must be invalidated before all other member variables.
152  base::WeakPtrFactory<CdmSessionAdapter> weak_ptr_factory_;
153
154  DISALLOW_COPY_AND_ASSIGN(CdmSessionAdapter);
155};
156
157}  // namespace content
158
159#endif  // CONTENT_RENDERER_MEDIA_CDM_SESSION_ADAPTER_H_
160