1// Copyright 2013 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_DECRYPTOR_H_
6#define CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/containers/hash_tables.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/memory/weak_ptr.h"
15#include "media/base/decryptor.h"
16#include "media/base/media_keys.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  // defined(ENABLE_BROWSER_CDMS)
29
30// ProxyDecryptor is for EME v0.1b only. It should not be used for the WD API.
31// A decryptor proxy that creates a real decryptor object on demand and
32// forwards decryptor calls to it.
33//
34// TODO(xhwang): Currently we don't support run-time switching among decryptor
35// objects. Fix this when needed.
36// TODO(xhwang): The ProxyDecryptor is not a Decryptor. Find a better name!
37class ProxyDecryptor {
38 public:
39  // These are similar to the callbacks in media_keys.h, but pass back the
40  // web session ID rather than the internal session ID.
41  typedef base::Callback<void(const std::string& session_id)> KeyAddedCB;
42  typedef base::Callback<void(const std::string& session_id,
43                              media::MediaKeys::KeyError error_code,
44                              uint32 system_code)> KeyErrorCB;
45  typedef base::Callback<void(const std::string& session_id,
46                              const std::vector<uint8>& message,
47                              const GURL& destination_url)> KeyMessageCB;
48
49  ProxyDecryptor(
50#if defined(ENABLE_PEPPER_CDMS)
51      const CreatePepperCdmCB& create_pepper_cdm_cb,
52#elif defined(ENABLE_BROWSER_CDMS)
53      RendererCdmManager* manager,
54#endif  // defined(ENABLE_PEPPER_CDMS)
55      const KeyAddedCB& key_added_cb,
56      const KeyErrorCB& key_error_cb,
57      const KeyMessageCB& key_message_cb);
58  virtual ~ProxyDecryptor();
59
60  // Returns the Decryptor associated with this object. May be NULL if no
61  // Decryptor is associated.
62  media::Decryptor* GetDecryptor();
63
64#if defined(ENABLE_BROWSER_CDMS)
65  // Returns the CDM ID associated with this object. May be kInvalidCdmId if no
66  // CDM ID is associated, such as when Clear Key is used.
67  int GetCdmId();
68#endif
69
70  // Only call this once.
71  bool InitializeCDM(const std::string& key_system,
72                     const GURL& security_origin);
73
74  // May only be called after InitializeCDM() succeeds.
75  bool GenerateKeyRequest(const std::string& type,
76                          const uint8* init_data,
77                          int init_data_length);
78  void AddKey(const uint8* key, int key_length,
79              const uint8* init_data, int init_data_length,
80              const std::string& session_id);
81  void CancelKeyRequest(const std::string& session_id);
82
83 private:
84  // Helper function to create MediaKeys to handle the given |key_system|.
85  scoped_ptr<media::MediaKeys> CreateMediaKeys(const std::string& key_system,
86                                               const GURL& security_origin);
87
88  // Callbacks for firing session events.
89  void OnSessionMessage(const std::string& web_session_id,
90                        const std::vector<uint8>& message,
91                        const GURL& default_url);
92  void OnSessionKeysChange(const std::string& web_session_id,
93                           bool has_additional_usable_key);
94  void OnSessionExpirationUpdate(const std::string& web_session_id,
95                                 const base::Time& new_expiry_time);
96  void OnSessionReady(const std::string& web_session_id);
97  void OnSessionClosed(const std::string& web_session_id);
98  void OnSessionError(const std::string& web_session_id,
99                      media::MediaKeys::Exception exception_code,
100                      uint32 system_code,
101                      const std::string& error_message);
102
103  enum SessionCreationType {
104    TemporarySession,
105    PersistentSession,
106    LoadSession
107  };
108
109  // Called when a session is actually created or loaded.
110  void SetSessionId(SessionCreationType session_type,
111                    const std::string& web_session_id);
112
113#if defined(ENABLE_PEPPER_CDMS)
114  // Callback to create the Pepper plugin.
115  CreatePepperCdmCB create_pepper_cdm_cb_;
116#elif defined(ENABLE_BROWSER_CDMS)
117  RendererCdmManager* manager_;
118  int cdm_id_;
119#endif  // defined(ENABLE_PEPPER_CDMS)
120
121  // The real MediaKeys that manages key operations for the ProxyDecryptor.
122  scoped_ptr<media::MediaKeys> media_keys_;
123
124  // Callbacks for firing key events.
125  KeyAddedCB key_added_cb_;
126  KeyErrorCB key_error_cb_;
127  KeyMessageCB key_message_cb_;
128
129  // Keep track of both persistent and non-persistent sessions.
130  base::hash_map<std::string, bool> active_sessions_;
131
132  bool is_clear_key_;
133
134  // NOTE: Weak pointers must be invalidated before all other member variables.
135  base::WeakPtrFactory<ProxyDecryptor> weak_ptr_factory_;
136
137  DISALLOW_COPY_AND_ASSIGN(ProxyDecryptor);
138};
139
140}  // namespace content
141
142#endif  // CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_
143