cdm_promise.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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. #ifndef MEDIA_BASE_CDM_PROMISE_H_
  5. #define MEDIA_BASE_CDM_PROMISE_H_
  6. #include <stdint.h>
  7. #include <string>
  8. #include "base/check.h"
  9. #include "base/logging.h"
  10. #include "media/base/cdm_key_information.h"
  11. #include "media/base/media_export.h"
  12. namespace media {
  13. // Interface for promises being resolved/rejected in response to various
  14. // session actions. These may be called synchronously or asynchronously.
  15. // The promise must be resolved or rejected exactly once. It is expected that
  16. // the caller free the promise once it is resolved/rejected.
  17. // These classes are almost generic, except for the parameters to reject(). If
  18. // a generic class for promises is available, this could be changed to use the
  19. // generic class as long as the parameters to reject() can be set appropriately.
  20. // The base class only has a reject() method and GetResolveParameterType() that
  21. // indicates the type of CdmPromiseTemplate. CdmPromiseTemplate<T> adds the
  22. // resolve(T) method that is dependent on the type of promise. This base class
  23. // is specified so that the promises can be easily saved before passing across
  24. // IPC.
  25. class MEDIA_EXPORT CdmPromise {
  26. public:
  27. enum class Exception {
  28. NOT_SUPPORTED_ERROR,
  29. INVALID_STATE_ERROR,
  30. QUOTA_EXCEEDED_ERROR,
  31. TYPE_ERROR,
  32. EXCEPTION_MAX = TYPE_ERROR
  33. };
  34. enum ResolveParameterType {
  35. VOID_TYPE,
  36. INT_TYPE,
  37. STRING_TYPE,
  38. KEY_STATUS_TYPE
  39. };
  40. // These values are reported to UMA. Never change existing values. Only add
  41. // new values at the bottom of the list.
  42. // TODO(xhwang): Make SystemCode an enum class and pass |system_code| as
  43. // SystemCode everywhere.
  44. enum SystemCode : uint32_t {
  45. kMinValue = 1000000, // To avoid conflict with system code reported by CDM.
  46. kOk = kMinValue,
  47. kFailure,
  48. kAborted,
  49. kConnectionError,
  50. kMaxValue = kConnectionError,
  51. };
  52. CdmPromise() = default;
  53. CdmPromise(const CdmPromise&) = delete;
  54. CdmPromise& operator=(const CdmPromise&) = delete;
  55. virtual ~CdmPromise() = default;
  56. // Used to indicate that the operation failed. |exception_code| must be
  57. // specified. |system_code| is a Key System-specific value for the error
  58. // that occurred, or 0 if there is no associated status code or such status
  59. // codes are not supported by the Key System. |error_message| is optional.
  60. virtual void reject(Exception exception_code,
  61. uint32_t system_code,
  62. const std::string& error_message) = 0;
  63. // Used to determine the template type of CdmPromiseTemplate<T> so that
  64. // saved CdmPromise objects can be cast to the correct templated version.
  65. virtual ResolveParameterType GetResolveParameterType() const = 0;
  66. };
  67. template <typename... T>
  68. struct CdmPromiseTraits {};
  69. template <>
  70. struct MEDIA_EXPORT CdmPromiseTraits<> {
  71. static const CdmPromise::ResolveParameterType kType;
  72. };
  73. template <>
  74. struct MEDIA_EXPORT CdmPromiseTraits<int> {
  75. static const CdmPromise::ResolveParameterType kType;
  76. };
  77. template <>
  78. struct MEDIA_EXPORT CdmPromiseTraits<std::string> {
  79. static const CdmPromise::ResolveParameterType kType;
  80. };
  81. template <>
  82. struct MEDIA_EXPORT CdmPromiseTraits<CdmKeyInformation::KeyStatus> {
  83. static const CdmPromise::ResolveParameterType kType;
  84. };
  85. // This class adds the resolve(T) method. This class is still an interface, and
  86. // is used as the type of promise that gets passed around.
  87. template <typename... T>
  88. class CdmPromiseTemplate : public CdmPromise {
  89. public:
  90. CdmPromiseTemplate() : is_settled_(false) {}
  91. CdmPromiseTemplate(const CdmPromiseTemplate&) = delete;
  92. CdmPromiseTemplate& operator=(const CdmPromiseTemplate&) = delete;
  93. virtual ~CdmPromiseTemplate() { DCHECK(is_settled_); }
  94. virtual void resolve(const T&... result) = 0;
  95. // CdmPromise implementation.
  96. ResolveParameterType GetResolveParameterType() const final;
  97. protected:
  98. bool IsPromiseSettled() const { return is_settled_; }
  99. // All implementations must call this method in resolve() and reject() methods
  100. // to indicate that the promise has been settled.
  101. void MarkPromiseSettled() {
  102. // Promise can only be settled once.
  103. DCHECK(!is_settled_);
  104. is_settled_ = true;
  105. }
  106. // Must be called by the concrete destructor if !IsPromiseSettled().
  107. // Note: We can't call reject() in ~CdmPromise() because reject() is virtual.
  108. void RejectPromiseOnDestruction() {
  109. DCHECK(!is_settled_);
  110. std::string message =
  111. "Unfulfilled promise rejected automatically during destruction.";
  112. DVLOG(1) << message;
  113. reject(Exception::INVALID_STATE_ERROR, SystemCode::kAborted, message);
  114. DCHECK(is_settled_);
  115. }
  116. private:
  117. // Keep track of whether the promise has been resolved or rejected yet.
  118. bool is_settled_;
  119. };
  120. // Explicitly defining all variants of GetResolveParameterType().
  121. // Without this component builds on Windows fail due to versions of the same
  122. // method being generated in multiple DLLs.
  123. template <>
  124. MEDIA_EXPORT CdmPromise::ResolveParameterType
  125. CdmPromiseTemplate<>::GetResolveParameterType() const;
  126. template <>
  127. MEDIA_EXPORT CdmPromise::ResolveParameterType
  128. CdmPromiseTemplate<int>::GetResolveParameterType() const;
  129. template <>
  130. MEDIA_EXPORT CdmPromise::ResolveParameterType
  131. CdmPromiseTemplate<std::string>::GetResolveParameterType() const;
  132. template <>
  133. MEDIA_EXPORT CdmPromise::ResolveParameterType CdmPromiseTemplate<
  134. CdmKeyInformation::KeyStatus>::GetResolveParameterType() const;
  135. // A dummy CdmPromise that does nothing. Used for APIs requiring a CdmPromise
  136. // while the result will be ignored.
  137. template <typename... T>
  138. class MEDIA_EXPORT DoNothingCdmPromise : public CdmPromiseTemplate<T...> {
  139. public:
  140. DoNothingCdmPromise() = default;
  141. DoNothingCdmPromise(const DoNothingCdmPromise&) = delete;
  142. DoNothingCdmPromise& operator=(const DoNothingCdmPromise&) = delete;
  143. ~DoNothingCdmPromise() override = default;
  144. // CdmPromiseTemplate.
  145. void resolve() final { CdmPromiseTemplate<T...>::MarkPromiseSettled(); }
  146. void reject(CdmPromise::Exception exception_code,
  147. uint32_t system_code,
  148. const std::string& error_message) final {
  149. CdmPromiseTemplate<T...>::MarkPromiseSettled();
  150. }
  151. };
  152. } // namespace media
  153. #endif // MEDIA_BASE_CDM_PROMISE_H_