• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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