Example #1
0
nsresult
nsMemoryImpl::FlushMemory(const PRUnichar* aReason, bool aImmediate)
{
    nsresult rv = NS_OK;

    if (aImmediate) {
        // They've asked us to run the flusher *immediately*. We've
        // got to be on the UI main thread for us to be able to do
        // that...are we?
        if (!NS_IsMainThread()) {
            NS_ERROR("can't synchronously flush memory: not on UI thread");
            return NS_ERROR_FAILURE;
        }
    }

    int32_t lastVal = sIsFlushing.exchange(1);
    if (lastVal)
        return NS_OK;

    PRIntervalTime now = PR_IntervalNow();

    // Run the flushers immediately if we can; otherwise, proxy to the
    // UI thread an run 'em asynchronously.
    if (aImmediate) {
        rv = RunFlushers(aReason);
    }
    else {
        // Don't broadcast more than once every 1000ms to avoid being noisy
        if (PR_IntervalToMicroseconds(now - sLastFlushTime) > 1000) {
            sFlushEvent.mReason = aReason;
            rv = NS_DispatchToMainThread(&sFlushEvent, NS_DISPATCH_NORMAL);
        }
    }

    sLastFlushTime = now;
    return rv;
}
nsresult
MediaEngineWebRTCVideoSource::Stop(SourceMediaStream *aSource, TrackID aID)
{
    LOG((__FUNCTION__));
    if (!mSources.RemoveElement(aSource)) {
        // Already stopped - this is allowed
        return NS_OK;
    }
    if (!mSources.IsEmpty()) {
        return NS_OK;
    }
#ifdef MOZ_B2G_CAMERA
    ReentrantMonitorAutoEnter sync(mCallbackMonitor);
#endif
    if (mState != kStarted) {
        return NS_ERROR_FAILURE;
    }

    {
        MonitorAutoLock lock(mMonitor);
        mState = kStopped;
        aSource->EndTrack(aID);
        // Drop any cached image so we don't start with a stale image on next
        // usage
        mImage = nullptr;
    }
#ifdef MOZ_B2G_CAMERA
    NS_DispatchToMainThread(WrapRunnable(this,
                                         &MediaEngineWebRTCVideoSource::StopImpl));
#else
    mViERender->StopRender(mCaptureIndex);
    mViERender->RemoveRenderer(mCaptureIndex);
    mViECapture->StopCapture(mCaptureIndex);
#endif

    return NS_OK;
}
  NS_IMETHOD
  Run()
  {
    NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");

    mManager = MediaManager::Get();

    // Was a backend provided?
    if (!mBackendChosen) {
      mBackend = mManager->GetBackend();
    }

    // Was a device provided?
    if (!mDeviceChosen) {
      nsresult rv = SelectDevice();
      if (rv != NS_OK) {
        return rv;
      }
    }

    // It is an error if audio or video are requested along with picture.
    if (mPicture && (mAudio || mVideo)) {
      NS_DispatchToMainThread(new ErrorCallbackRunnable(
        mSuccess, mError, NS_LITERAL_STRING("NOT_SUPPORTED_ERR"), mWindowID
      ));
      return NS_OK;
    }

    if (mPicture) {
      ProcessGetUserMediaSnapshot(mVideoDevice->GetSource(), 0);
      return NS_OK;
    }

    ProcessGetUserMedia(mAudio ? mAudioDevice->GetSource() : nullptr,
                        mVideo ? mVideoDevice->GetSource() : nullptr);
    return NS_OK;
  }
nsresult
MediaEngineWebRTCVideoSource::Allocate(const MediaEnginePrefs &aPrefs)
{
    LOG((__FUNCTION__));
#ifdef MOZ_B2G_CAMERA
    ReentrantMonitorAutoEnter sync(mCallbackMonitor);
    if (mState == kReleased && mInitDone) {
        ChooseCapability(aPrefs);
        NS_DispatchToMainThread(WrapRunnable(this,
                                             &MediaEngineWebRTCVideoSource::AllocImpl));
        mCallbackMonitor.Wait();
        if (mState != kAllocated) {
            return NS_ERROR_FAILURE;
        }
    }
#else
    if (mState == kReleased && mInitDone) {
        // Note: if shared, we don't allow a later opener to affect the resolution.
        // (This may change depending on spec changes for Constraints/settings)

        ChooseCapability(aPrefs);

        if (mViECapture->AllocateCaptureDevice(NS_ConvertUTF16toUTF8(mUniqueId).get(),
                                               KMaxUniqueIdLength, mCaptureIndex)) {
            return NS_ERROR_FAILURE;
        }
        mState = kAllocated;
        LOG(("Video device %d allocated", mCaptureIndex));
    } else if (mSources.IsEmpty()) {
        LOG(("Video device %d reallocated", mCaptureIndex));
    } else {
        LOG(("Video device %d allocated shared", mCaptureIndex));
    }
#endif

    return NS_OK;
}
/* boolean dispatchEvent (in sbIMediacoreEvent aEvent, [optional] PRBool aAsync); */
nsresult
sbBaseMediacoreEventTarget::DispatchEvent(sbIMediacoreEvent *aEvent,
                                          PRBool aAsync,
                                          PRBool* _retval)
{
  nsresult rv;

  // Note: in the async case, we need to make a new runnable, because
  // DispatchEvent has an out param, and XPCOM proxies can't deal with that.
  if (aAsync) {
    nsRefPtr<AsyncDispatchHelper> dispatchHelper =
      new AsyncDispatchHelper(static_cast<sbIMediacoreEventTarget*>(mTarget), aEvent);
    NS_ENSURE_TRUE(dispatchHelper, NS_ERROR_OUT_OF_MEMORY);
    rv = NS_DispatchToMainThread(dispatchHelper, NS_DISPATCH_NORMAL);
    NS_ENSURE_SUCCESS(rv, rv);
    return NS_OK;
  }
  if (!NS_IsMainThread()) {
    // we need to proxy to the main thread
    nsCOMPtr<sbIMediacoreEventTarget> proxiedSelf;
    { /* scope the monitor */
      NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
      nsAutoMonitor mon(mMonitor);
      rv = do_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
                                NS_GET_IID(sbIMediacoreEventTarget),
                                mTarget,
                                NS_PROXY_SYNC | NS_PROXY_ALWAYS,
                                getter_AddRefs(proxiedSelf));
      NS_ENSURE_SUCCESS(rv, rv);
    }
    // don't have a return value if dispatching asynchronously
    // (since the variable is likely to be dead by that point)
    return proxiedSelf->DispatchEvent(aEvent, PR_FALSE, _retval);
  }

  return DispatchEventInternal(aEvent, _retval);
}
Example #6
0
bool
NuwaParent::RecvNotifyReady()
{
#ifdef MOZ_NUWA_PROCESS
  if (!mContentParent || !mContentParent->IsNuwaProcess()) {
    NS_ERROR("Received NotifyReady() message from a non-Nuwa process.");
    return false;
  }

  // Creating a NonOwningRunnableMethod here is safe because refcount changes of
  // mContentParent have to go the the main thread. The mContentParent will
  // be alive when the runnable runs.
  nsCOMPtr<nsIRunnable> runnable =
    NS_NewNonOwningRunnableMethod(mContentParent.get(),
                                  &ContentParent::OnNuwaReady);
  MOZ_ASSERT(runnable);
  MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(runnable)));

  return true;
