dom/devicestorage/DeviceStorageAreaListener.cpp
author Nathan Froyd <froydnj@mozilla.com>
Wed, 07 Oct 2015 16:50:25 -0400
changeset 266617 91d4539e00cecb658604e021675a923c60ef3235
parent 249355 15f9071b4551df9963adc8613de127f5915c58a9
child 266639 41dea9df27ed995f8315ab4318c187a617937664
permissions -rwxr-xr-x
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. # 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

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/DeviceStorageAreaListener.h"
#include "mozilla/dom/DeviceStorageAreaListenerBinding.h"
#include "mozilla/Attributes.h"
#include "mozilla/Services.h"
#include "DeviceStorage.h"
#include "nsIObserverService.h"
#ifdef MOZ_WIDGET_GONK
#include "nsIVolume.h"
#include "nsIVolumeService.h"
#endif

namespace mozilla {
namespace dom {

class VolumeStateObserver final : public nsIObserver
{
public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIOBSERVER

  explicit VolumeStateObserver(DeviceStorageAreaListener* aListener)
    : mDeviceStorageAreaListener(aListener) {}
  void ForgetListener() { mDeviceStorageAreaListener = nullptr; }

private:
  ~VolumeStateObserver() {};

  // This reference is non-owning and it's cleared by
  // DeviceStorageAreaListener's destructor.
  DeviceStorageAreaListener* MOZ_NON_OWNING_REF mDeviceStorageAreaListener;
};

NS_IMPL_ISUPPORTS(VolumeStateObserver, nsIObserver)

NS_IMETHODIMP
VolumeStateObserver::Observe(nsISupports *aSubject,
                             const char *aTopic,
                             const char16_t *aData)
{
  if (!mDeviceStorageAreaListener) {
    return NS_OK;
  }

#ifdef MOZ_WIDGET_GONK
  if (!strcmp(aTopic, NS_VOLUME_STATE_CHANGED)) {
    nsCOMPtr<nsIVolume> vol = do_QueryInterface(aSubject);
    MOZ_ASSERT(vol);

    int32_t state;
    nsresult rv = vol->GetState(&state);
    NS_ENSURE_SUCCESS(rv, rv);

    nsString volName;
    vol->GetName(volName);

    switch (state) {
      case nsIVolume::STATE_MOUNTED:
        mDeviceStorageAreaListener->DispatchStorageAreaChangedEvent(
          volName,
          DeviceStorageAreaChangedEventOperation::Added);
        break;
      default:
        mDeviceStorageAreaListener->DispatchStorageAreaChangedEvent(
          volName,
          DeviceStorageAreaChangedEventOperation::Removed);
        break;
    }
  }
#endif
  return NS_OK;
}

NS_IMPL_ADDREF_INHERITED(DeviceStorageAreaListener, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(DeviceStorageAreaListener, DOMEventTargetHelper)

NS_INTERFACE_MAP_BEGIN(DeviceStorageAreaListener)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)

DeviceStorageAreaListener::DeviceStorageAreaListener(nsPIDOMWindow* aWindow)
  : DOMEventTargetHelper(aWindow)
{
  MOZ_ASSERT(aWindow);

  MOZ_ASSERT(NS_IsMainThread());

  mVolumeStateObserver = new VolumeStateObserver(this);
#ifdef MOZ_WIDGET_GONK
  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
  if (obs) {
    obs->AddObserver(mVolumeStateObserver, NS_VOLUME_STATE_CHANGED, false);
  }
#endif
}

DeviceStorageAreaListener::~DeviceStorageAreaListener()
{
#ifdef MOZ_WIDGET_GONK
  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
  if (obs) {
    obs->RemoveObserver(mVolumeStateObserver, NS_VOLUME_STATE_CHANGED);
  }
#endif
  mVolumeStateObserver->ForgetListener();
}

JSObject*
DeviceStorageAreaListener::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
  return DeviceStorageAreaListenerBinding::Wrap(aCx, this, aGivenProto);
}

void
DeviceStorageAreaListener::DispatchStorageAreaChangedEvent(
  const nsString& aStorageName,
  DeviceStorageAreaChangedEventOperation aOperation)
{
  StateMapType::const_iterator iter = mStorageAreaStateMap.find(aStorageName);
  if (iter == mStorageAreaStateMap.end() &&
      aOperation != DeviceStorageAreaChangedEventOperation::Added) {
    // The operation of the first event to dispatch should be "Added".
    return;
  }
  if (iter != mStorageAreaStateMap.end() &&
      iter->second == aOperation) {
    // No need to disptach the event if the state is unchanged.
    return;
  }

  DeviceStorageAreaChangedEventInit init;
  init.mOperation = aOperation;
  init.mStorageName = aStorageName;

  RefPtr<DeviceStorageAreaChangedEvent> event =
    DeviceStorageAreaChangedEvent::Constructor(this,
                                               NS_LITERAL_STRING("storageareachanged"),
                                               init);
  event->SetTrusted(true);

  mStorageAreaStateMap[aStorageName] = aOperation;

  nsDOMDeviceStorage::InvalidateVolumeCaches();

  bool ignore;
  DOMEventTargetHelper::DispatchEvent(event, &ignore);
}

} // namespace dom
} // namespace mozilla