gecko-dev/dom/workers/ServiceWorkerWindowClient.cpp

559 строки
16 KiB
C++
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "ServiceWorkerWindowClient.h"
#include "js/Value.h"
#include "mozilla/Mutex.h"
#include "mozilla/dom/ClientBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseWorkerProxy.h"
#include "mozilla/UniquePtr.h"
#include "nsContentUtils.h"
#include "nsGlobalWindow.h"
#include "nsIDocShell.h"
#include "nsIDocShellLoadInfo.h"
#include "nsIDocument.h"
#include "nsIGlobalObject.h"
#include "nsIPrincipal.h"
#include "nsIScriptSecurityManager.h"
#include "nsIWebNavigation.h"
#include "nsIWebProgress.h"
#include "nsIWebProgressListener.h"
#include "nsString.h"
#include "nsWeakReference.h"
#include "ServiceWorker.h"
#include "ServiceWorkerInfo.h"
#include "ServiceWorkerManager.h"
#include "WorkerPrivate.h"
#include "WorkerScope.h"
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::dom::workers;
using mozilla::UniquePtr;
JSObject*
Bug 1117172 part 3. Change the wrappercached WrapObject methods to allow passing in aGivenProto. r=peterv The only manual changes here are to BindingUtils.h, BindingUtils.cpp, Codegen.py, Element.cpp, IDBFileRequest.cpp, IDBObjectStore.cpp, dom/workers/Navigator.cpp, WorkerPrivate.cpp, DeviceStorageRequestChild.cpp, Notification.cpp, nsGlobalWindow.cpp, MessagePort.cpp, nsJSEnvironment.cpp, Sandbox.cpp, XPCConvert.cpp, ExportHelpers.cpp, and DataStoreService.cpp. The rest of this diff was generated by running the following commands: find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObject\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(Binding(?:_workers)?::Wrap\((?:aCx|cx|aContext|aCtx|js), [^,)]+)\)/\1, aGivenProto)/g'
2015-03-19 17:13:33 +03:00
ServiceWorkerWindowClient::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
Bug 1117172 part 3. Change the wrappercached WrapObject methods to allow passing in aGivenProto. r=peterv The only manual changes here are to BindingUtils.h, BindingUtils.cpp, Codegen.py, Element.cpp, IDBFileRequest.cpp, IDBObjectStore.cpp, dom/workers/Navigator.cpp, WorkerPrivate.cpp, DeviceStorageRequestChild.cpp, Notification.cpp, nsGlobalWindow.cpp, MessagePort.cpp, nsJSEnvironment.cpp, Sandbox.cpp, XPCConvert.cpp, ExportHelpers.cpp, and DataStoreService.cpp. The rest of this diff was generated by running the following commands: find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObject\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g' find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(Binding(?:_workers)?::Wrap\((?:aCx|cx|aContext|aCtx|js), [^,)]+)\)/\1, aGivenProto)/g'
2015-03-19 17:13:33 +03:00
return WindowClientBinding::Wrap(aCx, this, aGivenProto);
}
namespace {
class ResolveOrRejectPromiseRunnable final : public WorkerRunnable
{
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<PromiseWorkerProxy> mPromiseProxy;
UniquePtr<ServiceWorkerClientInfo> mClientInfo;
nsresult mRv;
public:
// Passing a null clientInfo will resolve the promise with a null value.
ResolveOrRejectPromiseRunnable(
WorkerPrivate* aWorkerPrivate, PromiseWorkerProxy* aPromiseProxy,
UniquePtr<ServiceWorkerClientInfo>&& aClientInfo)
: WorkerRunnable(aWorkerPrivate)
, mPromiseProxy(aPromiseProxy)
, mClientInfo(Move(aClientInfo))
, mRv(NS_OK)
{
AssertIsOnMainThread();
}
// Reject the promise with passed nsresult.
ResolveOrRejectPromiseRunnable(WorkerPrivate* aWorkerPrivate,
PromiseWorkerProxy* aPromiseProxy,
nsresult aRv)
: WorkerRunnable(aWorkerPrivate)
, mPromiseProxy(aPromiseProxy)
, mClientInfo(nullptr)
, mRv(aRv)
{
MOZ_ASSERT(NS_FAILED(aRv));
AssertIsOnMainThread();
}
bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
{
MOZ_ASSERT(aWorkerPrivate);
aWorkerPrivate->AssertIsOnWorkerThread();
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<Promise> promise = mPromiseProxy->WorkerPromise();
MOZ_ASSERT(promise);
if (NS_WARN_IF(NS_FAILED(mRv))) {
promise->MaybeReject(mRv);
} else if (mClientInfo) {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<ServiceWorkerWindowClient> client =
new ServiceWorkerWindowClient(promise->GetParentObject(), *mClientInfo);
promise->MaybeResolve(client);
} else {
promise->MaybeResolve(JS::NullHandleValue);
}
// Release the reference on the worker thread.
mPromiseProxy->CleanUp();
return true;
}
};
class ClientFocusRunnable final : public Runnable
{
uint64_t mWindowId;
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<PromiseWorkerProxy> mPromiseProxy;
public:
ClientFocusRunnable(uint64_t aWindowId, PromiseWorkerProxy* aPromiseProxy)
: mWindowId(aWindowId)
, mPromiseProxy(aPromiseProxy)
{
MOZ_ASSERT(mPromiseProxy);
}
NS_IMETHOD
Run() override
{
AssertIsOnMainThread();
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowId);
UniquePtr<ServiceWorkerClientInfo> clientInfo;
if (window) {
nsCOMPtr<nsIDocument> doc = window->GetDocument();
if (doc) {
nsContentUtils::DispatchFocusChromeEvent(window->GetOuterWindow());
clientInfo.reset(new ServiceWorkerClientInfo(doc));
}
}
DispatchResult(Move(clientInfo));
return NS_OK;
}
private:
void
DispatchResult(UniquePtr<ServiceWorkerClientInfo>&& aClientInfo)
{
AssertIsOnMainThread();
MutexAutoLock lock(mPromiseProxy->Lock());
if (mPromiseProxy->CleanedUp()) {
return;
}
RefPtr<ResolveOrRejectPromiseRunnable> resolveRunnable;
if (aClientInfo) {
resolveRunnable = new ResolveOrRejectPromiseRunnable(
mPromiseProxy->GetWorkerPrivate(), mPromiseProxy, Move(aClientInfo));
} else {
resolveRunnable = new ResolveOrRejectPromiseRunnable(
mPromiseProxy->GetWorkerPrivate(), mPromiseProxy,
NS_ERROR_DOM_INVALID_ACCESS_ERR);
}
resolveRunnable->Dispatch();
}
};
} // namespace
already_AddRefed<Promise>
ServiceWorkerWindowClient::Focus(ErrorResult& aRv) const
{
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
MOZ_ASSERT(global);
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<Promise> promise = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
if (workerPrivate->GlobalScope()->WindowInteractionAllowed()) {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<PromiseWorkerProxy> promiseProxy =
PromiseWorkerProxy::Create(workerPrivate, promise);
if (promiseProxy) {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<ClientFocusRunnable> r = new ClientFocusRunnable(mWindowId,
promiseProxy);
MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
} else {
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
}
} else {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
}
return promise.forget();
}
class WebProgressListener final : public nsIWebProgressListener,
public nsSupportsWeakReference
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(WebProgressListener,
nsIWebProgressListener)
WebProgressListener(PromiseWorkerProxy* aPromiseProxy,
ServiceWorkerPrivate* aServiceWorkerPrivate,
nsPIDOMWindowOuter* aWindow, nsIURI* aBaseURI)
: mPromiseProxy(aPromiseProxy)
, mServiceWorkerPrivate(aServiceWorkerPrivate)
, mWindow(aWindow)
, mBaseURI(aBaseURI)
{
MOZ_ASSERT(aPromiseProxy);
MOZ_ASSERT(aServiceWorkerPrivate);
MOZ_ASSERT(aWindow);
MOZ_ASSERT(aWindow->IsOuterWindow());
MOZ_ASSERT(aBaseURI);
AssertIsOnMainThread();
mServiceWorkerPrivate->StoreISupports(static_cast<nsIWebProgressListener*>(this));
}
NS_IMETHOD
OnStateChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
uint32_t aStateFlags, nsresult aStatus) override
{
if (!(aStateFlags & STATE_IS_DOCUMENT) ||
!(aStateFlags & (STATE_STOP | STATE_TRANSFERRING))) {
return NS_OK;
}
// This is safe because our caller holds a strong ref.
mServiceWorkerPrivate->RemoveISupports(static_cast<nsIWebProgressListener*>(this));
aWebProgress->RemoveProgressListener(this);
WorkerPrivate* workerPrivate;
{
MutexAutoLock lock(mPromiseProxy->Lock());
if (mPromiseProxy->CleanedUp()) {
return NS_OK;
}
workerPrivate = mPromiseProxy->GetWorkerPrivate();
}
nsCOMPtr<nsIDocument> doc = mWindow->GetExtantDoc();
RefPtr<ResolveOrRejectPromiseRunnable> resolveRunnable;
UniquePtr<ServiceWorkerClientInfo> clientInfo;
if (!doc) {
resolveRunnable = new ResolveOrRejectPromiseRunnable(
workerPrivate, mPromiseProxy, NS_ERROR_TYPE_ERR);
resolveRunnable->Dispatch();
return NS_OK;
}
// Check same origin.
nsCOMPtr<nsIScriptSecurityManager> securityManager =
nsContentUtils::GetSecurityManager();
nsresult rv = securityManager->CheckSameOriginURI(doc->GetOriginalURI(),
mBaseURI, false);
if (NS_SUCCEEDED(rv)) {
nsContentUtils::DispatchFocusChromeEvent(mWindow->GetOuterWindow());
clientInfo.reset(new ServiceWorkerClientInfo(doc));
}
resolveRunnable = new ResolveOrRejectPromiseRunnable(
workerPrivate, mPromiseProxy, Move(clientInfo));
resolveRunnable->Dispatch();
return NS_OK;
}
NS_IMETHOD
OnProgressChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
int32_t aCurSelfProgress, int32_t aMaxSelfProgress,
int32_t aCurTotalProgress,
int32_t aMaxTotalProgress) override
{
MOZ_CRASH("Unexpected notification.");
return NS_OK;
}
NS_IMETHOD
OnLocationChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
nsIURI* aLocation, uint32_t aFlags) override
{
MOZ_CRASH("Unexpected notification.");
return NS_OK;
}
NS_IMETHOD
OnStatusChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
nsresult aStatus, const char16_t* aMessage) override
{
MOZ_CRASH("Unexpected notification.");
return NS_OK;
}
NS_IMETHOD
OnSecurityChange(nsIWebProgress* aWebProgress, nsIRequest* aRequest,
uint32_t aState) override
{
MOZ_CRASH("Unexpected notification.");
return NS_OK;
}
private:
~WebProgressListener() {}
RefPtr<PromiseWorkerProxy> mPromiseProxy;
RefPtr<ServiceWorkerPrivate> mServiceWorkerPrivate;
nsCOMPtr<nsPIDOMWindowOuter> mWindow;
nsCOMPtr<nsIURI> mBaseURI;
};
NS_IMPL_CYCLE_COLLECTING_ADDREF(WebProgressListener)
NS_IMPL_CYCLE_COLLECTING_RELEASE(WebProgressListener)
NS_IMPL_CYCLE_COLLECTION(WebProgressListener, mPromiseProxy,
mServiceWorkerPrivate, mWindow)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebProgressListener)
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END
class ClientNavigateRunnable final : public Runnable
{
uint64_t mWindowId;
nsString mUrl;
nsCString mBaseUrl;
nsString mScope;
RefPtr<PromiseWorkerProxy> mPromiseProxy;
MOZ_INIT_OUTSIDE_CTOR WorkerPrivate* mWorkerPrivate;
public:
ClientNavigateRunnable(uint64_t aWindowId, const nsAString& aUrl,
const nsAString& aScope,
PromiseWorkerProxy* aPromiseProxy)
: mWindowId(aWindowId)
, mUrl(aUrl)
, mScope(aScope)
, mPromiseProxy(aPromiseProxy)
, mWorkerPrivate(nullptr)
{
MOZ_ASSERT(aPromiseProxy);
MOZ_ASSERT(aPromiseProxy->GetWorkerPrivate());
aPromiseProxy->GetWorkerPrivate()->AssertIsOnWorkerThread();
}
NS_IMETHOD
Run() override
{
AssertIsOnMainThread();
nsCOMPtr<nsIPrincipal> principal;
{
MutexAutoLock lock(mPromiseProxy->Lock());
if (mPromiseProxy->CleanedUp()) {
return NS_OK;
}
mWorkerPrivate = mPromiseProxy->GetWorkerPrivate();
WorkerPrivate::LocationInfo& info = mWorkerPrivate->GetLocationInfo();
mBaseUrl = info.mHref;
principal = mWorkerPrivate->GetPrincipal();
MOZ_DIAGNOSTIC_ASSERT(principal);
}
nsCOMPtr<nsIURI> baseUrl;
nsCOMPtr<nsIURI> url;
nsresult rv = ParseUrl(getter_AddRefs(baseUrl), getter_AddRefs(url));
if (NS_WARN_IF(NS_FAILED(rv))) {
return RejectPromise(NS_ERROR_TYPE_ERR);
}
rv = principal->CheckMayLoad(url, true, false);
if (NS_WARN_IF(NS_FAILED(rv))) {
return RejectPromise(rv);
}
nsGlobalWindow* window;
rv = Navigate(url, principal, &window);
if (NS_WARN_IF(NS_FAILED(rv))) {
return RejectPromise(rv);
}
nsCOMPtr<nsIDocShell> docShell = window->GetDocShell();
nsCOMPtr<nsIWebProgress> webProgress = do_GetInterface(docShell);
if (NS_WARN_IF(!webProgress)) {
return NS_ERROR_FAILURE;
}
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
if (!swm) {
return NS_ERROR_FAILURE;
}
RefPtr<ServiceWorkerRegistrationInfo> registration =
swm->GetRegistration(principal, NS_ConvertUTF16toUTF8(mScope));
if (NS_WARN_IF(!registration)) {
return NS_ERROR_FAILURE;
}
RefPtr<ServiceWorkerInfo> serviceWorkerInfo =
registration->GetServiceWorkerInfoById(mWorkerPrivate->ServiceWorkerID());
if (NS_WARN_IF(!serviceWorkerInfo)) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIWebProgressListener> listener =
new WebProgressListener(mPromiseProxy, serviceWorkerInfo->WorkerPrivate(),
window->GetOuterWindow(), baseUrl);
rv = webProgress->AddProgressListener(
listener, nsIWebProgress::NOTIFY_STATE_DOCUMENT);
if (NS_WARN_IF(NS_FAILED(rv))) {
return RejectPromise(rv);
}
return NS_OK;
}
private:
nsresult
RejectPromise(nsresult aRv)
{
MOZ_ASSERT(mWorkerPrivate);
RefPtr<ResolveOrRejectPromiseRunnable> resolveRunnable =
new ResolveOrRejectPromiseRunnable(mWorkerPrivate, mPromiseProxy, aRv);
resolveRunnable->Dispatch();
return NS_OK;
}
nsresult
ResolvePromise(UniquePtr<ServiceWorkerClientInfo>&& aClientInfo)
{
MOZ_ASSERT(mWorkerPrivate);
RefPtr<ResolveOrRejectPromiseRunnable> resolveRunnable =
new ResolveOrRejectPromiseRunnable(mWorkerPrivate, mPromiseProxy,
Move(aClientInfo));
resolveRunnable->Dispatch();
return NS_OK;
}
nsresult
ParseUrl(nsIURI** aBaseUrl, nsIURI** aUrl)
{
MOZ_ASSERT(aBaseUrl);
MOZ_ASSERT(aUrl);
AssertIsOnMainThread();
nsCOMPtr<nsIURI> baseUrl;
nsresult rv = NS_NewURI(getter_AddRefs(baseUrl), mBaseUrl);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> url;
rv = NS_NewURI(getter_AddRefs(url), mUrl, nullptr, baseUrl);
NS_ENSURE_SUCCESS(rv, rv);
baseUrl.forget(aBaseUrl);
url.forget(aUrl);
return NS_OK;
}
nsresult
Navigate(nsIURI* aUrl, nsIPrincipal* aPrincipal, nsGlobalWindow** aWindow)
{
MOZ_ASSERT(aWindow);
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(mWindowId);
if (NS_WARN_IF(!window)) {
return NS_ERROR_TYPE_ERR;
}
nsCOMPtr<nsIDocument> doc = window->GetDocument();
if (NS_WARN_IF(!doc)) {
return NS_ERROR_TYPE_ERR;
}
if (NS_WARN_IF(!doc->IsActive())) {
return NS_ERROR_TYPE_ERR;
}
nsCOMPtr<nsIDocShell> docShell = window->GetDocShell();
if (NS_WARN_IF(!docShell)) {
return NS_ERROR_TYPE_ERR;
}
nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
nsresult rv = docShell->CreateLoadInfo(getter_AddRefs(loadInfo));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
loadInfo->SetTriggeringPrincipal(aPrincipal);
loadInfo->SetReferrer(doc->GetOriginalURI());
loadInfo->SetReferrerPolicy(doc->GetReferrerPolicy());
loadInfo->SetLoadType(nsIDocShellLoadInfo::loadStopContentAndReplace);
loadInfo->SetSourceDocShell(docShell);
rv =
docShell->LoadURI(aUrl, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, true);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
*aWindow = window;
return NS_OK;
}
};
already_AddRefed<Promise>
ServiceWorkerWindowClient::Navigate(const nsAString& aUrl, ErrorResult& aRv)
{
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
MOZ_ASSERT(workerPrivate);
workerPrivate->AssertIsOnWorkerThread();
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
MOZ_ASSERT(global);
RefPtr<Promise> promise = Promise::Create(global, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
if (aUrl.EqualsLiteral("about:blank")) {
promise->MaybeReject(NS_ERROR_TYPE_ERR);
return promise.forget();
}
ServiceWorkerGlobalScope* globalScope =
static_cast<ServiceWorkerGlobalScope*>(workerPrivate->GlobalScope());
nsString scope;
globalScope->GetScope(scope);
RefPtr<PromiseWorkerProxy> promiseProxy =
PromiseWorkerProxy::Create(workerPrivate, promise);
if (promiseProxy) {
RefPtr<ClientNavigateRunnable> r =
new ClientNavigateRunnable(mWindowId, aUrl, scope, promiseProxy);
MOZ_ALWAYS_SUCCEEDS(workerPrivate->DispatchToMainThread(r.forget()));
} else {
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
}
return promise.forget();
}