android_device_oneplus_sm81.../sensors/AlsCorrection.cpp

102 lines
3.9 KiB
C++

/*
* Copyright (C) 2021 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "AlsCorrection.h"
#include <cutils/properties.h>
#include <fstream>
#include <log/log.h>
#include <time.h>
namespace android {
namespace hardware {
namespace sensors {
namespace V2_1 {
namespace implementation {
static int red_max_lux, green_max_lux, blue_max_lux, white_max_lux, max_brightness;
static int als_bias;
template <typename T>
static T get(const std::string& path, const T& def) {
std::ifstream file(path);
T result;
file >> result;
return file.fail() ? def : result;
}
void AlsCorrection::init() {
red_max_lux = get("/mnt/vendor/persist/engineermode/red_max_lux", 0);
green_max_lux = get("/mnt/vendor/persist/engineermode/green_max_lux", 0);
blue_max_lux = get("/mnt/vendor/persist/engineermode/blue_max_lux", 0);
white_max_lux = get("/mnt/vendor/persist/engineermode/white_max_lux", 0);
als_bias = get("/mnt/vendor/persist/engineermode/als_bias", 0);
max_brightness = get("/sys/class/backlight/panel0-backlight/max_brightness", 255);
ALOGV("max r = %d, max g = %d, max b = %d", red_max_lux, green_max_lux, blue_max_lux);
}
void AlsCorrection::correct(float& light) {
pid_t pid = property_get_int32("vendor.sensors.als_correction.pid", 0);
if (pid != 0) {
kill(pid, SIGUSR1);
}
// TODO: HIDL service and pass float instead
int r = property_get_int32("vendor.sensors.als_correction.r", 0);
int g = property_get_int32("vendor.sensors.als_correction.g", 0);
int b = property_get_int32("vendor.sensors.als_correction.b", 0);
ALOGV("Screen Color Above Sensor: %d, %d, %d", r, g, b);
ALOGV("Original reading: %f", light);
int screen_brightness = get("/sys/class/backlight/panel0-backlight/brightness", 0);
float correction = 0.0f, correction_scaled = 0.0f;
if (red_max_lux > 0 && green_max_lux > 0 && blue_max_lux > 0 && white_max_lux > 0) {
constexpr float rgb_scale = 0x7FFFFFFF;
int rgb_min = std::min({r, g, b});
r -= rgb_min;
g -= rgb_min;
b -= rgb_min;
correction += ((float) rgb_min) / rgb_scale * ((float) white_max_lux);
correction += ((float) r) / rgb_scale * ((float) red_max_lux);
correction += ((float) g) / rgb_scale * ((float) green_max_lux);
correction += ((float) b) / rgb_scale * ((float) blue_max_lux);
correction = correction * (((float) screen_brightness) / ((float) max_brightness));
correction += als_bias;
correction_scaled = correction * (((float) white_max_lux) /
(red_max_lux + green_max_lux + blue_max_lux));
}
if (light - correction >= 0) {
// Apply correction if light - correction >= 0
light -= correction;
} else if (light - correction > -4) {
// Return positive value if light - correction > -4
light = correction - light;
} else if (light - correction_scaled >= 0) {
// Substract scaled correction if light - correction_scaled >= 0
light -= correction_scaled;
} else {
// In low light conditions, sensor is just reporting bad values, using
// computed correction instead allows to fix the issue
light = correction;
}
ALOGV("Corrected reading: %f", light);
}
} // namespace implementation
} // namespace V2_1
} // namespace sensors
} // namespace hardware
} // namespace android