mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-09-10 11:54:40 +00:00
155 lines
4.4 KiB
C++
155 lines
4.4 KiB
C++
|
/* -*- 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
|