• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <map>
9 #include <string>
10 #include <vector>
11 
12 #include "base/basictypes.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/synchronization/lock.h"
16 #include "media/base/decryptor.h"
17 #include "media/base/media_keys.h"
18 
19 class GURL;
20 
21 namespace blink {
22 #if defined(ENABLE_PEPPER_CDMS)
23 class WebFrame;
24 class WebMediaPlayerClient;
25 #endif  // defined(ENABLE_PEPPER_CDMS)
26 }
27 
28 namespace content {
29 
30 #if defined(OS_ANDROID)
31 class RendererMediaPlayerManager;
32 #endif  // defined(OS_ANDROID)
33 
34 // ProxyDecryptor is for EME v0.1b only. It should not be used for the WD API.
35 // A decryptor proxy that creates a real decryptor object on demand and
36 // forwards decryptor calls to it.
37 //
38 // Now that the Pepper API calls use session ID to match responses with
39 // requests, this class maintains a mapping between session ID and web session
40 // ID. Callers of this class expect web session IDs in the responses.
41 // Session IDs are internal unique references to the session. Web session IDs
42 // are the CDM generated ID for the session, and are what are visible to users.
43 //
44 // TODO(xhwang): Currently we don't support run-time switching among decryptor
45 // objects. Fix this when needed.
46 // TODO(xhwang): The ProxyDecryptor is not a Decryptor. Find a better name!
47 class ProxyDecryptor {
48  public:
49   // These are similar to the callbacks in media_keys.h, but pass back the
50   // web session ID rather than the internal session ID.
51   typedef base::Callback<void(const std::string& session_id)> KeyAddedCB;
52   typedef base::Callback<void(const std::string& session_id,
53                               media::MediaKeys::KeyError error_code,
54                               int system_code)> KeyErrorCB;
55   typedef base::Callback<void(const std::string& session_id,
56                               const std::vector<uint8>& message,
57                               const std::string& default_url)> KeyMessageCB;
58 
59   ProxyDecryptor(
60 #if defined(ENABLE_PEPPER_CDMS)
61       blink::WebMediaPlayerClient* web_media_player_client,
62       blink::WebFrame* web_frame,
63 #elif defined(OS_ANDROID)
64       RendererMediaPlayerManager* manager,
65       int media_keys_id,
66 #endif  // defined(ENABLE_PEPPER_CDMS)
67       const KeyAddedCB& key_added_cb,
68       const KeyErrorCB& key_error_cb,
69       const KeyMessageCB& key_message_cb);
70   virtual ~ProxyDecryptor();
71 
72   // Only call this once.
73   bool InitializeCDM(const std::string& key_system, const GURL& frame_url);
74 
75   // Requests the ProxyDecryptor to notify the decryptor when it's ready through
76   // the |decryptor_ready_cb| provided.
77   // If |decryptor_ready_cb| is null, the existing callback will be fired with
78   // NULL immediately and reset.
79   void SetDecryptorReadyCB(const media::DecryptorReadyCB& decryptor_ready_cb);
80 
81   // May only be called after InitializeCDM() succeeds.
82   bool GenerateKeyRequest(const std::string& type,
83                           const uint8* init_data,
84                           int init_data_length);
85   void AddKey(const uint8* key, int key_length,
86               const uint8* init_data, int init_data_length,
87               const std::string& session_id);
88   void CancelKeyRequest(const std::string& session_id);
89 
90  private:
91   // Session_id <-> web_session_id map.
92   typedef std::map<uint32, std::string> SessionIdMap;
93 
94   // Helper function to create MediaKeys to handle the given |key_system|.
95   scoped_ptr<media::MediaKeys> CreateMediaKeys(const std::string& key_system,
96                                                const GURL& frame_url);
97 
98   // Callbacks for firing session events.
99   void OnSessionCreated(uint32 session_id, const std::string& web_session_id);
100   void OnSessionMessage(uint32 session_id,
101                         const std::vector<uint8>& message,
102                         const std::string& default_url);
103   void OnSessionReady(uint32 session_id);
104   void OnSessionClosed(uint32 session_id);
105   void OnSessionError(uint32 session_id,
106                       media::MediaKeys::KeyError error_code,
107                       int system_code);
108 
109   // Helper function to determine session_id for the provided |web_session_id|.
110   uint32 LookupSessionId(const std::string& web_session_id);
111 
112   // Helper function to determine web_session_id for the provided |session_id|.
113   // The returned web_session_id is only valid on the main thread, and should be
114   // stored by copy.
115   const std::string& LookupWebSessionId(uint32 session_id);
116 
117   base::WeakPtrFactory<ProxyDecryptor> weak_ptr_factory_;
118 
119 #if defined(ENABLE_PEPPER_CDMS)
120   // Callback for cleaning up a Pepper-based CDM.
121   void DestroyHelperPlugin();
122 
123   // Needed to create the PpapiDecryptor.
124   blink::WebMediaPlayerClient* web_media_player_client_;
125   blink::WebFrame* web_frame_;
126 #elif defined(OS_ANDROID)
127   RendererMediaPlayerManager* manager_;
128   int media_keys_id_;
129 #endif  // defined(ENABLE_PEPPER_CDMS)
130 
131   // The real MediaKeys that manages key operations for the ProxyDecryptor.
132   // This pointer is protected by the |lock_|.
133   scoped_ptr<media::MediaKeys> media_keys_;
134 
135   // Callbacks for firing key events.
136   KeyAddedCB key_added_cb_;
137   KeyErrorCB key_error_cb_;
138   KeyMessageCB key_message_cb_;
139 
140   // Protects the |decryptor_|. Note that |decryptor_| itself should be thread
141   // safe as per the Decryptor interface.
142   base::Lock lock_;
143 
144   media::DecryptorReadyCB decryptor_ready_cb_;
145 
146   // Session IDs are used to uniquely track sessions so that CDM callbacks
147   // can get mapped to the correct session ID. Session ID should be unique
148   // per renderer process for debugging purposes.
149   static uint32 next_session_id_;
150 
151   SessionIdMap sessions_;
152 
153   bool is_clear_key_;
154 
155   DISALLOW_COPY_AND_ASSIGN(ProxyDecryptor);
156 };
157 
158 }  // namespace content
159 
160 #endif  // CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_
161