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 "adapter/preview/entrance/flutter_ace_view.h"
17
18 #include "base/log/dump_log.h"
19 #include "base/log/event_report.h"
20 #include "base/log/log.h"
21 #include "base/utils/macros.h"
22 #include "base/utils/system_properties.h"
23 #include "base/utils/utils.h"
24 #include "core/common/ace_engine.h"
25 #include "core/components/theme/theme_manager.h"
26 #include "core/event/mouse_event.h"
27 #include "core/event/touch_event.h"
28 #include "core/image/image_cache.h"
29 #include "core/pipeline/layers/flutter_scene_builder.h"
30
31 namespace OHOS::Ace::Platform {
32 namespace {
33 constexpr int32_t DEFAULT_ACTION_ID = 0;
34
ConvertTouchPoint(flutter::PointerData * pointerItem)35 TouchPoint ConvertTouchPoint(flutter::PointerData* pointerItem)
36 {
37 TouchPoint touchPoint;
38 // just get the max of width and height
39 touchPoint.size = pointerItem->size;
40 touchPoint.id = pointerItem->device;
41 touchPoint.force = pointerItem->pressure;
42 touchPoint.x = pointerItem->physical_x;
43 touchPoint.y = pointerItem->physical_y;
44 touchPoint.screenX = pointerItem->physical_x;
45 touchPoint.screenY = pointerItem->physical_y;
46 return touchPoint;
47 }
48
ConvertTouchEvent(const std::vector<uint8_t> & data,std::vector<TouchEvent> & events)49 void ConvertTouchEvent(const std::vector<uint8_t>& data, std::vector<TouchEvent>& events)
50 {
51 const auto* origin = reinterpret_cast<const flutter::PointerData*>(data.data());
52 size_t size = data.size() / sizeof(flutter::PointerData);
53 auto current = const_cast<flutter::PointerData*>(origin);
54 auto end = current + size;
55
56 while (current < end) {
57 std::chrono::microseconds micros(current->time_stamp);
58 TimeStamp time(micros);
59 TouchEvent point {
60 static_cast<int32_t>(DEFAULT_ACTION_ID), static_cast<float>(current->physical_x),
61 static_cast<float>(current->physical_y), static_cast<float>(current->physical_x),
62 static_cast<float>(current->physical_y), TouchType::UNKNOWN, time, current->size,
63 static_cast<float>(current->pressure), static_cast<int64_t>(current->device)
64 };
65 point.pointers.emplace_back(ConvertTouchPoint(current));
66 switch (current->change) {
67 case flutter::PointerData::Change::kCancel:
68 point.type = TouchType::CANCEL;
69 events.push_back(point);
70 break;
71 case flutter::PointerData::Change::kAdd:
72 case flutter::PointerData::Change::kRemove:
73 case flutter::PointerData::Change::kHover:
74 break;
75 case flutter::PointerData::Change::kDown:
76 point.type = TouchType::DOWN;
77 events.push_back(point);
78 break;
79 case flutter::PointerData::Change::kMove:
80 point.type = TouchType::MOVE;
81 events.push_back(point);
82 break;
83 case flutter::PointerData::Change::kUp:
84 point.type = TouchType::UP;
85 events.push_back(point);
86 break;
87 }
88 current++;
89 }
90 }
91
92 } // namespace
93
RegisterTouchEventCallback(TouchEventCallback && callback)94 void FlutterAceView::RegisterTouchEventCallback(TouchEventCallback&& callback)
95 {
96 ACE_DCHECK(callback);
97 touchEventCallback_ = std::move(callback);
98 }
99
RegisterKeyEventCallback(KeyEventCallback && callback)100 void FlutterAceView::RegisterKeyEventCallback(KeyEventCallback&& callback)
101 {
102 ACE_DCHECK(callback);
103 keyEventCallback_ = std::move(callback);
104 }
105
RegisterMouseEventCallback(MouseEventCallback && callback)106 void FlutterAceView::RegisterMouseEventCallback(MouseEventCallback&& callback)
107 {
108 ACE_DCHECK(callback);
109 mouseEventCallback_ = std::move(callback);
110 }
111
RegisterAxisEventCallback(AxisEventCallback && callback)112 void FlutterAceView::RegisterAxisEventCallback(AxisEventCallback&& callback)
113 {
114 ACE_DCHECK(callback);
115 axisEventCallback_ = std::move(callback);
116 }
117
RegisterRotationEventCallback(RotationEventCallBack && callback)118 void FlutterAceView::RegisterRotationEventCallback(RotationEventCallBack&& callback)
119 {
120 ACE_DCHECK(callback);
121 rotationEventCallBack_ = std::move(callback);
122 }
123
Launch()124 void FlutterAceView::Launch()
125 {
126 }
127
Dump(const std::vector<std::string> & params)128 bool FlutterAceView::Dump(const std::vector<std::string>& params)
129 {
130 return false;
131 }
132
ProcessIdleEvent(int64_t deadline)133 void FlutterAceView::ProcessIdleEvent(int64_t deadline)
134 {
135 if (idleCallback_) {
136 idleCallback_(deadline);
137 }
138 }
139
HandleTouchEvent(const std::vector<uint8_t> & data)140 bool FlutterAceView::HandleTouchEvent(const std::vector<uint8_t>& data)
141 {
142 std::vector<TouchEvent> touchEvents;
143 ConvertTouchEvent(data, touchEvents);
144 for (const auto& point : touchEvents) {
145 LOGD("HandleTouchEvent point.x: %lf, point.y: %lf, point.size: %lf", point.x, point.y, point.size);
146 if (point.type == TouchType::UNKNOWN) {
147 LOGW("Unknown event.");
148 continue;
149 }
150 if (touchEventCallback_) {
151 touchEventCallback_(point);
152 }
153 }
154
155 return true;
156 }
157
HandleTouchEvent(const TouchEvent & touchEvent)158 bool FlutterAceView::HandleTouchEvent(const TouchEvent& touchEvent)
159 {
160 if (touchEvent.type == TouchType::UNKNOWN) {
161 LOGW("Unknown event.");
162 return false;
163 }
164
165 LOGD("HandleTouchEvent touchEvent.x: %lf, touchEvent.y: %lf, touchEvent.size: %lf",
166 touchEvent.x, touchEvent.y, touchEvent.size);
167 auto event = touchEvent.UpdatePointers();
168 if (touchEventCallback_) {
169 touchEventCallback_(event);
170 }
171
172 return true;
173 }
174
GetDrawDelegate()175 std::unique_ptr<DrawDelegate> FlutterAceView::GetDrawDelegate()
176 {
177 auto darwDelegate = std::make_unique<DrawDelegate>();
178
179 darwDelegate->SetDrawFrameCallback([this](RefPtr<Flutter::Layer>& layer, const Rect& dirty) {
180 if (!layer) {
181 return;
182 }
183 RefPtr<Flutter::FlutterSceneBuilder> flutterSceneBuilder = AceType::MakeRefPtr<Flutter::FlutterSceneBuilder>();
184 layer->AddToScene(*flutterSceneBuilder, 0.0, 0.0);
185 auto scene_ = flutterSceneBuilder->Build();
186 if (!flutter::UIDartState::Current()) {
187 LOGE("uiDartState is nullptr");
188 return;
189 }
190 auto window = flutter::UIDartState::Current()->window();
191 if (window != nullptr && window->client() != nullptr) {
192 window->client()->Render(scene_.get());
193 }
194 });
195
196 return darwDelegate;
197 }
198
GetPlatformWindow()199 std::unique_ptr<PlatformWindow> FlutterAceView::GetPlatformWindow()
200 {
201 return nullptr;
202 }
203
GetNativeWindowById(uint64_t textureId)204 const void* FlutterAceView::GetNativeWindowById(uint64_t textureId)
205 {
206 return nullptr;
207 }
208 } // namespace OHOS::Ace::Platform
209