michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:set ts=2 sw=2 sts=2 et cindent: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: #include "FileSystemPermissionRequest.h" michael@0: michael@0: #include "mozilla/dom/FileSystemBase.h" michael@0: #include "mozilla/dom/FileSystemTaskBase.h" michael@0: #include "mozilla/dom/FileSystemUtils.h" michael@0: #include "mozilla/dom/TabChild.h" michael@0: #include "nsIDocument.h" michael@0: #include "nsPIDOMWindow.h" michael@0: #include "nsString.h" michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: NS_IMPL_ISUPPORTS(FileSystemPermissionRequest, nsIRunnable, nsIContentPermissionRequest) michael@0: michael@0: // static michael@0: void michael@0: FileSystemPermissionRequest::RequestForTask(FileSystemTaskBase* aTask) michael@0: { michael@0: MOZ_ASSERT(aTask, "aTask should not be null!"); michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: nsRefPtr request = michael@0: new FileSystemPermissionRequest(aTask); michael@0: NS_DispatchToCurrentThread(request); michael@0: } michael@0: michael@0: FileSystemPermissionRequest::FileSystemPermissionRequest( michael@0: FileSystemTaskBase* aTask) michael@0: : mTask(aTask) michael@0: { michael@0: MOZ_ASSERT(mTask, "aTask should not be null!"); michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: michael@0: mTask->GetPermissionAccessType(mPermissionAccess); michael@0: michael@0: nsRefPtr filesystem = mTask->GetFileSystem(); michael@0: if (!filesystem) { michael@0: return; michael@0: } michael@0: michael@0: mPermissionType = filesystem->GetPermission(); michael@0: michael@0: mWindow = filesystem->GetWindow(); michael@0: if (!mWindow) { michael@0: return; michael@0: } michael@0: michael@0: nsCOMPtr doc = mWindow->GetDoc(); michael@0: if (!doc) { michael@0: return; michael@0: } michael@0: michael@0: mPrincipal = doc->NodePrincipal(); michael@0: } michael@0: michael@0: FileSystemPermissionRequest::~FileSystemPermissionRequest() michael@0: { michael@0: } michael@0: michael@0: bool michael@0: FileSystemPermissionRequest::Recv__delete__(const bool& aAllow, michael@0: const InfallibleTArray& aChoices) michael@0: { michael@0: MOZ_ASSERT(aChoices.IsEmpty(), michael@0: "FileSystemPermissionRequest doesn't support permission choice"); michael@0: if (aAllow) { michael@0: Allow(JS::UndefinedHandleValue); michael@0: } else { michael@0: Cancel(); michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: void michael@0: FileSystemPermissionRequest::IPDLRelease() michael@0: { michael@0: Release(); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: FileSystemPermissionRequest::GetTypes(nsIArray** aTypes) michael@0: { michael@0: nsTArray emptyOptions; michael@0: return CreatePermissionArray(mPermissionType, michael@0: mPermissionAccess, michael@0: emptyOptions, michael@0: aTypes); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: FileSystemPermissionRequest::GetPrincipal(nsIPrincipal** aRequestingPrincipal) michael@0: { michael@0: NS_IF_ADDREF(*aRequestingPrincipal = mPrincipal); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: FileSystemPermissionRequest::GetWindow(nsIDOMWindow** aRequestingWindow) michael@0: { michael@0: NS_IF_ADDREF(*aRequestingWindow = mWindow); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: FileSystemPermissionRequest::GetElement(nsIDOMElement** aRequestingElement) michael@0: { michael@0: *aRequestingElement = nullptr; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: FileSystemPermissionRequest::Cancel() michael@0: { michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: mTask->SetError(NS_ERROR_DOM_SECURITY_ERR); michael@0: mTask->Start(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: FileSystemPermissionRequest::Allow(JS::HandleValue aChoices) michael@0: { michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: MOZ_ASSERT(aChoices.isUndefined()); michael@0: mTask->Start(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: FileSystemPermissionRequest::Run() michael@0: { michael@0: MOZ_ASSERT(NS_IsMainThread()); michael@0: michael@0: nsRefPtr filesystem = mTask->GetFileSystem(); michael@0: if (!filesystem) { michael@0: Cancel(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (filesystem->IsTesting()) { michael@0: Allow(JS::UndefinedHandleValue); michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (FileSystemUtils::IsParentProcess()) { michael@0: nsCOMPtr prompt michael@0: = do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID); michael@0: if (!prompt || NS_FAILED(prompt->Prompt(this))) { michael@0: Cancel(); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (!mWindow) { michael@0: Cancel(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: // because owner implements nsITabChild, we can assume that it is michael@0: // the one and only TabChild. michael@0: TabChild* child = TabChild::GetFrom(mWindow->GetDocShell()); michael@0: if (!child) { michael@0: Cancel(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: // Retain a reference so the object isn't deleted without IPDL's michael@0: // knowledge. Corresponding release occurs in michael@0: // DeallocPContentPermissionRequest. michael@0: AddRef(); michael@0: michael@0: nsTArray permArray; michael@0: nsTArray emptyOptions; michael@0: permArray.AppendElement(PermissionRequest(mPermissionType, michael@0: mPermissionAccess, michael@0: emptyOptions)); michael@0: child->SendPContentPermissionRequestConstructor( michael@0: this, permArray, IPC::Principal(mPrincipal)); michael@0: michael@0: Sendprompt(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: } /* namespace dom */ michael@0: } /* namespace mozilla */