summaryrefslogtreecommitdiff
path: root/chromium/media/mojo/services/mojo_cdm_service.h
blob: 7c8034245e3bbfd0be7b7778b8d8136dfb8b6230 (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
// Copyright 2014 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_MOJO_SERVICES_MOJO_CDM_SERVICE_H_
#define MEDIA_MOJO_SERVICES_MOJO_CDM_SERVICE_H_

#include <stdint.h>

#include <memory>

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "media/base/content_decryption_module.h"
#include "media/base/eme_constants.h"
#include "media/mojo/mojom/content_decryption_module.mojom.h"
#include "media/mojo/services/media_mojo_export.h"
#include "media/mojo/services/mojo_cdm_promise.h"
#include "media/mojo/services/mojo_cdm_service_context.h"
#include "media/mojo/services/mojo_decryptor_service.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace media {

class CdmFactory;

// A mojom::ContentDecryptionModule implementation backed by a
// media::ContentDecryptionModule.
class MEDIA_MOJO_EXPORT MojoCdmService final
    : public mojom::ContentDecryptionModule {
 public:
  // Callback for Initialize(). Non-null `cdm_context` indicates success. Null
  // `cdm_context` indicates failure and the `error_message` provides a reason.
  using InitializeCB =
      base::OnceCallback<void(mojom::CdmContextPtr cdm_context,
                              const std::string& error_message)>;

  explicit MojoCdmService(MojoCdmServiceContext* context);

  MojoCdmService(const MojoCdmService&) = delete;
  MojoCdmService& operator=(const MojoCdmService&) = delete;

  ~MojoCdmService() final;

  // Initialize the MojoCdmService, including creating the real CDM using the
  // `cdm_factory`, which must not be null. The MojoCdmService should NOT be
  // used before the `init_cb` is returned.
  void Initialize(CdmFactory* cdm_factory,
                  const std::string& key_system,
                  const CdmConfig& cdm_config,
                  InitializeCB init_cb);

  // mojom::ContentDecryptionModule implementation.
  void SetClient(
      mojo::PendingAssociatedRemote<mojom::ContentDecryptionModuleClient>
          client) final;
  void SetServerCertificate(const std::vector<uint8_t>& certificate_data,
                            SetServerCertificateCallback callback) final;
  void GetStatusForPolicy(HdcpVersion min_hdcp_version,
                          GetStatusForPolicyCallback callback) final;
  void CreateSessionAndGenerateRequest(
      CdmSessionType session_type,
      EmeInitDataType init_data_type,
      const std::vector<uint8_t>& init_data,
      CreateSessionAndGenerateRequestCallback callback) final;
  void LoadSession(CdmSessionType session_type,
                   const std::string& session_id,
                   LoadSessionCallback callback) final;
  void UpdateSession(const std::string& session_id,
                     const std::vector<uint8_t>& response,
                     UpdateSessionCallback callback) final;
  void CloseSession(const std::string& session_id,
                    CloseSessionCallback callback) final;
  void RemoveSession(const std::string& session_id,
                     RemoveSessionCallback callback) final;

  // Get CDM to be used by the media pipeline.
  scoped_refptr<::media::ContentDecryptionModule> GetCdm();

  // Gets the remote ID of the CDM this is holding.
  base::UnguessableToken cdm_id() const { return cdm_id_.value(); }

 private:
  // Callback for CdmFactory::Create().
  void OnCdmCreated(InitializeCB callback,
                    const scoped_refptr<::media::ContentDecryptionModule>& cdm,
                    const std::string& error_message);

  // Callbacks for firing session events.
  void OnSessionMessage(const std::string& session_id,
                        ::media::CdmMessageType message_type,
                        const std::vector<uint8_t>& message);
  void OnSessionKeysChange(const std::string& session_id,
                           bool has_additional_usable_key,
                           CdmKeysInfo keys_info);
  void OnSessionExpirationUpdate(const std::string& session_id,
                                 base::Time new_expiry_time);
  void OnSessionClosed(const std::string& session_id,
                       CdmSessionClosedReason reason);

  // Callback for when |decryptor_| loses connectivity.
  void OnDecryptorConnectionError();

  MojoCdmServiceContext* const context_;
  scoped_refptr<::media::ContentDecryptionModule> cdm_;

  // MojoDecryptorService is passed the Decryptor from |cdm_|, so
  // |decryptor_| must not outlive |cdm_|.
  std::unique_ptr<MojoDecryptorService> decryptor_;
  mojo::PendingRemote<mojom::Decryptor> decryptor_remote_;
  std::unique_ptr<mojo::Receiver<mojom::Decryptor>> decryptor_receiver_;

  // Set to a valid CDM ID if the |cdm_| is successfully created.
  absl::optional<base::UnguessableToken> cdm_id_;

  mojo::AssociatedRemote<mojom::ContentDecryptionModuleClient> client_;

  base::WeakPtrFactory<MojoCdmService> weak_factory_{this};
};

}  // namespace media

#endif  // MEDIA_MOJO_SERVICES_MOJO_CDM_SERVICE_H_