1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdint.h>
18 #include <sys/types.h>
19 
20 #include <utils/Errors.h>
21 #include <utils/RefBase.h>
22 #include <utils/Timers.h>
23 
24 #include <binder/Parcel.h>
25 #include <binder/IInterface.h>
26 
27 #include "IExynosHWC.h"
28 
29 #include <vector>
30 
31 #define RET_IF_ERR(expr)      \
32     do {                      \
33         auto err = (expr);    \
34         if (err) [[unlikely]] \
35             return err;       \
36     } while (0)
37 
38 namespace android {
39 
40 enum {
41     ADD_VIRTUAL_DISPLAY_DEVICE = 0,
42     DESTROY_VIRTUAL_DISPLAY_DEVICE,
43     SET_WFD_MODE,
44     GET_WFD_MODE,
45     SEND_WFD_COMMAND,
46     SET_SECURE_VDS_MODE,
47     SET_WFD_OUTPUT_RESOLUTION,
48     GET_WFD_OUTPUT_RESOLUTION,
49     SET_PRESENTATION_MODE,
50     GET_PRESENTATION_MODE,
51     SET_VDS_GLES_FORMAT,
52     HWC_CONTROL,
53     SET_BOOT_FINISHED,
54     SET_VIRTUAL_HPD,
55     GET_EXTERNAL_DISPLAY_CONFIG,
56     SET_EXTERNAL_DISPLAY_CONFIG,
57     ENABLE_MPP,
58     SET_EXTERNAL_VSYNC,
59     SET_DDISCALER,
60     GET_EXTERNAL_HDR_CAPA,
61     SET_SCALE_DOWN_RATIO,
62     SET_HWC_DEBUG = 105,
63     GET_HWC_DEBUG = 106,
64     SET_HWC_FENCE_DEBUG = 107,
65     GET_HWC_FENCE_DEBUG = 108,
66     SET_DISPLAY_DEVICE_MODE = 1000,
67     SET_PANEL_GAMMA_TABLE_SOURCE = 1001,
68     SET_DISPLAY_BRIGHTNESS = 1002,
69     SET_DISPLAY_LHBM = 1003,
70     SET_LBE_CTRL = 1004,
71     SET_MIN_IDLE_REFRESH_RATE = 1005,
72     SET_REFRESH_RATE_THROTTLE = 1006,
73     SET_DISPLAY_RCDLAYER_ENABLED = 1007,
74     TRIGGER_DISPLAY_IDLE_ENTER = 1008,
75     SET_DISPLAY_DBM = 1009,
76     SET_DISPLAY_MULTI_THREADED_PRESENT = 1010,
77     TRIGGER_REFRESH_RATE_INDICATOR_UPDATE = 1011,
78     IGNORE_DISPLAY_BRIGHTNESS_UPDATE_REQUESTS = 1012,
79     SET_DISPLAY_BRIGHTNESS_NITS = 1013,
80     SET_DISPLAY_BRIGHTNESS_DBV = 1014,
81     DUMP_BUFFERS = 1015,
82     SET_PRESENT_TIMEOUT_PARAMETERS = 1016,
83     SET_PRESENT_TIMEOUT_CONTROLLER = 1017,
84     SET_FIXED_TE2_RATE = 1018,
85     SET_DISPLAY_TEMPERATURE = 1019,
86 };
87 
88 class BpExynosHWCService : public BpInterface<IExynosHWCService> {
89 public:
BpExynosHWCService(const sp<IBinder> & impl)90     BpExynosHWCService(const sp<IBinder>& impl)
91         : BpInterface<IExynosHWCService>(impl)
92     {
93     }
94 
addVirtualDisplayDevice()95     virtual int addVirtualDisplayDevice()
96     {
97         Parcel data, reply;
98         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
99         int result = remote()->transact(ADD_VIRTUAL_DISPLAY_DEVICE, data, &reply);
100         if (result == NO_ERROR)
101             result = reply.readInt32();
102         else
103             ALOGE("ADD_VIRTUAL_DISPLAY_DEVICE transact error(%d)", result);
104         return result;
105     }
106 
destroyVirtualDisplayDevice()107     virtual int destroyVirtualDisplayDevice()
108     {
109         Parcel data, reply;
110         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
111         int result = remote()->transact(DESTROY_VIRTUAL_DISPLAY_DEVICE, data, &reply);
112         if (result == NO_ERROR)
113             result = reply.readInt32();
114         else
115             ALOGE("DESTROY_VIRTUAL_DISPLAY_DEVICE transact error(%d)", result);
116         return result;
117     }
118 
setWFDMode(unsigned int mode)119     virtual int setWFDMode(unsigned int mode)
120     {
121         Parcel data, reply;
122         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
123         data.writeInt32(mode);
124         int result = remote()->transact(SET_WFD_MODE, data, &reply);
125         if (result == NO_ERROR)
126             result = reply.readInt32();
127         else
128             ALOGE("SET_WFD_MODE transact error(%d)", result);
129         return result;
130     }
131 
getWFDMode()132     virtual int getWFDMode()
133     {
134         Parcel data, reply;
135         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
136         int result = remote()->transact(GET_WFD_MODE, data, &reply);
137         if (result == NO_ERROR)
138             result = reply.readInt32();
139         else
140             ALOGE("GET_WFD_MODE transact error(%d)", result);
141         return result;
142     }
143 
sendWFDCommand(int32_t cmd,int32_t ext1,int32_t ext2)144     virtual int sendWFDCommand(int32_t cmd, int32_t ext1, int32_t ext2)
145     {
146         Parcel data, reply;
147         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
148         data.writeInt32(cmd);
149         data.writeInt32(ext1);
150         data.writeInt32(ext2);
151         int result = remote()->transact(SEND_WFD_COMMAND, data, &reply);
152         if (result == NO_ERROR)
153             result = reply.readInt32();
154         else
155             ALOGE("SEND_WFD_COMMAND transact error(%d)", result);
156         return result;
157     }
158 
setSecureVDSMode(unsigned int mode)159     virtual int setSecureVDSMode(unsigned int mode)
160     {
161         Parcel data, reply;
162         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
163         data.writeInt32(mode);
164         int result = remote()->transact(SET_SECURE_VDS_MODE, data, &reply);
165         if (result == NO_ERROR)
166             result = reply.readInt32();
167         else
168             ALOGE("SET_SECURE_VDS_MODE transact error(%d)", result);
169         return result;
170     }
171 
setWFDOutputResolution(unsigned int width,unsigned int height)172     virtual int setWFDOutputResolution(unsigned int width, unsigned int height)
173     {
174         Parcel data, reply;
175         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
176         data.writeInt32(width);
177         data.writeInt32(height);
178         int result = remote()->transact(SET_WFD_OUTPUT_RESOLUTION, data, &reply);
179         if (result == NO_ERROR)
180             result = reply.readInt32();
181         else
182             ALOGE("SET_WFD_OUTPUT_RESOLUTION transact error(%d)", result);
183         return result;
184     }
185 
getWFDOutputResolution(unsigned int * width,unsigned int * height)186     virtual int getWFDOutputResolution(unsigned int* width, unsigned int* height) {
187         Parcel data, reply;
188         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
189         int result = remote()->transact(GET_WFD_OUTPUT_RESOLUTION, data, &reply);
190         if (result == NO_ERROR) {
191             *width  = reply.readInt32();
192             *height = reply.readInt32();
193             result = reply.readInt32();
194         } else
195             ALOGE("GET_WFD_OUTPUT_RESOLUTION transact error(%d)", result);
196         return result;
197     }
198 
setPresentationMode(bool use)199     virtual void setPresentationMode(bool use)
200     {
201         Parcel data, reply;
202         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
203         data.writeInt32(use);
204         int result = remote()->transact(SET_PRESENTATION_MODE, data, &reply);
205         if (result != NO_ERROR)
206             ALOGE("SET_PRESENTATION_MODE transact error(%d)", result);
207     }
208 
getPresentationMode(void)209     virtual int getPresentationMode(void)
210     {
211         Parcel data, reply;
212         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
213         int result = remote()->transact(GET_PRESENTATION_MODE, data, &reply);
214         if (result == NO_ERROR)
215             result = reply.readInt32();
216         else
217             ALOGE("GET_PRESENTATION_MODE transact error(%d)", result);
218         return result;
219     }
220 
setVDSGlesFormat(int format)221     virtual int setVDSGlesFormat(int format)
222     {
223         Parcel data, reply;
224         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
225         data.writeInt32(format);
226         int result = remote()->transact(SET_VDS_GLES_FORMAT, data, &reply);
227         if (result == NO_ERROR)
228             result = reply.readInt32();
229         else
230             ALOGE("SET_VDS_GLES_FORMAT transact error(%d)", result);
231         return result;
232     }
233 
getExternalDisplayConfigs()234     virtual int getExternalDisplayConfigs()
235     {
236         Parcel data, reply;
237         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
238         int result = remote()->transact(GET_EXTERNAL_DISPLAY_CONFIG, data, &reply);
239         if (result == NO_ERROR)
240             result = reply.readInt32();
241         else
242             ALOGE("GET_EXTERNAL_DISPLAY_CONFIG transact error(%d)", result);
243         return result;
244     }
245 
setExternalDisplayConfig(unsigned int index)246     virtual int setExternalDisplayConfig(unsigned int index)
247     {
248         Parcel data, reply;
249         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
250         data.writeInt32(index);
251         int result = remote()->transact(SET_EXTERNAL_DISPLAY_CONFIG, data, &reply);
252         if (result == NO_ERROR)
253             result = reply.readInt32();
254         else
255             ALOGE("SET_EXTERNAL_DISPLAY_CONFIG transact error(%d)", result);
256         return result;
257     }
258 
setExternalVsyncEnabled(unsigned int index)259     virtual int setExternalVsyncEnabled(unsigned int index)
260     {
261         Parcel data, reply;
262         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
263         data.writeInt32(index);
264         int result = remote()->transact(SET_EXTERNAL_VSYNC, data, &reply);
265         if (result == NO_ERROR)
266             result = reply.readInt32();
267         else
268             ALOGE("SET_EXTERNAL_VSYNC transact error(%d)", result);
269         return result;
270     }
271 
getExternalHdrCapabilities()272     virtual int getExternalHdrCapabilities()
273     {
274         Parcel data, reply;
275         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
276         int result = remote()->transact(GET_EXTERNAL_HDR_CAPA, data, &reply);
277         if (result == NO_ERROR)
278             result = reply.readInt32();
279         else
280             ALOGE("GET_EXTERNAL_HDR_CAPA transact error(%d)", result);
281 
282         return result;
283     }
284 
setBootFinished()285     virtual void setBootFinished()
286     {
287         Parcel data, reply;
288         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
289         int result = remote()->transact(SET_BOOT_FINISHED, data, &reply);
290         if (result != NO_ERROR)
291             ALOGE("SET_BOOT_FINISHED transact error(%d)", result);
292     }
293 
enableMPP(uint32_t physicalType,uint32_t physicalIndex,uint32_t logicalIndex,uint32_t enable)294     virtual void enableMPP(uint32_t physicalType, uint32_t physicalIndex, uint32_t logicalIndex, uint32_t enable)
295     {
296         Parcel data, reply;
297         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
298         data.writeInt32(physicalType);
299         data.writeInt32(physicalIndex);
300         data.writeInt32(logicalIndex);
301         data.writeInt32(enable);
302         int result = remote()->transact(ENABLE_MPP, data, &reply);
303         if (result != NO_ERROR)
304             ALOGE("ENABLE_MPP transact error(%d)", result);
305     }
306 
setScaleDownRatio(uint32_t physicalType,uint32_t physicalIndex,uint32_t logicalIndex,uint32_t scaleDownRatio)307     virtual void setScaleDownRatio(uint32_t physicalType, uint32_t physicalIndex,
308             uint32_t logicalIndex, uint32_t scaleDownRatio)
309     {
310         Parcel data, reply;
311         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
312         data.writeInt32(physicalType);
313         data.writeInt32(physicalIndex);
314         data.writeInt32(logicalIndex);
315         data.writeInt32(scaleDownRatio);
316         int result = remote()->transact(SET_SCALE_DOWN_RATIO, data, &reply);
317         if (result != NO_ERROR)
318             ALOGE("SET_SCALE_DOWN_RATIO transact error(%d)", result);
319     }
320 
setLbeCtrl(uint32_t display_id,uint32_t state,uint32_t lux)321     virtual void setLbeCtrl(uint32_t display_id, uint32_t state, uint32_t lux) {
322         Parcel data, reply;
323         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
324         data.writeInt32(display_id);
325         data.writeInt32(state);
326         data.writeInt32(lux);
327         int result = remote()->transact(SET_LBE_CTRL, data, &reply);
328         if (result != NO_ERROR) ALOGE("SET_LBE_CTRL transact error(%d)", result);
329     }
330 
setHWCDebug(int debug)331     virtual void setHWCDebug(int debug)
332     {
333         Parcel data, reply;
334         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
335         data.writeInt32(debug);
336         int result = remote()->transact(SET_HWC_DEBUG, data, &reply);
337         if (result != NO_ERROR)
338             ALOGE("SET_HWC_DEBUG transact error(%d)", result);
339     }
340 
getHWCDebug()341     virtual uint32_t getHWCDebug()
342     {
343         Parcel data, reply;
344         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
345         int result = remote()->transact(GET_HWC_DEBUG, data, &reply);
346         if (result == NO_ERROR)
347             result = reply.readInt32();
348         else {
349             ALOGE("GET_HWC_DEBUG transact error(%d)", result);
350         }
351         return result;
352     }
353 
setHWCFenceDebug(uint32_t fenceNum,uint32_t ipNum,uint32_t mode)354     virtual void setHWCFenceDebug(uint32_t fenceNum, uint32_t ipNum, uint32_t mode)
355     {
356         Parcel data, reply;
357         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
358         data.writeInt32(fenceNum);
359         data.writeInt32(ipNum);
360         data.writeInt32(mode);
361         remote()->transact(SET_HWC_FENCE_DEBUG, data, &reply);
362     }
363 
getHWCFenceDebug()364     virtual void getHWCFenceDebug()
365     {
366         Parcel data, reply;
367         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
368         remote()->transact(GET_HWC_FENCE_DEBUG, data, &reply);
369     }
370 
setHWCCtl(uint32_t display,uint32_t ctrl,int32_t val)371     virtual int setHWCCtl(uint32_t display, uint32_t ctrl, int32_t val) {
372         Parcel data, reply;
373         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
374         data.writeInt32(display);
375         data.writeInt32(ctrl);
376         data.writeInt32(val);
377         int result = remote()->transact(HWC_CONTROL, data, &reply);
378         if (result == NO_ERROR)
379             result = reply.readInt32();
380         else
381             ALOGE("HWC_CONTROL transact error(%d)", result);
382         return result;
383     };
384 
setDDIScaler(uint32_t displayId,uint32_t width,uint32_t height)385     virtual int setDDIScaler(uint32_t displayId, uint32_t width, uint32_t height) {
386         Parcel data, reply;
387         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
388         data.writeUint32(displayId);
389         data.writeUint32(width);
390         data.writeUint32(height);
391         int result = remote()->transact(SET_DDISCALER, data, &reply);
392         if (result == NO_ERROR)
393             result = reply.readInt32();
394         else
395             ALOGE("SET_DDISCALER transact error(%d)", result);
396         return result;
397     }
398 
setDisplayDeviceMode(int32_t display_id,int32_t mode)399     int32_t setDisplayDeviceMode(int32_t display_id, int32_t mode)
400     {
401         ALOGD("null func: %s(%d %d)", __func__, display_id, mode);
402         return NO_ERROR;
403     }
404 
setPanelGammaTableSource(int32_t display_id,int32_t type,int32_t source)405     virtual int32_t setPanelGammaTableSource(int32_t display_id, int32_t type, int32_t source) {
406         ALOGD("null func: %s(%d %d %d)", __func__, display_id, type, source);
407         return NO_ERROR;
408     }
409 
setDisplayBrightness(int32_t display_id,float brightness)410     virtual int32_t setDisplayBrightness(int32_t display_id, float brightness) {
411         Parcel data, reply;
412         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
413         data.writeInt32(display_id);
414         data.writeFloat(brightness);
415         int result = remote()->transact(SET_DISPLAY_BRIGHTNESS, data, &reply);
416         if (result)
417             ALOGE("SET_DISPLAY_BRIGHTNESS transact error(%d)", result);
418         return result;
419     }
420 
ignoreDisplayBrightnessUpdateRequests(int32_t displayId,bool ignore)421     virtual int32_t ignoreDisplayBrightnessUpdateRequests(int32_t displayId, bool ignore) {
422         Parcel data, reply;
423         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
424         data.writeInt32(displayId);
425         data.writeBool(ignore);
426         int result = remote()->transact(IGNORE_DISPLAY_BRIGHTNESS_UPDATE_REQUESTS, data, &reply);
427         if (result) ALOGE("IGNORE_DISPLAY_BRIGHTNESS_UPDATE_REQUESTS transact error(%d)", result);
428         return result;
429     }
430 
setDisplayBrightnessNits(int32_t displayId,float nits)431     virtual int32_t setDisplayBrightnessNits(int32_t displayId, float nits) {
432         Parcel data, reply;
433         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
434         data.writeInt32(displayId);
435         data.writeFloat(nits);
436         int result = remote()->transact(SET_DISPLAY_BRIGHTNESS_NITS, data, &reply);
437         if (result) ALOGE("SET_DISPLAY_BRIGHTNESS_NITS transact error(%d)", result);
438         return result;
439     }
440 
setDisplayBrightnessDbv(int32_t displayId,uint32_t dbv)441     virtual int32_t setDisplayBrightnessDbv(int32_t displayId, uint32_t dbv) {
442         Parcel data, reply;
443         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
444         data.writeInt32(displayId);
445         data.writeUint32(dbv);
446         int result = remote()->transact(SET_DISPLAY_BRIGHTNESS_DBV, data, &reply);
447         if (result) {
448             ALOGE("SET_DISPLAY_BRIGHTNESS_DBV transact error(%d)", result);
449         }
450         return result;
451     }
452 
setDisplayLhbm(int32_t display_id,uint32_t on)453     virtual int32_t setDisplayLhbm(int32_t display_id, uint32_t on) {
454         Parcel data, reply;
455         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
456         data.writeInt32(display_id);
457         data.writeInt32(on);
458         int result = remote()->transact(SET_DISPLAY_LHBM, data, &reply);
459         if (result) ALOGE("SET_DISPLAY_LHBM transact error(%d)", result);
460         return result;
461     }
462 
setMinIdleRefreshRate(uint32_t display_id,int32_t fps)463     virtual int32_t setMinIdleRefreshRate(uint32_t display_id, int32_t fps) {
464         Parcel data, reply;
465         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
466         data.writeUint32(display_id);
467         data.writeInt32(fps);
468         int result = remote()->transact(SET_MIN_IDLE_REFRESH_RATE, data, &reply);
469         if (result) ALOGE("SET_MIN_IDLE_REFRESH_RATE transact error(%d)", result);
470         return result;
471     }
472 
setRefreshRateThrottle(uint32_t display_id,int32_t delay_ms)473     virtual int32_t setRefreshRateThrottle(uint32_t display_id, int32_t delay_ms) {
474         Parcel data, reply;
475         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
476         data.writeUint32(display_id);
477         data.writeInt32(delay_ms);
478         int result = remote()->transact(SET_REFRESH_RATE_THROTTLE, data, &reply);
479         if (result) ALOGE("SET_REFRESH_RATE_THROTTLE transact error(%d)", result);
480         return result;
481     }
482 
setDisplayRCDLayerEnabled(uint32_t displayIndex,bool enable)483     int32_t setDisplayRCDLayerEnabled(uint32_t displayIndex, bool enable) override {
484         Parcel data, reply;
485         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
486         data.writeUint32(displayIndex);
487         data.writeInt32(enable);
488 
489         auto result = remote()->transact(SET_DISPLAY_RCDLAYER_ENABLED, data, &reply);
490         ALOGE_IF(result != NO_ERROR, "SET_DISPLAY_RCDLAYER_ENABLED transact error(%d)", result);
491         return result;
492     }
493 
triggerDisplayIdleEnter(uint32_t displayIndex,uint32_t idleTeRefreshRate)494     int32_t triggerDisplayIdleEnter(uint32_t displayIndex, uint32_t idleTeRefreshRate) override {
495         Parcel data, reply;
496         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
497         data.writeUint32(displayIndex);
498         data.writeUint32(idleTeRefreshRate);
499 
500         auto result = remote()->transact(TRIGGER_DISPLAY_IDLE_ENTER, data, &reply);
501         ALOGE_IF(result != NO_ERROR, "TRIGGER_DISPLAY_IDLE_ENTER transact error(%d)", result);
502         return result;
503     }
504 
setDisplayDbm(int32_t display_id,uint32_t on)505     virtual int32_t setDisplayDbm(int32_t display_id, uint32_t on) {
506         Parcel data, reply;
507         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
508         data.writeInt32(display_id);
509         data.writeInt32(on);
510         int result = remote()->transact(SET_DISPLAY_DBM, data, &reply);
511         if (result) ALOGE("SET_DISPLAY_DBM transact error(%d)", result);
512         return result;
513     }
514 
setDisplayMultiThreadedPresent(const int32_t & displayId,const bool & enable)515     virtual int32_t setDisplayMultiThreadedPresent(const int32_t& displayId,
516                                                    const bool& enable) {
517         Parcel data, reply;
518         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
519         data.writeInt32(displayId);
520         data.writeBool(enable);
521         int result = remote()->transact(SET_DISPLAY_MULTI_THREADED_PRESENT, data, &reply);
522         if (result) ALOGE("SET_DISPLAY_MULTI_THREADED_PRESENT transact error(%d)", result);
523         return result;
524     }
525 
triggerRefreshRateIndicatorUpdate(uint32_t displayId,uint32_t refreshRate)526     virtual int32_t triggerRefreshRateIndicatorUpdate(uint32_t displayId,
527                                                       uint32_t refreshRate) override {
528         Parcel data, reply;
529         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
530         data.writeUint32(displayId);
531         data.writeUint32(refreshRate);
532 
533         auto result = remote()->transact(TRIGGER_REFRESH_RATE_INDICATOR_UPDATE, data, &reply);
534         ALOGE_IF(result != NO_ERROR, "TRIGGER_REFRESH_RATE_INDICATOR_UPDATE transact error(%d)",
535                  result);
536         return result;
537     }
538 
dumpBuffers(uint32_t displayId,int32_t count)539     virtual int32_t dumpBuffers(uint32_t displayId, int32_t count) override {
540         Parcel data, reply;
541         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
542         data.writeUint32(displayId);
543         data.writeInt32(count);
544 
545         auto result = remote()->transact(DUMP_BUFFERS, data, &reply);
546         ALOGE_IF(result != NO_ERROR, "DUMP_BUFFERS transact error(%d)", result);
547         return result;
548     }
549 
setPresentTimeoutController(uint32_t displayId,uint32_t controllerType)550     int32_t setPresentTimeoutController(uint32_t displayId, uint32_t controllerType) override {
551         Parcel data, reply;
552         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
553         data.writeInt32(displayId);
554         data.writeUint32(controllerType);
555         int result = remote()->transact(SET_PRESENT_TIMEOUT_CONTROLLER, data, &reply);
556         ALOGE_IF(result != NO_ERROR, "SET_PRESENT_TIMEOUT_CONTROLLER transact error(%d)", result);
557         return result;
558     }
559 
setPresentTimeoutParameters(uint32_t displayId,int timeoutNs,const std::vector<std::pair<uint32_t,uint32_t>> & settings)560     int32_t setPresentTimeoutParameters(
561             uint32_t displayId, int timeoutNs,
562             const std::vector<std::pair<uint32_t, uint32_t>>& settings) override {
563         Parcel data, reply;
564         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
565         data.writeInt32(displayId);
566         // The format is timeout, [ i32 <frames> i32 <intervalNs> ]+.
567         // E.g. if [2, 8333333], [1, 16666667] ..., the pattern is:
568         // last present <timeout> 1st task <8.3 ms> 2nd task <8.3 ms> 3rd task <16.67ms> ...
569         data.writeInt32(timeoutNs);
570         for (const auto& it : settings) {
571             data.writeUint32(it.first);  // frames
572             data.writeUint32(it.second); // intervalNs
573         }
574         int result = remote()->transact(SET_PRESENT_TIMEOUT_PARAMETERS, data, &reply);
575         ALOGE_IF(result != NO_ERROR, "SET_PRESENT_TIMEOUT_PARAMETERS transact error(%d)", result);
576         return result;
577     }
578 
setFixedTe2Rate(uint32_t displayId,int32_t rateHz)579     virtual int32_t setFixedTe2Rate(uint32_t displayId, int32_t rateHz) {
580         Parcel data, reply;
581         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
582         data.writeUint32(displayId);
583         data.writeInt32(rateHz);
584         int result = remote()->transact(SET_FIXED_TE2_RATE, data, &reply);
585         if (result) ALOGE("SET_FIXED_TE2_RATE transact error(%d)", result);
586         return result;
587     }
setDisplayTemperature(uint32_t displayId,int32_t temperature)588     virtual int32_t setDisplayTemperature(uint32_t displayId, int32_t temperature) {
589         Parcel data, reply;
590         data.writeInterfaceToken(IExynosHWCService::getInterfaceDescriptor());
591         data.writeUint32(displayId);
592         data.writeInt32(temperature);
593         int result = remote()->transact(SET_DISPLAY_TEMPERATURE, data, &reply);
594         if (result) ALOGE("SET_DISPLAY_TEMPERATURE transact error(%d)", result);
595         return result;
596     }
597 };
598 
599 IMPLEMENT_META_INTERFACE(ExynosHWCService, "android.hal.ExynosHWCService");
600 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)601 status_t BnExynosHWCService::onTransact(
602     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
603 {
604     switch(code) {
605         case ADD_VIRTUAL_DISPLAY_DEVICE: {
606             CHECK_INTERFACE(IExynosHWCService, data, reply);
607             int res = addVirtualDisplayDevice();
608             reply->writeInt32(res);
609             return NO_ERROR;
610         } break;
611         case DESTROY_VIRTUAL_DISPLAY_DEVICE: {
612             CHECK_INTERFACE(IExynosHWCService, data, reply);
613             int res = destroyVirtualDisplayDevice();
614             reply->writeInt32(res);
615             return NO_ERROR;
616         } break;
617         case SET_WFD_MODE: {
618             CHECK_INTERFACE(IExynosHWCService, data, reply);
619             int mode = data.readInt32();
620             int res = setWFDMode(mode);
621             reply->writeInt32(res);
622             return NO_ERROR;
623         } break;
624         case GET_WFD_MODE: {
625             CHECK_INTERFACE(IExynosHWCService, data, reply);
626             int res = getWFDMode();
627             reply->writeInt32(res);
628             return NO_ERROR;
629         } break;
630         case SEND_WFD_COMMAND: {
631             CHECK_INTERFACE(IExynosHWCService, data, reply);
632             int cmd = data.readInt32();
633             int ext1 = data.readInt32();
634             int ext2 = data.readInt32();
635             int res = sendWFDCommand(cmd, ext1, ext2);
636             reply->writeInt32(res);
637             return NO_ERROR;
638         } break;
639         case SET_SECURE_VDS_MODE: {
640             CHECK_INTERFACE(IExynosHWCService, data, reply);
641             int mode = data.readInt32();
642             int res = setSecureVDSMode(mode);
643             reply->writeInt32(res);
644             return NO_ERROR;
645         } break;
646         case SET_WFD_OUTPUT_RESOLUTION: {
647             CHECK_INTERFACE(IExynosHWCService, data, reply);
648             int width  = data.readInt32();
649             int height = data.readInt32();
650             int res = setWFDOutputResolution(width, height);
651             reply->writeInt32(res);
652             return NO_ERROR;
653         } break;
654         case GET_WFD_OUTPUT_RESOLUTION: {
655             CHECK_INTERFACE(IExynosHWCService, data, reply);
656             uint32_t width = 0, height = 0;
657             int res = getWFDOutputResolution(&width, &height);
658             reply->writeInt32(width);
659             reply->writeInt32(height);
660             reply->writeInt32(res);
661             return NO_ERROR;
662         } break;
663         case SET_PRESENTATION_MODE: {
664             CHECK_INTERFACE(IExynosHWCService, data, reply);
665             int use = data.readInt32();
666             setPresentationMode(use);
667             return NO_ERROR;
668         } break;
669         case GET_PRESENTATION_MODE: {
670             CHECK_INTERFACE(IExynosHWCService, data, reply);
671             int res = getPresentationMode();
672             reply->writeInt32(res);
673             return NO_ERROR;
674         } break;
675         case SET_VDS_GLES_FORMAT: {
676             CHECK_INTERFACE(IExynosHWCService, data, reply);
677             int format  = data.readInt32();
678             int res = setVDSGlesFormat(format);
679             reply->writeInt32(res);
680             return NO_ERROR;
681         } break;
682        case HWC_CONTROL: {
683             CHECK_INTERFACE(IExynosHWCService, data, reply);
684             int display = data.readInt32();
685             int ctrl = data.readInt32();
686             int value = data.readInt32();
687             int res = setHWCCtl(display, ctrl, value);
688             reply->writeInt32(res);
689             return NO_ERROR;
690         } break;
691         case GET_EXTERNAL_DISPLAY_CONFIG: {
692             CHECK_INTERFACE(IExynosHWCService, data, reply);
693             int res = getExternalDisplayConfigs();
694             reply->writeInt32(res);
695             return NO_ERROR;
696         } break;
697         case SET_EXTERNAL_DISPLAY_CONFIG: {
698             CHECK_INTERFACE(IExynosHWCService, data, reply);
699             int index = data.readInt32();
700             int res = setExternalDisplayConfig(index);
701             reply->writeInt32(res);
702             return NO_ERROR;
703         } break;
704         case SET_EXTERNAL_VSYNC: {
705             CHECK_INTERFACE(IExynosHWCService, data, reply);
706             int index = data.readInt32();
707             int res = setExternalVsyncEnabled(index);
708             reply->writeInt32(res);
709             return NO_ERROR;
710         } break;
711         case GET_EXTERNAL_HDR_CAPA: {
712             CHECK_INTERFACE(IExynosHWCService, data, reply);
713             int res = getExternalHdrCapabilities();
714             reply->writeInt32(res);
715             return NO_ERROR;
716         } break;
717         case SET_BOOT_FINISHED: {
718             CHECK_INTERFACE(IExynosHWCService, data, reply);
719             setBootFinished();
720             return NO_ERROR;
721         } break;
722         case ENABLE_MPP: {
723             CHECK_INTERFACE(IExynosHWCService, data, reply);
724             uint32_t type = data.readInt32();
725             uint32_t physicalIdx = data.readInt32();
726             uint32_t logicalIdx = data.readInt32();
727             uint32_t enable = data.readInt32();
728             enableMPP(type, physicalIdx, logicalIdx, enable);
729             return NO_ERROR;
730         } break;
731         case SET_SCALE_DOWN_RATIO: {
732             CHECK_INTERFACE(IExynosHWCService, data, reply);
733             uint32_t type = data.readInt32();
734             uint32_t physicalIdx = data.readInt32();
735             uint32_t logicalIdx = data.readInt32();
736             uint32_t scaleDownRatio = data.readInt32();
737             setScaleDownRatio(type, physicalIdx, logicalIdx, scaleDownRatio);
738             return NO_ERROR;
739         } break;
740         case SET_HWC_DEBUG: {
741             CHECK_INTERFACE(IExynosHWCService, data, reply);
742             int debug = data.readInt32();
743             setHWCDebug(debug);
744             reply->writeInt32(debug);
745             return NO_ERROR;
746         } break;
747         case GET_HWC_DEBUG: {
748             CHECK_INTERFACE(IExynosHWCService, data, reply);
749             int debugFlag = getHWCDebug();
750             reply->writeInt32(debugFlag);
751             return NO_ERROR;
752         } break;
753         case SET_HWC_FENCE_DEBUG: {
754             CHECK_INTERFACE(IExynosHWCService, data, reply);
755             uint32_t fenceNum = data.readInt32();
756             uint32_t ipNum = data.readInt32();
757             uint32_t mode = data.readInt32();
758             setHWCFenceDebug(fenceNum, ipNum, mode);
759             return NO_ERROR;
760         } break;
761         case SET_DDISCALER: {
762             CHECK_INTERFACE(IExynosHWCService, data, reply);
763             uint32_t display_id = data.readUint32();
764             uint32_t width = data.readUint32();
765             uint32_t height = data.readUint32();
766             int error = setDDIScaler(display_id, width, height);
767             reply->writeInt32(error);
768             return NO_ERROR;
769         } break;
770         case SET_DISPLAY_DEVICE_MODE: {
771             CHECK_INTERFACE(IExynosHWCService, data, reply);
772             int32_t display_id = data.readInt32();
773             int32_t mode = data.readInt32();
774             int32_t error = setDisplayDeviceMode(display_id, mode);
775             reply->writeInt32(error);
776             return NO_ERROR;
777         } break;
778         case SET_PANEL_GAMMA_TABLE_SOURCE: {
779             CHECK_INTERFACE(IExynosHWCService, data, reply);
780             int32_t display_id = data.readInt32();
781             int32_t type = data.readInt32();
782             int32_t source = data.readInt32();
783             int32_t error = setPanelGammaTableSource(display_id, type, source);
784             reply->writeInt32(error);
785             return NO_ERROR;
786         } break;
787 
788         case SET_DISPLAY_BRIGHTNESS: {
789             CHECK_INTERFACE(IExynosHWCService, data, reply);
790             int32_t display_id = data.readInt32();
791             float brightness = data.readFloat();
792             int32_t error = setDisplayBrightness(display_id, brightness);
793             reply->writeInt32(error);
794             return NO_ERROR;
795         } break;
796 
797         case SET_DISPLAY_LHBM: {
798             CHECK_INTERFACE(IExynosHWCService, data, reply);
799             int32_t display_id = data.readInt32();
800             uint32_t on = data.readInt32();
801             int32_t error = setDisplayLhbm(display_id, on);
802             reply->writeInt32(error);
803             return NO_ERROR;
804         } break;
805 
806         case SET_LBE_CTRL: {
807             CHECK_INTERFACE(IExynosHWCService, data, reply);
808             uint32_t display_id = data.readInt32();
809             uint32_t state = data.readInt32();
810             uint32_t lux = data.readInt32();
811             setLbeCtrl(display_id, state, lux);
812             return NO_ERROR;
813         } break;
814 
815         case SET_MIN_IDLE_REFRESH_RATE: {
816             CHECK_INTERFACE(IExynosHWCService, data, reply);
817             uint32_t display_id = data.readUint32();
818             int32_t fps = data.readInt32();
819             return setMinIdleRefreshRate(display_id, fps);
820         } break;
821 
822         case SET_REFRESH_RATE_THROTTLE: {
823             CHECK_INTERFACE(IExynosHWCService, data, reply);
824             uint32_t display_id = data.readUint32();
825             int32_t delay_ms = data.readInt32();
826             return setRefreshRateThrottle(display_id, delay_ms);
827         } break;
828 
829         case SET_DISPLAY_RCDLAYER_ENABLED: {
830             CHECK_INTERFACE(IExynosHWCService, data, reply);
831             uint32_t displayIndex = data.readUint32();
832             bool enable = data.readInt32();
833             return setDisplayRCDLayerEnabled(displayIndex, enable);
834         } break;
835 
836         case TRIGGER_DISPLAY_IDLE_ENTER: {
837             CHECK_INTERFACE(IExynosHWCService, data, reply);
838             uint32_t displayIndex = data.readUint32();
839             uint32_t idleTeRefreshRate = data.readUint32();
840             return triggerDisplayIdleEnter(displayIndex, idleTeRefreshRate);
841         } break;
842 
843         case SET_DISPLAY_DBM: {
844             CHECK_INTERFACE(IExynosHWCService, data, reply);
845             int32_t display_id = data.readInt32();
846             uint32_t on = data.readInt32();
847             int32_t error = setDisplayDbm(display_id, on);
848             reply->writeInt32(error);
849             return NO_ERROR;
850         } break;
851 
852         case SET_DISPLAY_MULTI_THREADED_PRESENT: {
853             CHECK_INTERFACE(IExynosHWCService, data, reply);
854             int32_t displayId = data.readInt32();
855             bool enable = data.readBool();
856             int32_t error = setDisplayMultiThreadedPresent(displayId, enable);
857             reply->writeInt32(error);
858             return NO_ERROR;
859         } break;
860 
861         case TRIGGER_REFRESH_RATE_INDICATOR_UPDATE: {
862             CHECK_INTERFACE(IExynosHWCService, data, reply);
863             uint32_t displayId = data.readUint32();
864             uint32_t refreshRate = data.readUint32();
865             return triggerRefreshRateIndicatorUpdate(displayId, refreshRate);
866         } break;
867 
868         case IGNORE_DISPLAY_BRIGHTNESS_UPDATE_REQUESTS: {
869             CHECK_INTERFACE(IExynosHWCService, data, reply);
870             int32_t displayId = data.readInt32();
871             bool ignore = data.readBool();
872             int32_t error = ignoreDisplayBrightnessUpdateRequests(displayId, ignore);
873             reply->writeInt32(error);
874             return NO_ERROR;
875         } break;
876 
877         case SET_DISPLAY_BRIGHTNESS_NITS: {
878             CHECK_INTERFACE(IExynosHWCService, data, reply);
879             int32_t displayId = data.readInt32();
880             float nits = data.readFloat();
881             int32_t error = setDisplayBrightnessNits(displayId, nits);
882             reply->writeInt32(error);
883             return NO_ERROR;
884         } break;
885 
886         case SET_DISPLAY_BRIGHTNESS_DBV: {
887             CHECK_INTERFACE(IExynosHWCService, data, reply);
888             int32_t displayId = data.readInt32();
889             uint32_t dbv = data.readUint32();
890             int32_t error = setDisplayBrightnessDbv(displayId, dbv);
891             reply->writeInt32(error);
892             return NO_ERROR;
893         } break;
894 
895         case DUMP_BUFFERS: {
896             CHECK_INTERFACE(IExynosHWCService, data, reply);
897             uint32_t displayId = data.readUint32();
898             int32_t count = data.readInt32();
899             return dumpBuffers(displayId, count);
900         } break;
901 
902         case SET_PRESENT_TIMEOUT_CONTROLLER: {
903             CHECK_INTERFACE(IExynosHWCService, data, reply);
904             int32_t displayId = data.readInt32();
905             uint32_t controllerType = data.readUint32();
906             int32_t error = setPresentTimeoutController(displayId, controllerType);
907             reply->writeInt32(error);
908             return NO_ERROR;
909         } break;
910 
911         case SET_PRESENT_TIMEOUT_PARAMETERS: {
912             CHECK_INTERFACE(IExynosHWCService, data, reply);
913             int32_t displayId;
914             uint32_t timeoutNs;
915             RET_IF_ERR(data.readInt32(&displayId));
916             RET_IF_ERR(data.readUint32(&timeoutNs));
917             std::vector<std::pair<uint32_t, uint32_t>> settings;
918             while (true) {
919                 uint32_t numOfWorks, intervalNs;
920                 if (data.readUint32(&numOfWorks)) {
921                     break;
922                 }
923                 RET_IF_ERR(data.readUint32(&intervalNs));
924                 settings.emplace_back(std::make_pair(numOfWorks, intervalNs));
925             }
926             int32_t error = setPresentTimeoutParameters(displayId, timeoutNs, settings);
927             reply->writeInt32(error);
928             return NO_ERROR;
929         } break;
930 
931         case SET_FIXED_TE2_RATE: {
932             CHECK_INTERFACE(IExynosHWCService, data, reply);
933             uint32_t displayId = data.readUint32();
934             int32_t rateHz = data.readInt32();
935             return setFixedTe2Rate(displayId, rateHz);
936         } break;
937 
938         case SET_DISPLAY_TEMPERATURE: {
939             CHECK_INTERFACE(IExynosHWCService, data, reply);
940             uint32_t displayId = data.readUint32();
941             int32_t temperature = data.readInt32();
942             return setDisplayTemperature(displayId, temperature);
943         } break;
944 
945         default:
946             return BBinder::onTransact(code, data, reply, flags);
947     }
948 }
949 } // namespace android
950