• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "pixel-display.h"
18 
19 #include <aidlcommonsupport/NativeHandle.h>
20 #include <android-base/logging.h>
21 #include <android/binder_manager.h>
22 #include <android/binder_process.h>
23 #include <sys/types.h>
24 #include <utils/Errors.h>
25 
26 #include "ExynosDisplay.h"
27 #include "ExynosPrimaryDisplay.h"
28 
29 extern int32_t load_png_image(const char *filepath, buffer_handle_t buffer);
30 
31 using ::aidl::com::google::hardware::pixel::display::Display;
32 
PixelDisplayInit(ExynosDisplay * exynos_display,const std::string_view instance_str)33 void PixelDisplayInit(ExynosDisplay *exynos_display, const std::string_view instance_str) {
34     ABinderProcess_setThreadPoolMaxThreadCount(0);
35 
36     std::shared_ptr<Display> display = ndk::SharedRefBase::make<Display>(exynos_display);
37     const std::string instance = std::string() + Display::descriptor + "/" + std::string(instance_str).c_str();
38     binder_status_t status =
39             AServiceManager_addService(display->asBinder().get(), instance.c_str());
40     LOG(INFO) << instance.c_str() << " service start...";
41     CHECK(status == STATUS_OK);
42 
43     ABinderProcess_startThreadPool();
44 }
45 
readCompensationImage(const aidl::android::hardware::common::NativeHandle & handle,const std::string & imageName)46 int32_t readCompensationImage(const aidl::android::hardware::common::NativeHandle &handle,
47                               const std::string &imageName) {
48     ALOGI("setCompensationImageHandle, imageName = %s", imageName.c_str());
49 
50     std::string shadowCompensationImage("/mnt/vendor/persist/display/");
51     shadowCompensationImage.append(imageName);
52 
53     native_handle_t *clone = makeFromAidl(handle);
54 
55     return load_png_image(shadowCompensationImage.c_str(), static_cast<buffer_handle_t>(clone));
56 }
57 
58 namespace aidl {
59 namespace com {
60 namespace google {
61 namespace hardware {
62 namespace pixel {
63 namespace display {
64 
65 // ----------------------------------------------------------------------------
66 
isHbmSupported(bool * _aidl_return)67 ndk::ScopedAStatus Display::isHbmSupported(bool *_aidl_return) {
68     *_aidl_return = false;
69     return ndk::ScopedAStatus::ok();
70 }
71 
setHbmState(HbmState state)72 ndk::ScopedAStatus Display::setHbmState(HbmState state) {
73     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
74 }
75 
getHbmState(HbmState * _aidl_return)76 ndk::ScopedAStatus Display::getHbmState(HbmState *_aidl_return) {
77     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
78 }
79 
isLbeSupported(bool * _aidl_return)80 ndk::ScopedAStatus Display::isLbeSupported(bool *_aidl_return) {
81     if (mDisplay) {
82         *_aidl_return = mDisplay->isLbeSupported();
83         return ndk::ScopedAStatus::ok();
84     }
85     *_aidl_return = false;
86     return ndk::ScopedAStatus::ok();
87 }
88 
setLbeState(LbeState state)89 ndk::ScopedAStatus Display::setLbeState(LbeState state) {
90     if (mDisplay) {
91         mDisplay->setLbeState(state);
92         return ndk::ScopedAStatus::ok();
93     }
94     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
95 }
96 
setLbeAmbientLight(int ambientLux)97 ndk::ScopedAStatus Display::setLbeAmbientLight(int ambientLux) {
98     if (mDisplay) {
99         mDisplay->setLbeAmbientLight(ambientLux);
100         return ndk::ScopedAStatus::ok();
101     }
102     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
103 }
104 
getLbeState(LbeState * _aidl_return)105 ndk::ScopedAStatus Display::getLbeState(LbeState *_aidl_return) {
106     if (mDisplay) {
107         *_aidl_return = mDisplay->getLbeState();
108         return ndk::ScopedAStatus::ok();
109     }
110     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
111 }
112 
isLhbmSupported(bool * _aidl_return)113 ndk::ScopedAStatus Display::isLhbmSupported(bool *_aidl_return) {
114     if (mDisplay) {
115         *_aidl_return = mDisplay->isLhbmSupported();
116         return ndk::ScopedAStatus::ok();
117     }
118     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
119 }
120 
setLhbmState(bool enabled)121 ndk::ScopedAStatus Display::setLhbmState(bool enabled) {
122     if (mDisplay && mDisplay->isLhbmSupported()) {
123         int32_t ret = mDisplay->setLhbmState(enabled);
124         if (!ret)
125             return ndk::ScopedAStatus::ok();
126         else if (ret == TIMED_OUT)
127             return ndk::ScopedAStatus::fromExceptionCode(STATUS_TIMED_OUT);
128     }
129     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
130 }
131 
getLhbmState(bool * _aidl_return)132 ndk::ScopedAStatus Display::getLhbmState(bool *_aidl_return) {
133     if (mDisplay && mDisplay->isLhbmSupported()) {
134         *_aidl_return = mDisplay->getLhbmState();
135         return ndk::ScopedAStatus::ok();
136     }
137     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
138 }
139 
setCompensationImageHandle(const NativeHandle & native_handle,const std::string & imageName,int * _aidl_return)140 ndk::ScopedAStatus Display::setCompensationImageHandle(const NativeHandle &native_handle,
141                                                        const std::string &imageName,
142                                                        int *_aidl_return) {
143     if (mDisplay && mDisplay->isColorCalibratedByDevice()) {
144         *_aidl_return = readCompensationImage(native_handle, imageName);
145     } else {
146         *_aidl_return = -1;
147     }
148     return ndk::ScopedAStatus::ok();
149 }
150 
setMinIdleRefreshRate(int fps,int * _aidl_return)151 ndk::ScopedAStatus Display::setMinIdleRefreshRate(int fps, int *_aidl_return) {
152     if (mDisplay) {
153         *_aidl_return = mDisplay->setMinIdleRefreshRate(fps);
154         return ndk::ScopedAStatus::ok();
155     }
156     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
157 }
158 
setRefreshRateThrottle(int delayMs,int * _aidl_return)159 ndk::ScopedAStatus Display::setRefreshRateThrottle(int delayMs, int *_aidl_return) {
160     if (mDisplay) {
161         if (delayMs < 0) {
162             *_aidl_return = BAD_VALUE;
163             ALOGW("%s fail: delayMs(%d) is less than 0", __func__, delayMs);
164             return ndk::ScopedAStatus::ok();
165         }
166 
167         *_aidl_return =
168                 mDisplay->setRefreshRateThrottleNanos(std::chrono::duration_cast<
169                                                               std::chrono::nanoseconds>(
170                                                               std::chrono::milliseconds(delayMs))
171                                                               .count(),
172                                                       VrrThrottleRequester::PIXEL_DISP);
173         return ndk::ScopedAStatus::ok();
174     }
175     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
176 }
177 
runMediator(const RoiRect roi,const Weight weight,const HistogramPos pos,std::vector<char16_t> * histogrambuffer)178 bool Display::runMediator(const RoiRect roi, const Weight weight, const HistogramPos pos,
179                             std::vector<char16_t> *histogrambuffer) {
180     if (mMediator.setRoiWeightThreshold(roi, weight, pos) != HistogramErrorCode::NONE) {
181         ALOGE("histogram error, SET_ROI_WEIGHT_THRESHOLD ERROR\n");
182         return false;
183     }
184     if (!mMediator.histRequested() &&
185         mMediator.requestHist() == HistogramErrorCode::ENABLE_HIST_ERROR) {
186         ALOGE("histogram error, ENABLE_HIST ERROR\n");
187     }
188     if (mMediator.getFrameCount() != mMediator.getSampleFrameCounter()) {
189         mDisplay->mDevice->onRefresh(mDisplay->mDisplayId); // DRM not busy & sampled frame changed
190     }
191     if (mMediator.collectRoiLuma(histogrambuffer) != HistogramErrorCode::NONE) {
192         ALOGE("histogram error, COLLECT_ROI_LUMA ERROR\n");
193         return false;
194     }
195     return true;
196 }
197 
histogramSample(const RoiRect & roi,const Weight & weight,HistogramPos pos,Priority pri,std::vector<char16_t> * histogrambuffer,HistogramErrorCode * _aidl_return)198 ndk::ScopedAStatus Display::histogramSample(const RoiRect &roi, const Weight &weight,
199                                             HistogramPos pos, Priority pri,
200                                             std::vector<char16_t> *histogrambuffer,
201                                             HistogramErrorCode *_aidl_return) {
202     if (!mDisplay) {
203         ALOGI("mDisplay is NULL \n");
204         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
205     }
206     if (histogrambuffer == nullptr) {
207         ALOGE("histogrambuffer is null");
208         *_aidl_return = HistogramErrorCode::BAD_HIST_DATA;
209         return ndk::ScopedAStatus::ok();
210     }
211     if (mMediator.isDisplayPowerOff() == true) {
212         *_aidl_return = HistogramErrorCode::DISPLAY_POWEROFF; // panel is off
213         return ndk::ScopedAStatus::ok();
214     }
215     if (mMediator.isSecureContentPresenting() == true) {
216         *_aidl_return = HistogramErrorCode::DRM_PLAYING; // panel is playing DRM content
217         return ndk::ScopedAStatus::ok();
218     }
219     if ((roi.left < 0) || (roi.top < 0) || ((roi.right - roi.left) <= 0) ||
220         ((roi.bottom - roi.top) <= 0)) {
221         *_aidl_return = HistogramErrorCode::BAD_ROI;
222         ALOGE("histogram error, BAD_ROI (%d, %d, %d, %d) \n", roi.left, roi.top, roi.right,
223               roi.bottom);
224         return ndk::ScopedAStatus::ok();
225     }
226     if ((weight.weightR + weight.weightG + weight.weightB) != (histogram::WEIGHT_SUM)) {
227         *_aidl_return = HistogramErrorCode::BAD_WEIGHT;
228         ALOGE("histogram error, BAD_WEIGHT(%d, %d, %d)\n", weight.weightR, weight.weightG,
229               weight.weightB);
230         return ndk::ScopedAStatus::ok();
231     }
232     if (pos != HistogramPos::POST && pos != HistogramPos::PRE) {
233         *_aidl_return = HistogramErrorCode::BAD_POSITION;
234         ALOGE("histogram error, BAD_POSITION(%d)\n", (int)pos);
235         return ndk::ScopedAStatus::ok();
236     }
237     if (pri != Priority::NORMAL && pri != Priority::PRIORITY) {
238         *_aidl_return = HistogramErrorCode::BAD_PRIORITY;
239         ALOGE("histogram error, BAD_PRIORITY(%d)\n", (int)pri);
240         return ndk::ScopedAStatus::ok();
241     }
242     RoiRect roiCaled = mMediator.calRoi(roi); // fit roi coordinates to RRS
243     runMediator(roiCaled, weight, pos, histogrambuffer);
244     if (mMediator.isSecureContentPresenting() == true) {
245         /* clear data to avoid leakage */
246         std::fill(histogrambuffer->begin(), histogrambuffer->end(), 0);
247         histogrambuffer->clear();
248         *_aidl_return = HistogramErrorCode::DRM_PLAYING; // panel is playing DRM content
249         return ndk::ScopedAStatus::ok();
250     }
251 
252     *_aidl_return = HistogramErrorCode::NONE;
253     return ndk::ScopedAStatus::ok();
254 }
255 
getPanelCalibrationStatus(PanelCalibrationStatus * _aidl_return)256 ndk::ScopedAStatus Display::getPanelCalibrationStatus(PanelCalibrationStatus *_aidl_return){
257     if (mDisplay) {
258         *_aidl_return = mDisplay->getPanelCalibrationStatus();
259         return ndk::ScopedAStatus::ok();
260     }
261     return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
262 }
263 
isDbmSupported(bool * _aidl_return)264 ndk::ScopedAStatus Display::isDbmSupported(bool *_aidl_return) {
265     if (!mDisplay) {
266         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
267     }
268     *_aidl_return = mDisplay->isDbmSupported();
269     return ndk::ScopedAStatus::ok();
270 }
271 
setDbmState(bool enabled)272 ndk::ScopedAStatus Display::setDbmState(bool enabled) {
273     if (!mDisplay) {
274         return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
275     }
276     mDisplay->setDbmState(enabled);
277     return ndk::ScopedAStatus::ok();
278 }
279 
280 } // namespace display
281 } // namespace pixel
282 } // namespace hardware
283 } // namespace google
284 } // namespace com
285 } // namespace aidl
286