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_context.h"
17
18 #include "context.h"
19 #include "cj_utils_ffi.h"
20 #include "cj_macro.h"
21 #include "cj_application_context.h"
22 #include "cj_ability_runtime_error.h"
23 #include "bundle_manager_convert.h"
24 #include "hilog_tag_wrapper.h"
25 #include "js_context_utils.h"
26
27 namespace OHOS {
28 namespace FfiContext {
29 using namespace OHOS::FFI;
30 using namespace OHOS::AbilityRuntime;
31 using namespace OHOS::CJSystemapi::BundleManager;
32
GetContextFromCJ(int64_t id)33 std::shared_ptr<AbilityRuntime::Context> GetContextFromCJ(int64_t id)
34 {
35 auto cjContext = FFI::FFIData::GetData<CJContext>(id);
36 if (cjContext == nullptr) {
37 TAG_LOGE(AAFwkTag::CONTEXT, "null cjContext");
38 return nullptr;
39 }
40 return cjContext->GetContext();
41 }
42
43 extern "C" {
FfiContextGetContext(int64_t id,int32_t type)44 CJ_EXPORT void* FfiContextGetContext(int64_t id, int32_t type)
45 {
46 (void)type;
47 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
48 if (nativeContext == nullptr) {
49 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
50 return nullptr;
51 }
52 // return shared_ptr.get() is not safe!
53 return nativeContext.get();
54 }
55
FfiContextGetApplicationInfo(int64_t id,int32_t type)56 CJ_EXPORT RetApplicationInfoV2 FfiContextGetApplicationInfo(int64_t id, int32_t type)
57 {
58 (void)type;
59 RetApplicationInfoV2 appInfo = {};
60 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
61 if (nativeContext == nullptr) {
62 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
63 return appInfo;
64 }
65 auto applicationInfo = nativeContext->GetApplicationInfo();
66 if (applicationInfo == nullptr) {
67 TAG_LOGE(AAFwkTag::CONTEXT, "null applicationInfo");
68 return appInfo;
69 }
70 return Convert::ConvertApplicationInfoV2(*applicationInfo);
71 }
72
FfiContextGetFilesDir(int64_t id,int32_t type)73 CJ_EXPORT char* FfiContextGetFilesDir(int64_t id, int32_t type)
74 {
75 (void)type;
76 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
77 if (nativeContext == nullptr) {
78 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
79 return nullptr;
80 }
81 auto filesDir = nativeContext->GetFilesDir();
82 return CreateCStringFromString(filesDir);
83 }
84
FfiContextGetCacheDir(int64_t id,int32_t type)85 CJ_EXPORT char* FfiContextGetCacheDir(int64_t id, int32_t type)
86 {
87 (void)type;
88 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
89 if (nativeContext == nullptr) {
90 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
91 return nullptr;
92 }
93 auto cacheDir = nativeContext->GetCacheDir();
94 return CreateCStringFromString(cacheDir);
95 }
96
FfiContextGetTempDir(int64_t id,int32_t type)97 CJ_EXPORT char* FfiContextGetTempDir(int64_t id, int32_t type)
98 {
99 (void)type;
100 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
101 if (nativeContext == nullptr) {
102 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
103 return nullptr;
104 }
105 auto tempDir = nativeContext->GetTempDir();
106 return CreateCStringFromString(tempDir);
107 }
108
FfiContextGetResourceDir(int64_t id,int32_t type)109 CJ_EXPORT char* FfiContextGetResourceDir(int64_t id, int32_t type)
110 {
111 (void)type;
112 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
113 if (nativeContext == nullptr) {
114 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
115 return nullptr;
116 }
117 auto resourceDir = nativeContext->GetResourceDir();
118 return CreateCStringFromString(resourceDir);
119 }
120
FfiContextGetDatabaseDir(int64_t id,int32_t type)121 CJ_EXPORT char* FfiContextGetDatabaseDir(int64_t id, int32_t type)
122 {
123 (void)type;
124 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
125 if (nativeContext == nullptr) {
126 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
127 return nullptr;
128 }
129 auto databaseDir = nativeContext->GetDatabaseDir();
130 return CreateCStringFromString(databaseDir);
131 }
132
FfiContextGetPreferencesDir(int64_t id,int32_t type)133 CJ_EXPORT char* FfiContextGetPreferencesDir(int64_t id, int32_t type)
134 {
135 (void)type;
136 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
137 if (nativeContext == nullptr) {
138 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
139 return nullptr;
140 }
141 auto preferencesDir = nativeContext->GetPreferencesDir();
142 return CreateCStringFromString(preferencesDir);
143 }
144
FfiContextGetBundleCodeDir(int64_t id,int32_t type)145 CJ_EXPORT char* FfiContextGetBundleCodeDir(int64_t id, int32_t type)
146 {
147 (void)type;
148 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
149 if (nativeContext == nullptr) {
150 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
151 return nullptr;
152 }
153 auto bundleCodeDir = nativeContext->GetBundleCodeDir();
154 return CreateCStringFromString(bundleCodeDir);
155 }
156
FfiContextGetDistributedFilesDir(int64_t id,int32_t type)157 CJ_EXPORT char* FfiContextGetDistributedFilesDir(int64_t id, int32_t type)
158 {
159 (void)type;
160 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
161 if (nativeContext == nullptr) {
162 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
163 return nullptr;
164 }
165 auto distributedFilesDir = nativeContext->GetDistributedFilesDir();
166 return CreateCStringFromString(distributedFilesDir);
167 }
168
FfiContextGetCloudFileDir(int64_t id,int32_t type)169 CJ_EXPORT char* FfiContextGetCloudFileDir(int64_t id, int32_t type)
170 {
171 (void)type;
172 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
173 if (nativeContext == nullptr) {
174 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
175 return nullptr;
176 }
177 auto cloudFileDir = nativeContext->GetCloudFileDir();
178 return CreateCStringFromString(cloudFileDir);
179 }
180
FfiContextGetArea(int64_t id,int32_t type)181 CJ_EXPORT int32_t FfiContextGetArea(int64_t id, int32_t type)
182 {
183 (void)type;
184 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
185 if (nativeContext == nullptr) {
186 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
187 return -1;
188 }
189 return nativeContext->GetArea();
190 }
191
FfiContextSwitchArea(int64_t id,int32_t mode)192 CJ_EXPORT void FfiContextSwitchArea(int64_t id, int32_t mode)
193 {
194 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
195 if (nativeContext == nullptr) {
196 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
197 return;
198 }
199 return nativeContext->SwitchArea(mode);
200 }
201
FfiContextGetApplicationContext()202 CJ_EXPORT int64_t FfiContextGetApplicationContext()
203 {
204 auto appContext = ApplicationContextCJ::CJApplicationContext::GetCJApplicationContext(
205 AbilityRuntime::Context::GetApplicationContext());
206 if (appContext == nullptr) {
207 TAG_LOGE(AAFwkTag::CONTEXT, "null app context");
208 return -1;
209 }
210 return appContext->GetID();
211 }
212
FfiContextGetGroupDir(int64_t id,int32_t type,char * groupId)213 CJ_EXPORT char* FfiContextGetGroupDir(int64_t id, int32_t type, char* groupId)
214 {
215 (void)type;
216 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
217 if (nativeContext == nullptr) {
218 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
219 return nullptr;
220 }
221 auto groupDir = nativeContext->GetGroupDir(std::string(groupId));
222 return CreateCStringFromString(groupDir);
223 }
224
FfiContextCreateModuleContext(int64_t id,int32_t type,char * moduleName)225 CJ_EXPORT int64_t FfiContextCreateModuleContext(int64_t id, int32_t type, char* moduleName)
226 {
227 (void)type;
228 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
229 if (nativeContext == nullptr) {
230 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
231 return -1;
232 }
233 auto moduleContext = nativeContext->CreateModuleContext(std::string(moduleName));
234 if (moduleContext == nullptr) {
235 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
236 return -ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
237 }
238 auto cjContext = FFIData::Create<CJContext>(moduleContext);
239 if (cjContext == nullptr) {
240 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
241 return -1;
242 }
243 return cjContext->GetID();
244 }
245
FfiConvertBaseContext2Napi(napi_env env,int64_t id)246 CJ_EXPORT napi_value FfiConvertBaseContext2Napi(napi_env env, int64_t id)
247 {
248 napi_value undefined = nullptr;
249 napi_get_undefined(env, &undefined);
250 auto cjContext = FFIData::GetData<CJContext>(id);
251 if (cjContext == nullptr || cjContext->GetContext() == nullptr) {
252 TAG_LOGE(AAFwkTag::CONTEXT, "cj context null ptr");
253 return undefined;
254 }
255
256 napi_value result = CreateJsBaseContext(env, cjContext->GetContext());
257 if (result == nullptr) {
258 TAG_LOGE(AAFwkTag::CONTEXT, "null object");
259 return undefined;
260 }
261 auto workContext = new (std::nothrow) std::weak_ptr<Context>(cjContext->GetContext());
262 auto res = napi_wrap(env, result, workContext,
263 [](napi_env, void *data, void *) {
264 TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr base context is called");
265 delete static_cast<std::weak_ptr<Context> *>(data);
266 },
267 nullptr, nullptr);
268 if (res != napi_ok && workContext != nullptr) {
269 TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
270 delete workContext;
271 return undefined;
272 }
273 napi_value falseValue = nullptr;
274 napi_get_boolean((napi_env)env, true, &falseValue);
275 napi_set_named_property((napi_env)env, result, "stageMode", falseValue);
276 return result;
277 }
278
FfiCreateBaseContextFromNapi(napi_env env,napi_value baseContext)279 CJ_EXPORT int64_t FfiCreateBaseContextFromNapi(napi_env env, napi_value baseContext)
280 {
281 if (env == nullptr || baseContext == nullptr) {
282 return ERR_INVALID_INSTANCE_CODE;
283 }
284
285 napi_valuetype type;
286 if (napi_typeof(env, baseContext, &type) || type != napi_object) {
287 return ERR_INVALID_INSTANCE_CODE;
288 }
289
290 std::weak_ptr<Context>* context = nullptr;
291 napi_status status = napi_unwrap(env, baseContext, reinterpret_cast<void**>(&context));
292 if (status != napi_ok) {
293 return ERR_INVALID_INSTANCE_CODE;
294 }
295
296 if (context == nullptr || (*context).lock() == nullptr) {
297 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
298 return ERR_INVALID_INSTANCE_CODE;
299 }
300 auto cjContext = FFI::FFIData::Create<CJContext>((*context).lock());
301 if (cjContext == nullptr) {
302 TAG_LOGE(AAFwkTag::CONTEXT, "null cjContext");
303 return ERR_INVALID_INSTANCE_CODE;
304 }
305 return cjContext->GetID();
306 }
307 }
308 }
309 }