diff --git a/device-tangorpro.mk b/device-tangorpro.mk index 02e1702..c2cdabf 100644 --- a/device-tangorpro.mk +++ b/device-tangorpro.mk @@ -190,6 +190,11 @@ PRODUCT_PACKAGES_DEBUG += \ PRODUCT_PACKAGES += \ android.hardware.lights-service.tangorpro +# LED Golden Config +PRODUCT_COPY_FILES += \ + device/google/tangorpro/lights/led_golden_calibration_LUT_white_CG.txt:$(TARGET_COPY_OUT_VENDOR)/etc/led_golden_calibration_LUT_white_CG.txt \ + device/google/tangorpro/lights/led_golden_calibration_LUT_black_CG.txt:$(TARGET_COPY_OUT_VENDOR)/etc/led_golden_calibration_LUT_black_CG.txt + # Device features PRODUCT_COPY_FILES += \ frameworks/native/data/etc/tablet_core_hardware.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/tablet_core_hardware.xml diff --git a/lights/Android.bp b/lights/Android.bp index dc4a269..9544e19 100644 --- a/lights/Android.bp +++ b/lights/Android.bp @@ -19,5 +19,11 @@ cc_binary { "android.hardware.light-V2-ndk", ], + static_libs: [ + "//hardware/google/interfaces:com.google.hardware.pixel.display-V7-ndk", + "android.hardware.common-V2-ndk", + "android.hardware.graphics.common-V4-ndk", + ], + srcs: ["Lights.cpp", "led_lut_calibrator.cpp"], } diff --git a/lights/Lights.cpp b/lights/Lights.cpp index 0c94698..c6594bd 100644 --- a/lights/Lights.cpp +++ b/lights/Lights.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -29,6 +30,10 @@ using ::aidl::android::hardware::light::ILights; using ::aidl::android::hardware::light::LightType; using ::ndk::ScopedAStatus; using ::ndk::SharedRefBase; +using ::ndk::SpAIBinder; + +using aidl::com::google::hardware::pixel::display::IDisplay; +using PanelCalibrationStatus = aidl::com::google::hardware::pixel::display::PanelCalibrationStatus; static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER; @@ -79,10 +84,34 @@ static int sys_write_int(int fd, int value) { return amount == -1 ? -errno : 0; } +static SpAIBinder WaitForDisplayService() { + LOG(INFO) << "waiting for display service to appear"; + static std::mutex svc_mutex; + static SpAIBinder svc; + std::unique_lock l(svc_mutex); + uint8_t retrycount = 0; + + if (svc != nullptr && AIBinder_isAlive(svc.get())) return svc; + + while (true && retrycount < 20) { + svc = SpAIBinder(AServiceManager_waitForService( + "com.google.hardware.pixel.display.IDisplay/default")); + if (svc != nullptr) { + LOG(INFO) << "A wild display service has appeared!"; + return svc; + } + retrycount++; + sleep(2); + } + + LOG(ERROR) << "Failed to get the display service"; + return NULL; +} + class Lights : public BnLights { private: std::vector availableLights; - LedLutCalibrator calibrator; + LedLutCalibrator *calibrator; void addLight(LightType const type, int const ordinal) { HwLight light{}; @@ -117,12 +146,18 @@ class Lights : public BnLights { addLight(LightType::MICROPHONE, 0); addLight(LightType::CAMERA, 0); + SpAIBinder display_service = WaitForDisplayService(); + auto ser = IDisplay::fromBinder(display_service); + PanelCalibrationStatus cal; + ser->getPanelCalibrationStatus(&cal); + calibrator = new LedLutCalibrator(cal); + int cal_color = 0; - cal_color = calibrator.GetByColorIntensity("green", MODE_DAY); + cal_color = calibrator->GetByColorIntensity("green", MODE_DAY); if (cal_color >= 0) { pwmIds[0].pwm = cal_color; } - cal_color = calibrator.GetByColorIntensity("green", MODE_NIGHT); + cal_color = calibrator->GetByColorIntensity("green", MODE_NIGHT); if (cal_color >= 0) { pwmIds[1].pwm = cal_color << 1; pwmIds[2].pwm = cal_color; @@ -166,6 +201,11 @@ class Lights : public BnLights { int main() { ABinderProcess_setThreadPoolMaxThreadCount(0); + SpAIBinder display_service = WaitForDisplayService(); + if (display_service == nullptr) { + return -1; + } + std::shared_ptr light = SharedRefBase::make(); const std::string instance = std::string() + ILights::descriptor + "/default"; diff --git a/lights/led_golden_calibration_LUT_black_CG.txt b/lights/led_golden_calibration_LUT_black_CG.txt new file mode 100644 index 0000000..9160177 --- /dev/null +++ b/lights/led_golden_calibration_LUT_black_CG.txt @@ -0,0 +1,3 @@ +green:4095:2100 +green:0000:243 +green_cal:1 diff --git a/lights/led_golden_calibration_LUT_white_CG.txt b/lights/led_golden_calibration_LUT_white_CG.txt new file mode 100644 index 0000000..f316c09 --- /dev/null +++ b/lights/led_golden_calibration_LUT_white_CG.txt @@ -0,0 +1,3 @@ +green:4095:680 +green:0000:49 +green_cal:1 diff --git a/lights/led_lut_calibrator.cpp b/lights/led_lut_calibrator.cpp index 0668693..860615d 100644 --- a/lights/led_lut_calibrator.cpp +++ b/lights/led_lut_calibrator.cpp @@ -17,14 +17,20 @@ #include "led_lut_calibrator.h" #include +#include #include #include #include -const char kCalibrationPath[] = "/mnt/vendor/persist/led/led_calibration_LUT.txt"; +using ::android::base::GetProperty; -LedLutCalibrator::LedLutCalibrator() { +const char D_kCalibrationPath[] = "/mnt/vendor/persist/led/led_calibration_LUT.txt"; +const char G_WHT_kCalibrationPath[] = "/vendor/etc/led_golden_calibration_LUT_white_CG.txt"; +const char G_BLK_kCalibrationPath[] = "/vendor/etc/led_golden_calibration_LUT_black_CG.txt"; + +LedLutCalibrator::LedLutCalibrator(PanelCalibrationStatus status) { + cal_status_ = status; if (!ReadCalibrationTable()) { LOG(ERROR) << "Failed to read calibration table"; cal_table_.clear(); @@ -47,19 +53,35 @@ bool LedLutCalibrator::ReadCalibrationTable() { int fd; int bytes; bool ret = true; + const char *k_path = D_kCalibrationPath; std::vector buffer; buffer.resize(512); - fd = open(kCalibrationPath, O_RDONLY); + fd = open(D_kCalibrationPath, O_RDONLY); + // If default calibration not found or display changed, deploy golen calibration. + if (fd < 0 || cal_status_ == PanelCalibrationStatus::GOLDEN) { + // Using golden white calibration as default + // even though bezel prooerty not found. + k_path = G_WHT_kCalibrationPath; + std::string cdt_hwid = GetProperty("ro.boot.cdt_hwid", ""); + std::string hex_variant_str = cdt_hwid.substr(16, 2); + int bezel_color; + sscanf(hex_variant_str.c_str(), "%x", &bezel_color); + // 0: white, 2: black + if (bezel_color == 2) + k_path = G_BLK_kCalibrationPath; + } + + fd = open(k_path, O_RDONLY); if (fd < 0) { - LOG(ERROR) << "Failed to open " << kCalibrationPath; + LOG(ERROR) << "Failed to open " << k_path; ret = false; goto ReadCalibrationTable_err; } bytes = read(fd, buffer.data(), buffer.size()); if (bytes == -1) { - LOG(ERROR) << "Failed to read " << kCalibrationPath; + LOG(ERROR) << "Failed to read " << k_path; ret = false; goto ReadCalibrationTable_err; } diff --git a/lights/led_lut_calibrator.h b/lights/led_lut_calibrator.h index 3756e86..7fb0eaa 100644 --- a/lights/led_lut_calibrator.h +++ b/lights/led_lut_calibrator.h @@ -20,10 +20,13 @@ #include #include #include +#include + +using PanelCalibrationStatus = aidl::com::google::hardware::pixel::display::PanelCalibrationStatus; class LedLutCalibrator { public: - LedLutCalibrator(); + LedLutCalibrator(PanelCalibrationStatus status); LedLutCalibrator &operator=(const LedLutCalibrator &) = delete; ~LedLutCalibrator() = default; int GetByColorIntensity(const std::string &color, int intensity) const; @@ -34,6 +37,7 @@ class LedLutCalibrator { std::string MakeLutKey(const std::string &color, int intensity) const; std::unordered_map cal_table_; + PanelCalibrationStatus cal_status_; }; #endif // GOOGLE_TANGOTRON_LIGHTS_LED_LUT_CALIBRATOR_H_