1 /*
2 * Copyright (c) 2022-2023 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 "js_enterprise_admin_extension.h"
17
18 #include <string>
19
20 #include "ability_handler.h"
21 #include "edm_log.h"
22 #include "enterprise_admin_extension.h"
23 #include "enterprise_admin_stub_impl.h"
24 #include "js_enterprise_admin_extension_context.h"
25 #include "js_runtime.h"
26 #include "js_runtime_utils.h"
27 #include "runtime.h"
28
29 namespace OHOS {
30 namespace EDM {
31 constexpr size_t JS_NAPI_ARGC_ZERO = 0;
32 constexpr size_t JS_NAPI_ARGC_ONE = 1;
33 constexpr size_t JS_NAPI_ARGC_TWO = 2;
34
Create(const std::unique_ptr<AbilityRuntime::Runtime> & runtime)35 JsEnterpriseAdminExtension* JsEnterpriseAdminExtension::Create(const std::unique_ptr<AbilityRuntime::Runtime>& runtime)
36 {
37 return new JsEnterpriseAdminExtension(static_cast<AbilityRuntime::JsRuntime&>(*runtime));
38 }
39
JsEnterpriseAdminExtension(AbilityRuntime::JsRuntime & jsRuntime)40 JsEnterpriseAdminExtension::JsEnterpriseAdminExtension(AbilityRuntime::JsRuntime& jsRuntime) : jsRuntime_(jsRuntime) {}
~JsEnterpriseAdminExtension()41 JsEnterpriseAdminExtension::~JsEnterpriseAdminExtension()
42 {
43 EDMLOGD("Js enterprise admin extension destructor.");
44 jsRuntime_.FreeNativeReference(std::move(jsObj_));
45 }
46
Init(const std::shared_ptr<AppExecFwk::AbilityLocalRecord> & record,const std::shared_ptr<AppExecFwk::OHOSApplication> & application,std::shared_ptr<AppExecFwk::AbilityHandler> & handler,const sptr<IRemoteObject> & token)47 void JsEnterpriseAdminExtension::Init(const std::shared_ptr<AppExecFwk::AbilityLocalRecord>& record,
48 const std::shared_ptr<AppExecFwk::OHOSApplication>& application,
49 std::shared_ptr<AppExecFwk::AbilityHandler>& handler,
50 const sptr<IRemoteObject>& token)
51 {
52 EnterpriseAdminExtension::Init(record, application, handler, token);
53 std::string srcPath;
54 GetSrcPath(srcPath);
55 if (srcPath.empty()) {
56 EDMLOGI("JsEnterpriseAdminExtension Failed to get srcPath");
57 return;
58 }
59
60 std::string moduleName(Extension::abilityInfo_->moduleName);
61 moduleName.append("::").append(abilityInfo_->name);
62 EDMLOGI("JsEnterpriseAdminExtension::Init moduleName:%{public}s,srcPath:%{public}s.",
63 moduleName.c_str(), srcPath.c_str());
64 AbilityRuntime::HandleScope handleScope(jsRuntime_);
65
66 jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath,
67 Extension::abilityInfo_->compileMode == AbilityRuntime::CompileMode::ES_MODULE);
68 if (jsObj_ == nullptr) {
69 EDMLOGI("JsEnterpriseAdminExtension Failed to get jsObj_");
70 return;
71 }
72 EDMLOGI("JsEnterpriseAdminExtension::Init ConvertNativeValueTo.");
73 JsEnterpriseAdminExtensionContextInit();
74 }
75
JsEnterpriseAdminExtensionContextInit()76 void JsEnterpriseAdminExtension::JsEnterpriseAdminExtensionContextInit()
77 {
78 napi_value obj = jsObj_->GetNapiValue();
79
80 auto env = jsRuntime_.GetNapiEnv();
81 auto context = GetContext();
82 if (context == nullptr) {
83 EDMLOGI("JsEnterpriseAdminExtension Failed to get context");
84 return;
85 }
86 EDMLOGI("JsEnterpriseAdminExtension::Init CreateJsEnterpriseAdminExtensionContext.");
87 napi_value contextObj = CreateJsEnterpriseAdminExtensionContext(env, context);
88 auto shellContextRef = jsRuntime_.LoadSystemModule("enterprise.EnterpriseAdminExtensionContext",
89 &contextObj, JS_NAPI_ARGC_ONE);
90 if (shellContextRef == nullptr) {
91 EDMLOGE("JsEnterpriseAdminExtensionContextInit LoadSystemModule null");
92 return;
93 }
94 contextObj = shellContextRef->GetNapiValue();
95 EDMLOGI("JsEnterpriseAdminExtension::Init Bind.");
96 context->Bind(jsRuntime_, shellContextRef.release());
97 EDMLOGI("JsEnterpriseAdminExtension::SetProperty.");
98 napi_set_named_property(env, obj, "context", contextObj);
99
100 EDMLOGI("Set enterprise admin extension context");
101
102 napi_wrap(env, contextObj, new std::weak_ptr<AbilityRuntime::Context>(context),
103 [](napi_env env, void* data, void*) {
104 EDMLOGI("Finalizer for weak_ptr service extension context is called");
105 delete static_cast<std::weak_ptr<AbilityRuntime::Context>*>(data);
106 }, nullptr, nullptr);
107
108 EDMLOGI("JsEnterpriseAdminExtension::Init end.");
109 }
110
OnStart(const AAFwk::Want & want)111 void JsEnterpriseAdminExtension::OnStart(const AAFwk::Want& want)
112 {
113 EDMLOGI("JsEnterpriseAdminExtension OnStart begin");
114 AbilityRuntime::Extension::OnStart(want);
115 auto task = [this]() {
116 CallObjectMethod("onStart", nullptr, JS_NAPI_ARGC_ZERO);
117 };
118 handler_->PostTask(task);
119 }
120
OnStop()121 void JsEnterpriseAdminExtension::OnStop()
122 {
123 AbilityRuntime::Extension::OnStop();
124 EDMLOGI("JsEnterpriseAdminExtension %{public}s end.", __func__);
125 }
126
OnConnect(const AAFwk::Want & want)127 sptr<IRemoteObject> JsEnterpriseAdminExtension::OnConnect(const AAFwk::Want& want)
128 {
129 AbilityRuntime::Extension::OnConnect(want);
130 EDMLOGI("EnterpriseAdminExtension %{public}s begin.", __func__);
131 sptr<EnterpriseAdminStubImpl> remoteObject = new (std::nothrow) EnterpriseAdminStubImpl(
132 std::static_pointer_cast<JsEnterpriseAdminExtension>(shared_from_this()));
133
134 if (remoteObject == nullptr) {
135 EDMLOGI("OnConnect get null");
136 return remoteObject;
137 }
138 EDMLOGI("JsEnterpriseAdminExtension %{public}s end. ", __func__);
139 return remoteObject->AsObject();
140 }
141
OnDisconnect(const AAFwk::Want & want)142 void JsEnterpriseAdminExtension::OnDisconnect(const AAFwk::Want& want)
143 {
144 EDMLOGI("JsEnterpriseAdminExtension %{public}s begin.", __func__);
145 AbilityRuntime::Extension::OnDisconnect(want);
146 }
147
OnAdminEnabled()148 void JsEnterpriseAdminExtension::OnAdminEnabled()
149 {
150 EDMLOGI("JsEnterpriseAdminExtension::OnAdminEnabled");
151 auto task = [this]() {
152 CallObjectMethod("onAdminEnabled", nullptr, JS_NAPI_ARGC_ZERO);
153 };
154 handler_->PostTask(task);
155 }
156
OnAdminDisabled()157 void JsEnterpriseAdminExtension::OnAdminDisabled()
158 {
159 EDMLOGI("JsEnterpriseAdminExtension::OnAdminDisabled");
160 auto task = [this]() {
161 CallObjectMethod("onAdminDisabled", nullptr, JS_NAPI_ARGC_ZERO);
162 };
163 handler_->PostTask(task);
164 }
165
OnBundleAdded(const std::string & bundleName,int32_t accountId)166 void JsEnterpriseAdminExtension::OnBundleAdded(const std::string &bundleName, int32_t accountId)
167 {
168 EDMLOGI("JsEnterpriseAdminExtension::OnBundleAdded");
169 auto task = [bundleName, accountId, this]() {
170 auto env = jsRuntime_.GetNapiEnv();
171 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, bundleName),
172 AbilityRuntime::CreateJsValue(env, accountId) };
173 CallObjectMethod("onBundleAdded", argv, JS_NAPI_ARGC_TWO);
174 };
175 handler_->PostTask(task);
176 }
177
OnBundleRemoved(const std::string & bundleName,int32_t accountId)178 void JsEnterpriseAdminExtension::OnBundleRemoved(const std::string &bundleName, int32_t accountId)
179 {
180 EDMLOGI("JsEnterpriseAdminExtension::OnBundleRemoved");
181 auto task = [bundleName, accountId, this]() {
182 auto env = jsRuntime_.GetNapiEnv();
183 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, bundleName),
184 AbilityRuntime::CreateJsValue(env, accountId) };
185 CallObjectMethod("onBundleRemoved", argv, JS_NAPI_ARGC_TWO);
186 };
187 handler_->PostTask(task);
188 }
189
OnAppStart(const std::string & bundleName)190 void JsEnterpriseAdminExtension::OnAppStart(const std::string &bundleName)
191 {
192 EDMLOGI("JsEnterpriseAdminExtension::OnAppStart");
193 auto task = [bundleName, this]() {
194 auto env = jsRuntime_.GetNapiEnv();
195 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, bundleName) };
196 CallObjectMethod("onAppStart", argv, JS_NAPI_ARGC_ONE);
197 };
198 handler_->PostTask(task);
199 }
200
OnAppStop(const std::string & bundleName)201 void JsEnterpriseAdminExtension::OnAppStop(const std::string &bundleName)
202 {
203 EDMLOGI("JsEnterpriseAdminExtension::OnAppStop");
204 auto task = [bundleName, this]() {
205 auto env = jsRuntime_.GetNapiEnv();
206 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, bundleName) };
207 CallObjectMethod("onAppStop", argv, JS_NAPI_ARGC_ONE);
208 };
209 handler_->PostTask(task);
210 }
211
OnSystemUpdate(const UpdateInfo & updateInfo)212 void JsEnterpriseAdminExtension::OnSystemUpdate(const UpdateInfo &updateInfo)
213 {
214 EDMLOGI("JsEnterpriseAdminExtension::OnSystemUpdate");
215 auto task = [updateInfo, this]() {
216 auto env = jsRuntime_.GetNapiEnv();
217 napi_value argv[] = { CreateUpdateInfoObject(env, updateInfo) };
218 CallObjectMethod("onSystemUpdate", argv, JS_NAPI_ARGC_ONE);
219 };
220 handler_->PostTask(task);
221 }
222
OnAccountAdded(const int32_t accountId)223 void JsEnterpriseAdminExtension::OnAccountAdded(const int32_t accountId)
224 {
225 EDMLOGI("JsEnterpriseAdminExtension::OnAccountAdded");
226 auto task = [accountId, this]() {
227 auto env = jsRuntime_.GetNapiEnv();
228 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, accountId) };
229 CallObjectMethod("onAccountAdded", argv, JS_NAPI_ARGC_ONE);
230 };
231 handler_->PostTask(task);
232 }
233
OnAccountSwitched(const int32_t accountId)234 void JsEnterpriseAdminExtension::OnAccountSwitched(const int32_t accountId)
235 {
236 EDMLOGI("JsEnterpriseAdminExtension::OnAccountSwitched");
237 auto task = [accountId, this]() {
238 auto env = jsRuntime_.GetNapiEnv();
239 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, accountId) };
240 CallObjectMethod("onAccountSwitched", argv, JS_NAPI_ARGC_ONE);
241 };
242 handler_->PostTask(task);
243 }
244
OnAccountRemoved(const int32_t accountId)245 void JsEnterpriseAdminExtension::OnAccountRemoved(const int32_t accountId)
246 {
247 EDMLOGI("JsEnterpriseAdminExtension::OnAccountRemoved");
248 auto task = [accountId, this]() {
249 auto env = jsRuntime_.GetNapiEnv();
250 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, accountId) };
251 CallObjectMethod("onAccountRemoved", argv, JS_NAPI_ARGC_ONE);
252 };
253 handler_->PostTask(task);
254 }
255
OnKioskModeEntering(const std::string & bundleName,int32_t accountId)256 void JsEnterpriseAdminExtension::OnKioskModeEntering(const std::string &bundleName, int32_t accountId)
257 {
258 EDMLOGI("JsEnterpriseAdminExtension::OnKioskModeEntering");
259 auto task = [bundleName, accountId, this]() {
260 auto env = jsRuntime_.GetNapiEnv();
261 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, bundleName),
262 AbilityRuntime::CreateJsValue(env, accountId) };
263 CallObjectMethod("onKioskModeEntering", argv, JS_NAPI_ARGC_TWO);
264 };
265 handler_->PostTask(task);
266 }
267
OnKioskModeExiting(const std::string & bundleName,int32_t accountId)268 void JsEnterpriseAdminExtension::OnKioskModeExiting(const std::string &bundleName, int32_t accountId)
269 {
270 EDMLOGI("JsEnterpriseAdminExtension::OnKioskModeExiting");
271 auto task = [bundleName, accountId, this]() {
272 auto env = jsRuntime_.GetNapiEnv();
273 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, bundleName),
274 AbilityRuntime::CreateJsValue(env, accountId) };
275 CallObjectMethod("onKioskModeExiting", argv, JS_NAPI_ARGC_TWO);
276 };
277 handler_->PostTask(task);
278 }
279
CreateUpdateInfoObject(napi_env env,const UpdateInfo & updateInfo)280 napi_value JsEnterpriseAdminExtension::CreateUpdateInfoObject(napi_env env, const UpdateInfo &updateInfo)
281 {
282 napi_value nSystemUpdateInfo = nullptr;
283 NAPI_CALL(env, napi_create_object(env, &nSystemUpdateInfo));
284
285 napi_value nVersionName = nullptr;
286 NAPI_CALL(env, napi_create_string_utf8(env, updateInfo.version.c_str(), NAPI_AUTO_LENGTH, &nVersionName));
287 NAPI_CALL(env, napi_set_named_property(env, nSystemUpdateInfo, "versionName", nVersionName));
288
289 napi_value nFirstReceivedTime = nullptr;
290 NAPI_CALL(env, napi_create_int64(env, updateInfo.firstReceivedTime, &nFirstReceivedTime));
291 NAPI_CALL(env, napi_set_named_property(env, nSystemUpdateInfo, "firstReceivedTime", nFirstReceivedTime));
292
293 napi_value nPackageType = nullptr;
294 NAPI_CALL(env, napi_create_string_utf8(env, updateInfo.packageType.c_str(), NAPI_AUTO_LENGTH, &nPackageType));
295 NAPI_CALL(env, napi_set_named_property(env, nSystemUpdateInfo, "packageType", nPackageType));
296
297 return nSystemUpdateInfo;
298 }
299
CallObjectMethod(const char * name,napi_value * argv,size_t argc)300 napi_value JsEnterpriseAdminExtension::CallObjectMethod(const char* name, napi_value* argv, size_t argc)
301 {
302 EDMLOGI("JsEnterpriseAdminExtension::CallObjectMethod(%{public}s), begin", name);
303
304 if (!jsObj_) {
305 EDMLOGW("Not found EnterpriseAdminExtension.js");
306 return nullptr;
307 }
308
309 AbilityRuntime::HandleScope handleScope(jsRuntime_);
310 auto env = jsRuntime_.GetNapiEnv();
311
312 napi_value value = jsObj_->GetNapiValue();
313 if (value == nullptr) {
314 EDMLOGE("Failed to get EnterpriseAdminExtension object");
315 return nullptr;
316 }
317 napi_value method = nullptr;
318 napi_get_named_property(env, value, name, &method);
319
320 if (method == nullptr) {
321 EDMLOGE("Failed to get '%{public}s' from EnterpriseAdminExtension object", name);
322 return nullptr;
323 }
324 napi_valuetype valueType = napi_undefined;
325 napi_typeof(env, method, &valueType);
326 if (valueType != napi_function) {
327 EDMLOGE("'%{public}s' is not function", name);
328 return nullptr;
329 }
330
331 EDMLOGI("JsEnterpriseAdminExtension::CallFunction(%{public}s), success", name);
332 napi_value result = nullptr;
333 napi_status status = napi_call_function(env, value, method, argc, argv, &result);
334 if (status != napi_ok) {
335 EDMLOGE("Failed to call function");
336 }
337 return result;
338 }
339
GetSrcPath(std::string & srcPath)340 void JsEnterpriseAdminExtension::GetSrcPath(std::string& srcPath)
341 {
342 if (!Extension::abilityInfo_->srcEntrance.empty()) {
343 srcPath.append(Extension::abilityInfo_->moduleName + "/");
344 srcPath.append(Extension::abilityInfo_->srcEntrance);
345 srcPath.erase(srcPath.rfind('.'));
346 srcPath.append(".abc");
347 }
348 }
349 } // namespace EDM
350 } // namespace OHOS