Bug 865347 - Add functions to manipulate fake volumes to test SD card insert/remove. r=dhylands

This commit is contained in:
JW Wang 2013-07-09 14:37:47 +08:00
parent ce066e521a
commit 485b8bde11
9 changed files with 141 additions and 8 deletions

View File

@ -2572,5 +2572,37 @@ ContentParent::RecvSystemMessageHandled()
return true;
}
bool
ContentParent::RecvCreateFakeVolume(const nsString& fsName, const nsString& mountPoint)
{
#ifdef MOZ_WIDGET_GONK
nsresult rv;
nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID, &rv);
if (vs) {
vs->CreateFakeVolume(fsName, mountPoint);
}
return true;
#else
NS_WARNING("ContentParent::RecvCreateFakeVolume shouldn't be called when MOZ_WIDGET_GONK is not defined");
return false;
#endif
}
bool
ContentParent::RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsState)
{
#ifdef MOZ_WIDGET_GONK
nsresult rv;
nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID, &rv);
if (vs) {
vs->SetFakeVolumeState(fsName, fsState);
}
return true;
#else
NS_WARNING("ContentParent::RecvSetFakeVolumeState shouldn't be called when MOZ_WIDGET_GONK is not defined");
return false;
#endif
}
} // namespace dom
} // namespace mozilla

View File

@ -416,6 +416,10 @@ private:
virtual bool RecvSystemMessageHandled() MOZ_OVERRIDE;
virtual bool RecvCreateFakeVolume(const nsString& fsName, const nsString& mountPoint) MOZ_OVERRIDE;
virtual bool RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsState) MOZ_OVERRIDE;
virtual void ProcessingError(Result what) MOZ_OVERRIDE;
GeckoChildProcessHost* mSubprocess;

View File

@ -515,6 +515,10 @@ parent:
// Notify the parent that the child has finished handling a system message.
async SystemMessageHandled();
// called by the child (test code only) to propagate volume changes to the parent
async CreateFakeVolume(nsString fsName, nsString mountPoint);
async SetFakeVolumeState(nsString fsName, int32_t fsState);
both:
AsyncMessage(nsString aMessage, ClonedMessageData aData);
};

View File

@ -5,7 +5,7 @@
#include "nsISupports.idl"
#include "nsIVolumeStat.idl"
[scriptable, uuid(1134f267-7b81-42f2-b64a-6edb91286576)]
[scriptable, uuid(4b5bd562-bd05-4658-ab0f-f668a9e25fb5)]
interface nsIVolume : nsISupports
{
// These MUST match the states from android's system/vold/Volume.h header
@ -49,6 +49,9 @@ interface nsIVolume : nsISupports
readonly attribute boolean isMountLocked;
nsIVolumeStat getStats();
// Whether this is a fake volume.
readonly attribute boolean isFake;
};
%{C++

View File

@ -12,7 +12,7 @@
%}
[ref] native nsStringTArrayRef(nsTArray<nsString>);
[scriptable, uuid(7c179fb7-67a0-43a3-9337-294e0360b858)]
[scriptable, uuid(a3b110cd-74f2-43cb-84c6-2a87713f2774)]
interface nsIVolumeService : nsISupports
{
nsIVolume getVolumeByName(in DOMString volName);
@ -24,6 +24,10 @@ interface nsIVolumeService : nsISupports
nsIVolumeMountLock createMountLock(in DOMString volName);
[noscript] void getVolumeNames(in nsStringTArrayRef aVolNames);
/* for test case only to simulate sdcard insertion/removal */
void createFakeVolume(in DOMString name, in DOMString path);
void SetFakeVolumeState(in DOMString name, in long state);
};
%{C++

View File

@ -50,7 +50,8 @@ nsVolume::nsVolume(const Volume* aVolume)
mMountPoint(NS_ConvertUTF8toUTF16(aVolume->MountPoint())),
mState(aVolume->State()),
mMountGeneration(aVolume->MountGeneration()),
mMountLocked(aVolume->IsMountLocked())
mMountLocked(aVolume->IsMountLocked()),
mIsFake(false)
{
}
@ -85,6 +86,13 @@ bool nsVolume::Equals(nsIVolume* aVolume)
if (mMountLocked != volIsMountLocked) {
return false;
}
bool isFake;
aVolume->GetIsFake(&isFake);
if (mIsFake != isFake) {
return false;
}
return true;
}
@ -136,6 +144,12 @@ NS_IMETHODIMP nsVolume::GetStats(nsIVolumeStat **aResult)
return NS_OK;
}
NS_IMETHODIMP nsVolume::GetIsFake(bool *aIsFake)
{
*aIsFake = mIsFake;
return NS_OK;
}
void
nsVolume::LogState() const
{
@ -156,6 +170,7 @@ void nsVolume::Set(nsIVolume* aVolume)
aVolume->GetName(mName);
aVolume->GetMountPoint(mMountPoint);
aVolume->GetState(&mState);
aVolume->GetIsFake(&mIsFake);
int32_t volMountGeneration;
aVolume->GetMountGeneration(&volMountGeneration);
@ -222,5 +237,25 @@ nsVolume::UpdateMountLock(bool aMountLocked)
MountGeneration(), aMountLocked));
}
void
nsVolume::SetState(int32_t aState)
{
static int32_t sMountGeneration = 0;
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(IsFake());
if (aState == mState) {
return;
}
if (aState == nsIVolume::STATE_MOUNTED) {
mMountGeneration = ++sMountGeneration;
}
mState = aState;
}
} // system
} // mozilla

