// Copyright 2015 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_CDM_ADAPTER_H_
#define MEDIA_CDM_CDM_ADAPTER_H_

#include <stdint.h>

#include <memory>
#include <string>
#include <vector>

#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 "base/scoped_native_library.h"
#include "base/threading/thread.h"
#include "components/crash/core/common/crash_key.h"
#include "media/base/audio_buffer.h"
#include "media/base/callback_registry.h"
#include "media/base/cdm_config.h"
#include "media/base/cdm_context.h"
#include "media/base/cdm_factory.h"
#include "media/base/cdm_promise_adapter.h"
#include "media/base/content_decryption_module.h"
#include "media/base/decryptor.h"
#include "media/base/media_export.h"
#include "media/base/video_aspect_ratio.h"
#include "media/cdm/api/content_decryption_module.h"
#include "ui/gfx/geometry/size.h"

namespace media {

class AudioFramesImpl;
class CdmAuxiliaryHelper;
class CdmWrapper;

class MEDIA_EXPORT CdmAdapter final : public ContentDecryptionModule,
                                      public CdmContext,
                                      public Decryptor,
                                      public cdm::Host_10,
                                      public cdm::Host_11 {
 public:
  using CreateCdmFunc = void* (*)(int cdm_interface_version,
                                  const char* key_system,
                                  uint32_t key_system_size,
                                  GetCdmHostFunc get_cdm_host_func,
                                  void* user_data);

  // Creates the CDM and initialize it using |key_system| and |cdm_config|.
  // |allocator| is to be used whenever the CDM needs memory and to create
  // VideoFrames. |file_io_provider| is to be used whenever the CDM needs access
  // to the file system. Callbacks will be used for events generated by the CDM.
  // |cdm_created_cb| will be called when the CDM is initialized.
  static void Create(
      const std::string& key_system,
      const CdmConfig& cdm_config,
      CreateCdmFunc create_cdm_func,
      std::unique_ptr<CdmAuxiliaryHelper> helper,
      const SessionMessageCB& session_message_cb,
      const SessionClosedCB& session_closed_cb,
      const SessionKeysChangeCB& session_keys_change_cb,
      const SessionExpirationUpdateCB& session_expiration_update_cb,
      CdmCreatedCB cdm_created_cb);

  // Returns the version of the CDM interface that the created CDM uses. Must
  // only be called after the CDM is successfully initialized.
  int GetInterfaceVersion();

  // ContentDecryptionModule implementation.
  void SetServerCertificate(const std::vector<uint8_t>& certificate,
                            std::unique_ptr<SimpleCdmPromise> promise) final;
  void GetStatusForPolicy(HdcpVersion min_hdcp_version,
                          std::unique_ptr<KeyStatusCdmPromise> promise) final;
  void CreateSessionAndGenerateRequest(
      CdmSessionType session_type,
      EmeInitDataType init_data_type,
      const std::vector<uint8_t>& init_data,
      std::unique_ptr<NewSessionCdmPromise> promise) final;
  void LoadSession(CdmSessionType session_type,
                   const std::string& session_id,
                   std::unique_ptr<NewSessionCdmPromise> promise) final;
  void UpdateSession(const std::string& session_id,
                     const std::vector<uint8_t>& response,
                     std::unique_ptr<SimpleCdmPromise> promise) final;
  void CloseSession(const std::string& session_id,
                    std::unique_ptr<SimpleCdmPromise> promise) final;
  void RemoveSession(const std::string& session_id,
                     std::unique_ptr<SimpleCdmPromise> promise) final;
  CdmContext* GetCdmContext() final;

  // CdmContext implementation.
  std::unique_ptr<CallbackRegistration> RegisterEventCB(EventCB event_cb) final;
  Decryptor* GetDecryptor() final;
  absl::optional<base::UnguessableToken> GetCdmId() const final;

  // Decryptor implementation.
  void Decrypt(StreamType stream_type,
               scoped_refptr<DecoderBuffer> encrypted,
               DecryptCB decrypt_cb) final;
  void CancelDecrypt(StreamType stream_type) final;
  void InitializeAudioDecoder(const AudioDecoderConfig& config,
                              DecoderInitCB init_cb) final;
  void InitializeVideoDecoder(const VideoDecoderConfig& config,
                              DecoderInitCB init_cb) final;
  void DecryptAndDecodeAudio(scoped_refptr<DecoderBuffer> encrypted,
                             AudioDecodeCB audio_decode_cb) final;
  void DecryptAndDecodeVideo(scoped_refptr<DecoderBuffer> encrypted,
                             VideoDecodeCB video_decode_cb) final;
  void ResetDecoder(StreamType stream_type) final;
  void DeinitializeDecoder(StreamType stream_type) final;

  // Common cdm::Host_10 and cdm::Host_11 implementation.
  cdm::Buffer* Allocate(uint32_t capacity) override;
  void SetTimer(int64_t delay_ms, void* context) override;
  cdm::Time GetCurrentWallTime() override;
  void OnInitialized(bool success) override;
  void OnResolveKeyStatusPromise(uint32_t promise_id,
                                 cdm::KeyStatus key_status) override;
  void OnResolveNewSessionPromise(uint32_t promise_id,
                                  const char* session_id,
                                  uint32_t session_id_size) override;
  void OnResolvePromise(uint32_t promise_id) override;
  void OnRejectPromise(uint32_t promise_id,
                       cdm::Exception exception,
                       uint32_t system_code,
                       const char* error_message,
                       uint32_t error_message_size) override;
  void OnSessionMessage(const char* session_id,
                        uint32_t session_id_size,
                        cdm::MessageType message_type,
                        const char* message,
                        uint32_t message_size) override;
  void OnSessionKeysChange(const char* session_id,
                           uint32_t session_id_size,
                           bool has_additional_usable_key,
                           const cdm::KeyInformation* keys_info,
                           uint32_t keys_info_count) override;
  void OnExpirationChange(const char* session_id,
                          uint32_t session_id_size,
                          cdm::Time new_expiry_time) override;
  void OnSessionClosed(const char* session_id,
                       uint32_t session_id_size) override;
  void SendPlatformChallenge(const char* service_id,
                             uint32_t service_id_size,
                             const char* challenge,
                             uint32_t challenge_size) override;
  void EnableOutputProtection(uint32_t desired_protection_mask) override;
  void QueryOutputProtectionStatus() override;
  void OnDeferredInitializationDone(cdm::StreamType stream_type,
                                    cdm::Status decoder_status) override;
  cdm::FileIO* CreateFileIO(cdm::FileIOClient* client) override;
  void RequestStorageId(uint32_t version) override;

 private:
  CdmAdapter(const std::string& key_system,
             const CdmConfig& cdm_config,
             CreateCdmFunc create_cdm_func,
             std::unique_ptr<CdmAuxiliaryHelper> helper,
             const SessionMessageCB& session_message_cb,
             const SessionClosedCB& session_closed_cb,
             const SessionKeysChangeCB& session_keys_change_cb,
             const SessionExpirationUpdateCB& session_expiration_update_cb);
  ~CdmAdapter() final;

  // Resolves the |promise| if the CDM is successfully initialized; rejects it
  // otherwise.
  void Initialize(std::unique_ptr<media::SimpleCdmPromise> promise);

  // Create an instance of the CDM for |key_system|.
  // Caller owns the returned pointer. Returns nullptr on error, e.g. does not
  // support |key_system|, does not support an supported interface, etc.
  CdmWrapper* CreateCdmInstance(const std::string& key_system);

  // Helper for SetTimer().
  void TimerExpired(void* context);

  // Converts audio data stored in |audio_frames| into individual audio
  // buffers in |result_frames|. Returns true upon success.
  bool AudioFramesDataToAudioFrames(
      std::unique_ptr<AudioFramesImpl> audio_frames,
      Decryptor::AudioFrames* result_frames);

  // Callbacks for Platform Verification.
  void OnChallengePlatformDone(bool success,
                               const std::string& signed_data,
                               const std::string& signed_data_signature,
                               const std::string& platform_key_certificate);
  void OnStorageIdObtained(uint32_t version,
                           const std::vector<uint8_t>& storage_id);

  // Callbacks for OutputProtection.
  void OnEnableOutputProtectionDone(bool success);
  void OnQueryOutputProtectionStatusDone(bool success,
                                         uint32_t link_mask,
                                         uint32_t protection_mask);

  // Helper methods to report output protection UMAs.
  void ReportOutputProtectionQuery();
  void ReportOutputProtectionQueryResult(uint32_t link_mask,
                                         uint32_t protection_mask);

  // Callback to report |file_size_bytes| of the file successfully read by
  // cdm::FileIO.
  void OnFileRead(int file_size_bytes);

  const std::string key_system_;
  const CdmConfig cdm_config_;

  CreateCdmFunc create_cdm_func_;

  // Helper that provides additional functionality for the CDM.
  std::unique_ptr<CdmAuxiliaryHelper> helper_;

  // Callbacks for firing session events.
  SessionMessageCB session_message_cb_;
  SessionClosedCB session_closed_cb_;
  SessionKeysChangeCB session_keys_change_cb_;
  SessionExpirationUpdateCB session_expiration_update_cb_;

  // CDM origin and crash key to be used in crash reporting.
  const std::string cdm_origin_;
  crash_reporter::ScopedCrashKeyString scoped_crash_key_;

  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
  scoped_refptr<AudioBufferMemoryPool> pool_;

  // Callback for Initialize().
  uint32_t init_promise_id_ = CdmPromiseAdapter::kInvalidPromiseId;

  // Callbacks for deferred initialization.
  DecoderInitCB audio_init_cb_;
  DecoderInitCB video_init_cb_;

  CallbackRegistry<EventCB::RunType> event_callbacks_;

  // Keep track of audio parameters.
  int audio_samples_per_second_ = 0;
  ChannelLayout audio_channel_layout_ = CHANNEL_LAYOUT_NONE;

  // Keep track of aspect ratio from the latest configuration.
  VideoAspectRatio aspect_ratio_;

  // Whether the current video config is encrypted.
  bool is_video_encrypted_ = false;

  // Tracks whether an output protection query and a positive query result (no
  // unprotected external link) have been reported to UMA.
  bool uma_for_output_protection_query_reported_ = false;
  bool uma_for_output_protection_positive_result_reported_ = false;

  // Tracks CDM file IO related states.
  int last_read_file_size_kb_ = 0;
  bool file_size_uma_reported_ = false;

  // Used to keep track of promises while the CDM is processing the request.
  CdmPromiseAdapter cdm_promise_adapter_;

  // Declare |cdm_| after other member variables to avoid the CDM accessing
  // deleted objects (e.g. |helper_|) during destruction.
  std::unique_ptr<CdmWrapper> cdm_;

  // NOTE: Weak pointers must be invalidated before all other member variables.
  base::WeakPtrFactory<CdmAdapter> weak_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(CdmAdapter);
};

}  // namespace media

#endif  // MEDIA_CDM_CDM_ADAPTER_H_
