blob: b267196280cc7f9540793ea9002fa53820e3b3d7 [file] [log] [blame]
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "extensions/common/user_scripts_allowed_state.h"
#include <map>
#include "base/containers/map_util.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/synchronization/lock.h"
#include "extensions/common/extension_id.h"
namespace extensions {
// A map of context ids to sets of extension ids. An extension id being present
// in the set indicates the user scripts API is allowed for the extension (in
// that context only).
using CurrentUserScriptAllowedMap = std::map<int, std::set<ExtensionId>>;
namespace {
// The user script allowed state map can be checked by different threads
// (e.g. the renderer process main thread and worker thread). Ensure
// thread-safety by locking.
base::Lock& GetUserScriptAllowedMapLock() {
static base::NoDestructor<base::Lock> g_lock;
return *g_lock;
}
CurrentUserScriptAllowedMap& GetUserScriptAllowedMap() {
GetUserScriptAllowedMapLock().AssertAcquired();
static base::NoDestructor<CurrentUserScriptAllowedMap> map;
return *map;
}
} // namespace
bool GetCurrentUserScriptAllowedState(int context_id,
const ExtensionId& extension_id) {
base::AutoLock lock(GetUserScriptAllowedMapLock());
CurrentUserScriptAllowedMap& map = GetUserScriptAllowedMap();
auto iter = map.find(context_id);
return iter != map.end() && iter->second.contains(extension_id);
}
void SetCurrentUserScriptAllowedState(int context_id,
const ExtensionId& extension_id,
bool user_script_allowed_state) {
base::AutoLock lock(GetUserScriptAllowedMapLock());
CurrentUserScriptAllowedMap& map = GetUserScriptAllowedMap();
// Adding an extension.
if (user_script_allowed_state) {
map[context_id].insert(extension_id);
return;
}
// Removing an extension.
auto iter = map.find(context_id);
// If key not found then the extension isn't allowed so there's nothing to do.
if (iter == map.end()) {
return;
}
// Delete the extension so it is no longer allowed.
iter->second.erase(extension_id);
// If no more extensions to track delete the (now unused) key.
if (iter->second.empty()) {
map.erase(iter);
}
}
} // namespace extensions