Example #1
0
/* static */ already_AddRefed<dom::Promise>
MP4Decoder::IsVideoAccelerated(layers::LayersBackend aBackend, nsIGlobalObject* aParent)
{
  MOZ_ASSERT(NS_IsMainThread());

  ErrorResult rv;
  RefPtr<dom::Promise> promise;
  promise = dom::Promise::Create(aParent, rv);
  if (rv.Failed()) {
    rv.SuppressException();
    return nullptr;
  }

  RefPtr<TaskQueue> taskQueue =
    new TaskQueue(GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER));
  VideoInfo config;
  RefPtr<MediaDataDecoder> decoder(CreateTestH264Decoder(aBackend, config, taskQueue));
  if (!decoder) {
    taskQueue->BeginShutdown();
    taskQueue->AwaitShutdownAndIdle();
    promise->MaybeResolve(NS_LITERAL_STRING("No; Failed to create H264 decoder"));
    return promise.forget();
  }

  decoder->Init()
    ->Then(AbstractThread::MainThread(), __func__,
           [promise, decoder, taskQueue] (TrackInfo::TrackType aTrack) {
             nsCString failureReason;
             bool ok = decoder->IsHardwareAccelerated(failureReason);
             nsAutoString result;
             if (ok) {
               result.AssignLiteral("Yes");
             } else {
               result.AssignLiteral("No");
             }
             if (failureReason.Length()) {
               result.AppendLiteral("; ");
               AppendUTF8toUTF16(failureReason, result);
             }
             decoder->Shutdown();
             taskQueue->BeginShutdown();
             taskQueue->AwaitShutdownAndIdle();
             promise->MaybeResolve(result);
           },
           [promise, decoder, taskQueue] (MediaDataDecoder::DecoderFailureReason aResult) {
             decoder->Shutdown();
             taskQueue->BeginShutdown();
             taskQueue->AwaitShutdownAndIdle();
             promise->MaybeResolve(NS_LITERAL_STRING("No; Failed to initialize H264 decoder"));
           });

  return promise.forget();
}
already_AddRefed<Promise>
PresentationRequest::GetAvailability(ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
  if (NS_WARN_IF(!global)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return nullptr;
  }

  nsCOMPtr<nsIDocument> doc = GetOwner()->GetExtantDoc();
  if (NS_WARN_IF(!doc)) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  if (doc->GetSandboxFlags() & SANDBOXED_PRESENTATION) {
    promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
    return promise.forget();
  }

  promise->MaybeResolve(mAvailability);
  return promise.forget();
}
already_AddRefed<Promise>
BluetoothGattDescriptor::ReadValue(ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
  if (!global) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  NS_ENSURE_TRUE(!aRv.Failed(), nullptr);

  BluetoothUuid appUuid;
  BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(StringToUuid(
                        mCharacteristic->Service()->GetAppUuid(), appUuid)),
                        promise,
                        NS_ERROR_DOM_OPERATION_ERR);

  if (mAttRole == ATT_SERVER_ROLE) {
    promise->MaybeResolve(mValue);
    return promise.forget();
  }

  BluetoothService* bs = BluetoothService::Get();
  BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);

  bs->GattClientReadDescriptorValueInternal(
    appUuid,
    mCharacteristic->Service()->GetServiceId(),
    mCharacteristic->GetCharacteristicId(),
    mDescriptorId,
    new ReadValueTask(this, promise));

  return promise.forget();
}
bool
PresentationAvailability::Init(RefPtr<Promise>& aPromise)
{
  nsCOMPtr<nsIPresentationService> service =
    do_GetService(PRESENTATION_SERVICE_CONTRACTID);
  if (NS_WARN_IF(!service)) {
    return false;
  }

  nsresult rv = service->RegisterAvailabilityListener(this);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    // If the user agent is unable to monitor available device,
    // Resolve promise with |value| set to false.
    mIsAvailable = false;
    aPromise->MaybeResolve(this);
    return true;
  }

  EnqueuePromise(aPromise);

  AvailabilityCollection* collection = AvailabilityCollection::GetSingleton();
  if (collection) {
    collection->Add(this);
  }

  return true;
}
Example #5
0
already_AddRefed<Promise>
ServiceWorkerGlobalScope::SkipWaiting(ErrorResult& aRv)
{
  mWorkerPrivate->AssertIsOnWorkerThread();
  MOZ_ASSERT(mWorkerPrivate->IsServiceWorker());

  RefPtr<Promise> promise = Promise::Create(this, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  RefPtr<PromiseWorkerProxy> promiseProxy =
    PromiseWorkerProxy::Create(mWorkerPrivate, promise);
  if (!promiseProxy) {
    promise->MaybeResolve(JS::UndefinedHandleValue);
    return promise.forget();
  }

  RefPtr<WorkerScopeSkipWaitingRunnable> runnable =
    new WorkerScopeSkipWaitingRunnable(promiseProxy,
                                       NS_ConvertUTF16toUTF8(mScope));

  MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(runnable));
  return promise.forget();
}
already_AddRefed<Promise>
PresentationReceiver::GetConnection(ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
  if (NS_WARN_IF(!global)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  // If there's no existing connection, leave the promise pending until a
  // connecting request arrives from the controlling browsing context (sender).
  // http://w3c.github.io/presentation-api/#dom-presentation-getconnection
  if (!mConnections.IsEmpty()) {
    promise->MaybeResolve(mConnections[0]);
  } else {
    mPendingGetConnectionPromises.AppendElement(promise);
  }

  return promise.forget();
}
already_AddRefed<Promise>
BluetoothGattServer::StopAdvertising(ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
  if (!global) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  NS_ENSURE_TRUE(!aRv.Failed(), nullptr);

  BT_ENSURE_TRUE_REJECT(mValid, promise, NS_ERROR_NOT_AVAILABLE);

  if (mAdvertisingAppUuid.IsCleared()) {
    promise->MaybeResolve(JS::UndefinedHandleValue);
    return promise.forget();
  }

  BluetoothService* bs = BluetoothService::Get();
  BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);

  bs->StopAdvertisingInternal(mAdvertisingAppUuid,
                              new StopAdvertisingTask(this, promise));

  return promise.forget();
}
Example #8
0
already_AddRefed<Promise> MediaDevices::GetDisplayMedia(
    const DisplayMediaStreamConstraints& aConstraints, CallerType aCallerType,
    ErrorResult& aRv) {
  RefPtr<Promise> p = Promise::Create(GetParentObject(), aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }
  RefPtr<MediaDevices> self(this);
  MediaManager::Get()
      ->GetDisplayMedia(GetOwner(), aConstraints, aCallerType)
      ->Then(GetCurrentThreadSerialEventTarget(), __func__,
             [this, self, p](RefPtr<DOMMediaStream>&& aStream) {
               if (!GetWindowIfCurrent()) {
                 return;  // leave promise pending after navigation.
               }
               p->MaybeResolve(std::move(aStream));
             },
             [this, self, p](RefPtr<MediaMgrError>&& error) {
               nsPIDOMWindowInner* window = GetWindowIfCurrent();
               if (!window) {
                 return;  // leave promise pending after navigation.
               }
               p->MaybeReject(MakeRefPtr<MediaStreamError>(window, *error));
             });
  return p.forget();
}
already_AddRefed<Promise>
BluetoothGattCharacteristic::ReadValue(ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
  if (!global) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  NS_ENSURE_TRUE(!aRv.Failed(), nullptr);

  if (mAttRole == ATT_SERVER_ROLE) {
    promise->MaybeResolve(mValue);
    return promise.forget();
  }

  BT_ENSURE_TRUE_REJECT(mProperties & GATT_CHAR_PROP_BIT_READ,
                        promise,
                        NS_ERROR_NOT_AVAILABLE);

  BluetoothService* bs = BluetoothService::Get();
  BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);

  bs->GattClientReadCharacteristicValueInternal(
    mService->GetAppUuid(), mService->GetServiceId(), mCharId,
    new ReadValueTask(this, promise));

  return promise.forget();
}
Example #10
0
already_AddRefed<Promise>
MediaStreamTrack::ApplyConstraints(const MediaTrackConstraints& aConstraints,
                                   ErrorResult &aRv)
{
  if (MOZ_LOG_TEST(gMediaStreamTrackLog, LogLevel::Info)) {
    nsString str;
    aConstraints.ToJSON(str);

    LOG(LogLevel::Info, ("MediaStreamTrack %p ApplyConstraints() with "
                         "constraints %s", this, NS_ConvertUTF16toUTF8(str).get()));
  }

  typedef media::Pledge<bool, MediaStreamError*> PledgeVoid;

  nsPIDOMWindowInner* window = mOwningStream->GetParentObject();

  nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(window);
  RefPtr<Promise> promise = Promise::Create(go, aRv);

  // Forward constraints to the source.
  //
  // After GetSource().ApplyConstraints succeeds (after it's been to media-thread
  // and back), and no sooner, do we set mConstraints to the newly applied values.

  // Keep a reference to this, to make sure it's still here when we get back.
  RefPtr<MediaStreamTrack> that = this;
  RefPtr<PledgeVoid> p = GetSource().ApplyConstraints(window, aConstraints);
  p->Then([this, that, promise, aConstraints](bool& aDummy) mutable {
    mConstraints = aConstraints;
    promise->MaybeResolve(false);
  }, [promise](MediaStreamError*& reason) mutable {
    promise->MaybeReject(reason);
  });
  return promise.forget();
}
already_AddRefed<Promise>
BluetoothGattCharacteristic::AddDescriptor(const nsAString& aDescriptorUuid,
                                           const GattPermissions& aPermissions,
                                           const ArrayBuffer& aValue,
                                           ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
  if (!global) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  NS_ENSURE_TRUE(!aRv.Failed(), nullptr);

  BT_ENSURE_TRUE_REJECT(mAttRole == ATT_SERVER_ROLE,
                        promise,
                        NS_ERROR_UNEXPECTED);

  /* The characteristic should not be actively acting with the Bluetooth
   * backend. Otherwise, descriptors cannot be added into the characteristic. */
  BT_ENSURE_TRUE_REJECT(!mActive, promise, NS_ERROR_UNEXPECTED);

  RefPtr<BluetoothGattDescriptor> descriptor =
    new BluetoothGattDescriptor(GetParentObject(),
                                this,
                                aDescriptorUuid,
                                aPermissions,
                                aValue);

  mDescriptors.AppendElement(descriptor);
  promise->MaybeResolve(descriptor);

  return promise.forget();
}
/* static */ already_AddRefed<Promise>
FileCreatorHelper::CreateFile(nsIGlobalObject* aGlobalObject,
                              nsIFile* aFile,
                              const ChromeFilePropertyBag& aBag,
                              bool aIsFromNsIFile,
                              ErrorResult& aRv)
{
  MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());

  RefPtr<Promise> promise = Promise::Create(aGlobalObject, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobalObject);

  // Parent process

  if (XRE_IsParentProcess()) {
    RefPtr<File> file =
      CreateFileInternal(window, aFile, aBag, aIsFromNsIFile, aRv);
    if (aRv.Failed()) {
      return nullptr;
    }
    promise->MaybeResolve(file);
    return promise.forget();
  }

  // Content process.

  ContentChild* cc = ContentChild::GetSingleton();
  if (!cc) {
    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
    return promise.forget();
  }

  if (!cc->GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE) &&
      !Preferences::GetBool("dom.file.createInChild", false)) {
    // If this pref is not set and the request is received by the parent
    // process, this child is killed for security reason.
    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
    return promise.forget();
  }

  RefPtr<FileCreatorHelper> helper = new FileCreatorHelper(promise, window);

  // The request is sent to the parent process and it's kept alive by
  // ContentChild.
  helper->SendRequest(aFile, aBag, aIsFromNsIFile, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  return promise.forget();
}
mozilla::ipc::IPCResult
GamepadEventChannelChild::RecvReplyGamepadVibrateHaptic(const uint32_t& aPromiseID)
{
  RefPtr<dom::Promise> p;
  if (!mPromiseList.Get(aPromiseID, getter_AddRefs(p))) {
    MOZ_CRASH("We should always have a promise.");
  }

  p->MaybeResolve(true);
  mPromiseList.Remove(aPromiseID);
  return IPC_OK();
}
Example #14
0
already_AddRefed<Promise>
Cache::AddAll(const GlobalObject& aGlobal,
              nsTArray<RefPtr<Request>>&& aRequestList, ErrorResult& aRv)
{
  MOZ_ASSERT(mActor);

  // If there is no work to do, then resolve immediately
  if (aRequestList.IsEmpty()) {
    RefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
    if (NS_WARN_IF(!promise)) {
      return nullptr;
    }

    promise->MaybeResolve(JS::UndefinedHandleValue);
    return promise.forget();
  }

  AutoTArray<RefPtr<Promise>, 256> fetchList;
  fetchList.SetCapacity(aRequestList.Length());

  // Begin fetching each request in parallel.  For now, if an error occurs just
  // abandon our previous fetch calls.  In theory we could cancel them in the
  // future once fetch supports it.

  for (uint32_t i = 0; i < aRequestList.Length(); ++i) {
    RequestOrUSVString requestOrString;
    requestOrString.SetAsRequest() = aRequestList[i];
    RefPtr<Promise> fetch = FetchRequest(mGlobal, requestOrString,
                                           RequestInit(), aRv);
    if (NS_WARN_IF(aRv.Failed())) {
      return nullptr;
    }

    fetchList.AppendElement(Move(fetch));
  }

  RefPtr<Promise> promise = Promise::Create(mGlobal, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  RefPtr<FetchHandler> handler =
    new FetchHandler(mActor->GetWorkerHolder(), this,
                     Move(aRequestList), promise);

  RefPtr<Promise> fetchPromise = Promise::All(aGlobal, fetchList, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }
  fetchPromise->AppendNativeHandler(handler);

  return promise.forget();
}
NS_IMETHODIMP
nsOSPermissionRequestBase::RequestAudioCapturePermission(JSContext* aCx,
                                                         Promise** aPromiseOut)
{
  RefPtr<Promise> promiseHandle;
  nsresult rv = GetPromise(aCx, promiseHandle);
  if (NS_FAILED(rv)) {
    return rv;
  }

  promiseHandle->MaybeResolve(true /* access authorized */);
  promiseHandle.forget(aPromiseOut);
  return NS_OK;
}
Example #16
0
mozilla::ipc::IPCResult
VRManagerChild::RecvReplyCreateVRServiceTestController(const nsCString& aID,
                                                       const uint32_t& aPromiseID,
                                                       const uint32_t& aDeviceID)
{
  RefPtr<dom::Promise> p;
  if (!mPromiseList.Get(aPromiseID, getter_AddRefs(p))) {
    MOZ_CRASH("We should always have a promise.");
  }

  p->MaybeResolve(new VRMockController(aID, aDeviceID));
  mPromiseList.Remove(aPromiseID);
  return IPC_OK();
}
Example #17
0
already_AddRefed<Promise>
TVTuner::GetSources(ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
  MOZ_ASSERT(global);

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  promise->MaybeResolve(mSources);

  return promise.forget();
}
Example #18
0
  bool
  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
  {
    RefPtr<Promise> promise = mProxy->WorkerPromise();
    if (NS_SUCCEEDED(mStatus)) {
      if (mEndpoint.IsEmpty()) {
        promise->MaybeResolve(JS::NullHandleValue);
      } else {
        RefPtr<PushSubscription> sub =
            new PushSubscription(nullptr, mEndpoint, mScope,
                                 Move(mRawP256dhKey), Move(mAuthSecret),
                                 Move(mAppServerKey));
        promise->MaybeResolve(sub);
      }
    } else if (NS_ERROR_GET_MODULE(mStatus) == NS_ERROR_MODULE_DOM_PUSH ) {
      promise->MaybeReject(mStatus);
    } else {
      promise->MaybeReject(NS_ERROR_DOM_PUSH_ABORT_ERR);
    }

    mProxy->CleanUp();

    return true;
  }
already_AddRefed<Promise>
BluetoothGattCharacteristic::WriteValue(const ArrayBuffer& aValue,
                                        ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
  if (!global) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  NS_ENSURE_TRUE(!aRv.Failed(), nullptr);

  aValue.ComputeLengthAndData();

  if (mAttRole == ATT_SERVER_ROLE) {
    mValue.Clear();
    mValue.AppendElements(aValue.Data(), aValue.Length());

    promise->MaybeResolve(JS::UndefinedHandleValue);
    return promise.forget();
  }

  BT_ENSURE_TRUE_REJECT(mProperties &
                          (GATT_CHAR_PROP_BIT_WRITE_NO_RESPONSE |
                           GATT_CHAR_PROP_BIT_WRITE |
                           GATT_CHAR_PROP_BIT_SIGNED_WRITE),
                        promise,
                        NS_ERROR_NOT_AVAILABLE);

  nsTArray<uint8_t> value;
  value.AppendElements(aValue.Data(), aValue.Length());

  BluetoothService* bs = BluetoothService::Get();
  BT_ENSURE_TRUE_REJECT(bs, promise, NS_ERROR_NOT_AVAILABLE);

  BluetoothUuid appUuid;
  BT_ENSURE_TRUE_REJECT(NS_SUCCEEDED(StringToUuid(mService->GetAppUuid(),
                                                  appUuid)),
                        promise,
                        NS_ERROR_DOM_OPERATION_ERR);

  bs->GattClientWriteCharacteristicValueInternal(
    appUuid, mService->GetServiceId(), mCharId, mWriteType, value,
    new BluetoothVoidReplyRunnable(nullptr, promise));

  return promise.forget();
}
Example #20
0
  bool
  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
  {
    MOZ_ASSERT(aWorkerPrivate);
    aWorkerPrivate->AssertIsOnWorkerThread();

    RefPtr<Promise> promise = mProxy->WorkerPromise();
    if (NS_SUCCEEDED(mStatus)) {
      promise->MaybeResolve(mState);
    } else {
      promise->MaybeReject(aCx, JS::UndefinedHandleValue);
    }

    mProxy->CleanUp();

    return true;
  }
already_AddRefed<Promise>
PresentationReceiver::GetConnections(ErrorResult& aRv) const
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
  if (NS_WARN_IF(!global)) {
    aRv.Throw(NS_ERROR_UNEXPECTED);
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  promise->MaybeResolve(mConnections);
  return promise.forget();
}
Example #22
0
mozilla::ipc::IPCResult
VRManagerChild::RecvReplyGamepadVibrateHaptic(const uint32_t& aPromiseID)
{
  // VRManagerChild could be at other processes, but GamepadManager
  // only exists at the content process or the same process
  // in non-e10s mode.
  MOZ_ASSERT(XRE_IsContentProcess() || IsSameProcess());

  RefPtr<dom::Promise> p;
  if (!mGamepadPromiseList.Get(aPromiseID, getter_AddRefs(p))) {
    MOZ_CRASH("We should always have a promise.");
  }

  p->MaybeResolve(true);
  mGamepadPromiseList.Remove(aPromiseID);
  return IPC_OK();
}
Example #23
0
already_AddRefed<Promise>
AudioContext::Resume(ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(GetParentObject());
  RefPtr<Promise> promise;
  promise = Promise::Create(parentObject, aRv);
  if (aRv.Failed()) {
    return nullptr;
  }

  if (mIsOffline) {
    promise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
    return promise.forget();
  }

  if (mAudioContextState == AudioContextState::Closed ||
      mCloseCalled) {
    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
    return promise.forget();
  }

  if (mAudioContextState == AudioContextState::Running) {
    promise->MaybeResolve(JS::UndefinedHandleValue);
    return promise.forget();
  }

  Destination()->Resume();

  nsTArray<MediaStream*> streams;
  // If mSuspendCalled is false then we already resumed all our streams,
  // so don't resume them again (since suspend(); resume(); resume(); should
  // be OK). But we still need to do ApplyAudioContextOperation
  // to ensure our new promise is resolved.
  if (mSuspendCalled) {
    streams = GetAllStreams();
  }
  mPromiseGripArray.AppendElement(promise);
  Graph()->ApplyAudioContextOperation(DestinationStream()->AsAudioNodeStream(),
                                      streams,
                                      AudioContextOperation::Resume, promise);

  mSuspendCalled = false;

  return promise.forget();
}
Example #24
0
already_AddRefed<Promise>
VRDisplay::RequestPresent(const nsTArray<VRLayer>& aLayers,
                          CallerType aCallerType,
                          ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
  if (!global) {
    aRv.Throw(NS_ERROR_FAILURE);
    return nullptr;
  }

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  NS_ENSURE_TRUE(!aRv.Failed(), nullptr);

  bool isChromePresentation = aCallerType == CallerType::System;
  uint32_t presentationGroup = isChromePresentation ? gfx::kVRGroupChrome : gfx::kVRGroupContent;

  if (!EventStateManager::IsHandlingUserInput() &&
      !isChromePresentation &&
      !IsHandlingVRNavigationEvent() &&
      gfxPrefs::VRRequireGesture()) {
    // The WebVR API states that if called outside of a user gesture, the
    // promise must be rejected.  We allow VR presentations to start within
    // trusted events such as vrdisplayactivate, which triggers in response to
    // HMD proximity sensors and when navigating within a VR presentation.
    // This user gesture requirement is not enforced for chrome/system code.
    promise->MaybeRejectWithUndefined();
  } else if (!IsPresenting() && IsAnyPresenting(presentationGroup)) {
    // Only one presentation allowed per VRDisplay on a
    // first-come-first-serve basis.
    // If this Javascript context is presenting, then we can replace our
    // presentation with a new one containing new layers but we should never
    // replace the presentation of another context.
    // Simultaneous presentations in other groups are allowed in separate
    // Javascript contexts to enable browser UI from chrome/system contexts.
    // Eventually, this restriction will be loosened to enable multitasking
    // use cases.
    promise->MaybeRejectWithUndefined();
  } else {
    mPresentation = mClient->BeginPresentation(aLayers, presentationGroup);
    mFrameInfo.Clear();
    promise->MaybeResolve(JS::UndefinedHandleValue);
  }
  return promise.forget();
}
Example #25
0
void JSWindowActor::ReceiveMessageOrQuery(
    JSContext* aCx, const JSWindowActorMessageMeta& aMetadata,
    JS::Handle<JS::Value> aData, ErrorResult& aRv) {
  // The argument which we want to pass to IPC.
  RootedDictionary<ReceiveMessageArgument> argument(aCx);
  argument.mObjects = JS_NewPlainObject(aCx);
  argument.mTarget = this;
  argument.mName = aMetadata.messageName();
  argument.mData = aData;
  argument.mJson = aData;
  argument.mSync = false;

  JS::Rooted<JSObject*> self(aCx, GetWrapper());
  JS::Rooted<JSObject*> global(aCx, JS::GetNonCCWObjectGlobal(self));

  // We only need to create a promise if we're dealing with a query here. It
  // will be resolved or rejected once the listener has been called. Our
  // listener on this promise will then send the reply.
  RefPtr<Promise> promise;
  if (aMetadata.kind() == JSWindowActorMessageKind::Query) {
    promise = Promise::Create(xpc::NativeGlobal(global), aRv);
    if (NS_WARN_IF(aRv.Failed())) {
      return;
    }

    RefPtr<QueryHandler> handler = new QueryHandler(this, aMetadata);
    promise->AppendNativeHandler(handler);
  }

  // Invoke the actual callback.
  JS::Rooted<JS::Value> retval(aCx);
  RefPtr<MessageListener> messageListener =
      new MessageListener(self, global, nullptr, nullptr);
  messageListener->ReceiveMessage(argument, &retval, aRv,
                                  "JSWindowActor receive message");

  // If we have a promise, resolve or reject it respectively.
  if (promise) {
    if (aRv.Failed()) {
      promise->MaybeReject(aRv);
    } else {
      promise->MaybeResolve(aCx, retval);
    }
  }
}
Example #26
0
mozilla::ipc::IPCResult
VRManagerChild::RecvReplyCreateVRServiceTestDisplay(const nsCString& aID,
                                                    const uint32_t& aPromiseID,
                                                    const uint32_t& aDeviceID)
{
  RefPtr<dom::Promise> p;
  if (!mPromiseList.Get(aPromiseID, getter_AddRefs(p))) {
    MOZ_CRASH("We should always have a promise.");
  }

  // We only allow one VRMockDisplay in VR tests.
  if (!mVRMockDisplay) {
    mVRMockDisplay = new VRMockDisplay(aID, aDeviceID);
  }
  p->MaybeResolve(mVRMockDisplay);
  mPromiseList.Remove(aPromiseID);
  return IPC_OK();
}
Example #27
0
already_AddRefed<Promise>
AudioContext::Close(ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(GetParentObject());
  RefPtr<Promise> promise;
  promise = Promise::Create(parentObject, aRv);
  if (aRv.Failed()) {
    return nullptr;
  }

  if (mIsOffline) {
    promise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
    return promise.forget();
  }

  if (mAudioContextState == AudioContextState::Closed) {
    promise->MaybeResolve(NS_ERROR_DOM_INVALID_STATE_ERR);
    return promise.forget();
  }

  if (Destination()) {
    Destination()->DestroyAudioChannelAgent();
  }

  mPromiseGripArray.AppendElement(promise);

  // This can be called when freeing a document, and the streams are dead at
  // this point, so we need extra null-checks.
  MediaStream* ds = DestinationStream();
  if (ds) {
    nsTArray<MediaStream*> streams;
    // If mSuspendCalled or mCloseCalled are true then we already suspended
    // all our streams, so don't suspend them again. But we still need to do
    // ApplyAudioContextOperation to ensure our new promise is resolved.
    if (!mSuspendCalled && !mCloseCalled) {
      streams = GetAllStreams();
    }
    Graph()->ApplyAudioContextOperation(ds->AsAudioNodeStream(), streams,
                                        AudioContextOperation::Close, promise);
  }
  mCloseCalled = true;

  return promise.forget();
}
Example #28
0
already_AddRefed<Promise>
InputPortManager::GetInputPorts(ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
  MOZ_ASSERT(global);

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  if (mIsReady) {
    promise->MaybeResolve(mInputPorts);
  } else {
    mPendingGetInputPortsPromises.AppendElement(promise);
  }

  return promise.forget();
}
Example #29
0
  bool
  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
  {
    MOZ_ASSERT(aWorkerPrivate);
    aWorkerPrivate->AssertIsOnWorkerThread();

    RefPtr<Promise> promise = mResolver->mPromiseProxy->WorkerPromise();

    if (mInternalResponse->Type() != ResponseType::Error) {
      RefPtr<nsIGlobalObject> global = aWorkerPrivate->GlobalScope();
      RefPtr<Response> response = new Response(global, mInternalResponse);
      promise->MaybeResolve(response);
    } else {
      ErrorResult result;
      result.ThrowTypeError<MSG_FETCH_FAILED>();
      promise->MaybeReject(result);
    }
    return true;
  }
Example #30
0
already_AddRefed<Promise>
TVManager::GetTuners(ErrorResult& aRv)
{
  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
  MOZ_ASSERT(global);

  RefPtr<Promise> promise = Promise::Create(global, aRv);
  if (NS_WARN_IF(aRv.Failed())) {
    return nullptr;
  }

  // Keep track of the promise when the manager hasn't been ready yet.
  if (mIsReady) {
    promise->MaybeResolve(mTuners);
  } else {
    mPendingGetTunersPromises.AppendElement(promise);
  }

  return promise.forget();
}