// 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/files/file_path.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 "media/base/audio_buffer.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/cdm/api/content_decryption_module.h"
#include "ui/gfx/geometry/size.h"

namespace media {

class AudioFramesImpl;
class CdmAuxiliaryHelper;
class CdmWrapper;

class MEDIA_EXPORT CdmAdapter : public ContentDecryptionModule,
                                public CdmContext,
                                public Decryptor,
                                public cdm::Host_9,
                                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 url::Origin& security_origin,
      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,
      const 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> RegisterNewKeyCB(
      base::RepeatingClosure new_key_cb) final;
  Decryptor* GetDecryptor() final;
  int GetCdmId() const final;

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

  // cdm::Host_9 implementation.
  cdm::Buffer* Allocate(uint32_t capacity) override;
  void SetTimer(int64_t delay_ms, void* context) override;
  cdm::Time GetCurrentWallTime() 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;

  // cdm::Host_10 specific implementation.
  void OnInitialized(bool success) override;

  // cdm::Host_11 specific implementation.
  cdm::CdmProxy* RequestCdmProxy(cdm::CdmProxyClient* client) override;

 private:
  CdmAdapter(const std::string& key_system,
             const url::Origin& security_origin,
             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 std::string origin_string_;
  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_;

  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_;

  // Callbacks for new keys added.
  NewKeyCB new_audio_key_cb_;
  NewKeyCB new_video_key_cb_;

  // 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.
  double pixel_aspect_ratio_ = 0.0;

  // 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;

  bool cdm_proxy_created_ = 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_;

  DISALLOW_COPY_AND_ASSIGN(CdmAdapter);
};

}  // namespace media

#endif  // MEDIA_CDM_CDM_ADAPTER_H_