#else
  NS_ERROR("NuwaParent::RecvNotifyReady() not implemented!");
  return false;
#endif
}
Example #7
0
NS_IMETHODIMP
_OldCacheLoad::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry,
                                     nsCacheAccessMode access,
                                     nsresult status)
{
  LOG(("_OldCacheLoad::OnCacheEntryAvailable [this=%p, ent=%p, cb=%p, appcache=%p, access=%x]",
    this, entry, mCallback.get(), mAppCache.get(), access));

  // XXX Bug 759805: Sometimes we will call this method directly from
  // HttpCacheQuery::Run when AsyncOpenCacheEntry fails, but
  // AsyncOpenCacheEntry will also call this method. As a workaround, we just
  // ensure we only execute this code once.
  NS_ENSURE_TRUE(mRunCount == 0, NS_ERROR_UNEXPECTED);
  ++mRunCount;

  mCacheEntry = entry ? new _OldCacheEntryWrapper(entry) : nullptr;
  mStatus = status;
  mNew = access == nsICache::ACCESS_WRITE;

  if (!mMainThreadOnly)
    Check();

  return NS_DispatchToMainThread(this);
}
nsresult
MediaEngineGonkVideoSource::Deallocate(AllocationHandle* aHandle)
{
  LOG((__FUNCTION__));
  AssertIsOnOwningThread();
  MOZ_ASSERT(!aHandle);

  bool empty;
  {
    MonitorAutoLock lock(mMonitor);
    empty = mSources.IsEmpty();
  }
  if (empty) {

    ReentrantMonitorAutoEnter sync(mCallbackMonitor);

    if (mState != kStopped && mState != kAllocated) {
      return NS_ERROR_FAILURE;
    }

    // We do not register success callback here

    NS_DispatchToMainThread(WrapRunnable(RefPtr<MediaEngineGonkVideoSource>(this),
                                         &MediaEngineGonkVideoSource::DeallocImpl));
    mCallbackMonitor.Wait();
    if (mState != kReleased) {
      return NS_ERROR_FAILURE;
    }

    mState = kReleased;
    LOG(("Video device %d deallocated", mCaptureIndex));
  } else {
    LOG(("Video device %d deallocated but still in use", mCaptureIndex));
  }
  return NS_OK;
}
Example #9
0
void
ClientLayerManager::Destroy()
{
  // It's important to call ClearCachedResource before Destroy because the
  // former will early-return if the later has already run.
  ClearCachedResources();
  LayerManager::Destroy();

  if (mTransactionIdAllocator) {
    // Make sure to notify the refresh driver just in case it's waiting on a
    // pending transaction. Do this at the top of the event loop so we don't
    // cause a paint to occur during compositor shutdown.
    RefPtr<TransactionIdAllocator> allocator = mTransactionIdAllocator;
    uint64_t id = mLatestTransactionId;

    RefPtr<Runnable> task = NS_NewRunnableFunction([allocator, id] () -> void {
      allocator->NotifyTransactionCompleted(id);
    });
    NS_DispatchToMainThread(task.forget());
  }

  // Forget the widget pointer in case we outlive our owning widget.
  mWidget = nullptr;
}
Example #10
0
int
VideoRenderer::DeliverFrame(unsigned char* buffer, int buffer_size, uint32_t time_stamp, int64_t render_time)
{
    PRTime epoch_c = PR_Now();
    PRFloat64 epoch = (PRFloat64)(epoch_c / MICROSECONDS);
    epoch += ((PRFloat64)(epoch_c % MICROSECONDS)) / MICROSECONDS;

    int fsize = width * height * 4;
    if (vCanvas) {
        /* Convert i420 to RGB32 to write on canvas */
        nsAutoArrayPtr<PRUint8> rgb32(new PRUint8[fsize]);
        I420toRGB32(width, height,
            (const char *)buffer, (char *)rgb32.get()
        );

        nsCOMPtr<nsIRunnable> render = new CanvasRenderer(
            vCanvas, width, height, rgb32, fsize
        );

        NS_DispatchToMainThread(render);
    }

    return 0;
}
Example #11
0
void
AudioContext::OnStateChanged(void* aPromise, AudioContextState aNewState)
{
  MOZ_ASSERT(NS_IsMainThread());

  MOZ_ASSERT((mAudioContextState == AudioContextState::Suspended &&
              aNewState == AudioContextState::Running)   ||
             (mAudioContextState == AudioContextState::Running   &&
              aNewState == AudioContextState::Suspended) ||
             (mAudioContextState == AudioContextState::Running   &&
              aNewState == AudioContextState::Closed)    ||
             (mAudioContextState == AudioContextState::Suspended &&
              aNewState == AudioContextState::Closed)    ||
             (mAudioContextState == aNewState),
             "Invalid AudioContextState transition");

  MOZ_ASSERT(
    mIsOffline || aPromise || aNewState == AudioContextState::Running,
    "We should have a promise here if this is a real-time AudioContext."
    "Or this is the first time we switch to \"running\".");

  if (aPromise) {
    Promise* promise = reinterpret_cast<Promise*>(aPromise);
    promise->MaybeResolve(JS::UndefinedHandleValue);
    DebugOnly<bool> rv = mPromiseGripArray.RemoveElement(promise);
    MOZ_ASSERT(rv, "Promise wasn't in the grip array?");
  }

  if (mAudioContextState != aNewState) {
    nsRefPtr<OnStateChangeTask> onStateChangeTask =
      new OnStateChangeTask(this);
    NS_DispatchToMainThread(onStateChangeTask);
  }

  mAudioContextState = aNewState;
}
Example #12
0
NS_IMETHODIMP_(MozExternalRefCountType) SharedThreadPool::Release(void)
{
  MOZ_ASSERT(sMonitor);
  ReentrantMonitorAutoEnter mon(*sMonitor);
  nsrefcnt count = --mRefCnt;
  NS_LOG_RELEASE(this, count, "SharedThreadPool");
  if (count) {
    return count;
  }

  // Remove SharedThreadPool from table of pools.
  sPools->Remove(mName);
  MOZ_ASSERT(!sPools->Get(mName));

  // Dispatch an event to the main thread to call Shutdown() on
  // the nsIThreadPool. The Runnable here will add a refcount to the pool,
  // and when the Runnable releases the nsIThreadPool it will be deleted.
  NS_DispatchToMainThread(NewRunnableMethod(mPool, &nsIThreadPool::Shutdown));

  // Stabilize refcount, so that if something in the dtor QIs, it won't explode.
  mRefCnt = 1;
  delete this;
  return 0;
}
nsresult
MediaEngineGonkVideoSource::Stop(SourceMediaStream* aSource, TrackID aID)
{
  LOG((__FUNCTION__));
  {
    MonitorAutoLock lock(mMonitor);

    if (!mSources.RemoveElement(aSource)) {
      // Already stopped - this is allowed
      return NS_OK;
    }
    if (!mSources.IsEmpty()) {
      return NS_OK;
    }
  }

  ReentrantMonitorAutoEnter sync(mCallbackMonitor);

  if (mState != kStarted) {
    return NS_ERROR_FAILURE;
  }

  {
    MonitorAutoLock lock(mMonitor);
    mState = kStopped;
    aSource->EndTrack(aID);
    // Drop any cached image so we don't start with a stale image on next
    // usage
    mImage = nullptr;
  }

  NS_DispatchToMainThread(WrapRunnable(nsRefPtr<MediaEngineGonkVideoSource>(this),
                                       &MediaEngineGonkVideoSource::StopImpl));

  return NS_OK;
}
Example #14
0
void
CDMProxy::gmp_Init(uint32_t aPromiseId)
{
  MOZ_ASSERT(IsOnGMPThread());

  nsCOMPtr<mozIGeckoMediaPluginService> mps =
    do_GetService("@mozilla.org/gecko-media-plugin-service;1");
  if (!mps) {
    RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
    return;
  }

  nsTArray<nsCString> tags;
  tags.AppendElement(NS_ConvertUTF16toUTF8(mKeySystem));
  nsresult rv = mps->GetGMPDecryptor(&tags, GetOrigin(), &mCDM);
  if (NS_FAILED(rv) || !mCDM) {
    RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR);
  } else {
    mCallback = new CDMCallbackProxy(this);
    mCDM->Init(mCallback);
    nsRefPtr<nsIRunnable> task(NS_NewRunnableMethodWithArg<uint32_t>(this, &CDMProxy::OnCDMCreated, aPromiseId));
    NS_DispatchToMainThread(task);
  }
}
NS_IMETHODIMP
EventSource::OnStopRequest(nsIRequest *aRequest,
                           nsISupports *aContext,
                           nsresult aStatusCode)
{
  mWaitingForOnStopRequest = false;

  if (mReadyState == CLOSED) {
    return NS_ERROR_ABORT;
  }

  if (NS_FAILED(aStatusCode)) {
    DispatchFailConnection();
    return aStatusCode;
  }

  nsresult rv;
  nsresult healthOfRequestResult = CheckHealthOfRequestCallback(aRequest);
  if (NS_SUCCEEDED(healthOfRequestResult) &&
      mLastConvertionResult == NS_PARTIAL_MORE_INPUT) {
    // we had an incomplete UTF8 char at the end of the stream
    rv = ParseCharacter(REPLACEMENT_CHAR);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  ClearFields();

  nsCOMPtr<nsIRunnable> event =
    NS_NewRunnableMethod(this, &EventSource::ReestablishConnection);
  NS_ENSURE_STATE(event);

  rv = NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
  NS_ENSURE_SUCCESS(rv, rv);

  return healthOfRequestResult;
}
Example #16
0
bool
WMFVideoMFTManager::InitializeDXVA()
{
  // If we use DXVA but aren't running with a D3D layer manager then the
  // readback of decoded video frames from GPU to CPU memory grinds painting
  // to a halt, and makes playback performance *worse*.
  if (!mDXVAEnabled ||
      (mLayersBackend != LayersBackend::LAYERS_D3D9 &&
       mLayersBackend != LayersBackend::LAYERS_D3D10 &&
       mLayersBackend != LayersBackend::LAYERS_D3D11)) {
    return false;
  }

  if (gfxWindowsPlatform::GetPlatform()->IsWARP()) {
    return false;
  }

  // The DXVA manager must be created on the main thread.
  nsRefPtr<CreateDXVAManagerEvent> event(new CreateDXVAManagerEvent());
  NS_DispatchToMainThread(event, NS_DISPATCH_SYNC);
  mDXVA2Manager = event->mDXVA2Manager;

  return mDXVA2Manager != nullptr;
}
void
ContentProcessController::DispatchToRepaintThread(already_AddRefed<Runnable> aTask)
{
  NS_DispatchToMainThread(Move(aTask));
}
Example #18
0
template<class Super> bool
Parent<Super>::RecvGetOriginKey(const uint32_t& aRequestId,
                                const nsCString& aOrigin,
                                const bool& aPrivateBrowsing,
                                const bool& aPersist)
{
    MOZ_ASSERT(NS_IsMainThread());

    // First, get profile dir.

    MOZ_ASSERT(NS_IsMainThread());
    nsCOMPtr<nsIFile> profileDir;
    nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
                                         getter_AddRefs(profileDir));
    if (NS_WARN_IF(NS_FAILED(rv))) {
        return false;
    }

    // Then over to stream-transport thread to do the actual file io.
    // Stash a pledge to hold the answer and get an id for this request.

    RefPtr<Pledge<nsCString>> p = new Pledge<nsCString>();
    uint32_t id = mOutstandingPledges.Append(*p);

    nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
    MOZ_ASSERT(sts);
    RefPtr<OriginKeyStore> store(mOriginKeyStore);
    bool sameProcess = mSameProcess;

    rv = sts->Dispatch(NewRunnableFrom([id, profileDir, store, sameProcess, aOrigin,
    aPrivateBrowsing, aPersist]() -> nsresult {
        MOZ_ASSERT(!NS_IsMainThread());
        store->mOriginKeys.SetProfileDir(profileDir);
        nsCString result;
        if (aPrivateBrowsing) {
            store->mPrivateBrowsingOriginKeys.GetOriginKey(aOrigin, result);
        } else {
            store->mOriginKeys.GetOriginKey(aOrigin, result, aPersist);
        }

        // Pass result back to main thread.
        nsresult rv;
        rv = NS_DispatchToMainThread(NewRunnableFrom([id, store, sameProcess,
        result]() -> nsresult {
            Parent* parent = GccGetSingleton<Super>(); // GetSingleton();
            if (!parent) {
                return NS_OK;
            }
            RefPtr<Pledge<nsCString>> p = parent->mOutstandingPledges.Remove(id);
            if (!p) {
                return NS_ERROR_UNEXPECTED;
            }
            p->Resolve(result);
            return NS_OK;
        }), NS_DISPATCH_NORMAL);

        if (NS_WARN_IF(NS_FAILED(rv))) {
            return rv;
        }
        return NS_OK;
    }), NS_DISPATCH_NORMAL);

    if (NS_WARN_IF(NS_FAILED(rv))) {
        return false;
    }

    p->Then([aRequestId, sameProcess](const nsCString& aKey) mutable {
        if (!sameProcess) {
            if (!sIPCServingParent) {
                return NS_OK;
            }
            Unused << sIPCServingParent->SendGetOriginKeyResponse(aRequestId, aKey);
        } else {
            RefPtr<MediaManager> mgr = MediaManager::GetInstance();
            if (!mgr) {
                return NS_OK;
            }
            RefPtr<Pledge<nsCString>> pledge =
            mgr->mGetOriginKeyPledges.Remove(aRequestId);
            if (pledge) {
                pledge->Resolve(aKey);
            }
        }
        return NS_OK;
    });
    return true;
}
Example #19
0
NS_IMETHODIMP
OpenDatabaseHelper::Run()
{
  NS_ASSERTION(mState != eCreated, "Dispatch was not called?!?");

  if (NS_IsMainThread()) {
    // If we need to queue up a SetVersionHelper, do that here.
    if (mState == eSetVersionPending) {
      nsresult rv = StartSetVersion();

      if (NS_SUCCEEDED(rv)) {
        return rv;
      }

      SetError(rv);
      // fall through and run the default error processing
    }

    // We've done whatever work we need to do on the DB thread, and any
    // SetVersion stuff is done by now.
    NS_ASSERTION(mState == eFiringEvents ||
                 mState == eSetVersionCompleted, "Why are we here?");

    if (mState == eSetVersionCompleted) {
      // Allow transaction creation/other version change transactions to proceed
      // before we fire events.  Other version changes will be postd to the end
      // of the event loop, and will be behind whatever the page does in
      // its error/success event handlers.
      mDatabase->ExitSetVersionTransaction();

      mState = eFiringEvents;
    } else {
      // Notify the request that we're done, but only if we didn't just finish
      // a SetVersionHelper.  In the SetVersionHelper case, that helper tells
      // the request that it is done, and we avoid calling NotifyHandlerCompleted
      // twice.

      nsresult rv = mOpenDBRequest->NotifyHelperCompleted(this);
      if (NS_SUCCEEDED(mResultCode) && NS_FAILED(rv)) {
        mResultCode = rv;
      }
    }

    NS_ASSERTION(mState == eFiringEvents, "Why are we here?");

    if (NS_FAILED(mResultCode)) {
      DispatchErrorEvent();
    } else {
      DispatchSuccessEvent();
    }

    IndexedDatabaseManager* manager = IndexedDatabaseManager::Get();
    NS_ASSERTION(manager, "This should never be null!");

    manager->AllowNextSynchronizedOp(mASCIIOrigin, mDatabaseId);

    ReleaseMainThreadObjects();

    return NS_OK;
  }

  // If we're on the DB thread, do that
  NS_ASSERTION(mState == eDBWork, "Why are we here?");
  mResultCode = DoDatabaseWork();
  NS_ASSERTION(mState != eDBWork, "We should be doing something else now.");

  return NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
}
Example #20
0
void
nsPicoService::Init()
{
  MOZ_ASSERT(!NS_IsMainThread());
  MOZ_ASSERT(!mInitialized);

  if (!sPicoApi.Init()) {
    NS_WARNING("Failed to initialize pico library");
    return;
  }

  // Use environment variable, or default android/b2g path
  nsAutoCString langPath(PR_GetEnv("PICO_LANG_PATH"));

  if (langPath.IsEmpty()) {
    langPath.AssignLiteral(GONK_PICO_LANG_PATH);
  }

  nsCOMPtr<nsIFile> voicesDir;
  NS_NewNativeLocalFile(langPath, true, getter_AddRefs(voicesDir));

  nsCOMPtr<nsISimpleEnumerator> dirIterator;
  nsresult rv = voicesDir->GetDirectoryEntries(getter_AddRefs(dirIterator));

  if (NS_FAILED(rv)) {
    NS_WARNING(nsPrintfCString("Failed to get contents of directory: %s", langPath.get()).get());
    return;
  }

  bool hasMoreElements = false;
  rv = dirIterator->HasMoreElements(&hasMoreElements);
  MOZ_ASSERT(NS_SUCCEEDED(rv));

  MonitorAutoLock autoLock(mVoicesMonitor);

  while (hasMoreElements && NS_SUCCEEDED(rv)) {
    nsCOMPtr<nsISupports> supports;
    rv = dirIterator->GetNext(getter_AddRefs(supports));
    MOZ_ASSERT(NS_SUCCEEDED(rv));

    nsCOMPtr<nsIFile> voiceFile = do_QueryInterface(supports);
    MOZ_ASSERT(voiceFile);

    nsAutoCString leafName;
    voiceFile->GetNativeLeafName(leafName);

    nsAutoString lang;

    if (GetVoiceFileLanguage(leafName, lang)) {
      nsAutoString uri;
      uri.AssignLiteral("urn:moz-tts:pico:");
      uri.Append(lang);

      bool found = false;
      PicoVoice* voice = mVoices.GetWeak(uri, &found);

      if (!found) {
        voice = new PicoVoice(lang);
        mVoices.Put(uri, voice);
      }

      // Each voice consists of two lingware files: A language resource file,
      // suffixed by _ta.bin, and a speaker resource file, suffixed by _sb.bin.
      // We currently assume that there is a pair of files for each language.
      if (StringEndsWith(leafName, NS_LITERAL_CSTRING("_ta.bin"))) {
        rv = voiceFile->GetPersistentDescriptor(voice->mTaFile);
        MOZ_ASSERT(NS_SUCCEEDED(rv));
      } else if (StringEndsWith(leafName, NS_LITERAL_CSTRING("_sg.bin"))) {
        rv = voiceFile->GetPersistentDescriptor(voice->mSgFile);
        MOZ_ASSERT(NS_SUCCEEDED(rv));
      }
    }

    rv = dirIterator->HasMoreElements(&hasMoreElements);
  }

  NS_DispatchToMainThread(NS_NewRunnableMethod(this, &nsPicoService::RegisterVoices));
}
Example #21
0
void
AudioContext::OnStateChanged(void* aPromise, AudioContextState aNewState)
{
  MOZ_ASSERT(NS_IsMainThread());

  // This can happen if close() was called right after creating the
  // AudioContext, before the context has switched to "running".
  if (mAudioContextState == AudioContextState::Closed &&
      aNewState == AudioContextState::Running &&
      !aPromise) {
    return;
  }

  // This can happen if this is called in reaction to a
  // MediaStreamGraph shutdown, and a AudioContext was being
  // suspended at the same time, for example if a page was being
  // closed.
  if (mAudioContextState == AudioContextState::Closed &&
      aNewState == AudioContextState::Suspended) {
    return;
  }

#ifndef WIN32 // Bug 1170547
#ifndef XP_MACOSX
#ifdef DEBUG

  if (!((mAudioContextState == AudioContextState::Suspended &&
       aNewState == AudioContextState::Running)   ||
      (mAudioContextState == AudioContextState::Running   &&
       aNewState == AudioContextState::Suspended) ||
      (mAudioContextState == AudioContextState::Running   &&
       aNewState == AudioContextState::Closed)    ||
      (mAudioContextState == AudioContextState::Suspended &&
       aNewState == AudioContextState::Closed)    ||
      (mAudioContextState == aNewState))) {
    fprintf(stderr,
            "Invalid transition: mAudioContextState: %d -> aNewState %d\n",
            static_cast<int>(mAudioContextState), static_cast<int>(aNewState));
    MOZ_ASSERT(false);
  }

#endif // DEBUG
#endif // XP_MACOSX
#endif // WIN32

  MOZ_ASSERT(
    mIsOffline || aPromise || aNewState == AudioContextState::Running,
    "We should have a promise here if this is a real-time AudioContext."
    "Or this is the first time we switch to \"running\".");

  if (aPromise) {
    Promise* promise = reinterpret_cast<Promise*>(aPromise);
    promise->MaybeResolveWithUndefined();
    DebugOnly<bool> rv = mPromiseGripArray.RemoveElement(promise);
    MOZ_ASSERT(rv, "Promise wasn't in the grip array?");
  }

  if (mAudioContextState != aNewState) {
    RefPtr<OnStateChangeTask> onStateChangeTask =
      new OnStateChangeTask(this);
    NS_DispatchToMainThread(onStateChangeTask);
  }

  mAudioContextState = aNewState;
}
Example #22
0
        mBufferSize ? static_cast<short*>(mBuffer->Data()) : nullptr, mBufferSize / 2);
    }

  private:
    nsRefPtr<SharedBuffer> mBuffer;

    size_t mBufferSize;

    bool mFirstData;

    nsRefPtr<PicoCallbackRunnable> mCallback;
  };

  nsCOMPtr<nsIRunnable> sendEvent =
    new PicoSynthDataRunnable(aBuffer, aBufferSize, mFirstData, this);
  NS_DispatchToMainThread(sendEvent);
  mFirstData = false;
}

