Skip to content

Commit

Permalink
Bug 1707963: Let the PermissionManager be initialized lazily but not …
Browse files Browse the repository at this point in the history
…after shutdown started. r=permissions-reviewers,timhuang,janv

Differential Revision: https://phabricator.services.mozilla.com/D132088
  • Loading branch information
jensstutte committed Dec 14, 2021
1 parent 71f30bf commit e8d4b25
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 54 deletions.
58 changes: 22 additions & 36 deletions extensions/permissions/PermissionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "mozilla/AbstractThread.h"
#include "mozilla/AppShutdown.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/ContentPrincipal.h"
Expand Down Expand Up @@ -612,12 +613,6 @@ PermissionManager::PermissionKey::CreateFromURI(nsIURI* aURI,
return new PermissionKey(origin);
}

/* static */
void PermissionManager::Startup() {
nsCOMPtr<nsIPermissionManager> permManager =
do_GetService("@mozilla.org/permissionmanager;1");
}

////////////////////////////////////////////////////////////////////////////////
// PermissionManager Implementation

Expand All @@ -628,7 +623,6 @@ PermissionManager::PermissionManager()
: mMonitor("PermissionManager::mMonitor"),
mState(eInitializing),
mMemoryOnlyDB(false),
mBlockerAdded(false),
mLargestID(0) {}

