Bug 1060196 - Mark the volume as if we've started unmounting. r=dhylands

This commit is contained in:
Alphan Chen 2014-09-22 11:42:33 +08:00
parent 450c97d26c
commit 42bec8ff4d
12 changed files with 96 additions and 27 deletions

View File

@ -1664,6 +1664,13 @@ DeviceStorageFile::GetStatus(nsAString& aStatus)
aStatus.AssignLiteral("unavailable");
return;
}
bool isUnmounting;
rv = vol->GetIsUnmounting(&isUnmounting);
NS_ENSURE_SUCCESS_VOID(rv);
if (isUnmounting) {
aStatus.AssignLiteral("unavailable");
return;
}
int32_t volState;
rv = vol->GetState(&volState);
NS_ENSURE_SUCCESS_VOID(rv);

View File

@ -1893,12 +1893,14 @@ ContentChild::RecvFileSystemUpdate(const nsString& aFsName,
const bool& aIsMediaPresent,
const bool& aIsSharing,
const bool& aIsFormatting,
const bool& aIsFake)
const bool& aIsFake,
const bool& aIsUnmounting)
{
#ifdef MOZ_WIDGET_GONK
nsRefPtr<nsVolume> volume = new nsVolume(aFsName, aVolumeName, aState,
aMountGeneration, aIsMediaPresent,
aIsSharing, aIsFormatting, aIsFake);
aIsSharing, aIsFormatting, aIsFake,
aIsUnmounting);
nsRefPtr<nsVolumeService> vs = nsVolumeService::GetSingleton();
if (vs) {
@ -1914,6 +1916,7 @@ ContentChild::RecvFileSystemUpdate(const nsString& aFsName,
unused << aIsSharing;
unused << aIsFormatting;
unused << aIsFake;
unused << aIsUnmounting;
#endif
return true;
}

View File

@ -312,7 +312,8 @@ public:
const bool& aIsMediaPresent,
const bool& aIsSharing,
const bool& aIsFormatting,
const bool& aIsFake) MOZ_OVERRIDE;
const bool& aIsFake,
const bool& aIsUnmounting) MOZ_OVERRIDE;
virtual bool RecvNuwaFork() MOZ_OVERRIDE;

View File

