1 /*
2  * Copyright (c) 2021-2022 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 #ifndef DEPTH_DATA_OUTPUT_NAPI_H_
17 #define DEPTH_DATA_OUTPUT_NAPI_H_
18 
19 #include "camera_napi_event_emitter.h"
20 #include "camera_napi_template_utils.h"
21 #include "camera_napi_utils.h"
22 #include "depth_data_napi.h"
23 #include "listener_base.h"
24 #include "input/camera_manager.h"
25 #include "output/camera_output_capability.h"
26 #include "output/depth_data_output.h"
27 #include "surface_utils.h"
28 
29 namespace OHOS {
30 namespace CameraStandard {
31 static const std::string CONST_DEPTH_DATA_AVAILABLE = "depthDataAvailable";
32 static const std::string CONST_DEPTH_DATA_ERROR = "error";
33 
34 static const char CAMERA_DEPTH_DATA_OUTPUT_NAPI_CLASS_NAME[] = "DepthDataOutput";
35 
36 enum DepthDataOutputEventType {
37     DEPTH_DATA_AVAILABLE,
38     DEPTH_DATA_ERROR,
39     DEPTH_DATA_INVALID_TYPE
40 };
41 
42 static EnumHelper<DepthDataOutputEventType> DepthDataOutputEventTypeHelper({
43         {DEPTH_DATA_AVAILABLE, CONST_DEPTH_DATA_AVAILABLE},
44         {DEPTH_DATA_ERROR, CONST_DEPTH_DATA_ERROR}
45     },
46     DepthDataOutputEventType::DEPTH_DATA_INVALID_TYPE
47 );
48 
49 class DepthDataBufferProcessor {
50 public:
DepthDataBufferProcessor(sptr<Surface> depthDataSurface)51     explicit DepthDataBufferProcessor(sptr<Surface> depthDataSurface) : depthDataSurface_(depthDataSurface) {}
~DepthDataBufferProcessor()52     ~DepthDataBufferProcessor()
53     {
54         depthDataSurface_ = nullptr;
55     }
Release(sptr<SurfaceBuffer> & buffer)56     void Release(sptr<SurfaceBuffer>& buffer)
57     {
58         if (depthDataSurface_ != nullptr) {
59             depthDataSurface_->ReleaseBuffer(buffer, -1);
60         }
61     }
62 
63 private:
64     sptr<Surface> depthDataSurface_ = nullptr;
65 };
66 
67 class DepthDataListener : public IBufferConsumerListener, public ListenerBase {
68 public:
69     explicit DepthDataListener(napi_env env, const sptr<Surface> depthSurface, sptr<DepthDataOutput> depthDataOutput);
70     ~DepthDataListener() = default;
71     void OnBufferAvailable() override;
72     void SaveCallback(const std::string eventName, napi_value callback);
73     void RemoveCallback(const std::string eventName, napi_value callback);
74     void SetDepthProfile(std::shared_ptr<DepthProfile> depthProfile);
75 
76 private:
77     sptr<Surface> depthDataSurface_;
78     sptr<DepthDataOutput> depthDataOutput_;
79     std::shared_ptr<DepthDataBufferProcessor> bufferProcessor_;
80     std::shared_ptr<DepthProfile> depthProfile_;
81     void UpdateJSCallback(sptr<Surface> depthSurface) const;
82     void UpdateJSCallbackAsync(sptr<Surface> depthSurface) const;
83     void ExecuteDepthData(sptr<SurfaceBuffer> surfaceBfuffer) const;
84 };
85 
86 struct DepthDataListenerInfo {
87     sptr<Surface> depthDataSurface_;
88     const DepthDataListener* listener_;
DepthDataListenerInfoDepthDataListenerInfo89     DepthDataListenerInfo(sptr<Surface> depthDataSurface, const DepthDataListener* listener)
90         : depthDataSurface_(depthDataSurface), listener_(listener)
91     {}
92 };
93 
94 class DepthDataOutputCallback : public DepthDataStateCallback,
95                               public ListenerBase,
96                               public std::enable_shared_from_this<DepthDataOutputCallback> {
97 public:
98     explicit DepthDataOutputCallback(napi_env env);
99     ~DepthDataOutputCallback() = default;
100 
101     void OnDepthDataError(const int32_t errorCode) const override;
102 
103 private:
104     void UpdateJSCallback(DepthDataOutputEventType eventType, const int32_t value) const;
105     void UpdateJSCallbackAsync(DepthDataOutputEventType eventType, const int32_t value) const;
106     void ExecuteDepthData(sptr<SurfaceBuffer> surfaceBuffer) const;
107 };
108 
109 struct DepthDataOutputCallbackInfo {
110     DepthDataOutputEventType eventType_;
111     int32_t value_;
112     weak_ptr<const DepthDataOutputCallback> listener_;
DepthDataOutputCallbackInfoDepthDataOutputCallbackInfo113     DepthDataOutputCallbackInfo(DepthDataOutputEventType eventType, int32_t value,
114         shared_ptr<const DepthDataOutputCallback> listener)
115         : eventType_(eventType), value_(value), listener_(listener) {}
116 };
117 
118 struct DepthDataOutputAsyncContext;
119 class DepthDataOutputNapi : public CameraNapiEventEmitter<DepthDataOutputNapi> {
120 public:
121     static napi_value Init(napi_env env, napi_value exports);
122     static napi_value CreateDepthDataOutput(napi_env env, DepthProfile& depthProfile);
123     static napi_value Start(napi_env env, napi_callback_info info);
124     static napi_value Stop(napi_env env, napi_callback_info info);
125     static napi_value Release(napi_env env, napi_callback_info info);
126     static napi_value On(napi_env env, napi_callback_info info);
127     static napi_value Once(napi_env env, napi_callback_info info);
128     static napi_value Off(napi_env env, napi_callback_info info);
129     sptr<DepthDataOutput> GetDepthDataOutput();
130     static bool IsDepthDataOutput(napi_env env, napi_value obj);
131 
132     const EmitterFunctions& GetEmitterFunctions() override;
133 
134     DepthDataOutputNapi();
135     ~DepthDataOutputNapi() override;
136 
137 private:
138     static void DepthDataOutputNapiDestructor(napi_env env, void* nativeObject, void* finalize_hint);
139     static napi_value DepthDataOutputNapiConstructor(napi_env env, napi_callback_info info);
140 
141     void RegisterDepthDataAvailableCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
142         const std::vector<napi_value>& args, bool isOnce);
143     void UnregisterDepthDataAvailableCallbackListener(
144         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
145     void RegisterErrorCallbackListener(const std::string& eventName, napi_env env, napi_value callback,
146         const std::vector<napi_value>& args, bool isOnce);
147     void UnregisterErrorCallbackListener(
148         const std::string& eventName, napi_env env, napi_value callback, const std::vector<napi_value>& args);
149 
150     static thread_local napi_ref sConstructor_;
151     static thread_local sptr<DepthDataOutput> sDepthDataOutput_;
152     static thread_local sptr<Surface> sDepthDataSurface_;
153     static thread_local uint32_t depthDataOutputTaskId;
154 
155     napi_env env_;
156     sptr<DepthDataOutput> depthDataOutput_;
157     sptr<DepthDataListener> depthDataListener_;
158     std::shared_ptr<DepthDataOutputCallback> depthDataCallback_;
159     static thread_local std::shared_ptr<DepthProfile> depthProfile_;
160 };
161 
162 struct DepthDataOutputAsyncContext : public AsyncContext {
163     DepthDataOutputNapi* objectInfo;
164     bool bRetBool;
165     std::string surfaceId;
~DepthDataOutputAsyncContextDepthDataOutputAsyncContext166     ~DepthDataOutputAsyncContext()
167     {
168         objectInfo = nullptr;
169     }
170 };
171 } // namespace CameraStandard
172 } // namespace OHOS
173 #endif /* DEPTH_DATA_OUTPUT_NAPI_H_ */