PermissionManager::~PermissionManager() {
Expand Down Expand Up @@ -679,6 +673,12 @@ PermissionManager* PermissionManager::GetInstance() {
}

nsresult PermissionManager::Init() {
// If we are already shutting down, do not permit a creation.
// This must match the phase in GetAsyncShutdownBarrier.
if (AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMWillShutdown)) {
return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
}

// If the 'permissions.memory_only' pref is set to true, then don't write any
// permission settings to disk, but keep them in a memory-only database.
mMemoryOnlyDB = Preferences::GetBool("permissions.memory_only", false);
Expand All @@ -705,31 +705,22 @@ nsresult PermissionManager::Init() {

nsCOMPtr<nsIObserverService> observerService = services::GetObserverService();
if (observerService) {
observerService->AddObserver(this, "profile-before-change", true);
observerService->AddObserver(this, "profile-do-change", true);
observerService->AddObserver(this, "testonly-reload-permissions-from-disk",
true);
}

if (XRE_IsParentProcess()) {
nsCOMPtr<nsIAsyncShutdownClient> asc = GetShutdownPhase();
if (asc) {
nsAutoString blockerName;
MOZ_ALWAYS_SUCCEEDS(GetName(blockerName));

// This method can fail during some xpcshell-tests.
nsresult rv =
asc->AddBlocker(this, NS_LITERAL_STRING_FROM_CSTRING(__FILE__),
__LINE__, blockerName);
Unused << NS_WARN_IF(NS_FAILED(rv));
if (NS_SUCCEEDED(rv)) {
mBlockerAdded = true;
}
nsCOMPtr<nsIAsyncShutdownClient> asc = GetAsyncShutdownBarrier();
if (!asc) {
return NS_ERROR_NOT_AVAILABLE;
}
nsAutoString blockerName;
MOZ_ALWAYS_SUCCEEDS(GetName(blockerName));

if (!mBlockerAdded) {
ClearOnShutdown(&gPermissionManager);
}
nsresult rv = asc->AddBlocker(
this, NS_LITERAL_STRING_FROM_CSTRING(__FILE__), __LINE__, blockerName);
NS_ENSURE_SUCCESS(rv, rv);
}

AddIdleDailyMaintenanceJob();
Expand Down Expand Up @@ -2556,15 +2547,7 @@ NS_IMETHODIMP PermissionManager::Observe(nsISupports* aSubject,
const char16_t* someData) {
ENSURE_NOT_CHILD_PROCESS;

if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
if (!mBlockerAdded) {
// The profile is about to change and the shutdown blocker has not been
// added yet (we are probably in a xpcshell-test).
RemoveIdleDailyMaintenanceJob();
RemoveAllFromMemory();
CloseDB(eNone);
}
} else if (!nsCRT::strcmp(aTopic, "profile-do-change")) {
if (!nsCRT::strcmp(aTopic, "profile-do-change")) {
// the profile has already changed; init the db from the new location
InitDB(false);
} else if (!nsCRT::strcmp(aTopic, "testonly-reload-permissions-from-disk")) {
Expand Down Expand Up @@ -3827,7 +3810,7 @@ nsresult PermissionManager::TestPermissionWithoutDefaultsFromPrincipal(
void PermissionManager::MaybeCompleteShutdown() {
MOZ_ASSERT(NS_IsMainThread());

nsCOMPtr<nsIAsyncShutdownClient> asc = GetShutdownPhase();
nsCOMPtr<nsIAsyncShutdownClient> asc = GetAsyncShutdownBarrier();
MOZ_ASSERT(asc);

DebugOnly<nsresult> rv = asc->RemoveBlocker(this);
Expand Down Expand Up @@ -3866,7 +3849,8 @@ PermissionManager::GetState(nsIPropertyBag** aBagOut) {
return NS_OK;
}

nsCOMPtr<nsIAsyncShutdownClient> PermissionManager::GetShutdownPhase() const {
nsCOMPtr<nsIAsyncShutdownClient> PermissionManager::GetAsyncShutdownBarrier()
const {
nsresult rv;
nsCOMPtr<nsIAsyncShutdownService> svc =
do_GetService("@mozilla.org/async-shutdown-service;1", &rv);
Expand All @@ -3875,7 +3859,9 @@ nsCOMPtr<nsIAsyncShutdownClient> PermissionManager::GetShutdownPhase() const {
}

nsCOMPtr<nsIAsyncShutdownClient> client;
rv = svc->GetProfileBeforeChange(getter_AddRefs(client));
// This feels very late but there seem to be other services that rely on
// us later than "profile-before-change".
rv = svc->GetXpcomWillShutdown(getter_AddRefs(client));
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));

return client;
Expand Down
13 changes: 1 addition & 12 deletions extensions/permissions/PermissionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,6 @@ class PermissionManager final : public nsIPermissionManager,
nsIURI* aURI, const OriginAttributes* aOriginAttributes,
const nsACString& aType, uint32_t* aPermission);

/**
* Initialize the permission-manager service.
* The permission manager is always initialized at startup because when it
* was lazy-initialized on demand, it was possible for it to be created
* once shutdown had begun, resulting in the manager failing to correctly
* shutdown because it missed its shutdown observer notification.
*/
static void Startup();

nsresult RemovePermissionsWithAttributes(OriginAttributesPattern& aAttrs);

/**
Expand Down Expand Up @@ -529,7 +520,7 @@ class PermissionManager final : public nsIPermissionManager,
uint32_t aExpireType, int64_t aExpireTime,
int64_t aModificationTime, int64_t aId);

nsCOMPtr<nsIAsyncShutdownClient> GetShutdownPhase() const;
nsCOMPtr<nsIAsyncShutdownClient> GetAsyncShutdownBarrier() const;

void MaybeCompleteShutdown();

Expand Down Expand Up @@ -646,8 +637,6 @@ class PermissionManager final : public nsIPermissionManager,

bool mMemoryOnlyDB;

bool mBlockerAdded;

nsTHashtable<PermissionHashKey> mPermissionTable;
// a unique, monotonically increasing id used to identify each database entry
int64_t mLargestID;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ var newClassID = Services.uuid.generateUUID();

var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
var oldClassID = registrar.contractIDToCID(CONTRACT_ID);
var oldFactory = Components.manager.getClassObject(
Cc[CONTRACT_ID],
Ci.nsIFactory
);
// TODO: There was a var oldFactory = here causing linter errors as it
// was unused. We should check if this function call is needed at all.
Components.manager.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory);
registrar.registerFactory(newClassID, "", CONTRACT_ID, factory);

function cleanupFactory() {
Expand Down Expand Up @@ -58,6 +57,11 @@ add_task(function test() {
Assert.ok(true, "There wasn't a nsINavHistoryService");
}

// We need to execute a pm method to be sure that the DB is fully
// initialized.
var pm = Services.perms;
Assert.ok(pm.all.length >= 0, "Permission manager not initialized?");

let db = Services.storage.openDatabase(GetPermissionsFile(profile));
db.schemaVersion = 4;
db.executeSimpleSQL("DROP TABLE moz_perms");
Expand Down
2 changes: 0 additions & 2 deletions layout/build/nsLayoutStatics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,6 @@ nsresult nsLayoutStatics::Initialize() {

ProcessPriorityManager::Init();

PermissionManager::Startup();

UIDirectionManager::Initialize();

CacheObserver::Init();
Expand Down

0 comments on commit e8d4b25

Please sign in to comment.