mirror of
https://github.com/joel16/android_device_sony_kitakami-common.git
synced 2024-11-23 03:39:50 +00:00
kitakami-common: light: Switch back to classic HAL
* Trying to fix notification led blinking, will re-write our HIDL HAL in the future. * Move led permissions to on init before HIDL service starts.
This commit is contained in:
parent
f72b37b65f
commit
2949861d08
@ -201,7 +201,9 @@ PRODUCT_PACKAGES += \
|
||||
|
||||
# Lights
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.light@2.0-service.kitakami
|
||||
android.hardware.light@2.0-service \
|
||||
android.hardware.light@2.0-impl \
|
||||
lights.msm8994
|
||||
|
||||
# LiveDisplay
|
||||
PRODUCT_PACKAGES += \
|
||||
|
@ -1,32 +0,0 @@
|
||||
//
|
||||
// Copyright (C) 2018 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.
|
||||
|
||||
cc_binary {
|
||||
name: "android.hardware.light@2.0-service.kitakami",
|
||||
relative_install_path: "hw",
|
||||
init_rc: ["android.hardware.light@2.0-service.kitakami.rc"],
|
||||
srcs: ["service.cpp", "Light.cpp"],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
"libcutils",
|
||||
"libhardware",
|
||||
"libhidlbase",
|
||||
"libhidltransport",
|
||||
"libhwbinder",
|
||||
"libutils",
|
||||
"android.hardware.light@2.0",
|
||||
],
|
||||
proprietary: true,
|
||||
}
|
34
light/Android.mk
Normal file
34
light/Android.mk
Normal file
@ -0,0 +1,34 @@
|
||||
# Copyright (C) 2008 The Android Open Source 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.
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
ifeq ($(TARGET_HAS_LOW_PERSISTENCE_DISPLAY),true)
|
||||
LOCAL_CFLAGS += -DLOW_PERSISTENCE_DISPLAY
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
|
||||
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
|
||||
endif
|
||||
|
||||
LOCAL_SRC_FILES := lights.c
|
||||
LOCAL_SHARED_LIBRARIES := liblog
|
||||
LOCAL_MODULE := lights.$(TARGET_BOARD_PLATFORM)
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_VENDOR_MODULE := true
|
||||
include $(BUILD_SHARED_LIBRARY)
|
273
light/Light.cpp
273
light/Light.cpp
@ -1,273 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "LightService"
|
||||
|
||||
#include "Light.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
namespace {
|
||||
using android::hardware::light::V2_0::LightState;
|
||||
|
||||
static constexpr int RAMP_SIZE = 8;
|
||||
static constexpr int RAMP_STEP_DURATION = 50;
|
||||
|
||||
static constexpr int BRIGHTNESS_RAMP[RAMP_SIZE] = {0, 12, 25, 37, 50, 72, 85, 100};
|
||||
static constexpr int DEFAULT_MAX_BRIGHTNESS = 255;
|
||||
|
||||
static uint32_t rgbToBrightness(const LightState& state) {
|
||||
uint32_t color = state.color & 0x00ffffff;
|
||||
return ((77 * ((color >> 16) & 0xff)) + (150 * ((color >> 8) & 0xff)) +
|
||||
(29 * (color & 0xff))) >> 8;
|
||||
}
|
||||
|
||||
static bool isLit(const LightState& state) {
|
||||
return (state.color & 0x00ffffff);
|
||||
}
|
||||
|
||||
static std::string getScaledDutyPcts(int brightness) {
|
||||
std::string buf, pad;
|
||||
|
||||
for (auto i : BRIGHTNESS_RAMP) {
|
||||
buf += pad;
|
||||
buf += std::to_string(i * brightness / 255);
|
||||
pad = ",";
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
Light::Light(std::pair<std::ofstream, uint32_t>&& lcd_backlight,
|
||||
std::ofstream&& red_led, std::ofstream&& green_led, std::ofstream&& blue_led,
|
||||
std::ofstream&& red_duty_pcts, std::ofstream&& green_duty_pcts, std::ofstream&& blue_duty_pcts,
|
||||
std::ofstream&& red_start_idx, std::ofstream&& green_start_idx, std::ofstream&& blue_start_idx,
|
||||
std::ofstream&& red_pause_lo, std::ofstream&& green_pause_lo, std::ofstream&& blue_pause_lo,
|
||||
std::ofstream&& red_pause_hi, std::ofstream&& green_pause_hi, std::ofstream&& blue_pause_hi,
|
||||
std::ofstream&& red_ramp_step_ms, std::ofstream&& green_ramp_step_ms, std::ofstream&& blue_ramp_step_ms,
|
||||
std::ofstream&& red_blink, std::ofstream&& green_blink, std::ofstream&& blue_blink)
|
||||
: mLcdBacklight(std::move(lcd_backlight)),
|
||||
mRedLed(std::move(red_led)),
|
||||
mGreenLed(std::move(green_led)),
|
||||
mBlueLed(std::move(blue_led)),
|
||||
mRedDutyPcts(std::move(red_duty_pcts)),
|
||||
mGreenDutyPcts(std::move(green_duty_pcts)),
|
||||
mBlueDutyPcts(std::move(blue_duty_pcts)),
|
||||
mRedStartIdx(std::move(red_start_idx)),
|
||||
mGreenStartIdx(std::move(green_start_idx)),
|
||||
mBlueStartIdx(std::move(blue_start_idx)),
|
||||
mRedPauseLo(std::move(red_pause_lo)),
|
||||
mGreenPauseLo(std::move(green_pause_lo)),
|
||||
mBluePauseLo(std::move(blue_pause_lo)),
|
||||
mRedPauseHi(std::move(red_pause_hi)),
|
||||
mGreenPauseHi(std::move(green_pause_hi)),
|
||||
mBluePauseHi(std::move(blue_pause_hi)),
|
||||
mRedRampStepMs(std::move(red_ramp_step_ms)),
|
||||
mGreenRampStepMs(std::move(green_ramp_step_ms)),
|
||||
mBlueRampStepMs(std::move(blue_ramp_step_ms)),
|
||||
mRedBlink(std::move(red_blink)),
|
||||
mGreenBlink(std::move(green_blink)),
|
||||
mBlueBlink(std::move(blue_blink)) {
|
||||
auto attnFn(std::bind(&Light::setAttentionLight, this, std::placeholders::_1));
|
||||
auto backlightFn(std::bind(&Light::setLcdBacklight, this, std::placeholders::_1));
|
||||
auto batteryFn(std::bind(&Light::setBatteryLight, this, std::placeholders::_1));
|
||||
auto notifFn(std::bind(&Light::setNotificationLight, this, std::placeholders::_1));
|
||||
mLights.emplace(std::make_pair(Type::ATTENTION, attnFn));
|
||||
mLights.emplace(std::make_pair(Type::BACKLIGHT, backlightFn));
|
||||
mLights.emplace(std::make_pair(Type::BATTERY, batteryFn));
|
||||
mLights.emplace(std::make_pair(Type::NOTIFICATIONS, notifFn));
|
||||
}
|
||||
|
||||
// Methods from ::android::hardware::light::V2_0::ILight follow.
|
||||
Return<Status> Light::setLight(Type type, const LightState& state) {
|
||||
auto it = mLights.find(type);
|
||||
|
||||
if (it == mLights.end()) {
|
||||
return Status::LIGHT_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
it->second(state);
|
||||
|
||||
return Status::SUCCESS;
|
||||
}
|
||||
|
||||
Return<void> Light::getSupportedTypes(getSupportedTypes_cb _hidl_cb) {
|
||||
std::vector<Type> types;
|
||||
|
||||
for (auto const& light : mLights) {
|
||||
types.push_back(light.first);
|
||||
}
|
||||
|
||||
_hidl_cb(types);
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
void Light::setAttentionLight(const LightState& state) {
|
||||
std::lock_guard<std::mutex> lock(mLock);
|
||||
mAttentionState = state;
|
||||
setSpeakerBatteryLightLocked();
|
||||
}
|
||||
|
||||
void Light::setLcdBacklight(const LightState& state) {
|
||||
std::lock_guard<std::mutex> lock(mLock);
|
||||
|
||||
uint32_t brightness = rgbToBrightness(state);
|
||||
|
||||
// If max panel brightness is not the default (255),
|
||||
// apply linear scaling across the accepted range.
|
||||
if (mLcdBacklight.second != DEFAULT_MAX_BRIGHTNESS) {
|
||||
int old_brightness = brightness;
|
||||
brightness = brightness * mLcdBacklight.second / DEFAULT_MAX_BRIGHTNESS;
|
||||
LOG(VERBOSE) << "scaling brightness " << old_brightness << " => " << brightness;
|
||||
}
|
||||
|
||||
mLcdBacklight.first << brightness << std::endl;
|
||||
}
|
||||
|
||||
void Light::setBatteryLight(const LightState& state) {
|
||||
std::lock_guard<std::mutex> lock(mLock);
|
||||
mBatteryState = state;
|
||||
setSpeakerBatteryLightLocked();
|
||||
}
|
||||
|
||||
void Light::setNotificationLight(const LightState& state) {
|
||||
std::lock_guard<std::mutex> lock(mLock);
|
||||
|
||||
uint32_t brightness, color, rgb[3];
|
||||
LightState localState = state;
|
||||
|
||||
// If a brightness has been applied by the user
|
||||
brightness = (localState.color & 0xff000000) >> 24;
|
||||
if (brightness > 0 && brightness < 255) {
|
||||
// Retrieve each of the RGB colors
|
||||
color = localState.color & 0x00ffffff;
|
||||
rgb[0] = (color >> 16) & 0xff;
|
||||
rgb[1] = (color >> 8) & 0xff;
|
||||
rgb[2] = color & 0xff;
|
||||
|
||||
// Apply the brightness level
|
||||
if (rgb[0] > 0) {
|
||||
rgb[0] = (rgb[0] * brightness) / 0xff;
|
||||
}
|
||||
if (rgb[1] > 0) {
|
||||
rgb[1] = (rgb[1] * brightness) / 0xff;
|
||||
}
|
||||
if (rgb[2] > 0) {
|
||||
rgb[2] = (rgb[2] * brightness) / 0xff;
|
||||
}
|
||||
|
||||
// Update with the new color
|
||||
localState.color = (rgb[0] << 16) + (rgb[1] << 8) + rgb[2];
|
||||
}
|
||||
|
||||
mNotificationState = localState;
|
||||
setSpeakerBatteryLightLocked();
|
||||
}
|
||||
|
||||
void Light::setSpeakerBatteryLightLocked() {
|
||||
if (isLit(mNotificationState)) {
|
||||
setSpeakerLightLocked(mNotificationState);
|
||||
} else if (isLit(mAttentionState)) {
|
||||
setSpeakerLightLocked(mAttentionState);
|
||||
} else if (isLit(mBatteryState)) {
|
||||
setSpeakerLightLocked(mBatteryState);
|
||||
} else {
|
||||
// Lights off
|
||||
mRedLed << 0 << std::endl;
|
||||
mGreenLed << 0 << std::endl;
|
||||
mBlueLed << 0 << std::endl;
|
||||
mRedBlink << 0 << std::endl;
|
||||
mGreenBlink << 0 << std::endl;
|
||||
mBlueBlink << 0 << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Light::setSpeakerLightLocked(const LightState& state) {
|
||||
int red, green, blue, blink;
|
||||
int onMs, offMs, stepDuration, pauseHi;
|
||||
uint32_t colorRGB = state.color;
|
||||
|
||||
switch (state.flashMode) {
|
||||
case Flash::TIMED:
|
||||
onMs = state.flashOnMs;
|
||||
offMs = state.flashOffMs;
|
||||
break;
|
||||
case Flash::NONE:
|
||||
default:
|
||||
onMs = 0;
|
||||
offMs = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
red = (colorRGB >> 16) & 0xff;
|
||||
green = (colorRGB >> 8) & 0xff;
|
||||
blue = colorRGB & 0xff;
|
||||
blink = onMs > 0 && offMs > 0;
|
||||
|
||||
if (blink) {
|
||||
stepDuration = RAMP_STEP_DURATION;
|
||||
pauseHi = onMs - (stepDuration * RAMP_SIZE * 2);
|
||||
|
||||
if (stepDuration * RAMP_SIZE * 2 > onMs) {
|
||||
stepDuration = onMs / (RAMP_SIZE * 2);
|
||||
pauseHi = 0;
|
||||
}
|
||||
|
||||
// Red
|
||||
mRedStartIdx << 0 << std::endl;
|
||||
mRedDutyPcts << getScaledDutyPcts(red) << std::endl;
|
||||
mRedPauseLo << offMs << std::endl;
|
||||
mRedPauseHi << pauseHi << std::endl;
|
||||
mRedRampStepMs << stepDuration << std::endl;
|
||||
|
||||
// Green
|
||||
mGreenStartIdx << RAMP_SIZE << std::endl;
|
||||
mGreenDutyPcts << getScaledDutyPcts(green) << std::endl;
|
||||
mGreenPauseLo << offMs << std::endl;
|
||||
mGreenPauseHi << pauseHi << std::endl;
|
||||
mGreenRampStepMs << stepDuration << std::endl;
|
||||
|
||||
// Blue
|
||||
mBlueStartIdx << RAMP_SIZE * 2 << std::endl;
|
||||
mBlueDutyPcts << getScaledDutyPcts(blue) << std::endl;
|
||||
mBluePauseLo << offMs << std::endl;
|
||||
mBluePauseHi << pauseHi << std::endl;
|
||||
mBlueRampStepMs << stepDuration << std::endl;
|
||||
} else {
|
||||
if (red == 0 && green == 0 && blue == 0) {
|
||||
mRedBlink << 0 << std::endl;
|
||||
mGreenBlink << 0 << std::endl;
|
||||
mBlueBlink << 0 << std::endl;
|
||||
}
|
||||
mRedLed << red << std::endl;
|
||||
mGreenLed << green << std::endl;
|
||||
mBlueLed << blue << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_HARDWARE_LIGHT_V2_0_LIGHT_H
|
||||
#define ANDROID_HARDWARE_LIGHT_V2_0_LIGHT_H
|
||||
|
||||
#include <android/hardware/light/2.0/ILight.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace light {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
struct Light : public ILight {
|
||||
Light(std::pair<std::ofstream, uint32_t>&& lcd_backlight,
|
||||
std::ofstream&& red_led, std::ofstream&& green_led, std::ofstream&& blue_led,
|
||||
std::ofstream&& red_duty_pcts, std::ofstream&& green_duty_pcts, std::ofstream&& blue_duty_pcts,
|
||||
std::ofstream&& red_start_idx, std::ofstream&& green_start_idx, std::ofstream&& blue_start_idx,
|
||||
std::ofstream&& red_pause_lo, std::ofstream&& green_pause_lo, std::ofstream&& blue_pause_lo,
|
||||
std::ofstream&& red_pause_hi, std::ofstream&& green_pause_hi, std::ofstream&& blue_pause_hi,
|
||||
std::ofstream&& red_ramp_step_ms, std::ofstream&& green_ramp_step_ms, std::ofstream&& blue_ramp_step_ms,
|
||||
std::ofstream&& red_blink, std::ofstream&& green_blink, std::ofstream&& blue_blink);
|
||||
|
||||
// Methods from ::android::hardware::light::V2_0::ILight follow.
|
||||
Return<Status> setLight(Type type, const LightState& state) override;
|
||||
Return<void> getSupportedTypes(getSupportedTypes_cb _hidl_cb) override;
|
||||
|
||||
private:
|
||||
void setAttentionLight(const LightState& state);
|
||||
void setBatteryLight(const LightState& state);
|
||||
void setLcdBacklight(const LightState& state);
|
||||
void setNotificationLight(const LightState& state);
|
||||
void setSpeakerBatteryLightLocked();
|
||||
void setSpeakerLightLocked(const LightState& state);
|
||||
|
||||
std::pair<std::ofstream, uint32_t> mLcdBacklight;
|
||||
std::ofstream mRedLed;
|
||||
std::ofstream mGreenLed;
|
||||
std::ofstream mBlueLed;
|
||||
std::ofstream mRedDutyPcts;
|
||||
std::ofstream mGreenDutyPcts;
|
||||
std::ofstream mBlueDutyPcts;
|
||||
std::ofstream mRedStartIdx;
|
||||
std::ofstream mGreenStartIdx;
|
||||
std::ofstream mBlueStartIdx;
|
||||
std::ofstream mRedPauseLo;
|
||||
std::ofstream mGreenPauseLo;
|
||||
std::ofstream mBluePauseLo;
|
||||
std::ofstream mRedPauseHi;
|
||||
std::ofstream mGreenPauseHi;
|
||||
std::ofstream mBluePauseHi;
|
||||
std::ofstream mRedRampStepMs;
|
||||
std::ofstream mGreenRampStepMs;
|
||||
std::ofstream mBlueRampStepMs;
|
||||
std::ofstream mRedBlink;
|
||||
std::ofstream mGreenBlink;
|
||||
std::ofstream mBlueBlink;
|
||||
|
||||
LightState mAttentionState;
|
||||
LightState mBatteryState;
|
||||
LightState mNotificationState;
|
||||
|
||||
std::unordered_map<Type, std::function<void(const LightState&)>> mLights;
|
||||
std::mutex mLock;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace light
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_HARDWARE_LIGHT_V2_0_LIGHT_H
|
@ -1,40 +0,0 @@
|
||||
on init
|
||||
# RGB lights
|
||||
chown system system /sys/class/leds/red/pause_lo
|
||||
chown system system /sys/class/leds/green/pause_lo
|
||||
chown system system /sys/class/leds/blue/pause_lo
|
||||
|
||||
chown system system /sys/class/leds/red/pause_hi
|
||||
chown system system /sys/class/leds/green/pause_hi
|
||||
chown system system /sys/class/leds/blue/pause_hi
|
||||
|
||||
chown system system /sys/class/leds/red/blink
|
||||
chown system system /sys/class/leds/green/blink
|
||||
chown system system /sys/class/leds/blue/blink
|
||||
|
||||
chown system system /sys/class/leds/red/ramp_step_ms
|
||||
chown system system /sys/class/leds/green/ramp_step_ms
|
||||
chown system system /sys/class/leds/blue/ramp_step_ms
|
||||
chown system system /sys/class/leds/red/duty_pcts
|
||||
chown system system /sys/class/leds/green/duty_pcts
|
||||
chown system system /sys/class/leds/blue/duty_pcts
|
||||
chown system system /sys/class/leds/red/start_idx
|
||||
chown system system /sys/class/leds/green/start_idx
|
||||
chown system system /sys/class/leds/blue/start_idx
|
||||
|
||||
chmod 660 /sys/class/leds/red/ramp_step_ms
|
||||
chmod 660 /sys/class/leds/green/ramp_step_ms
|
||||
chmod 660 /sys/class/leds/blue/ramp_step_ms
|
||||
chmod 660 /sys/class/leds/red/duty_pcts
|
||||
chmod 660 /sys/class/leds/green/duty_pcts
|
||||
chmod 660 /sys/class/leds/blue/duty_pcts
|
||||
chmod 660 /sys/class/leds/red/start_idx
|
||||
chmod 660 /sys/class/leds/green/start_idx
|
||||
chmod 660 /sys/class/leds/blue/start_idx
|
||||
|
||||
service vendor.light-hal-2-0 /vendor/bin/hw/android.hardware.light@2.0-service.kitakami
|
||||
class hal
|
||||
user system
|
||||
group system
|
||||
# shutting off lights while powering-off
|
||||
shutdown critical
|
497
light/lights.c
Normal file
497
light/lights.c
Normal file
@ -0,0 +1,497 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
* Copyright (C) 2017 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "lights"
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <hardware/lights.h>
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static pthread_once_t g_init = PTHREAD_ONCE_INIT;
|
||||
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static struct light_state_t g_attention;
|
||||
static struct light_state_t g_notification;
|
||||
static struct light_state_t g_battery;
|
||||
static short backlight_bits = 8;
|
||||
|
||||
char const*const RED_LED_FILE
|
||||
= "/sys/class/leds/red/brightness";
|
||||
|
||||
char const*const GREEN_LED_FILE
|
||||
= "/sys/class/leds/green/brightness";
|
||||
|
||||
char const*const BLUE_LED_FILE
|
||||
= "/sys/class/leds/blue/brightness";
|
||||
|
||||
char const*const LCD_FILE
|
||||
= "/sys/class/leds/lcd-backlight/brightness";
|
||||
|
||||
char const*const LCD_MAX_FILE
|
||||
= "/sys/class/leds/lcd-backlight/max_brightness";
|
||||
|
||||
char const*const RED_DUTY_PCTS_FILE
|
||||
= "/sys/class/leds/red/duty_pcts";
|
||||
|
||||
char const*const GREEN_DUTY_PCTS_FILE
|
||||
= "/sys/class/leds/green/duty_pcts";
|
||||
|
||||
char const*const BLUE_DUTY_PCTS_FILE
|
||||
= "/sys/class/leds/blue/duty_pcts";
|
||||
|
||||
char const*const RED_START_IDX_FILE
|
||||
= "/sys/class/leds/red/start_idx";
|
||||
|
||||
char const*const GREEN_START_IDX_FILE
|
||||
= "/sys/class/leds/green/start_idx";
|
||||
|
||||
char const*const BLUE_START_IDX_FILE
|
||||
= "/sys/class/leds/blue/start_idx";
|
||||
|
||||
char const*const RED_PAUSE_LO_FILE
|
||||
= "/sys/class/leds/red/pause_lo";
|
||||
|
||||
char const*const GREEN_PAUSE_LO_FILE
|
||||
= "/sys/class/leds/green/pause_lo";
|
||||
|
||||
char const*const BLUE_PAUSE_LO_FILE
|
||||
= "/sys/class/leds/blue/pause_lo";
|
||||
|
||||
char const*const RED_PAUSE_HI_FILE
|
||||
= "/sys/class/leds/red/pause_hi";
|
||||
|
||||
char const*const GREEN_PAUSE_HI_FILE
|
||||
= "/sys/class/leds/green/pause_hi";
|
||||
|
||||
char const*const BLUE_PAUSE_HI_FILE
|
||||
= "/sys/class/leds/blue/pause_hi";
|
||||
|
||||
char const*const RED_RAMP_STEP_MS_FILE
|
||||
= "/sys/class/leds/red/ramp_step_ms";
|
||||
|
||||
char const*const GREEN_RAMP_STEP_MS_FILE
|
||||
= "/sys/class/leds/green/ramp_step_ms";
|
||||
|
||||
char const*const BLUE_RAMP_STEP_MS_FILE
|
||||
= "/sys/class/leds/blue/ramp_step_ms";
|
||||
|
||||
char const*const RED_BLINK_FILE
|
||||
= "/sys/class/leds/red/blink";
|
||||
|
||||
char const*const GREEN_BLINK_FILE
|
||||
= "/sys/class/leds/green/blink";
|
||||
|
||||
char const*const BLUE_BLINK_FILE
|
||||
= "/sys/class/leds/blue/blink";
|
||||
|
||||
#define RAMP_SIZE 8
|
||||
static int BRIGHTNESS_RAMP[RAMP_SIZE]
|
||||
= { 0, 12, 25, 37, 50, 72, 85, 100 };
|
||||
#define RAMP_STEP_DURATION 50
|
||||
|
||||
/**
|
||||
* device methods
|
||||
*/
|
||||
|
||||
static int
|
||||
read_int(char const* path)
|
||||
{
|
||||
static int already_warned = 0;
|
||||
int fd;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd >= 0) {
|
||||
char read_str[10] = {0,0,0,0,0,0,0,0,0,0};
|
||||
ssize_t err = read(fd, &read_str, sizeof(read_str));
|
||||
close(fd);
|
||||
return err < 2 ? -errno : atoi(read_str);
|
||||
} else {
|
||||
if (already_warned == 0) {
|
||||
ALOGE("read_int failed to open %s\n", path);
|
||||
already_warned = 1;
|
||||
}
|
||||
return -errno;
|
||||
};
|
||||
}
|
||||
|
||||
void init_globals(void)
|
||||
{
|
||||
// init the mutex
|
||||
pthread_mutex_init(&g_lock, NULL);
|
||||
backlight_bits = (read_int(LCD_MAX_FILE) == 4095 ? 12 : 8);
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
write_int(char const* path, int value)
|
||||
{
|
||||
int fd;
|
||||
static int already_warned = 0;
|
||||
|
||||
fd = open(path, O_RDWR);
|
||||
if (fd >= 0) {
|
||||
char buffer[20];
|
||||
int bytes = snprintf(buffer, sizeof(buffer), "%d\n", value);
|
||||
ssize_t amt = write(fd, buffer, (size_t)bytes);
|
||||
close(fd);
|
||||
return amt == -1 ? -errno : 0;
|
||||
} else {
|
||||
if (already_warned == 0) {
|
||||
ALOGE("write_int failed to open %s\n", path);
|
||||
already_warned = 1;
|
||||
}
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
write_str(char const* path, char* value)
|
||||
{
|
||||
int fd;
|
||||
static int already_warned = 0;
|
||||
|
||||
fd = open(path, O_RDWR);
|
||||
if (fd >= 0) {
|
||||
char buffer[1024];
|
||||
int bytes = snprintf(buffer, sizeof(buffer), "%s\n", value);
|
||||
ssize_t amt = write(fd, buffer, (size_t)bytes);
|
||||
close(fd);
|
||||
return amt == -1 ? -errno : 0;
|
||||
} else {
|
||||
if (already_warned == 0) {
|
||||
ALOGE("write_int failed to open %s\n", path);
|
||||
already_warned = 1;
|
||||
}
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
is_lit(struct light_state_t const* state)
|
||||
{
|
||||
return state->color & 0x00ffffff;
|
||||
}
|
||||
|
||||
static int
|
||||
rgb_to_brightness(struct light_state_t const* state)
|
||||
{
|
||||
int color = state->color & 0x00ffffff;
|
||||
return ((77*((color>>16)&0x00ff))
|
||||
+ (150*((color>>8)&0x00ff)) + (29*(color&0x00ff))) >> 8;
|
||||
}
|
||||
|
||||
static int
|
||||
set_light_backlight(struct light_device_t* dev,
|
||||
struct light_state_t const* state)
|
||||
{
|
||||
int err = 0;
|
||||
int brightness = rgb_to_brightness(state);
|
||||
unsigned int lpEnabled = state->brightnessMode == BRIGHTNESS_MODE_LOW_PERSISTENCE;
|
||||
|
||||
if(!dev) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&g_lock);
|
||||
|
||||
if (!err) {
|
||||
if (backlight_bits > 8)
|
||||
brightness = brightness << (backlight_bits - 8);
|
||||
|
||||
err = write_int(LCD_FILE, brightness);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&g_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char*
|
||||
get_scaled_duty_pcts(int brightness)
|
||||
{
|
||||
char *buf = malloc(5 * RAMP_SIZE * sizeof(char));
|
||||
char *pad = "";
|
||||
int i = 0;
|
||||
|
||||
memset(buf, 0, 5 * RAMP_SIZE * sizeof(char));
|
||||
|
||||
for (i = 0; i < RAMP_SIZE; i++) {
|
||||
char temp[5] = "";
|
||||
snprintf(temp, sizeof(temp), "%s%d", pad, (BRIGHTNESS_RAMP[i] * brightness / 255));
|
||||
strcat(buf, temp);
|
||||
pad = ",";
|
||||
}
|
||||
ALOGV("%s: brightness=%d duty=%s", __func__, brightness, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int
|
||||
set_speaker_light_locked(struct light_device_t* dev,
|
||||
struct light_state_t const* state)
|
||||
{
|
||||
int red, green, blue, blink;
|
||||
int onMS, offMS, stepDuration, pauseHi;
|
||||
unsigned int colorRGB;
|
||||
char *duty;
|
||||
|
||||
if(!dev) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (state->flashMode) {
|
||||
case LIGHT_FLASH_TIMED:
|
||||
onMS = state->flashOnMS;
|
||||
offMS = state->flashOffMS;
|
||||
break;
|
||||
case LIGHT_FLASH_NONE:
|
||||
default:
|
||||
onMS = 0;
|
||||
offMS = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
colorRGB = state->color;
|
||||
|
||||
ALOGV("set_speaker_light_locked mode %d, colorRGB=%08X, onMS=%d, offMS=%d\n",
|
||||
state->flashMode, colorRGB, onMS, offMS);
|
||||
|
||||
red = (colorRGB >> 16) & 0xFF;
|
||||
green = (colorRGB >> 8) & 0xFF;
|
||||
blue = colorRGB & 0xFF;
|
||||
// bias for true white
|
||||
if (colorRGB != 0 && red == green && green == blue) {
|
||||
blue = (blue * 171) / 256;
|
||||
}
|
||||
blink = onMS > 0 && offMS > 0;
|
||||
|
||||
// disable all blinking to start
|
||||
write_int(RED_BLINK_FILE, 0);
|
||||
write_int(GREEN_BLINK_FILE, 0);
|
||||
write_int(BLUE_BLINK_FILE, 0);
|
||||
|
||||
if (blink) {
|
||||
stepDuration = RAMP_STEP_DURATION;
|
||||
pauseHi = onMS - (stepDuration * RAMP_SIZE * 2);
|
||||
if (stepDuration * RAMP_SIZE * 2 > onMS) {
|
||||
stepDuration = onMS / (RAMP_SIZE * 2);
|
||||
pauseHi = 0;
|
||||
}
|
||||
|
||||
// red
|
||||
write_int(RED_START_IDX_FILE, 0);
|
||||
duty = get_scaled_duty_pcts(red);
|
||||
write_str(RED_DUTY_PCTS_FILE, duty);
|
||||
write_int(RED_PAUSE_LO_FILE, offMS);
|
||||
// The led driver is configured to ramp up then ramp
|
||||
// down the lut. This effectively doubles the ramp duration.
|
||||
write_int(RED_PAUSE_HI_FILE, pauseHi);
|
||||
write_int(RED_RAMP_STEP_MS_FILE, stepDuration);
|
||||
free(duty);
|
||||
|
||||
// green
|
||||
write_int(GREEN_START_IDX_FILE, RAMP_SIZE);
|
||||
duty = get_scaled_duty_pcts(green);
|
||||
write_str(GREEN_DUTY_PCTS_FILE, duty);
|
||||
write_int(GREEN_PAUSE_LO_FILE, offMS);
|
||||
// The led driver is configured to ramp up then ramp
|
||||
// down the lut. This effectively doubles the ramp duration.
|
||||
write_int(GREEN_PAUSE_HI_FILE, pauseHi);
|
||||
write_int(GREEN_RAMP_STEP_MS_FILE, stepDuration);
|
||||
free(duty);
|
||||
|
||||
// blue
|
||||
write_int(BLUE_START_IDX_FILE, RAMP_SIZE * 2);
|
||||
duty = get_scaled_duty_pcts(blue);
|
||||
write_str(BLUE_DUTY_PCTS_FILE, duty);
|
||||
write_int(BLUE_PAUSE_LO_FILE, offMS);
|
||||
// The led driver is configured to ramp up then ramp
|
||||
// down the lut. This effectively doubles the ramp duration.
|
||||
write_int(BLUE_PAUSE_HI_FILE, pauseHi);
|
||||
write_int(BLUE_RAMP_STEP_MS_FILE, stepDuration);
|
||||
free(duty);
|
||||
|
||||
// start the party
|
||||
write_int(RED_BLINK_FILE, red);
|
||||
write_int(GREEN_BLINK_FILE, green);
|
||||
write_int(BLUE_BLINK_FILE, blue);
|
||||
|
||||
} else {
|
||||
write_int(RED_LED_FILE, red);
|
||||
write_int(GREEN_LED_FILE, green);
|
||||
write_int(BLUE_LED_FILE, blue);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_speaker_light_locked(struct light_device_t* dev)
|
||||
{
|
||||
if (is_lit(&g_attention)) {
|
||||
set_speaker_light_locked(dev, &g_attention);
|
||||
} else if (is_lit(&g_notification)) {
|
||||
set_speaker_light_locked(dev, &g_notification);
|
||||
} else {
|
||||
set_speaker_light_locked(dev, &g_battery);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
set_light_battery(struct light_device_t* dev,
|
||||
struct light_state_t const* state)
|
||||
{
|
||||
pthread_mutex_lock(&g_lock);
|
||||
g_battery = *state;
|
||||
handle_speaker_light_locked(dev);
|
||||
pthread_mutex_unlock(&g_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
set_light_notifications(struct light_device_t* dev,
|
||||
struct light_state_t const* state)
|
||||
{
|
||||
pthread_mutex_lock(&g_lock);
|
||||
|
||||
unsigned int brightness;
|
||||
unsigned int color;
|
||||
unsigned int rgb[3];
|
||||
|
||||
g_notification = *state;
|
||||
|
||||
// If a brightness has been applied by the user
|
||||
brightness = (g_notification.color & 0xFF000000) >> 24;
|
||||
if (brightness > 0 && brightness < 0xFF) {
|
||||
|
||||
// Retrieve each of the RGB colors
|
||||
color = g_notification.color & 0x00FFFFFF;
|
||||
rgb[0] = (color >> 16) & 0xFF;
|
||||
rgb[1] = (color >> 8) & 0xFF;
|
||||
rgb[2] = color & 0xFF;
|
||||
|
||||
// Apply the brightness level
|
||||
if (rgb[0] > 0)
|
||||
rgb[0] = (rgb[0] * brightness) / 0xFF;
|
||||
if (rgb[1] > 0)
|
||||
rgb[1] = (rgb[1] * brightness) / 0xFF;
|
||||
if (rgb[2] > 0)
|
||||
rgb[2] = (rgb[2] * brightness) / 0xFF;
|
||||
|
||||
// Update with the new color
|
||||
g_notification.color = (rgb[0] << 16) + (rgb[1] << 8) + rgb[2];
|
||||
}
|
||||
|
||||
handle_speaker_light_locked(dev);
|
||||
pthread_mutex_unlock(&g_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
set_light_attention(struct light_device_t* dev,
|
||||
struct light_state_t const* state)
|
||||
{
|
||||
pthread_mutex_lock(&g_lock);
|
||||
g_attention = *state;
|
||||
handle_speaker_light_locked(dev);
|
||||
pthread_mutex_unlock(&g_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Close the lights device */
|
||||
static int
|
||||
close_lights(struct light_device_t *dev)
|
||||
{
|
||||
if (dev) {
|
||||
free(dev);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* module methods
|
||||
*/
|
||||
|
||||
/** Open a new instance of a lights device using name */
|
||||
static int open_lights(const struct hw_module_t* module, char const* name,
|
||||
struct hw_device_t** device)
|
||||
{
|
||||
int (*set_light)(struct light_device_t* dev,
|
||||
struct light_state_t const* state);
|
||||
|
||||
if (0 == strcmp(LIGHT_ID_BACKLIGHT, name))
|
||||
set_light = set_light_backlight;
|
||||
else if (0 == strcmp(LIGHT_ID_BATTERY, name))
|
||||
set_light = set_light_battery;
|
||||
else if (0 == strcmp(LIGHT_ID_NOTIFICATIONS, name))
|
||||
set_light = set_light_notifications;
|
||||
else if (0 == strcmp(LIGHT_ID_ATTENTION, name))
|
||||
set_light = set_light_attention;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
pthread_once(&g_init, init_globals);
|
||||
|
||||
struct light_device_t *dev = malloc(sizeof(struct light_device_t));
|
||||
|
||||
if(!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
|
||||
dev->common.tag = HARDWARE_DEVICE_TAG;
|
||||
dev->common.version = 0;
|
||||
dev->common.module = (struct hw_module_t*)module;
|
||||
dev->common.close = (int (*)(struct hw_device_t*))close_lights;
|
||||
dev->set_light = set_light;
|
||||
|
||||
*device = (struct hw_device_t*)dev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct hw_module_methods_t lights_module_methods = {
|
||||
.open = open_lights,
|
||||
};
|
||||
|
||||
/*
|
||||
* The lights Module
|
||||
*/
|
||||
struct hw_module_t HAL_MODULE_INFO_SYM = {
|
||||
.tag = HARDWARE_MODULE_TAG,
|
||||
.version_major = 1,
|
||||
.version_minor = 0,
|
||||
.id = LIGHTS_HARDWARE_MODULE_ID,
|
||||
.name = "Lights Module",
|
||||
.author = "The LineageOS Project",
|
||||
.methods = &lights_module_methods,
|
||||
};
|
@ -1,247 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.light@2.0-service.kitakami"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
#include <utils/Errors.h>
|
||||
|
||||
#include "Light.h"
|
||||
|
||||
// libhwbinder:
|
||||
using android::hardware::configureRpcThreadpool;
|
||||
using android::hardware::joinRpcThreadpool;
|
||||
|
||||
// Generated HIDL files
|
||||
using android::hardware::light::V2_0::ILight;
|
||||
using android::hardware::light::V2_0::implementation::Light;
|
||||
|
||||
const static std::string kLcdBacklightPath = "/sys/class/leds/lcd-backlight/brightness";
|
||||
const static std::string kLcdMaxBacklightPath = "/sys/class/leds/lcd-backlight/max_brightness";
|
||||
const static std::string kRedLedPath = "/sys/class/leds/red/brightness";
|
||||
const static std::string kGreenLedPath = "/sys/class/leds/green/brightness";
|
||||
const static std::string kBlueLedPath = "/sys/class/leds/blue/brightness";
|
||||
const static std::string kRedDutyPctsPath = "/sys/class/leds/red/duty_pcts";
|
||||
const static std::string kGreenDutyPctsPath = "/sys/class/leds/green/duty_pcts";
|
||||
const static std::string kBlueDutyPctsPath = "/sys/class/leds/blue/duty_pcts";
|
||||
const static std::string kRedStartIdxPath = "/sys/class/leds/red/start_idx";
|
||||
const static std::string kGreenStartIdxPath = "/sys/class/leds/green/start_idx";
|
||||
const static std::string kBlueStartIdxPath = "/sys/class/leds/blue/start_idx";
|
||||
const static std::string kRedPauseLoPath = "/sys/class/leds/red/pause_lo";
|
||||
const static std::string kGreenPauseLoPath = "/sys/class/leds/green/pause_lo";
|
||||
const static std::string kBluePauseLoPath = "/sys/class/leds/blue/pause_lo";
|
||||
const static std::string kRedPauseHiPath = "/sys/class/leds/red/pause_hi";
|
||||
const static std::string kGreenPauseHiPath = "/sys/class/leds/green/pause_hi";
|
||||
const static std::string kBluePauseHiPath = "/sys/class/leds/blue/pause_hi";
|
||||
const static std::string kRedRampStepMsPath = "/sys/class/leds/red/ramp_step_ms";
|
||||
const static std::string kGreenRampStepMsPath = "/sys/class/leds/green/ramp_step_ms";
|
||||
const static std::string kBlueRampStepMsPath = "/sys/class/leds/blue/ramp_step_ms";
|
||||
const static std::string kRedBlinkPath = "/sys/class/leds/red/blink";
|
||||
const static std::string kGreenBlinkPath = "/sys/class/leds/green/blink";
|
||||
const static std::string kBlueBlinkPath = "/sys/class/leds/blue/blink";
|
||||
|
||||
int main() {
|
||||
uint32_t lcdMaxBrightness = 255;
|
||||
|
||||
std::ofstream lcdBacklight(kLcdBacklightPath);
|
||||
if (!lcdBacklight) {
|
||||
LOG(ERROR) << "Failed to open " << kLcdBacklightPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ifstream lcdMaxBacklight(kLcdMaxBacklightPath);
|
||||
if (!lcdMaxBacklight) {
|
||||
LOG(ERROR) << "Failed to open " << kLcdMaxBacklightPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
} else {
|
||||
lcdMaxBacklight >> lcdMaxBrightness;
|
||||
}
|
||||
|
||||
std::ofstream redLed(kRedLedPath);
|
||||
if (!redLed) {
|
||||
LOG(ERROR) << "Failed to open " << kRedLedPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream greenLed(kGreenLedPath);
|
||||
if (!greenLed) {
|
||||
LOG(ERROR) << "Failed to open " << kGreenLedPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream blueLed(kBlueLedPath);
|
||||
if (!blueLed) {
|
||||
LOG(ERROR) << "Failed to open " << kBlueLedPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream redDutyPcts(kRedDutyPctsPath);
|
||||
if (!redDutyPcts) {
|
||||
LOG(ERROR) << "Failed to open " << kRedDutyPctsPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream greenDutyPcts(kGreenDutyPctsPath);
|
||||
if (!greenDutyPcts) {
|
||||
LOG(ERROR) << "Failed to open " << kGreenDutyPctsPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream blueDutyPcts(kBlueDutyPctsPath);
|
||||
if (!blueDutyPcts) {
|
||||
LOG(ERROR) << "Failed to open " << kBlueDutyPctsPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream redStartIdx(kRedStartIdxPath);
|
||||
if (!redStartIdx) {
|
||||
LOG(ERROR) << "Failed to open " << kRedStartIdxPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream greenStartIdx(kGreenStartIdxPath);
|
||||
if (!greenStartIdx) {
|
||||
LOG(ERROR) << "Failed to open " << kGreenStartIdxPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream blueStartIdx(kBlueStartIdxPath);
|
||||
if (!blueStartIdx) {
|
||||
LOG(ERROR) << "Failed to open " << kBlueStartIdxPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream redPauseLo(kRedPauseLoPath);
|
||||
if (!redPauseLo) {
|
||||
LOG(ERROR) << "Failed to open " << kRedPauseLoPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream greenPauseLo(kGreenPauseLoPath);
|
||||
if (!greenPauseLo) {
|
||||
LOG(ERROR) << "Failed to open " << kGreenPauseLoPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream bluePauseLo(kBluePauseLoPath);
|
||||
if (!bluePauseLo) {
|
||||
LOG(ERROR) << "Failed to open " << kBluePauseLoPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream redPauseHi(kRedPauseHiPath);
|
||||
if (!redPauseHi) {
|
||||
LOG(ERROR) << "Failed to open " << kRedPauseHiPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream greenPauseHi(kGreenPauseHiPath);
|
||||
if (!greenPauseHi) {
|
||||
LOG(ERROR) << "Failed to open " << kGreenPauseHiPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream bluePauseHi(kBluePauseHiPath);
|
||||
if (!bluePauseHi) {
|
||||
LOG(ERROR) << "Failed to open " << kBluePauseHiPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream redRampStepMs(kRedRampStepMsPath);
|
||||
if (!redRampStepMs) {
|
||||
LOG(ERROR) << "Failed to open " << kRedRampStepMsPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream greenRampStepMs(kGreenRampStepMsPath);
|
||||
if (!greenRampStepMs) {
|
||||
LOG(ERROR) << "Failed to open " << kGreenRampStepMsPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream blueRampStepMs(kBlueRampStepMsPath);
|
||||
if (!blueRampStepMs) {
|
||||
LOG(ERROR) << "Failed to open " << kBlueRampStepMsPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream redBlink(kRedBlinkPath);
|
||||
if (!redBlink) {
|
||||
LOG(ERROR) << "Failed to open " << kRedBlinkPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream greenBlink(kGreenBlinkPath);
|
||||
if (!greenBlink) {
|
||||
LOG(ERROR) << "Failed to open " << kGreenBlinkPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
std::ofstream blueBlink(kBlueBlinkPath);
|
||||
if (!blueBlink) {
|
||||
LOG(ERROR) << "Failed to open " << kBlueBlinkPath << ", error=" << errno
|
||||
<< " (" << strerror(errno) << ")";
|
||||
return -errno;
|
||||
}
|
||||
|
||||
android::sp<ILight> service = new Light(
|
||||
{std::move(lcdBacklight), lcdMaxBrightness},
|
||||
std::move(redLed), std::move(greenLed), std::move(blueLed),
|
||||
std::move(redDutyPcts), std::move(greenDutyPcts), std::move(blueDutyPcts),
|
||||
std::move(redStartIdx), std::move(greenStartIdx), std::move(blueStartIdx),
|
||||
std::move(redPauseLo), std::move(greenPauseLo), std::move(bluePauseLo),
|
||||
std::move(redPauseHi), std::move(greenPauseHi), std::move(bluePauseHi),
|
||||
std::move(redRampStepMs), std::move(greenRampStepMs), std::move(blueRampStepMs),
|
||||
std::move(redBlink), std::move(greenBlink), std::move(blueBlink));
|
||||
|
||||
configureRpcThreadpool(1, true);
|
||||
|
||||
android::status_t status = service->registerAsService();
|
||||
|
||||
if (status != android::OK) {
|
||||
LOG(ERROR) << "Cannot register Light HAL service";
|
||||
return 1;
|
||||
}
|
||||
|
||||
LOG(INFO) << "Light HAL Ready.";
|
||||
joinRpcThreadpool();
|
||||
// Under normal cases, execution will not reach this line.
|
||||
LOG(ERROR) << "Light HAL failed to join thread pool.";
|
||||
return 1;
|
||||
}
|
@ -63,6 +63,43 @@ on init
|
||||
mkdir /storage/removable/remote 0700 root system
|
||||
mount tmpfs tmpfs /storage/removable/remote mode=0755,uid=0,gid=0
|
||||
|
||||
# Panel backlight
|
||||
chown system system /sys/class/leds/lcd-backlight/brightness
|
||||
chmod 660 /sys/class/leds/lcd-backlight/brightness
|
||||
|
||||
# RGB lights
|
||||
chown system system /sys/class/leds/red/pause_lo
|
||||
chown system system /sys/class/leds/green/pause_lo
|
||||
chown system system /sys/class/leds/blue/pause_lo
|
||||
|
||||
chown system system /sys/class/leds/red/pause_hi
|
||||
chown system system /sys/class/leds/green/pause_hi
|
||||
chown system system /sys/class/leds/blue/pause_hi
|
||||
|
||||
chown system system /sys/class/leds/red/blink
|
||||
chown system system /sys/class/leds/green/blink
|
||||
chown system system /sys/class/leds/blue/blink
|
||||
|
||||
chown system system /sys/class/leds/red/ramp_step_ms
|
||||
chown system system /sys/class/leds/green/ramp_step_ms
|
||||
chown system system /sys/class/leds/blue/ramp_step_ms
|
||||
chown system system /sys/class/leds/red/duty_pcts
|
||||
chown system system /sys/class/leds/green/duty_pcts
|
||||
chown system system /sys/class/leds/blue/duty_pcts
|
||||
chown system system /sys/class/leds/red/start_idx
|
||||
chown system system /sys/class/leds/green/start_idx
|
||||
chown system system /sys/class/leds/blue/start_idx
|
||||
|
||||
chmod 660 /sys/class/leds/red/ramp_step_ms
|
||||
chmod 660 /sys/class/leds/green/ramp_step_ms
|
||||
chmod 660 /sys/class/leds/blue/ramp_step_ms
|
||||
chmod 660 /sys/class/leds/red/duty_pcts
|
||||
chmod 660 /sys/class/leds/green/duty_pcts
|
||||
chmod 660 /sys/class/leds/blue/duty_pcts
|
||||
chmod 660 /sys/class/leds/red/start_idx
|
||||
chmod 660 /sys/class/leds/green/start_idx
|
||||
chmod 660 /sys/class/leds/blue/start_idx
|
||||
|
||||
# ZRAM setup
|
||||
write /sys/block/zram0/comp_algorithm lz4
|
||||
write /proc/sys/vm/page-cluster 0
|
||||
@ -337,41 +374,6 @@ on post-fs-data
|
||||
chown system system /sys/devices/platform/msm_sdcc.3/polling
|
||||
chown system system /sys/devices/platform/msm_sdcc.4/polling
|
||||
|
||||
# Panel backlight
|
||||
chown system system /sys/class/leds/lcd-backlight/brightness
|
||||
chmod 660 /sys/class/leds/lcd-backlight/brightness
|
||||
|
||||
# RGB light support
|
||||
chown system system /sys/class/leds/red/pause_lo
|
||||
chown system system /sys/class/leds/blue/pause_lo
|
||||
chown system system /sys/class/leds/green/pause_lo
|
||||
|
||||
chown system system /sys/class/leds/red/pause_hi
|
||||
chown system system /sys/class/leds/blue/pause_hi
|
||||
chown system system /sys/class/leds/green/pause_hi
|
||||
|
||||
chown system system /sys/class/leds/red/blink
|
||||
chown system system /sys/class/leds/blue/blink
|
||||
chown system system /sys/class/leds/green/blink
|
||||
|
||||
# RGB breath effect control support
|
||||
chown system system /sys/class/leds/red/ramp_step_ms
|
||||
chown system system /sys/class/leds/blue/ramp_step_ms
|
||||
chown system system /sys/class/leds/green/ramp_step_ms
|
||||
|
||||
chown system system /sys/class/leds/red/duty_pcts
|
||||
chown system system /sys/class/leds/blue/duty_pcts
|
||||
chown system system /sys/class/leds/green/duty_pcts
|
||||
|
||||
chmod 660 /sys/class/leds/red/ramp_step_ms
|
||||
chmod 660 /sys/class/leds/green/ramp_step_ms
|
||||
chmod 660 /sys/class/leds/blue/ramp_step_ms
|
||||
|
||||
chmod 660 /sys/class/leds/red/duty_pcts
|
||||
chmod 660 /sys/class/leds/green/duty_pcts
|
||||
chmod 660 /sys/class/leds/blue/duty_pcts
|
||||
|
||||
|
||||
# PM8994 flash
|
||||
chown cameraserver camera /sys/class/misc/pmi8994-flash/device/current1
|
||||
chown cameraserver camera /sys/class/misc/pmi8994-flash/device/current2
|
||||
|
Loading…
Reference in New Issue
Block a user