• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2  * Copyright (c) 2013-2014, 2016, 2018-2021, The Linux Foundation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *    * Redistributions of source code must retain the above copyright
8  *      notice, this list of conditions and the following disclaimer.
9  *    * Redistributions in binary form must reproduce the above
10  *      copyright notice, this list of conditions and the following
11  *      disclaimer in the documentation and/or other materials provided
12  *      with the distribution.
13  *    * Neither the name of The Linux Foundation. nor the names of its
14  *      contributors may be used to endorse or promote products derived
15  *      from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29  
30  /*
31   * Changes from Qualcomm Innovation Center are provided under the following license:
32   *
33   * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
34   *
35   * Redistribution and use in source and binary forms, with or without
36   * modification, are permitted (subject to the limitations in the
37   * disclaimer below) provided that the following conditions are met:
38   *
39   *    * Redistributions of source code must retain the above copyright
40   *      notice, this list of conditions and the following disclaimer.
41   *
42   *    * Redistributions in binary form must reproduce the above
43   *      copyright notice, this list of conditions and the following
44   *      disclaimer in the documentation and/or other materials provided
45   *      with the distribution.
46   *
47   *    * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its
48   *      contributors may be used to endorse or promote products derived
49   *      from this software without specific prior written permission.
50   *
51   * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
52   * GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
53   * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
54   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
55   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
56   * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
57   * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
59   * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
61   * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
62   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
63   * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64   */
65  
66  #include <fcntl.h>
67  #include <stdio.h>
68  #include <sys/types.h>
69  #include <sys/stat.h>
70  #include <unistd.h>
71  #include <display_config.h>
72  #include <QServiceUtils.h>
73  #include <qd_utils.h>
74  
75  using namespace android;
76  using namespace qService;
77  
78  namespace qdutils {
79  
80  //=============================================================================
81  // The functions below run in the client process and wherever necessary
82  // do a binder call to HWC to get/set data.
83  
isExternalConnected(void)84  int isExternalConnected(void) {
85      return FAILED_TRANSACTION;
86  }
87  
getDisplayAttributes(int,DisplayAttributes_t &)88  int getDisplayAttributes(int /* dpy */, DisplayAttributes_t& /* dpyattr */) {
89      return FAILED_TRANSACTION;
90  }
91  
getDisplayVisibleRegion(int dpy,hwc_rect_t & rect)92  int getDisplayVisibleRegion(int dpy, hwc_rect_t &rect) {
93      status_t err = (status_t) FAILED_TRANSACTION;
94      sp<IQService> binder = getBinder();
95      Parcel inParcel, outParcel;
96      inParcel.writeInt32(dpy);
97      if(binder != NULL) {
98          err = binder->dispatch(IQService::GET_DISPLAY_VISIBLE_REGION,
99                  &inParcel, &outParcel);
100      }
101      if(!err) {
102          rect.left = outParcel.readInt32();
103          rect.top = outParcel.readInt32();
104          rect.right = outParcel.readInt32();
105          rect.bottom = outParcel.readInt32();
106      } else {
107          ALOGE("%s: Failed to getVisibleRegion for dpy =%d: err = %d",
108                __FUNCTION__, dpy, err);
109      }
110      return err;
111  }
112  
setViewFrame(int,int,int,int,int)113  int setViewFrame(int /* dpy */, int /* l */, int /* t */, int /* r */, int /* b */) {
114      return FAILED_TRANSACTION;
115  }
116  
setSecondaryDisplayStatus(int dpy,uint32_t status)117  int setSecondaryDisplayStatus(int dpy, uint32_t status) {
118      status_t err = (status_t) FAILED_TRANSACTION;
119      sp<IQService> binder = getBinder();
120      Parcel inParcel, outParcel;
121      inParcel.writeInt32(dpy);
122      inParcel.writeInt32(status);
123  
124      if(binder != NULL) {
125          err = binder->dispatch(IQService::SET_SECONDARY_DISPLAY_STATUS,
126                  &inParcel, &outParcel);
127      }
128      if(err)
129          ALOGE("%s: Failed for dpy %d status = %d err=%d", __FUNCTION__, dpy,
130                                                          status, err);
131  
132      return err;
133  }
134  
configureDynRefreshRate(uint32_t op,uint32_t refreshRate)135  int configureDynRefreshRate(uint32_t op, uint32_t refreshRate) {
136      status_t err = (status_t) FAILED_TRANSACTION;
137      sp<IQService> binder = getBinder();
138      Parcel inParcel, outParcel;
139      inParcel.writeInt32(op);
140      inParcel.writeInt32(refreshRate);
141  
142      if(binder != NULL) {
143          err = binder->dispatch(IQService::CONFIGURE_DYN_REFRESH_RATE,
144                                 &inParcel, &outParcel);
145      }
146  
147      if(err)
148          ALOGE("%s: Failed setting op %d err=%d", __FUNCTION__, op, err);
149  
150      return err;
151  }
152  
getConfigCount(int)153  int getConfigCount(int /*dpy*/) {
154      int numConfigs = -1;
155      sp<IQService> binder = getBinder();
156      if(binder != NULL) {
157          Parcel inParcel, outParcel;
158          inParcel.writeInt32(DISPLAY_PRIMARY);
159          status_t err = binder->dispatch(IQService::GET_CONFIG_COUNT,
160                  &inParcel, &outParcel);
161          if(!err) {
162              numConfigs = outParcel.readInt32();
163              ALOGI("%s() Received num configs %d", __FUNCTION__, numConfigs);
164          } else {
165              ALOGE("%s() failed with err %d", __FUNCTION__, err);
166          }
167      }
168      return numConfigs;
169  }
170  
getActiveConfig(int dpy)171  int getActiveConfig(int dpy) {
172      int configIndex = -1;
173      sp<IQService> binder = getBinder();
174      if(binder != NULL) {
175          Parcel inParcel, outParcel;
176          inParcel.writeInt32(dpy);
177          status_t err = binder->dispatch(IQService::GET_ACTIVE_CONFIG,
178                  &inParcel, &outParcel);
179          if(!err) {
180              configIndex = outParcel.readInt32();
181              ALOGI("%s() Received active config index %d", __FUNCTION__,
182                      configIndex);
183          } else {
184              ALOGE("%s() failed with err %d", __FUNCTION__, err);
185          }
186      }
187      return configIndex;
188  }
189  
setActiveConfig(int configIndex,int)190  int setActiveConfig(int configIndex, int /*dpy*/) {
191      status_t err = (status_t) FAILED_TRANSACTION;
192      sp<IQService> binder = getBinder();
193      if(binder != NULL) {
194          Parcel inParcel, outParcel;
195          inParcel.writeInt32(configIndex);
196          inParcel.writeInt32(DISPLAY_PRIMARY);
197          err = binder->dispatch(IQService::SET_ACTIVE_CONFIG,
198                  &inParcel, &outParcel);
199          if(!err) {
200              ALOGI("%s() Successfully set active config index %d", __FUNCTION__,
201                      configIndex);
202          } else {
203              ALOGE("%s() failed with err %d", __FUNCTION__, err);
204          }
205      }
206      return err;
207  }
208  
getDisplayAttributes(int configIndex,int dpy)209  DisplayAttributes getDisplayAttributes(int configIndex, int dpy) {
210      DisplayAttributes dpyattr = {};
211      sp<IQService> binder = getBinder();
212      if(binder != NULL) {
213          Parcel inParcel, outParcel;
214          inParcel.writeInt32(configIndex);
215          inParcel.writeInt32(dpy);
216          status_t err = binder->dispatch(
217                  IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG, &inParcel,
218                  &outParcel);
219          if(!err) {
220              dpyattr.vsync_period = outParcel.readInt32();
221              dpyattr.xres = outParcel.readInt32();
222              dpyattr.yres = outParcel.readInt32();
223              dpyattr.xdpi = outParcel.readFloat();
224              dpyattr.ydpi = outParcel.readFloat();
225              dpyattr.panel_type = outParcel.readInt32();
226              dpyattr.is_yuv = outParcel.readInt32();
227              ALOGI("%s() Received attrs for index %d: xres %d, yres %d",
228                      __FUNCTION__, configIndex, dpyattr.xres, dpyattr.yres);
229          } else {
230              ALOGE("%s() failed with err %d", __FUNCTION__, err);
231          }
232      }
233      return dpyattr;
234  }
235  
setPanelMode(int mode)236  int setPanelMode(int mode) {
237      status_t err = (status_t) FAILED_TRANSACTION;
238      sp<IQService> binder = getBinder();
239      if(binder != NULL) {
240          Parcel inParcel, outParcel;
241          inParcel.writeInt32(mode);
242          err = binder->dispatch(IQService::SET_DISPLAY_MODE,
243                                 &inParcel, &outParcel);
244          if(!err) {
245              ALOGI("%s() Successfully set the display mode to %d", __FUNCTION__,
246                    mode);
247          } else {
248              ALOGE("%s() failed with err %d", __FUNCTION__, err);
249          }
250      }
251      return err;
252  }
253  
setPanelBrightness(int level)254  int setPanelBrightness(int level) {
255      status_t err = (status_t) FAILED_TRANSACTION;
256      sp<IQService> binder = getBinder();
257      Parcel inParcel, outParcel;
258  
259      if(binder != NULL) {
260          inParcel.writeInt32(level);
261          status_t err = binder->dispatch(IQService::SET_PANEL_BRIGHTNESS,
262                  &inParcel, &outParcel);
263          if(err) {
264              ALOGE("%s() failed with err %d", __FUNCTION__, err);
265          }
266      }
267      return err;
268  }
269  
getPanelBrightness()270  int getPanelBrightness() {
271      int panel_brightness = -1;
272      sp<IQService> binder = getBinder();
273      Parcel inParcel, outParcel;
274  
275      if(binder != NULL) {
276          status_t err = binder->dispatch(IQService::GET_PANEL_BRIGHTNESS,
277                  &inParcel, &outParcel);
278          if(!err) {
279              panel_brightness = outParcel.readInt32();
280              ALOGI("%s() Current panel brightness value %d", __FUNCTION__,
281                      panel_brightness);
282          } else {
283              ALOGE("%s() failed with err %d", __FUNCTION__, err);
284          }
285      }
286      return panel_brightness;
287  }
288  
setDsiClk(int dpy,uint64_t bitClk)289  int setDsiClk(int dpy, uint64_t bitClk) {
290      status_t err = (status_t) FAILED_TRANSACTION;
291      sp<IQService> binder = getBinder();
292      Parcel inParcel, outParcel;
293  
294      if(binder != NULL) {
295          inParcel.writeInt32(dpy);
296          inParcel.writeUint64(bitClk);
297          status_t err = binder->dispatch(IQService::SET_DSI_CLK, &inParcel, &outParcel);
298          if(err) {
299              ALOGE("%s() failed with err %d", __FUNCTION__, err);
300          }
301      }
302      return err;
303  }
304  
getDsiClk(int dpy)305  uint64_t getDsiClk(int dpy) {
306      uint64_t dsi_clk = 0;
307      sp<IQService> binder = getBinder();
308      Parcel inParcel, outParcel;
309  
310      if(binder != NULL) {
311          inParcel.writeInt32(dpy);
312          status_t err = binder->dispatch(IQService::GET_DSI_CLK, &inParcel, &outParcel);
313          if(!err) {
314              dsi_clk = outParcel.readUint64();
315          } else {
316              ALOGE("%s() failed with err %d", __FUNCTION__, err);
317          }
318      }
319      return dsi_clk;
320  }
321  
getSupportedBitClk(int dpy,std::vector<uint64_t> & bit_rates)322  int getSupportedBitClk(int dpy, std::vector<uint64_t>& bit_rates) {
323      sp<IQService> binder = getBinder();
324      Parcel inParcel, outParcel;
325  
326      if(binder != NULL) {
327          inParcel.writeInt32(dpy);
328          status_t err = binder->dispatch(IQService::GET_SUPPORTED_DSI_CLK, &inParcel, &outParcel);
329          if(err) {
330              ALOGE("%s() failed with err %d", __FUNCTION__, err);
331              return err;
332          }
333      }
334  
335      int32_t clk_levels = outParcel.readInt32();
336      while (clk_levels > 0) {
337        bit_rates.push_back(outParcel.readUint64());
338        clk_levels--;
339      }
340      return 0;
341  }
342  
setPanelLuminanceAttributes(int dpy,float min_lum,float max_lum)343  int setPanelLuminanceAttributes(int dpy, float min_lum, float max_lum) {
344      status_t err = (status_t) FAILED_TRANSACTION;
345      sp<IQService> binder = getBinder();
346      Parcel inParcel, outParcel;
347  
348      if(binder != NULL) {
349          inParcel.writeInt32(dpy);
350          inParcel.writeFloat(min_lum);
351          inParcel.writeFloat(max_lum);
352          status_t err = binder->dispatch(IQService::SET_PANEL_LUMINANCE, &inParcel, &outParcel);
353          if(err) {
354              ALOGE("%s() failed with err %d", __FUNCTION__, err);
355          }
356      }
357      return err;
358  }
359  
360  }// namespace
361  
362  // ----------------------------------------------------------------------------
363  // Functions for linking dynamically to libqdutils
364  // ----------------------------------------------------------------------------
minHdcpEncryptionLevelChanged(int dpy,int min_enc_level)365  extern "C" int minHdcpEncryptionLevelChanged(int dpy, int min_enc_level) {
366      status_t err = (status_t) FAILED_TRANSACTION;
367      sp<IQService> binder = getBinder();
368      Parcel inParcel, outParcel;
369      inParcel.writeInt32(dpy);
370      inParcel.writeInt32(min_enc_level);
371  
372      if(binder != NULL) {
373          err = binder->dispatch(IQService::MIN_HDCP_ENCRYPTION_LEVEL_CHANGED,
374                  &inParcel, &outParcel);
375      }
376  
377      if(err) {
378          ALOGE("%s: Failed for dpy %d err=%d", __FUNCTION__, dpy, err);
379      } else {
380          err = outParcel.readInt32();
381      }
382  
383      return err;
384  }
385  
refreshScreen(int dpy)386  extern "C" int refreshScreen(int dpy) {
387      int ret = 0;
388      ret = screenRefresh(dpy);
389      return ret;
390  }
391  
controlPartialUpdate(int dpy,int mode)392  extern "C" int controlPartialUpdate(int dpy, int mode) {
393      status_t err = (status_t) FAILED_TRANSACTION;
394      sp<IQService> binder = getBinder();
395      if(binder != NULL) {
396          Parcel inParcel, outParcel;
397          inParcel.writeInt32(dpy);
398          inParcel.writeInt32(mode);
399          err = binder->dispatch(IQService::CONTROL_PARTIAL_UPDATE, &inParcel, &outParcel);
400          if(err != 0) {
401              ALOGE_IF(getBinder(), "%s() failed with err %d", __FUNCTION__, err);
402          } else {
403              return outParcel.readInt32();
404          }
405      }
406  
407      return err;
408  }
409  
410  // returns 0 if composer is up
waitForComposerInit()411  extern "C" int waitForComposerInit() {
412      int status = false;
413      sp<IQService> binder = getBinder();
414      if (binder == NULL) {
415          sleep(2);
416          binder = getBinder();
417      }
418  
419      if (binder != NULL) {
420          Parcel inParcel, outParcel;
421          binder->dispatch(IQService::GET_COMPOSER_STATUS, &inParcel, &outParcel);
422          status = !!outParcel.readInt32();
423          if (!status) {
424              sleep(2);
425              binder->dispatch(IQService::GET_COMPOSER_STATUS, &inParcel, &outParcel);
426              status = !!outParcel.readInt32();
427          }
428      }
429  
430      return !status;
431  }
432  
setStandByMode(int mode,int is_twm=false)433  extern "C" int setStandByMode(int mode, int is_twm = false) {
434      status_t err = (status_t) FAILED_TRANSACTION;
435      sp<IQService> binder = getBinder();
436      Parcel inParcel, outParcel;
437  
438      if(binder != NULL) {
439          inParcel.writeInt32(mode);
440          inParcel.writeInt32(is_twm);
441          err = binder->dispatch(IQService::SET_STAND_BY_MODE,
442                &inParcel, &outParcel);
443          if(err) {
444              ALOGE("%s() failed with err %d", __FUNCTION__, err);
445          }
446      }
447      return err;
448  }
449  
getPanelResolution(int * width,int * height)450  extern "C" int getPanelResolution(int *width, int *height) {
451      status_t err = (status_t) FAILED_TRANSACTION;
452      sp<IQService> binder = getBinder();
453      Parcel inParcel, outParcel;
454  
455      if(binder != NULL) {
456          err = binder->dispatch(IQService::GET_PANEL_RESOLUTION,
457                &inParcel, &outParcel);
458          if(err != 0) {
459              ALOGE_IF(getBinder(), "%s() failed with err %d", __FUNCTION__, err);
460          } else {
461              *width = outParcel.readInt32();
462              *height = outParcel.readInt32();
463          }
464      }
465  
466      return err;
467  }
468  
delayFirstCommit(void)469  extern "C" int delayFirstCommit(void) {
470      status_t err = (status_t) FAILED_TRANSACTION;
471      sp<IQService> binder = getBinder();
472      if(binder != NULL) {
473          err = binder->dispatch(IQService::DELAY_FIRST_COMMIT, NULL, NULL);
474          if(err) {
475              ALOGE("%s() failed with err %d", __FUNCTION__, err);
476          }
477      }
478      return err;
479  }
480