void TabParent::Destroy() { if (mIsDestroyed) { return; } // If this fails, it's most likely due to a content-process crash, // and auto-cleanup will kick in. Otherwise, the child side will // destroy itself and send back __delete__(). unused << SendDestroy(); const InfallibleTArray<PIndexedDBParent*>& idbParents = ManagedPIndexedDBParent(); for (uint32_t i = 0; i < idbParents.Length(); ++i) { static_cast<IndexedDBParent*>(idbParents[i])->Disconnect(); } if (RenderFrameParent* frame = GetRenderFrame()) { frame->Destroy(); } mIsDestroyed = true; ContentParent* cp = static_cast<ContentParent*>(Manager()); cp->NotifyTabDestroying(this); mMarkedDestroying = true; }
mozilla::ipc::IProtocol* CrashReporterParent::CloneProtocol(Channel* aChannel, mozilla::ipc::ProtocolCloneContext* aCtx) { #ifdef MOZ_CRASHREPORTER ContentParent* contentParent = aCtx->GetContentParent(); CrashReporter::ThreadId childThreadId = contentParent->Pid(); GeckoProcessType childProcessType = contentParent->Process()->GetProcessType(); nsAutoPtr<PCrashReporterParent> actor( contentParent->AllocPCrashReporterParent(childThreadId, childProcessType) ); if (!actor || !contentParent->RecvPCrashReporterConstructor(actor, childThreadId, childThreadId)) { return nullptr; } return actor.forget(); #else MOZ_CRASH("Not Implemented"); return nullptr; #endif }
bool TabParent::Recv__delete__() { ContentParent* cp = static_cast<ContentParent*>(Manager()); cp->NotifyTabDestroyed(this, mMarkedDestroying); return true; }
BlobParent* FileSystemTaskBase::GetBlobParent(BlobImpl* aFile) const { MOZ_ASSERT(XRE_IsParentProcess(), "Only call from parent process!"); MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); MOZ_ASSERT(aFile); // Load the lazy dom file data from the parent before sending to the child. nsString mimeType; aFile->GetType(mimeType); // We call GetSize and GetLastModified to prepopulate the value in the // BlobImpl. { ErrorResult rv; aFile->GetSize(rv); rv.SuppressException(); } { ErrorResult rv; aFile->GetLastModified(rv); rv.SuppressException(); } ContentParent* cp = static_cast<ContentParent*>(mRequestParent->Manager()); return cp->GetOrCreateActorForBlobImpl(aFile); }
bool ContentPermissionRequestParent::IsBeingDestroyed() { // When ContentParent::MarkAsDead() is called, we are being destroyed. // It's unsafe to send out any message now. ContentParent* contentParent = static_cast<ContentParent*>(Manager()); return !contentParent->IsAlive(); }
mozilla::ipc::IProtocol* JavaScriptParent::CloneProtocol(Channel* aChannel, ProtocolCloneContext* aCtx) { ContentParent *contentParent = aCtx->GetContentParent(); nsAutoPtr<PJavaScriptParent> actor(contentParent->AllocPJavaScriptParent()); if (!actor || !contentParent->RecvPJavaScriptConstructor(actor)) { return nullptr; } return actor.forget(); }
NS_IMETHODIMP nsMemoryInfoDumper::DumpGCAndCCLogsToFile(const nsAString& aIdentifier, bool aDumpAllTraces, bool aDumpChildProcesses, nsIDumpGCAndCCLogsCallback* aCallback) { nsString identifier(aIdentifier); EnsureNonEmptyIdentifier(identifier); nsCOMPtr<nsIDumpGCAndCCLogsCallback> callbackHolder = new nsDumpGCAndCCLogsCallbackHolder(aCallback); if (aDumpChildProcesses) { nsTArray<ContentParent*> children; ContentParent::GetAll(children); for (uint32_t i = 0; i < children.Length(); i++) { ContentParent* cp = children[i]; nsCOMPtr<nsICycleCollectorLogSink> logSink = nsCycleCollector_createLogSink(); logSink->SetFilenameIdentifier(identifier); logSink->SetProcessIdentifier(cp->Pid()); Unused << cp->CycleCollectWithLogs(aDumpAllTraces, logSink, callbackHolder); } } nsCOMPtr<nsICycleCollectorListener> logger = do_CreateInstance("@mozilla.org/cycle-collector-logger;1"); if (aDumpAllTraces) { nsCOMPtr<nsICycleCollectorListener> allTracesLogger; logger->AllTraces(getter_AddRefs(allTracesLogger)); logger = allTracesLogger; } nsCOMPtr<nsICycleCollectorLogSink> logSink; logger->GetLogSink(getter_AddRefs(logSink)); logSink->SetFilenameIdentifier(identifier); nsJSContext::CycleCollectNow(logger); nsCOMPtr<nsIFile> gcLog, ccLog; logSink->GetGcLog(getter_AddRefs(gcLog)); logSink->GetCcLog(getter_AddRefs(ccLog)); callbackHolder->OnDump(gcLog, ccLog, /* parent = */ true); return NS_OK; }
bool ScreenManagerParent::RecvScreenForBrowser(const TabId& aTabId, ScreenDetails* aRetVal, bool* aSuccess) { *aSuccess = false; #ifdef MOZ_VALGRIND // Zero this so that Valgrind doesn't complain when we send it to another // process. memset(aRetVal, 0, sizeof(ScreenDetails)); #endif // Find the mWidget associated with the tabparent, and then return // the nsIScreen it's on. ContentParent* cp = static_cast<ContentParent*>(this->Manager()); ContentProcessManager* cpm = ContentProcessManager::GetSingleton(); nsRefPtr<TabParent> tabParent = cpm->GetTopLevelTabParentByProcessAndTabId(cp->ChildID(), aTabId); if(!tabParent){ return false; } nsCOMPtr<nsIWidget> widget = tabParent->GetWidget(); nsCOMPtr<nsIScreen> screen; if (widget) { if (widget->GetNativeData(NS_NATIVE_WINDOW)) { mScreenMgr->ScreenForNativeWidget(widget->GetNativeData(NS_NATIVE_WINDOW), getter_AddRefs(screen)); } } else { nsresult rv = mScreenMgr->GetPrimaryScreen(getter_AddRefs(screen)); if (NS_WARN_IF(NS_FAILED(rv))) { return true; } } NS_ENSURE_TRUE(screen, true); ScreenDetails details; if (!ExtractScreenDetails(screen, details)) { return true; } *aRetVal = details; *aSuccess = true; return true; }
void FilePickerParent::SendFiles(const nsCOMArray<nsIDOMFile>& aDomfiles) { ContentParent* parent = static_cast<ContentParent*>(Manager()->Manager()); InfallibleTArray<PBlobParent*> files; for (unsigned i = 0; i < aDomfiles.Length(); i++) { BlobParent* blob = parent->GetOrCreateActorForBlob(aDomfiles[i]); if (blob) { files.AppendElement(blob); } } InputFiles infiles; infiles.filesParent().SwapElements(files); unused << Send__delete__(this, infiles, mResult); }
FileSystemResponseValue GetFileOrDirectoryTask::GetSuccessRequestResult() const { MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread!"); if (mIsDirectory) { return FileSystemDirectoryResponse(mTargetRealPath); } ContentParent* cp = static_cast<ContentParent*>(mRequestParent->Manager()); BlobParent* actor = cp->GetOrCreateActorForBlob(mTargetFile); if (!actor) { return FileSystemErrorResponse(NS_ERROR_DOM_FILESYSTEM_UNKNOWN_ERR); } FileSystemFileResponse response; response.blobParent() = actor; return response; }
bool AssertAppProcess(PBrowserParent* aActor, AssertAppProcessType aType, const char* aCapability) { if (!aActor) { NS_WARNING("Testing process capability for null actor"); return false; } TabParent* tab = static_cast<TabParent*>(aActor); nsCOMPtr<mozIApplication> app = tab->GetOwnOrContainingApp(); bool aValid = false; // isBrowser frames inherit their app descriptor to identify their // data storage, but they don't inherit the capability associated // with that descriptor. if (app && (aType == ASSERT_APP_HAS_PERMISSION || !tab->IsBrowserElement())) { switch (aType) { case ASSERT_APP_HAS_PERMISSION: case ASSERT_APP_PROCESS_PERMISSION: if (!NS_SUCCEEDED(app->HasPermission(aCapability, &aValid))) { aValid = false; } break; case ASSERT_APP_PROCESS_MANIFEST_URL: { nsAutoString manifestURL; if (NS_SUCCEEDED(app->GetManifestURL(manifestURL)) && manifestURL.EqualsASCII(aCapability)) { aValid = true; } break; } default: break; } } if (!aValid) { printf_stderr("Security problem: Content process does not have `%s'. It will be killed.\n", aCapability); ContentParent* process = tab->Manager(); process->KillHard(); } return aValid; }
nsresult DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() { NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); nsString mime; CopyASCIItoUTF16(mMimeType, mime); nsCOMPtr<nsIDOMBlob> blob = new nsDOMFileFile(mFile->mPath, mime, mLength, mFile->mFile); ContentParent* cp = static_cast<ContentParent*>(mParent->Manager()); BlobParent* actor = cp->GetOrCreateActorForBlob(blob); BlobResponse response; response.blobParent() = actor; unused << mParent->Send__delete__(mParent, response); return NS_OK; }
void FilePickerParent::SendFilesOrDirectories( const nsTArray<BlobImplOrString>& aData) { ContentParent* parent = TabParent::GetFrom(Manager())->Manager(); if (mMode == nsIFilePicker::modeGetFolder) { MOZ_ASSERT(aData.Length() <= 1); if (aData.IsEmpty()) { Unused << Send__delete__(this, void_t(), mResult); return; } MOZ_ASSERT(aData[0].mType == BlobImplOrString::eDirectoryPath); // Let's inform the security singleton about the given access of this tab on // this directory path. RefPtr<FileSystemSecurity> fss = FileSystemSecurity::GetOrCreate(); fss->GrantAccessToContentProcess(parent->ChildID(), aData[0].mDirectoryPath); InputDirectory input; input.directoryPath() = aData[0].mDirectoryPath; Unused << Send__delete__(this, input, mResult); return; } InfallibleTArray<IPCBlob> ipcBlobs; for (unsigned i = 0; i < aData.Length(); i++) { IPCBlob ipcBlob; MOZ_ASSERT(aData[i].mType == BlobImplOrString::eBlobImpl); nsresult rv = IPCBlobUtils::Serialize(aData[i].mBlobImpl, parent, ipcBlob); if (NS_WARN_IF(NS_FAILED(rv))) { break; } ipcBlobs.AppendElement(ipcBlob); } InputBlobs inblobs; inblobs.blobs().SwapElements(ipcBlobs); Unused << Send__delete__(this, inblobs, mResult); }
nsresult nsPermissionManager::AddInternal(const nsAFlatCString &aHost, const nsAFlatCString &aType, PRUint32 aPermission, PRInt64 aID, PRUint32 aExpireType, PRInt64 aExpireTime, NotifyOperationType aNotifyOperation, DBOperationType aDBOperation) { if (!IsChildProcess()) { IPC::Permission permission((aHost), (aType), aPermission, aExpireType, aExpireTime); nsTArray<ContentParent*> cplist; ContentParent::GetAll(cplist); for (PRUint32 i = 0; i < cplist.Length(); ++i) { ContentParent* cp = cplist[i]; if (cp->NeedsPermissionsUpdate()) unused << cp->SendAddPermission(permission); } } if (!gHostArena) { gHostArena = new PLArenaPool; if (!gHostArena) return NS_ERROR_OUT_OF_MEMORY; PL_INIT_ARENA_POOL(gHostArena, "PermissionHostArena", HOST_ARENA_SIZE); } // look up the type index PRInt32 typeIndex = GetTypeIndex(aType.get(), true); NS_ENSURE_TRUE(typeIndex != -1, NS_ERROR_OUT_OF_MEMORY); // When an entry already exists, PutEntry will return that, instead // of adding a new one nsHostEntry *entry = mHostTable.PutEntry(aHost.get()); if (!entry) return NS_ERROR_FAILURE; if (!entry->GetKey()) { mHostTable.RawRemoveEntry(entry); return NS_ERROR_OUT_OF_MEMORY; } // figure out the transaction type, and get any existing permission value OperationType op; PRInt32 index = entry->GetPermissionIndex(typeIndex); if (index == -1) { if (aPermission == nsIPermissionManager::UNKNOWN_ACTION) op = eOperationNone; else op = eOperationAdding; } else { nsPermissionEntry oldPermissionEntry = entry->GetPermissions()[index]; // remove the permission if the permission is UNKNOWN, update the // permission if its value or expire type have changed OR if the time has // changed and the expire type is time, otherwise, don't modify. There's // no need to modify a permission that doesn't expire with time when the // only thing changed is the expire time. if (aPermission == oldPermissionEntry.mPermission && aExpireType == oldPermissionEntry.mExpireType && (aExpireType != nsIPermissionManager::EXPIRE_TIME || aExpireTime == oldPermissionEntry.mExpireTime)) op = eOperationNone; else if (aPermission == nsIPermissionManager::UNKNOWN_ACTION) op = eOperationRemoving; else op = eOperationChanging; } // do the work for adding, deleting, or changing a permission: // update the in-memory list, write to the db, and notify consumers. PRInt64 id; switch (op) { case eOperationNone: { // nothing to do return NS_OK; } case eOperationAdding: { if (aDBOperation == eWriteToDB) { // we'll be writing to the database - generate a known unique id id = ++mLargestID; } else { // we're reading from the database - use the id already assigned id = aID; } entry->GetPermissions().AppendElement(nsPermissionEntry(typeIndex, aPermission, id, aExpireType, aExpireTime)); if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION) UpdateDB(op, mStmtInsert, id, aHost, aType, aPermission, aExpireType, aExpireTime); if (aNotifyOperation == eNotify) { NotifyObserversWithPermission(aHost, mTypeArray[typeIndex], aPermission, aExpireType, aExpireTime, NS_LITERAL_STRING("added").get()); } break; } case eOperationRemoving: { nsPermissionEntry oldPermissionEntry = entry->GetPermissions()[index]; id = oldPermissionEntry.mID; entry->GetPermissions().RemoveElementAt(index); // If no more types are present, remove the entry if (entry->GetPermissions().IsEmpty()) mHostTable.RawRemoveEntry(entry); if (aDBOperation == eWriteToDB) UpdateDB(op, mStmtDelete, id, EmptyCString(), EmptyCString(), 0, nsIPermissionManager::EXPIRE_NEVER, 0); if (aNotifyOperation == eNotify) { NotifyObserversWithPermission(aHost, mTypeArray[typeIndex], oldPermissionEntry.mPermission, oldPermissionEntry.mExpireType, oldPermissionEntry.mExpireTime, NS_LITERAL_STRING("deleted").get()); } break; } case eOperationChanging: { id = entry->GetPermissions()[index].mID; entry->GetPermissions()[index].mPermission = aPermission; if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION) UpdateDB(op, mStmtUpdate, id, EmptyCString(), EmptyCString(), aPermission, aExpireType, aExpireTime); if (aNotifyOperation == eNotify) { NotifyObserversWithPermission(aHost, mTypeArray[typeIndex], aPermission, aExpireType, aExpireTime, NS_LITERAL_STRING("changed").get()); } break; } } return NS_OK; }