// nsISpeechTaskCallback

NS_IMETHODIMP
PicoCallbackRunnable::OnPause()
{
  return NS_OK;
}

NS_IMETHODIMP
PicoCallbackRunnable::OnResume()
{
  return NS_OK;
void
RootDirectoryEntry::GetInternal(const nsAString& aPath, const FileSystemFlags& aFlag,
                                const Optional<OwningNonNull<EntryCallback>>& aSuccessCallback,
                                const Optional<OwningNonNull<ErrorCallback>>& aErrorCallback,
                                GetInternalType aType) const
{
    if (!aSuccessCallback.WasPassed() && !aErrorCallback.WasPassed()) {
        return;
    }

    if (aFlag.mCreate) {
        ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback,
                                  NS_ERROR_DOM_SECURITY_ERR);
        return;
    }

    nsTArray<nsString> parts;
    if (!FileSystemUtils::IsValidRelativeDOMPath(aPath, parts)) {
        ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback,
                                  NS_ERROR_DOM_NOT_FOUND_ERR);
        return;
    }

    MOZ_ASSERT(!parts.IsEmpty());

    RefPtr<Entry> entry;
    for (uint32_t i = 0; i < mEntries.Length(); ++i) {
        ErrorResult rv;
        nsAutoString name;
        mEntries[i]->GetName(name, rv);

        if (NS_WARN_IF(rv.Failed())) {
            ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback,
                                      rv.StealNSResult());
            return;
        }

        if (name == parts[0]) {
            entry = mEntries[i];
            break;
        }
    }

    // Not found.
    if (!entry) {
        ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback,
                                  NS_ERROR_DOM_NOT_FOUND_ERR);
        return;
    }

    // No subdirectory in the path.
    if (parts.Length() == 1) {
        if ((entry->IsFile() && aType == eGetDirectory) ||
                (entry->IsDirectory() && aType == eGetFile)) {
            ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback,
                                      NS_ERROR_DOM_TYPE_MISMATCH_ERR);
            return;
        }

        if (aSuccessCallback.WasPassed()) {
            RefPtr<EntryCallbackRunnable> runnable =
                new EntryCallbackRunnable(&aSuccessCallback.Value(), entry);
            nsresult rv = NS_DispatchToMainThread(runnable);
            NS_WARN_IF(NS_FAILED(rv));
        }
        return;
    }

    // Subdirectories, but this is a file.
    if (entry->IsFile()) {
        ErrorCallbackHelper::Call(GetParentObject(), aErrorCallback,
                                  NS_ERROR_DOM_NOT_FOUND_ERR);
        return;
    }

    // Let's recreate a path without the first directory.
    nsAutoString path;
    for (uint32_t i = 1, len = parts.Length(); i < len; ++i) {
        path.Append(parts[i]);
        if (i < len - 1) {
            path.AppendLiteral(FILESYSTEM_DOM_PATH_SEPARATOR_LITERAL);
        }
    }

    auto* directoryEntry = static_cast<DirectoryEntry*>(entry.get());
    directoryEntry->GetInternal(path, aFlag, aSuccessCallback, aErrorCallback,
                                aType);
}
Example #24
0
void
DASHRepDecoder::LoadNextByteRange()
{
  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
  NS_ASSERTION(mResource, "Error: resource is reported as null!");

  // Return silently if shutting down.
  if (mShuttingDown) {
    LOG1("Shutting down! Ignoring LoadNextByteRange().");
    return;
  }

  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
  NS_ASSERTION(mMainDecoder, "Error: main decoder is null!");
  NS_ASSERTION(mMainDecoder->IsDecoderAllowedToDownloadData(this),
               "Should not be called on non-active decoders!");

  // Cannot have empty byte ranges.
  if (mByteRanges.IsEmpty()) {
    LOG1("Error getting list of subsegment byte ranges.");
    DecodeError();
    return;
  }

  // Get byte range for subsegment.
  int32_t subsegmentIdx = mMainDecoder->GetSubsegmentIndex(this);
  NS_ASSERTION(0 <= subsegmentIdx,
               "Subsegment index should be >= 0 for active decoders");
  if (subsegmentIdx >= 0 && (uint32_t)subsegmentIdx < mByteRanges.Length()) {
    mCurrentByteRange = mByteRanges[subsegmentIdx];
    mSubsegmentIdx = subsegmentIdx;
  } else {
    mCurrentByteRange.Clear();
    mSubsegmentIdx = -1;
    LOG("End of subsegments: index [%d] out of range.", subsegmentIdx);
    return;
  }

  // Request a seek for the first reader. Required so that the reader is
  // primed to start here, and will block subsequent subsegment seeks unless
  // the subsegment has been read.
  if (subsegmentIdx == 0) {
    ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
    mReader->RequestSeekToSubsegment(0);
  }

  // Query resource for cached ranges; only download if it's not there.
  if (IsSubsegmentCached(mSubsegmentIdx)) {
    LOG("Subsegment [%d] bytes [%lld] to [%lld] already cached. No need to "
        "download.", mSubsegmentIdx,
        mCurrentByteRange.mStart, mCurrentByteRange.mEnd);
    nsCOMPtr<nsIRunnable> event =
      NS_NewRunnableMethod(this, &DASHRepDecoder::DoNotifyDownloadEnded);
    nsresult rv = NS_DispatchToMainThread(event);
    if (NS_FAILED(rv)) {
      LOG("Error notifying subsegment [%d] cached: rv[0x%x].",
          mSubsegmentIdx, rv);
      NetworkError();
    }
    return;
  }

  // Open byte range corresponding to subsegment.
  nsresult rv = mResource->OpenByteRange(nullptr, mCurrentByteRange);
  if (NS_FAILED(rv)) {
    LOG("Error opening byte range [%lld - %lld]: subsegmentIdx [%d] rv [%x].",
        mCurrentByteRange.mStart, mCurrentByteRange.mEnd, mSubsegmentIdx, rv);
    NetworkError();
    return;
  }
}
Example #25
0
/*
 * Start session (called in a thread)
 */
