Esempio n. 1
0
already_AddRefed<DetailedPromise>
MediaKeys::SetServerCertificate(const ArrayBufferViewOrArrayBuffer& aCert, ErrorResult& aRv)
{
  RefPtr<DetailedPromise> promise(MakePromise(aRv,
    NS_LITERAL_CSTRING("MediaKeys.setServerCertificate")));
  if (aRv.Failed()) {
    return nullptr;
  }

  if (!mProxy) {
    NS_WARNING("Tried to use a MediaKeys without a CDM");
    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
                         NS_LITERAL_CSTRING("Null CDM in MediaKeys.setServerCertificate()"));
    return promise.forget();
  }

  nsTArray<uint8_t> data;
  CopyArrayBufferViewOrArrayBufferData(aCert, data);
  if (data.IsEmpty()) {
    promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
      NS_LITERAL_CSTRING("Empty certificate passed to MediaKeys.setServerCertificate()"));
    return promise.forget();
  }

  mProxy->SetServerCertificate(StorePromise(promise), data);
  return promise.forget();
}
Esempio n. 2
0
already_AddRefed<Promise>
MediaKeySession::GenerateRequest(const nsAString& aInitDataType,
                                 const ArrayBufferViewOrArrayBuffer& aInitData,
                                 ErrorResult& aRv)
{
  nsRefPtr<DetailedPromise> promise(MakePromise(aRv,
    NS_LITERAL_CSTRING("MediaKeySession.generateRequest")));
  if (aRv.Failed()) {
    return nullptr;
  }

  if (!mUninitialized) {
    EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, uninitialized",
            this, NS_ConvertUTF16toUTF8(mSessionId).get());
    promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR,
                         NS_LITERAL_CSTRING("Session is already initialized in MediaKeySession.generateRequest()"));
    return promise.forget();
  }

  mUninitialized = false;

  nsTArray<uint8_t> data;
  if (aInitDataType.IsEmpty() ||
      !CopyArrayBufferViewOrArrayBufferData(aInitData, data)) {
    promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR,
                         NS_LITERAL_CSTRING("Bad arguments to MediaKeySession.generateRequest()"));
    EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, "
            "invalid initData or initDataType",
      this, NS_ConvertUTF16toUTF8(mSessionId).get());
    return promise.forget();
  }

  // Convert initData to base64 for easier logging.
  // Note: UpdateSession() Move()s the data out of the array, so we have
  // to copy it here.
  nsAutoCString base64InitData;
  if (EME_LOG_ENABLED()) {
    nsDependentCSubstring rawInitData(reinterpret_cast<const char*>(data.Elements()),
      data.Length());
    if (NS_FAILED(Base64Encode(rawInitData, base64InitData))) {
      NS_WARNING("Failed to base64 encode initData for logging");
    }
  }

  PromiseId pid = mKeys->StorePromise(promise);
  mKeys->GetCDMProxy()->CreateSession(Token(),
                                      mSessionType,
                                      pid,
                                      aInitDataType, data);

  EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() sent, "
          "promiseId=%d initData(base64)='%s'",
          this,
          NS_ConvertUTF16toUTF8(mSessionId).get(),
          pid,
          base64InitData.get());

  return promise.forget();
}
Esempio n. 3
0
already_AddRefed<Promise>
MediaKeySession::GenerateRequest(const nsAString& aInitDataType,
                                 const ArrayBufferViewOrArrayBuffer& aInitData,
                                 ErrorResult& aRv)
{
  RefPtr<DetailedPromise> promise(MakePromise(aRv,
    NS_LITERAL_CSTRING("MediaKeySession.generateRequest")));
  if (aRv.Failed()) {
    return nullptr;
  }

  if (!mUninitialized) {
    EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, uninitialized",
            this, NS_ConvertUTF16toUTF8(mSessionId).get());
    promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR,
      NS_LITERAL_CSTRING("Session is already initialized in MediaKeySession.generateRequest()"));
    return promise.forget();
  }

  mUninitialized = false;

  if (aInitDataType.IsEmpty()) {
    promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
      NS_LITERAL_CSTRING("Empty initDataType passed to MediaKeySession.generateRequest()"));
    EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, empty initDataType",
      this, NS_ConvertUTF16toUTF8(mSessionId).get());
    return promise.forget();
  }

  nsTArray<uint8_t> data;
  CopyArrayBufferViewOrArrayBufferData(aInitData, data);
  if (data.IsEmpty()) {
    promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
      NS_LITERAL_CSTRING("Empty initData passed to MediaKeySession.generateRequest()"));
    EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, empty initData",
      this, NS_ConvertUTF16toUTF8(mSessionId).get());
    return promise.forget();
  }

  // Convert initData to base64 for easier logging.
  // Note: CreateSession() Move()s the data out of the array, so we have
  // to copy it here.
  nsAutoCString base64InitData(ToBase64(data));
  PromiseId pid = mKeys->StorePromise(promise);
  mKeys->GetCDMProxy()->CreateSession(Token(),
                                      mSessionType,
                                      pid,
                                      aInitDataType, data);

  EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() sent, "
          "promiseId=%d initData(base64)='%s' initDataType='%s'",
          this,
          NS_ConvertUTF16toUTF8(mSessionId).get(),
          pid,
          base64InitData.get(),
          NS_ConvertUTF16toUTF8(aInitDataType).get());

  return promise.forget();
}
Esempio n. 4
0
already_AddRefed<Promise>
MediaKeySession::Update(const ArrayBufferViewOrArrayBuffer& aResponse, ErrorResult& aRv)
{
  RefPtr<DetailedPromise> promise(MakePromise(aRv,
    NS_LITERAL_CSTRING("MediaKeySession.update")));
  if (aRv.Failed()) {
    return nullptr;
  }

  if (!IsCallable()) {
    // If this object's callable value is false, return a promise rejected
    // with a new DOMException whose name is InvalidStateError.
    EME_LOG("MediaKeySession[%p,''] Update() called before sessionId set by CDM", this);
    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
      NS_LITERAL_CSTRING("MediaKeySession.Update() called before sessionId set by CDM"));
    return promise.forget();
  }

  nsTArray<uint8_t> data;
  if (IsClosed() || !mKeys->GetCDMProxy()) {
    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
                         NS_LITERAL_CSTRING("Session is closed or was not properly initialized"));
    EME_LOG("MediaKeySession[%p,'%s'] Update() failed, session is closed or was not properly initialised.",
            this, NS_ConvertUTF16toUTF8(mSessionId).get());
    return promise.forget();
  }
  CopyArrayBufferViewOrArrayBufferData(aResponse, data);
  if (data.IsEmpty()) {
    promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
      NS_LITERAL_CSTRING("Empty response buffer passed to MediaKeySession.update()"));
    EME_LOG("MediaKeySession[%p,'%s'] Update() failed, empty response buffer",
            this, NS_ConvertUTF16toUTF8(mSessionId).get());
    return promise.forget();
  }


  // Convert response to base64 for easier logging.
  // Note: UpdateSession() Move()s the data out of the array, so we have
  // to copy it here.
  nsAutoCString base64Response(ToBase64(data));

  PromiseId pid = mKeys->StorePromise(promise);
  mKeys->GetCDMProxy()->UpdateSession(mSessionId,
                                      pid,
                                      data);

  EME_LOG("MediaKeySession[%p,'%s'] Update() sent to CDM, "
          "promiseId=%d Response(base64)='%s'",
           this,
           NS_ConvertUTF16toUTF8(mSessionId).get(),
           pid,
           base64Response.get());

  return promise.forget();
}
Esempio n. 5
0
already_AddRefed<Promise>
MediaKeySession::Update(const ArrayBufferViewOrArrayBuffer& aResponse, ErrorResult& aRv)
{
  nsRefPtr<DetailedPromise> promise(MakePromise(aRv,
    NS_LITERAL_CSTRING("MediaKeySession.update")));
  if (aRv.Failed()) {
    return nullptr;
  }
  nsTArray<uint8_t> data;
  if (IsClosed() || !mKeys->GetCDMProxy()) {
    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
                         NS_LITERAL_CSTRING("Session is closed or was not properly initialized"));
    EME_LOG("MediaKeySession[%p,'%s'] Update() failed, session is closed or was not properly initialised.",
            this, NS_ConvertUTF16toUTF8(mSessionId).get());
    return promise.forget();
  }
  if (!CopyArrayBufferViewOrArrayBufferData(aResponse, data)) {
    promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR,
                         NS_LITERAL_CSTRING("Invalid response buffer"));
    EME_LOG("MediaKeySession[%p,'%s'] Update() failed, invalid response buffer",
            this, NS_ConvertUTF16toUTF8(mSessionId).get());
    return promise.forget();
  }


  // Convert response to base64 for easier logging.
  // Note: UpdateSession() Move()s the data out of the array, so we have
  // to copy it here.
  nsAutoCString base64Response;
  if (EME_LOG_ENABLED()) {
    nsDependentCSubstring rawResponse(reinterpret_cast<const char*>(data.Elements()),
      data.Length());
    if (NS_FAILED(Base64Encode(rawResponse, base64Response))) {
      NS_WARNING("Failed to base64 encode response for logging");
    }
  }

  PromiseId pid = mKeys->StorePromise(promise);
  mKeys->GetCDMProxy()->UpdateSession(mSessionId,
                                      pid,
                                      data);

  EME_LOG("MediaKeySession[%p,'%s'] Update() sent to CDM, "
          "promiseId=%d Response(base64)='%s'",
           this,
           NS_ConvertUTF16toUTF8(mSessionId).get(),
           pid,
           base64Response.get());

  return promise.forget();
}
Esempio n. 6
0
already_AddRefed<Promise>
MediaKeys::SetServerCertificate(const ArrayBufferViewOrArrayBuffer& aCert, ErrorResult& aRv)
{
  nsRefPtr<Promise> promise(MakePromise(aRv));
  if (aRv.Failed()) {
    return nullptr;
  }

  nsTArray<uint8_t> data;
  if (!CopyArrayBufferViewOrArrayBufferData(aCert, data)) {
    promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
    return promise.forget();
  }

  mProxy->SetServerCertificate(StorePromise(promise), data);
  return promise.forget();
}
Esempio n. 7
0
already_AddRefed<Promise>
MediaKeySession::Update(const ArrayBufferViewOrArrayBuffer& aResponse, ErrorResult& aRv)
{
  nsRefPtr<Promise> promise(mKeys->MakePromise(aRv));
  if (aRv.Failed()) {
    return nullptr;
  }
  nsTArray<uint8_t> data;
  if (IsClosed() ||
      !mKeys->GetCDMProxy() ||
      !CopyArrayBufferViewOrArrayBufferData(aResponse, data)) {
    promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
    return promise.forget();
  }
  mKeys->GetCDMProxy()->UpdateSession(mSessionId,
                                      mKeys->StorePromise(promise),
                                      data);
  return promise.forget();
}
// Generates a license request based on the initData. A message of type
// "license-request" or "individualization-request" will always be queued
// if the algorithm succeeds and the promise is resolved.
already_AddRefed<Promise>
MediaKeySession::GenerateRequest(const nsAString& aInitDataType,
                                 const ArrayBufferViewOrArrayBuffer& aInitData,
                                 ErrorResult& aRv)
{
  RefPtr<DetailedPromise> promise(MakePromise(aRv,
    NS_LITERAL_CSTRING("MediaKeySession.generateRequest")));
  if (aRv.Failed()) {
    return nullptr;
  }

  // If this object is closed, return a promise rejected with an InvalidStateError.
  if (IsClosed()) {
    EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, closed",
            this, NS_ConvertUTF16toUTF8(mSessionId).get());
    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
      NS_LITERAL_CSTRING("Session is closed in MediaKeySession.generateRequest()"));
    return promise.forget();
  }

  // If this object's uninitialized value is false, return a promise rejected
  // with an InvalidStateError.
  if (!mUninitialized) {
    EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, uninitialized",
            this, NS_ConvertUTF16toUTF8(mSessionId).get());
    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
      NS_LITERAL_CSTRING("Session is already initialized in MediaKeySession.generateRequest()"));
    return promise.forget();
  }

  // Let this object's uninitialized value be false.
  mUninitialized = false;

  // If initDataType is the empty string, return a promise rejected
  // with a newly created TypeError.
  if (aInitDataType.IsEmpty()) {
    promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
      NS_LITERAL_CSTRING("Empty initDataType passed to MediaKeySession.generateRequest()"));
    EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, empty initDataType",
      this, NS_ConvertUTF16toUTF8(mSessionId).get());
    return promise.forget();
  }

  // If initData is an empty array, return a promise rejected with
  // a newly created TypeError.
  nsTArray<uint8_t> data;
  CopyArrayBufferViewOrArrayBufferData(aInitData, data);
  if (data.IsEmpty()) {
    promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
      NS_LITERAL_CSTRING("Empty initData passed to MediaKeySession.generateRequest()"));
    EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, empty initData",
            this, NS_ConvertUTF16toUTF8(mSessionId).get());
    return promise.forget();
  }

  // If the Key System implementation represented by this object's
  // cdm implementation value does not support initDataType as an
  // Initialization Data Type, return a promise rejected with a
  // NotSupportedError. String comparison is case-sensitive.
  if (!MediaKeySystemAccess::KeySystemSupportsInitDataType(mKeySystem, aInitDataType)) {
    promise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
      NS_LITERAL_CSTRING("Unsupported initDataType passed to MediaKeySession.generateRequest()"));
    EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() failed, unsupported initDataType",
            this, NS_ConvertUTF16toUTF8(mSessionId).get());
    return promise.forget();
  }

  // Let init data be a copy of the contents of the initData parameter.
  // Note: Handled by the CopyArrayBufferViewOrArrayBufferData call above.

  // Let session type be this object's session type.

  // Let promise be a new promise.

  // Run the following steps in parallel:

  // If the init data is not valid for initDataType, reject promise with
  // a newly created TypeError.
  if (!ValidateInitData(data, aInitDataType)) {
    // If the preceding step failed, reject promise with a newly created TypeError.
    promise->MaybeReject(NS_ERROR_DOM_TYPE_ERR,
      NS_LITERAL_CSTRING("initData sanitization failed in MediaKeySession.generateRequest()"));
    EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() initData sanitization failed",
            this, NS_ConvertUTF16toUTF8(mSessionId).get());
    return promise.forget();
  }

  // Let sanitized init data be a validated and sanitized version of init data.

  // If sanitized init data is empty, reject promise with a NotSupportedError.

  // Note: Remaining steps of generateRequest method continue in CDM.

  Telemetry::Accumulate(Telemetry::VIDEO_CDM_GENERATE_REQUEST_CALLED,
                        ToCDMTypeTelemetryEnum(mKeySystem));

  // Convert initData to base64 for easier logging.
  // Note: CreateSession() Move()s the data out of the array, so we have
  // to copy it here.
  nsAutoCString base64InitData(ToBase64(data));
  PromiseId pid = mKeys->StorePromise(promise);
  mKeys->ConnectPendingPromiseIdWithToken(pid, Token());
  mKeys->GetCDMProxy()->CreateSession(Token(),
                                      mSessionType,
                                      pid,
                                      aInitDataType, data);

  EME_LOG("MediaKeySession[%p,'%s'] GenerateRequest() sent, "
          "promiseId=%d initData(base64)='%s' initDataType='%s'",
          this,
          NS_ConvertUTF16toUTF8(mSessionId).get(),
          pid,
          base64InitData.get(),
          NS_ConvertUTF16toUTF8(aInitDataType).get());

  return promise.forget();
}