1 /*
2 * Copyright (c) 2021 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_wallpaper_extension.h"
17
18 #include "ability_info.h"
19 #include "hilog_wrapper.h"
20 #include "hitrace_meter.h"
21 #include "js_runtime.h"
22 #include "js_runtime_utils.h"
23 #include "js_wallpaper_extension_context.h"
24 #include "napi/native_api.h"
25 #include "napi/native_node_api.h"
26 #include "napi_common_util.h"
27 #include "napi_common_want.h"
28 #include "napi_remote_object.h"
29 #include "uv_queue.h"
30 #include "wallpaper_manager.h"
31 #include "wallpaper_extension_stub.h"
32
33 namespace OHOS {
34 namespace AbilityRuntime {
35 namespace {
36 constexpr size_t ARGC_ONE = 1;
37 }
38 struct WorkData {
39 NativeEngine *nativeEng_;
40 int wallpaperType_;
WorkDataOHOS::AbilityRuntime::WorkData41 WorkData(NativeEngine *nativeEng, int wallpaperType) : nativeEng_(nativeEng), wallpaperType_(wallpaperType)
42 {
43 }
44 };
45
46 JsWallpaperExtension* JsWallpaperExtension::jsWallpaperExtension = NULL;
47 using namespace OHOS::AppExecFwk;
48 using namespace OHOS::MiscServices;
Create(const std::unique_ptr<Runtime> & runtime)49 JsWallpaperExtension* JsWallpaperExtension::Create(const std::unique_ptr<Runtime>& runtime)
50 {
51 HILOG_INFO("jws JsWallpaperExtension begin Create");
52 jsWallpaperExtension = new JsWallpaperExtension(static_cast<JsRuntime&>(*runtime));
53 return jsWallpaperExtension;
54 }
55
JsWallpaperExtension(JsRuntime & jsRuntime)56 JsWallpaperExtension::JsWallpaperExtension(JsRuntime& jsRuntime) : jsRuntime_(jsRuntime) {}
57 JsWallpaperExtension::~JsWallpaperExtension() = default;
58
Init(const std::shared_ptr<AbilityLocalRecord> & record,const std::shared_ptr<OHOSApplication> & application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)59 void JsWallpaperExtension::Init(const std::shared_ptr<AbilityLocalRecord> &record,
60 const std::shared_ptr<OHOSApplication> &application, std::shared_ptr<AbilityHandler> &handler,
61 const sptr<IRemoteObject> &token)
62 {
63 HILOG_INFO("jws JsWallpaperExtension begin Init");
64 WallpaperExtension::Init(record, application, handler, token);
65 std::string srcPath = "";
66 GetSrcPath(srcPath);
67 if (srcPath.empty()) {
68 HILOG_ERROR("Failed to get srcPath");
69 return;
70 }
71
72 std::string moduleName(Extension::abilityInfo_->moduleName);
73 moduleName.append("::").append(abilityInfo_->name);
74 HILOG_INFO("JsWallpaperExtension::Init module:%{public}s,srcPath:%{public}s.", moduleName.c_str(), srcPath.c_str());
75 HandleScope handleScope(jsRuntime_);
76 auto& engine = jsRuntime_.GetNativeEngine();
77
78 jsObj_ = jsRuntime_.LoadModule(moduleName, srcPath, abilityInfo_->hapPath);
79 if (jsObj_ == nullptr) {
80 HILOG_ERROR("Failed to get jsObj_");
81 return;
82 }
83 HILOG_INFO("JsWallpaperExtension::Init ConvertNativeValueTo.");
84 NativeObject* obj = ConvertNativeValueTo<NativeObject>(jsObj_->Get());
85 if (obj == nullptr) {
86 HILOG_ERROR("Failed to get JsWallpaperExtension object");
87 return;
88 }
89
90 auto context = GetContext();
91 if (context == nullptr) {
92 HILOG_ERROR("Failed to get context");
93 return;
94 }
95 HILOG_INFO("JsWallpaperExtension::Init CreateJsWallpaperExtensionContext.");
96 NativeValue* contextObj = CreateJsWallpaperExtensionContext(engine, context);
97 auto shellContextRef = jsRuntime_.LoadSystemModule("WallpaperExtensionContext", &contextObj, ARGC_ONE);
98 contextObj = shellContextRef->Get();
99 HILOG_INFO("JsWallpaperExtension::Init Bind.");
100 context->Bind(jsRuntime_, shellContextRef.release());
101 HILOG_INFO("JsWallpaperExtension::SetProperty.");
102 obj->SetProperty("context", contextObj);
103
104 auto nativeObj = ConvertNativeValueTo<NativeObject>(contextObj);
105 if (nativeObj == nullptr) {
106 HILOG_ERROR("Failed to get wallpaper extension native object");
107 return;
108 }
109
110 HILOG_INFO("Set wallpaper extension");
111
112 nativeObj->SetNativePointer(new std::weak_ptr<AbilityRuntime::Context>(context),
113 [](NativeEngine*, void* data, void*) {
114 HILOG_INFO("Finalizer for weak_ptr wallpaper extension context is called");
115 delete static_cast<std::weak_ptr<AbilityRuntime::Context>*>(data);
116 }, nullptr);
117
118 HILOG_INFO("JsWallpaperExtension::Init end.");
119 }
120
OnStart(const AAFwk::Want & want)121 void JsWallpaperExtension::OnStart(const AAFwk::Want &want)
122 {
123 StartAsyncTrace(HITRACE_TAG_MISC, "OnStart", static_cast<int32_t>(TraceTaskId::ONSTART_EXTENSION));
124 StartAsyncTrace(
125 HITRACE_TAG_MISC, "Extension::OnStart", static_cast<int32_t>(TraceTaskId::ONSTART_MIDDLE_EXTENSION));
126 Extension::OnStart(want);
127 FinishAsyncTrace(
128 HITRACE_TAG_MISC, "Extension::OnStart", static_cast<int32_t>(TraceTaskId::ONSTART_MIDDLE_EXTENSION));
129 HILOG_INFO("jws JsWallpaperExtension OnStart begin..");
130 HandleScope handleScope(jsRuntime_);
131 NativeEngine* nativeEngine = &jsRuntime_.GetNativeEngine();
132 napi_value napiWant = OHOS::AppExecFwk::WrapWant(reinterpret_cast<napi_env>(nativeEngine), want);
133 NativeValue* nativeWant = reinterpret_cast<NativeValue*>(napiWant);
134 NativeValue* argv[] = {nativeWant};
135 StartAsyncTrace(HITRACE_TAG_MISC, "onCreated", static_cast<int32_t>(TraceTaskId::ONCREATE_EXTENSION));
136 CallObjectMethod("onCreated", argv, ARGC_ONE);
137 FinishAsyncTrace(HITRACE_TAG_MISC, "onCreated", static_cast<int32_t>(TraceTaskId::ONCREATE_EXTENSION));
138 CallObjectMethod("createWallpaperWin");
139 WallpaperMgrService::WallpaperManagerkits::GetInstance().RegisterWallpaperCallback([](int wallpaperType) -> bool {
140 HILOG_INFO("jsWallpaperExtension->CallObjectMethod");
141 NativeEngine *nativeEng = &(jsWallpaperExtension->jsRuntime_).GetNativeEngine();
142 WorkData *workData = new (std::nothrow) WorkData(nativeEng, wallpaperType);
143 if (workData == nullptr) {
144 return false;
145 }
146 uv_after_work_cb afterCallback = [](uv_work_t *work, int32_t status) {
147 WorkData *workData = reinterpret_cast<WorkData *>(work->data);
148 napi_value type = OHOS::AppExecFwk::WrapInt32ToJS(
149 reinterpret_cast<napi_env>(workData->nativeEng_), workData->wallpaperType_);
150 NativeValue *nativeType = reinterpret_cast<NativeValue *>(type);
151 NativeValue *arg[] = { nativeType };
152 jsWallpaperExtension->CallObjectMethod("onWallpaperChanged", arg, ARGC_ONE);
153 delete workData;
154 delete work;
155 };
156 UvQueue::Call(reinterpret_cast<napi_env>(nativeEng), workData, afterCallback);
157 return true;
158 });
159 HILOG_INFO("%{public}s end.", __func__);
160 FinishAsyncTrace(HITRACE_TAG_MISC, "onCreated", static_cast<int32_t>(TraceTaskId::ONSTART_EXTENSION));
161 }
162
OnStop()163 void JsWallpaperExtension::OnStop()
164 {
165 WallpaperExtension::OnStop();
166 HILOG_INFO("jws JsWallpaperExtension OnStop begin.");
167 CallObjectMethod("onDestroy");
168 bool ret = ConnectionManager::GetInstance().DisconnectCaller(GetContext()->GetToken());
169 if (ret) {
170 HILOG_INFO("The wallpaper extension connection is not disconnected.");
171 }
172 HILOG_INFO("%{public}s end.", __func__);
173 }
174
OnConnect(const AAFwk::Want & want)175 sptr<IRemoteObject> JsWallpaperExtension::OnConnect(const AAFwk::Want &want)
176 {
177 HILOG_INFO("jws JsWallpaperExtension OnConnect begin.");
178 Extension::OnConnect(want);
179 auto remoteObj = new (std::nothrow) WallpaperMgrService::WallpaperExtensionStub();
180
181 if (remoteObj == nullptr) {
182 HILOG_ERROR("failed to create IWallpaperExtension");
183 return nullptr;
184 }
185 return remoteObj;
186 }
187
OnDisconnect(const AAFwk::Want & want)188 void JsWallpaperExtension::OnDisconnect(const AAFwk::Want &want)
189 {
190 HILOG_INFO("jws JsWallpaperExtension OnDisconnect begin.");
191 Extension::OnDisconnect(want);
192 }
193
OnCommand(const AAFwk::Want & want,bool restart,int startId)194 void JsWallpaperExtension::OnCommand(const AAFwk::Want &want, bool restart, int startId)
195 {
196 HILOG_INFO("jws JsWallpaperExtension OnCommand begin.");
197 Extension::OnCommand(want, restart, startId);
198 HILOG_INFO("%{public}s begin restart=%{public}s,startId=%{public}d.",
199 __func__,
200 restart ? "true" : "false",
201 startId);
202 HILOG_INFO("%{public}s end.", __func__);
203 }
204
CallObjectMethod(const char * name,NativeValue * const * argv,size_t argc)205 NativeValue* JsWallpaperExtension::CallObjectMethod(const char* name, NativeValue* const* argv, size_t argc)
206 {
207 HILOG_INFO("jws JsWallpaperExtension::CallObjectMethod(%{public}s), begin", name);
208
209 if (!jsObj_) {
210 HILOG_WARN("Not found WallpaperExtension.js");
211 return nullptr;
212 }
213
214 HandleScope handleScope(jsRuntime_);
215 auto& nativeEngine = jsRuntime_.GetNativeEngine();
216
217 NativeValue* value = jsObj_->Get();
218 NativeObject* obj = ConvertNativeValueTo<NativeObject>(value);
219 if (obj == nullptr) {
220 HILOG_ERROR("Failed to get WallpaperExtension object");
221 return nullptr;
222 }
223
224 NativeValue* method = obj->GetProperty(name);
225 if (method == nullptr) {
226 HILOG_ERROR("Failed to get '%{public}s' from WallpaperExtension object", name);
227 return nullptr;
228 }
229 HILOG_INFO("JsWallpaperExtension::CallFunction(%{public}s), success", name);
230 return nativeEngine.CallFunction(value, method, argv, argc);
231 }
232
GetSrcPath(std::string & srcPath)233 void JsWallpaperExtension::GetSrcPath(std::string &srcPath)
234 {
235 HILOG_INFO("jws JsWallpaperExtension GetSrcPath begin.");
236 if (!Extension::abilityInfo_->isModuleJson) {
237 /* temporary compatibility api8 + config.json */
238 srcPath.append(Extension::abilityInfo_->package);
239 srcPath.append("/assets/js/");
240 if (!Extension::abilityInfo_->srcPath.empty()) {
241 srcPath.append(Extension::abilityInfo_->srcPath);
242 }
243 srcPath.append("/").append(Extension::abilityInfo_->name).append(".abc");
244 return;
245 }
246
247 if (!Extension::abilityInfo_->srcEntrance.empty()) {
248 srcPath.append(Extension::abilityInfo_->moduleName + "/");
249 srcPath.append(Extension::abilityInfo_->srcEntrance);
250 srcPath.erase(srcPath.rfind('.'));
251 srcPath.append(".abc");
252 }
253 }
254 }
255 }
256