• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <ani.h>
17 #include <cstdint>
18 #include <sys/stat.h>
19 #ifdef PIXEL_MAP_SUPPORTED
20 #include "pixel_map.h"
21 #include "pixel_map_ani.h"
22 #include "pixel_map_napi.h"
23 
24 #endif
25 #include "core/common/ace_engine.h"
26 #include "frameworks/bridge/common/utils/engine_helper.h"
27 
28 namespace {
createInt(ani_env * env,ani_int value)29 static ani_ref createInt(ani_env* env, ani_int value)
30 {
31     ani_class cls;
32     env->FindClass("Lstd/core/Int;", &cls);
33     ani_method ctor;
34     env->Class_FindMethod(cls, "<ctor>", ":V", &ctor);
35 
36     ani_object rs;
37     env->Object_New(cls, ctor, &rs, value);
38     return static_cast<ani_object>(rs);
39 }
40 } // namespace
41 
GetOptionsScale(ani_env * env,ani_object options,float & value)42 static bool GetOptionsScale(ani_env* env, ani_object options, float& value)
43 {
44     ani_boolean isUndefined;
45     env->Reference_IsUndefined(options, &isUndefined);
46     if (!isUndefined) {
47         return false;
48     }
49     static const char* className = "L@ohos/componentSnapshot/componentSnapshot/SnapshotOptions;";
50     ani_class cls;
51     if (ANI_OK != env->FindClass(className, &cls)) {
52         return false;
53     }
54     ani_ref propertyRef;
55     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "scale", &propertyRef)) {
56         return false;
57     }
58 
59     ani_boolean isPropertyUndefined;
60     env->Reference_IsUndefined(propertyRef, &isPropertyUndefined);
61     if (!isPropertyUndefined) {
62         return false;
63     }
64     ani_double aniValue;
65     if (ANI_OK !=
66         env->Object_CallMethodByName_Double(static_cast<ani_object>(propertyRef), "doubleValue", nullptr, &aniValue)) {
67         return false;
68     }
69     value = static_cast<double>(aniValue);
70     return true;
71 }
72 
GetOptionsWaitUntilRenderFinished(ani_env * env,ani_object options,bool & value)73 static bool GetOptionsWaitUntilRenderFinished(ani_env* env, ani_object options, bool& value)
74 {
75     ani_boolean isUndefined;
76     env->Reference_IsUndefined(options, &isUndefined);
77     if (!isUndefined) {
78         return false;
79     }
80     static const char* className = "L@ohos/componentSnapshot/componentSnapshot/SnapshotOptions;";
81     ani_class cls;
82     if (ANI_OK != env->FindClass(className, &cls)) {
83         return false;
84     }
85     ani_ref propertyRef;
86     if (ANI_OK != env->Object_GetPropertyByName_Ref(options, "waitUntilRenderFinished", &propertyRef)) {
87         return false;
88     }
89 
90     ani_boolean isPropertyUndefined;
91     env->Reference_IsUndefined(propertyRef, &isPropertyUndefined);
92     if (!isPropertyUndefined) {
93         return false;
94     }
95     ani_boolean aniValue;
96     if (ANI_OK !=
97         env->Object_CallMethodByName_Boolean(static_cast<ani_object>(propertyRef), "unboxed", nullptr, &aniValue)) {
98         return false;
99     }
100     value = static_cast<bool>(aniValue);
101     return true;
102 }
103 
GetDelay(ani_env * env,ani_object object,int32_t & value)104 static bool GetDelay(ani_env* env, ani_object object, int32_t& value)
105 {
106     ani_boolean isUndefined;
107     env->Reference_IsUndefined(object, &isUndefined);
108     if (!isUndefined) {
109         return false;
110     }
111     ani_int aniValue;
112     if (ANI_OK != env->Object_CallMethodByName_Int(object, "intValue", nullptr, &aniValue)) {
113         return false;
114     }
115     value = static_cast<int32_t>(aniValue);
116     return true;
117 }
118 
GetCheckImageStatus(ani_env * env,ani_object object,bool & value)119 static bool GetCheckImageStatus(ani_env* env, ani_object object, bool& value)
120 {
121     ani_boolean isUndefined;
122     env->Reference_IsUndefined(object, &isUndefined);
123     if (!isUndefined) {
124         return false;
125     }
126     ani_boolean aniValue;
127     if (ANI_OK != env->Object_CallMethodByName_Boolean(object, "unboxed", nullptr, &aniValue)) {
128         return false;
129     }
130     value = static_cast<bool>(aniValue);
131     return true;
132 }
133 
createFromBuilder(ani_env * env,ani_object builderObj,ani_object callbackObj,ani_object delay,ani_object checkImageStatus,ani_object options)134 static void createFromBuilder([[maybe_unused]] ani_env* env, ani_object builderObj, ani_object callbackObj,
135     ani_object delay, ani_object checkImageStatus, ani_object options)
136 {
137     auto biulder = [env, builderObj]() {
138         env->FunctionalObject_Call(static_cast<ani_fn_object>(builderObj), 0, nullptr, nullptr);
139     };
140     auto callback = [env, callbackObj](std::shared_ptr<OHOS::Media::PixelMap> pixmap, int32_t errCode,
141                         std::function<void()> finishCallback) {
142         std::vector<ani_ref> vec;
143         vec.push_back(createInt(env, ani_int(errCode)));
144         if (errCode == 0) {
145 #ifdef PIXEL_MAP_SUPPORTED
146             ani_ref pixmapItem = OHOS::Media::PixelMapAni::CreateAniPixelMap(env, pixmap);
147             if (pixmapItem) {
148                 vec.push_back(pixmapItem);
149             }
150 #endif
151         }
152         env->FunctionalObject_Call(static_cast<ani_fn_object>(callbackObj), vec.size(), vec.data(), nullptr);
153     };
154 
155     OHOS::Ace::NG::SnapshotParam param;
156     GetDelay(env, delay, param.delay);
157     GetCheckImageStatus(env, checkImageStatus, param.checkImageStatus);
158     GetOptionsScale(env, options, param.options.scale);
159     GetOptionsWaitUntilRenderFinished(env, options, param.options.waitUntilRenderFinished);
160 
161     auto delegate = OHOS::Ace::EngineHelper::GetCurrentDelegateSafely();
162     if (!delegate) {
163         return;
164     }
165     delegate->CreateSnapshot(biulder, callback, true, param);
166 }
167 
ANI_Constructor(ani_vm * vm,uint32_t * result)168 ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result)
169 {
170     ani_env* env;
171     if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) {
172         return ANI_ERROR;
173     }
174 
175     ani_namespace ns;
176     if (ANI_OK != env->FindNamespace("L@ohos/componentSnapshot/componentSnapshot;", &ns)) {
177         return ANI_ERROR;
178     }
179     std::array methods = {
180         ani_native_function { "createFromBuilder", nullptr, reinterpret_cast<void*>(createFromBuilder) },
181     };
182     if (ANI_OK != env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size())) {
183         return ANI_ERROR;
184     }
185 
186     *result = ANI_VERSION_1;
187     return ANI_OK;
188 }
189