void
MediaRecorder::BeginSessionThread(void *data)
{   
    nsresult rv;
    MediaRecorder *mr = static_cast<MediaRecorder*>(data);
    Properties *params = mr->params;

    /* Setup backends */
    #ifdef RAINBOW_Mac
    mr->aState->backend = new AudioSourceMac(params->chan, params->rate);
    mr->vState->backend = new VideoSourceMac(params->width, params->height);
    #endif
    #ifdef RAINBOW_Win
    mr->aState->backend = new AudioSourceWin(params->chan, params->rate);
    mr->vState->backend = new VideoSourceWin(params->width, params->height);
    #endif
    #ifdef RAINBOW_Nix
    mr->aState->backend = new AudioSourceNix(params->chan, params->rate);
    mr->vState->backend = new VideoSourceNix(params->width, params->height);
    #endif
 
    /* Is the given canvas source or destination? */
    if (params->canvas) {
        mr->vState->backend = new VideoSourceCanvas(params->width, params->height);
    }
       
    /* Update parameters. What we asked for were just hints,
     * may not end up the same */
    params->fps_n = mr->vState->backend->GetFPSN();
    params->fps_d = mr->vState->backend->GetFPSD();
    params->rate = mr->aState->backend->GetRate();
    params->chan = mr->aState->backend->GetChannels();

    /* FIXME: device detection TBD */
    if (params->audio && (mr->aState == nsnull)) {
        NS_DispatchToMainThread(new MediaCallback(
            mr->observer, "error", "audio requested but no devices found"
        ));
        return;
    }
    if (params->video && (mr->vState == nsnull)) {
        NS_DispatchToMainThread(new MediaCallback(
            mr->observer, "error", "video requested but no devices found"
        ));
        return;
    }

    /* Let's DO this. */
    if (params->video) {
        rv = mr->vState->backend->Start(mr->canvas);
        if (NS_FAILED(rv)) {
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "internal: could not start video session"
            ));
            return;
        }
    }
    /* No preview for audio */

    mr->m_session = PR_TRUE;
    NS_DispatchToMainThread(new MediaCallback(
        mr->observer, "session-began", ""
    ));
    return;
}
Example #26
0
/*
 * End recording (called in a thread)
 */