@ -2650,6 +2650,7 @@ ContentParent::Observe(nsISupports* aSubject,
bool isSharing;
bool isFormatting;
bool isFake;
bool isUnmounting;
vol->GetName(volName);
vol->GetMountPoint(mountPoint);
@ -2659,6 +2660,7 @@ ContentParent::Observe(nsISupports* aSubject,
vol->GetIsSharing(&isSharing);
vol->GetIsFormatting(&isFormatting);
vol->GetIsFake(&isFake);
vol->GetIsUnmounting(&isUnmounting);
#ifdef MOZ_NUWA_PROCESS
if (!(IsNuwaReady() && IsNuwaProcess()))
@ -2666,7 +2668,8 @@ ContentParent::Observe(nsISupports* aSubject,
{
unused << SendFileSystemUpdate(volName, mountPoint, state,
mountGeneration, isMediaPresent,
isSharing, isFormatting, isFake);
isSharing, isFormatting, isFake,
isUnmounting);
}
} else if (!strcmp(aTopic, "phone-state-changed")) {
nsString state(aData);

View File

@ -301,6 +301,7 @@ struct VolumeInfo {
bool isSharing;
bool isFormatting;
bool isFake;
bool isUnmounting;
};
union MaybeFileDesc {
@ -449,7 +450,7 @@ child:
// VolumeInfo above.
FileSystemUpdate(nsString fsName, nsString mountPoint, int32_t fsState,
int32_t mountGeneration, bool isMediaPresent,
bool isSharing, bool isFormatting, bool isFake);
bool isSharing, bool isFormatting, bool isFake, bool isUnmounting);
// Ask the Nuwa process to create a new child process.
NuwaFork();

View File

@ -909,14 +909,16 @@ AutoMounter::UpdateState()
break;
}
// Mark the volume as if we've started sharing. This will cause
// apps which watch device storage notifications to see the volume
// go into the shared state, and prompt them to close any open files
// that they might have.
// Mark the volume as if we've started sharing/formatting/unmmounting.
// This will cause apps which watch device storage notifications to see
// the volume go into the different state, and prompt them to close any
// open files that they might have.
if (tryToShare && vol->IsSharingEnabled()) {
vol->SetIsSharing(true);
} else if (vol->IsFormatRequested()){
vol->SetIsFormatting(true);
} else if (vol->IsUnmountRequested()){
vol->SetIsUnmounting(true);
}
// Check to see if there are any open files on the volume and

View File

@ -67,6 +67,7 @@ Volume::Volume(const nsCSubstring& aName)
mCanBeShared(true),
mIsSharing(false),
mIsFormatting(false),
mIsUnmounting(false),
mId(sNextId++)
{
DBG("Volume %s: created", NameStr());
@ -98,6 +99,18 @@ Volume::SetIsFormatting(bool aIsFormatting)
}
}
void
Volume::SetIsUnmounting(bool aIsUnmounting)
{
if (aIsUnmounting == mIsUnmounting) {
return;
}
mIsUnmounting = aIsUnmounting;
LOG("Volume %s: IsUnmounting set to %d state %s",
NameStr(), (int)mIsUnmounting, StateStr(mState));
mEventObserverList.Broadcast(this);
}
void
Volume::SetMediaPresent(bool aMediaPresent)
{
@ -201,17 +214,20 @@ Volume::SetState(Volume::STATE aNewState)
mIsSharing = false;
mUnmountRequested = false;
mMountRequested = false;
mIsUnmounting = false;
break;
case nsIVolume::STATE_MOUNTED:
mMountRequested = false;
mIsFormatting = false;
mIsSharing = false;
mIsUnmounting = false;
break;
case nsIVolume::STATE_FORMATTING:
mFormatRequested = false;
mIsFormatting = true;
mIsSharing = false;
mIsUnmounting = false;
break;
case nsIVolume::STATE_SHARED:
@ -221,6 +237,14 @@ Volume::SetState(Volume::STATE aNewState)
// it's conceivable that a volume could already be in a shared state
// when b2g starts.
mIsSharing = true;
mIsUnmounting = false;
mIsFormatting = false;
break;
case nsIVolume::STATE_UNMOUNTING:
mIsUnmounting = true;
mIsFormatting = false;
mIsSharing = false;
break;
case nsIVolume::STATE_IDLE:

View File

@ -58,6 +58,7 @@ public:
bool IsUnmountRequested() const { return CanBeMounted() && mUnmountRequested; }
bool IsSharing() const { return mIsSharing; }
bool IsFormatting() const { return mIsFormatting; }
bool IsUnmounting() const { return mIsUnmounting; }
void SetSharingEnabled(bool aSharingEnabled);
void SetFormatRequested(bool aFormatRequested);
@ -88,6 +89,7 @@ private:
void SetIsSharing(bool aIsSharing);
void SetIsFormatting(bool aIsFormatting);
void SetIsUnmounting(bool aIsUnmounting);
void SetState(STATE aNewState);
void SetMediaPresent(bool aMediaPresent);
void SetMountPoint(const nsCSubstring& aMountPoint);
@ -112,6 +114,7 @@ private:
bool mCanBeShared;
bool mIsSharing;
bool mIsFormatting;
bool mIsUnmounting;
uint32_t mId; // Unique ID (used by MTP)
static EventObserverList mEventObserverList;

View File

@ -5,7 +5,7 @@
#include "nsISupports.idl"
#include "nsIVolumeStat.idl"
[scriptable, uuid(13caa69c-8f1f-11e3-8e36-10bf48d707fb)]
[scriptable, uuid(9D0DC356-395D-11E4-9306-A97C1D5D46B0)]
interface nsIVolume : nsISupports
{
// These MUST match the states from android's system/vold/Volume.h header
@ -67,6 +67,8 @@ interface nsIVolume : nsISupports
// once the volume has been formatted and mounted again.
readonly attribute boolean isFormatting;
readonly attribute boolean isUnmounting;
nsIVolumeStat getStats();
// Formats the volume in IO thread, if the volume is ready to be formatted.

View File

@ -56,7 +56,8 @@ nsVolume::nsVolume(const Volume* aVolume)
mIsFake(false),
mIsMediaPresent(aVolume->MediaPresent()),
mIsSharing(aVolume->IsSharing()),
mIsFormatting(aVolume->IsFormatting())
mIsFormatting(aVolume->IsFormatting()),
mIsUnmounting(aVolume->IsUnmounting())
{
}
@ -110,33 +111,45 @@ bool nsVolume::Equals(nsIVolume* aVolume)
return false;
}
bool isUnmounting;
aVolume->GetIsUnmounting(&isUnmounting);
if (mIsUnmounting != isUnmounting) {
return false;
}
return true;
}
NS_IMETHODIMP nsVolume::GetIsMediaPresent(bool *aIsMediaPresent)
NS_IMETHODIMP nsVolume::GetIsMediaPresent(bool* aIsMediaPresent)
{
*aIsMediaPresent = mIsMediaPresent;
return NS_OK;
}
NS_IMETHODIMP nsVolume::GetIsMountLocked(bool *aIsMountLocked)
NS_IMETHODIMP nsVolume::GetIsMountLocked(bool* aIsMountLocked)
{
*aIsMountLocked = mMountLocked;
return NS_OK;
}
NS_IMETHODIMP nsVolume::GetIsSharing(bool *aIsSharing)
NS_IMETHODIMP nsVolume::GetIsSharing(bool* aIsSharing)
{
*aIsSharing = mIsSharing;
return NS_OK;
}
NS_IMETHODIMP nsVolume::GetIsFormatting(bool *aIsFormatting)
NS_IMETHODIMP nsVolume::GetIsFormatting(bool* aIsFormatting)
{
*aIsFormatting = mIsFormatting;
return NS_OK;
}
NS_IMETHODIMP nsVolume::GetIsUnmounting(bool* aIsUnmounting)
{
*aIsUnmounting = mIsUnmounting;
return NS_OK;
}
NS_IMETHODIMP nsVolume::GetName(nsAString& aName)
{
aName = mName;
@ -262,11 +275,11 @@ nsVolume::LogState() const
{
if (mState == nsIVolume::STATE_MOUNTED) {
LOG("nsVolume: %s state %s @ '%s' gen %d locked %d fake %d "
"media %d sharing %d formatting %d",
"media %d sharing %d formatting %d unmounting %d",
NameStr().get(), StateStr(), MountPointStr().get(),
MountGeneration(), (int)IsMountLocked(), (int)IsFake(),
(int)IsMediaPresent(), (int)IsSharing(),
(int)IsFormatting());
(int)IsFormatting(), (int)IsUnmounting());
return;
}
@ -284,6 +297,7 @@ void nsVolume::Set(nsIVolume* aVolume)
aVolume->GetIsMediaPresent(&mIsMediaPresent);
aVolume->GetIsSharing(&mIsSharing);
aVolume->GetIsFormatting(&mIsFormatting);
aVolume->GetIsUnmounting(&mIsUnmounting);
int32_t volMountGeneration;
aVolume->GetMountGeneration(&volMountGeneration);

View File

@ -30,7 +30,8 @@ public:
nsVolume(const nsAString& aName, const nsAString& aMountPoint,
const int32_t& aState, const int32_t& aMountGeneration,
const bool& aIsMediaPresent, const bool& aIsSharing,
const bool& aIsFormatting, const bool& aIsFake)
const bool& aIsFormatting, const bool& aIsFake,
const bool& aIsUnmounting)
: mName(aName),
mMountPoint(aMountPoint),
mState(aState),
@ -39,7 +40,8 @@ public:
mIsFake(aIsFake),
mIsMediaPresent(aIsMediaPresent),
mIsSharing(aIsSharing),
mIsFormatting(aIsFormatting)
mIsFormatting(aIsFormatting),
mIsUnmounting(aIsUnmounting)
{
}
@ -53,7 +55,8 @@ public:
mIsFake(false),
mIsMediaPresent(false),
mIsSharing(false),
mIsFormatting(false)
mIsFormatting(false),
mIsUnmounting(false)
{
}
@ -78,6 +81,7 @@ public:
bool IsMediaPresent() const { return mIsMediaPresent; }
bool IsSharing() const { return mIsSharing; }
bool IsFormatting() const { return mIsFormatting; }
bool IsUnmounting() const { return mIsUnmounting; }
typedef nsTArray<nsRefPtr<nsVolume> > Array;
@ -103,6 +107,7 @@ private:
bool mIsMediaPresent;
bool mIsSharing;
bool mIsFormatting;
bool mIsUnmounting;
};
} // system

