// Copyright 2020 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.

#include "media/renderers/win/media_foundation_protection_manager.h"

#include <mferror.h>
#include <windows.foundation.h>

#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/win/core_winrt_util.h"
#include "base/win/scoped_hstring.h"
#include "base/win/windows_types.h"
#include "media/base/win/mf_helpers.h"

namespace media {

using Microsoft::WRL::ComPtr;

MediaFoundationProtectionManager::MediaFoundationProtectionManager() {
  DVLOG_FUNC(1);
}

MediaFoundationProtectionManager::~MediaFoundationProtectionManager() {
  DVLOG_FUNC(1);
}

HRESULT MediaFoundationProtectionManager::RuntimeClassInitialize(
    scoped_refptr<base::SequencedTaskRunner> task_runner,
    WaitingCB waiting_cb) {
  DVLOG_FUNC(1);

  task_runner_ = std::move(task_runner);
  waiting_cb_ = std::move(waiting_cb);

  if (!base::win::ScopedHString::ResolveCoreWinRTStringDelayload())
    return E_FAIL;

  // Init an empty |property_set_| as MFMediaEngine could access it via
  // |get_Properties| before we populate it within SetPMPServer.
  base::win::ScopedHString property_set_id = base::win::ScopedHString::Create(
      RuntimeClass_Windows_Foundation_Collections_PropertySet);
  RETURN_IF_FAILED(
      base::win::RoActivateInstance(property_set_id.get(), &property_set_));
  return S_OK;
}

HRESULT MediaFoundationProtectionManager::SetCdmProxy(
    scoped_refptr<MediaFoundationCdmProxy> cdm_proxy) {
  DVLOG_FUNC(1);

  DCHECK(cdm_proxy);
  cdm_proxy_ = std::move(cdm_proxy);
  ComPtr<ABI::Windows::Media::Protection::IMediaProtectionPMPServer> pmp_server;
  RETURN_IF_FAILED(cdm_proxy_->GetPMPServer(IID_PPV_ARGS(&pmp_server)));
  RETURN_IF_FAILED(SetPMPServer(pmp_server.Get()));
  return S_OK;
}

HRESULT MediaFoundationProtectionManager::SetPMPServer(
    ABI::Windows::Media::Protection::IMediaProtectionPMPServer* pmp_server) {
  DVLOG_FUNC(1);

  DCHECK(pmp_server);
  ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>
      property_map;
  RETURN_IF_FAILED(property_set_.As(&property_map));

  // MFMediaEngine uses |pmp_server_key| to get the Protected Media Path (PMP)
  // server used for playing protected content. This is not currently documented
  // in MSDN.
  boolean replaced = false;
  base::win::ScopedHString pmp_server_key = base::win::ScopedHString::Create(
      L"Windows.Media.Protection.MediaProtectionPMPServer");
  RETURN_IF_FAILED(
      property_map->Insert(pmp_server_key.get(), pmp_server, &replaced));
  return S_OK;
}

HRESULT MediaFoundationProtectionManager::BeginEnableContent(
    IMFActivate* enabler_activate,
    IMFTopology* topology,
    IMFAsyncCallback* callback,
    IUnknown* state) {
  DVLOG_FUNC(1);

  ComPtr<IUnknown> unknown_object;
  ComPtr<IMFAsyncResult> async_result;
  RETURN_IF_FAILED(
      MFCreateAsyncResult(nullptr, callback, state, &async_result));
  RETURN_IF_FAILED(
      enabler_activate->ActivateObject(IID_PPV_ARGS(&unknown_object)));

  // |enabler_type| can be obtained from IMFContentEnabler
  // (https://docs.microsoft.com/en-us/windows/win32/api/mfidl/nn-mfidl-imfcontentenabler).
  // If not, try IMediaProtectionServiceRequest
  // (https://docs.microsoft.com/en-us/uwp/api/windows.media.protection.imediaprotectionservicerequest).
  GUID enabler_type = GUID_NULL;
  ComPtr<IMFContentEnabler> content_enabler;
  if (SUCCEEDED(unknown_object.As(&content_enabler))) {
    RETURN_IF_FAILED(content_enabler->GetEnableType(&enabler_type));
  } else {
    ComPtr<ABI::Windows::Media::Protection::IMediaProtectionServiceRequest>
        service_request;
    RETURN_IF_FAILED(unknown_object.As(&service_request));
    RETURN_IF_FAILED(service_request->get_Type(&enabler_type));
  }

  if (enabler_type == MFENABLETYPE_MF_RebootRequired) {
    DLOG(ERROR) << __func__ << ": MF_E_REBOOT_REQUIRED";
    return MF_E_REBOOT_REQUIRED;
  } else if (enabler_type == MFENABLETYPE_MF_UpdateRevocationInformation) {
    DLOG(ERROR) << __func__ << ": MF_E_GRL_VERSION_TOO_LOW";
    return MF_E_GRL_VERSION_TOO_LOW;
  } else if (enabler_type == MFENABLETYPE_MF_UpdateUntrustedComponent) {
    auto hr = HRESULT_FROM_WIN32(ERROR_INVALID_IMAGE_HASH);
    DLOG(ERROR) << __func__ << ": hr=" << hr;
    return hr;
  } else {
    RETURN_IF_FAILED(cdm_proxy_->ProcessContentEnabler(unknown_object.Get(),
                                                       async_result.Get()));

    // Force post task so `OnBeginEnableContent()` and `OnEndEnableContent()`
    // are always in sequence.
    task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&MediaFoundationProtectionManager::OnBeginEnableContent,
                       weak_factory_.GetWeakPtr()));
  }
  return S_OK;
}