View File

@ -32,7 +32,8 @@ public:
mMountPoint(aMountPoint),
mState(aState),
mMountGeneration(aMountGeneration),
mMountLocked(false)
mMountLocked(false),
mIsFake(false)
{
}
@ -42,7 +43,8 @@ public:
: mName(aName),
mState(STATE_INIT),
mMountGeneration(-1),
mMountLocked(true) // Needs to agree with Volume::Volume
mMountLocked(true), // Needs to agree with Volume::Volume
mIsFake(false)
{
}
@ -72,11 +74,16 @@ private:
void UpdateMountLock(const nsAString& aMountLockState);
void UpdateMountLock(bool aMountLocked);
bool IsFake() const { return mIsFake; }
void SetIsFake(bool aIsFake) { mIsFake = aIsFake; }
void SetState(int32_t aState);
nsString mName;
nsString mMountPoint;
int32_t mState;
int32_t mMountGeneration;
bool mMountLocked;
bool mIsFake;
};
} // system

View File

@ -326,7 +326,7 @@ nsVolumeService::FindVolumeByName(const nsAString& aName)
//static
already_AddRefed<nsVolume>
nsVolumeService::CreateOrFindVolumeByName(const nsAString& aName)
nsVolumeService::CreateOrFindVolumeByName(const nsAString& aName, bool aIsFake /*= false*/)
{
MonitorAutoLock autoLock(mArrayMonitor);
@ -337,6 +337,7 @@ nsVolumeService::CreateOrFindVolumeByName(const nsAString& aName)
}
// Volume not found - add a new one
vol = new nsVolume(aName);
vol->SetIsFake(aIsFake);
mVolumeArray.AppendElement(vol);
return vol.forget();
}
@ -348,11 +349,19 @@ nsVolumeService::UpdateVolume(nsIVolume* aVolume)
nsString volName;
aVolume->GetName(volName);
nsRefPtr<nsVolume> vol = CreateOrFindVolumeByName(volName);
bool aIsFake;
aVolume->GetIsFake(&aIsFake);
nsRefPtr<nsVolume> vol = CreateOrFindVolumeByName(volName, aIsFake);
if (vol->Equals(aVolume)) {
// Nothing has really changed. Don't bother telling anybody.
return;
}
if (!vol->IsFake() && aIsFake) {
// Prevent an incoming fake volume from overriding an existing real volume.
return;
}
vol->Set(aVolume);
nsCOMPtr<nsIObserverService> obs = GetObserverService();
if (!obs) {
@ -362,6 +371,41 @@ nsVolumeService::UpdateVolume(nsIVolume* aVolume)
obs->NotifyObservers(vol, NS_VOLUME_STATE_CHANGED, stateStr.get());
}
NS_IMETHODIMP
nsVolumeService::CreateFakeVolume(const nsAString& name, const nsAString& path)
{
if (XRE_GetProcessType() == GeckoProcessType_Default) {
nsRefPtr<nsVolume> vol = new nsVolume(name, path, nsIVolume::STATE_INIT, -1);
vol->SetIsFake(true);
UpdateVolume(vol.get());
return NS_OK;
}
ContentChild::GetSingleton()->SendCreateFakeVolume(nsString(name), nsString(path));
return NS_OK;
}
NS_IMETHODIMP
nsVolumeService::SetFakeVolumeState(const nsAString& name, int32_t state)
{
if (XRE_GetProcessType() == GeckoProcessType_Default) {
nsRefPtr<nsVolume> vol;
{
MonitorAutoLock autoLock(mArrayMonitor);
vol = FindVolumeByName(name);
}
if (!vol || !vol->IsFake()) {
return NS_ERROR_NOT_AVAILABLE;
}
vol->SetState(state);
UpdateVolume(vol.get());
return NS_OK;
}
ContentChild::GetSingleton()->SendSetFakeVolumeState(nsString(name), state);
return NS_OK;
}
/***************************************************************************
* The UpdateVolumeRunnable creates an nsVolume and updates the main thread
* data structure while running on the main thread.

View File

@ -50,7 +50,7 @@ private:
const nsAString& aMountLockState);
already_AddRefed<nsVolume> FindVolumeByMountLockName(const nsAString& aMountLockName);
already_AddRefed<nsVolume> FindVolumeByName(const nsAString& aName);
already_AddRefed<nsVolume> CreateOrFindVolumeByName(const nsAString& aName);
already_AddRefed<nsVolume> CreateOrFindVolumeByName(const nsAString& aName, bool aIsFake = false);
Monitor mArrayMonitor;
nsVolume::Array mVolumeArray;