1 /*
2 * Copyright (c) 2025 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 <hitrace_meter.h>
17
18 #include "ani.h"
19 #include "display_ani_utils.h"
20 #include "display_ani.h"
21 #include "display_info.h"
22 #include "display.h"
23 #include "singleton_container.h"
24 #include "display_manager.h"
25 #include "window_manager_hilog.h"
26 #include "dm_common.h"
27 #include "refbase.h"
28
29 namespace OHOS {
30 namespace Rosen {
31
32 enum class DisplayStateMode : uint32_t {
33 STATE_UNKNOWN = 0,
34 STATE_OFF,
35 STATE_ON,
36 STATE_DOZE,
37 STATE_DOZE_SUSPEND,
38 STATE_VR,
39 STATE_ON_SUSPEND
40 };
41
42 static const std::map<DisplayState, DisplayStateMode> NATIVE_TO_JS_DISPLAY_STATE_MAP {
43 { DisplayState::UNKNOWN, DisplayStateMode::STATE_UNKNOWN },
44 { DisplayState::OFF, DisplayStateMode::STATE_OFF },
45 { DisplayState::ON, DisplayStateMode::STATE_ON },
46 { DisplayState::DOZE, DisplayStateMode::STATE_DOZE },
47 { DisplayState::DOZE_SUSPEND, DisplayStateMode::STATE_DOZE_SUSPEND },
48 { DisplayState::VR, DisplayStateMode::STATE_VR },
49 { DisplayState::ON_SUSPEND, DisplayStateMode::STATE_ON_SUSPEND },
50 };
51
52
convertRect(DMRect rect,ani_object rectObj,ani_env * env)53 void DisplayAniUtils::convertRect(DMRect rect, ani_object rectObj, ani_env* env)
54 {
55 TLOGI(WmsLogTag::DMS, "[ANI] rect area start");
56 TLOGI(WmsLogTag::DMS, "[ANI] rect area info: %{public}d, %{public}d, %{public}u, %{public}u",
57 rect.posX_, rect.posY_, rect.width_, rect.height_);
58 env->Object_SetFieldByName_Double(rectObj, "<property>left", rect.posX_);
59 env->Object_SetFieldByName_Double(rectObj, "<property>width", rect.width_);
60 env->Object_SetFieldByName_Double(rectObj, "<property>top", rect.posY_);
61 env->Object_SetFieldByName_Double(rectObj, "<property>height", rect.height_);
62 }
63
convertWaterArea(WaterfallDisplayAreaRects waterfallDisplayAreaRects,ani_object waterfallObj,ani_env * env)64 void DisplayAniUtils::convertWaterArea(WaterfallDisplayAreaRects waterfallDisplayAreaRects,
65 ani_object waterfallObj, ani_env *env)
66 {
67 TLOGI(WmsLogTag::DMS, "[ANI] start convert WaterArea");
68 ani_ref leftObj;
69 ani_ref rightObj;
70 ani_ref topObj;
71 ani_ref bottomObj;
72 env->Object_GetFieldByName_Ref(waterfallObj, "<property>left", &leftObj);
73 env->Object_GetFieldByName_Ref(waterfallObj, "<property>right", &rightObj);
74 env->Object_GetFieldByName_Ref(waterfallObj, "<property>top", &topObj);
75 env->Object_GetFieldByName_Ref(waterfallObj, "<property>bottom", &bottomObj);
76 convertRect(waterfallDisplayAreaRects.left, static_cast<ani_object>(leftObj), env);
77 convertRect(waterfallDisplayAreaRects.right, static_cast<ani_object>(rightObj), env);
78 convertRect(waterfallDisplayAreaRects.top, static_cast<ani_object>(topObj), env);
79 convertRect(waterfallDisplayAreaRects.bottom, static_cast<ani_object>(bottomObj), env);
80 }
81
cvtDisplay(sptr<Display> display,ani_env * env,ani_object obj)82 ani_status DisplayAniUtils::cvtDisplay(sptr<Display> display, ani_env* env, ani_object obj)
83 {
84 sptr<DisplayInfo> info = display->GetDisplayInfoWithCache();
85 int setfieldid = env->Object_SetFieldByName_Double(obj, "<property>id", info->GetDisplayId());
86 if (ANI_OK != setfieldid) {
87 TLOGE(WmsLogTag::DMS, "[ANI] set id failed: %{public}d", setfieldid);
88 }
89 const ani_size stringLength = info->GetName().size();
90 TLOGI(WmsLogTag::DMS, "[ANI] display = %{public}u, name = %{public}s",
91 static_cast<uint32_t>(info->GetDisplayId()), info->GetName().c_str());
92 ani_string str = nullptr;
93 env->String_NewUTF8(info->GetName().data(), stringLength, &str);
94 env->Object_SetFieldByName_Ref(obj, "<property>name", str);
95 env->Object_SetFieldByName_Boolean(obj, "<property>alive", info->GetAliveStatus());
96 if (NATIVE_TO_JS_DISPLAY_STATE_MAP.count(info->GetDisplayState()) != 0) {
97 env->Object_SetFieldByName_Int(obj, "<property>state", static_cast<uint32_t>(info->GetDisplayState()));
98 } else {
99 env->Object_SetFieldByName_Int(obj, "<property>state", 0);
100 }
101 env->Object_SetFieldByName_Double(obj, "<property>refreshRate", info->GetRefreshRate());
102 env->Object_SetFieldByName_Double(obj, "<property>rotation", static_cast<uint32_t>(info->GetRotation()));
103 ani_status setfieldRes = env->Object_SetFieldByName_Double(obj, "<property>width",
104 static_cast<uint32_t>(info->GetWidth()));
105 if (ANI_OK != setfieldRes) {
106 TLOGE(WmsLogTag::DMS, "[ANI] set failed: %{public}d, %{public}u", info->GetWidth(), setfieldRes);
107 }
108 env->Object_SetFieldByName_Double(obj, "<property>height", display->GetHeight());
109 env->Object_SetFieldByName_Double(obj, "<property>availableWidth", info->GetAvailableWidth());
110 env->Object_SetFieldByName_Double(obj, "<property>availableHeight", info->GetAvailableHeight());
111 env->Object_SetFieldByName_Double(obj, "<property>densityDPI", info->GetVirtualPixelRatio() * DOT_PER_INCH);
112 env->Object_SetFieldByName_Double(obj, "<property>orientation",
113 static_cast<uint32_t>(info->GetDisplayOrientation()));
114 env->Object_SetFieldByName_Double(obj, "<property>densityPixels", info->GetVirtualPixelRatio());
115 env->Object_SetFieldByName_Double(obj, "<property>scaledDensity", info->GetVirtualPixelRatio());
116 env->Object_SetFieldByName_Double(obj, "<property>xDPI", info->GetXDpi());
117 env->Object_SetFieldByName_Double(obj, "<property>yDPI", info->GetYDpi());
118 auto colorSpaces = info->GetColorSpaces();
119 auto hdrFormats = info->GetHdrFormats();
120 TLOGI(WmsLogTag::DMS, "[ANI] colorSpaces(0) %{public}zu, %{public}u", colorSpaces.size(), colorSpaces[1]);
121 if (colorSpaces.size() != 0) {
122 ani_array_int colorSpacesAni;
123 CreateAniArrayInt(env, colorSpaces.size(), &colorSpacesAni, colorSpaces);
124 if (ANI_OK != env->Object_SetFieldByName_Ref(obj, "<property>colorSpaces",
125 static_cast<ani_ref>(colorSpacesAni))) {
126 TLOGE(WmsLogTag::DMS, "[ANI] Array set colorSpaces field error");
127 }
128 }
129 if (hdrFormats.size() != 0) {
130 ani_array_int hdrFormatsAni;
131 CreateAniArrayInt(env, hdrFormats.size(), &hdrFormatsAni, hdrFormats);
132 if (ANI_OK != env->Object_SetFieldByName_Ref(obj, "<property>hdrFormats",
133 static_cast<ani_ref>(hdrFormatsAni))) {
134 TLOGE(WmsLogTag::DMS, "[ANI] Array set hdrFormats field error");
135 }
136 }
137 return ANI_OK;
138 }
139
CreateAniArrayInt(ani_env * env,ani_size size,ani_array_int * aniArray,std::vector<uint32_t> vec)140 void DisplayAniUtils::CreateAniArrayInt(ani_env* env, ani_size size, ani_array_int *aniArray, std::vector<uint32_t> vec)
141 {
142 if (ANI_OK != env->Array_New_Int(size, aniArray)) {
143 TLOGE(WmsLogTag::DMS, "[ANI] create colorSpace array error");
144 }
145 ani_int* aniArrayBuf = reinterpret_cast<ani_int *>(vec.data());
146 if (ANI_OK != env->Array_SetRegion_Int(*aniArray, 0, size, aniArrayBuf)) {
147 TLOGE(WmsLogTag::DMS, "[ANI] Array set region int error");
148 }
149 }
150
GetStdString(ani_env * env,ani_string ani_str,std::string & result)151 ani_status DisplayAniUtils::GetStdString(ani_env *env, ani_string ani_str, std::string &result)
152 {
153 ani_size strSize;
154 ani_status ret = env->String_GetUTF8Size(ani_str, &strSize);
155 if (ret != ANI_OK) {
156 return ret;
157 }
158 std::vector<char> buffer(strSize + 1);
159 char* utf8_buffer = buffer.data();
160 ani_size bytes_written = 0;
161 ret = env->String_GetUTF8(ani_str, utf8_buffer, strSize + 1, &bytes_written);
162 if (ret != ANI_OK) {
163 return ret;
164 }
165 utf8_buffer[bytes_written] = '\0';
166 result = std::string(utf8_buffer);
167 return ret;
168 }
169
NewAniObject(ani_env * env,ani_class cls,const char * signature,ani_object * result,...)170 ani_status DisplayAniUtils::NewAniObject(ani_env* env, ani_class cls, const char *signature, ani_object* result, ...)
171 {
172 ani_method aniCtor;
173 auto ret = env->Class_FindMethod(cls, "<ctor>", signature, &aniCtor);
174 if (ret != ANI_OK) {
175 return ret;
176 }
177 va_list args;
178 va_start(args, result);
179 ani_status status = env->Object_New(cls, aniCtor, result, args);
180 va_end(args);
181 return status;
182 }
183
NewAniObjectNoParams(ani_env * env,ani_class cls,ani_object * object)184 ani_status DisplayAniUtils::NewAniObjectNoParams(ani_env* env, ani_class cls, ani_object* object)
185 {
186 ani_method aniCtor;
187 auto ret = env->Class_FindMethod(cls, "<ctor>", ":V", &aniCtor);
188 if (ret != ANI_OK) {
189 TLOGE(WmsLogTag::DMS, "[ANI] find ctor method fail");
190 return ret;
191 }
192 return env->Object_New(cls, aniCtor, object);
193 }
194
CreateAniUndefined(ani_env * env)195 ani_object DisplayAniUtils::CreateAniUndefined(ani_env* env)
196 {
197 ani_ref aniRef;
198 env->GetUndefined(&aniRef);
199 return static_cast<ani_object>(aniRef);
200 }
201
GetAniString(ani_env * env,const std::string & str,ani_string * result)202 ani_status DisplayAniUtils::GetAniString(ani_env* env, const std::string& str, ani_string* result)
203 {
204 return env->String_NewUTF8(str.c_str(), static_cast<ani_size>(str.size()), result);
205 }
206
CallAniFunctionVoid(ani_env * env,const char * ns,const char * fn,const char * signature,...)207 ani_status DisplayAniUtils::CallAniFunctionVoid(ani_env *env, const char* ns,
208 const char* fn, const char* signature, ...)
209 {
210 TLOGI(WmsLogTag::DMS, "[ANI]CallAniFunctionVoid begin");
211 ani_status ret = ANI_OK;
212 ani_namespace aniNamespace{};
213 if ((ret = env->FindNamespace(ns, &aniNamespace)) != ANI_OK) {
214 TLOGE(WmsLogTag::DMS, "[ANI]canot find ns %{public}d", ret);
215 return ret;
216 }
217 ani_function func{};
218 if ((ret = env->Namespace_FindFunction(aniNamespace, fn, signature, &func)) != ANI_OK) {
219 TLOGE(WmsLogTag::DMS, "[ANI]canot find callBack %{public}d", ret);
220 return ret;
221 }
222 va_list args;
223 va_start(args, signature);
224 TLOGI(WmsLogTag::DMS, "[ANI]CallAniFunctionVoid begin %{public}s", signature);
225 if (func == nullptr) {
226 TLOGI(WmsLogTag::DMS, "[ANI] null func ani");
227 return ret;
228 }
229 ret = env->Function_Call_Void_V(func, args);
230 va_end(args);
231 if (ret != ANI_OK) {
232 TLOGE(WmsLogTag::DMS, "[ANI]canot run callBack %{public}d", ret);
233 return ret;
234 }
235 return ret;
236 }
237
238 }
239 }