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_BROWSER_MEDIA_CDM_BROWSER_CDM_MANAGER_H_
6#define CONTENT_BROWSER_MEDIA_CDM_BROWSER_CDM_MANAGER_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/basictypes.h"
13#include "base/callback.h"
14#include "base/containers/scoped_ptr_hash_map.h"
15#include "base/memory/scoped_ptr.h"
16#include "content/common/content_export.h"
17#include "content/common/media/cdm_messages_enums.h"
18#include "content/public/browser/browser_message_filter.h"
19#include "ipc/ipc_message.h"
20// TODO(xhwang): Drop this when KeyError is moved to a common header.
21#include "media/base/media_keys.h"
22#include "url/gurl.h"
23
24namespace media {
25class BrowserCdm;
26}
27
28namespace content {
29
30// This class manages all CDM objects. It receives control operations from the
31// the render process, and forwards them to corresponding CDM object. Callbacks
32// from CDM objects are converted to IPCs and then sent to the render process.
33class CONTENT_EXPORT BrowserCdmManager : public BrowserMessageFilter {
34 public:
35  // Returns the BrowserCdmManager associated with the |render_process_id|.
36  // Returns NULL if no BrowserCdmManager is associated.
37  static BrowserCdmManager* FromProcess(int render_process_id);
38
39  // Constructs the BrowserCdmManager for |render_process_id| which runs on
40  // |task_runner|.
41  // If |task_runner| is not NULL, all CDM messages are posted to it. Otherwise,
42  // all messages are posted to the browser UI thread.
43  BrowserCdmManager(int render_process_id,
44                    const scoped_refptr<base::TaskRunner>& task_runner);
45
46  // BrowserMessageFilter implementations.
47  virtual void OnDestruct() const OVERRIDE;
48  virtual base::TaskRunner* OverrideTaskRunnerForMessage(
49      const IPC::Message& message) OVERRIDE;
50  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
51
52  media::BrowserCdm* GetCdm(int render_frame_id, int cdm_id);
53
54  // Notifies that the render frame has been deleted so that all CDMs belongs
55  // to this render frame needs to be destroyed as well. This is needed because
56  // in some cases (e.g. fast termination of the renderer), the message to
57  // destroy the CDM will not be received.
58  void RenderFrameDeleted(int render_frame_id);
59
60 protected:
61  friend class base::RefCountedThreadSafe<BrowserCdmManager>;
62  friend class base::DeleteHelper<BrowserCdmManager>;
63  virtual ~BrowserCdmManager();
64
65 private:
66  // CDM callbacks.
67  void OnSessionCreated(int render_frame_id,
68                        int cdm_id,
69                        uint32 session_id,
70                        const std::string& web_session_id);
71  void OnSessionMessage(int render_frame_id,
72                        int cdm_id,
73                        uint32 session_id,
74                        const std::vector<uint8>& message,
75                        const GURL& destination_url);
76  void OnSessionReady(int render_frame_id, int cdm_id, uint32 session_id);
77  void OnSessionClosed(int render_frame_id, int cdm_id, uint32 session_id);
78  void OnSessionError(int render_frame_id,
79                      int cdm_id,
80                      uint32 session_id,
81                      media::MediaKeys::KeyError error_code,
82                      uint32 system_code);
83
84  // Message handlers.
85  void OnInitializeCdm(int render_frame_id,
86                       int cdm_id,
87                       const std::string& key_system,
88                       const GURL& frame_url);
89  void OnCreateSession(int render_frame_id,
90                       int cdm_id,
91                       uint32 session_id,
92                       CdmHostMsg_CreateSession_ContentType content_type,
93                       const std::vector<uint8>& init_data);
94  void OnUpdateSession(int render_frame_id,
95                       int cdm_id,
96                       uint32 session_id,
97                       const std::vector<uint8>& response);
98  void OnReleaseSession(int render_frame_id,
99                        int cdm_id, uint32 session_id);
100  void OnDestroyCdm(int render_frame_id, int cdm_id);
101
102  void SendSessionError(int render_frame_id, int cdm_id, uint32 session_id);
103
104  // Adds a new CDM identified by |cdm_id| for the given |key_system| and
105  // |security_origin|.
106  void AddCdm(int render_frame_id,
107              int cdm_id,
108              const std::string& key_system,
109              const GURL& security_origin);
110
111  // Removes the CDM with the specified id.
112  void RemoveCdm(uint64 id);
113
114  // If |permitted| is false, it does nothing but send
115  // |CdmMsg_SessionError| IPC message.
116  // The primary use case is infobar permission callback, i.e., when infobar
117  // can decide user's intention either from interacting with the actual info
118  // bar or from the saved preference.
119  void CreateSessionIfPermitted(int render_frame_id,
120                                int cdm_id,
121                                uint32 session_id,
122                                const std::string& content_type,
123                                const std::vector<uint8>& init_data,
124                                bool permitted);
125
126  const int render_process_id_;
127
128  // TaskRunner to dispatch all CDM messages to. If it's NULL, all messages are
129  // dispatched to the browser UI thread.
130  scoped_refptr<base::TaskRunner> task_runner_;
131
132  // The key in the following maps is a combination of |render_frame_id| and
133  // |cdm_id|.
134
135  // Map of managed BrowserCdms.
136  typedef base::ScopedPtrHashMap<uint64, media::BrowserCdm> CdmMap;
137  CdmMap cdm_map_;
138
139  // Map of CDM's security origin.
140  std::map<uint64, GURL> cdm_security_origin_map_;
141
142  // Map of callbacks to cancel the permission request.
143  std::map<uint64, base::Closure> cdm_cancel_permission_map_;
144
145  DISALLOW_COPY_AND_ASSIGN(BrowserCdmManager);
146};
147
148}  // namespace content
149
150#endif  // CONTENT_BROWSER_MEDIA_CDM_BROWSER_CDM_MANAGER_H_
151