Bug 971615 - Implement "storageStatus" API for device storage. r=dhylands

This commit is contained in:
Alan Huang 2014-02-19 10:48:05 +08:00
parent bc91d86185
commit 94fb5bb896
9 changed files with 194 additions and 0 deletions

View File

@ -99,6 +99,7 @@ public:
void GetDiskFreeSpace(int64_t* aSoFar);
void GetStatus(nsAString& aStatus);
void GetStorageStatus(nsAString& aStatus);
void DoFormat(nsAString& aStatus);
static void GetRootDirectoryForType(const nsAString& aStorageType,
const nsAString& aStorageName,
@ -244,6 +245,7 @@ public:
already_AddRefed<DOMRequest> UsedSpace(ErrorResult& aRv);
already_AddRefed<DOMRequest> Available(ErrorResult& aRv);
already_AddRefed<DOMRequest> Format(ErrorResult& aRv);
already_AddRefed<DOMRequest> StorageStatus(ErrorResult& aRv);
bool Default();

View File

@ -136,6 +136,16 @@ DeviceStorageRequestChild::
break;
}
case DeviceStorageResponseValue::TStorageStatusResponse:
{
StorageStatusResponse r = aValue;
AutoJSContext cx;
JS::Rooted<JS::Value> result(
cx, StringToJsval(mRequest->GetOwner(), r.storageStatus()));
mRequest->FireSuccess(result);
break;
}
case DeviceStorageResponseValue::TFormatStorageResponse:
{
FormatStorageResponse r = aValue;

View File

@ -148,6 +148,19 @@ DeviceStorageRequestParent::Dispatch()
break;
}
case DeviceStorageParams::TDeviceStorageStatusParams:
{
DeviceStorageStatusParams p = mParams;
nsRefPtr<DeviceStorageFile> dsf =
new DeviceStorageFile(p.type(), p.storageName());
nsRefPtr<PostStatusResultEvent> r
= new PostStatusResultEvent(this, dsf);
DebugOnly<nsresult> rv = NS_DispatchToMainThread(r);
MOZ_ASSERT(NS_SUCCEEDED(rv));
break;
}
case DeviceStorageParams::TDeviceStorageFormatParams:
{
DeviceStorageFormatParams p = mParams;
@ -253,6 +266,14 @@ DeviceStorageRequestParent::EnsureRequiredPermissions(
break;
}
case DeviceStorageParams::TDeviceStorageStatusParams:
{
DeviceStorageStatusParams p = mParams;
type = p.type();
requestType = DEVICE_STORAGE_REQUEST_STATUS;
break;
}
case DeviceStorageParams::TDeviceStorageFormatParams:
{
DeviceStorageFormatParams p = mParams;
@ -823,6 +844,34 @@ DeviceStorageRequestParent::PostAvailableResultEvent::CancelableRun()
return NS_OK;
}
DeviceStorageRequestParent::PostStatusResultEvent::
PostStatusResultEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile)
: CancelableRunnable(aParent)
, mFile(aFile)
{
}
DeviceStorageRequestParent::PostStatusResultEvent::
~PostStatusResultEvent()
{
}
nsresult
DeviceStorageRequestParent::PostStatusResultEvent::CancelableRun()
{
MOZ_ASSERT(NS_IsMainThread());
nsString state = NS_LITERAL_STRING("undefined");
if (mFile) {
mFile->GetStorageStatus(state);
}
StorageStatusResponse response(state);
unused << mParent->Send__delete__(mParent, response);
return NS_OK;
}
DeviceStorageRequestParent::PostFormatResultEvent::
PostFormatResultEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile)

View File

@ -249,6 +249,16 @@ private:
nsRefPtr<DeviceStorageFile> mFile;
};
class PostStatusResultEvent : public CancelableRunnable
{
public:
PostStatusResultEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile);
virtual ~PostStatusResultEvent();
virtual nsresult CancelableRun();
private:
nsRefPtr<DeviceStorageFile> mFile;
};
class PostFormatResultEvent : public CancelableRunnable
{
public:

View File

@ -58,6 +58,11 @@ struct AvailableStorageResponse
nsString mountState;
};
struct StorageStatusResponse
{
nsString storageStatus;
};
struct FormatStorageResponse
{
nsString mountState;
@ -73,6 +78,7 @@ union DeviceStorageResponseValue
FreeSpaceStorageResponse;
UsedSpaceStorageResponse;
AvailableStorageResponse;
StorageStatusResponse;
FormatStorageResponse;
};

View File

