From 3097f7058f8089a95ec8adc36f634517fa065f24 Mon Sep 17 00:00:00 2001 From: Wonki Kim Date: Fri, 24 Apr 2020 19:03:11 +0900 Subject: [PATCH] bootstrap: implement getDeviceTime command this patch implement getDeviceTime command. the command serves a caller 1ms resolution timestamp. which means a unit of return value present in ms unit. Change-Id: Ic9f4dfa12f1e5a95ceb35a27b710903dea41887b --- libaurum/inc/DeviceImpl/TizenImpl.h | 1 + libaurum/inc/IDevice.h | 6 ++ libaurum/inc/UiDevice.h | 4 +- libaurum/src/DeviceImpl/TizenImpl.cc | 54 ++++++++++- libaurum/src/UiDevice.cc | 7 +- org.tizen.aurum-bootstrap/meson.build | 2 + .../src/Commands/GetDeviceTimeCommand.cc | 107 ++++++++++++++++++++- .../src/Commands/SyncCommand.cc | 14 +-- packaging/aurum.spec | 2 + protocol/aurum.proto | 7 ++ protocol/examples/python/testFeatures.py | 11 ++- 11 files changed, 197 insertions(+), 18 deletions(-) diff --git a/libaurum/inc/DeviceImpl/TizenImpl.h b/libaurum/inc/DeviceImpl/TizenImpl.h index 8db3236..f63803a 100644 --- a/libaurum/inc/DeviceImpl/TizenImpl.h +++ b/libaurum/inc/DeviceImpl/TizenImpl.h @@ -31,6 +31,7 @@ public: bool pressPower() override; bool pressKeyCode(std::string keycode) override; bool takeScreenshot(std::string path, float scale, int quality) override; + long long getSystemTime(TypeRequestType type) override; protected: bool pressKeyCode(std::string keycode, unsigned int intv); diff --git a/libaurum/inc/IDevice.h b/libaurum/inc/IDevice.h index 29b01de..f942130 100644 --- a/libaurum/inc/IDevice.h +++ b/libaurum/inc/IDevice.h @@ -4,6 +4,11 @@ #include +enum class TypeRequestType { + WALLCLOCK, + MONOTONIC, +}; + class IDevice { public: virtual ~IDevice() {} @@ -26,5 +31,6 @@ public: virtual bool pressKeyCode(std::string keycode) = 0; virtual bool takeScreenshot(std::string path, float scale, int quality) = 0; + virtual long long getSystemTime(TypeRequestType type) = 0; }; #endif \ No newline at end of file diff --git a/libaurum/inc/UiDevice.h b/libaurum/inc/UiDevice.h index 183fbab..bdfce02 100644 --- a/libaurum/inc/UiDevice.h +++ b/libaurum/inc/UiDevice.h @@ -39,8 +39,8 @@ public: bool pressPower() override; bool pressKeyCode(std::string keycode) override; - - bool takeScreenshot(std::string path, float scale, int quality); + bool takeScreenshot(std::string path, float scale, int quality) override; + long long getSystemTime(TypeRequestType type) override; public: bool hasObject(const std::shared_ptr selector) const override; diff --git a/libaurum/src/DeviceImpl/TizenImpl.cc b/libaurum/src/DeviceImpl/TizenImpl.cc index d7af264..8fbf1b6 100644 --- a/libaurum/src/DeviceImpl/TizenImpl.cc +++ b/libaurum/src/DeviceImpl/TizenImpl.cc @@ -1,12 +1,15 @@ #include "DeviceImpl/TizenImpl.h" +#include #include #include +#include +#include #include -#include +#include + #include -#include "loguru.hpp" TizenImpl::TizenImpl() { @@ -236,3 +239,50 @@ bool TizenImpl::takeScreenshot(std::string path, float scale, int quality) { return false; } + +class Clock { +public: + virtual ~Clock(){}; + +public: + virtual long long getTime() = 0; +protected: + long long convertTime(struct timespec t){ + return (long long)t.tv_sec * 1000L + (long long)(t.tv_nsec / 1000000); + } +}; + +class MonotonicClock : public Clock { +public: + virtual ~MonotonicClock(){}; + + long long getTime() override { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + return convertTime(t); + } + +}; + +class WallClock : public Clock { +public: + virtual ~WallClock(){}; + + long long getTime() override { + struct timespec t; + clock_gettime(CLOCK_REALTIME, &t); + return convertTime(t); + } +}; + +long long TizenImpl::getSystemTime(TypeRequestType type) +{ + std::unique_ptr clock; + if (type == TypeRequestType::MONOTONIC) + clock = std::make_unique(); + else if (type == TypeRequestType::WALLCLOCK) + clock = std::make_unique(); + + return clock->getTime(); + +} diff --git a/libaurum/src/UiDevice.cc b/libaurum/src/UiDevice.cc index 2c189ae..64fd676 100644 --- a/libaurum/src/UiDevice.cc +++ b/libaurum/src/UiDevice.cc @@ -154,4 +154,9 @@ bool UiDevice::pressKeyCode(std::string keycode) bool UiDevice::takeScreenshot(std::string path, float scale, int quality) { return mDeviceImpl->takeScreenshot(path, scale, quality); -} \ No newline at end of file +} + +long long UiDevice::getSystemTime(TypeRequestType type) +{ + return mDeviceImpl->getSystemTime(type); +} diff --git a/org.tizen.aurum-bootstrap/meson.build b/org.tizen.aurum-bootstrap/meson.build index 4327453..f79be31 100644 --- a/org.tizen.aurum-bootstrap/meson.build +++ b/org.tizen.aurum-bootstrap/meson.build @@ -53,6 +53,8 @@ bootstrap_svr_dep += [ dependency('capi-appfw-app-manager'), dependency('capi-appfw-package-manager'), dependency('capi-appfw-service-application'), + dependency('capi-system-system-settings'), + dependency('capi-base-utils-i18n'), ] endif diff --git a/org.tizen.aurum-bootstrap/src/Commands/GetDeviceTimeCommand.cc b/org.tizen.aurum-bootstrap/src/Commands/GetDeviceTimeCommand.cc index 6f9c2a6..61d58ec 100644 --- a/org.tizen.aurum-bootstrap/src/Commands/GetDeviceTimeCommand.cc +++ b/org.tizen.aurum-bootstrap/src/Commands/GetDeviceTimeCommand.cc @@ -1,6 +1,12 @@ #include "GetDeviceTimeCommand.h" + +#include +#include + #include +#include "UiDevice.h" + GetDeviceTimeCommand::GetDeviceTimeCommand( const ::aurum::ReqGetDeviceTime* request, ::aurum::RspGetDeviceTime* response) @@ -8,9 +14,108 @@ GetDeviceTimeCommand::GetDeviceTimeCommand( { } +class TizenLocaleTimeConverter { +public: + static std::string convert(long long timestamp) + { + std::string time; + i18n_udatepg_h pattern_generator = NULL; + char* locale; + + if (SYSTEM_SETTINGS_ERROR_NONE != + system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_COUNTRY, + &locale)) + return time; + //dlog_print(DLOG_INFO, LOG_TAG, "Current Locale Country : %s\n", locale); + LOG_F(INFO, "%s", locale); + i18n_udatepg_create(locale, &pattern_generator); + + if (!pattern_generator) return time; + + i18n_uchar bestPattern[64] = { + 0, + }; + char bestPatternString[64] = { + 0, + }; + int bestPatternLength, len; + const char* custom_format = "EEE, MMM d, yyyy 'at' HH:mm:ss zzz"; + i18n_uchar uch_custom_format[64]; + + i18n_ustring_copy_ua(uch_custom_format, custom_format); + len = i18n_ustring_get_length(uch_custom_format); + i18n_udatepg_get_best_pattern(pattern_generator, uch_custom_format, len, + bestPattern, 64, &bestPatternLength); + i18n_ustring_copy_au_n(bestPatternString, bestPattern, 64); + //dlog_print(DLOG_INFO, LOG_TAG, "BestPattern(char[]) : %s \n", bestPatternString); + i18n_udatepg_destroy(pattern_generator); + + i18n_udate_format_h formatter_Current = NULL; + i18n_uchar formatted[64] = { + 0, + }; + char result[64] = { + 0, + }; + int formattedLength; + i18n_udate date; + char* timezone_Current; + i18n_uchar utf16_timezone_Current[64] = { + 0, + }; + + if (SYSTEM_SETTINGS_ERROR_NONE != + system_settings_get_value_string( + SYSTEM_SETTINGS_KEY_LOCALE_TIMEZONE, &timezone_Current)) + return time; + + i18n_ustring_copy_ua_n(utf16_timezone_Current, timezone_Current, + strlen(timezone_Current)); + if (I18N_ERROR_NONE != + i18n_udate_create(I18N_UDATE_PATTERN, I18N_UDATE_PATTERN, locale, + utf16_timezone_Current, -1, bestPattern, -1, + &formatter_Current)) + return time; + + if (utf16_timezone_Current) { + date = (i18n_udate)((double)(timestamp / 1000.0)); + i18n_udate_format_date(formatter_Current, date, formatted, 64, NULL, + &formattedLength); + i18n_ustring_copy_au_n(result, formatted, 64); + //dlog_print(DLOG_INFO, LOG_TAG, "Current Date : %s\n", result); + time = std::string{result}; + LOG_F(INFO, "%s", result); + } + i18n_udate_destroy(formatter_Current); + return time; + } +}; + ::grpc::Status GetDeviceTimeCommand::execute() { LOG_SCOPE_F(INFO, "GetDeviceTime --------------- "); - // ObjectMapper *mObjMap = ObjectMapper::getInstance(); + + UiDevice* obj = UiDevice::getInstance(DeviceType::DEFAULT); + ::aurum::ReqGetDeviceTime_TimeType type = mRequest->type(); + long long utcStampMs; + +//if (type == ::aurum::ReqGetAttribute_RequestType::ReqGetAttribute_RequestType_VISIBLE) + + switch (type) { + case ::aurum::ReqGetDeviceTime_TimeType::ReqGetDeviceTime_TimeType_WALLCLOCK: + utcStampMs = obj->getSystemTime(TypeRequestType::WALLCLOCK); + mResponse->set_localedatetime( + TizenLocaleTimeConverter::convert(utcStampMs)); + mResponse->set_timestamputc(utcStampMs); + break; + + case ::aurum::ReqGetDeviceTime_TimeType::ReqGetDeviceTime_TimeType_SYSTEM: + default: + utcStampMs = obj->getSystemTime(TypeRequestType::MONOTONIC); + mResponse->set_timestamputc(utcStampMs); + break; + } + + mResponse->set_status(::aurum::RspStatus::OK); return grpc::Status::OK; } \ No newline at end of file diff --git a/org.tizen.aurum-bootstrap/src/Commands/SyncCommand.cc b/org.tizen.aurum-bootstrap/src/Commands/SyncCommand.cc index 9d09214..69066d7 100644 --- a/org.tizen.aurum-bootstrap/src/Commands/SyncCommand.cc +++ b/org.tizen.aurum-bootstrap/src/Commands/SyncCommand.cc @@ -1,8 +1,7 @@ #include "SyncCommand.h" #include -#include -#include +#include "UiDevice.h" SyncCommand::SyncCommand(const ::aurum::ReqEmpty *request, ::aurum::RspEmpty * response) @@ -12,12 +11,9 @@ SyncCommand::SyncCommand(const ::aurum::ReqEmpty *request, ::grpc::Status SyncCommand::execute() { - LOG_SCOPE_F(INFO, "Sync Command "); - const AccessibleWatcher *accObj = AccessibleWatcher::getInstance(); - - auto root = accObj->getRootNode(); - LOG_F(INFO, "root node tree / depth : 2"); - root->print(0, 2); - + UiDevice *obj = UiDevice::getInstance(DeviceType::DEFAULT); + long long timeMs = obj->getSystemTime(TypeRequestType::WALLCLOCK); + LOG_SCOPE_F(INFO, "Sync Command @ %f", timeMs/1000.0); + // do post-command return grpc::Status::OK; } \ No newline at end of file diff --git a/packaging/aurum.spec b/packaging/aurum.spec index bfea344..6b2030b 100644 --- a/packaging/aurum.spec +++ b/packaging/aurum.spec @@ -26,6 +26,8 @@ BuildRequires: pkgconfig(capi-appfw-app-manager) BuildRequires: pkgconfig(capi-appfw-service-application) BuildRequires: pkgconfig(capi-system-device) BuildRequires: pkgconfig(libtzplatform-config) +BuildRequires: pkgconfig(capi-system-system-settings) +BuildRequires: pkgconfig(capi-base-utils-i18n) %if "%{?profile}" == "tv" %define __hash_signing 0 diff --git a/protocol/aurum.proto b/protocol/aurum.proto index d3d3140..254690b 100644 --- a/protocol/aurum.proto +++ b/protocol/aurum.proto @@ -309,9 +309,16 @@ message RspCloseApp{ // ------------------------------------ // message ReqGetDeviceTime{ + enum TimeType { + WALLCLOCK= 0; + SYSTEM = 1; + } + TimeType type = 1; } message RspGetDeviceTime{ RspStatus status = 1; + int64 timestampUTC = 2; + string localeDatetime = 3; } message ReqGetLocation{ diff --git a/protocol/examples/python/testFeatures.py b/protocol/examples/python/testFeatures.py index 5dd4628..6a383b3 100644 --- a/protocol/examples/python/testFeatures.py +++ b/protocol/examples/python/testFeatures.py @@ -242,8 +242,11 @@ def scrollToTest(stub): return False def getDeviceTimeTest(stub): - print('getDeviceTime command not implemented') - return False + response1 = stub.getDeviceTime(ReqGetDeviceTime(type='WALLCLOCK')) + response2 = stub.getDeviceTime(ReqGetDeviceTime(type='WALLCLOCK')) + + print(response1, response2) + return response2.timeStampUTC > response1.timeStampUTC; def getLocationTest(stub): print('getLocation command not implemented') @@ -279,6 +282,8 @@ def run(): with grpc.insecure_channel('127.0.0.1:50051') as channel: stub = BootstrapStub(channel) + runTest(stub, getDeviceTimeTest) + runTest(stub, findElementTest) runTest(stub, getValueTest) runTest(stub, getSizeTest) @@ -295,9 +300,9 @@ def run(): runTestWithoutSetupAndTearDown(stub, closeAppTest) runTestWithoutSetupAndTearDown(stub, removeAppTest) + runTest(stub, scrollToTest, alwaySucceed=True) runTest(stub, longClickTest, alwaySucceed=True) - runTest(stub, getDeviceTimeTest, alwaySucceed=True) runTest(stub, getLocationTest, alwaySucceed=True) if __name__ == '__main__': -- 2.7.4