• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "core/components_ng/gestures/gesture_referee.h"
16 
17 #include "core/common/ace_application_info.h"
18 #include "core/components_ng/gestures/recognizers/recognizer_group.h"
19 
20 namespace OHOS::Ace::NG {
21 
AddMember(const RefPtr<NGGestureRecognizer> & recognizer)22 void GestureScope::AddMember(const RefPtr<NGGestureRecognizer>& recognizer)
23 {
24     CHECK_NULL_VOID(recognizer);
25 
26     if (Existed(recognizer)) {
27         return;
28     }
29 
30     recognizers_.emplace_back(recognizer);
31 }
32 
Existed(const RefPtr<NGGestureRecognizer> & recognizer)33 bool GestureScope::Existed(const RefPtr<NGGestureRecognizer>& recognizer)
34 {
35     CHECK_NULL_RETURN(recognizer, false);
36 
37     if (recognizers_.empty()) {
38         return false;
39     }
40 
41     auto result = std::find(recognizers_.cbegin(), recognizers_.cend(), recognizer);
42     return result != recognizers_.cend();
43 }
44 
CheckNeedBlocked(const RefPtr<NGGestureRecognizer> & recognizer)45 bool GestureScope::CheckNeedBlocked(const RefPtr<NGGestureRecognizer>& recognizer)
46 {
47     for (const auto& weak : recognizers_) {
48         auto member = weak.Upgrade();
49         if (!member || member->GetRefereeState() != RefereeState::PENDING) {
50             continue;
51         }
52         if (member == recognizer) {
53             return false;
54         }
55         RefPtr<NGGestureRecognizer> group = member->GetGestureGroup().Upgrade();
56         while (group) {
57             if (group == recognizer) {
58                 return false;
59             }
60             group = group->GetGestureGroup().Upgrade();
61         }
62         return true;
63     }
64     return false;
65 }
66 
OnAcceptGesture(const RefPtr<NGGestureRecognizer> & recognizer)67 void GestureScope::OnAcceptGesture(const RefPtr<NGGestureRecognizer>& recognizer)
68 {
69     hasGestureAccepted_ = true;
70     for (const auto& weak : recognizers_) {
71         auto gesture = weak.Upgrade();
72         if (gesture == recognizer) {
73             continue;
74         }
75         if (!gesture || gesture->IsBridgeMode()) {
76             continue;
77         }
78         gesture->OnRejected();
79         gesture->OnRejectBridgeObj();
80     }
81     if (queryStateFunc_) {
82         queryStateFunc_(touchId_);
83     }
84 }
85 
UnBlockGesture()86 RefPtr<NGGestureRecognizer> GestureScope::UnBlockGesture()
87 {
88     auto iter =
89         std::find_if(std::begin(recognizers_), std::end(recognizers_), [](const WeakPtr<NGGestureRecognizer>& member) {
90             auto recognizer = member.Upgrade();
91             return recognizer && ((recognizer->GetRefereeState() == RefereeState::PENDING_BLOCKED) ||
92                                      (recognizer->GetRefereeState() == RefereeState::SUCCEED_BLOCKED));
93         });
94     if (iter == recognizers_.end()) {
95         return nullptr;
96     }
97     return (*iter).Upgrade();
98 }
99 
IsPending(size_t touchId)100 bool GestureScope::IsPending(size_t touchId)
101 {
102     auto iter = std::find_if(
103         std::begin(recognizers_), std::end(recognizers_), [touchId](const WeakPtr<NGGestureRecognizer>& member) {
104             auto recognizer = member.Upgrade();
105             RefereeState state = RefereeState::READY;
106             if (recognizer) {
107                 state = recognizer->GetRefereeState();
108                 if (AceType::InstanceOf<RecognizerGroup>(recognizer)) {
109                     auto group = AceType::DynamicCast<RecognizerGroup>(recognizer);
110                     state = group->CheckStates(touchId);
111                 }
112             }
113             return recognizer && ((state == RefereeState::PENDING));
114         });
115     return iter != recognizers_.end();
116 }
117 
DectectAllDone(const RefPtr<NGGestureRecognizer> recognizer)118 bool DectectAllDone(const RefPtr<NGGestureRecognizer> recognizer)
119 {
120     RefereeState state = recognizer->GetRefereeState();
121     if (!AceType::InstanceOf<RecognizerGroup>(recognizer)) {
122         if (state != RefereeState::SUCCEED && state != RefereeState::SUCCEED_BLOCKED &&
123             state != RefereeState::FAIL && state != RefereeState::READY &&
124             state != RefereeState::DETECTING) {
125             return false;
126         }
127     } else {
128         auto group = AceType::DynamicCast<RecognizerGroup>(recognizer);
129         for (const auto& item : group->GetGroupRecognizer()) {
130             bool ret = DectectAllDone(item);
131             if (!ret) {
132                 return false;
133             }
134         }
135     }
136     return true;
137 }
138 
QueryAllDone(size_t touchId)139 bool GestureScope::QueryAllDone(size_t touchId)
140 {
141     bool ret = true;
142     for (auto item : recognizers_) {
143         auto recognizer = item.Upgrade();
144         if (!recognizer) {
145             continue;
146         }
147         ret = DectectAllDone(recognizer);
148         if (ret == false) {
149             break;
150         }
151     }
152     return ret;
153 }
154 
Close(bool isBlocked)155 void GestureScope::Close(bool isBlocked)
156 {
157     for (const auto& weak : recognizers_) {
158         auto recognizer = weak.Upgrade();
159         if (recognizer) {
160             auto weakGroup = recognizer->GetGestureGroup();
161             auto group = weakGroup.Upgrade();
162             while (group) {
163                 recognizer = group;
164                 weakGroup = group->GetGestureGroup();
165                 group = weakGroup.Upgrade();
166             }
167             recognizer->FinishReferee(static_cast<int32_t>(touchId_), isBlocked);
168         }
169     }
170 }
171 
CheckRecognizer(const RefPtr<NGGestureRecognizer> & recognizer)172 static bool CheckRecognizer(const RefPtr<NGGestureRecognizer>& recognizer)
173 {
174     if (!recognizer) {
175         return false;
176     }
177     auto group = AceType::DynamicCast<RecognizerGroup>(recognizer);
178     if (!group) {
179         return recognizer->GetRefereeState() == RefereeState::PENDING;
180     }
181     auto children = group->GetGroupRecognizer();
182     for (auto iter = children.begin(); iter != children.end(); ++iter) {
183         if (CheckRecognizer(*iter)) {
184             return true;
185         }
186     }
187     return group->CheckGroupState();
188 }
189 
CheckRecognizerState()190 bool GestureScope::CheckRecognizerState()
191 {
192     for (auto& weak : recognizers_) {
193         auto recognizer = weak.Upgrade();
194         if (CheckRecognizer(recognizer)) {
195             return true;
196         }
197     }
198     return false;
199 }
200 
IsReady()201 bool GestureScope::IsReady()
202 {
203     for (const auto& weak : recognizers_) {
204         auto recognizer = weak.Upgrade();
205         if (recognizer && !recognizer->IsReady()) {
206             return false;
207         }
208     }
209     return true;
210 }
211 
HasFailRecognizer()212 bool GestureScope::HasFailRecognizer()
213 {
214     for (const auto& weak : recognizers_) {
215         auto recognizer = weak.Upgrade();
216         if (recognizer && recognizer->GetRefereeState() == RefereeState::FAIL) {
217             return true;
218         }
219     }
220     return false;
221 }
222 
IsAnySucceedRecognizerExist()223 bool GestureScope::IsAnySucceedRecognizerExist()
224 {
225     for (const auto& weak : recognizers_) {
226         auto recognizer = weak.Upgrade();
227         if (recognizer && (recognizer->GetRefereeState() == RefereeState::SUCCEED ||
228                               recognizer->GetRefereeState() == RefereeState::SUCCEED_BLOCKED)) {
229             return true;
230         }
231     }
232     return false;
233 }
234 
ForceCleanGestureScope()235 void GestureScope::ForceCleanGestureScope()
236 {
237     for (const auto& weak : recognizers_) {
238         auto recognizer = weak.Upgrade();
239         if (recognizer) {
240             recognizer->ForceCleanRecognizer();
241         }
242     }
243     recognizers_.clear();
244 }
245 
ForceCleanGestureScopeState()246 void GestureScope::ForceCleanGestureScopeState()
247 {
248     for (const auto& weak : recognizers_) {
249         auto recognizer = weak.Upgrade();
250         if (recognizer) {
251             recognizer->ForceCleanRecognizer();
252         }
253     }
254 }
255 
CleanGestureScopeState()256 void GestureScope::CleanGestureScopeState()
257 {
258     for (const auto& weak : recognizers_) {
259         auto recognizer = weak.Upgrade();
260         auto multiFingerRecognizer = AceType::DynamicCast<MultiFingersRecognizer>(recognizer);
261         if (multiFingerRecognizer && multiFingerRecognizer->CheckTouchId(touchId_) &&
262             multiFingerRecognizer->GetTouchPointsSize() == 1) {
263             multiFingerRecognizer->CleanRecognizerState();
264         }
265     }
266 }
267 
CleanGestureScopeStateVoluntarily()268 void GestureScope::CleanGestureScopeStateVoluntarily()
269 {
270     for (const auto& weak : recognizers_) {
271         auto recognizer = weak.Upgrade();
272         if (recognizer) {
273             recognizer->CleanRecognizerStateVoluntarily();
274         }
275     }
276 }
277 
AddGestureToScope(size_t touchId,const TouchTestResult & result)278 void GestureReferee::AddGestureToScope(size_t touchId, const TouchTestResult& result)
279 {
280     RefPtr<GestureScope> scope;
281     const auto iter = gestureScopes_.find(touchId);
282     if (iter != gestureScopes_.end()) {
283         scope = iter->second;
284     } else {
285         scope = MakeRefPtr<GestureScope>(touchId);
286         gestureScopes_.try_emplace(touchId, scope);
287     }
288     for (const auto& item : result) {
289         if (AceType::InstanceOf<NGGestureRecognizer>(item)) {
290             scope->AddMember(DynamicCast<NGGestureRecognizer>(item));
291             scope->SetQueryStateFunc(queryStateFunc_);
292         }
293     }
294 }
295 
CleanGestureScope(size_t touchId)296 void GestureReferee::CleanGestureScope(size_t touchId)
297 {
298     const auto iter = gestureScopes_.find(touchId);
299     if (iter != gestureScopes_.end()) {
300         const auto& scope = iter->second;
301         if (scope->IsPending(touchId)) {
302             scope->SetDelayClose();
303             return;
304         }
305         scope->Close();
306         gestureScopes_.erase(iter);
307     }
308 }
309 
CleanGestureStateVoluntarily(size_t touchId)310 void GestureReferee::CleanGestureStateVoluntarily(size_t touchId)
311 {
312     const auto iter = gestureScopes_.find(touchId);
313     if (iter != gestureScopes_.end()) {
314         const auto& scope = iter->second;
315         CHECK_NULL_VOID(scope);
316         scope->CleanGestureScopeStateVoluntarily();
317     }
318 }
319 
QueryAllDone(size_t touchId)320 bool GestureReferee::QueryAllDone(size_t touchId)
321 {
322     bool ret = true;
323     const auto iter = gestureScopes_.find(touchId);
324     if (iter != gestureScopes_.end()) {
325         const auto& scope = iter->second;
326         ret = scope->QueryAllDone(touchId);
327     }
328     return ret;
329 }
330 
QueryAllDone()331 bool GestureReferee::QueryAllDone()
332 {
333     for (auto iter = gestureScopes_.begin(); iter != gestureScopes_.end(); ++iter) {
334         if (!iter->second->QueryAllDone(iter->first)) {
335             return false;
336         }
337     }
338     return true;
339 }
340 
CheckEventTypeChange(SourceType type,bool isAxis) const341 bool GestureReferee::CheckEventTypeChange(SourceType type, bool isAxis) const
342 {
343     if (!isAxis && lastIsAxis_) {
344         return (type == SourceType::TOUCH || type == SourceType::MOUSE);
345     }
346     return false;
347 }
348 
CheckSourceTypeChange(SourceType type,bool isAxis_)349 bool GestureReferee::CheckSourceTypeChange(SourceType type, bool isAxis_)
350 {
351     bool ret = false;
352     if (type != lastSourceType_) {
353         ret = true;
354         lastSourceType_ = type;
355     }
356     if (isAxis_ != lastIsAxis_) {
357         ret = true;
358         lastIsAxis_ = isAxis_;
359     }
360     return ret;
361 }
362 
CleanAll(bool isBlocked)363 void GestureReferee::CleanAll(bool isBlocked)
364 {
365     for (auto iter = gestureScopes_.begin(); iter != gestureScopes_.end(); iter++) {
366         iter->second->Close(isBlocked);
367     }
368     gestureScopes_.clear();
369 }
370 
CleanRedundanceScope()371 void GestureReferee::CleanRedundanceScope()
372 {
373     for (auto iter = gestureScopes_.begin(); iter != gestureScopes_.end(); iter++) {
374         if (iter->second->CheckRecognizerState()) {
375             continue;
376         }
377         iter->second->Close();
378     }
379 }
380 
IsReady()381 bool GestureReferee::IsReady()
382 {
383     for (auto iter = gestureScopes_.begin(); iter != gestureScopes_.end(); iter++) {
384         if (!iter->second->IsReady()) {
385             return false;
386         }
387     }
388     return true;
389 }
390 
HasFailRecognizer(int32_t touchId)391 bool GestureReferee::HasFailRecognizer(int32_t touchId)
392 {
393     const auto& iter = gestureScopes_.find(touchId);
394     if (iter == gestureScopes_.end()) {
395         return false;
396     }
397 
398     const auto& scope = iter->second;
399     CHECK_NULL_RETURN(scope, false);
400 
401     return scope->HasFailRecognizer();
402 }
403 
IsAnySucceedRecognizerExist(int32_t touchId)404 bool GestureReferee::IsAnySucceedRecognizerExist(int32_t touchId)
405 {
406     const auto& iter = gestureScopes_.find(touchId);
407     if (iter == gestureScopes_.end()) {
408         return false;
409     }
410 
411     const auto& scope = iter->second;
412     CHECK_NULL_RETURN(scope, false);
413 
414     return scope->IsAnySucceedRecognizerExist();
415 }
416 
ForceCleanGestureReferee()417 void GestureReferee::ForceCleanGestureReferee()
418 {
419     for (auto iter = gestureScopes_.begin(); iter != gestureScopes_.end(); iter++) {
420         iter->second->ForceCleanGestureScope();
421     }
422     gestureScopes_.clear();
423 }
424 
ForceCleanGestureRefereeState()425 void GestureReferee::ForceCleanGestureRefereeState()
426 {
427     for (auto iter = gestureScopes_.begin(); iter != gestureScopes_.end(); iter++) {
428         iter->second->ForceCleanGestureScopeState();
429     }
430 }
431 
CleanGestureRefereeState(int32_t touchId)432 void GestureReferee::CleanGestureRefereeState(int32_t touchId)
433 {
434     const auto& iter = gestureScopes_.find(touchId);
435     if (iter == gestureScopes_.end()) {
436         return;
437     }
438 
439     const auto& scope = iter->second;
440     CHECK_NULL_VOID(scope);
441 
442     scope->CleanGestureScopeState();
443 }
444 
Adjudicate(const RefPtr<NGGestureRecognizer> & recognizer,GestureDisposal disposal)445 void GestureReferee::Adjudicate(const RefPtr<NGGestureRecognizer>& recognizer, GestureDisposal disposal)
446 {
447     CHECK_NULL_VOID(recognizer);
448 
449     switch (disposal) {
450         case GestureDisposal::ACCEPT:
451             HandleAcceptDisposal(recognizer);
452             break;
453         case GestureDisposal::PENDING:
454             HandlePendingDisposal(recognizer);
455             break;
456         case GestureDisposal::REJECT:
457             HandleRejectDisposal(recognizer);
458             break;
459         default:
460             break;
461     }
462 }
463 
HandleAcceptDisposal(const RefPtr<NGGestureRecognizer> & recognizer)464 void GestureReferee::HandleAcceptDisposal(const RefPtr<NGGestureRecognizer>& recognizer)
465 {
466     CHECK_NULL_VOID(recognizer);
467 
468     if (recognizer->GetRefereeState() == RefereeState::SUCCEED) {
469         return;
470     }
471 
472     bool isBlocked = false;
473     for (const auto& scope : gestureScopes_) {
474         if (scope.second->CheckNeedBlocked(recognizer)) {
475             isBlocked = true;
476             break;
477         }
478     }
479     if (isBlocked) {
480         recognizer->OnBlocked();
481         return;
482     }
483     recognizer->AboutToAccept();
484     for (const auto& scope : gestureScopes_) {
485         scope.second->OnAcceptGesture(recognizer);
486     }
487 }
488 
HandlePendingDisposal(const RefPtr<NGGestureRecognizer> & recognizer)489 void GestureReferee::HandlePendingDisposal(const RefPtr<NGGestureRecognizer>& recognizer)
490 {
491     CHECK_NULL_VOID(recognizer);
492 
493     if (recognizer->GetRefereeState() == RefereeState::PENDING) {
494         return;
495     }
496 
497     bool isBlocked = false;
498     for (const auto& scope : gestureScopes_) {
499         if (scope.second->CheckNeedBlocked(recognizer)) {
500             isBlocked = true;
501             break;
502         }
503     }
504     if (isBlocked) {
505         recognizer->OnBlocked();
506         return;
507     }
508     recognizer->OnPending();
509 }
510 
HandleRejectDisposal(const RefPtr<NGGestureRecognizer> & recognizer)511 void GestureReferee::HandleRejectDisposal(const RefPtr<NGGestureRecognizer>& recognizer)
512 {
513     CHECK_NULL_VOID(recognizer);
514 
515     if (recognizer->GetRefereeState() == RefereeState::FAIL) {
516         return;
517     }
518 
519     auto prevState = recognizer->GetRefereeState();
520     recognizer->OnRejected();
521     if (prevState != RefereeState::PENDING) {
522         return;
523     }
524     RefPtr<NGGestureRecognizer> newBlockRecognizer;
525     for (const auto& scope : gestureScopes_) {
526         newBlockRecognizer = scope.second->UnBlockGesture();
527         if (newBlockRecognizer) {
528             break;
529         }
530     }
531     if (newBlockRecognizer) {
532         if (newBlockRecognizer->GetRefereeState() == RefereeState::PENDING_BLOCKED) {
533             newBlockRecognizer->OnPending();
534         } else if (newBlockRecognizer->GetRefereeState() == RefereeState::SUCCEED_BLOCKED) {
535             newBlockRecognizer->AboutToAccept();
536             for (const auto& scope : gestureScopes_) {
537                 scope.second->OnAcceptGesture(newBlockRecognizer);
538             }
539         }
540     }
541 }
542 
HasGestureAccepted(size_t touchId) const543 bool GestureReferee::HasGestureAccepted(size_t touchId) const
544 {
545     const auto& iter = gestureScopes_.find(touchId);
546     if (iter == gestureScopes_.end()) {
547         return false;
548     }
549 
550     const auto& scope = iter->second;
551     CHECK_NULL_RETURN(scope, false);
552     return scope->HasGestureAccepted();
553 }
554 
555 } // namespace OHOS::Ace::NG
556