nsresult StartupCache::Init() { if (XRE_GetProcessType() != GeckoProcessType_Default) { NS_WARNING("Startup cache is only available in the chrome process"); return NS_ERROR_NOT_AVAILABLE; } // workaround for bug 653936 nsCOMPtr<nsIProtocolHandler> jarInitializer(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "jar")); nsresult rv; mTable.Init(); #ifdef DEBUG mWriteObjectMap.Init(); #endif // This allows to override the startup cache filename // which is useful from xpcshell, when there is no ProfLDS directory to keep cache in. char *env = PR_GetEnv("MOZ_STARTUP_CACHE"); if (env) { rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(env), false, getter_AddRefs(mFile)); } else { nsCOMPtr<nsIFile> file; rv = NS_GetSpecialDirectory("ProfLDS", getter_AddRefs(file)); if (NS_FAILED(rv)) { // return silently, this will fail in mochitests's xpcshell process. return rv; } rv = file->AppendNative(NS_LITERAL_CSTRING("startupCache")); NS_ENSURE_SUCCESS(rv, rv); // Try to create the directory if it's not there yet rv = file->Create(nsIFile::DIRECTORY_TYPE, 0777); if (NS_FAILED(rv) && rv != NS_ERROR_FILE_ALREADY_EXISTS) return rv; rv = file->AppendNative(NS_LITERAL_CSTRING(sStartupCacheName)); NS_ENSURE_SUCCESS(rv, rv); mFile = do_QueryInterface(file); } NS_ENSURE_TRUE(mFile, NS_ERROR_UNEXPECTED); mObserverService = do_GetService("@mozilla.org/observer-service;1"); if (!mObserverService) { NS_WARNING("Could not get observerService."); return NS_ERROR_UNEXPECTED; } mListener = new StartupCacheListener(); rv = mObserverService->AddObserver(mListener, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); NS_ENSURE_SUCCESS(rv, rv); rv = mObserverService->AddObserver(mListener, "startupcache-invalidate", false); NS_ENSURE_SUCCESS(rv, rv); rv = LoadArchive(RECORD_AGE); // Sometimes we don't have a cache yet, that's ok. // If it's corrupted, just remove it and start over. if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND) { NS_WARNING("Failed to load startupcache file correctly, removing!"); InvalidateCache(); } mMappingMemoryReporter = new NS_MEMORY_REPORTER_NAME(StartupCacheMapping); mDataMemoryReporter = new NS_MEMORY_REPORTER_NAME(StartupCacheData); (void)::NS_RegisterMemoryReporter(mMappingMemoryReporter); (void)::NS_RegisterMemoryReporter(mDataMemoryReporter); return NS_OK; }
nsresult DOMStorageManager::Observe(const char* aTopic, const nsACString& aScopePrefix) { // Clear everything, caches + database if (!strcmp(aTopic, "cookie-cleared")) { ClearCacheEnumeratorData data(DOMStorageCache::kUnloadComplete); mCaches.EnumerateEntries(ClearCacheEnumerator, &data); return NS_OK; } // Clear from caches everything that has been stored // while in session-only mode if (!strcmp(aTopic, "session-only-cleared")) { ClearCacheEnumeratorData data(DOMStorageCache::kUnloadSession); data.mKeyPrefix = aScopePrefix; mCaches.EnumerateEntries(ClearCacheEnumerator, &data); return NS_OK; } // Clear everything (including so and pb data) from caches and database // for the gived domain and subdomains. if (!strcmp(aTopic, "domain-data-cleared")) { ClearCacheEnumeratorData data(DOMStorageCache::kUnloadComplete); data.mKeyPrefix = aScopePrefix; mCaches.EnumerateEntries(ClearCacheEnumerator, &data); return NS_OK; } // Clear all private-browsing caches if (!strcmp(aTopic, "private-browsing-data-cleared")) { ClearCacheEnumeratorData data(DOMStorageCache::kUnloadPrivate); mCaches.EnumerateEntries(ClearCacheEnumerator, &data); return NS_OK; } // Clear localStorage data beloging to an app. if (!strcmp(aTopic, "app-data-cleared")) { // sessionStorage is expected to stay if (mType == SessionStorage) { return NS_OK; } ClearCacheEnumeratorData data(DOMStorageCache::kUnloadComplete); data.mKeyPrefix = aScopePrefix; mCaches.EnumerateEntries(ClearCacheEnumerator, &data); return NS_OK; } if (!strcmp(aTopic, "profile-change")) { // For case caches are still referenced - clear them completely ClearCacheEnumeratorData data(DOMStorageCache::kUnloadComplete); mCaches.EnumerateEntries(ClearCacheEnumerator, &data); mCaches.Clear(); return NS_OK; } if (!strcmp(aTopic, "low-disk-space")) { if (mType == LocalStorage) { mLowDiskSpace = true; } return NS_OK; } if (!strcmp(aTopic, "no-low-disk-space")) { if (mType == LocalStorage) { mLowDiskSpace = false; } return NS_OK; } #ifdef DOM_STORAGE_TESTS if (!strcmp(aTopic, "test-reload")) { if (mType != LocalStorage) { return NS_OK; } // This immediately completely reloads all caches from the database. ClearCacheEnumeratorData data(DOMStorageCache::kTestReload); mCaches.EnumerateEntries(ClearCacheEnumerator, &data); return NS_OK; } if (!strcmp(aTopic, "test-flushed")) { if (XRE_GetProcessType() != GoannaProcessType_Default) { nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService(); if (obs) { obs->NotifyObservers(nullptr, "domstorage-test-flushed", nullptr); } } return NS_OK; } #endif NS_ERROR("Unexpected topic"); return NS_ERROR_UNEXPECTED; }
bool ParamTraits<MagicGrallocBufferHandle>::Read(const Message* aMsg, void** aIter, paramType* aResult) { size_t nbytes; size_t nfds; const char* data; int owner; int64_t index; if (!aMsg->ReadInt(aIter, &owner) || !aMsg->ReadInt64(aIter, &index) || !aMsg->ReadSize(aIter, &nbytes) || !aMsg->ReadSize(aIter, &nfds) || !aMsg->ReadBytes(aIter, &data, nbytes)) { printf_stderr("ParamTraits<MagicGrallocBufferHandle>::Read() failed to read a message\n"); return false; } int fds[nfds]; bool sameProcess = (XRE_GetProcessType() == GeckoProcessType_Default); for (size_t n = 0; n < nfds; ++n) { FileDescriptor fd; if (!aMsg->ReadFileDescriptor(aIter, &fd)) { printf_stderr("ParamTraits<MagicGrallocBufferHandle>::Read() failed to read file descriptors\n"); return false; } // If the GraphicBuffer was shared cross-process, SCM_RIGHTS does // the right thing and dup's the fd. If it's shared cross-thread, // SCM_RIGHTS doesn't dup the fd. // But in shared cross-thread, dup fd is not necessary because we get // a pointer to the GraphicBuffer directly from SharedBufferManagerParent // and don't create a new GraphicBuffer around the fd. fds[n] = fd.fd; } aResult->mRef.mOwner = owner; aResult->mRef.mKey = index; if (sameProcess) { aResult->mGraphicBuffer = SharedBufferManagerParent::GetGraphicBuffer(aResult->mRef); } else { aResult->mGraphicBuffer = SharedBufferManagerChild::GetSingleton()->GetGraphicBuffer(index); MOZ_ASSERT(!aResult->mGraphicBuffer.get()); // Deserialize GraphicBuffer #if ANDROID_VERSION >= 19 sp<GraphicBuffer> buffer(new GraphicBuffer()); const void* datap = (const void*)data; const int* fdsp = &fds[0]; if (NO_ERROR != buffer->unflatten(datap, nbytes, fdsp, nfds)) { buffer = nullptr; } #else sp<GraphicBuffer> buffer(new GraphicBuffer()); Flattenable *flattenable = buffer.get(); if (NO_ERROR != flattenable->unflatten(data, nbytes, fds, nfds)) { buffer = nullptr; } #endif if(buffer.get() && !aResult->mGraphicBuffer.get()) { aResult->mGraphicBuffer = buffer; } } if (!aResult->mGraphicBuffer.get()) { printf_stderr("ParamTraits<MagicGrallocBufferHandle>::Read() failed to get gralloc buffer\n"); return false; } return true; }
already_AddRefed<nsIInputStream> DeserializeInputStream(const InputStreamParams& aParams, const nsTArray<FileDescriptor>& aFileDescriptors) { nsCOMPtr<nsIInputStream> stream; nsCOMPtr<nsIIPCSerializableInputStream> serializable; switch (aParams.type()) { case InputStreamParams::TStringInputStreamParams: serializable = do_CreateInstance(kStringInputStreamCID); break; case InputStreamParams::TFileInputStreamParams: serializable = do_CreateInstance(kFileInputStreamCID); break; case InputStreamParams::TPartialFileInputStreamParams: serializable = do_CreateInstance(kPartialFileInputStreamCID); break; case InputStreamParams::TBufferedInputStreamParams: serializable = do_CreateInstance(kBufferedInputStreamCID); break; case InputStreamParams::TMIMEInputStreamParams: serializable = do_CreateInstance(kMIMEInputStreamCID); break; case InputStreamParams::TMultiplexInputStreamParams: serializable = do_CreateInstance(kMultiplexInputStreamCID); break; // When the input stream already exists in this process, all we need to do // is retrieve the original instead of sending any data over the wire. case InputStreamParams::TRemoteInputStreamParams: { if (NS_WARN_IF(XRE_GetProcessType() != GeckoProcessType_Default)) { return nullptr; } const nsID& id = aParams.get_RemoteInputStreamParams().id(); nsRefPtr<BlobImpl> blobImpl = BlobParent::GetBlobImplForID(id); MOZ_ASSERT(blobImpl, "Invalid blob contents"); // If fetching the internal stream fails, we ignore it and return a // null stream. nsCOMPtr<nsIInputStream> stream; nsresult rv = blobImpl->GetInternalStream(getter_AddRefs(stream)); if (NS_FAILED(rv) || !stream) { NS_WARNING("Couldn't obtain a valid stream from the blob"); } return stream.forget(); } case InputStreamParams::TSameProcessInputStreamParams: { MOZ_ASSERT(aFileDescriptors.IsEmpty()); const SameProcessInputStreamParams& params = aParams.get_SameProcessInputStreamParams(); stream = dont_AddRef( reinterpret_cast<nsIInputStream*>(params.addRefedInputStream())); MOZ_ASSERT(stream); return stream.forget(); } default: MOZ_ASSERT(false, "Unknown params!"); return nullptr; } MOZ_ASSERT(serializable); if (!serializable->Deserialize(aParams, aFileDescriptors)) { MOZ_ASSERT(false, "Deserialize failed!"); return nullptr; } stream = do_QueryInterface(serializable); MOZ_ASSERT(stream); return stream.forget(); }
CompositorWidgetParent::CompositorWidgetParent(const CompositorWidgetInitData& aInitData, const layers::CompositorOptions& aOptions) : X11CompositorWidget(aInitData, aOptions) { MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU); }
FileList* DataTransfer::GetFiles(ErrorResult& aRv) { if (mEventMessage != eDrop && mEventMessage != eLegacyDragDrop && mEventMessage != ePaste) { return nullptr; } if (!mFiles) { mFiles = new FileList(static_cast<nsIDOMDataTransfer*>(this)); uint32_t count = mItems.Length(); for (uint32_t i = 0; i < count; i++) { nsCOMPtr<nsIVariant> variant; aRv = MozGetDataAt(NS_ConvertUTF8toUTF16(kFileMime), i, getter_AddRefs(variant)); if (aRv.Failed()) { return nullptr; } if (!variant) continue; nsCOMPtr<nsISupports> supports; nsresult rv = variant->GetAsISupports(getter_AddRefs(supports)); if (NS_FAILED(rv)) continue; nsCOMPtr<nsIFile> file = do_QueryInterface(supports); RefPtr<File> domFile; if (file) { #ifdef DEBUG if (XRE_GetProcessType() == GeckoProcessType_Default) { bool isDir; file->IsDirectory(&isDir); MOZ_ASSERT(!isDir, "How did we get here?"); } #endif domFile = File::CreateFromFile(GetParentObject(), file); } else { nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(supports); if (!blobImpl) { continue; } MOZ_ASSERT(blobImpl->IsFile()); domFile = File::Create(GetParentObject(), blobImpl); MOZ_ASSERT(domFile); } if (!mFiles->Append(domFile)) { aRv.Throw(NS_ERROR_FAILURE); return nullptr; } } } return mFiles; }
NS_IMETHODIMP nsIOService::SetOffline(bool offline) { // When someone wants to go online (!offline) after we got XPCOM shutdown // throw ERROR_NOT_AVAILABLE to prevent return to online state. if (mShutdown && !offline) return NS_ERROR_NOT_AVAILABLE; // SetOffline() may re-enter while it's shutting down services. // If that happens, save the most recent value and it will be // processed when the first SetOffline() call is done bringing // down the service. mSetOfflineValue = offline; if (mSettingOffline) { return NS_OK; } mSettingOffline = true; nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService(); NS_ASSERTION(observerService, "The observer service should not be null"); if (XRE_GetProcessType() == GeckoProcessType_Default) { if (observerService) { (void)observerService->NotifyObservers(nullptr, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC, offline ? NS_LITERAL_STRING("true").get() : NS_LITERAL_STRING("false").get()); } } nsIIOService *subject = static_cast<nsIIOService *>(this); nsresult rv; while (mSetOfflineValue != mOffline) { offline = mSetOfflineValue; if (offline && !mOffline) { NS_NAMED_LITERAL_STRING(offlineString, NS_IOSERVICE_OFFLINE); mOffline = true; // indicate we're trying to shutdown // don't care if notifications fail if (observerService) observerService->NotifyObservers(subject, NS_IOSERVICE_GOING_OFFLINE_TOPIC, offlineString.get()); if (mDNSService) mDNSService->SetOffline(true); if (mSocketTransportService) mSocketTransportService->SetOffline(true); if (observerService) observerService->NotifyObservers(subject, NS_IOSERVICE_OFFLINE_STATUS_TOPIC, offlineString.get()); } else if (!offline && mOffline) { // go online if (mDNSService) { mDNSService->SetOffline(false); rv = mDNSService->Init(); NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service init failed"); } InitializeSocketTransportService(); mOffline = false; // indicate success only AFTER we've // brought up the services // trigger a PAC reload when we come back online if (mProxyService) mProxyService->ReloadPAC(); // don't care if notification fails if (observerService) observerService->NotifyObservers(subject, NS_IOSERVICE_OFFLINE_STATUS_TOPIC, NS_LITERAL_STRING(NS_IOSERVICE_ONLINE).get()); } } // Don't notify here, as the above notifications (if used) suffice. if (mShutdown && mOffline) { // be sure to try and shutdown both (even if the first fails)... // shutdown dns service first, because it has callbacks for socket transport if (mDNSService) { rv = mDNSService->Shutdown(); NS_ASSERTION(NS_SUCCEEDED(rv), "DNS service shutdown failed"); } if (mSocketTransportService) { rv = mSocketTransportService->Shutdown(); NS_ASSERTION(NS_SUCCEEDED(rv), "socket transport service shutdown failed"); } } mSettingOffline = false; return NS_OK; }
void Volume::SetState(Volume::STATE aNewState) { MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default); MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop()); if (aNewState == mState) { return; } if (aNewState == nsIVolume::STATE_MOUNTED) { mMountGeneration = ++sMountGeneration; LOG("Volume %s (%u): changing state from %s to %s @ '%s' (%d observers) " "mountGeneration = %d, locked = %d", NameStr(), mId, StateStr(mState), StateStr(aNewState), mMountPoint.get(), mEventObserverList.Length(), mMountGeneration, (int)mMountLocked); } else { LOG("Volume %s (%u): changing state from %s to %s (%d observers)", NameStr(), mId, StateStr(mState), StateStr(aNewState), mEventObserverList.Length()); } switch (aNewState) { case nsIVolume::STATE_NOMEDIA: // Cover the startup case where we don't get insertion/removal events mMediaPresent = false; mIsSharing = false; mUnmountRequested = false; mMountRequested = false; mIsUnmounting = false; break; case nsIVolume::STATE_MOUNTED: mMountRequested = false; mIsFormatting = false; mIsSharing = false; mIsUnmounting = false; break; case nsIVolume::STATE_FORMATTING: mFormatRequested = false; mIsFormatting = true; mIsSharing = false; mIsUnmounting = false; break; case nsIVolume::STATE_SHARED: case nsIVolume::STATE_SHAREDMNT: // Covers startup cases. Normally, mIsSharing would be set to true // when we issue the command to initiate the sharing process, but // it's conceivable that a volume could already be in a shared state // when b2g starts. mIsSharing = true; mIsUnmounting = false; mIsFormatting = false; break; case nsIVolume::STATE_UNMOUNTING: mIsUnmounting = true; mIsFormatting = false; mIsSharing = false; break; case nsIVolume::STATE_IDLE: break; default: break; } mState = aNewState; mEventObserverList.Broadcast(this); }
int content_process_main(int argc, char* argv[]) { // Check for the absolute minimum number of args we need to move // forward here. We expect the last arg to be the child process type. if (argc < 1) { return 3; } XRE_SetProcessType(argv[--argc]); bool isNuwa = false; for (int i = 1; i < argc; i++) { isNuwa |= strcmp(argv[i], "-nuwa") == 0; #if defined(XP_WIN) && defined(MOZ_SANDBOX) gIsSandboxEnabled |= strcmp(argv[i], "-sandbox") == 0; #endif } #ifdef MOZ_NUWA_PROCESS if (isNuwa) { PrepareNuwaProcess(); } #endif #ifdef MOZ_WIDGET_GONK // This creates a ThreadPool for binder ipc. A ThreadPool is necessary to // receive binder calls, though not necessary to send binder calls. // ProcessState::Self() also needs to be called once on the main thread to // register the main thread with the binder driver. #ifdef MOZ_NUWA_PROCESS if (!isNuwa) { InitializeBinder(nullptr); } else { NuwaAddFinalConstructor(&InitializeBinder, nullptr); } #else InitializeBinder(nullptr); #endif #endif #ifdef XP_WIN // For plugins, this is done in PluginProcessChild::Init, as we need to // avoid it for unsupported plugins. See PluginProcessChild::Init for // the details. if (XRE_GetProcessType() != GeckoProcessType_Plugin) { mozilla::SanitizeEnvironmentVariables(); SetDllDirectory(L""); } #ifdef MOZ_SANDBOX if (gIsSandboxEnabled) { sandbox::TargetServices* target_service = sandbox::SandboxFactory::GetTargetServices(); if (!target_service) { return 1; } sandbox::ResultCode result = target_service->Init(); if (result != sandbox::SBOX_ALL_OK) { return 2; } mozilla::SandboxTarget::Instance()->SetStartSandboxCallback(StartSandboxCallback); #if defined(MOZ_CONTENT_SANDBOX) mozilla::warnonlysandbox::PrepareForInit(); #endif } #endif #endif nsAutoPtr<mozilla::gmp::GMPLoader> loader; #if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK) // On desktop, the GMPLoader lives in plugin-container, so that its // code can be covered by an EME/GMP vendor's voucher. nsAutoPtr<mozilla::gmp::SandboxStarter> starter(MakeSandboxStarter()); if (XRE_GetProcessType() == GeckoProcessType_GMPlugin) { loader = mozilla::gmp::CreateGMPLoader(starter); } #endif nsresult rv = XRE_InitChildProcess(argc, argv, loader); NS_ENSURE_SUCCESS(rv, 1); return 0; }
void AudioChannelManager::GetAllowedAudioChannels( nsTArray<nsRefPtr<BrowserElementAudioChannel>>& aAudioChannels, ErrorResult& aRv) { MOZ_ASSERT(aAudioChannels.IsEmpty()); // Only main process is supported. if (XRE_GetProcessType() != GeckoProcessType_Default) { aRv.Throw(NS_ERROR_FAILURE); return; } nsCOMPtr<nsPIDOMWindow> window = GetOwner(); if (NS_WARN_IF(!window)) { aRv.Throw(NS_ERROR_FAILURE); return; } nsCOMPtr<nsIDocument> doc = window->GetExtantDoc(); if (NS_WARN_IF(!doc)) { aRv.Throw(NS_ERROR_FAILURE); return; } nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal(); MOZ_ASSERT(principal); uint16_t status; if (NS_WARN_IF(NS_FAILED(principal->GetAppStatus(&status)))) { aRv.Throw(NS_ERROR_FAILURE); return; } if (status != nsIPrincipal::APP_STATUS_CERTIFIED) { aRv.Throw(NS_ERROR_FAILURE); return; } uint32_t appId; aRv = principal->GetAppId(&appId); if (NS_WARN_IF(aRv.Failed())) { return; } nsCOMPtr<nsIAppsService> appsService = do_GetService("@mozilla.org/AppsService;1"); if (NS_WARN_IF(!appsService)) { aRv.Throw(NS_ERROR_FAILURE); return; } nsAutoString manifestURL; aRv = appsService->GetManifestURLByLocalId(appId, manifestURL); if (NS_WARN_IF(aRv.Failed())) { return; } nsBrowserElement::GenerateAllowedAudioChannels(window, nullptr, nullptr, manifestURL, aAudioChannels, aRv); NS_WARN_IF(aRv.Failed()); }
TelemetryImpl::TelemetryImpl(): mCanRecord(XRE_GetProcessType() == GeckoProcessType_Default) { mHistogramMap.Init(Telemetry::HistogramCount); }
void ThreadProfile::StreamJSObject(JSStreamWriter& b) { b.BeginObject(); // Thread meta data if (XRE_GetProcessType() == GeckoProcessType_Plugin) { // TODO Add the proper plugin name b.NameValue("name", "Plugin"); } else { b.NameValue("name", mName); } b.NameValue("tid", static_cast<int>(mThreadId)); b.Name("samples"); b.BeginArray(); bool sample = false; int readPos = mReadPos; while (readPos != mLastFlushPos) { // Number of tag consumed ProfileEntry entry = mEntries[readPos]; switch (entry.mTagName) { case 'r': { if (sample) { b.NameValue("responsiveness", entry.mTagFloat); } } break; case 'p': { if (sample) { b.NameValue("power", entry.mTagFloat); } } break; case 'f': { if (sample) { b.NameValue("frameNumber", entry.mTagLine); } } break; case 't': { if (sample) { b.NameValue("time", entry.mTagFloat); } } break; case 's': { // end the previous sample if there was one if (sample) { b.EndObject(); } // begin the next sample b.BeginObject(); sample = true; // Seek forward through the entire sample, looking for frames // this is an easier approach to reason about than adding more // control variables and cases to the loop that goes through the buffer once b.Name("frames"); b.BeginArray(); b.BeginObject(); b.NameValue("location", "(root)"); b.EndObject(); int framePos = (readPos + 1) % mEntrySize; ProfileEntry frame = mEntries[framePos]; while (framePos != mLastFlushPos && frame.mTagName != 's') { int incBy = 1; frame = mEntries[framePos]; // Read ahead to the next tag, if it's a 'd' tag process it now const char* tagStringData = frame.mTagData; int readAheadPos = (framePos + 1) % mEntrySize; char tagBuff[DYNAMIC_MAX_STRING]; // Make sure the string is always null terminated if it fills up // DYNAMIC_MAX_STRING-2 tagBuff[DYNAMIC_MAX_STRING-1] = '\0'; if (readAheadPos != mLastFlushPos && mEntries[readAheadPos].mTagName == 'd') { tagStringData = processDynamicTag(framePos, &incBy, tagBuff); } // Write one frame. It can have either // 1. only location - 'l' containing a memory address // 2. location and line number - 'c' followed by 'd's and an optional 'n' if (frame.mTagName == 'l') { b.BeginObject(); // Bug 753041 // We need a double cast here to tell GCC that we don't want to sign // extend 32-bit addresses starting with 0xFXXXXXX. unsigned long long pc = (unsigned long long)(uintptr_t)frame.mTagPtr; snprintf(tagBuff, DYNAMIC_MAX_STRING, "%#llx", pc); b.NameValue("location", tagBuff); b.EndObject(); } else if (frame.mTagName == 'c') { b.BeginObject(); b.NameValue("location", tagStringData); readAheadPos = (framePos + incBy) % mEntrySize; if (readAheadPos != mLastFlushPos && mEntries[readAheadPos].mTagName == 'n') { b.NameValue("line", mEntries[readAheadPos].mTagLine); incBy++; } b.EndObject(); } framePos = (framePos + incBy) % mEntrySize; } b.EndArray(); } break; } readPos = (readPos + 1) % mEntrySize; } if (sample) { b.EndObject(); } b.EndArray(); b.Name("markers"); b.BeginArray(); readPos = mReadPos; while (readPos != mLastFlushPos) { ProfileEntry entry = mEntries[readPos]; if (entry.mTagName == 'm') { entry.getMarker()->StreamJSObject(b); } readPos = (readPos + 1) % mEntrySize; } b.EndArray(); b.EndObject(); }
FileList* DataTransfer::GetFileListInternal(ErrorResult& aRv, nsIPrincipal* aSubjectPrincipal) { if (mEventMessage != eDrop && mEventMessage != eLegacyDragDrop && mEventMessage != ePaste) { return nullptr; } if (!mFileList) { mFileList = new FileList(static_cast<nsIDOMDataTransfer*>(this)); uint32_t count = mItems.Length(); for (uint32_t i = 0; i < count; i++) { nsCOMPtr<nsIVariant> variant; aRv = GetDataAtInternal(NS_ConvertUTF8toUTF16(kFileMime), i, aSubjectPrincipal, getter_AddRefs(variant)); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } if (!variant) { continue; } nsCOMPtr<nsISupports> supports; nsresult rv = variant->GetAsISupports(getter_AddRefs(supports)); if (NS_WARN_IF(NS_FAILED(rv))) { continue; } nsCOMPtr<nsIFile> file = do_QueryInterface(supports); RefPtr<File> domFile; if (file) { MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default, "nsIFile objects are not expected on the content process"); bool isDir; aRv = file->IsDirectory(&isDir); if (NS_WARN_IF(aRv.Failed())) { return nullptr; } if (isDir) { continue; } domFile = File::CreateFromFile(GetParentObject(), file); } else { nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(supports); if (!blobImpl) { continue; } MOZ_ASSERT(blobImpl->IsFile()); domFile = File::Create(GetParentObject(), blobImpl); MOZ_ASSERT(domFile); } mFileList->Append(domFile); } } return mFileList; }
nsresult nsPluginNativeWindowGtk::CallSetWindow(nsRefPtr<nsNPAPIPluginInstance> &aPluginInstance) { if (aPluginInstance) { if (type == NPWindowTypeWindow && XRE_GetProcessType() == GeckoProcessType_Content) { // In this case, most of the initialization code here has already happened // in the chrome process. The window we have in content is the XID of the // socket widget we need to hand to plugins. SetWindow((XID)window); } else if (type == NPWindowTypeWindow) { if (!mSocketWidget) { nsresult rv; // The documentation on the types for many variables in NP(N|P)_GetValue // is vague. Often boolean values are NPBool (1 byte), but // https://developer.mozilla.org/en/XEmbed_Extension_for_Mozilla_Plugins // treats NPPVpluginNeedsXEmbed as PRBool (int), and // on x86/32-bit, flash stores to this using |movl 0x1,&needsXEmbed|. // thus we can't use NPBool for needsXEmbed, or the three bytes above // it on the stack would get clobbered. so protect with the larger bool. int needsXEmbed = 0; rv = aPluginInstance->GetValueFromPlugin(NPPVpluginNeedsXEmbed, &needsXEmbed); // If the call returned an error code make sure we still use our default value. if (NS_FAILED(rv)) { needsXEmbed = 0; } #ifdef DEBUG printf("nsPluginNativeWindowGtk: NPPVpluginNeedsXEmbed=%d\n", needsXEmbed); #endif bool isOOPPlugin = aPluginInstance->GetPlugin()->GetLibrary()->IsOOP(); if (needsXEmbed || isOOPPlugin) { bool enableXtFocus = !needsXEmbed; rv = CreateXEmbedWindow(enableXtFocus); } else { #if (MOZ_WIDGET_GTK == 2) rv = CreateXtWindow(); #else return NS_ERROR_FAILURE; #endif } if (NS_FAILED(rv)) { return NS_ERROR_FAILURE; } } if (!mSocketWidget) { return NS_ERROR_FAILURE; } // Make sure to resize and re-place the window if required. SetAllocation(); // Need to reset "window" each time as nsPluginFrame::DidReflow sets it // to the ancestor window. #if (MOZ_WIDGET_GTK == 2) if (GTK_IS_XTBIN(mSocketWidget)) { // Point the NPWindow structures window to the actual X window SetWindow(GTK_XTBIN(mSocketWidget)->xtwindow); } else { // XEmbed or OOP&Xt SetWindow(gtk_socket_get_id(GTK_SOCKET(mSocketWidget))); } #else // Gtk3 supports only OOP by GtkSocket SetWindow(gtk_socket_get_id(GTK_SOCKET(mSocketWidget))); #endif #ifdef DEBUG printf("nsPluginNativeWindowGtk: call SetWindow with xid=%p\n", (void *)window); #endif } // NPWindowTypeWindow aPluginInstance->SetWindow(this); } else if (mPluginInstance) { mPluginInstance->SetWindow(nullptr); } SetPluginInstance(aPluginInstance); return NS_OK; }
void ClientCanvasLayer::Initialize(const Data& aData) { CopyableCanvasLayer::Initialize(aData); mCanvasClient = nullptr; if (!mGLContext) return; GLScreenBuffer* screen = mGLContext->Screen(); SurfaceCaps caps; if (mGLFrontbuffer) { // The screen caps are irrelevant if we're using a separate frontbuffer. caps = mGLFrontbuffer->mHasAlpha ? SurfaceCaps::ForRGBA() : SurfaceCaps::ForRGB(); } else { MOZ_ASSERT(screen); caps = screen->mCaps; } MOZ_ASSERT(caps.alpha == aData.mHasAlpha); auto forwarder = ClientManager()->AsShadowForwarder(); mFlags = TextureFlags::ORIGIN_BOTTOM_LEFT; if (!aData.mIsGLAlphaPremult) { mFlags |= TextureFlags::NON_PREMULTIPLIED; } UniquePtr<SurfaceFactory> factory; if (!gfxPrefs::WebGLForceLayersReadback()) { switch (forwarder->GetCompositorBackendType()) { case mozilla::layers::LayersBackend::LAYERS_OPENGL: { #if defined(XP_MACOSX) factory = SurfaceFactory_IOSurface::Create(mGLContext, caps, forwarder, mFlags); #elif defined(MOZ_WIDGET_GONK) factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext, caps, forwarder, mFlags); #else if (mGLContext->GetContextType() == GLContextType::EGL) { bool isCrossProcess = (XRE_GetProcessType() != GeckoProcessType_Default); if (!isCrossProcess) { factory = SurfaceFactory_EGLImage::Create(mGLContext, caps, forwarder, mFlags); } } #endif break; } case mozilla::layers::LayersBackend::LAYERS_D3D11: { #ifdef XP_WIN if (mGLContext->IsANGLE() && DoesD3D11TextureSharingWork(gfxWindowsPlatform::GetPlatform()->GetD3D11Device())) { factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps, forwarder, mFlags); } #endif break; } default: break; } } if (mGLFrontbuffer) { // We're using a source other than the one in the default screen. // (SkiaGL) mFactory = Move(factory); if (!mFactory) { // Absolutely must have a factory here, so create a basic one mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps, mFlags); } } else { if (factory) screen->Morph(Move(factory)); } }
int content_process_main(int argc, char* argv[]) { // Check for the absolute minimum number of args we need to move // forward here. We expect the last arg to be the child process type. if (argc < 1) { return 3; } bool isNuwa = false; for (int i = 1; i < argc; i++) { isNuwa |= strcmp(argv[i], "-nuwa") == 0; } XREChildData childData; #if defined(XP_WIN) && defined(MOZ_SANDBOX) if (IsSandboxedProcess()) { childData.sandboxTargetServices = mozilla::sandboxing::GetInitializedTargetServices(); if (!childData.sandboxTargetServices) { return 1; } childData.ProvideLogFunction = mozilla::sandboxing::ProvideLogFunction; } #endif XRE_SetProcessType(argv[--argc]); #ifdef MOZ_NUWA_PROCESS if (isNuwa) { PrepareNuwaProcess(); } #endif #if defined(XP_LINUX) && defined(MOZ_SANDBOX) // This has to happen while we're still single-threaded, and on // B2G that means before the Android Binder library is // initialized. Additional special handling is needed for Nuwa: // the Nuwa process itself needs to be unsandboxed, and the same // single-threadedness condition applies to its children; see also // AfterNuwaFork(). mozilla::SandboxEarlyInit(XRE_GetProcessType(), isNuwa); #endif #ifdef MOZ_WIDGET_GONK // This creates a ThreadPool for binder ipc. A ThreadPool is necessary to // receive binder calls, though not necessary to send binder calls. // ProcessState::Self() also needs to be called once on the main thread to // register the main thread with the binder driver. #ifdef MOZ_NUWA_PROCESS if (!isNuwa) { InitializeBinder(nullptr); } else { NuwaAddFinalConstructor(&InitializeBinder, nullptr); } #else InitializeBinder(nullptr); #endif #endif #ifdef XP_WIN // For plugins, this is done in PluginProcessChild::Init, as we need to // avoid it for unsupported plugins. See PluginProcessChild::Init for // the details. if (XRE_GetProcessType() != GeckoProcessType_Plugin) { mozilla::SanitizeEnvironmentVariables(); SetDllDirectoryW(L""); } #endif #if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK) && defined(MOZ_PLUGIN_CONTAINER) // On desktop, the GMPLoader lives in plugin-container, so that its // code can be covered by an EME/GMP vendor's voucher. nsAutoPtr<mozilla::gmp::SandboxStarter> starter(MakeSandboxStarter()); if (XRE_GetProcessType() == GeckoProcessType_GMPlugin) { childData.gmpLoader = mozilla::gmp::CreateGMPLoader(starter); } #endif nsresult rv = XRE_InitChildProcess(argc, argv, &childData); NS_ENSURE_SUCCESS(rv, 1); return 0; }
void ThreadProfile::BuildJSObject(Builder& b, typename Builder::ObjectHandle profile) { // Thread meta data if (XRE_GetProcessType() == GeckoProcessType_Plugin) { // TODO Add the proper plugin name b.DefineProperty(profile, "name", "Plugin"); } else { b.DefineProperty(profile, "name", mName); } b.DefineProperty(profile, "tid", static_cast<int>(mThreadId)); typename Builder::RootedArray samples(b.context(), b.CreateArray()); b.DefineProperty(profile, "samples", samples); typename Builder::RootedObject sample(b.context()); typename Builder::RootedArray frames(b.context()); typename Builder::RootedArray markers(b.context()); int readPos = mReadPos; while (readPos != mLastFlushPos) { // Number of tag consumed int incBy = 1; ProfileEntry entry = mEntries[readPos]; // Read ahead to the next tag, if it's a 'd' tag process it now const char* tagStringData = entry.mTagData; int readAheadPos = (readPos + 1) % mEntrySize; char tagBuff[DYNAMIC_MAX_STRING]; // Make sure the string is always null terminated if it fills up // DYNAMIC_MAX_STRING-2 tagBuff[DYNAMIC_MAX_STRING-1] = '\0'; if (readAheadPos != mLastFlushPos && mEntries[readAheadPos].mTagName == 'd') { tagStringData = processDynamicTag(readPos, &incBy, tagBuff); } switch (entry.mTagName) { case 'm': { if (sample) { if (!markers) { markers = b.CreateArray(); b.DefineProperty(sample, "marker", markers); } entry.getMarker()->BuildJSObject(b, markers); } } break; case 'r': { if (sample) { b.DefineProperty(sample, "responsiveness", entry.mTagFloat); } } break; case 'p': { if (sample) { b.DefineProperty(sample, "power", entry.mTagFloat); } } break; case 'f': { if (sample) { b.DefineProperty(sample, "frameNumber", entry.mTagLine); } } break; case 't': { if (sample) { b.DefineProperty(sample, "time", entry.mTagFloat); } } break; case 's': sample = b.CreateObject(); b.DefineProperty(sample, "name", tagStringData); frames = b.CreateArray(); b.DefineProperty(sample, "frames", frames); b.ArrayPush(samples, sample); // Created lazily markers = nullptr; // Fall though to create a label for the 's' tag case 'c': case 'l': { if (sample) { typename Builder::RootedObject frame(b.context(), b.CreateObject()); if (entry.mTagName == 'l') { // Bug 753041 // We need a double cast here to tell GCC that we don't want to sign // extend 32-bit addresses starting with 0xFXXXXXX. unsigned long long pc = (unsigned long long)(uintptr_t)entry.mTagPtr; snprintf(tagBuff, DYNAMIC_MAX_STRING, "%#llx", pc); b.DefineProperty(frame, "location", tagBuff); } else { b.DefineProperty(frame, "location", tagStringData); readAheadPos = (readPos + incBy) % mEntrySize; if (readAheadPos != mLastFlushPos && mEntries[readAheadPos].mTagName == 'n') { b.DefineProperty(frame, "line", mEntries[readAheadPos].mTagLine); incBy++; } } b.ArrayPush(frames, frame); } } } readPos = (readPos + incBy) % mEntrySize; } }
bool nsPerformanceGroupDetails::IsContentProcess() const { return XRE_GetProcessType() == GeckoProcessType_Content; }
static inline bool ProcessOwnsCompositor() { return XRE_GetProcessType() == GeckoProcessType_GPU || (XRE_IsParentProcess() && !gfxConfig::IsEnabled(Feature::GPU_PROCESS)); }
void BasicShadowableCanvasLayer::Paint(gfxContext* aContext, Layer* aMaskLayer) { if (!HasShadow()) { BasicCanvasLayer::Paint(aContext, aMaskLayer); return; } if (!IsDirty()) return; if (mGLContext && !mForceReadback && BasicManager()->GetParentBackendType() == mozilla::layers::LAYERS_OPENGL) { TextureImage::TextureShareType flags; // if process type is default, then it is single-process (non-e10s) if (XRE_GetProcessType() == GeckoProcessType_Default) flags = TextureImage::ThreadShared; else flags = TextureImage::ProcessShared; SharedTextureHandle handle = GetSharedBackBufferHandle(); if (!handle) { handle = mGLContext->CreateSharedHandle(flags); if (handle) { mBackBuffer = SharedTextureDescriptor(flags, handle, mBounds.Size(), false); } } if (handle) { mGLContext->MakeCurrent(); mGLContext->UpdateSharedHandle(flags, handle); // call Painted() to reset our dirty 'bit' Painted(); FireDidTransactionCallback(); BasicManager()->PaintedCanvas(BasicManager()->Hold(this), mNeedsYFlip, mBackBuffer); // Move SharedTextureHandle ownership to ShadowLayer mBackBuffer = SurfaceDescriptor(); return; } } bool isOpaque = (GetContentFlags() & CONTENT_OPAQUE); if (!IsSurfaceDescriptorValid(mBackBuffer) || isOpaque != mBufferIsOpaque) { DestroyBackBuffer(); mBufferIsOpaque = isOpaque; gfxIntSize size(mBounds.width, mBounds.height); gfxASurface::gfxContentType type = isOpaque ? gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA; if (!BasicManager()->AllocBuffer(size, type, &mBackBuffer)) { NS_RUNTIMEABORT("creating CanvasLayer back buffer failed!"); } } AutoOpenSurface autoBackSurface(OPEN_READ_WRITE, mBackBuffer); if (aMaskLayer) { static_cast<BasicImplData*>(aMaskLayer->ImplData()) ->Paint(aContext, nullptr); } UpdateSurface(autoBackSurface.Get(), nullptr); FireDidTransactionCallback(); BasicManager()->PaintedCanvas(BasicManager()->Hold(this), mNeedsYFlip, mBackBuffer); }
void InstallSignalHandlers(const char *ProgramName) { PL_strncpy(_progname,ProgramName, (sizeof(_progname)-1) ); const char *gdbSleep = PR_GetEnv("MOZ_GDB_SLEEP"); if (gdbSleep && *gdbSleep) { unsigned int s; if (1 == sscanf(gdbSleep, "%u", &s)) { _gdb_sleep_duration = s; } } #if defined(CRAWL_STACK_ON_SIGSEGV) if (!getenv("XRE_NO_WINDOWS_CRASH_DIALOG")) { void (*crap_handler)(int) = GeckoProcessType_Default != XRE_GetProcessType() ? child_ah_crap_handler : ah_crap_handler; signal(SIGSEGV, crap_handler); signal(SIGILL, crap_handler); signal(SIGABRT, crap_handler); } #endif // CRAWL_STACK_ON_SIGSEGV #ifdef SA_SIGINFO /* Install a handler for floating point exceptions and disable them if they occur. */ struct sigaction sa, osa; sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO; sa.sa_sigaction = fpehandler; sigemptyset(&sa.sa_mask); sigaction(SIGFPE, &sa, &osa); #endif if (XRE_GetProcessType() == GeckoProcessType_Content) { /* * If the user is debugging a Gecko parent process in gdb and hits ^C to * suspend, a SIGINT signal will be sent to the child. We ignore this signal * so the child isn't killed. */ signal(SIGINT, SIG_IGN); } #if defined(DEBUG) && defined(LINUX) const char *memLimit = PR_GetEnv("MOZ_MEM_LIMIT"); if (memLimit && *memLimit) { long m = atoi(memLimit); m *= (1024*1024); struct rlimit r; r.rlim_cur = m; r.rlim_max = m; setrlimit(RLIMIT_AS, &r); } #endif #if defined(SOLARIS) #define NOFILES 512 // Boost Solaris file descriptors { struct rlimit rl; if (getrlimit(RLIMIT_NOFILE, &rl) == 0) if (rl.rlim_cur < NOFILES) { rl.rlim_cur = NOFILES; if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { perror("setrlimit(RLIMIT_NOFILE)"); fprintf(stderr, "Cannot exceed hard limit for open files"); } #if defined(DEBUG) if (getrlimit(RLIMIT_NOFILE, &rl) == 0) printf("File descriptors set to %d\n", rl.rlim_cur); #endif //DEBUG } } #endif //SOLARIS #if defined(MOZ_WIDGET_GTK) && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6)) const char *assertString = PR_GetEnv("XPCOM_DEBUG_BREAK"); if (assertString && (!strcmp(assertString, "suspend") || !strcmp(assertString, "stack") || !strcmp(assertString, "abort") || !strcmp(assertString, "trap") || !strcmp(assertString, "break"))) { // Override the default glib logging function so we get stacks for it too. orig_log_func = g_log_set_default_handler(my_glib_log_func, nullptr); } #endif }
void InstallSignalHandlers(const char *ProgramName) { PL_strncpy(_progname,ProgramName, (sizeof(_progname)-1) ); const char *gdbSleep = PR_GetEnv("MOZ_GDB_SLEEP"); if (gdbSleep && *gdbSleep) { unsigned int s; if (1 == sscanf(gdbSleep, "%u", &s)) { _gdb_sleep_duration = s; } } #if defined(MOZ_WIDGET_PHOTON) /* Neutrino need this to free shared memory in case of a crash */ signal(SIGTERM, abnormal_exit_handler); signal(SIGQUIT, abnormal_exit_handler); signal(SIGINT, abnormal_exit_handler); signal(SIGHUP, abnormal_exit_handler); signal(SIGSEGV, abnormal_exit_handler); signal(SIGILL, abnormal_exit_handler); signal(SIGABRT, abnormal_exit_handler); #elif defined(CRAWL_STACK_ON_SIGSEGV) if (!getenv("XRE_NO_WINDOWS_CRASH_DIALOG")) { void (*crap_handler)(int) = #ifdef MOZ_IPC GeckoProcessType_Default != XRE_GetProcessType() ? child_ah_crap_handler : #endif ah_crap_handler; signal(SIGSEGV, crap_handler); signal(SIGILL, crap_handler); signal(SIGABRT, crap_handler); } #endif // CRAWL_STACK_ON_SIGSEGV /* Install a handler for floating point exceptions and disable them if they occur. */ struct sigaction sa, osa; sa.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO; sa.sa_sigaction = fpehandler; sigemptyset(&sa.sa_mask); sigaction(SIGFPE, &sa, &osa); #if defined(DEBUG) && defined(LINUX) const char *memLimit = PR_GetEnv("MOZ_MEM_LIMIT"); if (memLimit && *memLimit) { long m = atoi(memLimit); m *= (1024*1024); struct rlimit r; r.rlim_cur = m; r.rlim_max = m; setrlimit(RLIMIT_AS, &r); } #endif #if defined(SOLARIS) #define NOFILES 512 // Boost Solaris file descriptors { struct rlimit rl; if (getrlimit(RLIMIT_NOFILE, &rl) == 0) if (rl.rlim_cur < NOFILES) { rl.rlim_cur = NOFILES; if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { perror("setrlimit(RLIMIT_NOFILE)"); fprintf(stderr, "Cannot exceed hard limit for open files"); } #if defined(DEBUG) if (getrlimit(RLIMIT_NOFILE, &rl) == 0) printf("File descriptors set to %d\n", rl.rlim_cur); #endif //DEBUG } } #endif //SOLARIS #ifdef XP_BEOS signal(SIGTERM, beos_signal_handler); #endif #if defined(MOZ_WIDGET_GTK2) && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6)) const char *assertString = PR_GetEnv("XPCOM_DEBUG_BREAK"); if (assertString && (!strcmp(assertString, "suspend") || !strcmp(assertString, "stack") || !strcmp(assertString, "abort") || !strcmp(assertString, "trap") || !strcmp(assertString, "break"))) { // Override the default glib logging function so we get stacks for it too. orig_log_func = g_log_set_default_handler(my_glib_log_func, NULL); } #endif }
static int X11Error(Display *display, XErrorEvent *event) { // Get an indication of how long ago the request that caused the error was // made. unsigned long age = NextRequest(display) - event->serial; // Get a string to represent the request that caused the error. nsCAutoString message; if (event->request_code < 128) { // Core protocol request message.AppendInt(event->request_code); } else { // Extension request // man XSetErrorHandler says "the error handler should not call any // functions (directly or indirectly) on the display that will generate // protocol requests or that will look for input events" so we use another // temporary Display to request extension information. This assumes on // the DISPLAY environment variable has been set and matches what was used // to open |display|. Display *tmpDisplay = XOpenDisplay(NULL); if (tmpDisplay) { int nExts; char** extNames = XListExtensions(tmpDisplay, &nExts); int first_error; if (extNames) { for (int i = 0; i < nExts; ++i) { int major_opcode, first_event; if (XQueryExtension(tmpDisplay, extNames[i], &major_opcode, &first_event, &first_error) && major_opcode == event->request_code) { message.Append(extNames[i]); message.Append('.'); message.AppendInt(event->minor_code); break; } } XFreeExtensionList(extNames); } XCloseDisplay(tmpDisplay); #ifdef MOZ_WIDGET_GTK2 // GDK2 calls XCloseDevice the devices that it opened on startup, but // the XI protocol no longer ensures that the devices will still exist. // If they have been removed, then a BadDevice error results. Ignore // this error. if (message.EqualsLiteral("XInputExtension.4") && event->error_code == first_error + 0) { return 0; } #endif } } char buffer[BUFSIZE]; if (message.IsEmpty()) { buffer[0] = '\0'; } else { XGetErrorDatabaseText(display, "XRequest", message.get(), "", buffer, sizeof(buffer)); } nsCAutoString notes; if (buffer[0]) { notes.Append(buffer); } else { notes.Append("Request "); notes.AppendInt(event->request_code); notes.Append('.'); notes.AppendInt(event->minor_code); } notes.Append(": "); // Get a string to describe the error. XGetErrorText(display, event->error_code, buffer, sizeof(buffer)); notes.Append(buffer); // For requests where Xlib gets the reply synchronously, |age| will be 1 // and the stack will include the function making the request. For // asynchronous requests, the current stack will often be unrelated to the // point of making the request, even if |age| is 1, but sometimes this may // help us count back to the point of the request. With XSynchronize on, // the stack will include the function making the request, even though // |age| will be 2 for asynchronous requests because XSynchronize is // implemented by an empty request from an XSync, which has not yet been // processed. if (age > 1) { // XSynchronize returns the previous "after function". If a second // XSynchronize call returns the same function after an enable call then // synchronization must have already been enabled. if (XSynchronize(display, True) == XSynchronize(display, False)) { notes.Append("; sync"); } else { notes.Append("; "); notes.AppendInt(PRUint32(age)); notes.Append(" requests ago"); } } #ifdef MOZ_CRASHREPORTER switch (XRE_GetProcessType()) { case GeckoProcessType_Default: case GeckoProcessType_Plugin: case GeckoProcessType_Content: CrashReporter::AppendAppNotesToCrashReport(notes); break; default: ; // crash report notes not supported. } #endif #ifdef DEBUG // The resource id is unlikely to be useful in a crash report without // context of other ids, but add it to the debug console output. notes.Append("; id=0x"); notes.AppendInt(PRUint32(event->resourceid), 16); #ifdef MOZ_X11 // Actually, for requests where Xlib gets the reply synchronously, // MOZ_X_SYNC=1 will not be necessary, but we don't have a table to tell us // which requests get a synchronous reply. if (!PR_GetEnv("MOZ_X_SYNC")) { notes.Append("\nRe-running with MOZ_X_SYNC=1 in the environment may give a more helpful backtrace."); } #endif #endif #ifdef MOZ_WIDGET_QT // We should not abort here if MOZ_X_SYNC is not set // until http://bugreports.qt.nokia.com/browse/QTBUG-4042 // not fixed, just print error value if (!PR_GetEnv("MOZ_X_SYNC")) { fprintf(stderr, "XError: %s\n", notes.get()); return 0; // temporary workaround for bug 161472 } #endif NS_RUNTIMEABORT(notes.get()); return 0; // not reached }
void ClientCanvasLayer::Initialize(const Data& aData) { CopyableCanvasLayer::Initialize(aData); mCanvasClient = nullptr; if (mGLContext) { GLScreenBuffer* screen = mGLContext->Screen(); SurfaceCaps caps; if (mStream) { // The screen caps are irrelevant if we're using a separate stream caps = aData.mHasAlpha ? SurfaceCaps::ForRGBA() : SurfaceCaps::ForRGB(); } else { caps = screen->Caps(); } MOZ_ASSERT(caps.alpha == aData.mHasAlpha); SurfaceStreamType streamType = SurfaceStream::ChooseGLStreamType(SurfaceStream::OffMainThread, screen->PreserveBuffer()); SurfaceFactory_GL* factory = nullptr; if (!gfxPrefs::WebGLForceLayersReadback()) { if (ClientManager()->AsShadowForwarder()->GetCompositorBackendType() == mozilla::layers::LayersBackend::LAYERS_OPENGL) { if (mGLContext->GetContextType() == GLContextType::EGL) { bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default); if (!isCrossProcess) { // [Basic/OGL Layers, OMTC] WebGL layer init. factory = SurfaceFactory_EGLImage::Create(mGLContext, caps); } else { // [Basic/OGL Layers, OOPC] WebGL layer init. (Out Of Process Compositing) #ifdef MOZ_WIDGET_GONK factory = new SurfaceFactory_Gralloc(mGLContext, caps, ClientManager()->AsShadowForwarder()); #else // we could do readback here maybe NS_NOTREACHED("isCrossProcess but not on native B2G!"); #endif } } else { // [Basic Layers, OMTC] WebGL layer init. // Well, this *should* work... #ifdef XP_MACOSX factory = new SurfaceFactory_IOSurface(mGLContext, caps); #else factory = new SurfaceFactory_GLTexture(mGLContext, nullptr, caps); #endif } } } if (mStream) { // We're using a stream other than the one in the default screen mFactory = factory; if (!mFactory) { // Absolutely must have a factory here, so create a basic one mFactory = new SurfaceFactory_Basic(mGLContext, caps); } gfx::IntSize size = gfx::IntSize(aData.mSize.width, aData.mSize.height); mTextureSurface = SharedSurface_GLTexture::Create(mGLContext, mGLContext, mGLContext->GetGLFormats(), size, caps.alpha, aData.mTexID); SharedSurface* producer = mStream->SwapProducer(mFactory, size); if (!producer) { // Fallback to basic factory delete mFactory; mFactory = new SurfaceFactory_Basic(mGLContext, caps); producer = mStream->SwapProducer(mFactory, size); MOZ_ASSERT(producer, "Failed to create initial canvas surface with basic factory"); } } else if (factory) { screen->Morph(factory, streamType); } } }
RefPtr<VsyncObserver> CompositorWidgetParent::GetVsyncObserver() const { MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU); return mVsyncObserver; }
// static bool FileSystemUtils::IsParentProcess() { return XRE_GetProcessType() == GeckoProcessType_Default; }
void CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) { aLayer->mGLContext->MakeCurrent(); GLScreenBuffer* screen = aLayer->mGLContext->Screen(); SurfaceStream* stream = nullptr; if (aLayer->mStream) { stream = aLayer->mStream; // Copy our current surface to the current producer surface in our stream, then // call SwapProducer to make a new buffer ready. stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory); stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height)); } else { stream = screen->Stream(); } bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default); bool bufferCreated = false; if (isCrossProcess) { #ifdef MOZ_WIDGET_GONK SharedSurface* surf = stream->SwapConsumer(); if (!surf) { printf_stderr("surf is null post-SwapConsumer!\n"); return; } if (surf->Type() != SharedSurfaceType::Gralloc) { printf_stderr("Unexpected non-Gralloc SharedSurface in IPC path!"); MOZ_ASSERT(false); return; } SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf); RefPtr<GrallocTextureClientOGL> grallocTextureClient = static_cast<GrallocTextureClientOGL*>(grallocSurf->GetTextureClient()); // If IPDLActor is null means this TextureClient didn't AddTextureClient yet if (!grallocTextureClient->GetIPDLActor()) { grallocTextureClient->SetTextureFlags(mTextureInfo.mTextureFlags); AddTextureClient(grallocTextureClient); } if (grallocTextureClient->GetIPDLActor()) { GetForwarder()->UseTexture(this, grallocTextureClient); } #else printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!"); MOZ_ASSERT(false); #endif } else { if (!mBuffer) { StreamTextureClientOGL* textureClient = new StreamTextureClientOGL(mTextureInfo.mTextureFlags); textureClient->InitWith(stream); mBuffer = textureClient; bufferCreated = true; } if (bufferCreated && !AddTextureClient(mBuffer)) { mBuffer = nullptr; } if (mBuffer) { GetForwarder()->UseTexture(this, mBuffer); } } aLayer->Painted(); }
void ClientCanvasLayer::Initialize(const Data& aData) { CopyableCanvasLayer::Initialize(aData); mCanvasClient = nullptr; if (!mGLContext) return; GLScreenBuffer* screen = mGLContext->Screen(); SurfaceCaps caps; if (mGLFrontbuffer) { // The screen caps are irrelevant if we're using a separate frontbuffer. caps = mGLFrontbuffer->mHasAlpha ? SurfaceCaps::ForRGBA() : SurfaceCaps::ForRGB(); } else { MOZ_ASSERT(screen); caps = screen->mCaps; } MOZ_ASSERT(caps.alpha == aData.mHasAlpha); UniquePtr<SurfaceFactory> factory; if (!gfxPrefs::WebGLForceLayersReadback()) { switch (ClientManager()->AsShadowForwarder()->GetCompositorBackendType()) { case mozilla::layers::LayersBackend::LAYERS_OPENGL: { if (mGLContext->GetContextType() == GLContextType::EGL) { #ifdef MOZ_WIDGET_GONK TextureFlags flags = TextureFlags::DEALLOCATE_CLIENT | TextureFlags::ORIGIN_BOTTOM_LEFT; if (!aData.mIsGLAlphaPremult) { flags |= TextureFlags::NON_PREMULTIPLIED; } factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext, caps, flags, ClientManager()->AsShadowForwarder()); #else bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default); if (!isCrossProcess) { // [Basic/OGL Layers, OMTC] WebGL layer init. factory = SurfaceFactory_EGLImage::Create(mGLContext, caps); } else { // we could do readback here maybe NS_NOTREACHED("isCrossProcess but not on native B2G!"); } #endif } else { // [Basic Layers, OMTC] WebGL layer init. // Well, this *should* work... #ifdef XP_MACOSX factory = SurfaceFactory_IOSurface::Create(mGLContext, caps); #else GLContext* nullConsGL = nullptr; // Bug 1050044. factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, nullConsGL, caps); #endif } break; } case mozilla::layers::LayersBackend::LAYERS_D3D10: case mozilla::layers::LayersBackend::LAYERS_D3D11: { #ifdef XP_WIN if (mGLContext->IsANGLE() && DoesD3D11TextureSharingWork(gfxWindowsPlatform::GetPlatform()->GetD3D11Device())) { factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext, caps); } #endif break; } default: break; } } if (mGLFrontbuffer) { // We're using a source other than the one in the default screen. // (SkiaGL) mFactory = Move(factory); if (!mFactory) { // Absolutely must have a factory here, so create a basic one mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps); } } else { if (factory) screen->Morph(Move(factory)); } }
JSObject* WrapperFactory::Rewrap(JSContext* cx, HandleObject existing, HandleObject obj, HandleObject parent) { MOZ_ASSERT(!IsWrapper(obj) || GetProxyHandler(obj) == &XrayWaiver || js::GetObjectClass(obj)->ext.innerObject, "wrapped object passed to rewrap"); MOZ_ASSERT(!XrayUtils::IsXPCWNHolderClass(JS_GetClass(obj)), "trying to wrap a holder"); MOZ_ASSERT(!js::IsInnerObject(obj)); // We sometimes end up here after nsContentUtils has been shut down but before // XPConnect has been shut down, so check the context stack the roundabout way. MOZ_ASSERT(XPCJSRuntime::Get()->GetJSContextStack()->Peek() == cx); // Compute the information we need to select the right wrapper. JSCompartment* origin = js::GetObjectCompartment(obj); JSCompartment* target = js::GetContextCompartment(cx); bool originIsChrome = AccessCheck::isChrome(origin); bool targetIsChrome = AccessCheck::isChrome(target); bool originSubsumesTarget = AccessCheck::subsumesConsideringDomain(origin, target); bool targetSubsumesOrigin = AccessCheck::subsumesConsideringDomain(target, origin); bool sameOrigin = targetSubsumesOrigin && originSubsumesTarget; XrayType xrayType = GetXrayType(obj); const Wrapper* wrapper; // // First, handle the special cases. // // If UniversalXPConnect is enabled, this is just some dumb mochitest. Use // a vanilla CCW. if (xpc::IsUniversalXPConnectEnabled(target)) { CrashIfNotInAutomation(); wrapper = &CrossCompartmentWrapper::singleton; } // Let the SpecialPowers scope make its stuff easily accessible to content. else if (CompartmentPrivate::Get(origin)->forcePermissiveCOWs) { CrashIfNotInAutomation(); wrapper = &CrossCompartmentWrapper::singleton; } // Special handling for chrome objects being exposed to content. else if (originIsChrome && !targetIsChrome) { // If this is a chrome function being exposed to content, we need to allow // call (but nothing else). We allow CPOWs that purport to be function's // here, but only in the content process. if ((IdentifyStandardInstance(obj) == JSProto_Function || (jsipc::IsCPOW(obj) && JS::IsCallable(obj) && XRE_GetProcessType() == GeckoProcessType_Content))) { wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper, OpaqueWithCall>::singleton; } // For Vanilla JSObjects exposed from chrome to content, we use a wrapper // that supports __exposedProps__. We'd like to get rid of these eventually, // but in their current form they don't cause much trouble. else if (IdentifyStandardInstance(obj) == JSProto_Object) { wrapper = &ChromeObjectWrapper::singleton; } // Otherwise we get an opaque wrapper. else { wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton; } } // // Now, handle the regular cases. // // These are wrappers we can compute using a rule-based approach. In order // to do so, we need to compute some parameters. // else { // The wrapper is a security wrapper (protecting the wrappee) if and // only if the target does not subsume the origin. bool securityWrapper = !targetSubsumesOrigin; // Xrays are warranted if either the target or the origin don't trust // each other. This is generally the case, unless the two are same-origin // and the caller has not requested same-origin Xrays. // // Xrays are a bidirectional protection, since it affords clarity to the // caller and privacy to the callee. bool sameOriginXrays = CompartmentPrivate::Get(origin)->wantXrays || CompartmentPrivate::Get(target)->wantXrays; bool wantXrays = !sameOrigin || sameOriginXrays; // If Xrays are warranted, the caller may waive them for non-security // wrappers. bool waiveXrays = wantXrays && !securityWrapper && HasWaiveXrayFlag(obj); // We have slightly different behavior for the case when the object // being wrapped is in an XBL scope. bool originIsContentXBLScope = IsContentXBLScope(origin); wrapper = SelectWrapper(securityWrapper, wantXrays, xrayType, waiveXrays, originIsContentXBLScope, obj); // If we want to apply add-on interposition in the target compartment, // then we try to "upgrade" the wrapper to an interposing one. if (CompartmentPrivate::Get(target)->scope->HasInterposition()) wrapper = SelectAddonWrapper(cx, obj, wrapper); } if (!targetSubsumesOrigin) { // Do a belt-and-suspenders check against exposing eval()/Function() to // non-subsuming content. if (JSFunction* fun = JS_GetObjectFunction(obj)) { if (JS_IsBuiltinEvalFunction(fun) || JS_IsBuiltinFunctionConstructor(fun)) { NS_WARNING("Trying to expose eval or Function to non-subsuming content!"); wrapper = &FilteringWrapper<CrossCompartmentSecurityWrapper, Opaque>::singleton; } } } DEBUG_CheckUnwrapSafety(obj, wrapper, origin, target); if (existing) return Wrapper::Renew(cx, existing, obj, wrapper); return Wrapper::New(cx, obj, parent, wrapper); }
bool IsMainProcess() { return XRE_GetProcessType() == GeckoProcessType_Default; }