dom/broadcastchannel/BroadcastChannelService.cpp
author Nick Alexander <nalexander@mozilla.com>
Thu, 10 Dec 2015 10:51:42 -0500
changeset 310200 9bf656e590828c353452477c1553a98b0385eb53
parent 301570 e8c7dfe727cd970e2c3294934e2927b14143c205
child 337619 0659c92351361c56f819387c4add61eec96579e4
permissions -rw-r--r--
Bug 1231667 - Set Android SDK directory in topsrcdir Gradle configuration. r=me f=mcomella

/* -*- 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 "BroadcastChannelService.h"
#include "BroadcastChannelParent.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/ipc/BackgroundParent.h"

#ifdef XP_WIN
#undef PostMessage
#endif

namespace mozilla {

using namespace ipc;

namespace dom {

namespace {

BroadcastChannelService* sInstance = nullptr;

} // namespace

BroadcastChannelService::BroadcastChannelService()
{
  AssertIsOnBackgroundThread();

  // sInstance is a raw BroadcastChannelService*.
  MOZ_ASSERT(!sInstance);
  sInstance = this;
}

BroadcastChannelService::~BroadcastChannelService()
{
  AssertIsOnBackgroundThread();
  MOZ_ASSERT(sInstance == this);
  MOZ_ASSERT(mAgents.Count() == 0);

  sInstance = nullptr;
}

// static
already_AddRefed<BroadcastChannelService>
BroadcastChannelService::GetOrCreate()
{
  AssertIsOnBackgroundThread();

  RefPtr<BroadcastChannelService> instance = sInstance;
  if (!instance) {
    instance = new BroadcastChannelService();
  }
  return instance.forget();
}

void
BroadcastChannelService::RegisterActor(BroadcastChannelParent* aParent)
{
  AssertIsOnBackgroundThread();
  MOZ_ASSERT(aParent);
  MOZ_ASSERT(!mAgents.Contains(aParent));

  mAgents.PutEntry(aParent);
}

void
BroadcastChannelService::UnregisterActor(BroadcastChannelParent* aParent)
{
  AssertIsOnBackgroundThread();
  MOZ_ASSERT(aParent);
  MOZ_ASSERT(mAgents.Contains(aParent));

  mAgents.RemoveEntry(aParent);
}

void
BroadcastChannelService::PostMessage(BroadcastChannelParent* aParent,
                                     const ClonedMessageData& aData,
                                     const nsACString& aOrigin,
                                     const nsAString& aChannel,
                                     bool aPrivateBrowsing)
{
  AssertIsOnBackgroundThread();
  MOZ_ASSERT(aParent);
  MOZ_ASSERT(mAgents.Contains(aParent));

  // We need to keep the array alive for the life-time of this operation.
  nsTArray<RefPtr<BlobImpl>> blobs;
  if (!aData.blobsParent().IsEmpty()) {
    blobs.SetCapacity(aData.blobsParent().Length());

    for (uint32_t i = 0, len = aData.blobsParent().Length(); i < len; ++i) {
      RefPtr<BlobImpl> impl =
        static_cast<BlobParent*>(aData.blobsParent()[i])->GetBlobImpl();
     MOZ_ASSERT(impl);
     blobs.AppendElement(impl);
    }
  }

  for (auto iter = mAgents.Iter(); !iter.Done(); iter.Next()) {
    BroadcastChannelParent* parent = iter.Get()->GetKey();
    MOZ_ASSERT(parent);

    if (parent != aParent) {
      parent->CheckAndDeliver(aData, PromiseFlatCString(aOrigin),
                              PromiseFlatString(aChannel), aPrivateBrowsing);
    }
  }
}

} // namespace dom
} // namespace mozilla