зеркало из https://github.com/mozilla/gecko-dev.git
Bug 841660 - Implement format interface for volume-based device storage, r=dhylands
This commit is contained in:
Родитель
070d3ecdfb
Коммит
85ad595995
|
@ -95,6 +95,7 @@ public:
|
|||
|
||||
void GetDiskFreeSpace(int64_t* aSoFar);
|
||||
void GetStatus(nsAString& aStatus);
|
||||
void DoFormat(nsAString& aStatus);
|
||||
static void GetRootDirectoryForType(const nsAString& aStorageType,
|
||||
const nsAString& aStorageName,
|
||||
nsIFile** aFile);
|
||||
|
@ -237,6 +238,7 @@ public:
|
|||
already_AddRefed<DOMRequest> FreeSpace(ErrorResult& aRv);
|
||||
already_AddRefed<DOMRequest> UsedSpace(ErrorResult& aRv);
|
||||
already_AddRefed<DOMRequest> Available(ErrorResult& aRv);
|
||||
already_AddRefed<DOMRequest> Format(ErrorResult& aRv);
|
||||
|
||||
bool Default();
|
||||
|
||||
|
|
|
@ -103,6 +103,16 @@ DeviceStorageRequestChild::
|
|||
break;
|
||||
}
|
||||
|
||||
case DeviceStorageResponseValue::TFormatStorageResponse:
|
||||
{
|
||||
FormatStorageResponse r = aValue;
|
||||
AutoJSContext cx;
|
||||
JS::Rooted<JS::Value> result(
|
||||
cx, StringToJsval(mRequest->GetOwner(), r.mountState()));
|
||||
mRequest->FireSuccess(result);
|
||||
break;
|
||||
}
|
||||
|
||||
case DeviceStorageResponseValue::TEnumerationResponse:
|
||||
{
|
||||
EnumerationResponse r = aValue;
|
||||
|
|
|
@ -131,6 +131,18 @@ DeviceStorageRequestParent::Dispatch()
|
|||
break;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageFormatParams:
|
||||
{
|
||||
DeviceStorageFormatParams p = mParams;
|
||||
|
||||
nsRefPtr<DeviceStorageFile> dsf =
|
||||
new DeviceStorageFile(p.type(), p.storageName());
|
||||
nsRefPtr<PostFormatResultEvent> r
|
||||
= new PostFormatResultEvent(this, dsf);
|
||||
NS_DispatchToMainThread(r);
|
||||
break;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageEnumerationParams:
|
||||
{
|
||||
DeviceStorageEnumerationParams p = mParams;
|
||||
|
@ -215,6 +227,14 @@ DeviceStorageRequestParent::EnsureRequiredPermissions(
|
|||
break;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageFormatParams:
|
||||
{
|
||||
DeviceStorageFormatParams p = mParams;
|
||||
type = p.type();
|
||||
requestType = DEVICE_STORAGE_REQUEST_FORMAT;
|
||||
break;
|
||||
}
|
||||
|
||||
case DeviceStorageParams::TDeviceStorageEnumerationParams:
|
||||
{
|
||||
DeviceStorageEnumerationParams p = mParams;
|
||||
|
@ -726,6 +746,34 @@ DeviceStorageRequestParent::PostAvailableResultEvent::CancelableRun()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostFormatResultEvent::
|
||||
PostFormatResultEvent(DeviceStorageRequestParent* aParent,
|
||||
DeviceStorageFile* aFile)
|
||||
: CancelableRunnable(aParent)
|
||||
, mFile(aFile)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceStorageRequestParent::PostFormatResultEvent::
|
||||
~PostFormatResultEvent()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
DeviceStorageRequestParent::PostFormatResultEvent::CancelableRun()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
|
||||
nsString state = NS_LITERAL_STRING("unavailable");
|
||||
if (mFile) {
|
||||
mFile->DoFormat(state);
|
||||
}
|
||||
|
||||
FormatStorageResponse response(state);
|
||||
unused << mParent->Send__delete__(mParent, response);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace devicestorage
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -227,6 +227,16 @@ private:
|
|||
nsRefPtr<DeviceStorageFile> mFile;
|
||||
};
|
||||
|
||||
class PostFormatResultEvent : public CancelableRunnable
|
||||
{
|
||||
public:
|
||||
PostFormatResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
|
||||
virtual ~PostFormatResultEvent();
|
||||
virtual nsresult CancelableRun();
|
||||
private:
|
||||
nsRefPtr<DeviceStorageFile> mFile;
|
||||
};
|
||||
|
||||
protected:
|
||||
bool AddRunnable(CancelableRunnable* aRunnable) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
|
|
@ -53,6 +53,11 @@ struct AvailableStorageResponse
|
|||
nsString mountState;
|
||||
};
|
||||
|
||||
struct FormatStorageResponse
|
||||
{
|
||||
nsString mountState;
|
||||
};
|
||||
|
||||
union DeviceStorageResponseValue
|
||||
{
|
||||
ErrorResponse;
|
||||
|
@ -62,6 +67,7 @@ union DeviceStorageResponseValue
|
|||
FreeSpaceStorageResponse;
|
||||
UsedSpaceStorageResponse;
|
||||
AvailableStorageResponse;
|
||||
FormatStorageResponse;
|
||||
};
|
||||
|
||||
sync protocol PDeviceStorageRequest {
|
||||
|
|
|
@ -390,6 +390,7 @@ DeviceStorageTypeChecker::GetAccessForRequest(
|
|||
break;
|
||||
case DEVICE_STORAGE_REQUEST_WRITE:
|
||||
case DEVICE_STORAGE_REQUEST_DELETE:
|
||||
case DEVICE_STORAGE_REQUEST_FORMAT:
|
||||
aAccessResult.AssignLiteral("write");
|
||||
break;
|
||||
case DEVICE_STORAGE_REQUEST_CREATE:
|
||||
|
@ -1279,6 +1280,36 @@ DeviceStorageFile::IsAvailable()
|
|||
return status.EqualsLiteral("available");
|
||||
}
|
||||
|
||||
void
|
||||
DeviceStorageFile::DoFormat(nsAString& aStatus)
|
||||
{
|
||||
DeviceStorageTypeChecker* typeChecker
|
||||
= DeviceStorageTypeChecker::CreateOrGet();
|
||||
if (!typeChecker) {
|
||||
return;
|
||||
}
|
||||
if (!typeChecker->IsVolumeBased(mStorageType)) {
|
||||
aStatus.AssignLiteral("notVolume");
|
||||
return;
|
||||
}
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
nsCOMPtr<nsIVolumeService> vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE_VOID(vs);
|
||||
|
||||
nsCOMPtr<nsIVolume> vol;
|
||||
nsresult rv = vs->GetVolumeByName(mStorageName, getter_AddRefs(vol));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
if (!vol) {
|
||||
return;
|
||||
}
|
||||
|
||||
vol->Format();
|
||||
|
||||
aStatus.AssignLiteral("formatting");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
DeviceStorageFile::GetStatus(nsAString& aStatus)
|
||||
{
|
||||
|
@ -1316,6 +1347,13 @@ DeviceStorageFile::GetStatus(nsAString& aStatus)
|
|||
aStatus.AssignLiteral("shared");
|
||||
return;
|
||||
}
|
||||
bool isFormatting;
|
||||
rv = vol->GetIsFormatting(&isFormatting);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
if (isFormatting) {
|
||||
aStatus.AssignLiteral("unavailable");
|
||||
return;
|
||||
}
|
||||
int32_t volState;
|
||||
rv = vol->GetState(&volState);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
@ -1848,6 +1886,39 @@ private:
|
|||
nsRefPtr<DOMRequest> mRequest;
|
||||
};
|
||||
|
||||
class PostFormatResultEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
PostFormatResultEvent(DeviceStorageFile *aFile, DOMRequest* aRequest)
|
||||
: mFile(aFile)
|
||||
, mRequest(aRequest)
|
||||
{
|
||||
}
|
||||
|
||||
~PostFormatResultEvent() {}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsString state = NS_LITERAL_STRING("unavailable");
|
||||
if (mFile) {
|
||||
mFile->DoFormat(state);
|
||||
}
|
||||
|
||||
AutoJSContext cx;
|
||||
JS::Rooted<JS::Value> result(cx,
|
||||
StringToJsval(mRequest->GetOwner(), state));
|
||||
mRequest->FireSuccess(result);
|
||||
mRequest = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<DeviceStorageFile> mFile;
|
||||
nsRefPtr<DOMRequest> mRequest;
|
||||
};
|
||||
|
||||
class PostResultEvent : public nsRunnable
|
||||
{
|
||||
public:
|
||||
|
@ -2423,6 +2494,23 @@ public:
|
|||
mDeviceStorage->mAllowedToWatchFile = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
case DEVICE_STORAGE_REQUEST_FORMAT:
|
||||
{
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
PDeviceStorageRequestChild* child
|
||||
= new DeviceStorageRequestChild(mRequest, mFile);
|
||||
DeviceStorageFormatParams params(mFile->mStorageType,
|
||||
mFile->mStorageName);
|
||||
ContentChild::GetSingleton()
|
||||
->SendPDeviceStorageRequestConstructor(child, params);
|
||||
return NS_OK;
|
||||
}
|
||||
r = new PostFormatResultEvent(mFile, mRequest);
|
||||
NS_DispatchToMainThread(r);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (r) {
|
||||
|
@ -3083,6 +3171,26 @@ nsDOMDeviceStorage::Available(ErrorResult& aRv)
|
|||
return request.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
nsDOMDeviceStorage::Format(ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
||||
if (!win) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<DOMRequest> request = new DOMRequest(win);
|
||||
|
||||
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType,
|
||||
mStorageName);
|
||||
nsCOMPtr<nsIRunnable> r
|
||||
= new DeviceStorageRequest(DEVICE_STORAGE_REQUEST_FORMAT,
|
||||
win, mPrincipal, dsf, request);
|
||||
NS_DispatchToMainThread(r);
|
||||
return request.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDeviceStorage::GetRootDirectoryForFile(const nsAString& aName,
|
||||
nsIFile** aRootDirectory)
|
||||
|
|
|
@ -51,7 +51,8 @@ enum DeviceStorageRequestType {
|
|||
DEVICE_STORAGE_REQUEST_WATCH,
|
||||
DEVICE_STORAGE_REQUEST_FREE_SPACE,
|
||||
DEVICE_STORAGE_REQUEST_USED_SPACE,
|
||||
DEVICE_STORAGE_REQUEST_AVAILABLE
|
||||
DEVICE_STORAGE_REQUEST_AVAILABLE,
|
||||
DEVICE_STORAGE_REQUEST_FORMAT
|
||||
};
|
||||
|
||||
class DeviceStorageUsedSpaceCache MOZ_FINAL
|
||||
|
|
|
@ -79,6 +79,12 @@ struct DeviceStorageAvailableParams
|
|||
nsString storageName;
|
||||
};
|
||||
|
||||
struct DeviceStorageFormatParams
|
||||
{
|
||||
nsString type;
|
||||
nsString storageName;
|
||||
};
|
||||
|
||||
struct DeviceStorageAddParams
|
||||
{
|
||||
nsString type;
|
||||
|
@ -119,6 +125,7 @@ union DeviceStorageParams
|
|||
DeviceStorageFreeSpaceParams;
|
||||
DeviceStorageUsedSpaceParams;
|
||||
DeviceStorageAvailableParams;
|
||||
DeviceStorageFormatParams;
|
||||
};
|
||||
|
||||
struct FMRadioRequestEnableParams
|
||||
|
|
|
@ -263,6 +263,21 @@ public:
|
|||
UpdateState();
|
||||
}
|
||||
|
||||
void FormatVolume(const nsACString& aVolumeName)
|
||||
{
|
||||
RefPtr<Volume> vol = VolumeManager::FindVolumeByName(aVolumeName);
|
||||
if (!vol) {
|
||||
return;
|
||||
}
|
||||
if (vol->IsFormatRequested()) {
|
||||
return;
|
||||
}
|
||||
vol->SetFormatRequested(true);
|
||||
DBG("Calling UpdateState due to volume %s formatting set to %d",
|
||||
vol->NameStr(), (int)vol->IsFormatRequested());
|
||||
UpdateState();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
AutoVolumeEventObserver mVolumeEventObserver;
|
||||
|
@ -428,14 +443,14 @@ AutoMounter::UpdateState()
|
|||
continue;
|
||||
}
|
||||
|
||||
if (tryToShare && vol->IsSharingEnabled()) {
|
||||
if ((tryToShare && vol->IsSharingEnabled()) || vol->IsFormatRequested()) {
|
||||
// We're going to try to unmount and share the volumes
|
||||
switch (volState) {
|
||||
case nsIVolume::STATE_MOUNTED: {
|
||||
if (vol->IsMountLocked()) {
|
||||
// The volume is currently locked, so leave it in the mounted
|
||||
// state.
|
||||
LOGW("UpdateState: Mounted volume %s is locked, not sharing",
|
||||
LOGW("UpdateState: Mounted volume %s is locked, not sharing or formatting",
|
||||
vol->NameStr());
|
||||
break;
|
||||
}
|
||||
|
@ -444,7 +459,11 @@ AutoMounter::UpdateState()
|
|||
// 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.
|
||||
vol->SetIsSharing(true);
|
||||
if (tryToShare && vol->IsSharingEnabled()) {
|
||||
vol->SetIsSharing(true);
|
||||
} else if (vol->IsFormatRequested()){
|
||||
vol->SetIsFormatting(true);
|
||||
}
|
||||
|
||||
// Check to see if there are any open files on the volume and
|
||||
// don't initiate the unmount while there are open files.
|
||||
|
@ -461,7 +480,7 @@ AutoMounter::UpdateState()
|
|||
fileInfo.mComm.get(),
|
||||
fileInfo.mExe.get());
|
||||
} while (fileFinder.Next(&fileInfo));
|
||||
LOGW("UpdateState: Mounted volume %s has open files, not sharing",
|
||||
LOGW("UpdateState: Mounted volume %s has open files, not sharing or formatting",
|
||||
vol->NameStr());
|
||||
|
||||
// Check again in a few seconds to see if the files are closed.
|
||||
|
@ -495,10 +514,23 @@ AutoMounter::UpdateState()
|
|||
return; // UpdateState will be called again when the Unmount command completes
|
||||
}
|
||||
case nsIVolume::STATE_IDLE: {
|
||||
// Volume is unmounted. We can go ahead and share.
|
||||
LOG("UpdateState: Sharing %s", vol->NameStr());
|
||||
vol->StartShare(mResponseCallback);
|
||||
return; // UpdateState will be called again when the Share command completes
|
||||
LOG("UpdateState: Volume %s is nsIVolume::STATE_IDLE", vol->NameStr());
|
||||
if (vol->IsFormatting() && !vol->IsFormatRequested()) {
|
||||
vol->SetFormatRequested(false);
|
||||
LOG("UpdateState: Mounting %s", vol->NameStr());
|
||||
vol->StartMount(mResponseCallback);
|
||||
break;
|
||||
}
|
||||
if (tryToShare && vol->IsSharingEnabled()) {
|
||||
// Volume is unmounted. We can go ahead and share.
|
||||
LOG("UpdateState: Sharing %s", vol->NameStr());
|
||||
vol->StartShare(mResponseCallback);
|
||||
} else if (vol->IsFormatRequested()){
|
||||
// Volume is unmounted. We can go ahead and format.
|
||||
LOG("UpdateState: Formatting %s", vol->NameStr());
|
||||
vol->StartFormat(mResponseCallback);
|
||||
}
|
||||
return; // UpdateState will be called again when the Share/Format command completes
|
||||
}
|
||||
default: {
|
||||
// Not in a state that we can do anything about.
|
||||
|
@ -578,6 +610,15 @@ SetAutoMounterSharingModeIOThread(const nsCString& aVolumeName, const bool& aAll
|
|||
sAutoMounter->SetSharingMode(aVolumeName, aAllowSharing);
|
||||
}
|
||||
|
||||
static void
|
||||
AutoMounterFormatVolumeIOThread(const nsCString& aVolumeName)
|
||||
{
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
MOZ_ASSERT(sAutoMounter);
|
||||
|
||||
sAutoMounter->FormatVolume(aVolumeName);
|
||||
}
|
||||
|
||||
static void
|
||||
UsbCableEventIOThread()
|
||||
{
|
||||
|
@ -732,10 +773,19 @@ SetAutoMounterSharingMode(const nsCString& aVolumeName, bool aAllowSharing)
|
|||
{
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(SetAutoMounterSharingModeIOThread,
|
||||
NewRunnableFunction(SetAutoMounterSharingModeIOThread,
|
||||
aVolumeName, aAllowSharing));
|
||||
}
|
||||
|
||||
void
|
||||
AutoMounterFormatVolume(const nsCString& aVolumeName)
|
||||
{
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(AutoMounterFormatVolumeIOThread,
|
||||
aVolumeName));
|
||||
}
|
||||
|
||||
void
|
||||
ShutdownAutoMounter()
|
||||
{
|
||||
|
|
|
@ -59,6 +59,15 @@ GetAutoMounterStatus();
|
|||
void
|
||||
SetAutoMounterSharingMode(const nsCString& aVolumeName, bool aAllowSharing);
|
||||
|
||||
/**
|
||||
* Formats the volume with specified volume name.
|
||||
*
|
||||
* If the volume is ready to format, automounter
|
||||
* will unmount it, format it and then mount it again.
|
||||
*/
|
||||
void
|
||||
AutoMounterFormatVolume(const nsCString& aVolumeName);
|
||||
|
||||
/**
|
||||
* Shuts down the automounter.
|
||||
*
|
||||
|
|
|
@ -60,7 +60,9 @@ Volume::Volume(const nsCSubstring& aName)
|
|||
mMountLocked(true), // Needs to agree with nsVolume::nsVolume
|
||||
mSharingEnabled(false),
|
||||
mCanBeShared(true),
|
||||
mIsSharing(false)
|
||||
mIsSharing(false),
|
||||
mFormatRequested(false),
|
||||
mIsFormatting(false)
|
||||
{
|
||||
DBG("Volume %s: created", NameStr());
|
||||
}
|
||||
|
@ -79,6 +81,20 @@ Volume::SetIsSharing(bool aIsSharing)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Volume::SetIsFormatting(bool aIsFormatting)
|
||||
{
|
||||
if (aIsFormatting == mIsFormatting) {
|
||||
return;
|
||||
}
|
||||
mIsFormatting = aIsFormatting;
|
||||
LOG("Volume %s: IsFormatting set to %d state %s",
|
||||
NameStr(), (int)mIsFormatting, StateStr(mState));
|
||||
if (mIsFormatting) {
|
||||
mEventObserverList.Broadcast(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Volume::SetMediaPresent(bool aMediaPresent)
|
||||
{
|
||||
|
@ -126,12 +142,20 @@ Volume::SetSharingEnabled(bool aSharingEnabled)
|
|||
NameStr(), (int)mSharingEnabled, (int)mCanBeShared);
|
||||
}
|
||||
|
||||
void
|
||||
Volume::SetFormatRequested(bool aFormatRequested)
|
||||
{
|
||||
mFormatRequested = aFormatRequested;
|
||||
|
||||
LOG("SetFormatRequested for volume %s to %d CanBeFormatted = %d",
|
||||
NameStr(), (int)mFormatRequested, (int)CanBeFormatted());
|
||||
}
|
||||
|
||||
void
|
||||
Volume::SetState(Volume::STATE aNewState)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
if (aNewState == mState) {
|
||||
return;
|
||||
}
|
||||
|
@ -156,7 +180,12 @@ Volume::SetState(Volume::STATE aNewState)
|
|||
break;
|
||||
|
||||
case nsIVolume::STATE_MOUNTED:
|
||||
mIsFormatting = false;
|
||||
mIsSharing = false;
|
||||
break;
|
||||
case nsIVolume::STATE_FORMATTING:
|
||||
mFormatRequested = false;
|
||||
mIsFormatting = true;
|
||||
mIsSharing = false;
|
||||
break;
|
||||
|
||||
|
@ -207,6 +236,15 @@ Volume::StartUnmount(VolumeResponseCallback* aCallback)
|
|||
StartCommand(new VolumeActionCommand(this, "unmount", "force", aCallback));
|
||||
}
|
||||
|
||||
void
|
||||
Volume::StartFormat(VolumeResponseCallback* aCallback)
|
||||
{
|
||||
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
|
||||
StartCommand(new VolumeActionCommand(this, "format", "", aCallback));
|
||||
}
|
||||
|
||||
void
|
||||
Volume::StartShare(VolumeResponseCallback* aCallback)
|
||||
{
|
||||
|
|
|
@ -46,10 +46,14 @@ public:
|
|||
bool IsMountLocked() const { return mMountLocked; }
|
||||
bool MediaPresent() const { return mMediaPresent; }
|
||||
bool CanBeShared() const { return mCanBeShared; }
|
||||
bool CanBeFormatted() const { return CanBeShared(); }
|
||||
bool IsSharingEnabled() const { return mCanBeShared && mSharingEnabled; }
|
||||
bool IsFormatRequested() const { return CanBeFormatted() && mFormatRequested; }
|
||||
bool IsSharing() const { return mIsSharing; }
|
||||
bool IsFormatting() const { return mIsFormatting; }
|
||||
|
||||
void SetSharingEnabled(bool aSharingEnabled);
|
||||
void SetFormatRequested(bool aFormatRequested);
|
||||
|
||||
typedef mozilla::Observer<Volume *> EventObserver;
|
||||
typedef mozilla::ObserverList<Volume *> EventObserverList;
|
||||
|
@ -69,10 +73,12 @@ private:
|
|||
// be called as each one completes.
|
||||
void StartMount(VolumeResponseCallback* aCallback);
|
||||
void StartUnmount(VolumeResponseCallback* aCallback);
|
||||
void StartFormat(VolumeResponseCallback* aCallback);
|
||||
void StartShare(VolumeResponseCallback* aCallback);
|
||||
void StartUnshare(VolumeResponseCallback* aCallback);
|
||||
|
||||
void SetIsSharing(bool aIsSharing);
|
||||
void SetIsFormatting(bool aIsFormatting);
|
||||
void SetState(STATE aNewState);
|
||||
void SetMediaPresent(bool aMediaPresent);
|
||||
void SetMountPoint(const nsCSubstring& aMountPoint);
|
||||
|
@ -91,8 +97,10 @@ private:
|
|||
int32_t mMountGeneration;
|
||||
bool mMountLocked;
|
||||
bool mSharingEnabled;
|
||||
bool mFormatRequested;
|
||||
bool mCanBeShared;
|
||||
bool mIsSharing;
|
||||
bool mIsFormatting;
|
||||
|
||||
static EventObserverList mEventObserverList;
|
||||
};
|
||||
|
|
|
@ -37,6 +37,7 @@ private:
|
|||
|
||||
void InitVolumeServiceIOThread(nsVolumeService* const & aVolumeService);
|
||||
void ShutdownVolumeServiceIOThread();
|
||||
void FormatVolume(const nsCString& aVolume);
|
||||
|
||||
} // system
|
||||
} // mozilla
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "nsISupports.idl"
|
||||
#include "nsIVolumeStat.idl"
|
||||
|
||||
[scriptable, uuid(e476e7ea-5cde-4d5a-b00d-d60daad76398)]
|
||||
[scriptable, uuid(8c163fe4-5577-11e3-b3d0-10bf48d707fb)]
|
||||
interface nsIVolume : nsISupports
|
||||
{
|
||||
// These MUST match the states from android's system/vold/Volume.h header
|
||||
|
@ -62,8 +62,17 @@ interface nsIVolume : nsISupports
|
|||
// transitioning from mounted to sharing and back again.
|
||||
readonly attribute boolean isSharing;
|
||||
|
||||
// Determines if the volume is currently formatting. This sets true once
|
||||
// mFormatRequest == true and mState == STATE_MOUNTED, and sets false
|
||||
// once the volume has been formatted and mounted again.
|
||||
readonly attribute boolean isFormatting;
|
||||
|
||||
nsIVolumeStat getStats();
|
||||
|
||||
// Formats the volume in IO thread, if the volume is ready to be formatted.
|
||||
// Automounter will unmount it, format it and then mount it again.
|
||||
void format();
|
||||
|
||||
// Whether this is a fake volume.
|
||||
readonly attribute boolean isFake;
|
||||
};
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "nsVolumeStat.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "Volume.h"
|
||||
#include "AutoMounter.h"
|
||||
#include "VolumeManager.h"
|
||||
|
||||
#define VOLUME_MANAGER_LOG_TAG "nsVolume"
|
||||
#include "VolumeManagerLog.h"
|
||||
|
@ -53,7 +55,8 @@ nsVolume::nsVolume(const Volume* aVolume)
|
|||
mMountLocked(aVolume->IsMountLocked()),
|
||||
mIsFake(false),
|
||||
mIsMediaPresent(aVolume->MediaPresent()),
|
||||
mIsSharing(aVolume->IsSharing())
|
||||
mIsSharing(aVolume->IsSharing()),
|
||||
mIsFormatting(aVolume->IsFormatting())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -101,6 +104,12 @@ bool nsVolume::Equals(nsIVolume* aVolume)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool isFormatting;
|
||||
aVolume->GetIsFormatting(&isFormatting);
|
||||
if (mIsFormatting != isFormatting) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -122,6 +131,12 @@ NS_IMETHODIMP nsVolume::GetIsSharing(bool *aIsSharing)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolume::GetIsFormatting(bool *aIsFormatting)
|
||||
{
|
||||
*aIsFormatting = mIsFormatting;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolume::GetName(nsAString& aName)
|
||||
{
|
||||
aName = mName;
|
||||
|
@ -170,15 +185,36 @@ NS_IMETHODIMP nsVolume::GetIsFake(bool *aIsFake)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsVolume::Format()
|
||||
{
|
||||
XRE_GetIOMessageLoop()->PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableFunction(FormatVolumeIOThread, NameStr()));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void nsVolume::FormatVolumeIOThread(const nsCString& aVolume)
|
||||
{
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
if (VolumeManager::State() != VolumeManager::VOLUMES_READY) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoMounterFormatVolume(aVolume);
|
||||
}
|
||||
|
||||
void
|
||||
nsVolume::LogState() const
|
||||
{
|
||||
if (mState == nsIVolume::STATE_MOUNTED) {
|
||||
LOG("nsVolume: %s state %s @ '%s' gen %d locked %d fake %d "
|
||||
"media %d sharing %d",
|
||||
"media %d sharing %d formatting %d",
|
||||
NameStr().get(), StateStr(), MountPointStr().get(),
|
||||
MountGeneration(), (int)IsMountLocked(), (int)IsFake(),
|
||||
(int)IsMediaPresent(), (int)IsSharing());
|
||||
(int)IsMediaPresent(), (int)IsSharing(),
|
||||
(int)IsFormatting());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -195,6 +231,7 @@ void nsVolume::Set(nsIVolume* aVolume)
|
|||
aVolume->GetIsFake(&mIsFake);
|
||||
aVolume->GetIsMediaPresent(&mIsMediaPresent);
|
||||
aVolume->GetIsSharing(&mIsSharing);
|
||||
aVolume->GetIsFormatting(&mIsFormatting);
|
||||
|
||||
int32_t volMountGeneration;
|
||||
aVolume->GetMountGeneration(&volMountGeneration);
|
||||
|
|
|
@ -37,7 +37,8 @@ public:
|
|||
mMountLocked(false),
|
||||
mIsFake(false),
|
||||
mIsMediaPresent(aIsMediaPresent),
|
||||
mIsSharing(aIsSharing)
|
||||
mIsSharing(aIsSharing),
|
||||
mIsFormatting(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -50,7 +51,8 @@ public:
|
|||
mMountLocked(true), // Needs to agree with Volume::Volume
|
||||
mIsFake(false),
|
||||
mIsMediaPresent(false),
|
||||
mIsSharing(false)
|
||||
mIsSharing(false),
|
||||
mIsFormatting(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -74,6 +76,7 @@ public:
|
|||
bool IsFake() const { return mIsFake; }
|
||||
bool IsMediaPresent() const { return mIsMediaPresent; }
|
||||
bool IsSharing() const { return mIsSharing; }
|
||||
bool IsFormatting() const { return mIsFormatting; }
|
||||
|
||||
typedef nsTArray<nsRefPtr<nsVolume> > Array;
|
||||
|
||||
|
@ -86,6 +89,7 @@ private:
|
|||
|
||||
void SetIsFake(bool aIsFake);
|
||||
void SetState(int32_t aState);
|
||||
static void FormatVolumeIOThread(const nsCString& aVolume);
|
||||
|
||||
nsString mName;
|
||||
nsString mMountPoint;
|
||||
|
@ -95,6 +99,7 @@ private:
|
|||
bool mIsFake;
|
||||
bool mIsMediaPresent;
|
||||
bool mIsSharing;
|
||||
bool mIsFormatting;
|
||||
};
|
||||
|
||||
} // system
|
||||
|
|
|
@ -431,10 +431,11 @@ public:
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
DBG("UpdateVolumeRunnable::Run '%s' state %s gen %d locked %d "
|
||||
"media %d sharing %d",
|
||||
"media %d sharing %d formatting %d",
|
||||
mVolume->NameStr().get(), mVolume->StateStr(),
|
||||
mVolume->MountGeneration(), (int)mVolume->IsMountLocked(),
|
||||
(int)mVolume->IsMediaPresent(), mVolume->IsSharing());
|
||||
(int)mVolume->IsMediaPresent(), mVolume->IsSharing(),
|
||||
mVolume->IsFormatting());
|
||||
|
||||
mVolumeService->UpdateVolume(mVolume);
|
||||
mVolumeService = nullptr;
|
||||
|
@ -451,10 +452,11 @@ void
|
|||
nsVolumeService::UpdateVolumeIOThread(const Volume* aVolume)
|
||||
{
|
||||
DBG("UpdateVolumeIOThread: Volume '%s' state %s mount '%s' gen %d locked %d "
|
||||
"media %d sharing %d",
|
||||
"media %d sharing %d formatting %d",
|
||||
aVolume->NameStr(), aVolume->StateStr(), aVolume->MountPoint().get(),
|
||||
aVolume->MountGeneration(), (int)aVolume->IsMountLocked(),
|
||||
(int)aVolume->MediaPresent(), (int)aVolume->IsSharing());
|
||||
(int)aVolume->MediaPresent(), (int)aVolume->IsSharing(),
|
||||
(int)aVolume->IsFormatting());
|
||||
MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop());
|
||||
NS_DispatchToMainThread(new UpdateVolumeRunnable(this, aVolume));
|
||||
}
|
||||
|
|
|
@ -39,6 +39,8 @@ interface DeviceStorage : EventTarget {
|
|||
DOMRequest usedSpace();
|
||||
[Throws]
|
||||
DOMRequest available();
|
||||
[Throws]
|
||||
DOMRequest format();
|
||||
|
||||
// Note that the storageName is just a name (like sdcard), and doesn't
|
||||
// include any path information.
|
||||
|
|
Загрузка…
Ссылка в новой задаче