1 /*
2 * Copyright (c) 2021 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 "vsync_connection_proxy.h"
17 #include "graphic_common.h"
18 #include "vsync_log.h"
19
20 constexpr int MAX_RETRY = 3;
21 constexpr int RETRY_INTERVAL = 1000; // 1000us = 1ms
22 constexpr unsigned int DVSYNC_ANIMATION_LIST_SIZE_MAX = 20;
23 namespace OHOS {
24 namespace Rosen {
VSyncConnectionProxy(const sptr<IRemoteObject> & impl)25 VSyncConnectionProxy::VSyncConnectionProxy(const sptr<IRemoteObject>& impl)
26 : IRemoteProxy<IVSyncConnection>(impl)
27 {
28 }
29
RequestNextVSync()30 VsyncError VSyncConnectionProxy::RequestNextVSync()
31 {
32 return RequestNextVSync("unknown", 0);
33 }
34
RequestNextVSync(const std::string & fromWhom,int64_t lastVSyncTS,const int64_t & requestVsyncTime)35 VsyncError VSyncConnectionProxy::RequestNextVSync(
36 const std::string& fromWhom, int64_t lastVSyncTS, const int64_t& requestVsyncTime)
37 {
38 MessageOption opt(MessageOption::TF_ASYNC);
39 MessageParcel arg;
40 MessageParcel ret;
41
42 if (!arg.WriteInterfaceToken(GetDescriptor())) {
43 VLOGE("Failed to write interface token");
44 return VSYNC_ERROR_API_FAILED;
45 }
46 auto remote = Remote();
47 if (remote == nullptr) {
48 VLOGE("remote is null");
49 return VSYNC_ERROR_API_FAILED;
50 }
51
52 int sendCount = 0;
53 int res = NO_ERROR;
54 do {
55 res = remote->SendRequest(IVSYNC_CONNECTION_REQUEST_NEXT_VSYNC, arg, ret, opt);
56 if (res != NO_ERROR && sendCount < MAX_RETRY) {
57 sendCount++;
58 VLOGE("ipc send fail, error:%{public}d, try again, times:%{public}d", res, sendCount);
59 usleep(RETRY_INTERVAL * sendCount);
60 } else if (res != NO_ERROR) {
61 return VSYNC_ERROR_BINDER_ERROR;
62 }
63 } while (res != NO_ERROR);
64 return VSYNC_ERROR_OK;
65 }
66
SetUiDvsyncSwitch(bool dvsyncSwitch)67 VsyncError VSyncConnectionProxy::SetUiDvsyncSwitch(bool dvsyncSwitch)
68 {
69 MessageOption opt(MessageOption::TF_ASYNC);
70 MessageParcel arg;
71 MessageParcel ret;
72
73 if (!arg.WriteInterfaceToken(GetDescriptor())) {
74 VLOGE("Failed to write interface token");
75 return VSYNC_ERROR_API_FAILED;
76 }
77 if (!arg.WriteBool(dvsyncSwitch)) {
78 VLOGE("Failed to write dvsyncSwitch:%{public}d", dvsyncSwitch);
79 return VSYNC_ERROR_API_FAILED;
80 }
81 auto remote = Remote();
82 if (remote == nullptr) {
83 VLOGE("remote is null");
84 return VSYNC_ERROR_API_FAILED;
85 }
86 int res = remote->SendRequest(IVSYNC_CONNECTION_SET_UI_DVSYNC_SWITCH, arg, ret, opt);
87 if (res != NO_ERROR) {
88 VLOGE("ipc send fail, error:%{public}d", res);
89 return VSYNC_ERROR_UNKOWN;
90 }
91 return static_cast<VsyncError>(ret.ReadInt32());
92 }
93
SetNativeDVSyncSwitch(bool dvsyncSwitch)94 VsyncError VSyncConnectionProxy::SetNativeDVSyncSwitch(bool dvsyncSwitch)
95 {
96 MessageOption opt(MessageOption::TF_ASYNC);
97 MessageParcel arg;
98 MessageParcel ret;
99
100 if (!arg.WriteInterfaceToken(GetDescriptor())) {
101 VLOGE("Failed to write interface token");
102 return VSYNC_ERROR_API_FAILED;
103 }
104 if (!arg.WriteBool(dvsyncSwitch)) {
105 VLOGE("Failed to write dvsyncSwitch:%{public}d", dvsyncSwitch);
106 return VSYNC_ERROR_API_FAILED;
107 }
108 auto remote = Remote();
109 if (remote == nullptr) {
110 VLOGE("remote is null");
111 return VSYNC_ERROR_API_FAILED;
112 }
113 int res = remote->SendRequest(IVSYNC_CONNECTION_SET_NATIVE_DVSYNC_SWITCH, arg, ret, opt);
114 if (res != NO_ERROR) {
115 VLOGE("ipc send fail, error:%{public}d", res);
116 return VSYNC_ERROR_UNKOWN;
117 }
118 return static_cast<VsyncError>(ret.ReadInt32());
119 }
120
SetUiDvsyncConfig(int32_t bufferCount,bool compositeSceneEnable,bool nativeDelayEnable,const std::vector<std::string> & rsDvsyncAnimationList)121 VsyncError VSyncConnectionProxy::SetUiDvsyncConfig(int32_t bufferCount, bool compositeSceneEnable,
122 bool nativeDelayEnable, const std::vector<std::string>& rsDvsyncAnimationList)
123 {
124 MessageOption opt(MessageOption::TF_ASYNC);
125 MessageParcel arg;
126 MessageParcel ret;
127
128 if (!arg.WriteInterfaceToken(GetDescriptor())) {
129 VLOGE("Failed to write interface token");
130 return VSYNC_ERROR_API_FAILED;
131 }
132 if (!arg.WriteInt32(bufferCount)) {
133 VLOGE("SetUiDvsyncConfig bufferCount error");
134 return VSYNC_ERROR_UNKOWN;
135 }
136 if (!arg.WriteBool(compositeSceneEnable)) {
137 VLOGE("SetUiDvsyncConfig compositeSceneEnable error");
138 return VSYNC_ERROR_UNKOWN;
139 }
140 if (!arg.WriteBool(nativeDelayEnable)) {
141 VLOGE("SetUiDvsyncConfig nativeDelayEnable error");
142 return VSYNC_ERROR_UNKOWN;
143 }
144 if (rsDvsyncAnimationList.size() > DVSYNC_ANIMATION_LIST_SIZE_MAX) {
145 VLOGE("SetUiDvsyncConfig rsDvsyncAnimationList size exceeds maximum allowed size");
146 return VSYNC_ERROR_INVALID_ARGUMENTS;
147 }
148 if (!arg.WriteStringVector(rsDvsyncAnimationList)) {
149 VLOGE("SetUiDvsyncConfig rsDvsyncAnimationList error");
150 return VSYNC_ERROR_UNKOWN;
151 }
152 auto remote = Remote();
153 if (remote == nullptr) {
154 VLOGE("remote is null");
155 return VSYNC_ERROR_API_FAILED;
156 }
157 int res = remote->SendRequest(IVSYNC_CONNECTION_SET_UI_DVSYNC_CONFIG, arg, ret, opt);
158 if (res != NO_ERROR) {
159 return VSYNC_ERROR_UNKOWN;
160 }
161 return static_cast<VsyncError>(ret.ReadInt32());
162 }
163
GetReceiveFd(int32_t & fd)164 VsyncError VSyncConnectionProxy::GetReceiveFd(int32_t &fd)
165 {
166 MessageOption opt;
167 MessageParcel arg;
168 MessageParcel ret;
169
170 if (!arg.WriteInterfaceToken(GetDescriptor())) {
171 VLOGE("Failed to write interface token");
172 return VSYNC_ERROR_API_FAILED;
173 }
174 auto remote = Remote();
175 if (remote == nullptr) {
176 VLOGE("remote is null");
177 return VSYNC_ERROR_API_FAILED;
178 }
179 int res = remote->SendRequest(IVSYNC_CONNECTION_GET_RECEIVE_FD, arg, ret, opt);
180 if (res != NO_ERROR) {
181 VLOGE("GetReceiveFd Failed, res = %{public}d", res);
182 return VSYNC_ERROR_BINDER_ERROR;
183 }
184 res = ret.ReadInt32();
185 if (res != VSYNC_ERROR_OK) {
186 return static_cast<VsyncError>(res);
187 }
188 fd = ret.ReadFileDescriptor();
189 if (fd < 0) {
190 VLOGE("GetReceiveFd Invalid fd:%{public}d", fd);
191 return VSYNC_ERROR_API_FAILED;
192 }
193 return VSYNC_ERROR_OK;
194 }
195
SetVSyncRate(int32_t rate)196 VsyncError VSyncConnectionProxy::SetVSyncRate(int32_t rate)
197 {
198 if (rate < -1) {
199 return VSYNC_ERROR_INVALID_ARGUMENTS;
200 }
201 MessageOption opt;
202 MessageParcel arg;
203 MessageParcel ret;
204
205 if (!arg.WriteInterfaceToken(GetDescriptor())) {
206 VLOGE("Failed to write interface token");
207 return VSYNC_ERROR_API_FAILED;
208 }
209 if (!arg.WriteInt32(rate)) {
210 VLOGE("Failed to write rate:%{public}d", rate);
211 return VSYNC_ERROR_API_FAILED;
212 }
213 auto remote = Remote();
214 if (remote == nullptr) {
215 VLOGE("remote is null");
216 return VSYNC_ERROR_API_FAILED;
217 }
218 int res = remote->SendRequest(IVSYNC_CONNECTION_SET_RATE, arg, ret, opt);
219 if (res != NO_ERROR) {
220 return VSYNC_ERROR_BINDER_ERROR;
221 }
222 return static_cast<VsyncError>(ret.ReadInt32());
223 }
224
Destroy()225 VsyncError VSyncConnectionProxy::Destroy()
226 {
227 MessageOption opt;
228 MessageParcel arg;
229 MessageParcel ret;
230
231 if (!arg.WriteInterfaceToken(GetDescriptor())) {
232 VLOGE("Failed to write interface token");
233 return VSYNC_ERROR_API_FAILED;
234 }
235 auto remote = Remote();
236 if (remote == nullptr) {
237 VLOGE("remote is null");
238 return VSYNC_ERROR_API_FAILED;
239 }
240 int res = remote->SendRequest(IVSYNC_CONNECTION_DESTROY, arg, ret, opt);
241 if (res != NO_ERROR) {
242 return VSYNC_ERROR_BINDER_ERROR;
243 }
244 return static_cast<VsyncError>(ret.ReadInt32());
245 }
246 } // namespace Vsync
247 } // namespace OHOS
248