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
FfiContextGetApplicationContext()192 CJ_EXPORT int64_t FfiContextGetApplicationContext()
193 {
194 auto appContext = ApplicationContextCJ::CJApplicationContext::GetCJApplicationContext(
195 AbilityRuntime::Context::GetApplicationContext());
196 if (appContext == nullptr) {
197 TAG_LOGE(AAFwkTag::CONTEXT, "null app context");
198 return -1;
199 }
200 return appContext->GetID();
201 }
202
FfiContextGetGroupDir(int64_t id,int32_t type,char * groupId)203 CJ_EXPORT char* FfiContextGetGroupDir(int64_t id, int32_t type, char* groupId)
204 {
205 (void)type;
206 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
207 if (nativeContext == nullptr) {
208 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
209 return nullptr;
210 }
211 auto groupDir = nativeContext->GetGroupDir(std::string(groupId));
212 return CreateCStringFromString(groupDir);
213 }
214
FfiContextCreateModuleContext(int64_t id,int32_t type,char * moduleName)215 CJ_EXPORT int64_t FfiContextCreateModuleContext(int64_t id, int32_t type, char* moduleName)
216 {
217 (void)type;
218 std::shared_ptr<AbilityRuntime::Context> nativeContext = GetContextFromCJ(id);
219 if (nativeContext == nullptr) {
220 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
221 return -1;
222 }
223 auto moduleContext = nativeContext->CreateModuleContext(std::string(moduleName));
224 if (moduleContext == nullptr) {
225 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
226 return -ERR_ABILITY_RUNTIME_EXTERNAL_INVALID_PARAMETER;
227 }
228 auto cjContext = FFIData::Create<CJContext>(moduleContext);
229 if (cjContext == nullptr) {
230 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
231 return -1;
232 }
233 return cjContext->GetID();
234 }
235
FfiConvertBaseContext2Napi(napi_env env,int64_t id)236 CJ_EXPORT napi_value FfiConvertBaseContext2Napi(napi_env env, int64_t id)
237 {
238 napi_value undefined = nullptr;
239 napi_get_undefined(env, &undefined);
240 auto cjContext = FFIData::GetData<CJContext>(id);
241 if (cjContext == nullptr || cjContext->GetContext() == nullptr) {
242 TAG_LOGE(AAFwkTag::CONTEXT, "cj context null ptr");
243 return undefined;
244 }
245
246 napi_value result = CreateJsBaseContext(env, cjContext->GetContext());
247 if (result == nullptr) {
248 TAG_LOGE(AAFwkTag::CONTEXT, "null object");
249 return undefined;
250 }
251 auto workContext = new (std::nothrow) std::weak_ptr<Context>(cjContext->GetContext());
252 auto res = napi_wrap(env, result, workContext,
253 [](napi_env, void *data, void *) {
254 TAG_LOGD(AAFwkTag::APPKIT, "Finalizer for weak_ptr base context is called");
255 delete static_cast<std::weak_ptr<Context> *>(data);
256 },
257 nullptr, nullptr);
258 if (res != napi_ok && workContext != nullptr) {
259 TAG_LOGE(AAFwkTag::APPKIT, "napi_wrap failed:%{public}d", res);
260 delete workContext;
261 return undefined;
262 }
263 napi_value falseValue = nullptr;
264 napi_get_boolean((napi_env)env, true, &falseValue);
265 napi_set_named_property((napi_env)env, result, "stageMode", falseValue);
266 return result;
267 }
268
FfiCreateBaseContextFromNapi(napi_env env,napi_value baseContext)269 CJ_EXPORT int64_t FfiCreateBaseContextFromNapi(napi_env env, napi_value baseContext)
270 {
271 if (env == nullptr || baseContext == nullptr) {
272 return ERR_INVALID_INSTANCE_CODE;
273 }
274
275 napi_valuetype type;
276 if (napi_typeof(env, baseContext, &type) || type != napi_object) {
277 return ERR_INVALID_INSTANCE_CODE;
278 }
279
280 std::weak_ptr<Context>* context = nullptr;
281 napi_status status = napi_unwrap(env, baseContext, reinterpret_cast<void**>(&context));
282 if (status != napi_ok) {
283 return ERR_INVALID_INSTANCE_CODE;
284 }
285
286 if (context == nullptr || (*context).lock() == nullptr) {
287 TAG_LOGE(AAFwkTag::CONTEXT, "null context");
288 return ERR_INVALID_INSTANCE_CODE;
289 }
290 auto cjContext = FFI::FFIData::Create<CJContext>((*context).lock());
291 if (cjContext == nullptr) {
292 TAG_LOGE(AAFwkTag::CONTEXT, "null cjContext");
293 return ERR_INVALID_INSTANCE_CODE;
294 }
295 return cjContext->GetID();
296 }
297 }
298 }
299 }