@ -390,6 +390,7 @@ DeviceStorageTypeChecker::GetAccessForRequest(
case DEVICE_STORAGE_REQUEST_FREE_SPACE:
case DEVICE_STORAGE_REQUEST_USED_SPACE:
case DEVICE_STORAGE_REQUEST_AVAILABLE:
case DEVICE_STORAGE_REQUEST_STATUS:
aAccessResult.AssignLiteral("read");
break;
case DEVICE_STORAGE_REQUEST_WRITE:
@ -1402,6 +1403,38 @@ DeviceStorageFile::GetStatus(nsAString& aStatus)
#endif
}
void
DeviceStorageFile::GetStorageStatus(nsAString& aStatus)
{
DeviceStorageTypeChecker* typeChecker
= DeviceStorageTypeChecker::CreateOrGet();
if (!typeChecker) {
return;
}
if (!typeChecker->IsVolumeBased(mStorageType)) {
aStatus.AssignLiteral("available");
return;
}
aStatus.AssignLiteral("undefined");
#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;
}
int32_t volState;
rv = vol->GetState(&volState);
NS_ENSURE_SUCCESS_VOID(rv);
aStatus.AssignASCII(mozilla::system::NS_VolumeStateStr(volState));
#endif
}
NS_IMPL_ISUPPORTS0(DeviceStorageFile)
static void
@ -1921,6 +1954,40 @@ private:
nsRefPtr<DOMRequest> mRequest;
};
class PostStatusResultEvent : public nsRunnable
{
public:
PostStatusResultEvent(DeviceStorageFile *aFile, DOMRequest* aRequest)
: mFile(aFile)
, mRequest(aRequest)
{
MOZ_ASSERT(mRequest);
}
~PostStatusResultEvent() {}
NS_IMETHOD Run()
{
MOZ_ASSERT(NS_IsMainThread());
nsString state = NS_LITERAL_STRING("undefined");
if (mFile) {
mFile->GetStorageStatus(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 PostFormatResultEvent : public nsRunnable
{
public:
@ -2656,6 +2723,21 @@ public:
return NS_DispatchToCurrentThread(r);
}
case DEVICE_STORAGE_REQUEST_STATUS:
{
if (XRE_GetProcessType() != GeckoProcessType_Default) {
PDeviceStorageRequestChild* child
= new DeviceStorageRequestChild(mRequest, mFile);
DeviceStorageStatusParams params(mFile->mStorageType,
mFile->mStorageName);
ContentChild::GetSingleton()
->SendPDeviceStorageRequestConstructor(child, params);
return NS_OK;
}
r = new PostStatusResultEvent(mFile, mRequest);
return NS_DispatchToCurrentThread(r);
}
case DEVICE_STORAGE_REQUEST_WATCH:
{
mDeviceStorage->mAllowedToWatchFile = true;
@ -3378,6 +3460,31 @@ nsDOMDeviceStorage::Available(ErrorResult& aRv)
return request.forget();
}
already_AddRefed<DOMRequest>
nsDOMDeviceStorage::StorageStatus(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
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_STATUS,
win, mPrincipal, dsf, request);
nsresult rv = NS_DispatchToCurrentThread(r);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
return request.forget();
}
already_AddRefed<DOMRequest>
nsDOMDeviceStorage::Format(ErrorResult& aRv)
{

View File

@ -52,6 +52,7 @@ enum DeviceStorageRequestType {
DEVICE_STORAGE_REQUEST_FREE_SPACE,
DEVICE_STORAGE_REQUEST_USED_SPACE,
DEVICE_STORAGE_REQUEST_AVAILABLE,
DEVICE_STORAGE_REQUEST_STATUS,
DEVICE_STORAGE_REQUEST_FORMAT,
DEVICE_STORAGE_REQUEST_CREATEFD
};

View File

@ -80,6 +80,12 @@ struct DeviceStorageAvailableParams
nsString storageName;
};
struct DeviceStorageStatusParams
{
nsString type;
nsString storageName;
};
struct DeviceStorageFormatParams
{
nsString type;
@ -134,6 +140,7 @@ union DeviceStorageParams
DeviceStorageFreeSpaceParams;
DeviceStorageUsedSpaceParams;
DeviceStorageAvailableParams;
DeviceStorageStatusParams;
DeviceStorageFormatParams;
};

View File

@ -40,6 +40,8 @@ interface DeviceStorage : EventTarget {
[Throws]
DOMRequest available();
[Throws]
DOMRequest storageStatus();
[Throws]
DOMRequest format();
// Note that the storageName is just a name (like sdcard), and doesn't