• 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 "rs_render_service_connect_hub.h"
17 
18 #include <if_system_ability_manager.h>
19 #include <iremote_stub.h>
20 #include <iservice_registry.h>
21 #include <mutex>
22 #include <system_ability_definition.h>
23 #include <unistd.h>
24 
25 #include "message_parcel.h"
26 #include "pipeline/rs_render_thread.h"
27 #include "platform/common/rs_log.h"
28 #include "rs_render_service_connection_proxy.h"
29 #include "rs_render_service_proxy.h"
30 
31 namespace OHOS {
32 namespace Rosen {
33 std::once_flag RSRenderServiceConnectHub::flag_;
34 RSRenderServiceConnectHub* RSRenderServiceConnectHub::instance_ = nullptr;
35 OnConnectCallback RSRenderServiceConnectHub::onConnectCallback_ = nullptr;
36 
GetInstance()37 RSRenderServiceConnectHub* RSRenderServiceConnectHub::GetInstance()
38 {
39     std::call_once(flag_, &RSRenderServiceConnectHub::Init);
40     return instance_;
41 }
42 
Init()43 void RSRenderServiceConnectHub::Init()
44 {
45     RS_LOGI("RSRenderServiceConnectHub::Init");
46     instance_ = new RSRenderServiceConnectHub();
47     ::atexit(&RSRenderServiceConnectHub::Destroy);
48 }
49 
Destroy()50 void RSRenderServiceConnectHub::Destroy()
51 {
52     RS_LOGI("RSRenderServiceConnectHub::Destroy");
53     instance_ = nullptr;
54 }
55 
RSRenderServiceConnectHub()56 RSRenderServiceConnectHub::RSRenderServiceConnectHub()
57 {
58     RS_LOGI("RSRenderServiceConnectHub: ctor");
59 }
60 
~RSRenderServiceConnectHub()61 RSRenderServiceConnectHub::~RSRenderServiceConnectHub()
62 {
63     RS_LOGI("~RSRenderServiceConnectHub: dtor");
64 }
65 
GetRenderService()66 sptr<RSIRenderServiceConnection> RSRenderServiceConnectHub::GetRenderService()
67 {
68     auto connHub = RSRenderServiceConnectHub::GetInstance();
69     return connHub == nullptr ? nullptr : connHub->GetRenderServiceConnection();
70 }
71 
GetRenderServiceConnection()72 sptr<RSIRenderServiceConnection> RSRenderServiceConnectHub::GetRenderServiceConnection()
73 {
74     {
75         std::lock_guard<std::mutex> lock(mutex_);
76         if (conn_ != nullptr && renderService_ != nullptr) {
77             return conn_;
78         }
79     }
80 
81     if (!Connect()) {
82         ROSEN_LOGE("RenderService connect fail");
83         return nullptr;
84     }
85 
86     std::lock_guard<std::mutex> lock(mutex_);
87     return conn_;
88 }
89 
Connect()90 bool RSRenderServiceConnectHub::Connect()
91 {
92     int tryCnt = 0;
93     sptr<RSIRenderService> renderService = nullptr;
94     do {
95         // sleep move time (1000us * tryCnt) when tryCnt++
96         usleep(1000 * tryCnt);
97         ++tryCnt;
98         // try most 5 times to get render service.
99         if (tryCnt == 5) {
100             ROSEN_LOGE("RSRenderServiceConnectHub::Connect failed, tried %d times.", tryCnt);
101             break;
102         }
103 
104         auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
105         if (samgr == nullptr) {
106             continue;
107         }
108         auto remoteObject = samgr->GetSystemAbility(RENDER_SERVICE);
109         if (remoteObject == nullptr || !remoteObject->IsProxyObject()) {
110             continue;
111         }
112         renderService = iface_cast<RSRenderServiceProxy>(remoteObject);
113         if (renderService != nullptr) {
114             break;
115         }
116     } while (true);
117 
118     if (renderService == nullptr) {
119         ROSEN_LOGE("RSRenderServiceConnectHub::Connect, failed to get render service proxy.");
120         return false;
121     }
122 
123     deathRecipient_ = new RenderServiceDeathRecipient(this);
124     if (!renderService->AsObject()->AddDeathRecipient(deathRecipient_)) {
125         ROSEN_LOGW("RSRenderServiceConnectHub::Connect, failed to AddDeathRecipient of render service.");
126     }
127 
128     if (token_ == nullptr) {
129         token_ = new IRemoteStub<RSIConnectionToken>();
130     }
131 
132     sptr<RSIRenderServiceConnection> conn = renderService->CreateConnection(token_);
133     if (conn == nullptr) {
134         ROSEN_LOGE("RSRenderServiceConnectHub::Connect, failed to CreateConnection to render service.");
135         return false;
136     }
137 
138     {
139         std::lock_guard<std::mutex> lock(mutex_);
140         renderService_ = renderService;
141         conn_ = conn;
142 
143         if (onConnectCallback_) {
144             onConnectCallback_(conn_);
145         }
146     }
147 
148     return true;
149 }
150 
ConnectDied()151 void RSRenderServiceConnectHub::ConnectDied()
152 {
153     mutex_.lock();
154     RS_LOGI("RSRenderServiceConnectHub::ConnectDied lock pid: %d", getpid());
155     renderService_ = nullptr;
156     conn_ = nullptr;
157     deathRecipient_ = nullptr;
158     token_ = nullptr;
159     mutex_.unlock();
160     RS_LOGI("RSRenderServiceConnectHub::ConnectDied unlock pid: %d", getpid());
161 }
162 
OnRemoteDied(const wptr<IRemoteObject> & remote)163 void RSRenderServiceConnectHub::RenderServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
164 {
165     auto remoteSptr = remote.promote();
166     if (remoteSptr == nullptr) {
167         ROSEN_LOGW("RSRenderServiceConnectHub::RenderServiceDeathRecipient::OnRemoteDied: can't promote.");
168         return;
169     }
170 
171     auto rsConnHub = rsConnHub_.promote();
172     if (rsConnHub == nullptr) {
173         ROSEN_LOGW("RSRenderServiceConnectHub::RenderServiceDeathRecipient::OnRemoteDied: connHub was dead.");
174         return;
175     }
176 
177     rsConnHub->ConnectDied();
178 }
179 } // namespace Rosen
180 } // namespace OHOS
181