lights: Add golden calibration support

The units should deploy the golden calibration data
in either case of replacement of MLB or CG.

Bug: 264023021
Change-Id: Idb670bfefb3585ee1413e16c3e07d4d818f3f9ab
Signed-off-by: Chungjui Fan <chungjuifan@google.com>
This commit is contained in:
Chungjui Fan 2022-12-30 11:53:55 +00:00
parent 6a198d072c
commit bf3ff516ca
7 changed files with 92 additions and 9 deletions

View file

@ -190,6 +190,11 @@ PRODUCT_PACKAGES_DEBUG += \
PRODUCT_PACKAGES += \ PRODUCT_PACKAGES += \
android.hardware.lights-service.tangorpro 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 # Device features
PRODUCT_COPY_FILES += \ PRODUCT_COPY_FILES += \
frameworks/native/data/etc/tablet_core_hardware.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/tablet_core_hardware.xml frameworks/native/data/etc/tablet_core_hardware.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/tablet_core_hardware.xml

View file

@ -19,5 +19,11 @@ cc_binary {
"android.hardware.light-V2-ndk", "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"], srcs: ["Lights.cpp", "led_lut_calibrator.cpp"],
} }

View file

@ -15,6 +15,7 @@
*/ */
#include <aidl/android/hardware/light/BnLights.h> #include <aidl/android/hardware/light/BnLights.h>
#include <aidl/com/google/hardware/pixel/display/IDisplay.h>
#include <android-base/logging.h> #include <android-base/logging.h>
#include <android/binder_manager.h> #include <android/binder_manager.h>
#include <android/binder_process.h> #include <android/binder_process.h>
@ -29,6 +30,10 @@ using ::aidl::android::hardware::light::ILights;
using ::aidl::android::hardware::light::LightType; using ::aidl::android::hardware::light::LightType;
using ::ndk::ScopedAStatus; using ::ndk::ScopedAStatus;
using ::ndk::SharedRefBase; 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; 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; 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<std::mutex> 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 { class Lights : public BnLights {
private: private:
std::vector<HwLight> availableLights; std::vector<HwLight> availableLights;
LedLutCalibrator calibrator; LedLutCalibrator *calibrator;
void addLight(LightType const type, int const ordinal) { void addLight(LightType const type, int const ordinal) {
HwLight light{}; HwLight light{};
@ -117,12 +146,18 @@ class Lights : public BnLights {
addLight(LightType::MICROPHONE, 0); addLight(LightType::MICROPHONE, 0);
addLight(LightType::CAMERA, 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; int cal_color = 0;
cal_color = calibrator.GetByColorIntensity("green", MODE_DAY); cal_color = calibrator->GetByColorIntensity("green", MODE_DAY);
if (cal_color >= 0) { if (cal_color >= 0) {
pwmIds[0].pwm = cal_color; pwmIds[0].pwm = cal_color;
} }
cal_color = calibrator.GetByColorIntensity("green", MODE_NIGHT); cal_color = calibrator->GetByColorIntensity("green", MODE_NIGHT);
if (cal_color >= 0) { if (cal_color >= 0) {
pwmIds[1].pwm = cal_color << 1; pwmIds[1].pwm = cal_color << 1;
pwmIds[2].pwm = cal_color; pwmIds[2].pwm = cal_color;
@ -166,6 +201,11 @@ class Lights : public BnLights {
int main() { int main() {
ABinderProcess_setThreadPoolMaxThreadCount(0); ABinderProcess_setThreadPoolMaxThreadCount(0);
SpAIBinder display_service = WaitForDisplayService();
if (display_service == nullptr) {
return -1;
}
std::shared_ptr<Lights> light = SharedRefBase::make<Lights>(); std::shared_ptr<Lights> light = SharedRefBase::make<Lights>();
const std::string instance = std::string() + ILights::descriptor + "/default"; const std::string instance = std::string() + ILights::descriptor + "/default";

View file

@ -0,0 +1,3 @@
green:4095:2100
green:0000:243
green_cal:1

View file

@ -0,0 +1,3 @@
green:4095:680
green:0000:49
green_cal:1

View file

@ -17,14 +17,20 @@
#include "led_lut_calibrator.h" #include "led_lut_calibrator.h"
#include <android-base/logging.h> #include <android-base/logging.h>
#include <android-base/properties.h>
#include <fcntl.h> #include <fcntl.h>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
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()) { if (!ReadCalibrationTable()) {
LOG(ERROR) << "Failed to read calibration table"; LOG(ERROR) << "Failed to read calibration table";
cal_table_.clear(); cal_table_.clear();
@ -47,19 +53,35 @@ bool LedLutCalibrator::ReadCalibrationTable() {
int fd; int fd;
int bytes; int bytes;
bool ret = true; bool ret = true;
const char *k_path = D_kCalibrationPath;
std::vector<uint8_t> buffer; std::vector<uint8_t> buffer;
buffer.resize(512); 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) { if (fd < 0) {
LOG(ERROR) << "Failed to open " << kCalibrationPath; LOG(ERROR) << "Failed to open " << k_path;
ret = false; ret = false;
goto ReadCalibrationTable_err; goto ReadCalibrationTable_err;
} }
bytes = read(fd, buffer.data(), buffer.size()); bytes = read(fd, buffer.data(), buffer.size());
if (bytes == -1) { if (bytes == -1) {
LOG(ERROR) << "Failed to read " << kCalibrationPath; LOG(ERROR) << "Failed to read " << k_path;
ret = false; ret = false;
goto ReadCalibrationTable_err; goto ReadCalibrationTable_err;
} }

View file

@ -20,10 +20,13 @@
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include <aidl/com/google/hardware/pixel/display/IDisplay.h>
using PanelCalibrationStatus = aidl::com::google::hardware::pixel::display::PanelCalibrationStatus;
class LedLutCalibrator { class LedLutCalibrator {
public: public:
LedLutCalibrator(); LedLutCalibrator(PanelCalibrationStatus status);
LedLutCalibrator &operator=(const LedLutCalibrator &) = delete; LedLutCalibrator &operator=(const LedLutCalibrator &) = delete;
~LedLutCalibrator() = default; ~LedLutCalibrator() = default;
int GetByColorIntensity(const std::string &color, int intensity) const; 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::string MakeLutKey(const std::string &color, int intensity) const;
std::unordered_map<std::string, int> cal_table_; std::unordered_map<std::string, int> cal_table_;
PanelCalibrationStatus cal_status_;
}; };
#endif // GOOGLE_TANGOTRON_LIGHTS_LED_LUT_CALIBRATOR_H_ #endif // GOOGLE_TANGOTRON_LIGHTS_LED_LUT_CALIBRATOR_H_