View File

@ -208,7 +208,8 @@ nsVolumeService::CreateOrGetVolumeByPath(const nsAString& aPath, nsIVolume** aRe
true /* isMediaPresent*/,
false /* isSharing */,
false /* isFormatting */,
true /* isFake */);
true /* isFake */,
false /* isUnmounting*/);
vol.forget(aResult);
return NS_OK;
}
@ -269,6 +270,7 @@ nsVolumeService::GetVolumesForIPC(nsTArray<VolumeInfo>* aResult)
volInfo->isSharing() = vol->mIsSharing;
volInfo->isFormatting() = vol->mIsFormatting;
volInfo->isFake() = vol->mIsFake;
volInfo->isUnmounting() = vol->mIsUnmounting;
}
}
@ -296,7 +298,8 @@ nsVolumeService::GetVolumesFromParent()
volInfo.isMediaPresent(),
volInfo.isSharing(),
volInfo.isFormatting(),
volInfo.isFake());
volInfo.isFake(),
volInfo.isUnmounting());
UpdateVolume(vol, false);
}
}
@ -420,7 +423,8 @@ nsVolumeService::CreateFakeVolume(const nsAString& name, const nsAString& path)
true /* isMediaPresent */,
false /* isSharing */,
false /* isFormatting */,
true /* isFake */);
true /* isFake */,
false /* isUnmounting */);
vol->LogState();
UpdateVolume(vol.get());
return NS_OK;
@ -470,11 +474,11 @@ public:
{
MOZ_ASSERT(NS_IsMainThread());
DBG("UpdateVolumeRunnable::Run '%s' state %s gen %d locked %d "
"media %d sharing %d formatting %d",
"media %d sharing %d formatting %d unmounting %d",
mVolume->NameStr().get(), mVolume->StateStr(),
mVolume->MountGeneration(), (int)mVolume->IsMountLocked(),
(int)mVolume->IsMediaPresent(), mVolume->IsSharing(),
mVolume->IsFormatting());
mVolume->IsFormatting(), mVolume->IsUnmounting());
mVolumeService->UpdateVolume(mVolume);
mVolumeService = nullptr;
@ -491,11 +495,11 @@ void
nsVolumeService::UpdateVolumeIOThread(const Volume* aVolume)
{
DBG("UpdateVolumeIOThread: Volume '%s' state %s mount '%s' gen %d locked %d "
"media %d sharing %d formatting %d",
"media %d sharing %d formatting %d unmounting %d",
aVolume->NameStr(), aVolume->StateStr(), aVolume->MountPoint().get(),
aVolume->MountGeneration(), (int)aVolume->IsMountLocked(),
(int)aVolume->MediaPresent(), (int)aVolume->IsSharing(),
(int)aVolume->IsFormatting());
(int)aVolume->IsFormatting(), (int)mVolume->IsUnmounting());
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
NS_DispatchToMainThread(new UpdateVolumeRunnable(this, aVolume));
}