diff --git a/configs/framework_compatibility_matrix.xml b/configs/framework_compatibility_matrix.xml
index f670a77..124105e 100644
--- a/configs/framework_compatibility_matrix.xml
+++ b/configs/framework_compatibility_matrix.xml
@@ -113,6 +113,14 @@
IAdaptiveBacklight
default
+
+ IDisplayColorCalibration
+ default
+
+
+ IDisplayModes
+ default
+
ISunlightEnhancement
default
diff --git a/configs/manifest.xml b/configs/manifest.xml
index f90cd73..857d2c7 100644
--- a/configs/manifest.xml
+++ b/configs/manifest.xml
@@ -303,11 +303,21 @@
IAdaptiveBacklight
default
+
+ IDisplayColorCalibration
+ default
+
+
+ IDisplayModes
+ default
+
ISunlightEnhancement
default
@2.0::IAdaptiveBacklight/default
+ @2.0::IDisplayColorCalibration/default
+ @2.0::IDisplayModes/default
@2.0::ISunlightEnhancement/default
diff --git a/livedisplay/Android.bp b/livedisplay/Android.bp
index 7e2cdbf..88bcafa 100644
--- a/livedisplay/Android.bp
+++ b/livedisplay/Android.bp
@@ -19,7 +19,9 @@ cc_binary {
relative_install_path: "hw",
srcs: [
"AdaptiveBacklight.cpp",
+ "DisplayModes.cpp",
"SunlightEnhancement.cpp",
+ "DisplayColorCalibration.cpp",
"service.cpp",
],
shared_libs: [
diff --git a/livedisplay/DisplayColorCalibration.cpp b/livedisplay/DisplayColorCalibration.cpp
new file mode 100644
index 0000000..9ce3d44
--- /dev/null
+++ b/livedisplay/DisplayColorCalibration.cpp
@@ -0,0 +1,77 @@
+/*
+ * 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
+#include
+
+#include
+
+#include "DisplayColorCalibration.h"
+
+using android::base::ReadFileToString;
+using android::base::Split;
+using android::base::Trim;
+using android::base::WriteStringToFile;
+
+namespace vendor {
+namespace lineage {
+namespace livedisplay {
+namespace V2_0 {
+namespace samsung {
+
+static constexpr const char* kColorPath = "/sys/class/mdnie/mdnie/sensorRGB";
+
+bool DisplayColorCalibration::isSupported() {
+ std::fstream rgb(kColorPath, rgb.in | rgb.out);
+ return rgb.good();
+}
+
+Return DisplayColorCalibration::getMaxValue() {
+ return 255;
+}
+
+Return DisplayColorCalibration::getMinValue() {
+ return 1;
+}
+
+Return DisplayColorCalibration::getCalibration(getCalibration_cb resultCb) {
+ std::vector rgb;
+ std::string tmp;
+
+ if (ReadFileToString(kColorPath, &tmp)) {
+ std::vector colors = Split(Trim(tmp), " ");
+ for (const std::string& color : colors) {
+ rgb.push_back(std::stoi(color));
+ }
+ }
+
+ resultCb(rgb);
+ return Void();
+}
+
+Return DisplayColorCalibration::setCalibration(const hidl_vec& rgb) {
+ std::string contents;
+ for (const int32_t& color : rgb) {
+ contents += std::to_string(color) + " ";
+ }
+ return WriteStringToFile(Trim(contents), kColorPath, true);
+}
+
+} // namespace samsung
+} // namespace V2_0
+} // namespace livedisplay
+} // namespace lineage
+} // namespace vendor
diff --git a/livedisplay/DisplayColorCalibration.h b/livedisplay/DisplayColorCalibration.h
new file mode 100644
index 0000000..94188c0
--- /dev/null
+++ b/livedisplay/DisplayColorCalibration.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019-2022 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.
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+namespace vendor {
+namespace lineage {
+namespace livedisplay {
+namespace V2_0 {
+namespace samsung {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+class DisplayColorCalibration : public IDisplayColorCalibration {
+ public:
+ bool isSupported();
+
+ // Methods from ::vendor::lineage::livedisplay::V2_0::IDisplayColorCalibration follow.
+ Return getMaxValue() override;
+ Return getMinValue() override;
+ Return getCalibration(getCalibration_cb resultCb) override;
+ Return setCalibration(const hidl_vec& rgb) override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+};
+
+} // namespace samsung
+} // namespace V2_0
+} // namespace livedisplay
+} // namespace lineage
+} // namespace vendor
diff --git a/livedisplay/DisplayModes.cpp b/livedisplay/DisplayModes.cpp
new file mode 100644
index 0000000..12af3dc
--- /dev/null
+++ b/livedisplay/DisplayModes.cpp
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "DisplayModesService"
+
+#include "DisplayModes.h"
+#include
+#include
+
+namespace vendor {
+namespace lineage {
+namespace livedisplay {
+namespace V2_0 {
+namespace samsung {
+
+static constexpr const char* kModePath = "/sys/class/mdnie/mdnie/mode";
+static constexpr const char* kModeMaxPath = "/sys/class/mdnie/mdnie/mode_max";
+#ifdef LIVES_IN_SYSTEM
+static constexpr const char* kDefaultPath = "/data/misc/display/.displaymodedefault";
+#else
+static constexpr const char* kDefaultPath = "/data/vendor/display/.displaymodedefault";
+#endif
+
+const std::map DisplayModes::kModeMap = {
+ // clang-format off
+ {0, "Dynamic"},
+ {1, "Standard"},
+ {2, "Natural"},
+ {3, "Cinema"},
+ {4, "Adaptive"},
+ // clang-format on
+};
+
+DisplayModes::DisplayModes() : mDefaultModeId(4) {
+ std::ifstream defaultFile(kDefaultPath);
+ int value;
+
+ defaultFile >> value;
+ LOG(DEBUG) << "Default file read result " << value << " fail " << defaultFile.fail();
+ if (defaultFile.fail()) {
+ return;
+ }
+
+ for (const auto& entry : kModeMap) {
+ if (value == entry.first) {
+ mDefaultModeId = entry.first;
+ break;
+ }
+ }
+
+ setDisplayMode(mDefaultModeId, false);
+}
+
+bool DisplayModes::isSupported() {
+ std::ofstream modeFile(kModePath);
+ return modeFile.good();
+}
+
+// Methods from ::vendor::lineage::livedisplay::V2_0::IDisplayModes follow.
+Return DisplayModes::getDisplayModes(getDisplayModes_cb resultCb) {
+ std::ifstream maxModeFile(kModeMaxPath);
+ int value;
+ std::vector modes;
+ if (!maxModeFile.fail()) {
+ maxModeFile >> value;
+ } else {
+ value = kModeMap.size();
+ }
+ for (const auto& entry : kModeMap) {
+ if (entry.first < value) modes.push_back({entry.first, entry.second});
+ }
+ resultCb(modes);
+ return Void();
+}
+
+Return DisplayModes::getCurrentDisplayMode(getCurrentDisplayMode_cb resultCb) {
+ int32_t currentModeId = mDefaultModeId;
+ std::ifstream modeFile(kModePath);
+ int value;
+ modeFile >> value;
+ if (!modeFile.fail()) {
+ for (const auto& entry : kModeMap) {
+ if (value == entry.first) {
+ currentModeId = entry.first;
+ break;
+ }
+ }
+ }
+ resultCb({currentModeId, kModeMap.at(currentModeId)});
+ return Void();
+}
+
+Return DisplayModes::getDefaultDisplayMode(getDefaultDisplayMode_cb resultCb) {
+ resultCb({mDefaultModeId, kModeMap.at(mDefaultModeId)});
+ return Void();
+}
+
+Return DisplayModes::setDisplayMode(int32_t modeID, bool makeDefault) {
+ const auto iter = kModeMap.find(modeID);
+ if (iter == kModeMap.end()) {
+ return false;
+ }
+ std::ofstream modeFile(kModePath);
+ modeFile << iter->first;
+ if (modeFile.fail()) {
+ return false;
+ }
+
+ if (makeDefault) {
+ std::ofstream defaultFile(kDefaultPath);
+ defaultFile << iter->first;
+ if (defaultFile.fail()) {
+ return false;
+ }
+ mDefaultModeId = iter->first;
+ }
+ return true;
+}
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+} // namespace samsung
+} // namespace V2_0
+} // namespace livedisplay
+} // namespace lineage
+} // namespace vendor
diff --git a/livedisplay/DisplayModes.h b/livedisplay/DisplayModes.h
new file mode 100644
index 0000000..149edf3
--- /dev/null
+++ b/livedisplay/DisplayModes.h
@@ -0,0 +1,61 @@
+/*
+ * 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_DISPLAYMODES_H
+#define VENDOR_LINEAGE_LIVEDISPLAY_V2_0_DISPLAYMODES_H
+
+#include
+#include
+#include
+
+namespace vendor {
+namespace lineage {
+namespace livedisplay {
+namespace V2_0 {
+namespace samsung {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+class DisplayModes : public IDisplayModes {
+ public:
+ DisplayModes();
+ bool isSupported();
+
+ // Methods from ::vendor::lineage::livedisplay::V2_0::IDisplayModes follow.
+ Return getDisplayModes(getDisplayModes_cb resultCb) override;
+ Return getCurrentDisplayMode(getCurrentDisplayMode_cb resultCb) override;
+ Return getDefaultDisplayMode(getDefaultDisplayMode_cb resultCb) override;
+ Return setDisplayMode(int32_t modeID, bool makeDefault) override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+ private:
+ static const std::map kModeMap;
+ int32_t mDefaultModeId;
+};
+
+} // namespace samsung
+} // namespace V2_0
+} // namespace livedisplay
+} // namespace lineage
+} // namespace vendor
+
+#endif // VENDOR_LINEAGE_LIVEDISPLAY_V2_0_DISPLAYMODES_H
diff --git a/livedisplay/service.cpp b/livedisplay/service.cpp
index 78a0241..c1ee7bc 100644
--- a/livedisplay/service.cpp
+++ b/livedisplay/service.cpp
@@ -25,7 +25,9 @@
#include
#include "AdaptiveBacklight.h"
+#include "DisplayModes.h"
#include "SunlightEnhancement.h"
+#include "DisplayColorCalibration.h"
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
@@ -34,11 +36,15 @@ using android::status_t;
using android::OK;
using vendor::lineage::livedisplay::V2_0::samsung::AdaptiveBacklight;
+using vendor::lineage::livedisplay::V2_0::samsung::DisplayModes;
using vendor::lineage::livedisplay::V2_0::samsung::SunlightEnhancement;
+using vendor::lineage::livedisplay::V2_0::samsung::DisplayColorCalibration;
int main() {
sp adaptiveBacklight;
+ sp displayModes;
sp sunlightEnhancement;
+ sp displayColorCalibration;
status_t status;
LOG(INFO) << "LiveDisplay HAL service is starting.";
@@ -50,6 +56,11 @@ int main() {
goto shutdown;
}
+ displayModes = new DisplayModes();
+ if (displayModes == nullptr) {
+ LOG(ERROR) << "Can not create an instance of LiveDisplay HAL DisplayModes Iface, exiting.";
+ goto shutdown;
+ }
sunlightEnhancement = new SunlightEnhancement();
if (sunlightEnhancement == nullptr) {
@@ -58,6 +69,12 @@ int main() {
goto shutdown;
}
+ displayColorCalibration = new DisplayColorCalibration();
+ if (displayColorCalibration == nullptr) {
+ LOG(ERROR) << "Can not create an instance of LiveDisplay HAL DisplayColorCalibration "
+ "Iface, exiting.";
+ goto shutdown;
+ }
configureRpcThreadpool(1, true /*callerWillJoin*/);
@@ -70,6 +87,14 @@ int main() {
}
}
+ if (displayModes->isSupported()) {
+ status = displayModes->registerAsService();
+ if (status != OK) {
+ LOG(ERROR) << "Could not register service for LiveDisplay HAL DisplayModes Iface ("
+ << status << ")";
+ goto shutdown;
+ }
+ }
if (sunlightEnhancement->isSupported()) {
status = sunlightEnhancement->registerAsService();
@@ -81,6 +106,15 @@ int main() {
}
}
+ if (displayColorCalibration->isSupported()) {
+ status = displayColorCalibration->registerAsService();
+ if (status != OK) {
+ LOG(ERROR)
+ << "Could not register service for LiveDisplay HAL DisplayColorCalibration Iface ("
+ << status << ")";
+ goto shutdown;
+ }
+ }
LOG(INFO) << "LiveDisplay HAL service is ready.";
joinRpcThreadpool();