1 /*
2  * Copyright (c) 2023 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 "adapter/ohos/capability/time/time_event_proxy_ohos.h"
16 
17 #include "common_event_manager.h"
18 #include "common_event_support.h"
19 
20 #include "frameworks/core/common/container.h"
21 #include "frameworks/core/common/container_scope.h"
22 
23 namespace OHOS::Ace {
24 std::unique_ptr<TimeEventProxy> TimeEventProxy::instance_;
25 std::mutex TimeEventProxy::mutex_;
26 
GetInstance()27 TimeEventProxy* TimeEventProxy::GetInstance()
28 {
29     if (!instance_) {
30         std::scoped_lock lock(mutex_);
31         if (!instance_) {
32             instance_ = std::make_unique<TimeEventProxyOhos>();
33         }
34     }
35     return instance_.get();
36 }
37 
38 using OHOS::EventFwk::CommonEventManager;
39 using OHOS::EventFwk::CommonEventSubscribeInfo;
40 using OHOS::EventFwk::CommonEventSupport;
41 using OHOS::EventFwk::MatchingSkills;
42 
OnReceiveEvent(const CommonEventData &)43 void TimeEventSubscriber::OnReceiveEvent(const CommonEventData& /* data */)
44 {
45     TimeEventProxy::GetInstance()->OnTimeChange();
46 }
47 
TimeEventProxyOhos()48 TimeEventProxyOhos::TimeEventProxyOhos()
49 {
50     MatchingSkills matchingSkills;
51     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_TIME_CHANGED);
52     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_TIMEZONE_CHANGED);
53     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SCREEN_ON);
54     auto container = Container::Current();
55     if (container && container->IsFRSCardContainer()) {
56         matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_TIME_TICK);
57     }
58 
59     CommonEventSubscribeInfo subscribeInfo(matchingSkills);
60     subscribeInfo.SetThreadMode(CommonEventSubscribeInfo::ThreadMode::HANDLER);
61 
62     eventFwkSubscriber_ = std::make_shared<TimeEventSubscriber>(subscribeInfo);
63 }
64 
~TimeEventProxyOhos()65 TimeEventProxyOhos::~TimeEventProxyOhos()
66 {
67     CommonEventManager::UnSubscribeCommonEvent(eventFwkSubscriber_);
68 }
69 
70 namespace {
NotifyCard(const RefPtr<TimeChangeListener> & listener)71 void NotifyCard(const RefPtr<TimeChangeListener>& listener)
72 {
73     auto taskExecutor = Container::CurrentTaskExecutor();
74     CHECK_NULL_VOID(taskExecutor);
75     if (taskExecutor->WillRunOnCurrentThread(TaskExecutor::TaskType::UI)) {
76         listener->OnTimeChange();
77     } else {
78         taskExecutor->PostTask(
79             [listener, id = Container::CurrentId()] {
80                 ContainerScope scope(id);
81                 listener->OnTimeChange();
82             },
83             TaskExecutor::TaskType::UI, "ArkUINotifyCardTimeChange");
84     }
85 }
86 } // namespace
87 
OnTimeChange()88 void TimeEventProxyOhos::OnTimeChange()
89 {
90     for (auto it = listeners_.begin(); it != listeners_.end();) {
91         auto listener = it->first.Upgrade();
92         if (listener) {
93             ContainerScope scope(it->second);
94             auto container = Container::Current();
95             if (container && container->IsFRSCardContainer()) {
96                 NotifyCard(listener);
97             } else {
98                 listener->OnTimeChange();
99             }
100             ++it;
101         } else {
102             it = listeners_.erase(it);
103         }
104     }
105 }
106 
Register(const WeakPtr<TimeChangeListener> & listener)107 void TimeEventProxyOhos::Register(const WeakPtr<TimeChangeListener>& listener)
108 {
109     if (listeners_.empty()) {
110         CommonEventManager::SubscribeCommonEvent(eventFwkSubscriber_);
111     }
112     listeners_.insert({ listener, Container::CurrentId() });
113 }
114 } // namespace OHOS::Ace
115