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 CHROMECAST_MEDIA_CDM_CAST_CDM_H_
6 #define CHROMECAST_MEDIA_CDM_CAST_CDM_H_
7 
8 #include <stdint.h>
9 
10 #include <map>
11 #include <string>
12 #include <vector>
13 
14 #include "base/callback.h"
15 #include "base/macros.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/sequenced_task_runner_helpers.h"
18 #include "base/threading/thread_checker.h"
19 #include "base/time/time.h"
20 #include "chromecast/media/base/media_resource_tracker.h"
21 #include "chromecast/media/cdm/cast_cdm_context.h"
22 #include "chromecast/public/media/cast_key_status.h"
23 #include "media/base/callback_registry.h"
24 #include "media/base/content_decryption_module.h"
25 #include "media/cdm/json_web_key.h"
26 
27 namespace chromecast {
28 namespace media {
29 class DecryptContextImpl;
30 
31 // CastCdm is an extension of ContentDecryptionModule that provides common
32 // functionality across CDM implementations.
33 // All these additional functions are synchronous so:
34 // - either both the CDM and the media pipeline must be running on the same
35 //   thread,
36 // - or CastCdm implementations must use some locks.
37 //
38 class CastCdm : public ::media::ContentDecryptionModule {
39  public:
40   explicit CastCdm(MediaResourceTracker* media_resource_tracker);
41 
42   void Initialize(
43       const ::media::SessionMessageCB& session_message_cb,
44       const ::media::SessionClosedCB& session_closed_cb,
45       const ::media::SessionKeysChangeCB& session_keys_change_cb,
46       const ::media::SessionExpirationUpdateCB& session_expiration_update_cb);
47 
48   std::unique_ptr<::media::CallbackRegistration> RegisterEventCB(
49       ::media::CdmContext::EventCB event_cb);
50 
51   // Returns the decryption context needed to decrypt frames encrypted with
52   // |key_id|. Returns null if |key_id| is not available.
53   virtual std::unique_ptr<DecryptContextImpl> GetDecryptContext(
54       const std::string& key_id,
55       EncryptionScheme encryption_scheme) const = 0;
56 
57   // Notifies that key status has changed (e.g. if expiry is detected by
58   // hardware decoder).
59   virtual void SetKeyStatus(const std::string& key_id,
60                             CastKeyStatus key_status,
61                             uint32_t system_code) = 0;
62 
63   // Notifies of current decoded video resolution.
64   virtual void SetVideoResolution(int width, int height) = 0;
65 
66   // ::media::ContentDecryptionModule implementation.
67   ::media::CdmContext* GetCdmContext() override;
68 
69   // Cast video products always provide HDCP or equivalent content protection.
70   void GetStatusForPolicy(
71       ::media::HdcpVersion min_hdcp_version,
72       std::unique_ptr<::media::KeyStatusCdmPromise> promise) final;
73 
74  protected:
75   ~CastCdm() override;
76 
77   void OnSessionMessage(const std::string& session_id,
78                         const std::vector<uint8_t>& message,
79                         ::media::CdmMessageType message_type);
80   void OnSessionClosed(const std::string& session_id);
81   void OnSessionKeysChange(const std::string& session_id,
82                            bool newly_usable_keys,
83                            ::media::CdmKeysInfo keys_info);
84   void OnSessionExpirationUpdate(const std::string& session_id,
85                                  base::Time new_expiry_time);
86 
87   void KeyIdAndKeyPairsToInfo(const ::media::KeyIdAndKeyPairs& keys,
88                               ::media::CdmKeysInfo* key_info);
89 
90  private:
91   // Allow subclasses to override to provide key sysytem specific
92   // initialization.
93   virtual void InitializeInternal();
94 
95   ::media::SessionMessageCB session_message_cb_;
96   ::media::SessionClosedCB session_closed_cb_;
97   ::media::SessionKeysChangeCB session_keys_change_cb_;
98   ::media::SessionExpirationUpdateCB session_expiration_update_cb_;
99 
100   // Track the usage for hardware resource. nullptr means the implementation
101   // doesn't need hardware resource.
102   MediaResourceTracker* const media_resource_tracker_;
103   std::unique_ptr<MediaResourceTracker::ScopedUsage> media_resource_usage_;
104 
105   std::unique_ptr<CastCdmContext> cast_cdm_context_;
106 
107   ::media::CallbackRegistry<::media::CdmContext::EventCB::RunType>
108       event_callbacks_;
109 
110   base::ThreadChecker thread_checker_;
111 
112   DISALLOW_COPY_AND_ASSIGN(CastCdm);
113 };
114 
115 }  // namespace media
116 }  // namespace chromecast
117 
118 #endif  // CHROMECAST_MEDIA_CDM_CAST_CDM_H_
119