bool WMFVideoMFTManager::InitInternal(bool aForceD3D9) { mUseHwAccel = false; // default value; changed if D3D setup succeeds. bool useDxva = InitializeDXVA(aForceD3D9); RefPtr<MFTDecoder> decoder(new MFTDecoder()); HRESULT hr = decoder->Create(GetMFTGUID()); NS_ENSURE_TRUE(SUCCEEDED(hr), false); RefPtr<IMFAttributes> attr(decoder->GetAttributes()); UINT32 aware = 0; if (attr) { attr->GetUINT32(MF_SA_D3D_AWARE, &aware); attr->SetUINT32(CODECAPI_AVDecNumWorkerThreads, WMFDecoderModule::GetNumDecoderThreads()); hr = attr->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE); if (SUCCEEDED(hr)) { LOG("Enabling Low Latency Mode"); } else { LOG("Couldn't enable Low Latency Mode"); } } if (useDxva) { if (aware) { // TODO: Test if I need this anywhere... Maybe on Vista? //hr = attr->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE); //NS_ENSURE_TRUE(SUCCEEDED(hr), hr); MOZ_ASSERT(mDXVA2Manager); ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager()); hr = decoder->SendMFTMessage(MFT_MESSAGE_SET_D3D_MANAGER, manager); if (SUCCEEDED(hr)) { mUseHwAccel = true; } else { mDXVA2Manager = nullptr; mDXVAFailureReason = nsPrintfCString("MFT_MESSAGE_SET_D3D_MANAGER failed with code %X", hr); } } else { mDXVAFailureReason.AssignLiteral("Decoder returned false for MF_SA_D3D_AWARE"); } } mDecoder = decoder; hr = SetDecoderMediaTypes(); NS_ENSURE_TRUE(SUCCEEDED(hr), false); LOG("Video Decoder initialized, Using DXVA: %s", (mUseHwAccel ? "Yes" : "No")); // Just in case ConfigureVideoFrameGeometry() does not set these mVideoInfo = VideoInfo(); mVideoStride = 0; mVideoWidth = 0; mVideoHeight = 0; mPictureRegion.SetEmpty(); return true; }
bool WMFVideoMFTManager::InitInternal(bool aForceD3D9) { mUseHwAccel = false; // default value; changed if D3D setup succeeds. bool useDxva = InitializeDXVA(aForceD3D9 || mStreamType == VP8 || mStreamType == VP9); RefPtr<MFTDecoder> decoder(new MFTDecoder()); HRESULT hr = decoder->Create(GetMFTGUID()); NS_ENSURE_TRUE(SUCCEEDED(hr), false); RefPtr<IMFAttributes> attr(decoder->GetAttributes()); UINT32 aware = 0; if (attr) { attr->GetUINT32(MF_SA_D3D_AWARE, &aware); attr->SetUINT32(CODECAPI_AVDecNumWorkerThreads, WMFDecoderModule::GetNumDecoderThreads()); if (MediaPrefs::PDMWMFLowLatencyEnabled()) { hr = attr->SetUINT32(CODECAPI_AVLowLatencyMode, TRUE); if (SUCCEEDED(hr)) { LOG("Enabling Low Latency Mode"); } else { LOG("Couldn't enable Low Latency Mode"); } } } if (useDxva) { if (aware) { // TODO: Test if I need this anywhere... Maybe on Vista? //hr = attr->SetUINT32(CODECAPI_AVDecVideoAcceleration_H264, TRUE); //NS_ENSURE_TRUE(SUCCEEDED(hr), hr); MOZ_ASSERT(mDXVA2Manager); ULONG_PTR manager = ULONG_PTR(mDXVA2Manager->GetDXVADeviceManager()); hr = decoder->SendMFTMessage(MFT_MESSAGE_SET_D3D_MANAGER, manager); if (SUCCEEDED(hr)) { mUseHwAccel = true; } else { mDXVA2Manager = nullptr; mDXVAFailureReason = nsPrintfCString("MFT_MESSAGE_SET_D3D_MANAGER failed with code %X", hr); } } else { mDXVAFailureReason.AssignLiteral("Decoder returned false for MF_SA_D3D_AWARE"); } } if (!mUseHwAccel) { Telemetry::Accumulate(Telemetry::MEDIA_DECODER_BACKEND_USED, uint32_t(media::MediaDecoderBackend::WMFSoftware)); } mDecoder = decoder; hr = SetDecoderMediaTypes(); NS_ENSURE_TRUE(SUCCEEDED(hr), false); LOG("Video Decoder initialized, Using DXVA: %s", (mUseHwAccel ? "Yes" : "No")); return true; }
/* static */ RefPtr<AllocationWrapper::AllocateDecoderPromise> AllocationWrapper::CreateDecoder(const CreateDecoderParams& aParams) { // aParams.mConfig is guaranteed to stay alive during the lifetime of the // MediaDataDecoder, so keeping a pointer to the object is safe. const TrackInfo* config = &aParams.mConfig; RefPtr<TaskQueue> taskQueue = aParams.mTaskQueue; DecoderDoctorDiagnostics* diagnostics = aParams.mDiagnostics; RefPtr<layers::ImageContainer> imageContainer = aParams.mImageContainer; RefPtr<layers::KnowsCompositor> knowsCompositor = aParams.mKnowsCompositor; RefPtr<GMPCrashHelper> crashHelper = aParams.mCrashHelper; CreateDecoderParams::UseNullDecoder useNullDecoder = aParams.mUseNullDecoder; CreateDecoderParams::NoWrapper noWrapper = aParams.mNoWrapper; TrackInfo::TrackType type = aParams.mType; MediaEventProducer<TrackInfo::TrackType>* onWaitingForKeyEvent = aParams.mOnWaitingForKeyEvent; CreateDecoderParams::OptionSet options = aParams.mOptions; CreateDecoderParams::VideoFrameRate rate = aParams.mRate; RefPtr<AllocateDecoderPromise> p = GlobalAllocPolicy::Instance(aParams.mType) .Alloc() ->Then( AbstractThread::GetCurrent(), __func__, [=](RefPtr<Token> aToken) { // result may not always be updated by PDMFactory::CreateDecoder // either when the creation succeeded or failed, as such it must be // initialized to a fatal error by default. MediaResult result = MediaResult( NS_ERROR_DOM_MEDIA_FATAL_ERR, nsPrintfCString("error creating %s decoder", TrackTypeToStr(type))); RefPtr<PDMFactory> pdm = new PDMFactory(); CreateDecoderParams params{ *config, taskQueue, diagnostics, imageContainer, &result, knowsCompositor, crashHelper, useNullDecoder, noWrapper, type, onWaitingForKeyEvent, options, rate }; RefPtr<MediaDataDecoder> decoder = pdm->CreateDecoder(params); if (decoder) { RefPtr<AllocationWrapper> wrapper = new AllocationWrapper(decoder.forget(), aToken.forget()); return AllocateDecoderPromise::CreateAndResolve(wrapper, __func__); } return AllocateDecoderPromise::CreateAndReject(result, __func__); }, []() { return AllocateDecoderPromise::CreateAndReject( MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, "Allocation policy expired"), __func__); }); return p; }
bool WebGLFramebuffer::ValidateAndInitAttachments(const char* funcName) { MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this || mContext->mBoundReadFramebuffer == this); nsCString fbStatusInfo; const auto fbStatus = CheckFramebufferStatus(&fbStatusInfo); if (fbStatus != LOCAL_GL_FRAMEBUFFER_COMPLETE) { nsCString errorText = nsPrintfCString("Incomplete framebuffer: Status 0x%04x", fbStatus.get()); if (fbStatusInfo.Length()) { errorText += ": "; errorText += fbStatusInfo; } mContext->ErrorInvalidFramebufferOperation("%s: %s.", funcName, errorText.BeginReading()); return false; } // Cool! We've checked out ok. Just need to initialize. // Check if we need to initialize anything { bool hasUninitializedAttachments = false; if (mColorAttachment0.HasImage() && IsDrawBuffer(0)) hasUninitializedAttachments |= mColorAttachment0.HasUninitializedImageData(); size_t i = 1; for (const auto& cur : mMoreColorAttachments) { if (cur.HasImage() && IsDrawBuffer(i)) hasUninitializedAttachments |= cur.HasUninitializedImageData(); ++i; } if (mDepthAttachment.HasImage()) hasUninitializedAttachments |= mDepthAttachment.HasUninitializedImageData(); if (mStencilAttachment.HasImage()) hasUninitializedAttachments |= mStencilAttachment.HasUninitializedImageData(); if (mDepthStencilAttachment.HasImage()) hasUninitializedAttachments |= mDepthStencilAttachment.HasUninitializedImageData(); if (!hasUninitializedAttachments) return true; } // Get buffer-bit-mask and color-attachment-mask-list uint32_t clearBits = 0; std::vector<GLenum> tempDrawBuffers(1 + mMoreColorAttachments.Size(), LOCAL_GL_NONE); if (mColorAttachment0.HasUninitializedImageData() && IsDrawBuffer(0)) { clearBits |= LOCAL_GL_COLOR_BUFFER_BIT; tempDrawBuffers[0] = LOCAL_GL_COLOR_ATTACHMENT0; } size_t i = 1; for (const auto& cur : mMoreColorAttachments) { if (cur.HasUninitializedImageData() && IsDrawBuffer(i)) { clearBits |= LOCAL_GL_COLOR_BUFFER_BIT; tempDrawBuffers[i] = LOCAL_GL_COLOR_ATTACHMENT0 + i; } ++i; } if (mDepthAttachment.HasUninitializedImageData() || mDepthStencilAttachment.HasUninitializedImageData()) { clearBits |= LOCAL_GL_DEPTH_BUFFER_BIT; } if (mStencilAttachment.HasUninitializedImageData() || mDepthStencilAttachment.HasUninitializedImageData()) { clearBits |= LOCAL_GL_STENCIL_BUFFER_BIT; } mContext->MakeContextCurrent(); const auto fnDrawBuffers = [this](const std::vector<GLenum>& list) { const GLenum* ptr = nullptr; if (list.size()) { ptr = &(list[0]); } this->mContext->gl->fDrawBuffers(list.size(), ptr); }; const auto drawBufferExt = WebGLExtensionID::WEBGL_draw_buffers; const bool hasDrawBuffers = (mContext->IsWebGL2() || mContext->IsExtensionEnabled(drawBufferExt)); if (hasDrawBuffers) { fnDrawBuffers(tempDrawBuffers); } // Clear! mContext->ForceClearFramebufferWithDefaultValues(clearBits, false); if (hasDrawBuffers) { fnDrawBuffers(mDrawBuffers); } // Mark all the uninitialized images as initialized. if (mDepthAttachment.HasUninitializedImageData()) mDepthAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData); if (mStencilAttachment.HasUninitializedImageData()) mStencilAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData); if (mDepthStencilAttachment.HasUninitializedImageData()) mDepthStencilAttachment.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData); if (mColorAttachment0.HasUninitializedImageData() && IsDrawBuffer(0)) { mColorAttachment0.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData); } i = 1; for (auto& cur : mMoreColorAttachments) { if (cur.HasUninitializedImageData() && IsDrawBuffer(i)) cur.SetImageDataStatus(WebGLImageDataStatus::InitializedImageData); ++i; } return true; }
nsCString DecoderDoctorDiagnostics::GetDescription() const { nsCString s; switch (mDiagnosticsType) { case eUnsaved: s = "Unsaved diagnostics, cannot get accurate description"; break; case eFormatSupportCheck: s = "format='"; s += NS_ConvertUTF16toUTF8(mFormat).get(); s += mCanPlay ? "', can play" : "', cannot play"; if (mVideoNotSupported) { s+= ", but video format not supported"; } if (mAudioNotSupported) { s+= ", but audio format not supported"; } if (mWMFFailedToLoad) { s += ", Windows platform decoder failed to load"; } if (mFFmpegFailedToLoad) { s += ", Linux platform decoder failed to load"; } if (mGMPPDMFailedToStartup) { s += ", GMP PDM failed to startup"; } else if (!mGMP.IsEmpty()) { s += ", Using GMP '"; s += mGMP; s += "'"; } break; case eMediaKeySystemAccessRequest: s = "key system='"; s += NS_ConvertUTF16toUTF8(mKeySystem).get(); s += mIsKeySystemSupported ? "', supported" : "', not supported"; switch (mKeySystemIssue) { case eUnset: break; case eWidevineWithNoWMF: s += ", Widevine with no WMF"; break; } break; case eEvent: s = nsPrintfCString("event domain %s result=%" PRIu32, EventDomainString(mEvent.mDomain), static_cast<uint32_t>(mEvent.mResult)); break; case eDecodeError: s = "decode error: "; s += mDecodeIssue.Description(); s += ", src='"; s += mDecodeIssueMediaSrc.IsEmpty() ? "<none>" : "<provided>"; s += "'"; break; case eDecodeWarning: s = "decode warning: "; s += mDecodeIssue.Description(); s += ", src='"; s += mDecodeIssueMediaSrc.IsEmpty() ? "<none>" : "<provided>"; s += "'"; break; default: MOZ_ASSERT_UNREACHABLE("Unexpected DiagnosticsType"); s = "?"; break; } return s; }
NS_IMETHODIMP nsLocalFile::CreateUnique(uint32_t aType, uint32_t aAttributes) { nsresult rv; bool longName; #ifdef XP_WIN nsAutoString pathName, leafName, rootName, suffix; rv = GetPath(pathName); #else nsAutoCString pathName, leafName, rootName, suffix; rv = GetNativePath(pathName); #endif if (NS_FAILED(rv)) { return rv; } longName = (pathName.Length() + kMaxSequenceNumberLength > kMaxFilenameLength); if (!longName) { rv = Create(aType, aAttributes); if (rv != NS_ERROR_FILE_ALREADY_EXISTS) { return rv; } } #ifdef XP_WIN rv = GetLeafName(leafName); if (NS_FAILED(rv)) { return rv; } const int32_t lastDot = leafName.RFindChar(char16_t('.')); #else rv = GetNativeLeafName(leafName); if (NS_FAILED(rv)) { return rv; } const int32_t lastDot = leafName.RFindChar('.'); #endif if (lastDot == kNotFound) { rootName = leafName; } else { suffix = Substring(leafName, lastDot); // include '.' rootName = Substring(leafName, 0, lastDot); // strip suffix and dot } if (longName) { int32_t maxRootLength = (kMaxFilenameLength - (pathName.Length() - leafName.Length()) - suffix.Length() - kMaxSequenceNumberLength); // We cannot create an item inside a directory whose name is too long. // Also, ensure that at least one character remains after we truncate // the root name, as we don't want to end up with an empty leaf name. if (maxRootLength < 2) { return NS_ERROR_FILE_UNRECOGNIZED_PATH; } #ifdef XP_WIN // ensure that we don't cut the name in mid-UTF16-character rootName.SetLength(NS_IS_LOW_SURROGATE(rootName[maxRootLength]) ? maxRootLength - 1 : maxRootLength); SetLeafName(rootName + suffix); #else if (NS_IsNativeUTF8()) { // ensure that we don't cut the name in mid-UTF8-character // (assume the name is valid UTF8 to begin with) while (UTF8traits::isInSeq(rootName[maxRootLength])) { --maxRootLength; } // Another check to avoid ending up with an empty leaf name. if (maxRootLength == 0 && suffix.IsEmpty()) { return NS_ERROR_FILE_UNRECOGNIZED_PATH; } } rootName.SetLength(maxRootLength); SetNativeLeafName(rootName + suffix); #endif nsresult rv = Create(aType, aAttributes); if (rv != NS_ERROR_FILE_ALREADY_EXISTS) { return rv; } } for (int indx = 1; indx < 10000; ++indx) { // start with "Picture-1.jpg" after "Picture.jpg" exists #ifdef XP_WIN SetLeafName(rootName + NS_ConvertASCIItoUTF16(nsPrintfCString("-%d", indx)) + suffix); #else SetNativeLeafName(rootName + nsPrintfCString("-%d", indx) + suffix); #endif rv = Create(aType, aAttributes); if (NS_SUCCEEDED(rv) || rv != NS_ERROR_FILE_ALREADY_EXISTS) { return rv; } } // The disk is full, sort of return NS_ERROR_FILE_TOO_BIG; }
nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, PRBool set_default) { if (!gHashTable.ops) return NS_ERROR_OUT_OF_MEMORY; PrefHashEntry* pref = static_cast<PrefHashEntry*>(PL_DHashTableOperate(&gHashTable, key, PL_DHASH_ADD)); if (!pref) return NS_ERROR_OUT_OF_MEMORY; // new entry, better intialize if (!pref->key) { // initialize the pref entry pref->flags = type; pref->key = ArenaStrDup(key, &gPrefNameArena); memset(&pref->defaultPref, 0, sizeof(pref->defaultPref)); memset(&pref->userPref, 0, sizeof(pref->userPref)); } else if ((((PrefType)(pref->flags)) & PREF_VALUETYPE_MASK) != (type & PREF_VALUETYPE_MASK)) { NS_WARNING(nsPrintfCString(192, "Trying to set pref %s to with the wrong type!", key).get()); return NS_ERROR_UNEXPECTED; } PRBool valueChanged = PR_FALSE; if (set_default) { if (!PREF_IS_LOCKED(pref)) { /* ?? change of semantics? */ if (pref_ValueChanged(pref->defaultPref, value, type) || !(pref->flags & PREF_HAS_DEFAULT)) { pref_SetValue(&pref->defaultPref, value, type); pref->flags |= PREF_HAS_DEFAULT; if (!PREF_HAS_USER_VALUE(pref)) valueChanged = PR_TRUE; } } } else { /* If new value is same as the default value, then un-set the user value. Otherwise, set the user value only if it has changed */ if (!pref_ValueChanged(pref->defaultPref, value, type) && pref->flags & PREF_HAS_DEFAULT) { if (PREF_HAS_USER_VALUE(pref)) { pref->flags &= ~PREF_USERSET; if (!PREF_IS_LOCKED(pref)) valueChanged = PR_TRUE; } } else if ( !PREF_HAS_USER_VALUE(pref) || pref_ValueChanged(pref->userPref, value, type) ) { pref_SetValue(&pref->userPref, value, type); pref->flags |= PREF_USERSET; if (!PREF_IS_LOCKED(pref)) valueChanged = PR_TRUE; } } nsresult rv = NS_OK; if (valueChanged) { gDirty = PR_TRUE; nsresult rv2 = pref_DoCallback(key); if (NS_FAILED(rv2)) rv = rv2; } return rv; }
void nsPrinterFeatures::SetPlexRecord( PRInt32 aIndex, const char *aPlexName ) { SetCharValue(nsPrintfCString(256, "plex.%d.name", aIndex).get(), aPlexName); }
void nsPrinterFeatures::SetResolutionNameRecord( PRInt32 aIndex, const char *aResolutionName ) { SetCharValue(nsPrintfCString(256, "resolution.%d.name", aIndex).get(), aResolutionName); }
void nsPrinterFeatures::SetCharValue( const char *tagname, const char *value ) { mPrefs->SetCharPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value); }
void nsPrinterFeatures::SetOrientationRecord( PRInt32 aIndex, const char *aOrientationName ) { SetCharValue(nsPrintfCString(256, "orientation.%d.name", aIndex).get(), aOrientationName); }
UniquePtr<AudioStream::Chunk> DecodedAudioDataSink::PopFrames(uint32_t aFrames) { class Chunk : public AudioStream::Chunk { public: Chunk(AudioData* aBuffer, uint32_t aFrames, AudioDataValue* aData) : mBuffer(aBuffer), mFrames(aFrames), mData(aData) {} Chunk() : mFrames(0), mData(nullptr) {} const AudioDataValue* Data() const { return mData; } uint32_t Frames() const { return mFrames; } uint32_t Channels() const { return mBuffer ? mBuffer->mChannels: 0; } uint32_t Rate() const { return mBuffer ? mBuffer->mRate : 0; } AudioDataValue* GetWritable() const { return mData; } private: const RefPtr<AudioData> mBuffer; const uint32_t mFrames; AudioDataValue* const mData; }; class SilentChunk : public AudioStream::Chunk { public: SilentChunk(uint32_t aFrames, uint32_t aChannels, uint32_t aRate) : mFrames(aFrames) , mChannels(aChannels) , mRate(aRate) , mData(MakeUnique<AudioDataValue[]>(aChannels * aFrames)) { memset(mData.get(), 0, aChannels * aFrames * sizeof(AudioDataValue)); } const AudioDataValue* Data() const { return mData.get(); } uint32_t Frames() const { return mFrames; } uint32_t Channels() const { return mChannels; } uint32_t Rate() const { return mRate; } AudioDataValue* GetWritable() const { return mData.get(); } private: const uint32_t mFrames; const uint32_t mChannels; const uint32_t mRate; UniquePtr<AudioDataValue[]> mData; }; while (!mCurrentData) { // No data in the queue. Return an empty chunk. if (AudioQueue().GetSize() == 0) { return MakeUnique<Chunk>(); } AudioData* a = AudioQueue().PeekFront()->As<AudioData>(); // Ignore the element with 0 frames and try next. if (a->mFrames == 0) { RefPtr<MediaData> releaseMe = AudioQueue().PopFront(); continue; } // Ignore invalid samples. if (a->mRate != mInfo.mRate || a->mChannels != mInfo.mChannels) { NS_WARNING(nsPrintfCString( "mismatched sample format, data=%p rate=%u channels=%u frames=%u", a->mAudioData.get(), a->mRate, a->mChannels, a->mFrames).get()); RefPtr<MediaData> releaseMe = AudioQueue().PopFront(); continue; } // See if there's a gap in the audio. If there is, push silence into the // audio hardware, so we can play across the gap. // Calculate the timestamp of the next chunk of audio in numbers of // samples. CheckedInt64 sampleTime = UsecsToFrames(AudioQueue().PeekFront()->mTime, mInfo.mRate); // Calculate the number of frames that have been pushed onto the audio hardware. CheckedInt64 playedFrames = UsecsToFrames(mStartTime, mInfo.mRate) + static_cast<int64_t>(mWritten); CheckedInt64 missingFrames = sampleTime - playedFrames; if (!missingFrames.isValid() || !sampleTime.isValid()) { NS_WARNING("Int overflow in DecodedAudioDataSink"); mErrored = true; return MakeUnique<Chunk>(); } if (missingFrames.value() > AUDIO_FUZZ_FRAMES) { // The next audio chunk begins some time after the end of the last chunk // we pushed to the audio hardware. We must push silence into the audio // hardware so that the next audio chunk begins playback at the correct // time. missingFrames = std::min<int64_t>(UINT32_MAX, missingFrames.value()); auto framesToPop = std::min<uint32_t>(missingFrames.value(), aFrames); mWritten += framesToPop; return MakeUnique<SilentChunk>(framesToPop, mInfo.mChannels, mInfo.mRate); } mCurrentData = dont_AddRef(AudioQueue().PopFront().take()->As<AudioData>()); mCursor = MakeUnique<AudioBufferCursor>(mCurrentData->mAudioData.get(), mCurrentData->mChannels, mCurrentData->mFrames); MOZ_ASSERT(mCurrentData->mFrames > 0); } auto framesToPop = std::min(aFrames, mCursor->Available()); SINK_LOG_V("playing audio at time=%lld offset=%u length=%u", mCurrentData->mTime, mCurrentData->mFrames - mCursor->Available(), framesToPop); UniquePtr<AudioStream::Chunk> chunk = MakeUnique<Chunk>(mCurrentData, framesToPop, mCursor->Ptr()); mWritten += framesToPop; mCursor->Advance(framesToPop); // All frames are popped. Reset mCurrentData so we can pop new elements from // the audio queue in next calls to PopFrames(). if (mCursor->Available() == 0) { mCurrentData = nullptr; } return chunk; }
void ChromiumCDMProxy::Init(PromiseId aPromiseId, const nsAString& aOrigin, const nsAString& aTopLevelOrigin, const nsAString& aGMPName) { MOZ_ASSERT(NS_IsMainThread()); NS_ENSURE_TRUE_VOID(!mKeys.IsNull()); EME_LOG( "ChromiumCDMProxy::Init (pid=%u, origin=%s, topLevelOrigin=%s, gmp=%s)", aPromiseId, NS_ConvertUTF16toUTF8(aOrigin).get(), NS_ConvertUTF16toUTF8(aTopLevelOrigin).get(), NS_ConvertUTF16toUTF8(aGMPName).get()); if (!mGMPThread) { RejectPromise( aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, NS_LITERAL_CSTRING("Couldn't get GMP thread ChromiumCDMProxy::Init")); return; } if (aGMPName.IsEmpty()) { RejectPromise(aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, nsPrintfCString("Unknown GMP for keysystem '%s'", NS_ConvertUTF16toUTF8(mKeySystem).get())); return; } gmp::NodeId nodeId(aOrigin, aTopLevelOrigin, aGMPName); RefPtr<AbstractThread> thread = mGMPThread; RefPtr<GMPCrashHelper> helper(mCrashHelper); RefPtr<ChromiumCDMProxy> self(this); nsCString keySystem = NS_ConvertUTF16toUTF8(mKeySystem); RefPtr<Runnable> task(NS_NewRunnableFunction( [self, nodeId, helper, aPromiseId, thread, keySystem]() -> void { MOZ_ASSERT(self->IsOnOwnerThread()); RefPtr<gmp::GeckoMediaPluginService> service = gmp::GeckoMediaPluginService::GetGeckoMediaPluginService(); if (!service) { self->RejectPromise( aPromiseId, NS_ERROR_DOM_INVALID_STATE_ERR, NS_LITERAL_CSTRING( "Couldn't get GeckoMediaPluginService in ChromiumCDMProxy::Init")); return; } RefPtr<gmp::GetCDMParentPromise> promise = service->GetCDM(nodeId, { keySystem }, helper); promise->Then( thread, __func__, [self, aPromiseId](RefPtr<gmp::ChromiumCDMParent> cdm) { if (!cdm->Init(self, self->mDistinctiveIdentifierRequired, self->mPersistentStateRequired)) { self->RejectPromise(aPromiseId, NS_ERROR_FAILURE, NS_LITERAL_CSTRING("GetCDM failed.")); return; } { MutexAutoLock lock(self->mCDMMutex); self->mCDM = cdm; } self->OnCDMCreated(aPromiseId); }, [self, aPromiseId](nsresult rv) { self->RejectPromise( aPromiseId, NS_ERROR_FAILURE, NS_LITERAL_CSTRING("GetCDM failed.")); }); })); mGMPThread->Dispatch(task.forget()); }
void nsHttpConnectionInfo::SetTlsFlags(uint32_t aTlsFlags) { mTlsFlags = aTlsFlags; mHashKey.Replace(18, 8, nsPrintfCString("%08x", mTlsFlags)); }
nsACString& LayerManager::PrintInfo(nsACString& aTo, const char* aPrefix) { aTo += aPrefix; return aTo += nsPrintfCString(64, "%sLayerManager (0x%p)", Name(), this); }
void nsPrinterFeatures::SetColorspaceRecord( PRInt32 aIndex, const char *aColorspace ) { SetCharValue(nsPrintfCString(256, "colorspace.%d.name", aIndex).get(), aColorspace); }
nsresult pref_HashPref(const char *key, PrefValue value, PrefType type, PRBool set_default) { if (!gHashTable.ops) return NS_ERROR_OUT_OF_MEMORY; PrefHashEntry* pref = static_cast<PrefHashEntry*>(PL_DHashTableOperate(&gHashTable, key, PL_DHASH_ADD)); if (!pref) return NS_ERROR_OUT_OF_MEMORY; // new entry, better intialize if (!pref->key) { // initialize the pref entry pref->flags = type; pref->key = ArenaStrDup(key, &gPrefNameArena); memset(&pref->defaultPref, 0, sizeof(pref->defaultPref)); memset(&pref->userPref, 0, sizeof(pref->userPref)); /* ugly hack -- define it to a default that no pref will ever default to this should really get fixed right by some out of band data */ if (pref->flags & PREF_BOOL) pref->defaultPref.boolVal = (PRBool) BOGUS_DEFAULT_BOOL_PREF_VALUE; if (pref->flags & PREF_INT) pref->defaultPref.intVal = (PRInt32) BOGUS_DEFAULT_INT_PREF_VALUE; } else if ((((PrefType)(pref->flags)) & PREF_VALUETYPE_MASK) != (type & PREF_VALUETYPE_MASK)) { NS_WARNING(nsPrintfCString(192, "Trying to set pref %s to with the wrong type!", key).get()); return NS_ERROR_UNEXPECTED; } PRBool valueChanged = PR_FALSE; if (set_default) { if (!PREF_IS_LOCKED(pref)) { /* ?? change of semantics? */ if (pref_ValueChanged(pref->defaultPref, value, type)) { pref_SetValue(&pref->defaultPref, value, type); if (!PREF_HAS_USER_VALUE(pref)) valueChanged = PR_TRUE; } } } else { /* If new value is same as the default value, then un-set the user value. Otherwise, set the user value only if it has changed */ if ( !pref_ValueChanged(pref->defaultPref, value, type) ) { if (PREF_HAS_USER_VALUE(pref)) { pref->flags &= ~PREF_USERSET; if (!PREF_IS_LOCKED(pref)) valueChanged = PR_TRUE; } } else if ( !PREF_HAS_USER_VALUE(pref) || pref_ValueChanged(pref->userPref, value, type) ) { pref_SetValue(&pref->userPref, value, type); pref->flags |= PREF_USERSET; if (!PREF_IS_LOCKED(pref)) valueChanged = PR_TRUE; } } nsresult rv = NS_OK; if (valueChanged) { gDirty = PR_TRUE; if (gCallbacksEnabled) { nsresult rv2 = pref_DoCallback(key); if (NS_FAILED(rv2)) rv = rv2; } #ifdef MOZ_PROFILESHARING if (gSharedPrefHandler) gSharedPrefHandler->OnPrefChanged(set_default, pref, value); #endif } return rv; }
/* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */ NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, nsIPrintSettings *aPrintSettings) { DO_PR_DEBUG_LOG(("nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter()")); nsresult rv; NS_ENSURE_ARG_POINTER(aPrinterName); NS_ENSURE_ARG_POINTER(aPrintSettings); NS_ENSURE_TRUE(*aPrinterName, NS_ERROR_FAILURE); NS_ENSURE_TRUE(aPrintSettings, NS_ERROR_FAILURE); nsCOMPtr<nsIPrefBranch> pPrefs = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; nsXPIDLCString fullPrinterName, /* Full name of printer incl. driver-specific prefix */ printerName; /* "Stripped" name of printer */ fullPrinterName.Assign(NS_ConvertUTF16toUTF8(aPrinterName)); printerName.Assign(NS_ConvertUTF16toUTF8(aPrinterName)); DO_PR_DEBUG_LOG(("printerName='%s'\n", printerName.get())); PrintMethod type = pmInvalid; rv = nsDeviceContextSpecGTK::GetPrintMethod(printerName, type); if (NS_FAILED(rv)) return rv; #ifdef USE_POSTSCRIPT /* "Demangle" postscript printer name */ if (type == pmPostScript) { /* Strip the printing method name from the printer, * e.g. turn "PostScript/foobar" to "foobar" */ PRInt32 slash = printerName.FindChar('/'); if (kNotFound != slash) printerName.Cut(0, slash + 1); } #endif /* USE_POSTSCRIPT */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS /* Defaults to FALSE */ pPrefs->SetBoolPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.has_special_printerfeatures", fullPrinterName.get()).get(), PR_FALSE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ /* Set filename */ nsXPIDLCString filename; if (NS_FAILED(CopyPrinterCharPref(pPrefs, nsnull, printerName, "filename", filename))) { const char *path; if (!(path = PR_GetEnv("PWD"))) path = PR_GetEnv("HOME"); if (path) filename = nsPrintfCString(PATH_MAX, "%s/mozilla.ps", path); else filename.AssignLiteral("mozilla.ps"); } DO_PR_DEBUG_LOG(("Setting default filename to '%s'\n", filename.get())); aPrintSettings->SetToFileName(NS_ConvertUTF8toUTF16(filename).get()); aPrintSettings->SetIsInitializedFromPrinter(PR_TRUE); #ifdef USE_POSTSCRIPT if (type == pmPostScript) { DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for PostScript printer\n")); #ifdef SET_PRINTER_FEATURES_VIA_PREFS nsPrinterFeatures printerFeatures(fullPrinterName); printerFeatures.SetSupportsPaperSizeChange(PR_TRUE); printerFeatures.SetSupportsOrientationChange(PR_TRUE); printerFeatures.SetSupportsPlexChange(PR_FALSE); printerFeatures.SetSupportsResolutionNameChange(PR_FALSE); printerFeatures.SetSupportsColorspaceChange(PR_FALSE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangeOrientation(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ nsXPIDLCString orientation; if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "orientation", orientation))) { if (orientation.LowerCaseEqualsLiteral("portrait")) { DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n")); aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation); } else if (orientation.LowerCaseEqualsLiteral("landscape")) { DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n")); aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation); } else { DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", orientation.get())); } } #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetOrientationRecord(0, "portrait"); printerFeatures.SetOrientationRecord(1, "landscape"); printerFeatures.SetNumOrientationRecords(2); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ /* PostScript module does not support changing the plex mode... */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangePlex(PR_FALSE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ DO_PR_DEBUG_LOG(("setting default plex to '%s'\n", "default")); aPrintSettings->SetPlexName(NS_LITERAL_STRING("default").get()); #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetPlexRecord(0, "default"); printerFeatures.SetNumPlexRecords(1); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ /* PostScript module does not support changing the resolution mode... */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangeResolutionName(PR_FALSE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ DO_PR_DEBUG_LOG(("setting default resolution to '%s'\n", "default")); aPrintSettings->SetResolutionName(NS_LITERAL_STRING("default").get()); #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetResolutionNameRecord(0, "default"); printerFeatures.SetNumResolutionNameRecords(1); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ /* PostScript module does not support changing the colorspace... */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangeColorspace(PR_FALSE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", "default")); aPrintSettings->SetColorspace(NS_LITERAL_STRING("default").get()); #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetColorspaceRecord(0, "default"); printerFeatures.SetNumColorspaceRecords(1); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangePaperSize(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ nsXPIDLCString papername; if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", papername))) { nsPaperSizePS paper; if (paper.Find(papername)) { DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n", paper.Name(), paper.Width_mm(), paper.Height_mm())); aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters); aPrintSettings->SetPaperWidth(paper.Width_mm()); aPrintSettings->SetPaperHeight(paper.Height_mm()); aPrintSettings->SetPaperName(NS_ConvertASCIItoUTF16(paper.Name()).get()); } else { DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get())); } #ifdef SET_PRINTER_FEATURES_VIA_PREFS paper.First(); int count = 0; while (!paper.AtEnd()) { printerFeatures.SetPaperRecord(count++, paper.Name(), (int)paper.Width_mm(), (int)paper.Height_mm(), !paper.IsMetric()); paper.Next(); } printerFeatures.SetNumPaperSizeRecords(count); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ } PRBool hasSpoolerCmd = (nsPSPrinterList::kTypePS == nsPSPrinterList::GetPrinterType(fullPrinterName)); #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetSupportsSpoolerCommandChange(hasSpoolerCmd); printerFeatures.SetCanChangeSpoolerCommand(hasSpoolerCmd); /* Postscript module does not pass the job title to lpr */ printerFeatures.SetSupportsJobTitleChange(PR_FALSE); printerFeatures.SetCanChangeJobTitle(PR_FALSE); /* Postscript module has no control over builtin fonts yet */ printerFeatures.SetSupportsDownloadFontsChange(PR_FALSE); printerFeatures.SetCanChangeDownloadFonts(PR_FALSE); /* Postscript module does not support multiple colorspaces * so it has to use the old way */ printerFeatures.SetSupportsPrintInColorChange(PR_TRUE); printerFeatures.SetCanChangePrintInColor(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ if (hasSpoolerCmd) { nsXPIDLCString command; if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "print_command", command))) { DO_PR_DEBUG_LOG(("setting default print command to '%s'\n", command.get())); aPrintSettings->SetPrintCommand(NS_ConvertUTF8toUTF16(command).get()); } } #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangeNumCopies(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ return NS_OK; } #endif /* USE_POSTSCRIPT */ return NS_ERROR_UNEXPECTED; }
void TextureSource::PrintInfo(nsACString& aTo, const char* aPrefix) { aTo += aPrefix; aTo += nsPrintfCString("UnknownTextureSource (0x%p)", this); }
void WebGLProgram::LinkProgram() { mContext->InvalidateBufferFetching(); // we do it early in this function // as some of the validation below changes program state mLinkLog.Truncate(); mMostRecentLinkInfo = nullptr; if (!mVertShader || !mVertShader->IsCompiled()) { mLinkLog.AssignLiteral("Must have a compiled vertex shader attached."); mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); return; } if (!mFragShader || !mFragShader->IsCompiled()) { mLinkLog.AssignLiteral("Must have an compiled fragment shader attached."); mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); return; } if (!mFragShader->CanLinkTo(mVertShader, &mLinkLog)) { mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); return; } gl::GLContext* gl = mContext->gl; gl->MakeCurrent(); if (gl->WorkAroundDriverBugs() && mContext->mIsMesa) { // Bug 777028: Mesa can't handle more than 16 samplers per program, // counting each array entry. size_t numSamplerUniforms_upperBound = mVertShader->CalcNumSamplerUniforms() + mFragShader->CalcNumSamplerUniforms(); if (numSamplerUniforms_upperBound > 16) { mLinkLog.AssignLiteral("Programs with more than 16 samplers are disallowed on" " Mesa drivers to avoid crashing."); mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); return; } // Bug 1203135: Mesa crashes internally if we exceed the reported maximum attribute count. if (mVertShader->NumAttributes() > mContext->MaxVertexAttribs()) { mLinkLog.AssignLiteral("Number of attributes exceeds Mesa's reported max attribute count."); mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading()); return; } } // Bind the attrib locations. // This can't be done trivially, because we have to deal with mapped attrib names. for (auto itr = mBoundAttribLocs.begin(); itr != mBoundAttribLocs.end(); ++itr) { const nsCString& name = itr->first; GLuint index = itr->second; mVertShader->BindAttribLocation(mGLName, name, index); } if (!mTransformFeedbackVaryings.empty()) { // Bind the transform feedback varyings. // This can't be done trivially, because we have to deal with mapped names too. mVertShader->ApplyTransformFeedbackVaryings(mGLName, mTransformFeedbackVaryings, mTransformFeedbackBufferMode, &mTempMappedVaryings); } LinkAndUpdate(); if (IsLinked()) { // Check if the attrib name conflicting to uniform name for (const auto& uniform : mMostRecentLinkInfo->uniformMap) { if (mMostRecentLinkInfo->attribMap.find(uniform.first) != mMostRecentLinkInfo->attribMap.end()) { mLinkLog = nsPrintfCString("The uniform name (%s) conflicts with attribute name.", uniform.first.get()); mMostRecentLinkInfo = nullptr; break; } } } if (mMostRecentLinkInfo) return; // Failed link. if (mContext->ShouldGenerateWarnings()) { // report shader/program infoLogs as warnings. // note that shader compilation errors can be deferred to linkProgram, // which is why we can't do anything in compileShader. In practice we could // report in compileShader the translation errors generated by ANGLE, // but it seems saner to keep a single way of obtaining shader infologs. if (!mLinkLog.IsEmpty()) { mContext->GenerateWarning("linkProgram: Failed to link, leaving the following" " log:\n%s\n", mLinkLog.BeginReading()); } } }
bool WebGLFBAttachPoint::IsComplete(WebGLContext* webgl, nsCString* const out_info) const { MOZ_ASSERT(IsDefined()); if (!HasImage()) { AttachmentName(out_info); out_info->AppendLiteral("'s image is not defined"); return false; } uint32_t width; uint32_t height; Size(&width, &height); if (!width || !height) { AttachmentName(out_info); out_info->AppendLiteral(" has no width or height"); return false; } const auto formatUsage = Format(); if (!formatUsage->isRenderable) { nsAutoCString attachName; AttachmentName(&attachName); *out_info = nsPrintfCString("%s has an effective format of %s, which is not" " renderable", attachName.BeginReading(), formatUsage->format->name); return false; } const auto format = formatUsage->format; bool hasRequiredBits; switch (mAttachmentPoint) { case LOCAL_GL_DEPTH_ATTACHMENT: hasRequiredBits = format->hasDepth; break; case LOCAL_GL_STENCIL_ATTACHMENT: hasRequiredBits = format->hasStencil; break; case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT: MOZ_ASSERT(!webgl->IsWebGL2()); hasRequiredBits = (format->hasDepth && format->hasStencil); break; default: MOZ_ASSERT(mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0); hasRequiredBits = format->isColorFormat; break; } if (!hasRequiredBits) { AttachmentName(out_info); out_info->AppendLiteral("'s format is missing required color/depth/stencil bits"); return false; } if (!webgl->IsWebGL2()) { bool hasSurplusPlanes = false; switch (mAttachmentPoint) { case LOCAL_GL_DEPTH_ATTACHMENT: hasSurplusPlanes = format->hasStencil; break; case LOCAL_GL_STENCIL_ATTACHMENT: hasSurplusPlanes = format->hasDepth; break; } if (hasSurplusPlanes) { AttachmentName(out_info); out_info->AppendLiteral("'s format has depth or stencil bits when it" " shouldn't"); return false; } } return true; }
nsresult nsSceneTracker::UpdateSceneNumberLiterals ( nsIDOMHTMLParagraphElement* aScene) { NS_ENSURE_ARG(aScene); nsAutoString className; nsresult rv = aScene->GetClassName(className); NS_ENSURE_SUCCESS(rv, rv); if (! className.Equals(NS_LITERAL_STRING("sceneheading"))) return NS_ERROR_INVALID_ARG; nsAutoString sceneNumberStr; rv = aScene->GetAttribute(NS_LITERAL_STRING("scenenumber"), sceneNumberStr); NS_ENSURE_SUCCESS(rv, rv); // Durrrr... maybe this should be an error? if (sceneNumberStr.IsEmpty()) return NS_OK; PRUint32 sceneNumber[DEFAULT_MAX_SCENE_DEPTH]; PRUint32 sceneNumberLength = DEFAULT_MAX_SCENE_DEPTH; rv = ParseSceneNumber(sceneNumberStr, &sceneNumberLength, sceneNumber); NS_ENSURE_SUCCESS(rv, rv); nsAutoString displayStr; rv = mScheme.SceneNumberToString(sceneNumberLength, sceneNumber, displayStr); NS_ENSURE_SUCCESS(rv, rv); aScene->SetAttribute(NS_LITERAL_STRING("scenestr"), displayStr); nsAutoString sceneID; rv = aScene->GetAttribute(NS_LITERAL_STRING("id"), sceneID); NS_ENSURE_SUCCESS(rv, rv); if (sceneID.IsEmpty()) return NS_ERROR_UNEXPECTED; nsCOMPtr<nsIRDFResource> sceneres; rv = SceneForSceneID(sceneID, getter_AddRefs(sceneres)); NS_ENSURE_SUCCESS(rv, rv); if (! sceneres) return NS_ERROR_UNEXPECTED; nsCOMPtr<nsIRDFResource> ordarc; nsCOMPtr<nsIRDFResource> sortordarc; mRDFSvc->GetResource(NS_LITERAL_CSTRING("http://celtx.com/NS/v1/ordinal"), getter_AddRefs(ordarc)); mRDFSvc->GetResource(NS_LITERAL_CSTRING("http://celtx.com/NS/v1/sortord"), getter_AddRefs(sortordarc)); // TODO: Distinguish canonical string from display string SetRDFString(mDS, sceneres, ordarc, displayStr); // This is for sorting only. Each scene number component is // zero-padded to 4 digits, allowing alphabetical sorting. nsCAutoString sortStr; sortStr.Assign(nsPrintfCString("%04d", sceneNumber[0])); for (PRUint32 i = 1; i < sceneNumberLength; ++i) sortStr.Append(nsPrintfCString("%04d", sceneNumber[i])); SetRDFString(mDS, sceneres, sortordarc, NS_ConvertASCIItoUTF16(sortStr)); return NS_OK; }
NS_DECL_THREADSAFE_ISUPPORTS NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCallback, nsISupports *aClosure, bool aAnonymize) { typedef DOMFileImplMemory::DataOwner DataOwner; StaticMutexAutoLock lock(DataOwner::sDataOwnerMutex); if (!DataOwner::sDataOwners) { return NS_OK; } const size_t LARGE_OBJECT_MIN_SIZE = 8 * 1024; size_t smallObjectsTotal = 0; for (DataOwner *owner = DataOwner::sDataOwners->getFirst(); owner; owner = owner->getNext()) { size_t size = DOMMemoryFileDataOwnerMallocSizeOf(owner->mData); if (size < LARGE_OBJECT_MIN_SIZE) { smallObjectsTotal += size; } else { SHA1Sum sha1; sha1.update(owner->mData, owner->mLength); uint8_t digest[SHA1Sum::kHashSize]; // SHA1 digests are 20 bytes long. sha1.finish(digest); nsAutoCString digestString; for (size_t i = 0; i < sizeof(digest); i++) { digestString.AppendPrintf("%02x", digest[i]); } nsresult rv = aCallback->Callback( /* process */ NS_LITERAL_CSTRING(""), nsPrintfCString( "explicit/dom/memory-file-data/large/file(length=%llu, sha1=%s)", owner->mLength, aAnonymize ? "<anonymized>" : digestString.get()), KIND_HEAP, UNITS_BYTES, size, nsPrintfCString( "Memory used to back a memory file of length %llu bytes. The file " "has a sha1 of %s.\n\n" "Note that the allocator may round up a memory file's length -- " "that is, an N-byte memory file may take up more than N bytes of " "memory.", owner->mLength, digestString.get()), aClosure); NS_ENSURE_SUCCESS(rv, rv); } } if (smallObjectsTotal > 0) { nsresult rv = aCallback->Callback( /* process */ NS_LITERAL_CSTRING(""), NS_LITERAL_CSTRING("explicit/dom/memory-file-data/small"), KIND_HEAP, UNITS_BYTES, smallObjectsTotal, nsPrintfCString( "Memory used to back small memory files (less than %d bytes each).\n\n" "Note that the allocator may round up a memory file's length -- " "that is, an N-byte memory file may take up more than N bytes of " "memory."), aClosure); NS_ENSURE_SUCCESS(rv, rv); } return NS_OK; }
nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request, nsIURI* aURL) { nsresult rv = NS_OK; // If we don't yet have a stream listener, we need to get // one from the plugin. // NOTE: this should only happen when a stream was NOT created // with GetURL or PostURL (i.e. it's the initial stream we // send to the plugin as determined by the SRC or DATA attribute) if (!mPStreamListener) { if (!mPluginInstance) { return NS_ERROR_FAILURE; } RefPtr<nsNPAPIPluginStreamListener> streamListener; rv = mPluginInstance->NewStreamListener(nullptr, nullptr, getter_AddRefs(streamListener)); if (NS_FAILED(rv) || !streamListener) { return NS_ERROR_FAILURE; } mPStreamListener = static_cast<nsNPAPIPluginStreamListener*>(streamListener.get()); } mPStreamListener->SetStreamListenerPeer(this); // get httpChannel to retrieve some info we need for nsIPluginStreamInfo setup nsCOMPtr<nsIChannel> channel = do_QueryInterface(request); nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel); /* * Assumption * By the time nsPluginStreamListenerPeer::OnDataAvailable() gets * called, all the headers have been read. */ if (httpChannel) { // Reassemble the HTTP response status line and provide it to our // listener. Would be nice if we could get the raw status line, // but nsIHttpChannel doesn't currently provide that. // Status code: required; the status line isn't useful without it. uint32_t statusNum; if (NS_SUCCEEDED(httpChannel->GetResponseStatus(&statusNum)) && statusNum < 1000) { // HTTP version: provide if available. Defaults to empty string. nsCString ver; nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(channel); if (httpChannelInternal) { uint32_t major, minor; if (NS_SUCCEEDED(httpChannelInternal->GetResponseVersion(&major, &minor))) { ver = nsPrintfCString("/%" PRIu32 ".%" PRIu32, major, minor); } } // Status text: provide if available. Defaults to "OK". nsCString statusText; if (NS_FAILED(httpChannel->GetResponseStatusText(statusText))) { statusText = "OK"; } // Assemble everything and pass to listener. nsPrintfCString status("HTTP%s %" PRIu32 " %s", ver.get(), statusNum, statusText.get()); static_cast<nsIHTTPHeaderListener*>(mPStreamListener)->StatusLine(status.get()); } // Also provide all HTTP response headers to our listener. rv = httpChannel->VisitResponseHeaders(this); MOZ_ASSERT(NS_SUCCEEDED(rv)); // we require a content len // get Last-Modified header for plugin info nsAutoCString lastModified; if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("last-modified"), lastModified)) && !lastModified.IsEmpty()) { PRTime time64; PR_ParseTimeString(lastModified.get(), true, &time64); //convert string time to integer time // Convert PRTime to unix-style time_t, i.e. seconds since the epoch double fpTime = double(time64); mModified = (uint32_t)(fpTime * 1e-6 + 0.5); } } MOZ_ASSERT(!mRequest); mRequest = request; rv = mPStreamListener->OnStartBinding(this); mStartBinding = true; if (NS_FAILED(rv)) return rv; return NS_OK; }
// If a blacklisted DLL is found, return its information, otherwise "". static const nsACString& FindDXVABlacklistedDLL(StaticAutoPtr<D3DDLLBlacklistingCache>& aDLLBlacklistingCache, const char* aDLLBlacklistPrefName) { NS_ASSERTION(NS_IsMainThread(), "Must be on main thread."); if (!aDLLBlacklistingCache) { // First time here, create persistent data that will be reused in all // D3D11-blacklisting checks. aDLLBlacklistingCache = new D3DDLLBlacklistingCache(); ClearOnShutdown(&aDLLBlacklistingCache); } nsAdoptingCString blacklist = Preferences::GetCString(aDLLBlacklistPrefName); if (blacklist.IsEmpty()) { // Empty blacklist -> No blacklisting. aDLLBlacklistingCache->mBlacklistPref.SetLength(0); aDLLBlacklistingCache->mBlacklistedDLL.SetLength(0); return aDLLBlacklistingCache->mBlacklistedDLL; } // Detect changes in pref. if (aDLLBlacklistingCache->mBlacklistPref.Equals(blacklist)) { // Same blacklist -> Return same result (i.e., don't check DLLs again). return aDLLBlacklistingCache->mBlacklistedDLL; } // Adopt new pref now, so we don't work on it again. aDLLBlacklistingCache->mBlacklistPref = blacklist; // media.wmf.disable-d3d*-for-dlls format: (whitespace is trimmed) // "dll1.dll: 1.2.3.4[, more versions...][; more dlls...]" nsTArray<nsCString> dlls; SplitAt(";", blacklist, dlls); for (const auto& dll : dlls) { nsTArray<nsCString> nameAndVersions; SplitAt(":", dll, nameAndVersions); if (nameAndVersions.Length() != 2) { NS_WARNING(nsPrintfCString("Skipping incorrect '%s' dll:versions format", aDLLBlacklistPrefName).get()); continue; } nameAndVersions[0].CompressWhitespace(); NS_ConvertUTF8toUTF16 name(nameAndVersions[0]); WCHAR systemPath[MAX_PATH + 1]; if (!ConstructSystem32Path(name.get(), systemPath, MAX_PATH + 1)) { // Cannot build path -> Assume it's not the blacklisted DLL. continue; } DWORD zero; DWORD infoSize = GetFileVersionInfoSizeW(systemPath, &zero); if (infoSize == 0) { // Can't get file info -> Assume we don't have the blacklisted DLL. continue; } // vInfo is a pointer into infoData, that's why we keep it outside of the loop. auto infoData = MakeUnique<unsigned char[]>(infoSize); VS_FIXEDFILEINFO *vInfo; UINT vInfoLen; if (!GetFileVersionInfoW(systemPath, 0, infoSize, infoData.get()) || !VerQueryValueW(infoData.get(), L"\\", (LPVOID*)&vInfo, &vInfoLen) || !vInfo) { // Can't find version -> Assume it's not blacklisted. continue; } nsTArray<nsCString> versions; SplitAt(",", nameAndVersions[1], versions); for (const auto& version : versions) { nsTArray<nsCString> numberStrings; SplitAt(".", version, numberStrings); if (numberStrings.Length() != 4) { NS_WARNING(nsPrintfCString("Skipping incorrect '%s' a.b.c.d version format", aDLLBlacklistPrefName).get()); continue; } DWORD numbers[4]; nsresult errorCode = NS_OK; for (int i = 0; i < 4; ++i) { numberStrings[i].CompressWhitespace(); numbers[i] = DWORD(numberStrings[i].ToInteger(&errorCode)); if (NS_FAILED(errorCode)) { break; } if (numbers[i] > UINT16_MAX) { errorCode = NS_ERROR_FAILURE; break; } } if (NS_FAILED(errorCode)) { NS_WARNING(nsPrintfCString("Skipping incorrect '%s' a.b.c.d version format", aDLLBlacklistPrefName).get()); continue; } if (vInfo->dwFileVersionMS == ((numbers[0] << 16) | numbers[1]) && vInfo->dwFileVersionLS == ((numbers[2] << 16) | numbers[3])) { // Blacklisted! Record bad DLL. aDLLBlacklistingCache->mBlacklistedDLL.SetLength(0); aDLLBlacklistingCache->mBlacklistedDLL.AppendPrintf( "%s (%lu.%lu.%lu.%lu)", nameAndVersions[0].get(), numbers[0], numbers[1], numbers[2], numbers[3]); return aDLLBlacklistingCache->mBlacklistedDLL; } } } // No blacklisted DLL. aDLLBlacklistingCache->mBlacklistedDLL.SetLength(0); return aDLLBlacklistingCache->mBlacklistedDLL; }
bool WebGLProgram::ValidateAfterTentativeLink(nsCString* const out_linkLog) const { const auto& linkInfo = mMostRecentLinkInfo; const auto& gl = mContext->gl; // Check if the attrib name conflicting to uniform name for (const auto& attrib : linkInfo->attribs) { const auto& attribName = attrib.mActiveInfo->mBaseUserName; for (const auto& uniform : linkInfo->uniforms) { const auto& uniformName = uniform->mActiveInfo->mBaseUserName; if (attribName == uniformName) { *out_linkLog = nsPrintfCString("Attrib name conflicts with uniform name:" " %s", attribName.BeginReading()); return false; } } } std::map<uint32_t, const webgl::AttribInfo*> attribsByLoc; for (const auto& attrib : linkInfo->attribs) { const auto& elemType = attrib.mActiveInfo->mElemType; const auto numUsedLocs = NumUsedLocationsByElemType(elemType); for (uint32_t i = 0; i < numUsedLocs; i++) { const uint32_t usedLoc = attrib.mLoc + i; const auto res = attribsByLoc.insert({usedLoc, &attrib}); const bool& didInsert = res.second; if (!didInsert) { const auto& aliasingName = attrib.mActiveInfo->mBaseUserName; const auto& itrExisting = res.first; const auto& existingInfo = itrExisting->second; const auto& existingName = existingInfo->mActiveInfo->mBaseUserName; *out_linkLog = nsPrintfCString("Attrib \"%s\" aliases locations used by" " attrib \"%s\".", aliasingName.BeginReading(), existingName.BeginReading()); return false; } } } // Forbid: // * Unrecognized varying name // * Duplicate varying name // * Too many components for specified buffer mode if (mNextLink_TransformFeedbackVaryings.size()) { GLuint maxComponentsPerIndex = 0; switch (mNextLink_TransformFeedbackBufferMode) { case LOCAL_GL_INTERLEAVED_ATTRIBS: gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, &maxComponentsPerIndex); break; case LOCAL_GL_SEPARATE_ATTRIBS: gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, &maxComponentsPerIndex); break; default: MOZ_CRASH("`bufferMode`"); } std::vector<size_t> componentsPerVert; std::set<const WebGLActiveInfo*> alreadyUsed; for (const auto& wideUserName : mNextLink_TransformFeedbackVaryings) { if (!componentsPerVert.size() || mNextLink_TransformFeedbackBufferMode == LOCAL_GL_SEPARATE_ATTRIBS) { componentsPerVert.push_back(0); } //// const WebGLActiveInfo* curInfo = nullptr; for (const auto& info : linkInfo->transformFeedbackVaryings) { const NS_ConvertASCIItoUTF16 info_wideUserName(info->mBaseUserName); if (info_wideUserName == wideUserName) { curInfo = info.get(); break; } } if (!curInfo) { const NS_LossyConvertUTF16toASCII asciiUserName(wideUserName); *out_linkLog = nsPrintfCString("Transform feedback varying \"%s\" not" " found.", asciiUserName.BeginReading()); return false; } const auto insertResPair = alreadyUsed.insert(curInfo); const auto& didInsert = insertResPair.second; if (!didInsert) { const NS_LossyConvertUTF16toASCII asciiUserName(wideUserName); *out_linkLog = nsPrintfCString("Transform feedback varying \"%s\"" " specified twice.", asciiUserName.BeginReading()); return false; } //// size_t varyingComponents = NumComponents(curInfo->mElemType); varyingComponents *= curInfo->mElemCount; auto& totalComponentsForIndex = *(componentsPerVert.rbegin()); totalComponentsForIndex += varyingComponents; if (totalComponentsForIndex > maxComponentsPerIndex) { const NS_LossyConvertUTF16toASCII asciiUserName(wideUserName); *out_linkLog = nsPrintfCString("Transform feedback varying \"%s\"" " pushed `componentsForIndex` over the" " limit of %u.", asciiUserName.BeginReading(), maxComponentsPerIndex); return false; } } linkInfo->componentsPerTFVert.swap(componentsPerVert); } return true; }
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)); }
nsACString& Layer::PrintInfo(nsACString& aTo, const char* aPrefix) { aTo += aPrefix; aTo += nsPrintfCString("%s%s (0x%p)", mManager->Name(), Name(), this); layers::PrintInfo(aTo, AsLayerComposite()); if (mUseClipRect) { AppendToString(aTo, mClipRect, " [clip=", "]"); } if (1.0 != mPostXScale || 1.0 != mPostYScale) { aTo.AppendPrintf(" [postScale=%g, %g]", mPostXScale, mPostYScale); } if (!mTransform.IsIdentity()) { AppendToString(aTo, mTransform, " [transform=", "]"); } if (!mVisibleRegion.IsEmpty()) { AppendToString(aTo, mVisibleRegion, " [visible=", "]"); } else { aTo += " [not visible]"; } if (!mEventRegions.mHitRegion.IsEmpty()) { AppendToString(aTo, mEventRegions.mHitRegion, " [hitregion=", "]"); } if (!mEventRegions.mDispatchToContentHitRegion.IsEmpty()) { AppendToString(aTo, mEventRegions.mDispatchToContentHitRegion, " [dispatchtocontentregion=", "]"); } if (1.0 != mOpacity) { aTo.AppendPrintf(" [opacity=%g]", mOpacity); } if (GetContentFlags() & CONTENT_OPAQUE) { aTo += " [opaqueContent]"; } if (GetContentFlags() & CONTENT_COMPONENT_ALPHA) { aTo += " [componentAlpha]"; } if (GetScrollbarDirection() == VERTICAL) { aTo.AppendPrintf(" [vscrollbar=%lld]", GetScrollbarTargetContainerId()); } if (GetScrollbarDirection() == HORIZONTAL) { aTo.AppendPrintf(" [hscrollbar=%lld]", GetScrollbarTargetContainerId()); } if (GetIsFixedPosition()) { aTo.AppendPrintf(" [isFixedPosition anchor=%f,%f margin=%f,%f,%f,%f]", mAnchor.x, mAnchor.y, mMargins.top, mMargins.right, mMargins.bottom, mMargins.left); } if (GetIsStickyPosition()) { aTo.AppendPrintf(" [isStickyPosition scrollId=%d outer=%f,%f %fx%f " "inner=%f,%f %fx%f]", mStickyPositionData->mScrollId, mStickyPositionData->mOuter.x, mStickyPositionData->mOuter.y, mStickyPositionData->mOuter.width, mStickyPositionData->mOuter.height, mStickyPositionData->mInner.x, mStickyPositionData->mInner.y, mStickyPositionData->mInner.width, mStickyPositionData->mInner.height); } if (mMaskLayer) { aTo.AppendPrintf(" [mMaskLayer=%p]", mMaskLayer.get()); } return aTo; }
nsresult nsPluginStreamListenerPeer::SetUpStreamListener(nsIRequest *request, nsIURI* aURL) { nsresult rv = NS_OK; // If we don't yet have a stream listener, we need to get // one from the plugin. // NOTE: this should only happen when a stream was NOT created // with GetURL or PostURL (i.e. it's the initial stream we // send to the plugin as determined by the SRC or DATA attribute) if (!mPStreamListener) { if (!mPluginInstance) { return NS_ERROR_FAILURE; } nsRefPtr<nsNPAPIPluginStreamListener> streamListener; rv = mPluginInstance->NewStreamListener(nullptr, nullptr, getter_AddRefs(streamListener)); if (NS_FAILED(rv) || !streamListener) { return NS_ERROR_FAILURE; } mPStreamListener = static_cast<nsNPAPIPluginStreamListener*>(streamListener.get()); } mPStreamListener->SetStreamListenerPeer(this); bool useLocalCache = false; // get httpChannel to retrieve some info we need for nsIPluginStreamInfo setup nsCOMPtr<nsIChannel> channel = do_QueryInterface(request); nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel); /* * Assumption * By the time nsPluginStreamListenerPeer::OnDataAvailable() gets * called, all the headers have been read. */ if (httpChannel) { // Reassemble the HTTP response status line and provide it to our // listener. Would be nice if we could get the raw status line, // but nsIHttpChannel doesn't currently provide that. // Status code: required; the status line isn't useful without it. uint32_t statusNum; if (NS_SUCCEEDED(httpChannel->GetResponseStatus(&statusNum)) && statusNum < 1000) { // HTTP version: provide if available. Defaults to empty string. nsCString ver; nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(channel); if (httpChannelInternal) { uint32_t major, minor; if (NS_SUCCEEDED(httpChannelInternal->GetResponseVersion(&major, &minor))) { ver = nsPrintfCString("/%lu.%lu", major, minor); } } // Status text: provide if available. Defaults to "OK". nsCString statusText; if (NS_FAILED(httpChannel->GetResponseStatusText(statusText))) { statusText = "OK"; } // Assemble everything and pass to listener. nsPrintfCString status("HTTP%s %lu %s", ver.get(), statusNum, statusText.get()); static_cast<nsIHTTPHeaderListener*>(mPStreamListener)->StatusLine(status.get()); } // Also provide all HTTP response headers to our listener. httpChannel->VisitResponseHeaders(this); mSeekable = false; // first we look for a content-encoding header. If we find one, we tell the // plugin that stream is not seekable, because the plugin always sees // uncompressed data, so it can't make meaningful range requests on a // compressed entity. Also, we force the plugin to use // nsPluginStreamType_AsFile stream type and we have to save decompressed // file into local plugin cache, because necko cache contains original // compressed file. nsAutoCString contentEncoding; if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Encoding"), contentEncoding))) { useLocalCache = true; } else { // set seekability (seekable if the stream has a known length and if the // http server accepts byte ranges). uint32_t length; GetLength(&length); if (length) { nsAutoCString range; if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("accept-ranges"), range)) && range.Equals(NS_LITERAL_CSTRING("bytes"), nsCaseInsensitiveCStringComparator())) { mSeekable = true; } } } // we require a content len // get Last-Modified header for plugin info nsAutoCString lastModified; if (NS_SUCCEEDED(httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("last-modified"), lastModified)) && !lastModified.IsEmpty()) { PRTime time64; PR_ParseTimeString(lastModified.get(), true, &time64); //convert string time to integer time // Convert PRTime to unix-style time_t, i.e. seconds since the epoch double fpTime = double(time64); mModified = (uint32_t)(fpTime * 1e-6 + 0.5); } } rv = mPStreamListener->OnStartBinding(this); mStartBinding = true; if (NS_FAILED(rv)) return rv; mPStreamListener->GetStreamType(&mStreamType); if (!useLocalCache && mStreamType >= NP_ASFILE) { // check it out if this is not a file channel. nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(request); if (!fileChannel) { useLocalCache = true; } } if (useLocalCache) { SetupPluginCacheFile(channel); } return NS_OK; }
nsresult nsDOMStorageDBWrapper::CreateScopeDBKey(nsIPrincipal* aPrincipal, nsACString& aKey) { nsCOMPtr<nsIURI> uri; nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED); nsAutoCString domainScope; rv = uri->GetAsciiHost(domainScope); NS_ENSURE_SUCCESS(rv, rv); if (domainScope.IsEmpty()) { // About pages have an empty host but a valid path. Since they are handled // internally by our own redirector, we can trust them and use path as key. // if file:/// protocol, let's make the exact directory the domain bool isScheme = false; if ((NS_SUCCEEDED(uri->SchemeIs("about", &isScheme)) && isScheme) || (NS_SUCCEEDED(uri->SchemeIs("moz-safe-about", &isScheme)) && isScheme)) { rv = uri->GetPath(domainScope); NS_ENSURE_SUCCESS(rv, rv); // While the host is always canonicalized to lowercase, the path is not, // thus need to force the casing. ToLowerCase(domainScope); } else if (NS_SUCCEEDED(uri->SchemeIs("file", &isScheme)) && isScheme) { nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = url->GetDirectory(domainScope); NS_ENSURE_SUCCESS(rv, rv); } } nsAutoCString key; rv = CreateReversedDomain(domainScope, key); NS_ENSURE_SUCCESS(rv, rv); nsAutoCString scheme; rv = uri->GetScheme(scheme); NS_ENSURE_SUCCESS(rv, rv); key.Append(NS_LITERAL_CSTRING(":") + scheme); int32_t port = NS_GetRealPort(uri); if (port != -1) { key.Append(nsPrintfCString(":%d", port)); } uint32_t appId; rv = aPrincipal->GetAppId(&appId); NS_ENSURE_SUCCESS(rv, rv); bool isInBrowserElement; rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement); NS_ENSURE_SUCCESS(rv, rv); if (appId == nsIScriptSecurityManager::NO_APP_ID && !isInBrowserElement) { aKey.Assign(key); return NS_OK; } aKey.Truncate(); aKey.AppendInt(appId); aKey.Append(NS_LITERAL_CSTRING(":") + (isInBrowserElement ? NS_LITERAL_CSTRING("t") : NS_LITERAL_CSTRING("f")) + NS_LITERAL_CSTRING(":") + key); return NS_OK; }