diff --git a/frameworks/c/ability_runtime/src/application_context.cpp b/frameworks/c/ability_runtime/src/application_context.cpp index f7df0086b0d6c172c398f4c3f64c382c6b90b672..a625ffc6a814cfc4ca0d23caf75de42c3c234422 100644 --- a/frameworks/c/ability_runtime/src/application_context.cpp +++ b/frameworks/c/ability_runtime/src/application_context.cpp @@ -303,6 +303,42 @@ AbilityRuntime_ErrorCode OH_AbilityRuntime_ApplicationContextGetResourceDir(cons return WriteStringToBuffer(resourceDir, buffer, bufferSize, writeLength); } +AbilityRuntime_ErrorCode OH_AbilityRuntime_ApplicationContextGetLaunchParameter( + char* buffer, const int32_t bufferSize, int32_t* writeLength) +{ + TAG_LOGD(AAFwkTag::APPKIT, "%{public}s called", __func__); + auto ret = CheckParameters(buffer, writeLength); + if (ret != ABILITY_RUNTIME_ERROR_CODE_NO_ERROR) { + return ret; + } + const auto appContext = Context::GetApplicationContext(); + if (appContext == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "appContext is null"); + return ABILITY_RUNTIME_ERROR_CODE_CONTEXT_NOT_EXIST; + } + + const std::string launchParameter = appContext->GetLaunchParameter(); + return WriteStringToBuffer(launchParameter, buffer, bufferSize, writeLength); +} + +AbilityRuntime_ErrorCode OH_AbilityRuntime_ApplicationContextGetLatestParameter( + char* buffer, const int32_t bufferSize, int32_t* writeLength) +{ + TAG_LOGD(AAFwkTag::APPKIT, "%{public}s called", __func__); + auto ret = CheckParameters(buffer, writeLength); + if (ret != ABILITY_RUNTIME_ERROR_CODE_NO_ERROR) { + return ret; + } + const auto appContext = Context::GetApplicationContext(); + if (appContext == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "appContext is null"); + return ABILITY_RUNTIME_ERROR_CODE_CONTEXT_NOT_EXIST; + } + + const std::string latestParameter = appContext->GetLatestParameter(); + return WriteStringToBuffer(latestParameter, buffer, bufferSize, writeLength); +} + AbilityRuntime_ErrorCode OH_AbilityRuntime_StartSelfUIAbility(AbilityBase_Want *want) { TAG_LOGD(AAFwkTag::APPKIT, "StartSelfUIAbility called"); diff --git a/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp b/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp index cbc1fd0f01a90cdefd63fdd503d2c081e612b600..c45475a3e9d8f53f6358e4b77cd4ab629facf4b0 100644 --- a/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp +++ b/frameworks/native/ability/native/ability_runtime/js_ui_ability.cpp @@ -451,6 +451,7 @@ void JsUIAbility::OnStart(const Want &want, sptr sessionInfo auto applicationContext = AbilityRuntime::Context::GetApplicationContext(); if (applicationContext != nullptr) { + applicationContext->SetLaunchParameter(want); applicationContext->DispatchOnAbilityWillCreate(jsAbilityObj_); } @@ -1766,6 +1767,7 @@ void JsUIAbility::OnNewWant(const Want &want) auto applicationContext = AbilityRuntime::Context::GetApplicationContext(); if (applicationContext != nullptr) { + applicationContext->SetLatestParameter(want); applicationContext->DispatchOnWillNewWant(jsAbilityObj_); } diff --git a/frameworks/native/appkit/ability_runtime/context/application_context.cpp b/frameworks/native/appkit/ability_runtime/context/application_context.cpp index 9bf0dfe0465ffc0de92b092f7a02a63d0bf970a9..5f57c32f64d876e714f7107b640de3ff00fa692e 100644 --- a/frameworks/native/appkit/ability_runtime/context/application_context.cpp +++ b/frameworks/native/appkit/ability_runtime/context/application_context.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -670,6 +670,35 @@ std::string ApplicationContext::GetCloudFileDir() return (contextImpl_ != nullptr) ? contextImpl_->GetCloudFileDir() : ""; } +std::string ApplicationContext::GetLaunchParameter() const +{ + return (contextImpl_ != nullptr) ? contextImpl_->GetLaunchParameter() : ""; +} + +void ApplicationContext::SetLaunchParameter(const AAFwk::Want &want) +{ + if (contextImpl_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null contextImpl_"); + return; + } + contextImpl_->SetLaunchParameter(want); + contextImpl_->SetLatestParameter(want); +} + +std::string ApplicationContext::GetLatestParameter() const +{ + return (contextImpl_ != nullptr) ? contextImpl_->GetLatestParameter() : ""; +} + +void ApplicationContext::SetLatestParameter(const AAFwk::Want &want) +{ + if (contextImpl_ == nullptr) { + TAG_LOGE(AAFwkTag::APPKIT, "null contextImpl_"); + return; + } + contextImpl_->SetLatestParameter(want); +} + sptr ApplicationContext::GetToken() { return (contextImpl_ != nullptr) ? contextImpl_->GetToken() : nullptr; diff --git a/frameworks/native/appkit/ability_runtime/context/context_impl.cpp b/frameworks/native/appkit/ability_runtime/context/context_impl.cpp index 48f7491f3827b595657bd4cb0c2192c6cf6a481b..57114de9547757b7998d49e0752c08adf28f2de3 100644 --- a/frameworks/native/appkit/ability_runtime/context/context_impl.cpp +++ b/frameworks/native/appkit/ability_runtime/context/context_impl.cpp @@ -1718,6 +1718,7 @@ int32_t ContextImpl::CreateHspModuleResourceManager(const std::string &bundleNam UpdateResConfig(GetResourceManager(), resourceManager); return ERR_OK; } + bool ContextImpl::UpdateDisplayConfiguration(std::shared_ptr &contextImpl, uint64_t displayId, float density, std::string direction) { @@ -1763,6 +1764,45 @@ bool ContextImpl::UpdateDisplayConfiguration(std::shared_ptr &conte return true; } +void ContextImpl::SetLaunchParameter(const AAFwk::Want& want) +{ + // only cold-start need save parameter + std::lock_guard lock(launchParameterMutex_); + if (!launchParameter_) { + launchParameter_ = std::make_shared(want.GetParams()); + } +} + +std::string ContextImpl::GetLaunchParameter() +{ + std::lock_guard lock(launchParameterMutex_); + if (launchParameter_ != nullptr) { + return launchParameter_->ToString(); + } + TAG_LOGW(AAFwkTag::APPKIT, "launchParameter_ is null"); + return ""; +} + +void ContextImpl::SetLatestParameter(const AAFwk::Want& want) +{ + std::lock_guard lock(latestParameterMutex_); + if (!latestParameter_) { + latestParameter_ = std::make_shared(want.GetParams()); + } else { + *latestParameter_ = want.GetParams(); + } +} + +std::string ContextImpl::GetLatestParameter() +{ + std::lock_guard lock(latestParameterMutex_); + if (latestParameter_ != nullptr) { + return latestParameter_->ToString(); + } + TAG_LOGW(AAFwkTag::APPKIT, "latestParameter_ is null"); + return ""; +} + #ifdef SUPPORT_GRAPHICS std::shared_ptr ContextImpl::CreateDisplayContext(uint64_t displayId) { diff --git a/interfaces/kits/c/ability_runtime/application_context.h b/interfaces/kits/c/ability_runtime/application_context.h index 0fcab7b5023f7cde45c1d592b90a78cd542cc79c..b89be845b3eae15ca461b53cf5e817bbfa85f095 100644 --- a/interfaces/kits/c/ability_runtime/application_context.h +++ b/interfaces/kits/c/ability_runtime/application_context.h @@ -310,6 +310,39 @@ AbilityRuntime_ErrorCode OH_AbilityRuntime_ApplicationContextGetResourceDir(cons */ AbilityRuntime_ErrorCode OH_AbilityRuntime_ApplicationContextGetVersionCode(int64_t* versionCode); +/** + * @brief Obtain the launch parameter of starting UIAbility. + * + * @param buffer A pointer to a buffer that receives the launch parameter of starting UIAbility. + * @param bufferSize The length of the buffer. + * @param writeLength The string length actually written to the buffer, + * when returning {@link ABILITY_RUNTIME_ERROR_CODE_NO_ERROR}. + * @return The error code. + * {@link ABILITY_RUNTIME_ERROR_CODE_NO_ERROR} if the operation is successful. + * {@link ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID} if the buffer or writeLength is null, + * or the buffer size is less than the minimum buffer size. + * {@link ABILITY_RUNTIME_ERROR_CODE_CONTEXT_NOT_EXIST} if the application context does not exist. + * @since 21 + */ +AbilityRuntime_ErrorCode OH_AbilityRuntime_ApplicationContextGetLaunchParameter( + char* buffer, const int32_t bufferSize, int32_t* writeLength); + +/** + * @brief Obtain the latest parameter of starting UIAbility. + * + * @param buffer A pointer to a buffer that receives the latest parameter of starting UIAbility. + * @param bufferSize The length of the buffer. + * @param writeLength The string length actually written to the buffer, + * when returning {@link ABILITY_RUNTIME_ERROR_CODE_NO_ERROR}. + * @return The error code. + * {@link ABILITY_RUNTIME_ERROR_CODE_NO_ERROR} if the operation is successful. + * {@link ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID} if the buffer or writeLength is null, + * or the buffer size is less than the minimum buffer size. + * {@link ABILITY_RUNTIME_ERROR_CODE_CONTEXT_NOT_EXIST} if the application context does not exist. + * @since 21 + */ +AbilityRuntime_ErrorCode OH_AbilityRuntime_ApplicationContextGetLatestParameter( + char* buffer, const int32_t bufferSize, int32_t* writeLength); #ifdef __cplusplus } // extern "C" #endif diff --git a/interfaces/kits/native/appkit/ability_runtime/context/application_context.h b/interfaces/kits/native/appkit/ability_runtime/context/application_context.h index de9011e7968a170d6e432913a0e00c308fb27f06..599d93f9d24d05ab9f809893289093ee06743e96 100644 --- a/interfaces/kits/native/appkit/ability_runtime/context/application_context.h +++ b/interfaces/kits/native/appkit/ability_runtime/context/application_context.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2024 Huawei Device Co., Ltd. + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -165,6 +165,10 @@ public: using SelfType = ApplicationContext; static const size_t CONTEXT_TYPE_ID; std::string GetDataDir(); + void SetLaunchParameter(const AAFwk::Want &want); + void SetLatestParameter(const AAFwk::Want &want); + std::string GetLaunchParameter() const; + std::string GetLatestParameter() const; protected: bool IsContext(size_t contextTypeId) override diff --git a/interfaces/kits/native/appkit/ability_runtime/context/context_impl.h b/interfaces/kits/native/appkit/ability_runtime/context/context_impl.h index 52a48ac299df5faf86d8e24a12f5b5618bd01f6e..26bd763825a40b1925c85ced183392769e6c1339 100644 --- a/interfaces/kits/native/appkit/ability_runtime/context/context_impl.h +++ b/interfaces/kits/native/appkit/ability_runtime/context/context_impl.h @@ -423,6 +423,14 @@ public: */ std::shared_ptr CreateAreaModeContext(int areaMode) override; + void SetLaunchParameter(const AAFwk::Want& want); + + std::string GetLaunchParameter(); + + void SetLatestParameter(const AAFwk::Want& want); + + std::string GetLatestParameter(); + #ifdef SUPPORT_GRAPHICS /** * @brief Create a context by displayId. This Context updates the density and direction properties @@ -559,6 +567,11 @@ private: std::mutex overlaySubscriberMutex_; std::shared_ptr overlaySubscriber_; std::string processName_; + std::mutex launchParameterMutex_; + std::shared_ptr launchParameter_ = nullptr; + std::mutex latestParameterMutex_; + std::shared_ptr latestParameter_ = nullptr; + #ifdef SUPPORT_GRAPHICS static std::mutex getDisplayConfigCallbackMutex_; static GetDisplayConfigCallback getDisplayConfigCallback_; diff --git a/test/unittest/capi_ability_runtime_application_context_test/capi_ability_runtime_application_context_test.cpp b/test/unittest/capi_ability_runtime_application_context_test/capi_ability_runtime_application_context_test.cpp index 2571a5e36c8495ba92ea2c90eeb84a1b7843f862..ebde4411163ace795c81a8502024346794f71f3e 100644 --- a/test/unittest/capi_ability_runtime_application_context_test/capi_ability_runtime_application_context_test.cpp +++ b/test/unittest/capi_ability_runtime_application_context_test/capi_ability_runtime_application_context_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -22,6 +22,7 @@ #include "context/application_context.h" #include "securec.h" #include "start_options_impl.h" +#include "string_wrapper.h" #include "want_manager.h" #include "want_utils.h" @@ -2393,6 +2394,148 @@ HWTEST_F(CapiAbilityRuntimeApplicationContextTest, OH_AbilityRuntime_StartSelfUI EXPECT_EQ(ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID, result); } +/** + * @tc.number: OH_AbilityRuntime_ApplicationContextGetLaunchParameter_001 + * @tc.desc: Function test with buffer is nullptr and applicationContext is nullptr + * @tc.type: FUNC + */ +HWTEST_F(CapiAbilityRuntimeApplicationContextTest, OH_AbilityRuntime_ApplicationContextGetLaunchParameter_001, + TestSize.Level2) +{ + char buffer[BUFFER_SIZE] = { 0 }; + int32_t writeLength = 0; + + AbilityRuntime_ErrorCode code = + OH_AbilityRuntime_ApplicationContextGetLaunchParameter(NULL, BUFFER_SIZE, &writeLength); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID); + ASSERT_EQ(writeLength, 0); + + code = OH_AbilityRuntime_ApplicationContextGetLaunchParameter(buffer, BUFFER_SIZE, NULL); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID); + + code = OH_AbilityRuntime_ApplicationContextGetLaunchParameter(buffer, BUFFER_SIZE, nullptr); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID); + + code = OH_AbilityRuntime_ApplicationContextGetLaunchParameter(buffer, -1, &writeLength); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_CONTEXT_NOT_EXIST); + ASSERT_EQ(writeLength, 0); + + code = OH_AbilityRuntime_ApplicationContextGetLaunchParameter(buffer, 0, &writeLength); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_CONTEXT_NOT_EXIST); + ASSERT_EQ(writeLength, 0); + + code = OH_AbilityRuntime_ApplicationContextGetLaunchParameter(buffer, BUFFER_SIZE, &writeLength); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_CONTEXT_NOT_EXIST); + ASSERT_EQ(writeLength, 0); +} + +/** + * @tc.number: OH_AbilityRuntime_ApplicationContextGetLaunchParameter_002 + * @tc.desc: Function test + * @tc.type: FUNC + */ +HWTEST_F(CapiAbilityRuntimeApplicationContextTest, OH_AbilityRuntime_ApplicationContextGetLaunchParameter_002, + TestSize.Level2) +{ + char buffer[BUFFER_SIZE] = { 0 }; + int32_t writeLength = 0; + OHOS::AAFwk::Want want; + std::string abilityName = "testAbility"; + std::string deviceId = "testDeviceId"; + std::string bundleName = "testBundleName"; + want.SetElementName(deviceId, bundleName, abilityName); + OHOS::AAFwk::WantParams wantParams; + wantParams.SetParam("key1", AAFwk::String::Box("value1")); + wantParams.SetParam("key2", AAFwk::String::Box("value2")); + want.SetParams(wantParams); + auto applicationContext = ApplicationContext::GetInstance(); + ASSERT_NE(applicationContext, nullptr); + auto contextImpl = std::make_shared(TEST_BUNDLE_NAME); + ASSERT_NE(contextImpl, nullptr); + AbilityRuntime_ErrorCode code = + OH_AbilityRuntime_ApplicationContextGetLaunchParameter(buffer, BUFFER_SIZE, &writeLength); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_NO_ERROR); + + applicationContext->AttachContextImpl(contextImpl); + applicationContext->SetLaunchParameter(want); + code = OH_AbilityRuntime_ApplicationContextGetLaunchParameter(buffer, BUFFER_SIZE, &writeLength); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_NO_ERROR); + ASSERT_EQ(wantParams.ToString(), buffer); + ASSERT_GT(writeLength, 0); + ASSERT_LT(writeLength, BUFFER_SIZE); +} + +/** + * @tc.number: OH_AbilityRuntime_ApplicationContextGetLatestParameter_001 + * @tc.desc: Function test with buffer is nullptr and applicationContext is nullptr + * @tc.type: FUNC + */ +HWTEST_F(CapiAbilityRuntimeApplicationContextTest, OH_AbilityRuntime_ApplicationContextGetLatestParameter_001, + TestSize.Level2) +{ + char buffer[BUFFER_SIZE] = { 0 }; + int32_t writeLength = 0; + + AbilityRuntime_ErrorCode code = + OH_AbilityRuntime_ApplicationContextGetLatestParameter(NULL, BUFFER_SIZE, &writeLength); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID); + ASSERT_EQ(writeLength, 0); + + code = OH_AbilityRuntime_ApplicationContextGetLatestParameter(buffer, BUFFER_SIZE, NULL); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID); + + code = OH_AbilityRuntime_ApplicationContextGetLatestParameter(buffer, BUFFER_SIZE, nullptr); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_PARAM_INVALID); + + code = OH_AbilityRuntime_ApplicationContextGetLatestParameter(buffer, -1, &writeLength); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_CONTEXT_NOT_EXIST); + ASSERT_EQ(writeLength, 0); + + code = OH_AbilityRuntime_ApplicationContextGetLatestParameter(buffer, 0, &writeLength); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_CONTEXT_NOT_EXIST); + ASSERT_EQ(writeLength, 0); + + code = OH_AbilityRuntime_ApplicationContextGetLatestParameter(buffer, BUFFER_SIZE, &writeLength); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_CONTEXT_NOT_EXIST); + ASSERT_EQ(writeLength, 0); +} + +/** + * @tc.number: OH_AbilityRuntime_ApplicationContextGetLatestParameter_002 + * @tc.desc: Function test + * @tc.type: FUNC + */ +HWTEST_F(CapiAbilityRuntimeApplicationContextTest, OH_AbilityRuntime_ApplicationContextGetLatestParameter_002, + TestSize.Level2) +{ + char buffer[BUFFER_SIZE] = { 0 }; + int32_t writeLength = 0; + OHOS::AAFwk::Want want; + std::string abilityName = "testAbility"; + std::string deviceId = "testDeviceId"; + std::string bundleName = "testBundleName"; + want.SetElementName(deviceId, bundleName, abilityName); + OHOS::AAFwk::WantParams wantParams; + wantParams.SetParam("key1", AAFwk::String::Box("value1")); + wantParams.SetParam("key2", AAFwk::String::Box("value2")); + want.SetParams(wantParams); + auto applicationContext = ApplicationContext::GetInstance(); + ASSERT_NE(applicationContext, nullptr); + auto contextImpl = std::make_shared(TEST_BUNDLE_NAME); + ASSERT_NE(contextImpl, nullptr); + AbilityRuntime_ErrorCode code = + OH_AbilityRuntime_ApplicationContextGetLatestParameter(buffer, BUFFER_SIZE, &writeLength); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_NO_ERROR); + + applicationContext->AttachContextImpl(contextImpl); + applicationContext->SetLatestParameter(want); + code = OH_AbilityRuntime_ApplicationContextGetLatestParameter(buffer, BUFFER_SIZE, &writeLength); + ASSERT_EQ(code, ABILITY_RUNTIME_ERROR_CODE_NO_ERROR); + ASSERT_EQ(wantParams.ToString(), buffer); + ASSERT_GT(writeLength, 0); + ASSERT_LT(writeLength, BUFFER_SIZE); +} + /** * @tc.number: ConvertToCommonBusinessErrorCode_001 * @tc.desc: ConvertToCommonBusinessErrorCode