void OnError(BluetoothStatus aStatus) override { MOZ_ASSERT(NS_IsMainThread()); mRes->OnError(aStatus); }
already_AddRefed<Promise> GetFileOrDirectoryTaskChild::GetPromise() { MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); return RefPtr<Promise>(mPromise).forget(); }
void CDMProxy::Shutdown() { MOZ_ASSERT(NS_IsMainThread()); mKeys.Clear(); }
FileSystemSecurity::~FileSystemSecurity() { MOZ_ASSERT(NS_IsMainThread()); AssertIsInMainProcess(); }
SourceBuffer::~SourceBuffer() { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!mMediaSource); MSE_DEBUG("SourceBuffer(%p)::~SourceBuffer", this); }
double HTMLVideoElement::MozFrameDelay() { MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread."); VideoFrameContainer* container = GetVideoFrameContainer(); return container ? container->GetFrameDelay() : 0; }
CompositorThreadHolder::CompositorThreadHolder() : mCompositorThread(CreateCompositorThread()) { MOZ_ASSERT(NS_IsMainThread()); MOZ_COUNT_CTOR(CompositorThreadHolder); }
static ObjectType* GetInstance() { MOZ_ASSERT(NS_IsMainThread()); return sA2dpNotificationHandler; }
// https://html.spec.whatwg.org/multipage/embedded-content.html#time-marches-on void TextTrackManager::TimeMarchesOn() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); mTimeMarchesOnDispatched = false; // Early return if we don't have any TextTracks. if (mTextTracks->Length() == 0) { return; } nsISupports* parentObject = mMediaElement->OwnerDoc()->GetParentObject(); if (NS_WARN_IF(!parentObject)) { return; } nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(parentObject); if (mMediaElement && (!(mMediaElement->GetPlayedOrSeeked()) || mMediaElement->Seeking())) { return; } // Step 3. double currentPlaybackTime = mMediaElement->CurrentTime(); bool hasNormalPlayback = !mHasSeeked; mHasSeeked = false; // Step 1, 2. RefPtr<TextTrackCueList> currentCues = new TextTrackCueList(window); RefPtr<TextTrackCueList> otherCues = new TextTrackCueList(window); bool dummy; for (uint32_t index = 0; index < mTextTracks->Length(); ++index) { TextTrack* ttrack = mTextTracks->IndexedGetter(index, dummy); if (ttrack && dummy) { // TODO: call GetCueListByTimeInterval on mNewCues? TextTrackCueList* activeCueList = ttrack->GetActiveCues(); if (activeCueList) { for (uint32_t i = 0; i < activeCueList->Length(); ++i) { currentCues->AddCue(*((*activeCueList)[i])); } } } } // Populate otherCues with 'non-active" cues. if (hasNormalPlayback) { if (currentPlaybackTime < mLastTimeMarchesOnCalled) { // TODO: Add log and find the root cause why the // playback position goes backward. mLastTimeMarchesOnCalled = currentPlaybackTime; } media::Interval<double> interval(mLastTimeMarchesOnCalled, currentPlaybackTime); otherCues = mNewCues->GetCueListByTimeInterval(interval);; } else { // Seek case. Put the mLastActiveCues into otherCues. otherCues = mLastActiveCues; } for (uint32_t i = 0; i < currentCues->Length(); ++i) { TextTrackCue* cue = (*currentCues)[i]; otherCues->RemoveCue(*cue); } // Step 4. RefPtr<TextTrackCueList> missedCues = new TextTrackCueList(window); if (hasNormalPlayback) { for (uint32_t i = 0; i < otherCues->Length(); ++i) { TextTrackCue* cue = (*otherCues)[i]; if (cue->StartTime() >= mLastTimeMarchesOnCalled && cue->EndTime() <= currentPlaybackTime) { missedCues->AddCue(*cue); } } } // Step 5. Empty now. // TODO: Step 6: fire timeupdate? // Step 7. Abort steps if condition 1, 2, 3 are satisfied. // 1. All of the cues in current cues have their active flag set. // 2. None of the cues in other cues have their active flag set. // 3. Missed cues is empty. bool c1 = true; for (uint32_t i = 0; i < currentCues->Length(); ++i) { if (!(*currentCues)[i]->GetActive()) { c1 = false; break; } } bool c2 = true; for (uint32_t i = 0; i < otherCues->Length(); ++i) { if ((*otherCues)[i]->GetActive()) { c2 = false; break; } } bool c3 = (missedCues->Length() == 0); if (c1 && c2 && c3) { mLastTimeMarchesOnCalled = currentPlaybackTime; return; } // Step 8. Respect PauseOnExit flag if not seek. if (hasNormalPlayback) { for (uint32_t i = 0; i < otherCues->Length(); ++i) { TextTrackCue* cue = (*otherCues)[i]; if (cue && cue->PauseOnExit() && cue->GetActive()) { mMediaElement->Pause(); break; } } for (uint32_t i = 0; i < missedCues->Length(); ++i) { TextTrackCue* cue = (*missedCues)[i]; if (cue && cue->PauseOnExit()) { mMediaElement->Pause(); break; } } } // Step 15. // Sort text tracks in the same order as the text tracks appear // in the media element's list of text tracks, and remove // duplicates. TextTrackListInternal affectedTracks; // Step 13, 14. nsTArray<RefPtr<SimpleTextTrackEvent>> eventList; // Step 9, 10. // For each text track cue in missed cues, prepare an event named // enter for the TextTrackCue object with the cue start time. for (uint32_t i = 0; i < missedCues->Length(); ++i) { TextTrackCue* cue = (*missedCues)[i]; if (cue) { SimpleTextTrackEvent* event = new SimpleTextTrackEvent(NS_LITERAL_STRING("enter"), cue->StartTime(), cue->GetTrack(), cue); eventList.InsertElementSorted(event, CompareSimpleTextTrackEvents(mMediaElement)); affectedTracks.AddTextTrack(cue->GetTrack(), CompareTextTracks(mMediaElement)); } } // Step 11, 17. for (uint32_t i = 0; i < otherCues->Length(); ++i) { TextTrackCue* cue = (*otherCues)[i]; if (cue->GetActive() || missedCues->IsCueExist(cue)) { double time = cue->StartTime() > cue->EndTime() ? cue->StartTime() : cue->EndTime(); SimpleTextTrackEvent* event = new SimpleTextTrackEvent(NS_LITERAL_STRING("exit"), time, cue->GetTrack(), cue); eventList.InsertElementSorted(event, CompareSimpleTextTrackEvents(mMediaElement)); affectedTracks.AddTextTrack(cue->GetTrack(), CompareTextTracks(mMediaElement)); } cue->SetActive(false); } // Step 12, 17. for (uint32_t i = 0; i < currentCues->Length(); ++i) { TextTrackCue* cue = (*currentCues)[i]; if (!cue->GetActive()) { SimpleTextTrackEvent* event = new SimpleTextTrackEvent(NS_LITERAL_STRING("enter"), cue->StartTime(), cue->GetTrack(), cue); eventList.InsertElementSorted(event, CompareSimpleTextTrackEvents(mMediaElement)); affectedTracks.AddTextTrack(cue->GetTrack(), CompareTextTracks(mMediaElement)); } cue->SetActive(true); } // Fire the eventList for (uint32_t i = 0; i < eventList.Length(); ++i) { NS_DispatchToMainThread(eventList[i].forget()); } // Step 16. for (uint32_t i = 0; i < affectedTracks.Length(); ++i) { TextTrack* ttrack = affectedTracks[i]; if (ttrack) { ttrack->DispatchTrustedEvent(NS_LITERAL_STRING("cuechange")); HTMLTrackElement* trackElement = ttrack->GetTrackElement(); if (trackElement) { trackElement->DispatchTrackRunnable(NS_LITERAL_STRING("cuechange")); } } } mLastTimeMarchesOnCalled = currentPlaybackTime; mLastActiveCues = currentCues; // Step 18. UpdateCueDisplay(); }
already_AddRefed<IDBOpenDBRequest> IDBFactory::OpenInternal(nsIPrincipal* aPrincipal, const nsAString& aName, const Optional<uint64_t>& aVersion, const Optional<StorageType>& aStorageType, bool aDeleting, ErrorResult& aRv) { MOZ_ASSERT(mWindow || mOwningObject); MOZ_ASSERT_IF(!mWindow, !mPrivateBrowsingMode); CommonFactoryRequestParams commonParams; commonParams.privateBrowsingMode() = mPrivateBrowsingMode; PrincipalInfo& principalInfo = commonParams.principalInfo(); if (aPrincipal) { if (!NS_IsMainThread()) { MOZ_CRASH("Figure out security checks for workers!"); } MOZ_ASSERT(nsContentUtils::IsCallerChrome()); if (NS_WARN_IF(NS_FAILED(PrincipalToPrincipalInfo(aPrincipal, &principalInfo)))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } if (principalInfo.type() != PrincipalInfo::TContentPrincipalInfo && principalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } } else { principalInfo = *mPrincipalInfo; } uint64_t version = 0; if (!aDeleting && aVersion.WasPassed()) { if (aVersion.Value() < 1) { aRv.ThrowTypeError(MSG_INVALID_VERSION); return nullptr; } version = aVersion.Value(); } // Nothing can be done here if we have previously failed to create a // background actor. if (mBackgroundActorFailed) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } PersistenceType persistenceType; if (principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) { // Chrome privilege always gets persistent storage. persistenceType = PERSISTENCE_TYPE_PERSISTENT; } else { persistenceType = PersistenceTypeFromStorage(aStorageType); } DatabaseMetadata& metadata = commonParams.metadata(); metadata.name() = aName; metadata.persistenceType() = persistenceType; FactoryRequestParams params; if (aDeleting) { metadata.version() = 0; params = DeleteDatabaseRequestParams(commonParams); } else { metadata.version() = version; params = OpenDatabaseRequestParams(commonParams); } if (!mBackgroundActor && mPendingRequests.IsEmpty()) { // We need to start the sequence to create a background actor for this // thread. BackgroundChildImpl::ThreadLocal* threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); nsAutoPtr<ThreadLocal> newIDBThreadLocal; ThreadLocal* idbThreadLocal; if (threadLocal && threadLocal->mIndexedDBThreadLocal) { idbThreadLocal = threadLocal->mIndexedDBThreadLocal; } else { nsCOMPtr<nsIUUIDGenerator> uuidGen = do_GetService("@mozilla.org/uuid-generator;1"); MOZ_ASSERT(uuidGen); nsID id; MOZ_ALWAYS_TRUE(NS_SUCCEEDED(uuidGen->GenerateUUIDInPlace(&id))); newIDBThreadLocal = idbThreadLocal = new ThreadLocal(id); } nsRefPtr<BackgroundCreateCallback> cb = new BackgroundCreateCallback(this, idbThreadLocal->GetLoggingInfo()); if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread(cb))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } if (newIDBThreadLocal) { if (!threadLocal) { threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); } MOZ_ASSERT(threadLocal); MOZ_ASSERT(!threadLocal->mIndexedDBThreadLocal); threadLocal->mIndexedDBThreadLocal = newIDBThreadLocal.forget(); } } AutoJSAPI autoJS; nsRefPtr<IDBOpenDBRequest> request; if (mWindow) { AutoJSContext cx; if (NS_WARN_IF(!autoJS.Init(mWindow, cx))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } JS::Rooted<JSObject*> scriptOwner(cx, static_cast<nsGlobalWindow*>(mWindow.get())->FastGetGlobalJSObject()); MOZ_ASSERT(scriptOwner); request = IDBOpenDBRequest::CreateForWindow(this, mWindow, scriptOwner); } else { autoJS.Init(mOwningObject.get()); JS::Rooted<JSObject*> scriptOwner(autoJS.cx(), mOwningObject); request = IDBOpenDBRequest::CreateForJS(this, scriptOwner); } MOZ_ASSERT(request); if (aDeleting) { IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " "indexedDB.deleteDatabase(\"%s\")", "IndexedDB %s: C R[%llu]: IDBFactory.deleteDatabase()", IDB_LOG_ID_STRING(), request->LoggingSerialNumber(), NS_ConvertUTF16toUTF8(aName).get()); } else { IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " "indexedDB.open(\"%s\", %s)", "IndexedDB %s: C R[%llu]: IDBFactory.open()", IDB_LOG_ID_STRING(), request->LoggingSerialNumber(), NS_ConvertUTF16toUTF8(aName).get(), IDB_LOG_STRINGIFY(aVersion)); } // If we already have a background actor then we can start this request now. if (mBackgroundActor) { nsresult rv = InitiateRequest(request, params); if (NS_WARN_IF(NS_FAILED(rv))) { IDB_REPORT_INTERNAL_ERR(); aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); return nullptr; } } else { mPendingRequests.AppendElement(new PendingRequestInfo(request, params)); } return request.forget(); }
void MediaDecodeTask::Decode() { MOZ_ASSERT(!mThreadPool == NS_IsMainThread(), "We should be on the main thread only if we don't have a thread pool"); mBufferDecoder->BeginDecoding(NS_GetCurrentThread()); // Tell the decoder reader that we are not going to play the data directly, // and that we should not reject files with more channels than the audio // bakend support. mDecoderReader->SetIgnoreAudioOutputFormat(); mDecoderReader->OnDecodeThreadStart(); MediaInfo mediaInfo; nsAutoPtr<MetadataTags> tags; nsresult rv = mDecoderReader->ReadMetadata(&mediaInfo, getter_Transfers(tags)); if (NS_FAILED(rv)) { ReportFailureOnMainThread(WebAudioDecodeJob::InvalidContent); return; } if (!mDecoderReader->HasAudio()) { ReportFailureOnMainThread(WebAudioDecodeJob::NoAudio); return; } while (mDecoderReader->DecodeAudioData()) { // consume all of the buffer continue; } mDecoderReader->OnDecodeThreadFinish(); MediaQueue<AudioData>& audioQueue = mDecoderReader->AudioQueue(); uint32_t frameCount = audioQueue.FrameCount(); uint32_t channelCount = mediaInfo.mAudio.mChannels; uint32_t sampleRate = mediaInfo.mAudio.mRate; if (!frameCount || !channelCount || !sampleRate) { ReportFailureOnMainThread(WebAudioDecodeJob::InvalidContent); return; } const uint32_t destSampleRate = mDecodeJob.mContext->SampleRate(); AutoResampler resampler; uint32_t resampledFrames = frameCount; if (sampleRate != destSampleRate) { resampledFrames = static_cast<uint32_t>( static_cast<uint64_t>(destSampleRate) * static_cast<uint64_t>(frameCount) / static_cast<uint64_t>(sampleRate) ); resampler = speex_resampler_init(channelCount, sampleRate, destSampleRate, SPEEX_RESAMPLER_QUALITY_DEFAULT, nullptr); speex_resampler_skip_zeros(resampler); resampledFrames += speex_resampler_get_output_latency(resampler); } // Allocate the channel buffers. Note that if we end up resampling, we may // write fewer bytes than mResampledFrames to the output buffer, in which // case mWriteIndex will tell us how many valid samples we have. static const fallible_t fallible = fallible_t(); bool memoryAllocationSuccess = true; if (!mDecodeJob.mChannelBuffers.SetLength(channelCount)) { memoryAllocationSuccess = false; } else { for (uint32_t i = 0; i < channelCount; ++i) { mDecodeJob.mChannelBuffers[i] = new(fallible) float[resampledFrames]; if (!mDecodeJob.mChannelBuffers[i]) { memoryAllocationSuccess = false; break; } } } if (!memoryAllocationSuccess) { ReportFailureOnMainThread(WebAudioDecodeJob::UnknownError); return; } nsAutoPtr<AudioData> audioData; while ((audioData = audioQueue.PopFront())) { audioData->EnsureAudioBuffer(); // could lead to a copy :( AudioDataValue* bufferData = static_cast<AudioDataValue*> (audioData->mAudioBuffer->Data()); if (sampleRate != destSampleRate) { const uint32_t maxOutSamples = resampledFrames - mDecodeJob.mWriteIndex; for (uint32_t i = 0; i < audioData->mChannels; ++i) { uint32_t inSamples = audioData->mFrames; uint32_t outSamples = maxOutSamples; WebAudioUtils::SpeexResamplerProcess( resampler, i, &bufferData[i * audioData->mFrames], &inSamples, mDecodeJob.mChannelBuffers[i] + mDecodeJob.mWriteIndex, &outSamples); if (i == audioData->mChannels - 1) { mDecodeJob.mWriteIndex += outSamples; MOZ_ASSERT(mDecodeJob.mWriteIndex <= resampledFrames); MOZ_ASSERT(inSamples == audioData->mFrames); } } } else { for (uint32_t i = 0; i < audioData->mChannels; ++i) { ConvertAudioSamples(&bufferData[i * audioData->mFrames], mDecodeJob.mChannelBuffers[i] + mDecodeJob.mWriteIndex, audioData->mFrames); if (i == audioData->mChannels - 1) { mDecodeJob.mWriteIndex += audioData->mFrames; } } } } if (sampleRate != destSampleRate) { uint32_t inputLatency = speex_resampler_get_input_latency(resampler); const uint32_t maxOutSamples = resampledFrames - mDecodeJob.mWriteIndex; for (uint32_t i = 0; i < channelCount; ++i) { uint32_t inSamples = inputLatency; uint32_t outSamples = maxOutSamples; WebAudioUtils::SpeexResamplerProcess( resampler, i, (AudioDataValue*)nullptr, &inSamples, mDecodeJob.mChannelBuffers[i] + mDecodeJob.mWriteIndex, &outSamples); if (i == channelCount - 1) { mDecodeJob.mWriteIndex += outSamples; MOZ_ASSERT(mDecodeJob.mWriteIndex <= resampledFrames); MOZ_ASSERT(inSamples == inputLatency); } } } mPhase = PhaseEnum::AllocateBuffer; RunNextPhase(); }
// static nsresult IDBFactory::AllowedForWindowInternal(nsPIDOMWindow* aWindow, nsIPrincipal** aPrincipal) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aWindow); MOZ_ASSERT(aWindow->IsInnerWindow()); if (NS_WARN_IF(!IndexedDatabaseManager::GetOrCreate())) { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } nsIDocument* document = aWindow->GetExtantDoc(); if (document->GetSandboxFlags() & SANDBOXED_ORIGIN) { return NS_ERROR_DOM_SECURITY_ERR; } nsCOMPtr<nsIScriptObjectPrincipal> sop = do_QueryInterface(aWindow); MOZ_ASSERT(sop); nsCOMPtr<nsIPrincipal> principal = sop->GetPrincipal(); if (NS_WARN_IF(!principal)) { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } if (nsContentUtils::IsSystemPrincipal(principal)) { principal.forget(aPrincipal); return NS_OK; } bool isNullPrincipal; if (NS_WARN_IF(NS_FAILED(principal->GetIsNullPrincipal(&isNullPrincipal))) || isNullPrincipal) { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } // Whitelist about:home, since it doesn't have a base domain it would not // pass the ThirdPartyUtil check, though it should be able to use indexedDB. bool skipThirdPartyCheck = false; nsCOMPtr<nsIURI> uri; MOZ_ALWAYS_TRUE(NS_SUCCEEDED(principal->GetURI(getter_AddRefs(uri)))); bool isAbout; MOZ_ALWAYS_TRUE(NS_SUCCEEDED(uri->SchemeIs("about", &isAbout))); if (isAbout) { nsCOMPtr<nsIAboutModule> module; if (NS_SUCCEEDED(NS_GetAboutModule(uri, getter_AddRefs(module)))) { uint32_t flags; if (NS_SUCCEEDED(module->GetURIFlags(uri, &flags))) { skipThirdPartyCheck = flags & nsIAboutModule::ENABLE_INDEXED_DB; } else { NS_WARNING("GetURIFlags failed!"); } } else { NS_WARNING("NS_GetAboutModule failed!"); } } if (!skipThirdPartyCheck) { nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = do_GetService(THIRDPARTYUTIL_CONTRACTID); MOZ_ASSERT(thirdPartyUtil); bool isThirdParty; if (NS_WARN_IF(NS_FAILED( thirdPartyUtil->IsThirdPartyWindow(aWindow, nullptr, &isThirdParty)))) { return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; } if (isThirdParty) { return NS_ERROR_DOM_NOT_SUPPORTED_ERR; } } principal.forget(aPrincipal); return NS_OK; }
WebrtcVideoConduit::~WebrtcVideoConduit() { #ifdef MOZILLA_INTERNAL_API // unit tests create their own "main thread" NS_ASSERTION(NS_IsMainThread(), "Only call on main thread"); #endif CSFLogDebug(logTag, "%s ", __FUNCTION__); for(std::vector<VideoCodecConfig*>::size_type i=0;i < mRecvCodecList.size();i++) { delete mRecvCodecList[i]; } delete mCurSendCodecConfig; // The first one of a pair to be deleted shuts down media for both //Deal with External Capturer if(mPtrViECapture) { if (!mShutDown) { mPtrViECapture->DisconnectCaptureDevice(mCapId); mPtrViECapture->ReleaseCaptureDevice(mCapId); mPtrExtCapture = nullptr; if (mOtherDirection) mOtherDirection->mPtrExtCapture = nullptr; } mPtrViECapture->Release(); } if (mPtrExtCodec) { mPtrExtCodec->Release(); mPtrExtCodec = NULL; } //Deal with External Renderer if(mPtrViERender) { if (!mShutDown) { if(mRenderer) { mPtrViERender->StopRender(mChannel); } mPtrViERender->RemoveRenderer(mChannel); } mPtrViERender->Release(); } //Deal with the transport if(mPtrViENetwork) { if (!mShutDown) { mPtrViENetwork->DeregisterSendTransport(mChannel); } mPtrViENetwork->Release(); } if(mPtrViECodec) { mPtrViECodec->Release(); } if(mPtrViEBase) { if (!mShutDown) { mPtrViEBase->StopSend(mChannel); mPtrViEBase->StopReceive(mChannel); SyncTo(nullptr); mPtrViEBase->DeleteChannel(mChannel); } mPtrViEBase->Release(); } if (mPtrRTP) { mPtrRTP->Release(); } if (mOtherDirection) { // mOtherDirection owns these now! mOtherDirection->mOtherDirection = nullptr; // let other side we terminated the channel mOtherDirection->mShutDown = true; mVideoEngine = nullptr; } else { // only one opener can call Delete. Have it be the last to close. if(mVideoEngine) { webrtc::VideoEngine::Delete(mVideoEngine); } } }
void RegisterModule() override { MOZ_ASSERT(NS_IsMainThread()); mRes->Init(); }
uint32_t HTMLVideoElement::MozPresentedFrames() const { MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread."); return mDecoder ? mDecoder->GetFrameStatistics().GetPresentedFrames() : 0; }
NS_IMETHOD Run() { NS_ASSERTION(NS_IsMainThread(), "Must be on main thread."); mDXVA2Manager = DXVA2Manager::Create(); return NS_OK; }
uint32_t HTMLVideoElement::MozPaintedFrames() { MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread."); layers::ImageContainer* container = GetImageContainer(); return container ? container->GetPaintCount() : 0; }
OSFileConstantsService::OSFileConstantsService() { MOZ_ASSERT(NS_IsMainThread()); }
/* readonly attribute bool mozHasAudio */ bool HTMLVideoElement::MozHasAudio() const { MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread."); return mHasAudio; }
/** * Perform the part of initialization that can only be * executed on the main thread. */ nsresult InitOSFileConstants() { MOZ_ASSERT(NS_IsMainThread()); if (gInitialized) { return NS_OK; } gInitialized = true; nsAutoPtr<Paths> paths(new Paths); // Initialize paths->libDir nsCOMPtr<nsIFile> file; nsresult rv = NS_GetSpecialDirectory(NS_XPCOM_LIBRARY_FILE, getter_AddRefs(file)); if (NS_FAILED(rv)) { return rv; } nsCOMPtr<nsIFile> libDir; rv = file->GetParent(getter_AddRefs(libDir)); if (NS_FAILED(rv)) { return rv; } rv = libDir->GetPath(paths->libDir); if (NS_FAILED(rv)) { return rv; } // Setup profileDir and localProfileDir immediately if possible (we // assume that NS_APP_USER_PROFILE_50_DIR and // NS_APP_USER_PROFILE_LOCAL_50_DIR are set simultaneously) rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_50_DIR, paths->profileDir); if (NS_SUCCEEDED(rv)) { rv = GetPathToSpecialDir(NS_APP_USER_PROFILE_LOCAL_50_DIR, paths->localProfileDir); } // Otherwise, delay setup of profileDir/localProfileDir until they // become available. if (NS_FAILED(rv)) { nsCOMPtr<nsIObserverService> obsService = do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) { return rv; } RefPtr<DelayedPathSetter> pathSetter = new DelayedPathSetter(); rv = obsService->AddObserver(pathSetter, "profile-do-change", false); if (NS_FAILED(rv)) { return rv; } } // For other directories, ignore errors (they may be undefined on // some platforms or in non-Firefox embeddings of Gecko). GetPathToSpecialDir(NS_OS_TEMP_DIR, paths->tmpDir); GetPathToSpecialDir(NS_OS_HOME_DIR, paths->homeDir); GetPathToSpecialDir(NS_OS_DESKTOP_DIR, paths->desktopDir); GetPathToSpecialDir(XRE_USER_APP_DATA_DIR, paths->userApplicationDataDir); #if defined(XP_WIN) GetPathToSpecialDir(NS_WIN_APPDATA_DIR, paths->winAppDataDir); GetPathToSpecialDir(NS_WIN_PROGRAMS_DIR, paths->winStartMenuProgsDir); #endif // defined(XP_WIN) #if defined(XP_MACOSX) GetPathToSpecialDir(NS_MAC_USER_LIB_DIR, paths->macUserLibDir); GetPathToSpecialDir(NS_OSX_LOCAL_APPLICATIONS_DIR, paths->macLocalApplicationsDir); GetPathToSpecialDir(NS_MAC_TRASH_DIR, paths->macTrashDir); #endif // defined(XP_MACOSX) gPaths = paths.forget(); // Get the umask from the system-info service. // The property will always be present, but it will be zero on // non-Unix systems. nsCOMPtr<nsIPropertyBag2> infoService = do_GetService("@mozilla.org/system-info;1"); MOZ_ASSERT(infoService, "Could not access the system information service"); rv = infoService->GetPropertyAsUint32(NS_LITERAL_STRING("umask"), &gUserUmask); if (NS_FAILED(rv)) { return rv; } return NS_OK; }
AbstractThread* DocGroup::AbstractMainThreadFor(TaskCategory aCategory) { MOZ_RELEASE_ASSERT(NS_IsMainThread()); return mTabGroup->AbstractMainThreadFor(aCategory); }
nsresult ShutdownXPCOM(nsIServiceManager* servMgr) { // Make sure the hang monitor is enabled for shutdown. HangMonitor::NotifyActivity(); NS_ENSURE_STATE(NS_IsMainThread()); nsresult rv; nsCOMPtr<nsISimpleEnumerator> moduleLoaders; // Notify observers of xpcom shutting down { // Block it so that the COMPtr will get deleted before we hit // servicemanager shutdown nsCOMPtr<nsIThread> thread = do_GetCurrentThread(); NS_ENSURE_STATE(thread); nsRefPtr<nsObserverService> observerService; CallGetService("@mozilla.org/observer-service;1", (nsObserverService**) getter_AddRefs(observerService)); if (observerService) { (void) observerService-> NotifyObservers(nsnull, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID, nsnull); nsCOMPtr<nsIServiceManager> mgr; rv = NS_GetServiceManager(getter_AddRefs(mgr)); if (NS_SUCCEEDED(rv)) { (void) observerService-> NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID, nsnull); } } NS_ProcessPendingEvents(thread); mozilla::scache::StartupCache::DeleteSingleton(); if (observerService) (void) observerService-> NotifyObservers(nsnull, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, nsnull); nsCycleCollector_shutdownThreads(); NS_ProcessPendingEvents(thread); // Shutdown the timer thread and all timers that might still be alive before // shutting down the component manager nsTimerImpl::Shutdown(); NS_ProcessPendingEvents(thread); // Shutdown all remaining threads. This method does not return until // all threads created using the thread manager (with the exception of // the main thread) have exited. nsThreadManager::get()->Shutdown(); NS_ProcessPendingEvents(thread); HangMonitor::NotifyActivity(); // We save the "xpcom-shutdown-loaders" observers to notify after // the observerservice is gone. if (observerService) { observerService-> EnumerateObservers(NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID, getter_AddRefs(moduleLoaders)); observerService->Shutdown(); } } // Free ClearOnShutdown()'ed smart pointers. This needs to happen *after* // we've finished notifying observers of XPCOM shutdown, because shutdown // observers themselves might call ClearOnShutdown(). mozilla::KillClearOnShutdown(); // XPCOM is officially in shutdown mode NOW // Set this only after the observers have been notified as this // will cause servicemanager to become inaccessible. mozilla::services::Shutdown(); #ifdef DEBUG_dougt fprintf(stderr, "* * * * XPCOM shutdown. Access will be denied * * * * \n"); #endif // We may have AddRef'd for the caller of NS_InitXPCOM, so release it // here again: NS_IF_RELEASE(servMgr); // Shutdown global servicemanager if (nsComponentManagerImpl::gComponentManager) { nsComponentManagerImpl::gComponentManager->FreeServices(); } // Release the directory service NS_IF_RELEASE(nsDirectoryService::gService); nsCycleCollector_shutdown(); if (moduleLoaders) { bool more; nsCOMPtr<nsISupports> el; while (NS_SUCCEEDED(moduleLoaders->HasMoreElements(&more)) && more) { moduleLoaders->GetNext(getter_AddRefs(el)); // Don't worry about weak-reference observers here: there is // no reason for weak-ref observers to register for // xpcom-shutdown-loaders nsCOMPtr<nsIObserver> obs(do_QueryInterface(el)); if (obs) (void) obs->Observe(nsnull, NS_XPCOM_SHUTDOWN_LOADERS_OBSERVER_ID, nsnull); } moduleLoaders = nsnull; } // Shutdown nsLocalFile string conversion NS_ShutdownLocalFile(); #ifdef XP_UNIX NS_ShutdownNativeCharsetUtils(); #endif // Shutdown xpcom. This will release all loaders and cause others holding // a refcount to the component manager to release it. if (nsComponentManagerImpl::gComponentManager) { rv = (nsComponentManagerImpl::gComponentManager)->Shutdown(); NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed."); } else NS_WARNING("Component Manager was never created ..."); // Release our own singletons // Do this _after_ shutting down the component manager, because the // JS component loader will use XPConnect to call nsIModule::canUnload, // and that will spin up the InterfaceInfoManager again -- bad mojo xptiInterfaceInfoManager::FreeInterfaceInfoManager(); // Finally, release the component manager last because it unloads the // libraries: if (nsComponentManagerImpl::gComponentManager) { nsrefcnt cnt; NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt); NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown."); } nsComponentManagerImpl::gComponentManager = nsnull; nsCategoryManager::Destroy(); NS_PurgeAtomTable(); NS_IF_RELEASE(gDebug); if (sIOThread) { delete sIOThread; sIOThread = nsnull; } if (sMessageLoop) { delete sMessageLoop; sMessageLoop = nsnull; } if (sCommandLineWasInitialized) { CommandLine::Terminate(); sCommandLineWasInitialized = false; } if (sExitManager) { delete sExitManager; sExitManager = nsnull; } Omnijar::CleanUp(); HangMonitor::Shutdown(); NS_LogTerm(); return NS_OK; }
CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback, ErrorResult& aRv, const char* aExecutionReason, ExceptionHandling aExceptionHandling, JSCompartment* aCompartment, bool aIsJSImplementedWebIDL) : mCx(nullptr) , mCompartment(aCompartment) , mErrorResult(aRv) , mExceptionHandling(aExceptionHandling) , mIsMainThread(NS_IsMainThread()) { if (mIsMainThread) { nsContentUtils::EnterMicroTask(); } // Compute the caller's subject principal (if necessary) early, before we // do anything that might perturb the relevant state. nsIPrincipal* webIDLCallerPrincipal = nullptr; if (aIsJSImplementedWebIDL) { webIDLCallerPrincipal = nsContentUtils::SubjectPrincipalOrSystemIfNativeCaller(); } // First, find the real underlying callback. JSObject* realCallback = js::UncheckedUnwrap(aCallback->CallbackPreserveColor()); nsIGlobalObject* globalObject = nullptr; JSContext* cx; { // Bug 955660: we cannot do "proper" rooting here because we need the // global to get a context. Everything here is simple getters that cannot // GC, so just paper over the necessary dataflow inversion. JS::AutoSuppressGCAnalysis nogc; // Now get the global for this callback. Note that for the case of // JS-implemented WebIDL we never have a window here. nsGlobalWindow* win = mIsMainThread && !aIsJSImplementedWebIDL ? xpc::WindowGlobalOrNull(realCallback) : nullptr; if (win) { MOZ_ASSERT(win->IsInnerWindow()); // We don't want to run script in windows that have been navigated away // from. if (!win->AsInner()->HasActiveDocument()) { aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR, NS_LITERAL_CSTRING("Refusing to execute function from window " "whose document is no longer active.")); return; } globalObject = win; } else { // No DOM Window. Store the global. JSObject* global = js::GetGlobalForObjectCrossCompartment(realCallback); globalObject = xpc::NativeGlobal(global); MOZ_ASSERT(globalObject); } // Bail out if there's no useful global. This seems to happen intermittently // on gaia-ui tests, probably because nsInProcessTabChildGlobal is returning // null in some kind of teardown state. if (!globalObject->GetGlobalJSObject()) { aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR, NS_LITERAL_CSTRING("Refusing to execute function from global which is " "being torn down.")); return; } mAutoEntryScript.emplace(globalObject, aExecutionReason, mIsMainThread); mAutoEntryScript->SetWebIDLCallerPrincipal(webIDLCallerPrincipal); nsIGlobalObject* incumbent = aCallback->IncumbentGlobalOrNull(); if (incumbent) { // The callback object traces its incumbent JS global, so in general it // should be alive here. However, it's possible that we could run afoul // of the same IPC global weirdness described above, wherein the // nsIGlobalObject has severed its reference to the JS global. Let's just // be safe here, so that nobody has to waste a day debugging gaia-ui tests. if (!incumbent->GetGlobalJSObject()) { aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR, NS_LITERAL_CSTRING("Refusing to execute function because our " "incumbent global is being torn down.")); return; } mAutoIncumbentScript.emplace(incumbent); } cx = mAutoEntryScript->cx(); // Unmark the callable (by invoking Callback() and not the CallbackPreserveColor() // variant), and stick it in a Rooted before it can go gray again. // Nothing before us in this function can trigger a CC, so it's safe to wait // until here it do the unmark. This allows us to construct mRootedCallable // with the cx from mAutoEntryScript, avoiding the cost of finding another // JSContext. (Rooted<> does not care about requests or compartments.) mRootedCallable.emplace(cx, aCallback->Callback()); } // JS-implemented WebIDL is always OK to run, since it runs with Chrome // privileges anyway. if (mIsMainThread && !aIsJSImplementedWebIDL) { // Check that it's ok to run this callback at all. // Make sure to use realCallback to get the global of the callback object, // not the wrapper. bool allowed = xpc::Scriptability::Get(realCallback).Allowed(); if (!allowed) { aRv.ThrowDOMException(NS_ERROR_DOM_NOT_SUPPORTED_ERR, NS_LITERAL_CSTRING("Refusing to execute function from global in which " "script is disabled.")); return; } } mAsyncStack.emplace(cx, aCallback->GetCreationStack()); if (*mAsyncStack) { mAsyncStackSetter.emplace(cx, *mAsyncStack, aExecutionReason); } // Enter the compartment of our callback, so we can actually work with it. // // Note that if the callback is a wrapper, this will not be the same // compartment that we ended up in with mAutoEntryScript above, because the // entry point is based off of the unwrapped callback (realCallback). mAc.emplace(cx, *mRootedCallable); // And now we're ready to go. mCx = cx; }
nsresult GetFileOrDirectoryTask::Work() { MOZ_ASSERT(FileSystemUtils::IsParentProcess(), "Only call from parent process!"); MOZ_ASSERT(!NS_IsMainThread(), "Only call on worker thread!"); if (mFileSystem->IsShutdown()) { return NS_ERROR_FAILURE; } // Whether we want to get the root directory. bool getRoot = mTargetRealPath.IsEmpty(); nsCOMPtr<nsIFile> file = mFileSystem->GetLocalFile(mTargetRealPath); if (!file) { return NS_ERROR_DOM_FILESYSTEM_INVALID_PATH_ERR; } bool exists; nsresult rv = file->Exists(&exists); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (!exists) { if (!getRoot) { return NS_ERROR_DOM_FILE_NOT_FOUND_ERR; } // If the root directory doesn't exit, create it. rv = file->Create(nsIFile::DIRECTORY_TYPE, 0777); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } // Get isDirectory. rv = file->IsDirectory(&mIsDirectory); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (mIsDirectory) { return NS_OK; } // Check if the root is a directory. if (getRoot) { return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR; } bool isFile; // Get isFile rv = file->IsFile(&isFile); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (!isFile) { // Neither directory or file. return NS_ERROR_DOM_FILESYSTEM_TYPE_MISMATCH_ERR; } if (!mFileSystem->IsSafeFile(file)) { return NS_ERROR_DOM_SECURITY_ERR; } mTargetFileImpl = new DOMFileImplFile(file); return NS_OK; }
GetFileOrDirectoryTaskChild::~GetFileOrDirectoryTaskChild() { MOZ_ASSERT(NS_IsMainThread()); }
GetFileOrDirectoryTask::~GetFileOrDirectoryTask() { MOZ_ASSERT(!mPromise || NS_IsMainThread(), "mPromise should be released on main thread!"); }
nsresult BackgroundFileSaver::ExtractSignatureInfo(const nsAString& filePath) { MOZ_ASSERT(!NS_IsMainThread(), "Cannot extract signature on main thread"); nsNSSShutDownPreventionLock nssLock; if (isAlreadyShutDown()) { return NS_ERROR_NOT_AVAILABLE; } { MutexAutoLock lock(mLock); if (!mSignatureInfoEnabled) { return NS_OK; } } nsresult rv; nsCOMPtr<nsIX509CertDB> certDB = do_GetService(NS_X509CERTDB_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); #ifdef XP_WIN // Setup the file to check. WINTRUST_FILE_INFO fileToCheck = {0}; fileToCheck.cbStruct = sizeof(WINTRUST_FILE_INFO); fileToCheck.pcwszFilePath = filePath.Data(); fileToCheck.hFile = nullptr; fileToCheck.pgKnownSubject = nullptr; // We want to check it is signed and trusted. WINTRUST_DATA trustData = {0}; trustData.cbStruct = sizeof(trustData); trustData.pPolicyCallbackData = nullptr; trustData.pSIPClientData = nullptr; trustData.dwUIChoice = WTD_UI_NONE; trustData.fdwRevocationChecks = WTD_REVOKE_NONE; trustData.dwUnionChoice = WTD_CHOICE_FILE; trustData.dwStateAction = WTD_STATEACTION_VERIFY; trustData.hWVTStateData = nullptr; trustData.pwszURLReference = nullptr; // Disallow revocation checks over the network trustData.dwProvFlags = WTD_CACHE_ONLY_URL_RETRIEVAL; // no UI trustData.dwUIContext = 0; trustData.pFile = &fileToCheck; // The WINTRUST_ACTION_GENERIC_VERIFY_V2 policy verifies that the certificate // chains up to a trusted root CA and has appropriate permissions to sign // code. GUID policyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2; // Check if the file is signed by something that is trusted. If the file is // not signed, this is a no-op. LONG ret = WinVerifyTrust(nullptr, &policyGUID, &trustData); CRYPT_PROVIDER_DATA* cryptoProviderData = nullptr; // According to the Windows documentation, we should check against 0 instead // of ERROR_SUCCESS, which is an HRESULT. if (ret == 0) { cryptoProviderData = WTHelperProvDataFromStateData(trustData.hWVTStateData); } if (cryptoProviderData) { // Lock because signature information is read on the main thread. MutexAutoLock lock(mLock); LOG(("Downloaded trusted and signed file [this = %p].", this)); // A binary may have multiple signers. Each signer may have multiple certs // in the chain. for (DWORD i = 0; i < cryptoProviderData->csSigners; ++i) { const CERT_CHAIN_CONTEXT* certChainContext = cryptoProviderData->pasSigners[i].pChainContext; if (!certChainContext) { break; } for (DWORD j = 0; j < certChainContext->cChain; ++j) { const CERT_SIMPLE_CHAIN* certSimpleChain = certChainContext->rgpChain[j]; if (!certSimpleChain) { break; } nsCOMPtr<nsIX509CertList> nssCertList = do_CreateInstance(NS_X509CERTLIST_CONTRACTID); if (!nssCertList) { break; } bool extractionSuccess = true; for (DWORD k = 0; k < certSimpleChain->cElement; ++k) { CERT_CHAIN_ELEMENT* certChainElement = certSimpleChain->rgpElement[k]; if (certChainElement->pCertContext->dwCertEncodingType != X509_ASN_ENCODING) { continue; } nsCOMPtr<nsIX509Cert> nssCert = nullptr; rv = certDB->ConstructX509( reinterpret_cast<char *>( certChainElement->pCertContext->pbCertEncoded), certChainElement->pCertContext->cbCertEncoded, getter_AddRefs(nssCert)); if (!nssCert) { extractionSuccess = false; LOG(("Couldn't create NSS cert [this = %p]", this)); break; } nssCertList->AddCert(nssCert); nsString subjectName; nssCert->GetSubjectName(subjectName); LOG(("Adding cert %s [this = %p]", NS_ConvertUTF16toUTF8(subjectName).get(), this)); } if (extractionSuccess) { mSignatureInfo.AppendObject(nssCertList); } } } // Free the provider data if cryptoProviderData is not null. trustData.dwStateAction = WTD_STATEACTION_CLOSE; WinVerifyTrust(nullptr, &policyGUID, &trustData); } else { LOG(("Downloaded unsigned or untrusted file [this = %p].", this)); } #endif return NS_OK; }
FileSystemParams GetFileOrDirectoryTask::GetRequestParams(const nsString& aFileSystem) const { MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); return FileSystemGetFileOrDirectoryParams(aFileSystem, mTargetRealPath); }
void CDMProxy::OnSessionClosed(const nsAString& aSessionId) { MOZ_ASSERT(NS_IsMainThread()); NS_WARNING("CDMProxy::OnSessionClosed() not implemented"); }
static void AssertMainThread() { MOZ_ASSERT(NS_IsMainThread()); }