HRESULT MediaFoundationProtectionManager::EndEnableContent(
    IMFAsyncResult* async_result) {
  DVLOG_FUNC(1);

  // Force post task so `OnBeginEnableContent()` and `OnEndEnableContent()` are
  // always in sequence.
  task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&MediaFoundationProtectionManager::OnEndEnableContent,
                     weak_factory_.GetWeakPtr()));

  // Get status from the given |async_result| for the purpose of logging.
  // Returns S_OK as there is no additional work being done here.
  HRESULT async_status = async_result->GetStatus();
  if (FAILED(async_status)) {
    DLOG(ERROR) << "Content enabling failed. hr=" << async_status;
  } else {
    DVLOG(2) << "Content enabling succeeded";
  }
  return S_OK;
}

// IMediaProtectionManager implementation
HRESULT MediaFoundationProtectionManager::add_ServiceRequested(
    ABI::Windows::Media::Protection::IServiceRequestedEventHandler* handler,
    EventRegistrationToken* cookie) {
  return E_NOTIMPL;
}

HRESULT MediaFoundationProtectionManager::remove_ServiceRequested(
    EventRegistrationToken cookie) {
  return E_NOTIMPL;
}

HRESULT MediaFoundationProtectionManager::add_RebootNeeded(
    ABI::Windows::Media::Protection::IRebootNeededEventHandler* handler,
    EventRegistrationToken* cookie) {
  return E_NOTIMPL;
}

HRESULT MediaFoundationProtectionManager::remove_RebootNeeded(
    EventRegistrationToken cookie) {
  return E_NOTIMPL;
}

HRESULT MediaFoundationProtectionManager::add_ComponentLoadFailed(
    ABI::Windows::Media::Protection::IComponentLoadFailedEventHandler* handler,
    EventRegistrationToken* cookie) {
  return E_NOTIMPL;
}

HRESULT MediaFoundationProtectionManager::remove_ComponentLoadFailed(
    EventRegistrationToken cookie) {
  return E_NOTIMPL;
}

HRESULT MediaFoundationProtectionManager::get_Properties(
    ABI::Windows::Foundation::Collections::IPropertySet** properties) {
  DVLOG_FUNC(2);
  if (!properties)
    return E_POINTER;
  return property_set_.CopyTo(properties);
}

void MediaFoundationProtectionManager::OnBeginEnableContent() {
  DVLOG_FUNC(2);
  DCHECK(task_runner_->RunsTasksInCurrentSequence());

  // If EnableContent takes too long, report waiting for key status. Choose a
  // timeout of 500ms to be on the safe side, e.g. on slower machines.
  const auto kWaitingForKeyTimeOut = base::Milliseconds(500);

  waiting_for_key_time_out_cb_.Reset(
      base::BindOnce(&MediaFoundationProtectionManager::OnWaitingForKeyTimeOut,
                     weak_factory_.GetWeakPtr()));
  task_runner_->PostDelayedTask(FROM_HERE,
                                waiting_for_key_time_out_cb_.callback(),
                                kWaitingForKeyTimeOut);
}

void MediaFoundationProtectionManager::OnEndEnableContent() {
  DVLOG_FUNC(2);
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
  waiting_for_key_time_out_cb_.Cancel();
}

void MediaFoundationProtectionManager::OnWaitingForKeyTimeOut() {
  DVLOG_FUNC(2);
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
  waiting_for_key_time_out_cb_.Cancel();
  waiting_cb_.Run(WaitingReason::kNoDecryptionKey);
}

}  // namespace media