mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 763976 - Add onchange notifications to DeviceStorage - IPC - r=khuey
This commit is contained in:
parent
0cc5c1e0ee
commit
7f0d522454
@ -7,18 +7,21 @@
|
||||
|
||||
#include "nsIDOMDeviceStorage.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
|
||||
class nsDOMDeviceStorage MOZ_FINAL
|
||||
: public nsIDOMDeviceStorage
|
||||
, public nsIFileUpdateListener
|
||||
, public nsDOMEventTargetHelper
|
||||
, public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMDEVICESTORAGE
|
||||
|
||||
NS_DECL_NSIFILEUPDATELISTENER
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSIDOMEVENTTARGET
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMDeviceStorage, nsDOMEventTargetHelper)
|
||||
NS_DECL_EVENT_HANDLER(change)
|
||||
|
@ -1216,10 +1216,21 @@ public:
|
||||
|
||||
case DEVICE_STORAGE_REQUEST_WATCH:
|
||||
{
|
||||
if (!mDeviceStorage->mIsWatchingFile) {
|
||||
mFile->mFile->Watch(mDeviceStorage);
|
||||
mDeviceStorage->mIsWatchingFile = true;
|
||||
}
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
nsString fullpath;
|
||||
mFile->mFile->GetPath(fullpath);
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
obs->AddObserver(mDeviceStorage, "file-watcher-update", false);
|
||||
ContentChild::GetSingleton()->SendAddFileWatch(fullpath);
|
||||
} else {
|
||||
if (!mDeviceStorage->mIsWatchingFile) {
|
||||
|
||||
//TODO
|
||||
|
||||
mFile->mFile->Watch(mDeviceStorage);
|
||||
mDeviceStorage->mIsWatchingFile = true;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
@ -1301,6 +1312,7 @@ DOMCI_DATA(DeviceStorage, nsDOMDeviceStorage)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMDeviceStorage)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMDeviceStorage)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFileUpdateListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DeviceStorage)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||
|
||||
@ -1345,7 +1357,17 @@ nsDOMDeviceStorage::Shutdown()
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
if (mIsWatchingFile) {
|
||||
mFile->Unwatch(this);
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
obs->RemoveObserver(this, "file-watcher-update");
|
||||
|
||||
nsString fullpath;
|
||||
mFile->GetPath(fullpath);
|
||||
ContentChild::GetSingleton()->SendRemoveFileWatch(fullpath);
|
||||
}
|
||||
else {
|
||||
mFile->Unwatch(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1633,6 +1655,42 @@ nsDOMDeviceStorage::EnumerateInternal(const JS::Value & aName,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDeviceStorage::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
|
||||
{
|
||||
// data strings will have the format of
|
||||
// reason:path
|
||||
nsDependentString data(aData);
|
||||
|
||||
nsAString::const_iterator start, end;
|
||||
nsAString::const_iterator colon;
|
||||
|
||||
data.BeginReading(start);
|
||||
data.EndReading(end);
|
||||
colon = end;
|
||||
|
||||
nsString reason;
|
||||
nsString filepath;
|
||||
if (!FindInReadable(NS_LITERAL_STRING(":"), start, colon)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
filepath = Substring(colon, end);
|
||||
data.BeginReading(start);
|
||||
reason = Substring(start, --colon);
|
||||
|
||||
nsCOMPtr<nsIFile> f;
|
||||
NS_NewLocalFile(filepath, false, getter_AddRefs(f));
|
||||
|
||||
nsCString creason;
|
||||
creason.AssignWithConversion(reason);
|
||||
CopyUTF16toUTF8(reason, creason);
|
||||
|
||||
Update(creason.get(), f);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDeviceStorage::Update(const char* aReason, nsIFile* aFile)
|
||||
{
|
||||
@ -1709,7 +1767,16 @@ nsDOMDeviceStorage::RemoveEventListener(const nsAString & aType,
|
||||
nsDOMEventTargetHelper::RemoveEventListener(aType, aListener, false);
|
||||
|
||||
if (mIsWatchingFile && !HasListenersFor(NS_LITERAL_STRING("change"))) {
|
||||
mFile->Unwatch(this);
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
obs->RemoveObserver(this, "file-watcher-update");
|
||||
|
||||
nsString fullpath;
|
||||
mFile->GetPath(fullpath);
|
||||
ContentChild::GetSingleton()->SendRemoveFileWatch(fullpath);
|
||||
} else {
|
||||
mFile->Unwatch(this);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -911,5 +911,20 @@ ContentChild::RecvLastPrivateDocShellDestroyed()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvFilePathUpdate(const nsString& path, const nsCString& aReason)
|
||||
{
|
||||
// data strings will have the format of
|
||||
// reason:path
|
||||
nsString data;
|
||||
CopyASCIItoUTF16(aReason, data);
|
||||
data.Append(NS_LITERAL_STRING(":"));
|
||||
data.Append(path);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
obs->NotifyObservers(nullptr, "file-watcher-update", data.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
} // namespace mozilla
|
||||
|
@ -162,6 +162,8 @@ public:
|
||||
|
||||
virtual bool RecvLastPrivateDocShellDestroyed();
|
||||
|
||||
virtual bool RecvFilePathUpdate(const nsString& path, const nsCString& reason);
|
||||
|
||||
#ifdef ANDROID
|
||||
gfxIntSize GetScreenSize() { return mScreenSize; }
|
||||
#endif
|
||||
|
@ -528,6 +528,8 @@ ContentParent::ContentParent(const nsAString& aAppManifestURL)
|
||||
//Sending all information to content process
|
||||
unused << SendAppInfo(version, buildID);
|
||||
}
|
||||
|
||||
mFileWatchers.Init();
|
||||
}
|
||||
|
||||
ContentParent::~ContentParent()
|
||||
@ -764,6 +766,9 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
const PRUnichar* aData)
|
||||
{
|
||||
if (!strcmp(aTopic, "xpcom-shutdown") && mSubprocess) {
|
||||
|
||||
mFileWatchers.Clear();
|
||||
|
||||
Close();
|
||||
NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
|
||||
}
|
||||
@ -1507,5 +1512,64 @@ ContentParent::RecvPrivateDocShellsExist(const bool& aExist)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvAddFileWatch(const nsString& root)
|
||||
{
|
||||
nsRefPtr<WatchedFile> f;
|
||||
if (mFileWatchers.Get(root, getter_AddRefs(f))) {
|
||||
f->mUsageCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
f = new WatchedFile(this, root);
|
||||
mFileWatchers.Put(root, f);
|
||||
|
||||
f->Watch();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvRemoveFileWatch(const nsString& root)
|
||||
{
|
||||
nsRefPtr<WatchedFile> f;
|
||||
bool result = mFileWatchers.Get(root, getter_AddRefs(f));
|
||||
if (!result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!f)
|
||||
return true;
|
||||
|
||||
f->mUsageCount--;
|
||||
|
||||
if (f->mUsageCount > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
f->Unwatch();
|
||||
mFileWatchers.Remove(root);
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ContentParent::WatchedFile, nsIFileUpdateListener)
|
||||
|
||||
nsresult
|
||||
ContentParent::WatchedFile::Update(const char* aReason, nsIFile* aFile)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsString path;
|
||||
aFile->GetPath(path);
|
||||
|
||||
unused << mParent->SendFilePathUpdate(path, nsDependentCString(aReason));
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCString cpath;
|
||||
aFile->GetNativePath(cpath);
|
||||
printf("ContentParent::WatchedFile::Update: %s -- %s\n", cpath.get(), aReason);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
} // namespace mozilla
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
class nsFrameMessageManager;
|
||||
@ -256,6 +257,10 @@ private:
|
||||
const nsCString& aCategory);
|
||||
|
||||
virtual bool RecvPrivateDocShellsExist(const bool& aExist);
|
||||
|
||||
virtual bool RecvAddFileWatch(const nsString& root);
|
||||
virtual bool RecvRemoveFileWatch(const nsString& root);
|
||||
|
||||
GeckoChildProcessHost* mSubprocess;
|
||||
|
||||
PRInt32 mGeolocationWatchID;
|
||||
@ -274,6 +279,34 @@ private:
|
||||
const nsString mAppManifestURL;
|
||||
nsRefPtr<nsFrameMessageManager> mMessageManager;
|
||||
|
||||
class WatchedFile : public nsIFileUpdateListener {
|
||||
public:
|
||||
WatchedFile(ContentParent* aParent, const nsString& aPath)
|
||||
: mParent(aParent)
|
||||
, mUsageCount(1)
|
||||
{
|
||||
NS_NewLocalFile(aPath, false, getter_AddRefs(mFile));
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFILEUPDATELISTENER
|
||||
|
||||
void Watch() {
|
||||
mFile->Watch(this);
|
||||
}
|
||||
|
||||
void Unwatch() {
|
||||
mFile->Watch(this);
|
||||
}
|
||||
|
||||
nsRefPtr<ContentParent> mParent;
|
||||
PRInt32 mUsageCount;
|
||||
nsCOMPtr<nsIFile> mFile;
|
||||
};
|
||||
|
||||
// This is a cache of all of the registered file watchers.
|
||||
nsInterfaceHashtable<nsStringHashKey, WatchedFile> mFileWatchers;
|
||||
|
||||
friend class CrashReporterParent;
|
||||
};
|
||||
|
||||
|
@ -199,6 +199,8 @@ child:
|
||||
// Notify child that last-pb-context-exited notification was observed
|
||||
LastPrivateDocShellDestroyed();
|
||||
|
||||
FilePathUpdate(nsString filepath, nsCString reasons);
|
||||
|
||||
parent:
|
||||
PAudio(PRInt32 aNumChannels, PRInt32 aRate, PRInt32 aFormat);
|
||||
|
||||
@ -281,6 +283,9 @@ parent:
|
||||
// Notify the parent of the presence or absence of private docshells
|
||||
PrivateDocShellsExist(bool aExist);
|
||||
|
||||
AddFileWatch(nsString filepath);
|
||||
RemoveFileWatch(nsString filepath);
|
||||
|
||||
both:
|
||||
AsyncMessage(nsString aMessage, ClonedMessageData aData);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user