Bug 1529122 - P1 - Remove the origin directory if the requesting client is the only client in the directroy; r=asuth

This patch do:
- Removing the directroy if the requesting client is the only client.
- Avoid unnecessary initialization for a client if it hasn't been initialized.

Differential Revision: https://phabricator.services.mozilla.com/D24371

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Tom Tung 2019-03-25 17:49:44 +00:00
Родитель 6e3591513f
Коммит df8446efe6
5 изменённых файлов: 135 добавлений и 20 удалений

Просмотреть файл

@ -7648,32 +7648,77 @@ void ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
}
UsageInfo usageInfo;
bool initialized;
Client::Type clientType;
if (!mClientType.IsNull()) {
Client::Type clientType = mClientType.Value();
nsAutoString clientDirectoryName;
rv = Client::TypeToText(clientType, clientDirectoryName);
if (NS_WARN_IF(NS_FAILED(rv))) {
// Checking whether there is any other client in the directory is needed.
// If there is not, removing whole directory is needed.
nsCOMPtr<nsIDirectoryEnumerator> originEntries;
bool hasOtherClient = false;
if (NS_WARN_IF(NS_FAILED(
file->GetDirectoryEntries(getter_AddRefs(originEntries)))) ||
!originEntries) {
return;
}
rv = file->Append(clientDirectoryName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
nsCOMPtr<nsIFile> clientFile;
while (NS_SUCCEEDED((rv = originEntries->GetNextFile(
getter_AddRefs(clientFile)))) &&
clientFile) {
bool isDirectory;
rv = clientFile->IsDirectory(&isDirectory);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
if (!isDirectory) {
continue;
}
nsString leafName;
rv = clientFile->GetLeafName(leafName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
rv = Client::TypeFromText(leafName, clientType);
if (NS_FAILED(rv)) {
UNKNOWN_FILE_WARNING(leafName);
continue;
}
if (clientType != mClientType.Value()) {
hasOtherClient = true;
break;
}
}
bool exists;
rv = file->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
if (hasOtherClient) {
Client::Type clientType = mClientType.Value();
nsAutoString clientDirectoryName;
rv = Client::TypeToText(clientType, clientDirectoryName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
rv = file->Append(clientDirectoryName);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
bool exists;
rv = file->Exists(&exists);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
if (!exists) {
continue;
}
}
if (!exists) {
continue;
}
bool initialized;
if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
initialized = aQuotaManager->IsOriginInitialized(origin);
} else {
@ -7687,9 +7732,6 @@ void ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
if (initialized) {
rv = client->GetUsageForOrigin(aPersistenceType, group, origin, dummy,
&usageInfo);
} else {
rv = client->InitOrigin(aPersistenceType, group, origin, dummy,
&usageInfo);
}
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
@ -7711,6 +7753,12 @@ void ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
NS_WARNING("Failed to remove directory, giving up!");
}
// If it hasn't been initialized, we don't need to update the quota and
// notify the removing client.
if (!initialized) {
return;
}
if (aPersistenceType != PERSISTENCE_TYPE_PERSISTENT) {
if (mClientType.IsNull()) {
aQuotaManager->RemoveQuotaForOrigin(aPersistenceType, group, origin);

Двоичные данные
dom/quota/test/unit/clearStorageForPrincipal_profile.zip Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -156,6 +156,17 @@ function clear(callback)
return request;
}
function clearClient(principal, persistence, client, callback)
{
let request =
SpecialPowers._getQuotaManager().clearStoragesForPrincipal(principal,
persistence,
client);
request.callback = callback;
return request;
}
function clearOrigin(principal, persistence, callback)
{
let request =

Просмотреть файл

@ -0,0 +1,54 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* This test is an unit test for clearStorageForPrincipal. It verifies that if
* the removing client is the last client in the targeting origin, then it is
* expected to remove the origin directory as well.
*/
async function testSteps()
{
const testingOrigins = [
{
origin: "http://example.com",
path: "storage/default/http+++example.com/",
only_idb: false
},
{
origin: "http://www.mozilla.org",
path: "storage/default/http+++www.mozilla.org/",
only_idb: true
}
];
const removingClient = "idb";
info("Installing package to create the environment");
// The package is manually created and it contains:
// - storage/default/http+++www.mozilla.org/idb/
// - storage/default/http+++www.example.com/idb/
// - storage/default/http+++www.example.com/cache/
installPackage("clearStorageForPrincipal_profile");
let request;
let file;
for (let i = 0; i < testingOrigins.length; ++i) {
info("Clearing");
request = clearClient(getPrincipal(testingOrigins[i].origin), null,
removingClient);
await requestFinished(request);
info("Verifying");
file = getRelativeFile(testingOrigins[i].path + removingClient);
ok(!file.exists(), "Client file doesn't exist");
file = getRelativeFile(testingOrigins[i].path);
if (testingOrigins[i].only_idb) {
ok(!file.exists(), "Origin file doesn't exist");
} else {
ok(file.exists(), "Origin file does exist");
}
}
}

Просмотреть файл

@ -6,6 +6,7 @@
head = head.js
support-files =
basics_profile.zip
clearStorageForPrincipal_profile.zip
createLocalStorage_profile.zip
defaultStorageUpgrade_profile.zip
getUsage_profile.zip
@ -26,6 +27,7 @@ support-files =
[test_basics.js]
[test_bad_origin_directory.js]
[test_createLocalStorage.js]
[test_clearStorageForPrincipal.js]
[test_defaultStorageUpgrade.js]
[test_getUsage.js]
[test_groupMismatch.js]