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 contextObj = shellContextRef->GetNapiValue();
91 EDMLOGI("JsEnterpriseAdminExtension::Init Bind.");
92 context->Bind(jsRuntime_, shellContextRef.release());
93 EDMLOGI("JsEnterpriseAdminExtension::SetProperty.");
94 napi_set_named_property(env, obj, "context", contextObj);
95
96 EDMLOGI("Set enterprise admin extension context");
97
98 napi_wrap(env, contextObj, new std::weak_ptr<AbilityRuntime::Context>(context),
99 [](napi_env env, void* data, void*) {
100 EDMLOGI("Finalizer for weak_ptr service extension context is called");
101 delete static_cast<std::weak_ptr<AbilityRuntime::Context>*>(data);
102 }, nullptr, nullptr);
103
104 EDMLOGI("JsEnterpriseAdminExtension::Init end.");
105 }
106
OnStart(const AAFwk::Want & want)107 void JsEnterpriseAdminExtension::OnStart(const AAFwk::Want& want)
108 {
109 EDMLOGI("JsEnterpriseAdminExtension OnStart begin");
110 AbilityRuntime::Extension::OnStart(want);
111 auto task = [this]() {
112 CallObjectMethod("onStart", nullptr, JS_NAPI_ARGC_ZERO);
113 };
114 handler_->PostTask(task);
115 }
116
OnStop()117 void JsEnterpriseAdminExtension::OnStop()
118 {
119 AbilityRuntime::Extension::OnStop();
120 EDMLOGI("JsEnterpriseAdminExtension %{public}s end.", __func__);
121 }
122
OnConnect(const AAFwk::Want & want)123 sptr<IRemoteObject> JsEnterpriseAdminExtension::OnConnect(const AAFwk::Want& want)
124 {
125 AbilityRuntime::Extension::OnConnect(want);
126 EDMLOGI("EnterpriseAdminExtension %{public}s begin.", __func__);
127 sptr<EnterpriseAdminStubImpl> remoteObject = new (std::nothrow) EnterpriseAdminStubImpl(
128 std::static_pointer_cast<JsEnterpriseAdminExtension>(shared_from_this()));
129
130 if (remoteObject == nullptr) {
131 EDMLOGI("OnConnect get null");
132 return remoteObject;
133 }
134 EDMLOGI("JsEnterpriseAdminExtension %{public}s end. ", __func__);
135 return remoteObject->AsObject();
136 }
137
OnDisconnect(const AAFwk::Want & want)138 void JsEnterpriseAdminExtension::OnDisconnect(const AAFwk::Want& want)
139 {
140 EDMLOGI("JsEnterpriseAdminExtension %{public}s begin.", __func__);
141 AbilityRuntime::Extension::OnDisconnect(want);
142 }
143
OnAdminEnabled()144 void JsEnterpriseAdminExtension::OnAdminEnabled()
145 {
146 EDMLOGI("JsEnterpriseAdminExtension::OnAdminEnabled");
147 auto task = [this]() {
148 CallObjectMethod("onAdminEnabled", nullptr, JS_NAPI_ARGC_ZERO);
149 };
150 handler_->PostTask(task);
151 }
152
OnAdminDisabled()153 void JsEnterpriseAdminExtension::OnAdminDisabled()
154 {
155 EDMLOGI("JsEnterpriseAdminExtension::OnAdminDisabled");
156 auto task = [this]() {
157 CallObjectMethod("onAdminDisabled", nullptr, JS_NAPI_ARGC_ZERO);
158 };
159 handler_->PostTask(task);
160 }
161
OnBundleAdded(const std::string & bundleName,int32_t accountId)162 void JsEnterpriseAdminExtension::OnBundleAdded(const std::string &bundleName, int32_t accountId)
163 {
164 EDMLOGI("JsEnterpriseAdminExtension::OnBundleAdded");
165 auto task = [bundleName, accountId, this]() {
166 auto env = jsRuntime_.GetNapiEnv();
167 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, bundleName),
168 AbilityRuntime::CreateJsValue(env, accountId) };
169 CallObjectMethod("onBundleAdded", argv, JS_NAPI_ARGC_TWO);
170 };
171 handler_->PostTask(task);
172 }
173
OnBundleRemoved(const std::string & bundleName,int32_t accountId)174 void JsEnterpriseAdminExtension::OnBundleRemoved(const std::string &bundleName, int32_t accountId)
175 {
176 EDMLOGI("JsEnterpriseAdminExtension::OnBundleRemoved");
177 auto task = [bundleName, accountId, this]() {
178 auto env = jsRuntime_.GetNapiEnv();
179 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, bundleName),
180 AbilityRuntime::CreateJsValue(env, accountId) };
181 CallObjectMethod("onBundleRemoved", argv, JS_NAPI_ARGC_TWO);
182 };
183 handler_->PostTask(task);
184 }
185
OnAppStart(const std::string & bundleName)186 void JsEnterpriseAdminExtension::OnAppStart(const std::string &bundleName)
187 {
188 EDMLOGI("JsEnterpriseAdminExtension::OnAppStart");
189 auto task = [bundleName, this]() {
190 auto env = jsRuntime_.GetNapiEnv();
191 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, bundleName) };
192 CallObjectMethod("onAppStart", argv, JS_NAPI_ARGC_ONE);
193 };
194 handler_->PostTask(task);
195 }
196
OnAppStop(const std::string & bundleName)197 void JsEnterpriseAdminExtension::OnAppStop(const std::string &bundleName)
198 {
199 EDMLOGI("JsEnterpriseAdminExtension::OnAppStop");
200 auto task = [bundleName, this]() {
201 auto env = jsRuntime_.GetNapiEnv();
202 napi_value argv[] = { AbilityRuntime::CreateJsValue(env, bundleName) };
203 CallObjectMethod("onAppStop", argv, JS_NAPI_ARGC_ONE);
204 };
205 handler_->PostTask(task);
206 }
207
OnSystemUpdate(const UpdateInfo & updateInfo)208 void JsEnterpriseAdminExtension::OnSystemUpdate(const UpdateInfo &updateInfo)
209 {
210 EDMLOGI("JsEnterpriseAdminExtension::OnSystemUpdate");
211 auto task = [updateInfo, this]() {
212 auto env = jsRuntime_.GetNapiEnv();
213 napi_value argv[] = { CreateUpdateInfoObject(env, updateInfo) };
214 CallObjectMethod("onSystemUpdate", argv, JS_NAPI_ARGC_ONE);
215 };
216 handler_->PostTask(task);
217 }
218
CreateUpdateInfoObject(napi_env env,const UpdateInfo & updateInfo)219 napi_value JsEnterpriseAdminExtension::CreateUpdateInfoObject(napi_env env, const UpdateInfo &updateInfo)
220 {
221 napi_value nSystemUpdateInfo = nullptr;
222 NAPI_CALL(env, napi_create_object(env, &nSystemUpdateInfo));
223
224 napi_value nVersionName = nullptr;
225 NAPI_CALL(env, napi_create_string_utf8(env, updateInfo.version.c_str(), NAPI_AUTO_LENGTH, &nVersionName));
226 NAPI_CALL(env, napi_set_named_property(env, nSystemUpdateInfo, "versionName", nVersionName));
227
228 napi_value nFirstReceivedTime = nullptr;
229 NAPI_CALL(env, napi_create_int64(env, updateInfo.firstReceivedTime, &nFirstReceivedTime));
230 NAPI_CALL(env, napi_set_named_property(env, nSystemUpdateInfo, "firstReceivedTime", nFirstReceivedTime));
231
232 napi_value nPackageType = nullptr;
233 NAPI_CALL(env, napi_create_string_utf8(env, updateInfo.packageType.c_str(), NAPI_AUTO_LENGTH, &nPackageType));
234 NAPI_CALL(env, napi_set_named_property(env, nSystemUpdateInfo, "packageType", nPackageType));
235
236 return nSystemUpdateInfo;
237 }
238
CallObjectMethod(const char * name,napi_value * argv,size_t argc)239 napi_value JsEnterpriseAdminExtension::CallObjectMethod(const char* name, napi_value* argv, size_t argc)
240 {
241 EDMLOGI("JsEnterpriseAdminExtension::CallObjectMethod(%{public}s), begin", name);
242
243 if (!jsObj_) {
244 EDMLOGW("Not found EnterpriseAdminExtension.js");
245 return nullptr;
246 }
247
248 AbilityRuntime::HandleScope handleScope(jsRuntime_);
249 auto env = jsRuntime_.GetNapiEnv();
250
251 napi_value value = jsObj_->GetNapiValue();
252 if (value == nullptr) {
253 EDMLOGE("Failed to get EnterpriseAdminExtension object");
254 return nullptr;
255 }
256 napi_value method = nullptr;
257 napi_get_named_property(env, value, name, &method);
258
259 if (method == nullptr) {
260 EDMLOGE("Failed to get '%{public}s' from EnterpriseAdminExtension object", name);
261 return nullptr;
262 }
263 napi_valuetype valueType = napi_undefined;
264 napi_typeof(env, method, &valueType);
265 if (valueType != napi_function) {
266 EDMLOGE("'%{public}s' is not function", name);
267 return nullptr;
268 }
269
270 EDMLOGI("JsEnterpriseAdminExtension::CallFunction(%{public}s), success", name);
271 napi_value result = nullptr;
272 napi_status status = napi_call_function(env, value, method, argc, argv, &result);
273 if (status != napi_ok) {
274 EDMLOGE("Failed to call function");
275 }
276 return result;
277 }
278
GetSrcPath(std::string & srcPath)279 void JsEnterpriseAdminExtension::GetSrcPath(std::string& srcPath)
280 {
281 if (!Extension::abilityInfo_->srcEntrance.empty()) {
282 srcPath.append(Extension::abilityInfo_->moduleName + "/");
283 srcPath.append(Extension::abilityInfo_->srcEntrance);
284 srcPath.erase(srcPath.rfind('.'));
285 srcPath.append(".abc");
286 }
287 }
288 } // namespace EDM
289 } // namespace OHOS