• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "frameworks/bridge/common/dom/dom_video.h"
17 
18 #include "frameworks/bridge/common/dom/dom_type.h"
19 #include "frameworks/bridge/common/utils/utils.h"
20 
21 namespace OHOS::Ace::Framework {
22 namespace {
23 
24 constexpr uint32_t METHOD_VIDEO_TO_ARGS_SIZE = 1;
25 
26 }
27 
DOMVideo(NodeId nodeId,const std::string & nodeName)28 DOMVideo::DOMVideo(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
29 {
30     videoChild_ = AceType::MakeRefPtr<VideoComponent>();
31     videoChild_->SetFullscreenEvent([weak = AceType::WeakClaim(this)](bool fullscreen, const WeakPtr<Player>& player,
32                                         const WeakPtr<Texture>& texture) {
33         auto client = weak.Upgrade();
34         RefPtr<OHOS::Ace::Component> result;
35         if (client) {
36             result = client->FireFullscreen(fullscreen, player, texture);
37         }
38         return result;
39     });
40     if (IsRightToLeft()) {
41         videoChild_->SetTextDirection(TextDirection::RTL);
42     }
43 }
44 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)45 bool DOMVideo::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
46 {
47     // Operator map for attr
48     static const std::unordered_map<std::string, void (*)(const RefPtr<VideoComponent>&, const std::string&)>
49         attrOperators = {
50             { DOM_VIDEO_MUTED,
51                 [](const RefPtr<VideoComponent>& video, const std::string& val) {
52                     video->SetMute(StringToBool(val));
53                 } },
54             { DOM_VIDEO_SRC,
55                 [](const RefPtr<VideoComponent>& video, const std::string& val) {
56                     video->SetSrc(val);
57                 } },
58             { DOM_VIDEO_AUTOPLAY,
59                 [](const RefPtr<VideoComponent>& video, const std::string& val) {
60                     video->SetAutoPlay(StringToBool(val));
61                 } },
62             { DOM_VIDEO_POSTER,
63                 [](const RefPtr<VideoComponent>& video, const std::string& val) {
64                     video->SetPoster(val);
65                 } },
66             { DOM_VIDEO_CONTROLS,
67                 [](const RefPtr<VideoComponent>& video, const std::string& val) {
68                     video->SetNeedControls(StringToBool(val));
69                 } },
70             { DOM_VIDEO_LOOP,
71                 [](const RefPtr<VideoComponent>& video, const std::string& val) {
72                     video->SetLoop(StringToBool(val));
73                 } },
74             { DOM_VIDEO_START_TIME,
75                 [](const RefPtr<VideoComponent>& video, const std::string& val) {
76                     video->SetStartTime(StringToInt(val));
77                 } },
78             { DOM_VIDEO_SPEED, [](const RefPtr<VideoComponent>& video, const std::string& val) {
79                     video->SetSpeed(StringUtils::StringToDouble(val));
80                 } },
81             { DOM_VIDEO_DIRECTION, [](const RefPtr<VideoComponent>& video, const std::string& val) {
82                     video->SetDirection(val);
83                 } },
84         };
85     auto operatorIter = attrOperators.find(attr.first);
86     if (operatorIter != attrOperators.end()) {
87         operatorIter->second(videoChild_, attr.second);
88         return true;
89     }
90     return false;
91 }
92 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)93 bool DOMVideo::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
94 {
95     // Operator map for styles
96     static const std::unordered_map<std::string, void (*)(const RefPtr<VideoComponent>&, const std::string&)>
97         styleOperators = {
98             // Set video-fit
99             { DOM_VIDEO_FIT, [](const RefPtr<VideoComponent>& video,
100                              const std::string& val) { video->SetFit(ConvertStrToFit(val)); } },
101             // Set video-position
102             { DOM_VIDEO_POSITION, [](const RefPtr<VideoComponent>& video,
103                                 const std::string& val) { video->SetImagePosition(ConvertStrToPosition(val)); } },
104         };
105     auto operatorIter = styleOperators.find(style.first);
106     if (operatorIter != styleOperators.end()) {
107         operatorIter->second(videoChild_, style.second);
108         return true;
109     }
110     return false;
111 }
112 
AddSpecializedEvent(int32_t pageId,const std::string & event)113 bool DOMVideo::AddSpecializedEvent(int32_t pageId, const std::string& event)
114 {
115     // Operator map for event
116     static const std::unordered_map<std::string, void (*)(const RefPtr<VideoComponent>&, const EventMarker&)>
117         eventOperators = {
118             { DOM_VIDEO_EVENT_PREPARED, [](const RefPtr<VideoComponent>& video,
119                                         const EventMarker& event) { video->SetPreparedEventId(event); } },
120             { DOM_VIDEO_EVENT_START,
121                 [](const RefPtr<VideoComponent>& video, const EventMarker& event) { video->SetStartEventId(event); } },
122             { DOM_VIDEO_EVENT_PAUSE,
123                 [](const RefPtr<VideoComponent>& video, const EventMarker& event) { video->SetPauseEventId(event); } },
124             { DOM_VIDEO_EVENT_STOP,
125                 [](const RefPtr<VideoComponent>& video, const EventMarker& event) { video->SetStopEventId(event); } },
126             { DOM_VIDEO_EVENT_FINISH,
127                 [](const RefPtr<VideoComponent>& video, const EventMarker& event) { video->SetFinishEventId(event); } },
128             { DOM_VIDEO_EVENT_ERROR,
129                 [](const RefPtr<VideoComponent>& video, const EventMarker& event) { video->SetErrorEventId(event); } },
130             { DOM_VIDEO_EVENT_SEEKING, [](const RefPtr<VideoComponent>& video,
131                                        const EventMarker& event) { video->SetSeekingEventId(event); } },
132             { DOM_VIDEO_EVENT_SEEKED,
133                 [](const RefPtr<VideoComponent>& video, const EventMarker& event) { video->SetSeekedEventId(event); } },
134             { DOM_VIDEO_EVENT_TIMEUPDATE, [](const RefPtr<VideoComponent>& video,
135                                           const EventMarker& event) { video->SetTimeUpdateEventId(event); } },
136             { DOM_VIDEO_EVENT_FULLSCREENCHANGE,
137                 [](const RefPtr<VideoComponent>& video, const EventMarker& event) {
138                     video->SetFullscreenChangeEventId(event);
139                 } },
140         };
141     auto operatorIter = eventOperators.find(event);
142     if (operatorIter != eventOperators.end()) {
143         operatorIter->second(videoChild_, EventMarker(GetNodeIdForEvent(), event, pageId));
144         return true;
145     }
146     return false;
147 }
148 
CallSpecializedMethod(const std::string & method,const std::string & args)149 void DOMVideo::CallSpecializedMethod(const std::string& method, const std::string& args)
150 {
151     // Operator map for method
152     static const std::unordered_map<std::string, void (*)(const RefPtr<VideoComponent>&, const std::string&)>
153         methedOperators = {
154             { DOM_VIDEO_METHOD_START,
155                 [](const RefPtr<VideoComponent>& video, const std::string& args) {
156                     auto controller = video->GetVideoController();
157                     ACE_DCHECK(controller);
158                     controller->Start();
159                 } },
160             { DOM_VIDEO_METHOD_PAUSE,
161                 [](const RefPtr<VideoComponent>& video, const std::string& args) {
162                     auto controller = video->GetVideoController();
163                     ACE_DCHECK(controller);
164                     controller->Pause();
165                 } },
166             { DOM_VIDEO_METHOD_STOP,
167                 [](const RefPtr<VideoComponent>& video, const std::string& args) {
168                   auto controller = video->GetVideoController();
169                   ACE_DCHECK(controller);
170                   controller->Stop();
171                 } },
172             { DOM_VIDEO_METHOD_SEEK_TO,
173                 [](const RefPtr<VideoComponent>& video, const std::string& args) {
174                     auto controller = video->GetVideoController();
175                     ACE_DCHECK(controller);
176                     auto value = GetParamFromJson(args, "currenttime");
177                     if (value) {
178                         int32_t pos = value->GetInt();
179                         controller->SeekTo(pos);
180                     }
181                 } },
182             { DOM_VIDEO_METHOD_REQUEST_FULLSCREEN,
183                 [](const RefPtr<VideoComponent>& video, const std::string& args) {
184                     auto controller = video->GetVideoController();
185                     ACE_DCHECK(controller);
186                     auto value = GetParamFromJson(args, "screenOrientation ");
187                     if (value) {
188                         controller->RequestFullscreen(!(value->GetString() == "landscape"));
189                     }
190                 } },
191             { DOM_VIDEO_METHOD_EXIT_FULLSCREEN,
192                 [](const RefPtr<VideoComponent>& video, const std::string& args) {
193                     auto controller = video->GetVideoController();
194                     ACE_DCHECK(controller);
195                     controller->ExitFullscreen(false);
196                 } },
197         };
198     auto operatorIter = methedOperators.find(method);
199     if (operatorIter != methedOperators.end()) {
200         operatorIter->second(videoChild_, args);
201     }
202 }
203 
GetParamFromJson(const std::string & json,const std::string & key)204 std::unique_ptr<JsonValue> DOMVideo::GetParamFromJson(const std::string& json, const std::string& key)
205 {
206     std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(json);
207     if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() != METHOD_VIDEO_TO_ARGS_SIZE) {
208         LOGE("parse args error");
209         return nullptr;
210     }
211 
212     std::unique_ptr<JsonValue> Value = argsValue->GetArrayItem(0)->GetValue(key);
213     if (!Value) {
214         LOGE("get index failed");
215         return nullptr;
216     }
217     return Value;
218 }
219 
FireFullscreen(bool isFullScreen,const WeakPtr<Player> & player,const WeakPtr<Texture> & texture)220 RefPtr<Component> DOMVideo::FireFullscreen(
221     bool isFullScreen, const WeakPtr<Player>& player, const WeakPtr<Texture>& texture)
222 {
223     const auto& composed = GetRootComponent();
224     ACE_DCHECK(composed);
225     if (isFullScreen) {
226         if (isFullscreen_) {
227             return nullptr;
228         }
229         originComponent_ = composed->GetChild();
230         videoChild_->SetFullscreen(true);
231         videoChild_->SetPlayer(player);
232         videoChild_->SetTexture(texture);
233         composed->SetChild(GetEventComponents(videoChild_));
234         isFullscreen_ = true;
235     } else {
236         if (!isFullscreen_) {
237             return nullptr;
238         }
239         if (!originComponent_) {
240             LOGE("the origin component is null");
241             return nullptr;
242         }
243         videoChild_->SetFullscreen(false);
244         videoChild_->SetPlayer(nullptr);
245         videoChild_->SetTexture(nullptr);
246         composed->SetChild(originComponent_);
247         isFullscreen_ = false;
248 
249         auto controller = videoChild_->GetVideoController();
250         ACE_DCHECK(controller);
251         controller->ExitFullscreen(true);
252         return nullptr;
253     }
254 
255     return GetRootComponent();
256 }
257 
GetEventComponents(const RefPtr<Component> & videoChild)258 RefPtr<Component> DOMVideo::GetEventComponents(const RefPtr<Component>& videoChild)
259 {
260     std::vector<RefPtr<SoleChildComponent>> components;
261     RefPtr<FocusableComponent> focusableEventComponent = GetFocusableComponent();
262     if (focusableEventComponent) {
263         components.emplace_back(focusableEventComponent);
264     }
265     RefPtr<TouchListenerComponent> touchEventComponent = GetTouchListenerComponent();
266     if (touchEventComponent) {
267         components.emplace_back(touchEventComponent);
268     }
269     RefPtr<GestureListenerComponent> gestureEventComponent = GetGestureListenerComponent();
270     if (gestureEventComponent) {
271         components.emplace_back(gestureEventComponent);
272     }
273     RefPtr<MouseListenerComponent> mouseEventComponent = GetMouseListenerComponent();
274     if (mouseEventComponent) {
275         components.emplace_back(mouseEventComponent);
276     }
277     for (int32_t idx = static_cast<int32_t>(components.size()) - 1; idx >= 1; --idx) {
278         components[idx - 1]->SetChild(components[idx]);
279     }
280 
281     auto box = AceType::MakeRefPtr<BoxComponent>();
282     Component::MergeRSNode(box);
283     RefPtr<BoxComponent> oldBox = GetBoxComponent();
284     if (oldBox) {
285         box->SetOnClick(oldBox->GetOnClick());
286     }
287     box->SetChild(videoChild);
288 
289     if (!components.empty()) {
290         const auto& lastEventComponent = components.back();
291         if (lastEventComponent) {
292             lastEventComponent->SetChild(box);
293             return components.front();
294         }
295     }
296     return box;
297 }
298 
ConvertStrToFit(const std::string & fit)299 ImageFit DOMVideo::ConvertStrToFit(const std::string& fit)
300 {
301     static const std::unordered_map<std::string, ImageFit> IMAGE_FIT_TABLE = {
302         { "fill", ImageFit::FILL },
303         { "contain", ImageFit::CONTAIN },
304         { "cover", ImageFit::COVER },
305         { "scaledown", ImageFit::SCALE_DOWN },
306         { "none", ImageFit::NONE },
307     };
308     auto imageFitIter = IMAGE_FIT_TABLE.find(fit);
309     return imageFitIter != IMAGE_FIT_TABLE.end() ? imageFitIter->second : ImageFit::CONTAIN;
310 }
311 
ConvertStrToPosition(const std::string & position)312 ImageObjectPosition DOMVideo::ConvertStrToPosition(const std::string& position)
313 {
314     ImageObjectPosition objectPosition;
315     if (!ParseBackgroundImagePosition(position, objectPosition)) {
316         LOGE("ConvertStrToPosition failed");
317     }
318     return objectPosition;
319 }
320 
321 } // namespace OHOS::Ace::Framework
322