void
MediaRecorder::EndRecordingThread(void *data)
{
    nsresult rv;
    PRUint32 wr;
    MediaRecorder *mr = static_cast<MediaRecorder*>(data);
    
    if (mr->v_rec) {
        rv = mr->vState->backend->StopRecording();
        if (NS_FAILED(rv)) {
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "could not stop video recording"
            ));
            return;
        }
    }

    if (mr->a_rec) {
        rv = mr->aState->backend->Stop();
        if (NS_FAILED(rv)) {
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "could not stop audio recording"
            ));
            return;
        }
    }

    /* Wait for encoder to finish */
    if (mr->v_rec) {
        mr->v_stp = PR_TRUE;
        mr->vState->vPipeOut->Close();
    }
    if (mr->a_rec) {
        mr->a_stp = PR_TRUE;
        mr->aState->aPipeOut->Close();
    }

    PR_JoinThread(mr->thread);

    if (mr->v_rec) {
        mr->vState->vPipeIn->Close();
        th_encode_free(mr->vState->th);

        /* Video trailer */
        if (ogg_stream_flush(&mr->vState->os, &mr->vState->og)) {
            rv = mr->WriteData(
                mr->vState->og.header, mr->vState->og.header_len, &wr
            );
            rv = mr->WriteData(
                mr->vState->og.body, mr->vState->og.body_len, &wr
            );
        }

        ogg_stream_clear(&mr->vState->os);
        mr->v_rec = PR_FALSE;
    }

    if (mr->a_rec) {
        mr->aState->aPipeIn->Close();

        /* Audio trailer */
        vorbis_analysis_wrote(&mr->aState->vd, 0);
        mr->WriteAudio();

        vorbis_block_clear(&mr->aState->vb);
        vorbis_dsp_clear(&mr->aState->vd);
        vorbis_comment_clear(&mr->aState->vc);
        vorbis_info_clear(&mr->aState->vi);
        ogg_stream_clear(&mr->aState->os);
        mr->a_rec = PR_FALSE;
    }

    /* GG */
    mr->pipeStream->Close();
    NS_DispatchToMainThread(new MediaCallback(
        mr->observer, "record-ended", ""
    ));
    return;
}
Example #27
0
void
MediaRecorder::BeginRecordingThread(void *data)
{
    nsresult rv;
    MediaRecorder *mr = static_cast<MediaRecorder*>(data);
    
    /* Get ready for video! */
    if (mr->params->video) {
        mr->SetupTheoraBOS();
        rv = mr->MakePipe(
            getter_AddRefs(mr->vState->vPipeIn),
            getter_AddRefs(mr->vState->vPipeOut)
        );
        if (NS_FAILED(rv)) {
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "internal: could not create video pipe"
            ));
            return;
        }
    }

    /* Get ready for audio! */
    if (mr->params->audio) {
        mr->SetupVorbisBOS();
        rv = mr->MakePipe(
            getter_AddRefs(mr->aState->aPipeIn),
            getter_AddRefs(mr->aState->aPipeOut)
        );
        if (NS_FAILED(rv)) {
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "internal: could not create audio pipe"
            ));
            return;
        }
    }
    
    if (mr->params->video) {
        mr->v_rec = PR_TRUE;
        mr->v_stp = PR_FALSE;
        mr->SetupTheoraHeaders();
        mr->vState->backend->StartRecording(mr->vState->vPipeOut);
    }

    if (mr->params->audio) {
        mr->SetupVorbisHeaders();
        rv = mr->aState->backend->Start(mr->aState->aPipeOut);
        if (NS_FAILED(rv)) {
            /* FIXME: Stop and clean up video! */
            NS_DispatchToMainThread(new MediaCallback(
                mr->observer, "error", "internal: could not start audio recording"
            ));
            return;
        }
        mr->a_rec = PR_TRUE;
        mr->a_stp = PR_FALSE;
    }
    
    /* Start off encoder after notifying observer */
    NS_DispatchToMainThread(new MediaCallback(
        mr->observer, "record-began", ""
    ));
    mr->Encode();
}
NS_IMETHODIMP RenameFolderTask::Run() {
	int ret = EWS_FAIL;
	nsresult rv;

	if (EWS_FAIL == NotifyBegin(this)) {
		return NS_OK;
	}
	
	ews_session * session = NULL;
	nsCOMPtr<IMailEwsMsgIncomingServer> ewsServer(do_QueryInterface(m_pIncomingServer, &rv));
	NS_ENSURE_SUCCESS(rv, rv);

	nsCOMPtr<IMailEwsService> ewsService;
	rv = ewsServer->GetService(getter_AddRefs(ewsService));
	NS_ENSURE_SUCCESS(rv, rv);

	nsresult rv1 = ewsService->GetNewSession(&session);

	if (NS_SUCCEEDED(rv)
	    && NS_SUCCEEDED(rv1)
	    && session) {
		nsCOMPtr<IMailEwsMsgFolder> curFolder(do_QueryInterface(m_Folder));
		
		nsCString savedFolderId;
		rv = curFolder->GetFolderId(savedFolderId);
		if (NS_FAILED(rv)) {
			NotifyError(this, EWS_FAIL, "unable to get folder id");
			return NS_OK;
		}

		nsCString change_key;
		rv = curFolder->GetChangeKey(change_key);
		if (NS_FAILED(rv)) {
			NotifyError(this, EWS_FAIL, "unable to get folder change key");
			return NS_OK;
		}
  
		ews_folder * folder = (ews_folder *)malloc(sizeof(char) * sizeof(ews_folder));
		memset(folder, 0, sizeof(ews_folder));
		char * display_name = ToNewUTF8String(m_NewName);
		folder->display_name = strdup(display_name);
		folder->id = strdup(savedFolderId.get());
		folder->change_key = strdup(change_key.get());
		NS_Free(display_name);
		
		char * err_msg = NULL;

		ret = ews_update_folder(session,
		                            folder,
		                            &err_msg);

		if (ret != EWS_SUCCESS) {
			mailews_logger << "rename folder on server fail:"
			          << ret
			          << ","
			          << err_msg
			          << std::endl;
			NotifyError(this, ret, err_msg);
		}

		if (err_msg) free(err_msg);

		ews_free_folder(folder);
	} else {
		NotifyError(this, session ? EWS_FAIL : 401, NULL);
	}

	ewsService->ReleaseSession(session);
	
	nsCOMPtr<nsIRunnable> resultrunnable =
			new RenameFolderDoneTask(ret,
			                         m_Folder,
			                         m_NewName,
			                         m_MsgWindow,
			                         m_pEwsTaskCallbacks,
			                         this);
		
	NS_DispatchToMainThread(resultrunnable);

	return NS_OK;
}
void
FakeMediaStreamGraph::DispatchToMainThreadAfterStreamStateUpdate(already_AddRefed<nsIRunnable> aRunnable)
{
    nsCOMPtr<nsIRunnable> task = aRunnable;
    NS_DispatchToMainThread(task);
}
Example #30
0
template<class Super> mozilla::ipc::IPCResult
Parent<Super>::RecvGetPrincipalKey(const uint32_t& aRequestId,
                                   const ipc::PrincipalInfo& aPrincipalInfo,
                                   const bool& aPersist)
{
  MOZ_ASSERT(NS_IsMainThread());

  // First, get profile dir.

  MOZ_ASSERT(NS_IsMainThread());
  nsCOMPtr<nsIFile> profileDir;
  nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
                                       getter_AddRefs(profileDir));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return IPCResult(this, false);
  }

  // Then over to stream-transport thread to do the actual file io.
  // Stash a pledge to hold the answer and get an id for this request.

  RefPtr<Pledge<nsCString>> p = new Pledge<nsCString>();
  uint32_t id = mOutstandingPledges.Append(*p);

  nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
  MOZ_ASSERT(sts);
  RefPtr<Parent<Super>> that(this);

  rv = sts->Dispatch(NewRunnableFrom([this, that, id, profileDir,
                                      aPrincipalInfo, aPersist]() -> nsresult {
    MOZ_ASSERT(!NS_IsMainThread());
    mOriginKeyStore->mOriginKeys.SetProfileDir(profileDir);

    nsresult rv;
    nsAutoCString result;
    if (IsPincipalInfoPrivate(aPrincipalInfo)) {
      rv = mOriginKeyStore->mPrivateBrowsingOriginKeys.GetPrincipalKey(aPrincipalInfo, result);
    } else {
      rv = mOriginKeyStore->mOriginKeys.GetPrincipalKey(aPrincipalInfo, result, aPersist);
    }

    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }

    // Pass result back to main thread.
    rv = NS_DispatchToMainThread(NewRunnableFrom([this, that, id,
                                                  result]() -> nsresult {
      if (mDestroyed) {
        return NS_OK;
      }
      RefPtr<Pledge<nsCString>> p = mOutstandingPledges.Remove(id);
      if (!p) {
        return NS_ERROR_UNEXPECTED;
      }
      p->Resolve(result);
      return NS_OK;
    }), NS_DISPATCH_NORMAL);

    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
    return NS_OK;
  }), NS_DISPATCH_NORMAL);

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return IPCResult(this, false);
  }
  p->Then([this, that, aRequestId](const nsCString& aKey) mutable {
    if (mDestroyed) {
      return NS_OK;
    }
    Unused << this->SendGetPrincipalKeyResponse(aRequestId, aKey);
    return NS_OK;
  });
  return IPC_OK();
}