diff --git a/universal7885-common/apps/aidl-support/parts/default/Android.bp b/universal7885-common/apps/aidl-support/parts/default/Android.bp index 2aa259b..aa4651f 100644 --- a/universal7885-common/apps/aidl-support/parts/default/Android.bp +++ b/universal7885-common/apps/aidl-support/parts/default/Android.bp @@ -14,6 +14,7 @@ cc_binary { "libfileio", "vendor.eureka.hardware.parts-V1-ndk", ], + header_libs: ["logformat"], init_rc: ["vendor.eureka.hardware.parts-service.rc"], vintf_fragments: ["vendor.eureka.hardware.parts.xml"], } diff --git a/universal7885-common/apps/aidl-support/parts/default/Display.cpp b/universal7885-common/apps/aidl-support/parts/default/Display.cpp index 4441432..d1e00e6 100644 --- a/universal7885-common/apps/aidl-support/parts/default/Display.cpp +++ b/universal7885-common/apps/aidl-support/parts/default/Display.cpp @@ -12,31 +12,118 @@ // See the License for the specific language governing permissions and // limitations under the License. +#define LOG_TAG "PartsHAL-Display" + #include "Display.h" +#include +#include #include #include +#include namespace aidl::vendor::eureka::hardware::parts { constexpr const char *SEC_TSP_CMD = "/sys/class/sec/tsp/cmd"; +constexpr const char *SEC_TSP_CMD_RESULT = "/sys/class/sec/tsp/cmd_result"; + +static std::string DisplayStrBuilder(bool enable, DisplaySys type) { + std::stringstream builder; + switch (type) { + case DisplaySys::DOUBLE_TAP: + builder << "aot_enable"; + break; + case DisplaySys::GLOVE_MODE: + builder << "glove_mode"; + break; + }; + builder << ","; + builder << enable; // Implicit conversion + return builder.str(); +} + +enum DisplayResult { + OK, + NOOP, + INVALID, +}; + +constexpr const char *OK_STR = "OK"; +constexpr const char *NOOP_STR = "NOOP"; + +static DisplayResult parseResult(std::string *result, DisplaySys from) { + std::stringstream ss; + std::string parsed; + const std::function addEmpty = [](std::string *str) { + if (str->empty()) + *str = std::string("(empty)"); + }; + ss << DisplayStrBuilder(true, from); + ss << ":"; + if (result->find(ss.str()) == std::string::npos) { + LOG_E("Unexpected: Failed to find built string in result string"); + goto error; + } + parsed = result->substr(result->find(ss.str()) + 1); + if (parsed == OK_STR) { + return DisplayResult::OK; + } else if (parsed == NOOP_STR) { + return DisplayResult::NOOP; + } + addEmpty(&parsed); + LOG_E("Unexpected: Failed to parse by matching parsed result string"); + LOG_E("Parsed string was %s", parsed.c_str()); +error: + LOG_W("Falling back to find"); + if (result->find(OK_STR) != std::string::npos) + return DisplayResult::OK; + else if (result->find(NOOP_STR) != std::string::npos) + return DisplayResult::NOOP; + else { + addEmpty(result); + LOG_E("Failed to find result string in result string"); + LOG_E("Resulting string was: %s", result->c_str()); + return DisplayResult::INVALID; + } +} ::ndk::ScopedAStatus DisplayConfigs::writeDisplay(bool enable, DisplaySys type) { - std::string writevalue; - if (type == DisplaySys::DOUBLE_TAP) { - writevalue = "aot_enable"; - } else if (type == DisplaySys::GLOVE_MODE) { - writevalue = "glove_mode"; + FileIO::writeline(SEC_TSP_CMD, DisplayStrBuilder(enable, type)); + return ::ndk::ScopedAStatus::ok(); +} + +::ndk::ScopedAStatus DisplayConfigs::readDisplay(DisplaySys type, + bool *_aidl_return) { + std::string res; + writeDisplay(true, type); + res = FileIO::readline(SEC_TSP_CMD_RESULT); + switch (parseResult(&res, type)) { + case DisplayResult::NOOP: { + *_aidl_return = true; + break; } - writevalue += ","; - if (enable) { - writevalue += "1"; - } else { - writevalue += "0"; - } - FileIO::writeline(SEC_TSP_CMD, writevalue); + case DisplayResult::OK: { + writeDisplay(true, type); + res = FileIO::readline(SEC_TSP_CMD_RESULT); + switch (parseResult(&res, type)) { + case DisplayResult::NOOP: { + *_aidl_return = false; + writeDisplay(false, type); + break; + } + case DisplayResult::OK: { + LOG_W("Double enable returns OK: function not implemented."); + return ::ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); + } + case DisplayResult::INVALID: + return ::ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + }; + } break; + case DisplayResult::INVALID: + return ::ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); + }; return ::ndk::ScopedAStatus::ok(); } } // namespace aidl::vendor::eureka::hardware::parts diff --git a/universal7885-common/apps/aidl-support/parts/default/Display.h b/universal7885-common/apps/aidl-support/parts/default/Display.h index 091afe8..b8fb563 100644 --- a/universal7885-common/apps/aidl-support/parts/default/Display.h +++ b/universal7885-common/apps/aidl-support/parts/default/Display.h @@ -22,5 +22,6 @@ struct DisplayConfigs : public BnDisplayConfigs { // Methods from ::aidl::vendor::eureka::hardware::parts::IDisplayConfigs // follow. ::ndk::ScopedAStatus writeDisplay(bool enable, DisplaySys type); + ::ndk::ScopedAStatus readDisplay(DisplaySys type, bool *_aidl_return); }; } // namespace aidl::vendor::eureka::hardware::parts diff --git a/universal7885-common/apps/aidl-support/parts/vendor/eureka/hardware/parts/IDisplayConfigs.aidl b/universal7885-common/apps/aidl-support/parts/vendor/eureka/hardware/parts/IDisplayConfigs.aidl index a934c2e..30edadb 100644 --- a/universal7885-common/apps/aidl-support/parts/vendor/eureka/hardware/parts/IDisplayConfigs.aidl +++ b/universal7885-common/apps/aidl-support/parts/vendor/eureka/hardware/parts/IDisplayConfigs.aidl @@ -21,3 +21,4 @@ interface IDisplayConfigs { oneway void writeDisplay(in boolean enable, in DisplaySys type); boolean readDisplay(in DisplaySys type); } +