mirror of
https://github.com/openharmony/ability_ability_runtime.git
synced 2026-08-24 12:43:16 -04:00
增强 ScreenUnlockInterceptor 配置加载失败的鲁棒性
当 ams_extension_config.json 读取或解析失败时,configMap_ 为空, 导致所有 extension 在解锁前被拦截。增加 isConfigLoaded_ 标志位, 配置未加载成功时拦截器直接放行所有 extension。 变更内容: - ExtensionConfig 新增 std::atomic<bool> isConfigLoaded_ 标志 - LoadExtensionConfig 解析完成后设置标志为 true - ScreenUnlockInterceptor::CheckExtensionInterception 增加前置判断, 配置未加载时直接返回 ERR_OK 放行 - 补充 4 个测试用例覆盖新增分支,修改 NoConfig 测试用例适配新逻辑 Signed-off-by: yewei0794 <weiyejxnf@163.com> Co-Authored-By: Agent 🤖 AI[100%] 👌 AI Adopted[100%] 🧑 Human[0%] Co-authored-by: claude (glm-5.1) <ai@local> Change-Id: Iaed7559ddceb3914c69366aa38b58347b5478492
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#ifndef OHOS_ABILITY_RUNTIME_EXTENSION_CONFIG_H
|
||||
#define OHOS_ABILITY_RUNTIME_EXTENSION_CONFIG_H
|
||||
|
||||
#include <atomic>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <nlohmann/json.hpp>
|
||||
@@ -96,6 +97,7 @@ public:
|
||||
bool HasScreenUnlockAccessConfig(const std::string &extensionTypeName);
|
||||
bool HasScreenUnlockAccessAllowList(const std::string &extensionTypeName);
|
||||
bool HasScreenUnlockAccessBlockList(const std::string &extensionTypeName);
|
||||
bool IsConfigLoaded() const;
|
||||
private:
|
||||
void LoadExtensionConfig(const nlohmann::json &object);
|
||||
bool ReadFileInfoJson(const std::string &filePath, nlohmann::json &jsonBuf);
|
||||
@@ -124,6 +126,7 @@ private:
|
||||
|
||||
std::unordered_map<std::string, ExtensionConfigItem> configMap_;
|
||||
std::mutex configMapMutex_;
|
||||
std::atomic<bool> isConfigLoaded_ = false;
|
||||
};
|
||||
} // OHOS
|
||||
} // AAFwk
|
||||
|
||||
@@ -143,6 +143,7 @@ void ExtensionConfig::LoadExtensionConfig(const nlohmann::json &object)
|
||||
LoadExtensionSAEnable(jsonObject, extensionTypeName);
|
||||
LoadScreenUnlockAccess(jsonObject, extensionTypeName);
|
||||
}
|
||||
isConfigLoaded_.store(true);
|
||||
}
|
||||
|
||||
void ExtensionConfig::LoadExtensionAutoDisconnectTime(const nlohmann::json &object,
|
||||
@@ -667,6 +668,11 @@ bool ExtensionConfig::ReadFileInfoJson(const std::string &filePath, nlohmann::js
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExtensionConfig::IsConfigLoaded() const
|
||||
{
|
||||
return isConfigLoaded_.load();
|
||||
}
|
||||
|
||||
bool ExtensionConfig::CheckExtensionUriValid(const std::string &uri)
|
||||
{
|
||||
const size_t memberNum = 4;
|
||||
|
||||
@@ -150,6 +150,10 @@ ErrCode ScreenUnlockInterceptor::CheckExtensionInterception(const std::string &e
|
||||
const std::string &bundleName, bool isSystemApp)
|
||||
{
|
||||
auto extensionConfig = DelayedSingleton<ExtensionConfig>::GetInstance();
|
||||
if (!extensionConfig->IsConfigLoaded()) {
|
||||
TAG_LOGW(AAFwkTag::ABILITYMGR, "extension config not loaded, allow all extensions");
|
||||
return ERR_OK;
|
||||
}
|
||||
if (!extensionConfig->HasScreenUnlockAccessConfig(extensionTypeName)) {
|
||||
TAG_LOGD(AAFwkTag::ABILITYMGR, "no screen_unlock_access config for extension: %{public}s",
|
||||
extensionTypeName.c_str());
|
||||
|
||||
+5
-1
@@ -64,10 +64,14 @@ void ScreenUnlockInterceptorCoverageTest::TearDownTestCase()
|
||||
void ScreenUnlockInterceptorCoverageTest::SetUp()
|
||||
{
|
||||
extensionConfig_->configMap_.clear();
|
||||
extensionConfig_->isConfigLoaded_.store(false);
|
||||
}
|
||||
|
||||
void ScreenUnlockInterceptorCoverageTest::TearDown()
|
||||
{}
|
||||
{
|
||||
extensionConfig_->configMap_.clear();
|
||||
extensionConfig_->isConfigLoaded_.store(false);
|
||||
}
|
||||
|
||||
void ScreenUnlockInterceptorCoverageTest::LoadTestConfig(const std::string &configStr)
|
||||
{
|
||||
|
||||
@@ -63,10 +63,14 @@ void ScreenUnlockInterceptorTest::TearDownTestCase()
|
||||
void ScreenUnlockInterceptorTest::SetUp()
|
||||
{
|
||||
extensionConfig_->configMap_.clear();
|
||||
extensionConfig_->isConfigLoaded_.store(false);
|
||||
}
|
||||
|
||||
void ScreenUnlockInterceptorTest::TearDown()
|
||||
{}
|
||||
{
|
||||
extensionConfig_->configMap_.clear();
|
||||
extensionConfig_->isConfigLoaded_.store(false);
|
||||
}
|
||||
|
||||
void ScreenUnlockInterceptorTest::LoadTestConfig(const std::string &configStr)
|
||||
{
|
||||
@@ -202,12 +206,20 @@ HWTEST_F(ScreenUnlockInterceptorTest, DoProcess_ScreenUnlocked, TestSize.Level1)
|
||||
|
||||
/**
|
||||
* @tc.name: CheckExtensionInterception_NoConfig_ShouldBlock
|
||||
* @tc.desc: Test CheckExtensionInterception when no screen_unlock_access config exists
|
||||
* @tc.desc: Test CheckExtensionInterception when config is loaded but no screen_unlock_access config for this type
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ScreenUnlockInterceptorTest, CheckExtensionInterception_NoConfig_ShouldBlock, TestSize.Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "CheckExtensionInterception_NoConfig_ShouldBlock start";
|
||||
// Load a dummy config so isConfigLoaded_ is true, simulating successful file read
|
||||
const std::string configStr = R"({
|
||||
"ams_extension_config": [{
|
||||
"extension_type_name": "other_type",
|
||||
"screen_unlock_access": { "defaultInterception": false }
|
||||
}]
|
||||
})";
|
||||
LoadTestConfig(configStr);
|
||||
ScreenUnlockInterceptor screenUnlockInterceptor;
|
||||
auto ret = screenUnlockInterceptor.CheckExtensionInterception("form", "com.test.bundle", true);
|
||||
EXPECT_EQ(ret, ERR_BLOCK_START_FIRST_BOOT_SCREEN_UNLOCK);
|
||||
@@ -580,5 +592,103 @@ HWTEST_F(ScreenUnlockInterceptorTest, CheckExtensionInterception_SystemApp_NoInt
|
||||
EXPECT_EQ(ret, ERR_BLOCK_START_FIRST_BOOT_SCREEN_UNLOCK);
|
||||
GTEST_LOG_(INFO) << "CheckExtensionInterception_SystemApp_NoInterceptionConfig end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: CheckExtensionInterception_ConfigNotLoaded_ShouldAllow
|
||||
* @tc.desc: Test CheckExtensionInterception when config file failed to load, should allow all
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ScreenUnlockInterceptorTest, CheckExtensionInterception_ConfigNotLoaded_ShouldAllow, TestSize.Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "CheckExtensionInterception_ConfigNotLoaded_ShouldAllow start";
|
||||
// isConfigLoaded_ is false by default (SetUp resets it), simulating config file read failure
|
||||
EXPECT_FALSE(extensionConfig_->IsConfigLoaded());
|
||||
ScreenUnlockInterceptor screenUnlockInterceptor;
|
||||
// system app extension
|
||||
auto ret = screenUnlockInterceptor.CheckExtensionInterception("form", "com.test.bundle", true);
|
||||
EXPECT_EQ(ret, ERR_OK);
|
||||
// third-party extension
|
||||
ret = screenUnlockInterceptor.CheckExtensionInterception("service", "com.test.bundle", false);
|
||||
EXPECT_EQ(ret, ERR_OK);
|
||||
GTEST_LOG_(INFO) << "CheckExtensionInterception_ConfigNotLoaded_ShouldAllow end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: IsConfigLoaded_AfterLoadConfig_ShouldReturnTrue
|
||||
* @tc.desc: Test IsConfigLoaded returns true after config loaded, false after reset
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ScreenUnlockInterceptorTest, IsConfigLoaded_AfterLoadConfig_ShouldReturnTrue, TestSize.Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "IsConfigLoaded_AfterLoadConfig_ShouldReturnTrue start";
|
||||
EXPECT_FALSE(extensionConfig_->IsConfigLoaded());
|
||||
const std::string configStr = R"({
|
||||
"ams_extension_config": [{
|
||||
"extension_type_name": "form",
|
||||
"screen_unlock_access": { "defaultInterception": false }
|
||||
}]
|
||||
})";
|
||||
LoadTestConfig(configStr);
|
||||
EXPECT_TRUE(extensionConfig_->IsConfigLoaded());
|
||||
GTEST_LOG_(INFO) << "IsConfigLoaded_AfterLoadConfig_ShouldReturnTrue end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: DoProcess_SystemAppExtension_ConfigNotLoaded_ShouldAllow
|
||||
* @tc.desc: Test DoProcess full chain: system app extension with config not loaded should allow
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ScreenUnlockInterceptorTest, DoProcess_SystemAppExtension_ConfigNotLoaded_ShouldAllow, TestSize.Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "DoProcess_SystemAppExtension_ConfigNotLoaded_ShouldAllow start";
|
||||
EXPECT_FALSE(extensionConfig_->IsConfigLoaded());
|
||||
ScreenUnlockInterceptor screenUnlockInterceptor;
|
||||
StartAbilityUtils::startAbilityInfo = std::make_shared<StartAbilityInfo>();
|
||||
StartAbilityUtils::startAbilityInfo->abilityInfo.type = AbilityType::EXTENSION;
|
||||
StartAbilityUtils::startAbilityInfo->abilityInfo.extensionTypeName = "form";
|
||||
StartAbilityUtils::startAbilityInfo->abilityInfo.applicationInfo.isSystemApp = true;
|
||||
StartAbilityUtils::startAbilityInfo->abilityInfo.applicationInfo.allowAppRunWhenDeviceFirstLocked = true;
|
||||
StartAbilityUtils::startAbilityInfo->abilityInfo.applicationInfo.bundleName = "com.test.bundle";
|
||||
|
||||
Want want;
|
||||
AbilityInterceptorParam param(want, 0, 100, true, nullptr, []() { return false; });
|
||||
|
||||
auto screenLockManager = OHOS::ScreenLock::ScreenLockManager::GetInstance();
|
||||
EXPECT_NE(screenLockManager, nullptr);
|
||||
screenLockManager->SetScreenLockedState(true);
|
||||
|
||||
auto ret = screenUnlockInterceptor.DoProcess(param);
|
||||
EXPECT_EQ(ret, ERR_OK);
|
||||
GTEST_LOG_(INFO) << "DoProcess_SystemAppExtension_ConfigNotLoaded_ShouldAllow end";
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: DoProcess_ThirdPartyExtension_ConfigNotLoaded_ShouldAllow
|
||||
* @tc.desc: Test DoProcess full chain: third-party extension with config not loaded should allow
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ScreenUnlockInterceptorTest, DoProcess_ThirdPartyExtension_ConfigNotLoaded_ShouldAllow, TestSize.Level1)
|
||||
{
|
||||
GTEST_LOG_(INFO) << "DoProcess_ThirdPartyExtension_ConfigNotLoaded_ShouldAllow start";
|
||||
EXPECT_FALSE(extensionConfig_->IsConfigLoaded());
|
||||
ScreenUnlockInterceptor screenUnlockInterceptor;
|
||||
StartAbilityUtils::startAbilityInfo = std::make_shared<StartAbilityInfo>();
|
||||
StartAbilityUtils::startAbilityInfo->abilityInfo.type = AbilityType::EXTENSION;
|
||||
StartAbilityUtils::startAbilityInfo->abilityInfo.extensionTypeName = "service";
|
||||
StartAbilityUtils::startAbilityInfo->abilityInfo.applicationInfo.isSystemApp = false;
|
||||
StartAbilityUtils::startAbilityInfo->abilityInfo.applicationInfo.allowAppRunWhenDeviceFirstLocked = false;
|
||||
StartAbilityUtils::startAbilityInfo->abilityInfo.applicationInfo.bundleName = "com.test.thirdparty";
|
||||
|
||||
Want want;
|
||||
AbilityInterceptorParam param(want, 0, 100, true, nullptr, []() { return false; });
|
||||
|
||||
auto screenLockManager = OHOS::ScreenLock::ScreenLockManager::GetInstance();
|
||||
EXPECT_NE(screenLockManager, nullptr);
|
||||
screenLockManager->SetScreenLockedState(true);
|
||||
|
||||
auto ret = screenUnlockInterceptor.DoProcess(param);
|
||||
EXPECT_EQ(ret, ERR_OK);
|
||||
GTEST_LOG_(INFO) << "DoProcess_ThirdPartyExtension_ConfigNotLoaded_ShouldAllow end";
|
||||
}
|
||||
} // namespace AAFwk
|
||||
} // namespace OHOS
|
||||
|
||||
Reference in New Issue
Block a user