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

media / mojo / services / fuchsia_cdm_provisioning_fetcher_impl.cc [blame]

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/mojo/services/fuchsia_cdm_provisioning_fetcher_impl.h"

#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/mem_buffer_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/logging.h"

namespace media {

FuchsiaCdmProvisioningFetcherImpl::FuchsiaCdmProvisioningFetcherImpl(
    CreateFetcherCB create_fetcher_callback)
    : create_fetcher_callback_(std::move(create_fetcher_callback)),
      binding_(this) {
  DCHECK(create_fetcher_callback_);
}

FuchsiaCdmProvisioningFetcherImpl::~FuchsiaCdmProvisioningFetcherImpl() =
    default;

fidl::InterfaceHandle<fuchsia::media::drm::ProvisioningFetcher>
FuchsiaCdmProvisioningFetcherImpl::Bind(base::OnceClosure error_callback) {
  error_callback_ = std::move(error_callback);

  binding_.set_error_handler(
      [&error_callback = error_callback_](zx_status_t status) {
        ZX_DLOG_IF(ERROR, (status != ZX_OK) && (status != ZX_ERR_PEER_CLOSED),
                   status)
            << "ProvisioningFetcher closed with an unexpected status";
        std::move(error_callback).Run();
      });
  return binding_.NewBinding();
}

void FuchsiaCdmProvisioningFetcherImpl::Fetch(
    fuchsia::media::drm::ProvisioningRequest request,
    FetchCallback callback) {
  if (retrieve_in_progress_) {
    DLOG(WARNING) << "Received too many ProvisioningRequests.";
    OnError(ZX_ERR_BAD_STATE);
    return;
  }

  std::optional<std::string> request_str =
      base::StringFromMemBuffer(request.message);
  if (!request_str) {
    DLOG(WARNING) << "Failed to read ProvisioningRequest.";
    OnError(ZX_ERR_INVALID_ARGS);
    return;
  }

  if (!request.default_provisioning_server_url) {
    DLOG(WARNING) << "Missing default provisioning server URL.";
    OnError(ZX_ERR_INVALID_ARGS);
    return;
  }

  if (!fetcher_) {
    fetcher_ = create_fetcher_callback_.Run();
  }

  retrieve_in_progress_ = true;
  fetcher_->Retrieve(
      GURL(request.default_provisioning_server_url.value()), *request_str,
      base::BindOnce(&FuchsiaCdmProvisioningFetcherImpl::OnRetrieveComplete,
                     base::Unretained(this), std::move(callback)));
}

void FuchsiaCdmProvisioningFetcherImpl::OnRetrieveComplete(
    FetchCallback callback,
    bool success,
    const std::string& response) {
  retrieve_in_progress_ = false;
  // Regardless of success or failure, send the response back to acknowledge
  // it has been completed.
  DLOG_IF(WARNING, !success) << "Failed to fetch provision response.";

  fuchsia::media::drm::ProvisioningResponse provision_response;
  provision_response.message =
      base::MemBufferFromString(response, "cr-drm-provision-response");

  callback(std::move(provision_response));
}

void FuchsiaCdmProvisioningFetcherImpl::OnError(zx_status_t status) {
  DCHECK(error_callback_);

  binding_.Close(status);
  std::move(error_callback_).Run();
}

}  // namespace media