blob: e3608572c37e6f5a0c271b37e2dea0c0ff2e0fda [file] [log] [blame]
// 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/fuchsia/cdm/service/provisioning_fetcher_impl.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/fuchsia/mem_buffer_util.h"
#include "base/logging.h"
namespace media {
ProvisioningFetcherImpl::ProvisioningFetcherImpl(
CreateFetcherCB create_fetcher_callback)
: create_fetcher_callback_(std::move(create_fetcher_callback)),
binding_(this) {
DCHECK(create_fetcher_callback_);
}
ProvisioningFetcherImpl::~ProvisioningFetcherImpl() = default;
fidl::InterfaceHandle<fuchsia::media::drm::ProvisioningFetcher>
ProvisioningFetcherImpl::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 ProvisioningFetcherImpl::Fetch(
fuchsia::media::drm::ProvisioningRequest request,
FetchCallback callback) {
if (retrieve_in_progress_) {
DLOG(WARNING)
<< "ProvisioningFetcherImpl received too many ProvisioningRequests";
OnError(ZX_ERR_BAD_STATE);
return;
}
absl::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::BindRepeating(&ProvisioningFetcherImpl::OnRetrieveComplete,
base::Unretained(this),
base::Passed(std::move(callback))));
}
void ProvisioningFetcherImpl::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 ProvisioningFetcherImpl::OnError(zx_status_t status) {
DCHECK(error_callback_);
binding_.Close(status);
std::move(error_callback_).Run();
}
} // namespace media