1 /*
2  * Copyright (c) 2024 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 "render_state_observer_manager.h"
17 
18 #include "hilog_tag_wrapper.h"
19 #include "iremote_object.h"
20 
21 namespace OHOS {
22 namespace AppExecFwk {
RenderStateObserverManager()23 RenderStateObserverManager::RenderStateObserverManager()
24 {}
25 
~RenderStateObserverManager()26 RenderStateObserverManager::~RenderStateObserverManager()
27 {}
28 
Init()29 void RenderStateObserverManager::Init()
30 {
31     if (!handler_) {
32         handler_ = AAFwk::TaskHandlerWrap::CreateQueueHandler("render_state_task_queue");
33     }
34 }
35 
RegisterRenderStateObserver(const sptr<IRenderStateObserver> & observer)36 int32_t RenderStateObserverManager::RegisterRenderStateObserver(const sptr<IRenderStateObserver> &observer)
37 {
38     TAG_LOGD(AAFwkTag::APPMGR, "begin.");
39     if (observer == nullptr) {
40         TAG_LOGE(AAFwkTag::APPMGR, "the observer is nullptr.");
41         return ERR_INVALID_VALUE;
42     }
43     if (handler_ == nullptr) {
44         TAG_LOGE(AAFwkTag::APPMGR, "handler is nullptr.");
45         return ERR_INVALID_VALUE;
46     }
47     auto task = [weak = weak_from_this(), observer]() {
48         auto self = weak.lock();
49         if (self == nullptr) {
50             TAG_LOGE(AAFwkTag::APPMGR, "self is nullptr.");
51             return;
52         }
53         self->HandleRegisterRenderStateObserver(observer);
54     };
55     handler_->SubmitTask(task);
56     return ERR_OK;
57 }
58 
HandleRegisterRenderStateObserver(const sptr<IRenderStateObserver> & observer)59 void RenderStateObserverManager::HandleRegisterRenderStateObserver(const sptr<IRenderStateObserver> &observer)
60 {
61     if (deathRecipient_ == nullptr) {
62         std::weak_ptr<RenderStateObserverManager> thisWeakPtr(shared_from_this());
63         deathRecipient_ =
64             new (std::nothrow) RenderStateObserverRecipient([thisWeakPtr](const wptr<IRemoteObject> &remote) {
65                 auto renderStateObserverManager = thisWeakPtr.lock();
66                 if (renderStateObserverManager) {
67                     renderStateObserverManager->OnObserverDied(remote);
68                 }
69             });
70         if (deathRecipient_ == nullptr) {
71             TAG_LOGE(AAFwkTag::APPMGR, "New RenderStateObserverManager failed.");
72         }
73     }
74 
75     auto observerObj = observer->AsObject();
76     if (!observerObj || !observerObj->AddDeathRecipient(deathRecipient_)) {
77         TAG_LOGE(AAFwkTag::APPMGR, "AddDeathRecipient failed.");
78     }
79 
80     observerList_.emplace_back(observer);
81     TAG_LOGD(AAFwkTag::APPMGR, "observerList_ size:%{public}zu", observerList_.size());
82 }
83 
UnregisterRenderStateObserver(const sptr<IRenderStateObserver> & observer)84 int32_t RenderStateObserverManager::UnregisterRenderStateObserver(const sptr<IRenderStateObserver> &observer)
85 {
86     TAG_LOGD(AAFwkTag::APPMGR, "begin.");
87     if (observer == nullptr) {
88         TAG_LOGE(AAFwkTag::APPMGR, "the observer is nullptr.");
89         return ERR_INVALID_VALUE;
90     }
91     if (handler_ == nullptr) {
92         TAG_LOGE(AAFwkTag::APPMGR, "handler is nullptr.");
93         return ERR_INVALID_VALUE;
94     }
95     auto task = [weak = weak_from_this(), observer]() {
96         auto self = weak.lock();
97         if (self == nullptr) {
98             TAG_LOGE(AAFwkTag::APPMGR, "self is nullptr.");
99             return;
100         }
101         self->HandleUnregisterRenderStateObserver(observer);
102     };
103     handler_->SubmitTask(task);
104     return ERR_OK;
105 }
106 
HandleUnregisterRenderStateObserver(const sptr<IRenderStateObserver> & observer)107 void RenderStateObserverManager::HandleUnregisterRenderStateObserver(const sptr<IRenderStateObserver> &observer)
108 {
109     auto it = std::find_if(observerList_.begin(), observerList_.end(),
110         [&observer](const sptr<IRenderStateObserver> &item) {
111         return (item && item->AsObject() == observer->AsObject());
112     });
113     if (it != observerList_.end()) {
114         observerList_.erase(it);
115         TAG_LOGI(AAFwkTag::APPMGR, "observerList_ size:%{public}zu", observerList_.size());
116         return;
117     }
118     TAG_LOGE(AAFwkTag::APPMGR, "Observer not exist or has been removed.");
119 }
120 
OnRenderStateChanged(const std::shared_ptr<RenderRecord> & renderRecord,int32_t state)121 int32_t RenderStateObserverManager::OnRenderStateChanged(const std::shared_ptr<RenderRecord> &renderRecord,
122     int32_t state)
123 {
124     if (handler_ == nullptr) {
125         TAG_LOGE(AAFwkTag::APPMGR, "handler is nullptr.");
126         return ERR_INVALID_VALUE;
127     }
128     auto task = [weak = weak_from_this(), renderRecord, state]() {
129         auto self = weak.lock();
130         if (self == nullptr) {
131             TAG_LOGE(AAFwkTag::APPMGR, "self is nullptr.");
132             return;
133         }
134         self->HandleOnRenderStateChanged(renderRecord, state);
135     };
136     handler_->SubmitTask(task);
137     return ERR_OK;
138 }
139 
HandleOnRenderStateChanged(const std::shared_ptr<RenderRecord> & renderRecord,int32_t state)140 void RenderStateObserverManager::HandleOnRenderStateChanged(const std::shared_ptr<RenderRecord> &renderRecord,
141     int32_t state)
142 {
143     if (renderRecord == nullptr) {
144         TAG_LOGE(AAFwkTag::APPMGR, "renderRecord is nullptr");
145         return;
146     }
147     RenderStateData data = WrapRenderStateData(renderRecord, state);
148     TAG_LOGD(AAFwkTag::APPMGR,
149         "pid:%{public}d, hostPid:%{public}d, uid:%{public}d, hostUid:%{public}d, state:%{public}d",
150         data.pid, data.hostPid, data.uid, data.hostUid, data.state);
151     for (auto it = observerList_.begin(); it != observerList_.end(); ++it) {
152         if ((*it) == nullptr) {
153             continue;
154         }
155         (*it)->OnRenderStateChanged(data);
156     }
157 }
158 
WrapRenderStateData(const std::shared_ptr<RenderRecord> & renderRecord,int32_t state)159 RenderStateData RenderStateObserverManager::WrapRenderStateData(const std::shared_ptr<RenderRecord> &renderRecord,
160     int32_t state)
161 {
162     RenderStateData renderStateData;
163     renderStateData.pid = renderRecord->GetPid();
164     renderStateData.uid = renderRecord->GetUid();
165     renderStateData.hostPid = renderRecord->GetHostPid();
166     renderStateData.hostUid = renderRecord->GetHostUid();
167     renderStateData.state = state;
168     return renderStateData;
169 }
170 
OnObserverDied(const wptr<IRemoteObject> & remote)171 void RenderStateObserverManager::OnObserverDied(const wptr<IRemoteObject> &remote)
172 {
173     TAG_LOGI(AAFwkTag::APPMGR, "OnObserverDied begin.");
174     auto remoteObj = remote.promote();
175     if (remoteObj == nullptr) {
176         TAG_LOGE(AAFwkTag::APPMGR, "observer is nullptr.");
177         return;
178     }
179     remoteObj->RemoveDeathRecipient(deathRecipient_);
180 
181     sptr<IRenderStateObserver> observer = iface_cast<IRenderStateObserver>(remoteObj);
182     UnregisterRenderStateObserver(observer);
183 }
184 
RenderStateObserverRecipient(RemoteDiedHandler handler)185 RenderStateObserverRecipient::RenderStateObserverRecipient(RemoteDiedHandler handler) : handler_(handler)
186 {}
187 
~RenderStateObserverRecipient()188 RenderStateObserverRecipient::~RenderStateObserverRecipient()
189 {}
190 
OnRemoteDied(const wptr<IRemoteObject> & remote)191 void RenderStateObserverRecipient::OnRemoteDied(const wptr<IRemoteObject> &__attribute__((unused)) remote)
192 {
193     TAG_LOGE(AAFwkTag::APPMGR, "RenderStateObserverRecipient On remote died.");
194     if (handler_) {
195         handler_(remote);
196     }
197 }
198 } // namespace AppExecFwk
199 } // namespace OHOS