bootstrap: implement getDeviceTime command
authorWonki Kim <wonki_.kim@samsung.com>
Fri, 24 Apr 2020 10:03:11 +0000 (19:03 +0900)
committerWonki Kim <wonki_.kim@samsung.com>
Sat, 25 Apr 2020 05:58:37 +0000 (14:58 +0900)
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
libaurum/inc/IDevice.h
libaurum/inc/UiDevice.h
libaurum/src/DeviceImpl/TizenImpl.cc
libaurum/src/UiDevice.cc
org.tizen.aurum-bootstrap/meson.build
org.tizen.aurum-bootstrap/src/Commands/GetDeviceTimeCommand.cc
org.tizen.aurum-bootstrap/src/Commands/SyncCommand.cc
packaging/aurum.spec
protocol/aurum.proto
protocol/examples/python/testFeatures.py

index 8db32365652195d16bf8efd052e4a0658d6d30b3..f63803ada53d625702c4d80032449f5ceb78d7b7 100644 (file)
@@ -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);
index 29b01dee31d02d433b256d20cdfb192a1ff7840e..f942130d3b10540e5680284c9b296c01802fc3ba 100644 (file)
@@ -4,6 +4,11 @@
 
 #include <string>
 
+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
index 183fbab42fc6d743351a75b83b721e2e33127a87..bdfce02ad9bb400cbe049c26db7445e3f88e37c5 100644 (file)
@@ -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<UiSelector> selector) const override;
index d7af26497bd92bb51c4e32db4838f729f1159fa5..8fbf1b6a3d1b642b4837087bac3d7e6739b81bb3 100644 (file)
@@ -1,12 +1,15 @@
 #include "DeviceImpl/TizenImpl.h"
+#include <loguru.hpp>
 
 #include <functional>
 #include <tuple>
+#include <iostream>
+#include <memory>
 
 #include <stdlib.h>
-#include <iostream>
+#include <time.h>
+
 #include <Ecore.h>
-#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> clock;
+    if (type == TypeRequestType::MONOTONIC)
+        clock = std::make_unique<MonotonicClock>();
+    else if (type == TypeRequestType::WALLCLOCK)
+        clock = std::make_unique<WallClock>();
+
+    return clock->getTime();
+
+}
index 2c189aea59e3d967dd1f7ed83095bb58db56ba82..64fd6763e1ab60fde2d69b7deb92fde6ba6ea77d 100644 (file)
@@ -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);
+}
index 432745370bd03a8d9f02a616381b26ced52f7d34..f79be31713dde4bd7859fb5f771bc45fac37716b 100644 (file)
@@ -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
 
index 6f9c2a66ef429041aaa0893312f0411585283518..61d58ec6514460cc44a7c2466ce9a846651f7b33 100644 (file)
@@ -1,6 +1,12 @@
 #include "GetDeviceTimeCommand.h"
+
+#include <system_settings.h>
+#include <utils_i18n.h>
+
 #include <loguru.hpp>
 
+#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
index 9d092145c0ab5c4a8084a9fa8c958c6c6b41e35f..69066d772a33e614744b851bc31009b78f7bace2 100644 (file)
@@ -1,8 +1,7 @@
 #include "SyncCommand.h"
 #include <loguru.hpp>
 
-#include <AccessibleWatcher.h>
-#include <AccessibleNode.h>
+#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
index bfea344cd3f7baf5c65a1760f2669026c8dcf0e1..6b2030bed2644440826e83fcee49a63a6e3d5a24 100644 (file)
@@ -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
index d3d3140f728128b53acd4101405d5c4f2385d6cf..254690ba18b7f93b0232710816d236a603c972bb 100644 (file)
@@ -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{
index 5dd46287fa0f0af811a96f647f387c0357b0793d..6a383b32e4fe35fc2782e6a85fadc6baea0ac194 100644 (file)
@@ -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__':