summaryrefslogtreecommitdiffstats
path: root/media/cdm/proxy_decryptor.h
blob: bcf34c218cca2827c9642ae8a0d78d9f8f059f9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_CDM_PROXY_DECRYPTOR_H_
#define MEDIA_CDM_PROXY_DECRYPTOR_H_

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "media/base/cdm_context.h"
#include "media/base/decryptor.h"
#include "media/base/eme_constants.h"
#include "media/base/media_export.h"
#include "media/base/media_keys.h"
#include "url/gurl.h"

namespace media {

class CdmFactory;
class MediaPermission;

// ProxyDecryptor is for EME v0.1b only. It should not be used for the WD API.
// A decryptor proxy that creates a real decryptor object on demand and
// forwards decryptor calls to it.
//
// TODO(xhwang): Currently we don't support run-time switching among decryptor
// objects. Fix this when needed.
// TODO(xhwang): The ProxyDecryptor is not a Decryptor. Find a better name!
class MEDIA_EXPORT ProxyDecryptor {
 public:
  // Callback to provide a CdmContext when the CDM creation is finished.
  // If CDM creation failed, |cdm_context| will be null.
  typedef base::Callback<void(CdmContext* cdm_context)> CdmContextReadyCB;

  // These are similar to the callbacks in media_keys.h, but pass back the
  // session ID rather than the internal session ID.
  typedef base::Callback<void(const std::string& session_id)> KeyAddedCB;
  typedef base::Callback<void(const std::string& session_id,
                              MediaKeys::KeyError error_code,
                              uint32 system_code)> KeyErrorCB;
  typedef base::Callback<void(const std::string& session_id,
                              const std::vector<uint8>& message,
                              const GURL& destination_url)> KeyMessageCB;

  ProxyDecryptor(MediaPermission* media_permission,
                 bool use_hw_secure_codecs,
                 const KeyAddedCB& key_added_cb,
                 const KeyErrorCB& key_error_cb,
                 const KeyMessageCB& key_message_cb);
  virtual ~ProxyDecryptor();

  // Creates the CDM and fires |cdm_created_cb|. This method should only be
  // called once. If CDM creation failed, all following GenerateKeyRequest,
  // AddKey and CancelKeyRequest calls will result in a KeyError.
  void CreateCdm(CdmFactory* cdm_factory,
                 const std::string& key_system,
                 const GURL& security_origin,
                 const CdmContextReadyCB& cdm_context_ready_cb);

  // May only be called after CreateCDM().
  void GenerateKeyRequest(EmeInitDataType init_data_type,
                          const uint8* init_data,
                          int init_data_length);
  void AddKey(const uint8* key, int key_length,
              const uint8* init_data, int init_data_length,
              const std::string& session_id);
  void CancelKeyRequest(const std::string& session_id);

 private:
  // Callback for CreateCdm().
  void OnCdmCreated(const std::string& key_system,
                    const GURL& security_origin,
                    const CdmContextReadyCB& cdm_context_ready_cb,
                    const scoped_refptr<MediaKeys>& cdm,
                    const std::string& error_message);

  void GenerateKeyRequestInternal(EmeInitDataType init_data_type,
                                  const std::vector<uint8>& init_data);

  // Callbacks for firing session events.
  void OnSessionMessage(const std::string& session_id,
                        MediaKeys::MessageType message_type,
                        const std::vector<uint8>& message,
                        const GURL& legacy_destination_url);
  void OnSessionKeysChange(const std::string& session_id,
                           bool has_additional_usable_key,
                           CdmKeysInfo keys_info);
  void OnSessionExpirationUpdate(const std::string& session_id,
                                 const base::Time& new_expiry_time);
  void GenerateKeyAdded(const std::string& session_id);
  void OnSessionClosed(const std::string& session_id);
  void OnLegacySessionError(const std::string& session_id,
                            MediaKeys::Exception exception_code,
                            uint32 system_code,
                            const std::string& error_message);

  // Callback for permission request.
  void OnPermissionStatus(MediaKeys::SessionType session_type,
                          EmeInitDataType init_data_type,
                          const std::vector<uint8>& init_data,
                          scoped_ptr<NewSessionCdmPromise> promise,
                          bool granted);

  enum SessionCreationType {
    TemporarySession,
    PersistentSession,
    LoadSession
  };

  // Called when a session is actually created or loaded.
  void SetSessionId(SessionCreationType session_type,
                    const std::string& session_id);

  struct PendingGenerateKeyRequestData {
    PendingGenerateKeyRequestData(EmeInitDataType init_data_type,
                                  const std::vector<uint8>& init_data);
    ~PendingGenerateKeyRequestData();

    const EmeInitDataType init_data_type;
    const std::vector<uint8> init_data;
  };

  bool is_creating_cdm_;

  // The real MediaKeys that manages key operations for the ProxyDecryptor.
  scoped_refptr<MediaKeys> media_keys_;

#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
  MediaPermission* media_permission_;
#endif

  bool use_hw_secure_codecs_;

  // Callbacks for firing key events.
  KeyAddedCB key_added_cb_;
  KeyErrorCB key_error_cb_;
  KeyMessageCB key_message_cb_;

  std::string key_system_;
  GURL security_origin_;

  // Keep track of both persistent and non-persistent sessions.
  base::hash_map<std::string, bool> active_sessions_;

  bool is_clear_key_;

  ScopedVector<PendingGenerateKeyRequestData> pending_requests_;

  // NOTE: Weak pointers must be invalidated before all other member variables.
  base::WeakPtrFactory<ProxyDecryptor> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(ProxyDecryptor);
};

}  // namespace media

#endif  // MEDIA_CDM_PROXY_DECRYPTOR_H_