Bug 1000829 - getDataStores() should be able to retrieve data stores by owner. r=baku sr=jst

This commit is contained in:
Sean Lin 2014-07-17 11:53:23 +08:00
parent 444fbd2caa
commit 5101141c0a
12 changed files with 110 additions and 32 deletions

View File

@ -1466,6 +1466,7 @@ Navigator::GetBattery(ErrorResult& aRv)
/* static */ already_AddRefed<Promise>
Navigator::GetDataStores(nsPIDOMWindow* aWindow,
const nsAString& aName,
const nsAString& aOwner,
ErrorResult& aRv)
{
if (!aWindow || !aWindow->GetDocShell()) {
@ -1480,16 +1481,18 @@ Navigator::GetDataStores(nsPIDOMWindow* aWindow,
}
nsCOMPtr<nsISupports> promise;
aRv = service->GetDataStores(aWindow, aName, getter_AddRefs(promise));
aRv = service->GetDataStores(aWindow, aName, aOwner, getter_AddRefs(promise));
nsRefPtr<Promise> p = static_cast<Promise*>(promise.get());
return p.forget();
}
already_AddRefed<Promise>
Navigator::GetDataStores(const nsAString& aName, ErrorResult& aRv)
Navigator::GetDataStores(const nsAString& aName,
const nsAString& aOwner,
ErrorResult& aRv)
{
return GetDataStores(mWindow, aName, aRv);
return GetDataStores(mWindow, aName, aOwner, aRv);
}
already_AddRefed<Promise>

View File

@ -161,13 +161,15 @@ public:
static already_AddRefed<Promise> GetDataStores(nsPIDOMWindow* aWindow,
const nsAString& aName,
const nsAString& aOwner,
ErrorResult& aRv);
already_AddRefed<Promise> GetDataStores(const nsAString &aName,
already_AddRefed<Promise> GetDataStores(const nsAString& aName,
const nsAString& aOwner,
ErrorResult& aRv);
// Feature Detection API
already_AddRefed<Promise> GetFeature(const nsAString &aName,
already_AddRefed<Promise> GetFeature(const nsAString& aName,
ErrorResult& aRv);
bool Vibrate(uint32_t aDuration);

View File

@ -322,16 +322,18 @@ class MOZ_STACK_CLASS GetDataStoreInfosData
{
public:
GetDataStoreInfosData(nsClassHashtable<nsStringHashKey, HashApp>& aAccessStores,
const nsAString& aName, uint32_t aAppId,
nsTArray<DataStoreInfo>& aStores)
const nsAString& aName, const nsAString& aManifestURL,
uint32_t aAppId, nsTArray<DataStoreInfo>& aStores)
: mAccessStores(aAccessStores)
, mName(aName)
, mManifestURL(aManifestURL)
, mAppId(aAppId)
, mStores(aStores)
{}
nsClassHashtable<nsStringHashKey, HashApp>& mAccessStores;
nsString mName;
nsString mManifestURL;
uint32_t mAppId;
nsTArray<DataStoreInfo>& mStores;
};
@ -354,6 +356,11 @@ GetDataStoreInfosEnumerator(const uint32_t& aAppId,
return PL_DHASH_NEXT;
}
if (!data->mManifestURL.IsEmpty() &&
!data->mManifestURL.Equals(aInfo->mManifestURL)) {
return PL_DHASH_NEXT;
}
DataStoreInfo* accessInfo = nullptr;
if (!apps->Get(data->mAppId, &accessInfo)) {
return PL_DHASH_NEXT;
@ -873,6 +880,7 @@ DataStoreService::InstallAccessDataStore(uint32_t aAppId,
NS_IMETHODIMP
DataStoreService::GetDataStores(nsIDOMWindow* aWindow,
const nsAString& aName,
const nsAString& aOwner,
nsISupports** aDataStores)
{
// FIXME This will be a thread-safe method.
@ -909,7 +917,7 @@ DataStoreService::GetDataStores(nsIDOMWindow* aWindow,
return NS_OK;
}
rv = GetDataStoreInfos(aName, appId, principal, stores);
rv = GetDataStoreInfos(aName, aOwner, appId, principal, stores);
if (NS_FAILED(rv)) {
RejectPromise(window, promise, rv);
promise.forget(aDataStores);
@ -924,6 +932,7 @@ DataStoreService::GetDataStores(nsIDOMWindow* aWindow,
nsTArray<DataStoreSetting> array;
if (!contentChild->SendDataStoreGetStores(nsAutoString(aName),
nsAutoString(aOwner),
IPC::Principal(principal),
&array)) {
RejectPromise(window, promise, NS_ERROR_FAILURE);
@ -1048,6 +1057,7 @@ DataStoreService::GetDataStoresResolve(nsPIDOMWindow* aWindow,
// name and available for this 'aAppId'.
nsresult
DataStoreService::GetDataStoreInfos(const nsAString& aName,
const nsAString& aOwner,
uint32_t aAppId,
nsIPrincipal* aPrincipal,
nsTArray<DataStoreInfo>& aStores)
@ -1083,13 +1093,14 @@ DataStoreService::GetDataStoreInfos(const nsAString& aName,
}
DataStoreInfo* info = nullptr;
if (apps->Get(aAppId, &info)) {
if (apps->Get(aAppId, &info) &&
(aOwner.IsEmpty() || aOwner.Equals(info->mManifestURL))) {
DataStoreInfo* owned = aStores.AppendElement();
owned->Init(info->mName, info->mOriginURL, info->mManifestURL, false,
info->mEnabled);
}
GetDataStoreInfosData data(mAccessStores, aName, aAppId, aStores);
GetDataStoreInfosData data(mAccessStores, aName, aOwner, aAppId, aStores);
apps->EnumerateRead(GetDataStoreInfosEnumerator, &data);
return NS_OK;
}
@ -1336,6 +1347,7 @@ DataStoreService::RemoveCounter(uint32_t aId)
nsresult
DataStoreService::GetDataStoresFromIPC(const nsAString& aName,
const nsAString& aOwner,
nsIPrincipal* aPrincipal,
nsTArray<DataStoreSetting>* aValue)
{
@ -1349,7 +1361,7 @@ DataStoreService::GetDataStoresFromIPC(const nsAString& aName,
}
nsTArray<DataStoreInfo> stores;
rv = GetDataStoreInfos(aName, appId, aPrincipal, stores);
rv = GetDataStoreInfos(aName, aOwner, appId, aPrincipal, stores);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

View File

@ -53,6 +53,7 @@ public:
nsresult GenerateUUID(nsAString& aID);
nsresult GetDataStoresFromIPC(const nsAString& aName,
const nsAString& aOwner,
nsIPrincipal* aPrincipal,
nsTArray<DataStoreSetting>* aValue);
@ -83,8 +84,8 @@ private:
void GetDataStoresResolve(nsPIDOMWindow* aWindow, Promise* aPromise,
const nsTArray<DataStoreInfo>& aStores);
nsresult GetDataStoreInfos(const nsAString& aName, uint32_t aAppId,
nsIPrincipal* aPrincipal,
nsresult GetDataStoreInfos(const nsAString& aName, const nsAString& aOwner,
uint32_t aAppId, nsIPrincipal* aPrincipal,
nsTArray<DataStoreInfo>& aStores);
void DeleteDataStores(uint32_t aAppId);

View File

@ -8,7 +8,7 @@
interface nsIDOMWindow;
interface nsIPrincipal;
[scriptable, uuid(43a731b9-0b5d-400a-8711-8c912c3c3572)]
[scriptable, uuid(9b59c49a-0cd7-11e4-b096-74d02b97e723)]
interface nsIDataStoreService : nsISupports
{
void installDataStore(in unsigned long appId,
@ -24,7 +24,8 @@ interface nsIDataStoreService : nsISupports
in boolean readOnly);
nsISupports getDataStores(in nsIDOMWindow window,
in DOMString name);
in DOMString name,
in DOMString owner);
boolean checkPermission(in nsIPrincipal principal);
};

View File

@ -6,6 +6,8 @@
<body>
<script type="application/javascript;version=1.7">
var gHostedManifestURL = 'http://test/tests/dom/datastore/tests/file_app.sjs?testToken=file_app_install.html';
function is(a, b, msg) {
alert((a === b ? 'OK' : 'KO') + ' ' + msg)
}
@ -22,19 +24,68 @@
alert('DONE');
}
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
ok(stores[0].owner, 'The dataStore.owner exists');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
var tests = [
// Get datastore with name 'foo'
function() {
navigator.getDataStores('foo').then(function(stores) {
is(stores.length, 1, "getDataStores('foo') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
ok(stores[0].owner, 'The dataStore.owner exists');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
runTest();
}, cbError);
},
navigator.getDataStores('bar').then(function(stores) {
is(stores.length, 1, "getDataStores('bar') returns 1 element");
is(stores[0].name, 'bar', 'The dataStore.name is bar');
ok(stores[0].owner, 'The dataStore.owner exists');
is(stores[0].readOnly, false, 'The dataStore bar is in readonly');
// Get datastore with name 'bar'
function() {
navigator.getDataStores('bar').then(function(stores) {
is(stores.length, 1, "getDataStores('bar') returns 1 element");
is(stores[0].name, 'bar', 'The dataStore.name is bar');
ok(stores[0].owner, 'The dataStore.owner exists');
is(stores[0].readOnly, false, 'The dataStore bar is in readonly');
runTest();
}, cbError);
},
// Get datastore with name 'foo' and a specified owner
function() {
navigator.getDataStores('foo', gHostedManifestURL).then(function(stores) {
is(stores.length, 1, "getDataStores('foo','" + gHostedManifestURL +
"') returns 1 element");
is(stores[0].name, 'foo', 'The dataStore.name is foo');
ok(stores[0].owner, 'The dataStore.owner exists');
is(stores[0].readOnly, false, 'The dataStore foo is not in readonly');
runTest();
}, cbError);
},
// Get datastore with name 'foo' and an arbitrary non-existent owner
function() {
navigator.getDataStores('foo', 'non-existent').then(function(stores) {
is(stores.length, 0, "getDataStores('foo','non-existent') returns 0 element");
runTest();
}, cbError);
},
// Get datastore with an arbitrary non-existent name
function() {
navigator.getDataStores('non-existent').then(function(stores) {
is(stores.length, 0, "getDataStores('non-existent') returns 0 element");
runTest();
}, cbError);
},
];
function runTest() {
if (!tests.length) {
finish();
}, cbError);
}, cbError);
return;
}
var test = tests.shift();
test();
}
runTest();
</script>
</html>

View File

@ -2290,6 +2290,7 @@ ContentParent::RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
bool
ContentParent::RecvDataStoreGetStores(
const nsString& aName,
const nsString& aOwner,
const IPC::Principal& aPrincipal,
InfallibleTArray<DataStoreSetting>* aValue)
{
@ -2298,7 +2299,7 @@ ContentParent::RecvDataStoreGetStores(
return false;
}
nsresult rv = service->GetDataStoresFromIPC(aName, aPrincipal, aValue);
nsresult rv = service->GetDataStoresFromIPC(aName, aOwner, aPrincipal, aValue);
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}

View File

@ -577,6 +577,7 @@ private:
virtual bool RecvDataStoreGetStores(
const nsString& aName,
const nsString& aOwner,
const IPC::Principal& aPrincipal,
InfallibleTArray<DataStoreSetting>* aValue) MOZ_OVERRIDE;

View File

@ -603,7 +603,7 @@ parent:
async AudioChannelChangedNotification();
async AudioChannelChangeDefVolChannel(int32_t aChannel, bool aHidden);
sync DataStoreGetStores(nsString aName, Principal aPrincipal)
sync DataStoreGetStores(nsString aName, nsString aOwner, Principal aPrincipal)
returns (DataStoreSetting[] dataStores);
async FilePathUpdateNotify(nsString aType,

View File

@ -123,7 +123,7 @@ Navigator implements NavigatorBattery;
[NoInterfaceObject]
interface NavigatorDataStore {
[Throws, NewObject, Func="Navigator::HasDataStoreSupport"]
Promise getDataStores(DOMString name);
Promise getDataStores(DOMString name, optional DOMString? owner = null);
};
Navigator implements NavigatorDataStore;

View File

@ -206,15 +206,18 @@ class NavigatorGetDataStoresRunnable MOZ_FINAL : public WorkerMainThreadRunnable
{
nsRefPtr<PromiseWorkerProxy> mPromiseWorkerProxy;
const nsString mName;
const nsString mOwner;
ErrorResult& mRv;
public:
NavigatorGetDataStoresRunnable(WorkerPrivate* aWorkerPrivate,
Promise* aWorkerPromise,
const nsAString& aName,
const nsAString& aOwner,
ErrorResult& aRv)
: WorkerMainThreadRunnable(aWorkerPrivate)
, mName(aName)
, mOwner(aOwner)
, mRv(aRv)
{
MOZ_ASSERT(aWorkerPrivate);
@ -246,7 +249,8 @@ protected:
return false;
}
nsRefPtr<Promise> promise = Navigator::GetDataStores(window, mName, mRv);
nsRefPtr<Promise> promise =
Navigator::GetDataStores(window, mName, mOwner, mRv);
promise->AppendNativeHandler(mPromiseWorkerProxy);
return true;
}
@ -255,6 +259,7 @@ protected:
already_AddRefed<Promise>
WorkerNavigator::GetDataStores(JSContext* aCx,
const nsAString& aName,
const nsAString& aOwner,
ErrorResult& aRv)
{
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
@ -267,7 +272,7 @@ WorkerNavigator::GetDataStores(JSContext* aCx,
}
nsRefPtr<NavigatorGetDataStoresRunnable> runnable =
new NavigatorGetDataStoresRunnable(workerPrivate, promise, aName, aRv);
new NavigatorGetDataStoresRunnable(workerPrivate, promise, aName, aOwner, aRv);
runnable->Dispatch(aCx);
return promise.forget();

View File

@ -110,6 +110,7 @@ public:
already_AddRefed<Promise> GetDataStores(JSContext* aCx,
const nsAString& aName,
const nsAString& aOwner,
ErrorResult& aRv);
};