/*! \brief Creates and initialises a model info object. * * \return A valid model info object or \c NULL if unable to acquire * the necessary memory resources. */ static _model_info_t * _model_info_ctor (const char *fw_name, SANE_Status *status) { SANE_Status s = SANE_STATUS_GOOD; _model_info_t *self = NULL; log_call ("(%s)", fw_name); require (fw_name); self = t_calloc (1, _model_info_t); if (!self) { if (status) *status = SANE_STATUS_NO_MEM; return NULL; } self->fw_name = strdup (fw_name); if (!self->fw_name) { _model_info_dtor (self); if (status) *status = SANE_STATUS_NO_MEM; return NULL; } /* Set defaults using data defined in the source code. The various * getters decide a decent default in case self->fw_name is not one * of the names for which we have data in our sources. */ self->overseas = get_scanner_data (self->fw_name, MODEL_OVERSEAS); self->japan = get_scanner_data (self->fw_name, MODEL_JAPAN); self->profile = get_epson_scan_hard (self->fw_name); self->command = get_scan_command (self->fw_name); self->from_file = false; s = _model_info_merge_file (self); self->name = _model_info_guess_name (self); if (self) /* make sure things are compliant */ { promise (self->fw_name && self->name); promise ( self->name == self->fw_name || self->name == self->overseas || self->name == self->japan); promise (self->profile); promise (self->command); } if (status) *status = s; return self; }
boost::shared_ptr<cql::cql_connection_t> cql::cql_session_impl_t::allocate_connection( const boost::shared_ptr<cql_host_t>& host) { if (!increase_connection_counter(host)) { throw cql_too_many_connections_per_host_exception(); } boost::shared_ptr<cql_promise_t<cql_future_connection_t> > promise( new cql_promise_t<cql_future_connection_t>()); boost::shared_ptr<cql_connection_t> connection(_client_callback()); connection->set_credentials(_configuration->credentials()); connection->connect(host->endpoint(), boost::bind(&cql_session_impl_t::connect_callback, this->shared_from_this(), promise, ::_1), boost::bind(&cql_session_impl_t::connect_errback, this->shared_from_this(), promise, ::_1, ::_2)); connection->set_keyspace(_keyspace_name); boost::shared_future<cql_future_connection_t> shared_future = promise->shared_future(); shared_future.wait(); if (shared_future.get().error.is_err()) { decrease_connection_counter(host); throw cql_connection_allocation_error( ("Error when connecting to host: " + host->endpoint().to_string()).c_str()); connection.reset(); } return connection; }
qi::FutureSync<void> Session::waitForService(const std::string& servicename) { boost::shared_ptr<qi::Atomic<int> > link = boost::make_shared<qi::Atomic<int> >(0); qi::Promise<void> promise(qi::bindWithFallback<void(qi::Promise<void>)>( boost::function<void()>(), &SessionPrivate::onServiceTrackingCancelled, boost::weak_ptr<SessionPrivate>(_p), _1, link)); *link = (int)_p->_sdClient.serviceAdded.connect( &SessionPrivate::onTrackedServiceAdded, boost::weak_ptr<SessionPrivate>(_p), _2, servicename, promise, link); qi::Future<qi::AnyObject> s = service(servicename); if (!s.hasError()) // service is already available, trigger manually (it's ok if it's // triggered multiple time) _p->onTrackedServiceAdded(servicename, servicename, promise, link); return promise.future(); }
void MediaKeys::ResolvePromise(PromiseId aId) { EME_LOG("MediaKeys[%p]::ResolvePromise(%d)", this, aId); RefPtr<DetailedPromise> promise(RetrievePromise(aId)); if (!promise) { return; } if (mPendingSessions.Contains(aId)) { // We should only resolve LoadSession calls via this path, // not CreateSession() promises. RefPtr<MediaKeySession> session; if (!mPendingSessions.Get(aId, getter_AddRefs(session)) || !session || session->GetSessionId().IsEmpty()) { NS_WARNING("Received activation for non-existent session!"); promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR, NS_LITERAL_CSTRING("CDM LoadSession() returned a different session ID than requested")); mPendingSessions.Remove(aId); return; } mPendingSessions.Remove(aId); mKeySessions.Put(session->GetSessionId(), session); promise->MaybeResolve(session); } else { promise->MaybeResolve(JS::UndefinedHandleValue); } MOZ_ASSERT(!mPromises.Contains(aId)); }
void MediaKeys::RejectPromise(PromiseId aId, nsresult aExceptionCode, const nsCString& aReason) { EME_LOG("MediaKeys[%p]::RejectPromise(%d, 0x%x)", this, aId, aExceptionCode); RefPtr<DetailedPromise> promise(RetrievePromise(aId)); if (!promise) { return; } if (mPendingSessions.Contains(aId)) { // This promise could be a createSession or loadSession promise, // so we might have a pending session waiting to be resolved into // the promise on success. We've been directed to reject to promise, // so we can throw away the corresponding session object. mPendingSessions.Remove(aId); } MOZ_ASSERT(NS_FAILED(aExceptionCode)); promise->MaybeReject(aExceptionCode, aReason); if (mCreatePromiseId == aId) { // Note: This will probably destroy the MediaKeys object! Release(); } }
void MediaKeys::OnCDMCreated(PromiseId aId, const nsACString& aNodeId, const uint32_t aPluginId) { RefPtr<DetailedPromise> promise(RetrievePromise(aId)); if (!promise) { return; } mNodeId = aNodeId; RefPtr<MediaKeys> keys(this); EME_LOG("MediaKeys[%p]::OnCDMCreated() resolve promise id=%d", this, aId); promise->MaybeResolve(keys); if (mCreatePromiseId == aId) { Release(); } MediaKeySystemAccess::NotifyObservers(mParent, mKeySystem, MediaKeySystemStatus::Cdm_created); if (aPluginId) { // Prepare plugin crash reporter. RefPtr<gmp::GeckoMediaPluginService> service = gmp::GeckoMediaPluginService::GetGeckoMediaPluginService(); if (NS_WARN_IF(!service)) { return; } if (NS_WARN_IF(!mParent)) { return; } service->AddPluginCrashedEventTarget(aPluginId, mParent); EME_LOG("MediaKeys[%p]::OnCDMCreated() registered crash handler for pluginId '%i'", this, aPluginId); } }
already_AddRefed<Promise> MediaKeys::CreateSession(const nsAString& initDataType, const Uint8Array& aInitData, SessionType aSessionType, ErrorResult& aRv) { aInitData.ComputeLengthAndData(); nsRefPtr<Promise> promise(MakePromise(aRv)); if (aRv.Failed()) { return nullptr; } nsRefPtr<MediaKeySession> session = new MediaKeySession(GetParentObject(), this, mKeySystem, aSessionType, aRv); if (aRv.Failed()) { return nullptr; } auto pid = StorePromise(promise); // Hang onto session until the CDM has finished setting it up. mPendingSessions.Put(pid, session); mProxy->CreateSession(aSessionType, pid, initDataType, aInitData); return promise.forget(); }
already_AddRefed<Promise> MediaKeys::LoadSession(const nsAString& aSessionId, ErrorResult& aRv) { nsRefPtr<Promise> promise(MakePromise(aRv)); if (aRv.Failed()) { return nullptr; } if (aSessionId.IsEmpty()) { promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR); // "The sessionId parameter is empty." return promise.forget(); } // TODO: The spec doesn't specify what to do in this case... if (mKeySessions.Contains(aSessionId)) { promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR); return promise.forget(); } // Create session. nsRefPtr<MediaKeySession> session( new MediaKeySession(GetParentObject(), this, mKeySystem, SessionType::Persistent, aRv)); if (aRv.Failed()) { return nullptr; } session->Init(aSessionId); auto pid = StorePromise(promise); mPendingSessions.Put(pid, session); mProxy->LoadSession(pid, aSessionId); return promise.forget(); }
already_AddRefed<Promise> MediaKeySession::GetUsableKeyIds(ErrorResult& aRv) { nsRefPtr<Promise> promise(mKeys->MakePromise(aRv)); if (aRv.Failed()) { return nullptr; } if (IsClosed() || !mKeys->GetCDMProxy()) { promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR); return promise.forget(); } nsTArray<CencKeyId> keyIds; { CDMCaps::AutoLock caps(mKeys->GetCDMProxy()->Capabilites()); caps.GetUsableKeysForSession(mSessionId, keyIds); } nsTArray<TypedArrayCreator<ArrayBuffer>> array; for (size_t i = 0; i < keyIds.Length(); i++) { array.AppendElement(keyIds[i]); } promise->MaybeResolve(array); return promise.forget(); }
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(); }
already_AddRefed<Promise> MediaKeySession::Remove(ErrorResult& aRv) { nsRefPtr<DetailedPromise> promise(MakePromise(aRv, NS_LITERAL_CSTRING("MediaKeySession.remove"))); if (aRv.Failed()) { return nullptr; } if (mSessionType != SessionType::Persistent) { promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR, NS_LITERAL_CSTRING("Calling MediaKeySession.remove() on non-persistent session")); // "The operation is not supported on session type sessions." EME_LOG("MediaKeySession[%p,'%s'] Remove() failed, sesion not persisrtent.", this, NS_ConvertUTF16toUTF8(mSessionId).get()); return promise.forget(); } if (IsClosed() || !mKeys->GetCDMProxy()) { promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR, NS_LITERAL_CSTRING("MediaKeySesison.remove() called but session is not active")); // "The session is closed." EME_LOG("MediaKeySession[%p,'%s'] Remove() failed, already session closed.", this, NS_ConvertUTF16toUTF8(mSessionId).get()); return promise.forget(); } PromiseId pid = mKeys->StorePromise(promise); mKeys->GetCDMProxy()->RemoveSession(mSessionId, pid); EME_LOG("MediaKeySession[%p,'%s'] Remove() sent to CDM, promiseId=%d.", this, NS_ConvertUTF16toUTF8(mSessionId).get(), pid); return promise.forget(); }
void MediaKeys::ResolvePromise(PromiseId aId) { nsRefPtr<Promise> promise(RetrievePromise(aId)); if (!promise) { NS_WARNING("MediaKeys tried to resolve a non-existent promise"); return; } if (mPendingSessions.Contains(aId)) { // We should only resolve LoadSession calls via this path, // not CreateSession() promises. nsRefPtr<MediaKeySession> session; if (!mPendingSessions.Get(aId, getter_AddRefs(session)) || !session || session->GetSessionId().IsEmpty()) { NS_WARNING("Received activation for non-existent session!"); promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR); mPendingSessions.Remove(aId); return; } mPendingSessions.Remove(aId); mKeySessions.Put(session->GetSessionId(), session); promise->MaybeResolve(session); } else { promise->MaybeResolve(JS::UndefinedHandleValue); } }
already_AddRefed<Promise> MediaKeySession::Close(ErrorResult& aRv) { RefPtr<DetailedPromise> promise(MakePromise(aRv, NS_LITERAL_CSTRING("MediaKeySession.close"))); 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,''] Close() called before sessionId set by CDM", this); promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR, NS_LITERAL_CSTRING("MediaKeySession.Close() called before sessionId set by CDM")); return promise.forget(); } if (IsClosed() || !mKeys->GetCDMProxy()) { EME_LOG("MediaKeySession[%p,'%s'] Close() already closed", this, NS_ConvertUTF16toUTF8(mSessionId).get()); promise->MaybeResolve(JS::UndefinedHandleValue); return promise.forget(); } PromiseId pid = mKeys->StorePromise(promise); mKeys->GetCDMProxy()->CloseSession(mSessionId, pid); EME_LOG("MediaKeySession[%p,'%s'] Close() sent to CDM, promiseId=%d", this, NS_ConvertUTF16toUTF8(mSessionId).get(), pid); return promise.forget(); }
void MediaKeys::OnSessionCreated(PromiseId aId, const nsAString& aSessionId) { nsRefPtr<Promise> promise(RetrievePromise(aId)); if (!promise) { NS_WARNING("MediaKeys tried to resolve a non-existent promise"); return; } MOZ_ASSERT(mPendingSessions.Contains(aId)); nsRefPtr<MediaKeySession> session; bool gotSession = mPendingSessions.Get(aId, getter_AddRefs(session)); // Session has completed creation/loading, remove it from mPendingSessions, // and resolve the promise with it. We store it in mKeySessions, so we can // find it again if we need to send messages to it etc. mPendingSessions.Remove(aId); if (!gotSession || !session) { NS_WARNING("Received activation for non-existent session!"); promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR); return; } session->Init(aSessionId); mKeySessions.Put(aSessionId, session); promise->MaybeResolve(session); }
TEST_F(ScriptPromiseTest, constructFromNonPromise) { v8::TryCatch trycatch; ScriptPromise promise(scriptState(), v8::Undefined(isolate())); ASSERT_TRUE(trycatch.HasCaught()); ASSERT_TRUE(promise.isEmpty()); }
already_AddRefed<Promise> MediaKeySession::Load(const nsAString& aSessionId, ErrorResult& aRv) { nsRefPtr<Promise> promise(mKeys->MakePromise(aRv)); if (aRv.Failed()) { return nullptr; } if (aSessionId.IsEmpty()) { promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR); // "The sessionId parameter is empty." return promise.forget(); } if (!mUninitialized) { promise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR); return promise.forget(); } mUninitialized = false; // We now know the sessionId being loaded into this session. Remove the // session from its owning MediaKey's set of sessions awaiting a sessionId. nsRefPtr<MediaKeySession> session(mKeys->GetPendingSession(Token())); MOZ_ASSERT(session == this, "Session should be awaiting id on its own token"); // Associate with the known sessionId. SetSessionId(aSessionId); mKeys->GetCDMProxy()->LoadSession(mKeys->StorePromise(promise), aSessionId); return promise.forget(); }
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(); }
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(); }
void Z3STRConstraintWriter::visit(Symbolic::StringCoercion* stringcoercion, void* args) { CoercionPromise promise(Symbolic::STRING); stringcoercion->getExpression()->accept(this); if (!promise.isCoerced) { coercetype(mExpressionType, Symbolic::STRING, mExpressionBuffer); // Sets mExpressionBuffer and Type. } }
void SMTConstraintWriter::visit(Symbolic::BooleanCoercion* booleancoercion, void* args) { CoercionPromise promise(Symbolic::BOOL); booleancoercion->getExpression()->accept(this); if (!promise.isCoerced) { coercetype(mExpressionType, Symbolic::BOOL, mExpressionBuffer); // Sets mExpressionBuffer and Type. } }
void SMTConstraintWriter::visit(Symbolic::IntegerCoercion* integercoercion, void* args) { CoercionPromise promise(Symbolic::INT); integercoercion->getExpression()->accept(this, &promise); if (!promise.isCoerced) { coercetype(mExpressionType, Symbolic::INT, mExpressionBuffer); // Sets mExpressionBuffer and Type. } }
VoidFuture TaskDispatcherBase::stop() { std::shared_ptr<VoidPromise> promise(new VoidPromise()); std::lock_guard<std::mutex> l(*this); mAcceptTasks = false; mQeuedTasks.push_back([promise, this]() { abort(); promise->set_value(); }); activateProcessing(); return promise->get_future(); }
void MediaKeys::OnSessionLoaded(PromiseId aId, bool aSuccess) { nsRefPtr<Promise> promise(RetrievePromise(aId)); if (!promise) { NS_WARNING("MediaKeys tried to resolve a non-existent promise"); return; } promise->MaybeResolve(aSuccess); }
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(); }
RefPtr<CDMProxy::DecryptPromise> CDMProxy::Decrypt(MediaRawData* aSample) { RefPtr<DecryptJob> job(new DecryptJob(aSample)); RefPtr<DecryptPromise> promise(job->Ensure()); nsCOMPtr<nsIRunnable> task( NewRunnableMethod<RefPtr<DecryptJob>>(this, &CDMProxy::gmp_Decrypt, job)); mGMPThread->Dispatch(task, NS_DISPATCH_NORMAL); return promise; }
void MediaKeys::OnSessionLoaded(PromiseId aId, bool aSuccess) { RefPtr<DetailedPromise> promise(RetrievePromise(aId)); if (!promise) { return; } EME_LOG("MediaKeys[%p]::OnSessionLoaded() resolve promise id=%d", this, aId); promise->MaybeResolve(aSuccess); }
// Optimized for repeating calls char *typestr::append_char(char c) { size_t existing_len = m_str ? strlen(m_str) : 0; size_t needed = existing_len + 1 + 1; if (m_size < needed) { needed += 100; promise(needed); } m_str[existing_len] = c; m_str[existing_len + 1] = '\0'; return m_str; }
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(); }
void Promise::Then(JSContext* aCx, // aCalleeGlobal may not be in the compartment of aCx, when called over // Xrays. JS::Handle<JSObject*> aCalleeGlobal, AnyCallback* aResolveCallback, AnyCallback* aRejectCallback, JS::MutableHandle<JS::Value> aRetval, ErrorResult& aRv) { NS_ASSERT_OWNINGTHREAD(Promise); // Let's hope this does the right thing with Xrays... Ensure everything is // just in the caller compartment; that ought to do the trick. In theory we // should consider aCalleeGlobal, but in practice our only caller is // DOMRequest::Then, which is not working with a Promise subclass, so things // should be OK. JS::Rooted<JSObject*> promise(aCx, PromiseObj()); if (!JS_WrapObject(aCx, &promise)) { aRv.NoteJSContextException(aCx); return; } JS::Rooted<JSObject*> resolveCallback(aCx); if (aResolveCallback) { resolveCallback = aResolveCallback->CallbackOrNull(); if (!JS_WrapObject(aCx, &resolveCallback)) { aRv.NoteJSContextException(aCx); return; } } JS::Rooted<JSObject*> rejectCallback(aCx); if (aRejectCallback) { rejectCallback = aRejectCallback->CallbackOrNull(); if (!JS_WrapObject(aCx, &rejectCallback)) { aRv.NoteJSContextException(aCx); return; } } JS::Rooted<JSObject*> retval(aCx); retval = JS::CallOriginalPromiseThen(aCx, promise, resolveCallback, rejectCallback); if (!retval) { aRv.NoteJSContextException(aCx); return; } aRetval.setObject(*retval); }
void MediaKeys::OnCDMCreated(PromiseId aId) { nsRefPtr<Promise> promise(RetrievePromise(aId)); if (!promise) { NS_WARNING("MediaKeys tried to resolve a non-existent promise"); return; } nsRefPtr<MediaKeys> keys(this); promise->MaybeResolve(keys); if (mCreatePromiseId == aId) { Release(); } }