• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }