mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
1c5959ee6e
- Bug 1125750 - Check the overflow region direction to avoid unnecesary reflow for scrollable frame. (6b5067631) - Bug 1125750 - Add auto test to detect error when using mOuter to check overflow area of a scrollable frame. (4e9c43e31) - override -> MOZ_OVERRIDE (ed1ecc151) - Bug 990907 - Don't add text-overflow markers while being actively scrolled by APZ. (523bc5a3e) - Bug 945584: Part 6 - Implementation of scroll snapping (v10 Patch) (bf64eb0f3) - Bug 945584: Part 7 - Implement Scroll Snapping for Autoscroll, - Triggering scroll snapping at the end of an autoscroll. - This enables text selection to be unencumbered by scroll snapping, while restoring the scroll position to a valid snapping position when the drag operation is completed. (db9ce9811) - Bug 945584: Part 8 - Implement Scroll Snapping for Middle Mouse Button Scrolls (v2 Patch) (06d1b733d) - some MacOS 10.5 Leopard support (6a37f6745) - Bug 945584: Part 9 - Tests for scroll snapping (v4 Patch) (f67175387) - Bug 1102427 - Ensure scroll parents of an active scrollframe are layerized. (910d43ec5) - Bug 1142731 followup. Check isInterpreted() before we call environment(), because of the asmjs lambdas. (29b2acdc7) - Bug 1161627 - part 1 - add move constructor and assignment operator for already_AddRefed&& to RefPtr; This change is prep work for future mass rewriting. (98416d45c) - Bug 1161627 - part 2 - machine-convert TemporaryRef<T> to already_AddRefed<T>; (336e96af7) - Bug 1161627 - part 3 - remove TemporaryRef<T> from RefPtr.h (6c3acdaed) - Bug 940273 - Part 3 - Service Worker Cache webidl. (4b6803d0a) - Bug 940273 - Part 4 - Initial implementation of Service Worker Cache. (74498c108) - Bug 1133861 - Bustage fix. (4a81437c2)
451 lines
13 KiB
C++
451 lines
13 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 "mozilla/dom/cache/CacheStorageParent.h"
|
|
|
|
#include "mozilla/dom/ContentParent.h"
|
|
#include "mozilla/dom/cache/ActorUtils.h"
|
|
#include "mozilla/dom/cache/AutoUtils.h"
|
|
#include "mozilla/dom/cache/CacheParent.h"
|
|
#include "mozilla/dom/cache/CacheStreamControlParent.h"
|
|
#include "mozilla/dom/cache/Manager.h"
|
|
#include "mozilla/dom/cache/ManagerId.h"
|
|
#include "mozilla/dom/cache/ReadStream.h"
|
|
#include "mozilla/dom/cache/SavedTypes.h"
|
|
#include "mozilla/dom/cache/StreamList.h"
|
|
#include "mozilla/ipc/PBackgroundParent.h"
|
|
#include "mozilla/ipc/InputStreamUtils.h"
|
|
#include "mozilla/ipc/PFileDescriptorSetParent.h"
|
|
#include "mozilla/DebugOnly.h"
|
|
#include "nsCOMPtr.h"
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
namespace cache {
|
|
|
|
using mozilla::ipc::PBackgroundParent;
|
|
using mozilla::ipc::PFileDescriptorSetParent;
|
|
using mozilla::ipc::PrincipalInfo;
|
|
|
|
// declared in ActorUtils.h
|
|
PCacheStorageParent*
|
|
AllocPCacheStorageParent(PBackgroundParent* aManagingActor,
|
|
Namespace aNamespace,
|
|
const mozilla::ipc::PrincipalInfo& aPrincipalInfo)
|
|
{
|
|
return new CacheStorageParent(aManagingActor, aNamespace, aPrincipalInfo);
|
|
}
|
|
|
|
// declared in ActorUtils.h
|
|
void
|
|
DeallocPCacheStorageParent(PCacheStorageParent* aActor)
|
|
{
|
|
delete aActor;
|
|
}
|
|
|
|
CacheStorageParent::CacheStorageParent(PBackgroundParent* aManagingActor,
|
|
Namespace aNamespace,
|
|
const PrincipalInfo& aPrincipalInfo)
|
|
: mNamespace(aNamespace)
|
|
, mVerifiedStatus(NS_OK)
|
|
{
|
|
MOZ_COUNT_CTOR(cache::CacheStorageParent);
|
|
MOZ_ASSERT(aManagingActor);
|
|
|
|
// Start the async principal verification process immediately.
|
|
mVerifier = PrincipalVerifier::CreateAndDispatch(this, aManagingActor,
|
|
aPrincipalInfo);
|
|
MOZ_ASSERT(mVerifier);
|
|
}
|
|
|
|
CacheStorageParent::~CacheStorageParent()
|
|
{
|
|
MOZ_COUNT_DTOR(cache::CacheStorageParent);
|
|
MOZ_ASSERT(!mVerifier);
|
|
MOZ_ASSERT(!mManager);
|
|
}
|
|
|
|
void
|
|
CacheStorageParent::ActorDestroy(ActorDestroyReason aReason)
|
|
{
|
|
if (mVerifier) {
|
|
mVerifier->ClearListener();
|
|
mVerifier = nullptr;
|
|
}
|
|
|
|
if (mManager) {
|
|
MOZ_ASSERT(!mActiveRequests.IsEmpty());
|
|
mManager->RemoveListener(this);
|
|
mManager = nullptr;
|
|
}
|
|
}
|
|
|
|
bool
|
|
CacheStorageParent::RecvTeardown()
|
|
{
|
|
if (!Send__delete__(this)) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to delete actor.");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
CacheStorageParent::RecvMatch(const RequestId& aRequestId,
|
|
const PCacheRequest& aRequest,
|
|
const PCacheQueryParams& aParams)
|
|
{
|
|
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
|
if (!SendMatchResponse(aRequestId, mVerifiedStatus, void_t())) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Match response.");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// queue requests if we are still waiting for principal verification
|
|
if (!mManagerId) {
|
|
Entry* entry = mPendingRequests.AppendElement();
|
|
entry->mOp = OP_MATCH;
|
|
entry->mRequestId = aRequestId;
|
|
entry->mRequest = aRequest;
|
|
entry->mParams = aParams;
|
|
return true;
|
|
}
|
|
|
|
nsRefPtr<cache::Manager> manager;
|
|
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
if (!SendMatchResponse(aRequestId, rv, void_t())) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Match response.");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
manager->StorageMatch(this, aRequestId, mNamespace, aRequest,
|
|
aParams);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
CacheStorageParent::RecvHas(const RequestId& aRequestId, const nsString& aKey)
|
|
{
|
|
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
|
if (!SendHasResponse(aRequestId, mVerifiedStatus, false)) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Has response.");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// queue requests if we are still waiting for principal verification
|
|
if (!mManagerId) {
|
|
Entry* entry = mPendingRequests.AppendElement();
|
|
entry->mOp = OP_HAS;
|
|
entry->mRequestId = aRequestId;
|
|
entry->mKey = aKey;
|
|
return true;
|
|
}
|
|
|
|
nsRefPtr<cache::Manager> manager;
|
|
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
if (!SendHasResponse(aRequestId, rv, false)) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Has response.");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
manager->StorageHas(this, aRequestId, mNamespace, aKey);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
CacheStorageParent::RecvOpen(const RequestId& aRequestId, const nsString& aKey)
|
|
{
|
|
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
|
if (!SendOpenResponse(aRequestId, mVerifiedStatus, nullptr)) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Open response.");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// queue requests if we are still waiting for principal verification
|
|
if (!mManagerId) {
|
|
Entry* entry = mPendingRequests.AppendElement();
|
|
entry->mOp = OP_OPEN;
|
|
entry->mRequestId = aRequestId;
|
|
entry->mKey = aKey;
|
|
return true;
|
|
}
|
|
|
|
nsRefPtr<cache::Manager> manager;
|
|
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
if (!SendOpenResponse(aRequestId, rv, nullptr)) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Open response.");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
manager->StorageOpen(this, aRequestId, mNamespace, aKey);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
CacheStorageParent::RecvDelete(const RequestId& aRequestId,
|
|
const nsString& aKey)
|
|
{
|
|
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
|
if (!SendDeleteResponse(aRequestId, mVerifiedStatus, false)) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Delete response.");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// queue requests if we are still waiting for principal verification
|
|
if (!mManagerId) {
|
|
Entry* entry = mPendingRequests.AppendElement();
|
|
entry->mOp = OP_DELETE;
|
|
entry->mRequestId = aRequestId;
|
|
entry->mKey = aKey;
|
|
return true;
|
|
}
|
|
|
|
nsRefPtr<cache::Manager> manager;
|
|
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
if (!SendDeleteResponse(aRequestId, rv, false)) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Delete response.");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
manager->StorageDelete(this, aRequestId, mNamespace, aKey);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
CacheStorageParent::RecvKeys(const RequestId& aRequestId)
|
|
{
|
|
if (NS_WARN_IF(NS_FAILED(mVerifiedStatus))) {
|
|
if (!SendKeysResponse(aRequestId, mVerifiedStatus, nsTArray<nsString>())) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Keys response.");
|
|
}
|
|
}
|
|
|
|
// queue requests if we are still waiting for principal verification
|
|
if (!mManagerId) {
|
|
Entry* entry = mPendingRequests.AppendElement();
|
|
entry->mOp = OP_DELETE;
|
|
entry->mRequestId = aRequestId;
|
|
return true;
|
|
}
|
|
|
|
nsRefPtr<cache::Manager> manager;
|
|
nsresult rv = RequestManager(aRequestId, getter_AddRefs(manager));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
if (!SendKeysResponse(aRequestId, rv, nsTArray<nsString>())) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Keys response.");
|
|
}
|
|
return true;
|
|
}
|
|
|
|
manager->StorageKeys(this, aRequestId, mNamespace);
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
CacheStorageParent::OnPrincipalVerified(nsresult aRv, ManagerId* aManagerId)
|
|
{
|
|
MOZ_ASSERT(mVerifier);
|
|
MOZ_ASSERT(!mManagerId);
|
|
MOZ_ASSERT(!mManager);
|
|
MOZ_ASSERT(NS_SUCCEEDED(mVerifiedStatus));
|
|
|
|
if (NS_WARN_IF(NS_FAILED(aRv))) {
|
|
mVerifiedStatus = aRv;
|
|
}
|
|
|
|
mManagerId = aManagerId;
|
|
mVerifier->ClearListener();
|
|
mVerifier = nullptr;
|
|
|
|
RetryPendingRequests();
|
|
}
|
|
|
|
void
|
|
CacheStorageParent::OnStorageMatch(RequestId aRequestId, nsresult aRv,
|
|
const SavedResponse* aSavedResponse,
|
|
StreamList* aStreamList)
|
|
{
|
|
PCacheResponseOrVoid responseOrVoid;
|
|
|
|
ReleaseManager(aRequestId);
|
|
|
|
AutoParentResponseOrVoid response(Manager());
|
|
|
|
// no match
|
|
if (NS_FAILED(aRv) || !aSavedResponse) {
|
|
if (!SendMatchResponse(aRequestId, aRv, response.SendAsResponseOrVoid())) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Match response.");
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (aSavedResponse) {
|
|
response.Add(*aSavedResponse, aStreamList);
|
|
}
|
|
|
|
if (!SendMatchResponse(aRequestId, aRv, response.SendAsResponseOrVoid())) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Match response.");
|
|
}
|
|
}
|
|
|
|
void
|
|
CacheStorageParent::OnStorageHas(RequestId aRequestId, nsresult aRv,
|
|
bool aCacheFound)
|
|
{
|
|
ReleaseManager(aRequestId);
|
|
if (!SendHasResponse(aRequestId, aRv, aCacheFound)) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Has response.");
|
|
}
|
|
}
|
|
|
|
void
|
|
CacheStorageParent::OnStorageOpen(RequestId aRequestId, nsresult aRv,
|
|
CacheId aCacheId)
|
|
{
|
|
if (NS_FAILED(aRv)) {
|
|
ReleaseManager(aRequestId);
|
|
if (!SendOpenResponse(aRequestId, aRv, nullptr)) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Open response.");
|
|
}
|
|
return;
|
|
}
|
|
|
|
MOZ_ASSERT(mManager);
|
|
CacheParent* actor = new CacheParent(mManager, aCacheId);
|
|
|
|
ReleaseManager(aRequestId);
|
|
|
|
PCacheParent* base = Manager()->SendPCacheConstructor(actor);
|
|
actor = static_cast<CacheParent*>(base);
|
|
if (!SendOpenResponse(aRequestId, aRv, actor)) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Open response.");
|
|
}
|
|
}
|
|
|
|
void
|
|
CacheStorageParent::OnStorageDelete(RequestId aRequestId, nsresult aRv,
|
|
bool aCacheDeleted)
|
|
{
|
|
ReleaseManager(aRequestId);
|
|
if (!SendDeleteResponse(aRequestId, aRv, aCacheDeleted)) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Delete response.");
|
|
}
|
|
}
|
|
|
|
void
|
|
CacheStorageParent::OnStorageKeys(RequestId aRequestId, nsresult aRv,
|
|
const nsTArray<nsString>& aKeys)
|
|
{
|
|
ReleaseManager(aRequestId);
|
|
if (!SendKeysResponse(aRequestId, aRv, aKeys)) {
|
|
// child process is gone, warn and allow actor to clean up normally
|
|
NS_WARNING("CacheStorage failed to send Keys response.");
|
|
}
|
|
}
|
|
|
|
void
|
|
CacheStorageParent::RetryPendingRequests()
|
|
{
|
|
MOZ_ASSERT(mManagerId || NS_FAILED(mVerifiedStatus));
|
|
for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) {
|
|
const Entry& entry = mPendingRequests[i];
|
|
switch(entry.mOp) {
|
|
case OP_MATCH:
|
|
RecvMatch(entry.mRequestId, entry.mRequest, entry.mParams);
|
|
break;
|
|
case OP_HAS:
|
|
RecvHas(entry.mRequestId, entry.mKey);
|
|
break;
|
|
case OP_OPEN:
|
|
RecvOpen(entry.mRequestId, entry.mKey);
|
|
break;
|
|
case OP_DELETE:
|
|
RecvDelete(entry.mRequestId, entry.mKey);
|
|
break;
|
|
case OP_KEYS:
|
|
RecvKeys(entry.mRequestId);
|
|
break;
|
|
default:
|
|
MOZ_ASSERT_UNREACHABLE("Pending request within unknown op");
|
|
}
|
|
}
|
|
mPendingRequests.Clear();
|
|
mPendingRequests.Compact();
|
|
}
|
|
|
|
nsresult
|
|
CacheStorageParent::RequestManager(RequestId aRequestId,
|
|
cache::Manager** aManagerOut)
|
|
{
|
|
MOZ_ASSERT(!mActiveRequests.Contains(aRequestId));
|
|
nsRefPtr<cache::Manager> ref = mManager;
|
|
if (!ref) {
|
|
MOZ_ASSERT(mActiveRequests.IsEmpty());
|
|
nsresult rv = cache::Manager::GetOrCreate(mManagerId, getter_AddRefs(ref));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
|
mManager = ref;
|
|
}
|
|
mActiveRequests.AppendElement(aRequestId);
|
|
ref.forget(aManagerOut);
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
CacheStorageParent::ReleaseManager(RequestId aRequestId)
|
|
{
|
|
// Note that if the child process dies we also clean up the mManager in
|
|
// ActorDestroy(). There is no race with this method, however, because
|
|
// ActorDestroy removes this object from the Manager's listener list.
|
|
// Therefore ReleaseManager() should never be called after ActorDestroy()
|
|
// runs.
|
|
MOZ_ASSERT(mManager);
|
|
MOZ_ASSERT(!mActiveRequests.IsEmpty());
|
|
|
|
MOZ_ALWAYS_TRUE(mActiveRequests.RemoveElement(aRequestId));
|
|
|
|
if (mActiveRequests.IsEmpty()) {
|
|
mManager->RemoveListener(this);
|
|
mManager = nullptr;
|
|
}
|
|
}
|
|
|
|
} // namespace cache
|
|
} // namespace dom
|
|
} // namespace mozilla
|