diff --git a/framework_manifest.xml b/framework_manifest.xml index 583c61b..a7b965a 100644 --- a/framework_manifest.xml +++ b/framework_manifest.xml @@ -16,6 +16,10 @@ IDisplayModes default + + IPictureAdjustment + default + ISunlightEnhancement default diff --git a/livedisplay/Android.bp b/livedisplay/Android.bp index e7a1aac..9d7cb12 100644 --- a/livedisplay/Android.bp +++ b/livedisplay/Android.bp @@ -20,6 +20,7 @@ cc_binary { relative_install_path: "hw", srcs: [ "DisplayModes.cpp", + "PictureAdjustment.cpp", "SunlightEnhancement.cpp", "service.cpp", ], diff --git a/livedisplay/Constants.h b/livedisplay/Constants.h new file mode 100644 index 0000000..c7589ef --- /dev/null +++ b/livedisplay/Constants.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2019 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 VENDOR_LINEAGE_LIVEDISPLAY_V2_0_CONSTANTS_H +#define VENDOR_LINEAGE_LIVEDISPLAY_V2_0_CONSTANTS_H + +namespace vendor { +namespace lineage { +namespace livedisplay { +namespace V2_0 { +namespace implementation { + +#define DPPS_BUF_SIZE 64 + +#define FOSS_PROPERTY "ro.vendor.display.foss" +#define FOSS_ON "foss:on" +#define FOSS_OFF "foss:off" + +#define COLOR_BALANCE_FEATURE 3 +#define DISPLAY_MODES_FEATURE 4 +#define PICTURE_ADJUSTMENT_FEATURE 1 + +} // namespace implementation +} // namespace V2_0 +} // namespace livedisplay +} // namespace lineage +} // namespace vendor + +#endif // VENDOR_LINEAGE_LIVEDISPLAY_V2_0_CONSTANTS_H diff --git a/livedisplay/PictureAdjustment.cpp b/livedisplay/PictureAdjustment.cpp new file mode 100644 index 0000000..95f243c --- /dev/null +++ b/livedisplay/PictureAdjustment.cpp @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2019 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 "PictureAdjustment.h" + +#include + +#include "Constants.h" +#include "Types.h" + +namespace vendor { +namespace lineage { +namespace livedisplay { +namespace V2_0 { +namespace implementation { + +static sp sInstance; + +PictureAdjustment::PictureAdjustment(void* libHandle, uint64_t cookie) { + sInstance = this; + + mLibHandle = libHandle; + mCookie = cookie; + disp_api_get_feature_version = + reinterpret_cast( + dlsym(mLibHandle, "disp_api_get_feature_version")); + disp_api_get_global_pa_range = reinterpret_cast( + dlsym(mLibHandle, "disp_api_get_global_pa_range")); + disp_api_get_global_pa_config = + reinterpret_cast( + dlsym(mLibHandle, "disp_api_get_global_pa_config")); + disp_api_set_global_pa_config = + reinterpret_cast( + dlsym(mLibHandle, "disp_api_set_global_pa_config")); + memset(&mDefaultPictureAdjustment, 0, sizeof(HSIC)); +} + +bool PictureAdjustment::isSupported() { + sdm_feature_version version{}; + hsic_ranges r{}; + uint32_t flags = 0; + static int supported = -1; + + if (supported >= 0) { + goto out; + } + + if (disp_api_get_feature_version == nullptr || + disp_api_get_feature_version(mCookie, PICTURE_ADJUSTMENT_FEATURE, &version, &flags) != 0) { + supported = 0; + goto out; + } + + if (version.x <= 0 && version.y <= 0 && version.z <= 0) { + supported = 0; + goto out; + } + + if (disp_api_get_global_pa_range == nullptr || + disp_api_get_global_pa_range(mCookie, 0, &r) != 0) { + supported = 0; + goto out; + } + + supported = r.hue.max != 0 && r.hue.min != 0 && r.saturation.max != 0.f && + r.saturation.min != 0.f && r.intensity.max != 0.f && r.intensity.min != 0.f && + r.contrast.max != 0.f && r.contrast.min != 0.f; +out: + return supported; +} + +HSIC PictureAdjustment::getPictureAdjustmentInternal() { + hsic_config config{}; + uint32_t enable = 0; + + if (disp_api_get_global_pa_config != nullptr) { + if (disp_api_get_global_pa_config(mCookie, 0, &enable, &config) == 0) { + return HSIC{static_cast(config.data.hue), config.data.saturation, + config.data.intensity, config.data.contrast, + config.data.saturationThreshold}; + } + } + + return HSIC{}; +} + +void PictureAdjustment::updateDefaultPictureAdjustment() { + if (sInstance != nullptr) { + sInstance->mDefaultPictureAdjustment = sInstance->getPictureAdjustmentInternal(); + } +} + +// Methods from ::vendor::lineage::livedisplay::V2_0::IPictureAdjustment follow. +Return PictureAdjustment::getHueRange(getHueRange_cb _hidl_cb) { + FloatRange range{}; + hsic_ranges r{}; + + if (disp_api_get_global_pa_range != nullptr) { + if (disp_api_get_global_pa_range(mCookie, 0, &r) == 0) { + range.max = r.hue.max; + range.min = r.hue.min; + range.step = r.hue.step; + } + } + + _hidl_cb(range); + return Void(); +} + +Return PictureAdjustment::getSaturationRange(getSaturationRange_cb _hidl_cb) { + FloatRange range{}; + hsic_ranges r{}; + + if (disp_api_get_global_pa_range != nullptr) { + if (disp_api_get_global_pa_range(mCookie, 0, &r) == 0) { + range.max = r.saturation.max; + range.min = r.saturation.min; + range.step = r.saturation.step; + } + } + + _hidl_cb(range); + return Void(); +} + +Return PictureAdjustment::getIntensityRange(getIntensityRange_cb _hidl_cb) { + FloatRange range{}; + hsic_ranges r{}; + + if (disp_api_get_global_pa_range != nullptr) { + if (disp_api_get_global_pa_range(mCookie, 0, &r) == 0) { + range.max = r.intensity.max; + range.min = r.intensity.min; + range.step = r.intensity.step; + } + } + + _hidl_cb(range); + return Void(); +} + +Return PictureAdjustment::getContrastRange(getContrastRange_cb _hidl_cb) { + FloatRange range{}; + hsic_ranges r{}; + + if (disp_api_get_global_pa_range != nullptr) { + if (disp_api_get_global_pa_range(mCookie, 0, &r) == 0) { + range.max = r.contrast.max; + range.min = r.contrast.min; + range.step = r.contrast.step; + } + } + + _hidl_cb(range); + return Void(); +} + +Return PictureAdjustment::getSaturationThresholdRange( + getSaturationThresholdRange_cb _hidl_cb) { + FloatRange range{}; + hsic_ranges r{}; + + if (disp_api_get_global_pa_range != nullptr) { + if (disp_api_get_global_pa_range(mCookie, 0, &r) == 0) { + range.max = r.saturationThreshold.max; + range.min = r.saturationThreshold.min; + range.step = r.saturationThreshold.step; + } + } + + _hidl_cb(range); + return Void(); +} + +Return PictureAdjustment::getPictureAdjustment(getPictureAdjustment_cb _hidl_cb) { + _hidl_cb(getPictureAdjustmentInternal()); + return Void(); +} + +Return PictureAdjustment::getDefaultPictureAdjustment( + getDefaultPictureAdjustment_cb _hidl_cb) { + _hidl_cb(mDefaultPictureAdjustment); + return Void(); +} + +Return PictureAdjustment::setPictureAdjustment( + const ::vendor::lineage::livedisplay::V2_0::HSIC& hsic) { + hsic_config config = {0, + {static_cast(hsic.hue), hsic.saturation, hsic.intensity, + hsic.contrast, hsic.saturationThreshold}}; + + if (disp_api_set_global_pa_config != nullptr) { + return disp_api_set_global_pa_config(mCookie, 0, 1, &config) == 0; + } + + return false; +} + +} // namespace implementation +} // namespace V2_0 +} // namespace livedisplay +} // namespace lineage +} // namespace vendor diff --git a/livedisplay/PictureAdjustment.h b/livedisplay/PictureAdjustment.h new file mode 100644 index 0000000..a1c82c3 --- /dev/null +++ b/livedisplay/PictureAdjustment.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019 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 VENDOR_LINEAGE_LIVEDISPLAY_V2_0_PICTUREADJUSTMENT_H +#define VENDOR_LINEAGE_LIVEDISPLAY_V2_0_PICTUREADJUSTMENT_H + +#include + +namespace vendor { +namespace lineage { +namespace livedisplay { +namespace V2_0 { +namespace implementation { + +using ::android::sp; +using ::android::hardware::Return; +using ::android::hardware::Void; + +class PictureAdjustment : public IPictureAdjustment { + public: + PictureAdjustment(void* libHandle, uint64_t cookie); + + bool isSupported(); + + // Methods from ::vendor::lineage::livedisplay::V2_0::IPictureAdjustment follow. + Return getHueRange(getHueRange_cb _hidl_cb) override; + Return getSaturationRange(getSaturationRange_cb _hidl_cb) override; + Return getIntensityRange(getIntensityRange_cb _hidl_cb) override; + Return getContrastRange(getContrastRange_cb _hidl_cb) override; + Return getSaturationThresholdRange(getSaturationThresholdRange_cb _hidl_cb) override; + Return getPictureAdjustment(getPictureAdjustment_cb _hidl_cb) override; + Return getDefaultPictureAdjustment(getDefaultPictureAdjustment_cb _hidl_cb) override; + Return setPictureAdjustment( + const ::vendor::lineage::livedisplay::V2_0::HSIC& hsic) override; + + static void updateDefaultPictureAdjustment(); + + private: + void* mLibHandle; + uint64_t mCookie; + + int32_t (*disp_api_get_feature_version)(uint64_t, uint32_t, void*, uint32_t*); + int32_t (*disp_api_get_global_pa_range)(uint64_t, uint32_t, void*); + int32_t (*disp_api_get_global_pa_config)(uint64_t, uint32_t, uint32_t*, void*); + int32_t (*disp_api_set_global_pa_config)(uint64_t, uint32_t, uint32_t, void*); + + HSIC getPictureAdjustmentInternal(); + + HSIC mDefaultPictureAdjustment; +}; + +} // namespace implementation +} // namespace V2_0 +} // namespace livedisplay +} // namespace lineage +} // namespace vendor + +#endif // VENDOR_LINEAGE_LIVEDISPLAY_V2_0_PICTUREADJUSTMENT_H diff --git a/livedisplay/Types.h b/livedisplay/Types.h new file mode 100644 index 0000000..72399c0 --- /dev/null +++ b/livedisplay/Types.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2019 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 VENDOR_LINEAGE_LIVEDISPLAY_V2_0_TYPES_H +#define VENDOR_LINEAGE_LIVEDISPLAY_V2_0_TYPES_H + +namespace vendor { +namespace lineage { +namespace livedisplay { +namespace V2_0 { +namespace implementation { + +struct sdm_feature_version { + uint8_t x, y; + uint16_t z; +}; + +struct sdm_disp_mode { + int32_t id; + int32_t type; + int32_t len; + char* name; +}; + +struct hsic_data { + int32_t hue; + float saturation; + float intensity; + float contrast; + float saturationThreshold; +}; + +struct hsic_config { + uint32_t unused; + hsic_data data; +}; + +struct hsic_int_range { + int32_t max; + int32_t min; + uint32_t step; +}; + +struct hsic_float_range { + float max; + float min; + float step; +}; + +struct hsic_ranges { + uint32_t unused; + struct hsic_int_range hue; + struct hsic_float_range saturation; + struct hsic_float_range intensity; + struct hsic_float_range contrast; + struct hsic_float_range saturationThreshold; +}; + +} // namespace implementation +} // namespace V2_0 +} // namespace livedisplay +} // namespace lineage +} // namespace vendor + +#endif // VENDOR_LINEAGE_LIVEDISPLAY_V2_0_TYPES_H diff --git a/livedisplay/service.cpp b/livedisplay/service.cpp index 623a291..6f21363 100644 --- a/livedisplay/service.cpp +++ b/livedisplay/service.cpp @@ -14,39 +14,143 @@ * limitations under the License. */ +#include + #define LOG_TAG "lineage.livedisplay@2.0-service.oneplus_kona" +#define SDM_DISP_LIB "libsdm-disp-apis.qti.so" + #include #include #include + #include "DisplayModes.h" +#include "PictureAdjustment.h" #include "SunlightEnhancement.h" +using android::OK; +using android::sp; +using android::status_t; +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; + using ::vendor::lineage::livedisplay::V2_0::IDisplayModes; +using ::vendor::lineage::livedisplay::V2_0::IPictureAdjustment; using ::vendor::lineage::livedisplay::V2_0::ISunlightEnhancement; using ::vendor::lineage::livedisplay::V2_0::implementation::DisplayModes; +using ::vendor::lineage::livedisplay::V2_0::implementation::PictureAdjustment; using ::vendor::lineage::livedisplay::V2_0::implementation::SunlightEnhancement; int main() { - android::sp modesService = new DisplayModes(); - android::sp sreService = new SunlightEnhancement(); + // Vendor backend + void* libHandle = nullptr; + const char* libName = nullptr; + int32_t (*disp_api_init)(uint64_t*, uint32_t) = nullptr; + int32_t (*disp_api_deinit)(uint64_t, uint32_t) = nullptr; + uint64_t cookie = 0; - android::hardware::configureRpcThreadpool(2, true /*callerWillJoin*/); + // HIDL frontend + sp dm; + sp pa; + sp se; - if (modesService->registerAsService() != android::OK) { - LOG(ERROR) << "Cannot register display modes HAL service."; - return 1; + status_t status = OK; + + android::ProcessState::initWithDriver("/dev/binder"); + + LOG(INFO) << "LiveDisplay HAL service is starting."; + + libHandle = dlopen(SDM_DISP_LIB, RTLD_NOW); + if (libHandle == nullptr) { + LOG(ERROR) << "Failed to load SDM display lib, exiting."; + goto shutdown; } - if (sreService->registerAsService() != android::OK) { - LOG(ERROR) << "Cannot register sunlight enhancement HAL service."; - return 1; + disp_api_init = + reinterpret_cast(dlsym(libHandle, "disp_api_init")); + if (disp_api_init == nullptr) { + LOG(ERROR) << "Can not get disp_api_init from " << libName << " (" << dlerror() << ")"; + goto shutdown; } - LOG(INFO) << "LiveDisplay HAL service ready."; + disp_api_deinit = + reinterpret_cast(dlsym(libHandle, "disp_api_deinit")); + if (disp_api_deinit == nullptr) { + LOG(ERROR) << "Can not get disp_api_deinit from " << libName << " (" << dlerror() << ")"; + goto shutdown; + } - android::hardware::joinRpcThreadpool(); + status = disp_api_init(&cookie, 0); + if (status != OK) { + LOG(ERROR) << "Can not initialize " << libName << " (" << status << ")"; + goto shutdown; + } - LOG(ERROR) << "LiveDisplay HAL service failed to join thread pool."; + dm = new DisplayModes(); + if (dm == nullptr) { + LOG(ERROR) << "Can not create an instance of LiveDisplay HAL DisplayModes Iface, exiting."; + goto shutdown; + } + + pa = new PictureAdjustment(libHandle, cookie); + if (pa == nullptr) { + LOG(ERROR) << "Can not create an instance of LiveDisplay HAL PictureAdjustment Iface, " + "exiting."; + goto shutdown; + } + + se = new SunlightEnhancement(); + if (se == nullptr) { + LOG(ERROR) << "Can not create an instance of LiveDisplay HAL SunlightEnhancement Iface, " + "exiting."; + goto shutdown; + } + + if (!pa->isSupported()) { + // Backend isn't ready yet, so restart and try again + goto shutdown; + } + + configureRpcThreadpool(1, true /*callerWillJoin*/); + + status = dm->registerAsService(); + if (status != OK) { + LOG(ERROR) << "Could not register service for LiveDisplay HAL DisplayModes Iface (" + << status << ")"; + goto shutdown; + } + + if (pa->isSupported()) { + status = pa->registerAsService(); + if (status != OK) { + LOG(ERROR) << "Could not register service for LiveDisplay HAL PictureAdjustment Iface (" + << status << ")"; + goto shutdown; + } + } + + status = se->registerAsService(); + if (status != OK) { + LOG(ERROR) << "Could not register service for LiveDisplay HAL SunlightEnhancement Iface (" + << status << ")"; + goto shutdown; + } + + LOG(INFO) << "LiveDisplay HAL service is ready."; + joinRpcThreadpool(); + // Should not pass this line + +shutdown: + // Cleanup what we started + if (disp_api_deinit != nullptr) { + disp_api_deinit(cookie, 0); + } + + if (libHandle != nullptr) { + dlclose(libHandle); + } + + // In normal operation, we don't expect the thread pool to shutdown + LOG(ERROR) << "LiveDisplay HAL service is shutting down."; return 1; } diff --git a/proprietary-files.txt b/proprietary-files.txt index 209af7f..7a1a033 100644 --- a/proprietary-files.txt +++ b/proprietary-files.txt @@ -13,6 +13,10 @@ product/lib64/libaptXHD_encoder.so|e13fa70c97caaa24d061678bdee608eb8850a69e # DASH sbin/dashd:bin/dashd +# Display +product/lib64/libsdm-disp-apis.qti.so +product/lib64/vendor.display.color@1.0.so + # DPM framework/tcmclient.jar product/bin/dpmd diff --git a/sepolicy/private/hal_livedisplay_kona.te b/sepolicy/private/hal_livedisplay_kona.te index 55ac7a0..4683a66 100644 --- a/sepolicy/private/hal_livedisplay_kona.te +++ b/sepolicy/private/hal_livedisplay_kona.te @@ -4,6 +4,17 @@ hal_server_domain(hal_livedisplay_kona, hal_lineage_livedisplay) type hal_livedisplay_kona_exec, system_file_type, exec_type, file_type; init_daemon_domain(hal_livedisplay_kona) +# Allow hal_livedisplay_kona to find hal_display_color_hwservice +type hal_display_color_hwservice, hwservice_manager_type; +allow hal_livedisplay_kona hal_display_color_hwservice:hwservice_manager find; + +# Allow binder communication with hal_display_color_default +type hal_display_color_default, domain; +binder_call(hal_livedisplay_kona, hal_display_color_default) + +# Allow hal_livedisplay_kona to use binder service +binder_use(hal_livedisplay_kona) + # Allow LiveDisplay to store files under /data/misc/display and access them allow hal_livedisplay_kona display_misc_file:dir rw_dir_perms; allow hal_livedisplay_kona display_misc_file:file create_file_perms;