diff --git a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h index 6b8e1d8fa82de081d242559a179226d7d2cd3148..9e1d79ed1766ff4afaa0cef1286cb7bb89eeb898 100644 --- a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h +++ b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h @@ -905,6 +905,8 @@ public: virtual bool GetAllBundleStats(int32_t userId, std::vector &bundleStats) override; virtual ErrCode GetAllBundleCacheStat(const sptr processCacheCallback) override; + + ErrCode GetAllBundleCacheStatExec(const sptr processCacheCallback); virtual ErrCode CleanAllBundleCache(const sptr processCacheCallback) override; diff --git a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/process_cache_callback_host.h b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/process_cache_callback_host.h index 3ef7c3b2288f879e96275148fae4d2a91ef1b5de..8871ce8d583399f05f9e50add4773fd0e1d1731f 100644 --- a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/process_cache_callback_host.h +++ b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/process_cache_callback_host.h @@ -33,10 +33,16 @@ public: int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; void OnGetAllBundleCacheFinished(uint64_t cacheStat) override; - uint64_t GetCacheStat(); + uint64_t GetCacheStat() override; void OnCleanAllBundleCacheFinished(int32_t result) override; int32_t GetCleanRet(); + void setAllComplete(bool getAllcomplete) + { + std::lock_guard lock(getAllMutex_); + getAllcomplete_ = getAllcomplete; + } private: + uint64_t cacheSize_ = 0; std::mutex getAllMutex_; bool getAllcomplete_ = false; std::promise getAllPromise_; diff --git a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/process_cache_callback_interface.h b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/process_cache_callback_interface.h index 2d73d29688ab72f2a7afcc0874071f10b9345cf0..9802dd6632274b73e072b21483d325085e87e20c 100644 --- a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/process_cache_callback_interface.h +++ b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/process_cache_callback_interface.h @@ -35,6 +35,11 @@ public: * @param succeeded Indicates the result of progress. */ virtual void OnCleanAllBundleCacheFinished(int32_t resulted) = 0; + + /** + * @brief get all bundle cache stat. + */ + virtual uint64_t GetCacheStat() = 0; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/process_cache_callback_proxy.h b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/process_cache_callback_proxy.h index dcbbe817d6a88055bb1b23af09be4625a28ac2b3..218a6f223ce634256b89aacce087fbd005dfc294 100644 --- a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/process_cache_callback_proxy.h +++ b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/process_cache_callback_proxy.h @@ -37,6 +37,11 @@ public: * @param succeeded Indicates the result of the delete cache files progress. */ virtual void OnCleanAllBundleCacheFinished(int32_t resulted) override; + + /** + * @brief get all bundle cache stat. + */ + virtual uint64_t GetCacheStat() override; private: static inline BrokerDelegator delegator_; diff --git a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp index a1c862bbbc7ba400eaa7d19a616a24310a8b6ba0..77a30e2f15a492028c0fe9bb9c07a440fa3a5fc8 100644 --- a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp +++ b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp @@ -15,6 +15,7 @@ #include "bundle_mgr_proxy.h" +#include #include #include #include @@ -36,6 +37,7 @@ #ifdef BUNDLE_FRAMEWORK_QUICK_FIX #include "quick_fix_manager_proxy.h" #endif +#include "process_cache_callback_host.h" #include "securec.h" namespace OHOS { @@ -49,6 +51,15 @@ const std::unordered_map IPC_ERR_MAP = { {29189, ERR_APPEXECFWK_IPC_REMOTE_DEAD_ERROR} }; +enum class AllBundleCacheSizeState : uint8_t { + GET_START = 0, + GET_END = 1, +}; +std::shared_mutex g_cacheCallbackMutex; +std::vector> g_bundleCacheCallBackList; +std::shared_mutex g_cacheCallstateMutex; +AllBundleCacheSizeState g_getAllBundleCacheSizeState = AllBundleCacheSizeState::GET_END; + bool GetData(void *&buffer, size_t size, const void *data) { if (data == nullptr) { @@ -5636,27 +5647,76 @@ ErrCode BundleMgrProxy::GetAllBundleCacheStat(const sptr APP_LOGI("GetAllBundleCacheStat start"); HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); if (processCacheCallback == nullptr) { - APP_LOGE("fail to CleanBundleCacheFiles due to params error"); + APP_LOGE("fail to GetAllBundleCacheStat due to params error"); + return ERR_BUNDLE_MANAGER_PARAM_ERROR; + } + ErrCode ret = ERR_OK; + std::unique_lock stateLock1(g_cacheCallstateMutex); + if (g_getAllBundleCacheSizeState == AllBundleCacheSizeState::GET_END) { + // set state GET_START + g_getAllBundleCacheSizeState = AllBundleCacheSizeState::GET_START; + stateLock1.unlock(); + APP_LOGI("start first time"); + uint64_t cacheSize = 0; + ret = GetAllBundleCacheStatExec(processCacheCallback); + if (ret == ERR_OK) { + cacheSize = processCacheCallback->GetCacheStat(); + APP_LOGD("exec first time end, size: %{public}" PRIu64, cacheSize); + } + std::unique_lock callBackListLock(g_cacheCallbackMutex); + if (!g_bundleCacheCallBackList.empty()) { + int count = 0; + // finish current callback + processCacheCallback->OnGetAllBundleCacheFinished(cacheSize); + // finish other callback + for (const auto& callback : g_bundleCacheCallBackList) { + count++; + callback->OnGetAllBundleCacheFinished(cacheSize); + APP_LOGD("exec count: %{public}d callback end", count); + } + g_bundleCacheCallBackList.clear(); + } + callBackListLock.unlock(); + + std::unique_lock stateLock2(g_cacheCallstateMutex); + g_getAllBundleCacheSizeState = AllBundleCacheSizeState::GET_END; + stateLock2.unlock(); + } else { + stateLock1.unlock(); + std::unique_lock callBackListLock2(g_cacheCallbackMutex); + g_bundleCacheCallBackList.emplace_back(processCacheCallback); + callBackListLock2.unlock(); + APP_LOGD("add new callback"); + } + return ret; +} + +ErrCode BundleMgrProxy::GetAllBundleCacheStatExec(const sptr processCacheCallback) +{ + APP_LOGI("GetAllBundleCacheStatExec start"); + HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); + if (processCacheCallback == nullptr) { + APP_LOGE("fail to GetAllBundleCacheStatExec due to params error"); return ERR_BUNDLE_MANAGER_PARAM_ERROR; } MessageParcel data; if (!data.WriteInterfaceToken(GetDescriptor())) { - APP_LOGE("failed to GetAllBundleCacheStat due to write MessageParcel fail"); + APP_LOGE("failed to GetAllBundleCacheStatExec due to write MessageParcel fail"); return ERR_APPEXECFWK_PARCEL_ERROR; } if (!data.WriteRemoteObject(processCacheCallback->AsObject())) { - APP_LOGE("fail to GetAllBundleCacheStat, for write parcel failed"); + APP_LOGE("fail to GetAllBundleCacheStatExec, for write parcel failed"); return ERR_APPEXECFWK_PARCEL_ERROR; } MessageParcel reply; if (!SendTransactCmd(BundleMgrInterfaceCode::GET_ALL_BUNDLE_CACHE, data, reply)) { - APP_LOGE("fail to GetAllBundleCacheStat from server"); + APP_LOGE("fail to GetAllBundleCacheStatExec from server"); return ERR_BUNDLE_MANAGER_IPC_TRANSACTION; } ErrCode res = reply.ReadInt32(); if (res != ERR_OK) { - APP_LOGE("fail to GetAllBundleCacheStat from reply: %{public}d", res); + APP_LOGE("fail to GetAllBundleCacheStatExec from reply: %{public}d", res); return res; } return ERR_OK; diff --git a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/process_cache_callback_host.cpp b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/process_cache_callback_host.cpp index 7d8d8c7f00f748c07517fd516abc880e92ccc09a..7a1371ab75f80db17136f4883a0e80169cb6e703 100644 --- a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/process_cache_callback_host.cpp +++ b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/process_cache_callback_host.cpp @@ -15,6 +15,7 @@ #include "process_cache_callback_host.h" +#include #include "app_log_wrapper.h" #include "bundle_framework_core_ipc_interface_code.h" #include "bundle_memory_guard.h" @@ -69,11 +70,18 @@ void ProcessCacheCallbackHost::OnGetAllBundleCacheFinished(uint64_t cacheStat) } getAllcomplete_ = true; getAllPromise_.set_value(cacheStat); + cacheSize_ = cacheStat; + APP_LOGD("OnGetAllBundleCacheFinished, size: %{public}" PRIu64, cacheStat); } uint64_t ProcessCacheCallbackHost::GetCacheStat() { - return getAllFuture_.get(); + if (getAllcomplete_) { + return cacheSize_; + } + // wait for ready + cacheSize_ = getAllFuture_.get(); + return cacheSize_; }; void ProcessCacheCallbackHost::OnCleanAllBundleCacheFinished(int32_t result) diff --git a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/process_cache_callback_proxy.cpp b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/process_cache_callback_proxy.cpp index 1c924541f18c67f5349aeb7bb90c9831146e4779..47464d389d0135065298f62e6a628551cd56b8d8 100644 --- a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/process_cache_callback_proxy.cpp +++ b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/process_cache_callback_proxy.cpp @@ -89,5 +89,10 @@ void ProcessCacheCallbackProxy::OnCleanAllBundleCacheFinished(int32_t result) APP_LOGW("call OnCleanAllBundleCacheFinished fail, for transact failed, error code: %{public}d", ret); } } + +uint64_t ProcessCacheCallbackProxy::GetCacheStat() +{ + return 0; +}; } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/test/unittest/bundle_mgr_proxy_test/bundle_mgr_proxy_test.cpp b/interfaces/inner_api/test/unittest/bundle_mgr_proxy_test/bundle_mgr_proxy_test.cpp index a2a96eba35862d15807c99070805b3a7ab431420..4b27878124dbc184d4c6efbc5d1b741b26e08ea3 100644 --- a/interfaces/inner_api/test/unittest/bundle_mgr_proxy_test/bundle_mgr_proxy_test.cpp +++ b/interfaces/inner_api/test/unittest/bundle_mgr_proxy_test/bundle_mgr_proxy_test.cpp @@ -38,6 +38,7 @@ #ifdef BUNDLE_FRAMEWORK_QUICK_FIX #include "quick_fix_manager_proxy.h" #endif +#include "process_cache_callback_host.h" #include "securec.h" using namespace testing::ext; diff --git a/interfaces/kits/js/bundle_manager/bundle_manager.cpp b/interfaces/kits/js/bundle_manager/bundle_manager.cpp index e8ecd9c2a88a7056870f1faa7c34d17b446ac6d9..ccc9656e749ad669d7248857db1172786bd127f0 100644 --- a/interfaces/kits/js/bundle_manager/bundle_manager.cpp +++ b/interfaces/kits/js/bundle_manager/bundle_manager.cpp @@ -643,7 +643,7 @@ void GetAllBundleCacheSizeComplete(napi_env env, napi_status status, void *data) napi_value GetAllBundleCacheSize(napi_env env, napi_callback_info info) { - APP_LOGD("begin to GetAllBundleCacheSize"); + APP_LOGI("begin to GetAllBundleCacheSize"); GetAllBundleCacheCallbackInfo *asyncCallbackInfo = new (std::nothrow) GetAllBundleCacheCallbackInfo(env); if (asyncCallbackInfo == nullptr) { APP_LOGE("asyncCallbackInfo is null"); @@ -654,7 +654,7 @@ napi_value GetAllBundleCacheSize(napi_env env, napi_callback_info info) auto promise = CommonFunc::AsyncCallNativeMethod( env, asyncCallbackInfo, GET_ALL_BUNDLE_CACHE_SIZE, GetAllBundleCacheSizeExec, GetAllBundleCacheSizeComplete); callbackPtr.release(); - APP_LOGD("call GetAllBundleCacheSize done"); + APP_LOGI("call GetAllBundleCacheSize done"); return promise; } diff --git a/services/bundlemgr/test/unittest/bms_bundle_kit_service_test/bms_bundle_kit_service_test.cpp b/services/bundlemgr/test/unittest/bms_bundle_kit_service_test/bms_bundle_kit_service_test.cpp index de9a0438f1d1ca2f02c3575cc1d4635bcfa9953d..82b6052d96fd5e1265279f0bb86c6588566ec44f 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_kit_service_test/bms_bundle_kit_service_test.cpp +++ b/services/bundlemgr/test/unittest/bms_bundle_kit_service_test/bms_bundle_kit_service_test.cpp @@ -375,7 +375,7 @@ public: {} void OnGetAllBundleCacheFinished(uint64_t cacheStat) override; void OnCleanAllBundleCacheFinished(int32_t result) override; - uint64_t GetCacheStat(); + uint64_t GetCacheStat() override; int32_t GetDelRet(); private: std::shared_ptr> cacheStat_; diff --git a/services/bundlemgr/test/unittest/bms_bundle_mgr_proxy_test/bms_bundle_mgr_proxy_test.cpp b/services/bundlemgr/test/unittest/bms_bundle_mgr_proxy_test/bms_bundle_mgr_proxy_test.cpp index fec8787aeb58fca3790fb2ffcdc4933d87af527f..e9d15719f46f973c988c3456dbb015ab0080d997 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_mgr_proxy_test/bms_bundle_mgr_proxy_test.cpp +++ b/services/bundlemgr/test/unittest/bms_bundle_mgr_proxy_test/bms_bundle_mgr_proxy_test.cpp @@ -20,6 +20,7 @@ #include "bundle_mgr_proxy.h" #include "if_system_ability_manager.h" #include "iservice_registry.h" +#include "process_cache_callback_host.h" #include "system_ability_definition.h" #include "want.h" @@ -1102,5 +1103,28 @@ HWTEST_F(BmsBundleMgrProxyTest, ParseStr_0100, Function | MediumTest | Level0) auto res = ParseStr(buf, itemLen, index, result); EXPECT_TRUE(res); } + +/** + * @tc.number: ProcessCacheCallbackHost_0100 + * @tc.name: test the ProcessCacheCallbackHost + * @tc.desc: 1. test ProcessCacheCallbackHost + */ +HWTEST_F(BmsBundleMgrProxyTest, ProcessCacheCallbackHost_0100, Function | MediumTest | Level1) +{ + sptr impl; + BundleMgrProxy bundleMgrProxy(impl); + sptr getCache = new (std::nothrow) ProcessCacheCallbackHost(); + EXPECT_NE(getCache, nullptr); + + // test finish + getCache->OnGetAllBundleCacheFinished(2); + uint64_t cacheSize = getCache->GetCacheStat(); + EXPECT_EQ(cacheSize, 2); + + // test no finish, wait timeout + getCache->setAllComplete(false); + cacheSize = getCache->GetCacheStat(); + EXPECT_EQ(cacheSize, 2); +} } } \ No newline at end of file diff --git a/test/systemtest/common/bms/acts_bms_kit_system_test/acts_bms_kit_system_test.cpp b/test/systemtest/common/bms/acts_bms_kit_system_test/acts_bms_kit_system_test.cpp index b20437c1fe6047a5045da87308afe79c6567b0ca..b86e45a5daadf48491cc8f4328187dd3964e7549 100644 --- a/test/systemtest/common/bms/acts_bms_kit_system_test/acts_bms_kit_system_test.cpp +++ b/test/systemtest/common/bms/acts_bms_kit_system_test/acts_bms_kit_system_test.cpp @@ -14,6 +14,7 @@ */ #define private public +#include #include #include #include @@ -180,7 +181,7 @@ public: {} void OnGetAllBundleCacheFinished(uint64_t cacheStat) override; void OnCleanAllBundleCacheFinished(int32_t result) override; - uint64_t GetCacheStat(); + uint64_t GetCacheStat() override; int32_t GetDelRet(); private: std::shared_ptr> cacheStat_; @@ -228,6 +229,23 @@ int32_t ProcessCacheCallbackImpl::GetDelRet() return -1; }; +class TestGetAllBundleCacheCallBack : public ProcessCacheCallbackHost { +public: + uint64_t GetCacheStat() override; +}; + +uint64_t TestGetAllBundleCacheCallBack::GetCacheStat() +{ + sleep(3); + if (getAllcomplete_) { + APP_LOGI("GetCacheStat cacheSize_: %{public}" PRIu64, cacheSize_); + return cacheSize_; + } + cacheSize_ = getAllFuture_.get(); + APP_LOGI("GetCacheStat getAllFuture_: %{public}" PRIu64, cacheSize_); + return cacheSize_; +} + class CleanCacheCallBackImpl : public CleanCacheCallbackHost { public: CleanCacheCallBackImpl(); @@ -10104,34 +10122,6 @@ HWTEST_F(ActsBmsKitSystemTest, GetAllBundleDirs_0002, Function | MediumTest | Le std::cout << "END GetAllBundleDirs_0002" << std::endl; } -/** - * @tc.number: GetAllBundleCacheStat_0001 - * @tc.name: test GetAllBundleCacheStat interface - * @tc.desc: 1. call GetAllBundleCacheStat - */ -HWTEST_F(ActsBmsKitSystemTest, GetAllBundleCacheStat_0001, Function | MediumTest | Level1) -{ - std::cout << "START GetAllBundleCacheStat_0001" << std::endl; - sptr bundleMgrProxy = GetBundleMgrProxy(); - EXPECT_NE(bundleMgrProxy, nullptr); - if (bundleMgrProxy != nullptr) { - setuid(Constants::STORAGE_MANAGER_UID); - sptr getCache = new (std::nothrow) ProcessCacheCallbackImpl(); - ErrCode ret; - if (getCache == nullptr) { - ret = bundleMgrProxy->GetAllBundleCacheStat(getCache); - EXPECT_EQ(ret, ERR_BUNDLE_MANAGER_PARAM_ERROR); - } else { - ret = bundleMgrProxy->GetAllBundleCacheStat(getCache); - EXPECT_EQ(ret, ERR_OK); - setuid(Constants::FOUNDATION_UID); - ret = bundleMgrProxy->GetAllBundleCacheStat(getCache); - EXPECT_EQ(ret, ERR_OK); - } - } - std::cout << "END GetAllBundleCacheStat_0001" << std::endl; -} - /** * @tc.number: CleanAllBundleCache_0001 * @tc.name: test CleanAllBundleCache interface @@ -10159,5 +10149,46 @@ HWTEST_F(ActsBmsKitSystemTest, CleanAllBundleCache_0001, Function | MediumTest | } std::cout << "END CleanAllBundleCache_0001" << std::endl; } + +/** + * @tc.number: GetAllBundleCacheStat_0002 + * @tc.name: test GetAllBundleCacheStat interface + * @tc.desc: 1. call GetAllBundleCacheStat + */ +HWTEST_F(ActsBmsKitSystemTest, GetAllBundleCacheStat_0002, Function | MediumTest | Level1) +{ + std::cout << "START GetAllBundleCacheStat_0002" << std::endl; + sptr bundleMgrProxy = GetBundleMgrProxy(); + EXPECT_NE(bundleMgrProxy, nullptr); + + ErrCode ret = ERR_OK; + sptr getCache1 = nullptr; + // test param is nullptr + ret = bundleMgrProxy->GetAllBundleCacheStat(getCache1); + EXPECT_EQ(ret, ERR_BUNDLE_MANAGER_PARAM_ERROR); + + // test one calling + getCache1 = new (std::nothrow) TestGetAllBundleCacheCallBack(); + EXPECT_NE(getCache1, nullptr); + ret = bundleMgrProxy->GetAllBundleCacheStat(getCache1); + EXPECT_EQ(ret, ERR_OK); + sleep(5); + + // test multi calling + sptr getCache2 = new (std::nothrow) TestGetAllBundleCacheCallBack(); + EXPECT_NE(getCache2, nullptr); + sptr getCache3 = new (std::nothrow) TestGetAllBundleCacheCallBack(); + EXPECT_NE(getCache2, nullptr); + sptr getCache4 = new (std::nothrow) TestGetAllBundleCacheCallBack(); + EXPECT_NE(getCache2, nullptr); + + ret = bundleMgrProxy->GetAllBundleCacheStat(getCache2); + EXPECT_EQ(ret, ERR_OK); + ret = bundleMgrProxy->GetAllBundleCacheStat(getCache3); + EXPECT_EQ(ret, ERR_OK); + ret = bundleMgrProxy->GetAllBundleCacheStat(getCache4); + EXPECT_EQ(ret, ERR_OK); + std::cout << "END GetAllBundleCacheStat_0002" << std::endl; +} } // namespace AppExecFwk } // namespace OHOS \ No newline at end of file