1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "cj_ability_stage.h"
17 #include "cj_ability_stage_context.h"
18 #include "cj_runtime.h"
19 #include "context_impl.h"
20 #include "hilog_tag_wrapper.h"
21 #include "securec.h"
22 
23 using namespace OHOS::AbilityRuntime;
24 
25 namespace {
CreateCStringFromString(const std::string & source)26 char* CreateCStringFromString(const std::string& source)
27 {
28     if (source.size() == 0) {
29         return nullptr;
30     }
31     size_t length = source.size() + 1;
32     auto res = static_cast<char*>(malloc(length));
33     if (res == nullptr) {
34         TAG_LOGE(AAFwkTag::APPKIT, "fail to mallc string.");
35         return nullptr;
36     }
37     if (strcpy_s(res, length, source.c_str()) != 0) {
38         free(res);
39         TAG_LOGE(AAFwkTag::APPKIT, "fail to strcpy source.");
40         return nullptr;
41     }
42     return res;
43 }
44 }
45 
46 extern "C" {
FFICJCurrentHapModuleInfo(int64_t id)47 CJ_EXPORT CurrentHapModuleInfo* FFICJCurrentHapModuleInfo(int64_t id)
48 {
49     auto abilityStageContext = OHOS::FFI::FFIData::GetData<CJAbilityStageContext>(id);
50     if (abilityStageContext == nullptr) {
51         TAG_LOGE(AAFwkTag::APPKIT, "Get abilityStageContext failed. ");
52         return nullptr;
53     }
54 
55     auto hapInfo = abilityStageContext->GetHapModuleInfo();
56     if (hapInfo == nullptr) {
57         TAG_LOGE(AAFwkTag::APPKIT, "CurrentHapMoudleInfo is nullptr.");
58         return nullptr;
59     }
60 
61     CurrentHapModuleInfo* buffer = static_cast<CurrentHapModuleInfo*>(malloc(sizeof(CurrentHapModuleInfo)));
62 
63     if (buffer == nullptr) {
64         TAG_LOGE(AAFwkTag::APPKIT, "Create CurrentHapMoudleInfo failed, CurrentHapMoudleInfo is nullptr.");
65         return nullptr;
66     }
67 
68     buffer->name = CreateCStringFromString(hapInfo->name);
69     buffer->icon = CreateCStringFromString(hapInfo->iconPath);
70     buffer->iconId = hapInfo->iconId;
71     buffer->label = CreateCStringFromString(hapInfo->label);
72     buffer->labelId = hapInfo->labelId;
73     buffer->description = CreateCStringFromString(hapInfo->description);
74     buffer->descriptionId = hapInfo->descriptionId;
75     buffer->mainElementName = CreateCStringFromString(hapInfo->mainElementName);
76     buffer->installationFree = hapInfo->installationFree;
77     buffer->hashValue = CreateCStringFromString(hapInfo->hashValue);
78 
79     return buffer;
80 }
81 
FFIAbilityGetAbilityStageContext(AbilityStageHandle abilityStageHandle)82 CJ_EXPORT int64_t FFIAbilityGetAbilityStageContext(AbilityStageHandle abilityStageHandle)
83 {
84     auto ability = static_cast<CJAbilityStage*>(abilityStageHandle);
85     auto context = ability->GetContext();
86     if (context == nullptr) {
87         TAG_LOGE(AAFwkTag::APPKIT, "GetAbilityStageContext failed, abilityContext is nullptr.");
88         return ERR_INVALID_INSTANCE_CODE;
89     }
90     auto cjStageContext = OHOS::FFI::FFIData::Create<CJAbilityStageContext>(context);
91     if (cjStageContext == nullptr) {
92         TAG_LOGE(AAFwkTag::APPKIT, "GetAbilityStageContext failed, abilityContext is nullptr.");
93         return ERR_INVALID_INSTANCE_CODE;
94     }
95     return cjStageContext->GetID();
96 }
97 }
98 
Create(const std::unique_ptr<Runtime> & runtime,const AppExecFwk::HapModuleInfo & hapModuleInfo)99 std::shared_ptr<CJAbilityStage> CJAbilityStage::Create(
100     const std::unique_ptr<Runtime>& runtime, const AppExecFwk::HapModuleInfo& hapModuleInfo)
101 {
102     if (!runtime) {
103         TAG_LOGE(AAFwkTag::APPKIT, "Runtime does not exist.");
104         return nullptr;
105     }
106     auto& cjRuntime = static_cast<CJRuntime&>(*runtime);
107     // Load cj app library.
108     if (!cjRuntime.IsAppLibLoaded()) {
109         TAG_LOGE(AAFwkTag::APPKIT, "Failed to create CJAbilityStage, applib not loaded.");
110         return nullptr;
111     }
112 
113     auto cjAbilityStageObject = CJAbilityStageObject::LoadModule(hapModuleInfo.moduleName);
114     if (cjAbilityStageObject == nullptr) {
115         cjRuntime.UnLoadCJAppLibrary();
116         TAG_LOGE(AAFwkTag::APPKIT, "Failed to create CJAbilityStage.");
117         return nullptr;
118     }
119 
120     return std::make_shared<CJAbilityStage>(cjAbilityStageObject);
121 }
122 
Init(const std::shared_ptr<Context> & context,const std::weak_ptr<AppExecFwk::OHOSApplication> application)123 void CJAbilityStage::Init(const std::shared_ptr<Context> &context,
124     const std::weak_ptr<AppExecFwk::OHOSApplication> application)
125 {
126     AbilityStage::Init(context, application);
127     if (!cjAbilityStageObject_) {
128         TAG_LOGE(AAFwkTag::APPKIT, "Failed to create CJAbilityStage.");
129         return;
130     }
131     cjAbilityStageObject_->Init(this);
132 }
133 
OnCreate(const AAFwk::Want & want) const134 void CJAbilityStage::OnCreate(const AAFwk::Want& want) const
135 {
136     AbilityStage::OnCreate(want);
137     if (!cjAbilityStageObject_) {
138         TAG_LOGE(AAFwkTag::APPKIT, "CJAbilityStage is not loaded.");
139         return;
140     }
141     TAG_LOGD(AAFwkTag::APPKIT, "CJAbilityStage::OnCreate");
142     cjAbilityStageObject_->OnCreate();
143 }
144 
OnAcceptWant(const AAFwk::Want & want)145 std::string CJAbilityStage::OnAcceptWant(const AAFwk::Want& want)
146 {
147     AbilityStage::OnAcceptWant(want);
148     if (!cjAbilityStageObject_) {
149         TAG_LOGE(AAFwkTag::APPKIT, "CJAbilityStage is not loaded.");
150         return "";
151     }
152     return cjAbilityStageObject_->OnAcceptWant(want);
153 }
154 
OnConfigurationUpdated(const AppExecFwk::Configuration & configuration)155 void CJAbilityStage::OnConfigurationUpdated(const AppExecFwk::Configuration& configuration)
156 {
157     AbilityStage::OnConfigurationUpdated(configuration);
158     auto fullConfig = GetContext()->GetConfiguration();
159     if (!fullConfig) {
160         TAG_LOGE(AAFwkTag::APPKIT, "configuration is nullptr.");
161         return;
162     }
163 
164     if (!cjAbilityStageObject_) {
165         TAG_LOGE(AAFwkTag::APPKIT, "CJAbilityStage is not loaded.");
166         return;
167     }
168     cjAbilityStageObject_->OnConfigurationUpdated(fullConfig);
169 }
170 
OnMemoryLevel(int level)171 void CJAbilityStage::OnMemoryLevel(int level)
172 {
173     AbilityStage::OnMemoryLevel(level);
174     if (!cjAbilityStageObject_) {
175         TAG_LOGE(AAFwkTag::APPKIT, "CJAbilityStage is not loaded.");
176         return;
177     }
178     cjAbilityStageObject_->OnMemoryLevel(level);
179 }
180