Merge #1728 into sdk650 from refs/changes/1728/head 1730/target/1
authoraliyun3243248791 <accounts_67aaf52ad497cd558d73ac32@mail.teambition.com>
Tue, 22 Apr 2025 03:16:32 +0000 (03:16 +0000)
committer袁清梦 <3449750381@qq.com>
Tue, 22 Apr 2025 03:16:32 +0000 (03:16 +0000)
Code review from aliyun3243248791

* refs/changes/1728/head: (4 commits squashed)

  - 【省电模式】UI

  - 【睡眠】UI

  - 【计算器】UI

  - Merge branch &#39;sdk650&#39; of https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230 into sdk650

Signed-off-by: 薛文强 <accounts_67aaf52ad497cd558d73ac32@mail.teambition.com>
Merged-by: Caisking <3449750381@qq.com>
link: https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230/change/1728
33 files changed:
code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/include/CalculatorModel.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/include/CalculatorPresenter.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/include/CalculatorView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/src/CalculatorModel.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/src/CalculatorPresenter.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/src/CalculatorView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveBatPresenter.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveBatView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveEleModel.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveElePresenter.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveEleView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveBatPresenter.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveBatView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveEleModel.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveElePresenter.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveEleView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepCardView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepControlPresenter.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepControlView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepModel.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepModelC.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepNapView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepTimeView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepCardView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepControlPresenter.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepControlView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepModel.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepNapView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepTimeView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepView.cpp [new file with mode: 0644]
code/sdk/build/config/target_config/brandy/config.py
code/sdk/zhihui/utils/custom_fileoperate_service.c

diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/include/CalculatorModel.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/include/CalculatorModel.h
new file mode 100644 (file)
index 0000000..9412c33
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: CalculatorModel.h
+ * Author:
+ * Create: 2021-10-12
+ */
+#ifndef CALCULATOR_MODEL_H
+#define CALCULATOR_MODEL_H
+
+#include "los_mux.h"
+#include "string"
+#include "PhoneService.h"
+#include "AppViewIDs.h"
+#include "components/ui_label_ext.h"
+#include"ui_resource_string.h"
+#include "message.h"
+#include "msg_center.h"
+#include "stack"
+
+namespace OHOS {
+
+
+class CalculatorModel {
+public:
+    static CalculatorModel *GetInstance(void);
+   
+
+    void number_push_stack(double );
+    void symbol_push_stack(char symbol);
+    double  calculate_stack();
+    uint8_t get_stcak_size();
+    void  symbol_stack_top_uddata(char data);
+    void clean_stack();
+    void symbol_stack_pop(void);
+private:
+    CalculatorModel();
+    CalculatorModel(const CalculatorModel &);
+    virtual ~CalculatorModel();
+    std::stack<long double > numberStack;
+    std::stack<char>  symbolStack;
+   
+};
+}
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/include/CalculatorPresenter.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/include/CalculatorPresenter.h
new file mode 100644 (file)
index 0000000..8550f31
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: CalculatorPresenter.h
+ * Author:
+ * Create: 2021-10-12
+ */
+
+#ifndef CALCULATOR_PRESENTER_H
+#define CALCULATOR_PRESENTER_H
+
+#include "Presenter.h"
+#include "ohos_types.h"
+#include "CallerLogModel.h"
+//#include "BaseView.h"
+#include "cmsis_os.h"
+
+namespace OHOS {
+class CalculatorView;
+class CalculatorPresenter : public Presenter<CalculatorView>,
+                                public UIView::OnClickListener,
+                                public UIView::OnDragListener,
+                                public RootView::OnKeyActListener
+{
+public:
+    CalculatorPresenter();
+    ~CalculatorPresenter() override;
+
+    void OnStart() override;
+  
+    
+    static CalculatorPresenter *GetInstance(void);
+    bool OnClick(UIView &view, const ClickEvent &event) override;
+    bool OnKeyAct(UIView &view, const KeyEvent &event) override;
+    bool OnDragEnd(UIView &view, const DragEvent &event) override;
+   
+   
+private:
+
+};
+}
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/include/CalculatorView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/include/CalculatorView.h
new file mode 100644 (file)
index 0000000..f892a10
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: CalculatorView.h
+ * Author:
+ * Create: 2021-10-12
+ */
+
+#ifndef CALCULATOR_VIEW_H
+#define CALCULATOR_VIEW_H
+
+#include "View.h"
+#include "CalculatorPresenter.h"
+#include "CalculatorView.h"
+//#include "BaseView.h"
+#include "components/ui_view_group.h"
+#include "components/ui_image_animator.h"
+#include "components/ui_scroll_view.h"
+#include "components/ui_label.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_label_button.h"
+#include "components/ui_list.h"
+#include "components/abstract_adapter.h"
+#include "components/ui_image_view.h"
+
+#include "PhoneService.h"
+#include "vector.h"
+#include "ChangeSliceListener.h"
+#include "cmsis_os2.h"
+
+namespace OHOS {
+
+class CalculatorView :
+ public UIViewGroup, 
+public View<CalculatorPresenter> {
+public:
+    CalculatorView();
+    ~CalculatorView();
+
+   
+    void OnStart() override;
+    static CalculatorView *GetInstance();
+    void number_text_updata_buf(const char *buf);
+    void symbol_text_updata_buf(const char *buf);
+    void symbol_text_updata_single_buf(const char *buf);
+    void symbol_text_updata_calculate_buf(const char *buf);
+
+    void start_call_roll_timer();
+    void start_call_roll_timer_move();
+    
+    void show_hint_label(bool data);
+    
+    void show_long_label();
+    bool string_have_dot(std::string buf);
+
+    osTimerId_t call_roll_timer=NULL;
+    osTimerId_t call_roll_timer_move=NULL;
+
+private:
+    uint8_t number_falg=0;
+    bool button_init();
+    bool Label_init();
+    UILabelButton *Button[20]={nullptr};
+
+    UIImageView *image1_{nullptr};
+
+    UIViewGroup *group{nullptr};
+    UILabel *number{nullptr};
+    UILabelExt *hint{nullptr};
+
+    std::string number_string=" ";
+
+    UIView::OnClickListener* clickLeftListener{nullptr};
+    UIView:: OnDragListener* dragListener{nullptr};
+
+    
+};
+}
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/src/CalculatorModel.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/src/CalculatorModel.cpp
new file mode 100644 (file)
index 0000000..c2a67bd
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: CalculatorModel.cpp
+ * Author:
+ * Create: 2021-10-12
+ */
+#include "DialingScreenView.h"
+
+#include "service_id_define.h"
+#include "cmsis_os.h"
+#include "samgr_lite.h"
+#include "calculator/include/CalculatorModel.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+using namespace OHOS;
+
+
+static bool g_isWatchCallView = false;
+
+CalculatorModel::CalculatorModel()
+{
+
+}
+
+CalculatorModel::~CalculatorModel()
+{
+
+}
+
+
+void CalculatorModel:: number_push_stack(double data)
+{
+    // printf("%lf\r\n",data);
+    if(!symbolStack.empty())
+    {
+        if(symbolStack.top()=='-')
+        {
+            char symbol_= symbolStack.top();
+            symbolStack.pop();
+            data=-data;
+            symbolStack.push('+');
+
+        }
+    }
+    numberStack.push(data);
+}
+
+
+void CalculatorModel:: symbol_stack_top_uddata(char data)
+{
+    // printf("%c\r\n",data);
+    if(!symbolStack.empty())
+    {
+        symbolStack.pop();
+        symbolStack.push(data);
+    }
+}
+
+
+void CalculatorModel:: symbol_stack_pop(void)
+{
+    if(!symbolStack.empty())
+    {
+        symbolStack.pop();
+    }
+}
+
+uint8_t CalculatorModel::get_stcak_size()
+{
+    return numberStack.size();
+}
+
+void  CalculatorModel:: symbol_push_stack(char symbol)
+{
+    // printf("%c\r\n",symbol);
+
+    if(numberStack.empty())
+    {
+        return ;
+    }
+    symbolStack.push(symbol);
+    return ;
+       
+}
+
+void CalculatorModel:: clean_stack()
+{
+    while (!numberStack.empty())
+    {
+       numberStack.pop();
+    }
+
+    while (!symbolStack.empty())
+    {
+       symbolStack.pop();
+    }
+}
+
+double  CalculatorModel:: calculate_stack()
+{
+    double  sum=0;
+    if(numberStack.empty())
+    return sum;
+    double  number_1= numberStack.top();
+    numberStack.pop();
+    sum=number_1;
+    while (!numberStack.empty())
+    {
+        double  number_= numberStack.top();
+        numberStack.pop();
+
+        if(symbolStack.empty())
+        break;
+        char symbol= symbolStack.top();
+        if(symbol=='+')
+        {
+            sum+=number_;
+        }
+        if(symbol=='x')
+        {
+            sum*=number_;
+        }
+        if(symbol=='-')
+        {
+            sum=-number_;
+        }
+        if(symbol=='/')
+        {
+            if(sum==0)
+            {
+                return sum;
+            }
+            sum=number_/sum;
+        }
+        // printf("sum:%lf\r\n",sum);
+    }
+    return sum;
+}
+
+
+CalculatorModel *CalculatorModel::GetInstance(void)
+{
+    static CalculatorModel callLogModel;
+    return &callLogModel;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/src/CalculatorPresenter.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/src/CalculatorPresenter.cpp
new file mode 100644 (file)
index 0000000..e216299
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: CalculatorPresenter.cpp
+ * Author:
+ * Create: 2021-10-12
+ */
+
+#include "calculator/include/CalculatorPresenter.h"
+#include "calculator/include/CalculatorView.h"
+#include "gfx_utils/mem_check.h"
+#include "common/key_code.h"
+#include "custom_utils.h"
+#include "NativeRegisterManager.h"
+#include "uicomponents/UIComponents.h"
+namespace OHOS {
+
+  REGIST_MENU_PRO( VIEW_CALCULATOR, CalculatorView, CalculatorPresenter,
+    PNG_APPLIST_INFORMATION_IMAGE_BIG, PNG_APPLIST_INFORMATION_IMAGE, PNG_APPLIST_INFORMATION_IMAGE, "计算器", STR_CALCULATOR);
+
+static CalculatorPresenter *g_pMainView = nullptr;
+CalculatorPresenter::CalculatorPresenter()
+{
+    g_pMainView = this;
+#ifdef MEM_CHECK
+        MemCheck::GetInstance()->EnableLeakCheck(true);
+#endif
+}
+
+CalculatorPresenter::~CalculatorPresenter()
+{
+    g_pMainView = nullptr;
+#ifdef MEM_CHECK
+        MemCheck::GetInstance()->EnableLeakCheck(false);
+#endif
+}
+
+CalculatorPresenter *CalculatorPresenter::GetInstance(void)
+{
+    return g_pMainView;
+}
+
+void CalculatorPresenter::OnStart()
+{
+    Presenter<CalculatorView>::OnStart();
+}
+
+
+
+
+bool CalculatorPresenter::OnClick(UIView &view, const ClickEvent &event)
+{
+    UNUSED(event);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "OnClick %s",view.GetViewId());
+    if (strcmp(view.GetViewId(), "0") == 0) {
+        CalculatorView::GetInstance()->number_text_updata_buf(view.GetViewId());
+        return true;
+    } 
+    else if (strcmp(view.GetViewId(), "1") == 0)
+    {
+        CalculatorView::GetInstance()->number_text_updata_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), "2") == 0)
+    {
+        CalculatorView::GetInstance()->number_text_updata_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), "3") == 0)
+    {
+        CalculatorView::GetInstance()->number_text_updata_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), "4") == 0)
+    {
+        CalculatorView::GetInstance()->number_text_updata_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), "5") == 0)
+    {
+        CalculatorView::GetInstance()->number_text_updata_buf(view.GetViewId());
+        return true;
+    }
+
+    else if (strcmp(view.GetViewId(), "6") == 0)
+    {
+        CalculatorView::GetInstance()->number_text_updata_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), "7") == 0)
+    {
+        CalculatorView::GetInstance()->number_text_updata_buf(view.GetViewId());
+        return true;
+    }else if (strcmp(view.GetViewId(), "8") == 0)
+    {
+        CalculatorView::GetInstance()->number_text_updata_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), "9") == 0)
+    {
+        CalculatorView::GetInstance()->number_text_updata_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), ".") == 0)
+    {
+        CalculatorView::GetInstance()->number_text_updata_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), "÷") == 0)
+    {
+        CalculatorView::GetInstance()->symbol_text_updata_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), "x") == 0)
+    {
+        CalculatorView::GetInstance()->symbol_text_updata_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), "+") == 0)
+    {
+        CalculatorView::GetInstance()->symbol_text_updata_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), "-") == 0)
+    {
+        CalculatorView::GetInstance()->symbol_text_updata_buf(view.GetViewId());
+        return true;
+    }
+     else if (strcmp(view.GetViewId(), "C") == 0)
+    {
+        CalculatorView::GetInstance()->symbol_text_updata_single_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), "%") == 0)
+    {
+        CalculatorView::GetInstance()->symbol_text_updata_single_buf(view.GetViewId());
+        return true;
+    }
+    else if (strcmp(view.GetViewId(), "=") == 0)
+    {
+        CalculatorView::GetInstance()->symbol_text_updata_calculate_buf(view.GetViewId());
+        return true;
+    }
+     else if (strcmp(view.GetViewId(),"D") == 0)
+    {
+        CalculatorView::GetInstance()->symbol_text_updata_single_buf(view.GetViewId());
+        return true;
+    }
+
+    return false;
+}
+
+bool CalculatorPresenter::OnDragEnd(OHOS::UIView& view, const OHOS::DragEvent& event)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "MainCallingPresenter OnDragEnd");
+    if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT)
+    { 
+        if(event.GetPreLastPoint().x-event.GetStartPoint().x>150) 
+        NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+    }
+    return true;
+}
+
+bool CalculatorPresenter::OnKeyAct(UIView &view, const KeyEvent &event)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AlipayPresenter::OnKeyAct");
+    uint16 keyID = event.GetKeyId();
+    uint16_t keyState = event.GetState();
+    // 如果是power键就返回上一级
+    if (keyID == static_cast<uint16_t>(ZliteKeyCode::ZLITE_KEY_POWER) &&  keyState == 1 && uapi_get_screen_state() == 0)
+    {
+        uint16_t preSlice = NativeAbility::GetInstance().GetPreSliceId();
+        NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+    }
+    return true;
+
+}
+}
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/src/CalculatorView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/calculator/src/CalculatorView.cpp
new file mode 100644 (file)
index 0000000..d032f7b
--- /dev/null
@@ -0,0 +1,669 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: CalculatorView.cpp
+ * Author:
+ * Create: 2021-10-12
+ */
+
+#include "calculator/include/CalculatorView.h"
+#include "calculator/include/CalculatorPresenter.h"
+#include "calculator/include/CalculatorModel.h"
+#include "wearable_log.h"
+#include <math.h>
+#include <iostream>
+#include <iomanip>
+
+namespace OHOS {
+
+static CalculatorView *g_pMainView = nullptr;
+CalculatorView::CalculatorView()
+{
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "::CalculatorView::CalculatorView ");
+    g_pMainView = this;
+}
+
+CalculatorView::~CalculatorView()
+{
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "::CalculatorView::~CalculatorView ");
+    RootView::GetInstance()->ClearOnKeyActListener();
+    g_pMainView = nullptr;
+    group->RemoveAll();
+    if(number)
+    {
+        delete number;
+        number =nullptr;
+    }
+    for(int i=0;i<20;i++)
+    {
+        if(Button[i])
+        {
+            delete Button[i];
+            Button[i] =nullptr;
+        }
+    }
+    if(image1_)
+    {
+        delete image1_;
+        image1_=nullptr;
+    }
+    if(hint)
+    {
+        delete hint;
+        hint=nullptr;
+    }
+    if(group)
+    {
+        delete group;
+        group =nullptr;
+    }
+
+    if(call_roll_timer)
+    {
+        osTimerStop(call_roll_timer);
+        osTimerDelete(call_roll_timer);
+        call_roll_timer = NULL;
+    }
+
+    if(call_roll_timer_move)
+    {
+        osTimerStop(call_roll_timer_move);
+        osTimerDelete(call_roll_timer_move);
+        call_roll_timer_move = NULL; 
+    }
+
+}
+static int8_t  roll_falg=0;//0.1s一次变换
+
+static int8_t  roll_falg_2=0;//0.1s一次变换
+
+ static void  label_Timer_CallBack(int data)
+{
+    roll_falg--;
+    if(roll_falg<=0)
+    {
+        if(CalculatorView::GetInstance())
+        {
+            GraphicService::GetInstance()->PostGraphicEvent(std::bind(&CalculatorView::show_hint_label, CalculatorView::GetInstance(),false));
+        }
+       
+
+        if(g_pMainView->call_roll_timer)
+        {
+            osTimerStop(g_pMainView->call_roll_timer);
+            osTimerDelete(g_pMainView->call_roll_timer);
+            g_pMainView->call_roll_timer = NULL;
+        }
+    }
+}
+
+static void  label_Timer_CallBack_move(int data)
+{
+    roll_falg_2--;
+    if(roll_falg_2<=0)
+    {
+        if(CalculatorView::GetInstance())
+        {
+            GraphicService::GetInstance()->PostGraphicEvent(std::bind(&CalculatorView::show_long_label, CalculatorView::GetInstance()));
+        }
+
+        if(g_pMainView->call_roll_timer_move)
+        {
+            osTimerStop(g_pMainView->call_roll_timer_move);
+            osTimerDelete(g_pMainView->call_roll_timer_move);
+            g_pMainView->call_roll_timer_move = NULL;
+        }
+    }
+}
+
+
+
+CalculatorView *CalculatorView::GetInstance()
+{
+    return g_pMainView;
+}
+
+
+void CalculatorView::show_hint_label(bool data)
+{
+    hint->SetVisible(data);
+    Invalidate();
+}
+
+void CalculatorView::show_long_label(void)
+{
+    number->SetText(number_string.c_str());
+    number->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER);
+
+    Invalidate();
+}
+
+void CalculatorView::start_call_roll_timer()
+{
+    uint32_t tick;
+    osStatus_t retTimer;
+    if(call_roll_timer)
+    {
+        roll_falg=10;
+    }
+    else
+    {
+        roll_falg=10;
+
+        call_roll_timer = osTimerNew((osTimerFunc_t)label_Timer_CallBack, osTimerPeriodic, NULL, NULL);
+        tick =100;// osMs2Tick(1000);
+        retTimer = osTimerStart(call_roll_timer, tick);
+        if (retTimer != osOK && call_roll_timer != NULL) {
+            osTimerDelete(call_roll_timer);
+            call_roll_timer = NULL;
+            return ;
+        }
+    }
+}
+
+
+void CalculatorView::start_call_roll_timer_move()
+{
+    uint32_t tick;
+    osStatus_t retTimer;
+    if(call_roll_timer_move)
+    {
+        roll_falg_2=15;
+    }
+    else
+    {
+        roll_falg_2=15;
+
+        call_roll_timer_move = osTimerNew((osTimerFunc_t)label_Timer_CallBack_move, osTimerPeriodic, NULL, NULL);
+        tick =100;// osMs2Tick(1000);
+        retTimer = osTimerStart(call_roll_timer_move, tick);
+        if (retTimer != osOK && call_roll_timer_move != NULL) {
+            osTimerDelete(call_roll_timer_move);
+            call_roll_timer_move = NULL;
+            return ;
+        }
+    }
+}
+
+bool CalculatorView::string_have_dot(std::string buf)
+{
+    for(int i=0;i<buf.length();i++)
+    {
+        if(buf.c_str()[i]=='.')
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+
+void CalculatorView::number_text_updata_buf(const char *buf)
+{
+  
+    char new_buf[64]={0};
+    const char*text_buf=NULL;
+
+    if(number_falg!=1)
+    number_string="";
+
+    if(buf[0]=='.' && string_have_dot(number_string))
+    {
+        return;
+    }
+
+
+    if(number_string.length()>15)
+    {
+        //超出长度限制
+        start_call_roll_timer();
+        show_hint_label(true);
+        return;
+    }
+
+    number_string=number_string+buf;
+
+    // if(number_string.length()>12)
+    // {
+    //     number->SetText(number_string.c_str()+number_string.length()-12);
+    //     number->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER);
+    //     number_falg=1;
+    //     start_call_roll_timer_move();
+    //     Invalidate();
+    //     return;
+    // }
+
+    number->SetText(number_string.c_str());
+    number->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER);
+
+    number_falg=1;
+
+    Invalidate();
+    return;
+}
+
+void CalculatorView::symbol_text_updata_buf(const char *buf)
+{
+
+    if(g_pMainView->call_roll_timer_move)
+    {
+        osTimerStop(g_pMainView->call_roll_timer_move);
+        osTimerDelete(g_pMainView->call_roll_timer_move);
+        g_pMainView->call_roll_timer_move = NULL;
+    }
+
+    char new_buf[64]={0};
+    
+    std::string text_buf=number_string;
+    if(number_falg==0)
+    {
+       if(strcmp(buf,"÷")==0)
+        CalculatorModel::GetInstance()->symbol_stack_top_uddata('/');
+        else
+        CalculatorModel::GetInstance()->symbol_stack_top_uddata(buf[0]);
+
+        number_string=new_buf;
+        number->SetText(buf);
+        number->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER);
+
+       Invalidate();
+        return;
+    }
+    double number_float=strtod(text_buf.c_str(),NULL);
+    // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%lf %s",number_float,text_buf.c_str());
+
+    char new_buf_[64]={0};
+    sprintf_s(new_buf_,64,"%.010lf",number_float);
+    number_float=strtod(new_buf_,NULL);
+
+    CalculatorModel::GetInstance()->number_push_stack(number_float);
+
+    if( CalculatorModel::GetInstance()->get_stcak_size()>=2)
+    {
+        number_float =CalculatorModel::GetInstance()->calculate_stack();
+        CalculatorModel::GetInstance()->number_push_stack(number_float);
+        Invalidate();
+
+    }
+
+    sprintf_s(new_buf,64,"%s",buf);
+
+    number_string=new_buf;
+    number->SetText(new_buf);
+    number->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER);
+
+   Invalidate();
+    
+    if(strcmp(buf,"÷")==0)
+    CalculatorModel::GetInstance()->symbol_push_stack('/');
+    else
+    CalculatorModel::GetInstance()->symbol_push_stack(buf[0]);
+
+    number_falg=0;
+
+    return;
+}
+
+void CalculatorView::symbol_text_updata_single_buf(const char *buf)
+{
+    if(g_pMainView->call_roll_timer_move)
+    {
+        osTimerStop(g_pMainView->call_roll_timer_move);
+        osTimerDelete(g_pMainView->call_roll_timer_move);
+        g_pMainView->call_roll_timer_move = NULL;
+    }
+
+    char new_buf[64]={0};
+
+    std::string text_buf=number_string;
+   
+    double number_float=strtod(text_buf.c_str(),NULL);
+    if(buf[0]=='C')
+    {
+        CalculatorModel::GetInstance()->clean_stack();
+        number->SetText("");
+        number_string="";
+        Invalidate();
+    }
+    else if (buf[0]=='%')
+    {
+    number_float=0.01*number_float;
+
+    double number_float_=number_float;
+    int decimal_places = 0;
+    double frac;
+
+    while (modf(number_float_ * pow(10, decimal_places), &frac) != 0.0f) 
+    {
+        decimal_places++;
+    }
+
+    // printf("该浮点数的小数部分有 %d %lf 位。\n", decimal_places,number_float);
+    switch (decimal_places)
+    {
+        case 0:
+            sprintf_s(new_buf,64,"%.00lf",number_float);
+            break;
+        case 1:
+            sprintf_s(new_buf,64,"%.01lf",number_float);
+            break;
+        case 2:
+            sprintf_s(new_buf,64,"%.02lf",number_float);
+            break;
+        case 3:
+            sprintf_s(new_buf,64,"%.03lf",number_float);
+            break;
+        case 4:
+            sprintf_s(new_buf,64,"%.04lf",number_float);
+            break;
+        case 6:
+            sprintf_s(new_buf,64,"%.06lf",number_float);
+            break;
+        case 7:
+            sprintf_s(new_buf,64,"%.07lf",number_float);
+            break;
+        case 8:
+            sprintf_s(new_buf,64,"%.08lf",number_float);
+            break;
+        default:
+            sprintf_s(new_buf,64,"%.09lf",number_float);
+            break;
+    }
+        number_string=new_buf;
+        number->SetText(new_buf);
+        number->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER);
+        Invalidate();
+    }
+    else if (buf[0]=='D')
+    {
+        number_string.pop_back();
+        number->SetText(number_string.c_str());
+        number->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER);
+        if(number_falg==0)
+        {
+            CalculatorModel::GetInstance()->symbol_stack_pop();
+            number_falg=1;
+        }
+        else 
+        {
+            number_falg=1;
+        }
+        
+       
+       Invalidate();
+    }
+
+    return;
+}
+
+void CalculatorView::symbol_text_updata_calculate_buf(const char *buf)
+{
+    if(g_pMainView->call_roll_timer_move)
+    {
+        osTimerStop(g_pMainView->call_roll_timer_move);
+        osTimerDelete(g_pMainView->call_roll_timer_move);
+        g_pMainView->call_roll_timer_move = NULL;
+    }
+
+    char new_buf[64]={0};
+    std::string text_buf=number_string;
+    double number_float=0;
+
+    if(text_buf[0]>='0' && text_buf[0]<='9')
+    {
+        number_float=strtod(text_buf.c_str(),NULL);
+        char new_buf_[64]={0};
+        sprintf_s(new_buf_,64,"%.010lf",number_float);
+        number_float=strtod(new_buf_,NULL);
+
+        CalculatorModel::GetInstance()->number_push_stack(number_float);
+    }
+    
+    number_float =CalculatorModel::GetInstance()->calculate_stack();
+
+    char new_buf_[64]={0};
+    sprintf_s(new_buf_,64,"%.010lf",number_float);
+    number_float=strtod(new_buf_,NULL);
+
+    double number_float_=number_float;
+    int decimal_places = 0;
+    double frac;
+
+    while (modf(number_float_ * pow(10, decimal_places), &frac) != 0.0f) 
+    {
+        decimal_places++;
+    }
+    switch (decimal_places)
+    {
+    case 0:
+        sprintf_s(new_buf,64,"%.00lf",number_float);
+        break;
+    case 1:
+        sprintf_s(new_buf,64,"%.01lf",number_float);
+        break;
+    case 2:
+        sprintf_s(new_buf,64,"%.02lf",number_float);
+        break;
+    case 3:
+        sprintf_s(new_buf,64,"%.03lf",number_float);
+        break;
+    case 4:
+        sprintf_s(new_buf,64,"%.04lf",number_float);
+        break;
+     case 6:
+        sprintf_s(new_buf,64,"%.06lf",number_float);
+        break;
+    case 7:
+        sprintf_s(new_buf,64,"%.07lf",number_float);
+        break;
+    case 8:
+        sprintf_s(new_buf,64,"%.08lf",number_float);
+        break;
+    default:
+        sprintf_s(new_buf,64,"%.09lf",number_float);
+        break;
+    }
+
+    // CalculatorModel::GetInstance()->number_push_stack(number_float);
+    number_falg=2;
+
+    number_string=new_buf;
+
+    number->SetText(new_buf);
+    number->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER);
+    Invalidate();
+
+
+    // number->SetText("");
+    return;
+}
+
+
+
+
+static char *dial_id_str[]={"7","8","9","C","%","4","5","6","÷","x","1","2","3","-","+","","0",".","=",""};
+
+bool CalculatorView::button_init()
+{
+    uint8_t showdial_i=0;
+    for(int i=0;i<4;i++)
+    {
+        for(int j=0;j<5;j++)
+        {
+            if(showdial_i==15 || showdial_i==19)
+            {
+                showdial_i++;
+                continue;
+            }
+            if (Button[showdial_i] == nullptr) {
+                Button[showdial_i] = new UILabelButton();
+            }
+            if(Button[showdial_i]==nullptr)
+            {
+                    return false;
+            }
+            Button[showdial_i]->SetPosition(17+(j*88), 140+(i*68));         // widget's left position and top position
+
+            Button[showdial_i]->Resize(80, 60);          // widget's width and height
+            Button[showdial_i]->SetViewId(dial_id_str[showdial_i]);// Set style
+            
+            Button[showdial_i]->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+            Button[showdial_i]->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff191919, UIButton::PRESSED);
+            if(j>2)
+            {
+                Button[showdial_i]->SetStyle(STYLE_BACKGROUND_COLOR, 0xFFFF8A36);
+                Button[showdial_i]->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xFFFF8A36, UIButton::PRESSED);
+                if(i==0)
+                {
+                    Button[showdial_i]->SetStyle(STYLE_BACKGROUND_COLOR, 0xFFAAAAAA);
+                    Button[showdial_i]->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xFFAAAAAA, UIButton::PRESSED);
+                }
+            }
+
+            Button[showdial_i]->SetText(dial_id_str[showdial_i]);
+            Button[showdial_i]->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 40);
+          
+
+            group->Add(Button[showdial_i]);
+            Button[showdial_i]->SetVisible(true);
+
+            clickLeftListener = (UIView::OnClickListener*)OHOS::CalculatorPresenter::GetInstance();
+            if (clickLeftListener == nullptr) {
+                return false;
+            }
+
+            Button[showdial_i]->SetOnClickListener(clickLeftListener);
+
+            showdial_i++;
+        }
+    }
+
+    return true;
+}
+
+bool CalculatorView::Label_init()
+{
+     if (number == nullptr) {
+        number = new UILabel();
+    }
+    if(number==nullptr)
+    {
+        return false;
+    }
+    number->SetPosition(65, 73);         // widget's left position and top position
+    number->Resize(310, 60);          // widget's width and height
+    number->SetViewId("label5");// Set style
+    number->SetStyle(STYLE_TEXT_FONT, 50);
+
+    // Set additional property
+    number->SetText("");
+    number->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE);
+    number->SetAlign(TEXT_ALIGNMENT_RIGHT, TEXT_ALIGNMENT_CENTER);
+    number->SetRollSpeed(0);
+    number->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 50);
+
+    // Add to rootView
+    group->Add(number);
+
+    number->SetVisible(true);
+
+    if (image1_ == nullptr) {
+        image1_ = new UIImageView();
+    }
+    image1_->SetPosition(378, 85);         // widget's left position and top position
+    image1_->Resize(60, 60);          // widget's width and height
+    image1_->SetViewId("D");// Set style
+    image1_->SetAutoEnable(false);
+    image1_->SetResizeMode(UIImageView::CENTER);
+
+
+    char* DimagesPath = "/user/res/Vector.bin";
+
+    image1_->SetSrc(DimagesPath);
+    clickLeftListener = (UIView::OnClickListener*)OHOS::CalculatorPresenter::GetInstance();
+    if (clickLeftListener == nullptr) {
+        return false;
+    }
+
+    image1_->SetOnClickListener(clickLeftListener);
+    image1_->SetTouchable(true);
+    // Add to rootView
+    group->Add(image1_);
+
+    image1_->SetVisible(true);
+
+
+      if (hint == nullptr) {
+        hint = new UILabelExt();
+    }
+    hint->SetPosition(109, 169);         // widget's left position and top position
+    hint->Resize(247, 60);          // widget's width and height
+    hint->SetViewId("label2");// Set style
+    hint->SetStyle(STYLE_BACKGROUND_COLOR, 0xff191919);
+    hint->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+    hint->SetStyle(STYLE_BORDER_RADIUS, 25);
+    hint->SetStyle(STYLE_PADDING_BOTTOM, 8);
+    hint->SetStyle(STYLE_TEXT_FONT, 30);
+    hint->SetStyle(STYLE_LINE_HEIGHT, 20);
+
+    // Set additional property
+    hint->SetTextId(STR_NUM_LENGTH);
+    hint->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE);
+    hint->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+    hint->SetRollSpeed(0);
+    hint->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
+    group->Add(hint);
+    hint->SetVisible(false);
+
+
+    return true;
+}
+
+void CalculatorView::OnStart()
+{
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CalculatorView::OnStart");
+    View<CalculatorPresenter>::OnStart();
+
+    AddViewToRootContainer(new UIViewGroup());
+    GetRootContainer()->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+    GetRootContainer()->SetTouchable(true);
+    GetRootContainer()->SetDraggable(true);
+
+    RootView::OnKeyActListener *keyactListener = (RootView::OnKeyActListener *)OHOS::CalculatorPresenter::GetInstance();
+    RootView::GetInstance()->SetOnKeyActListener(keyactListener);
+
+    group = new UIViewGroup();
+    if (group == nullptr) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CallingView::UIViewGroup::new group error");
+        return ;
+    }
+    group->SetPosition(0, 0);
+    group->Resize(VERTICAL_RESOLUTION, HORIZONTAL_RESOLUTION); // 454 : value
+    group->SetTouchable(true);
+    group->SetDraggable(true);
+    
+    dragListener = (UIView::OnDragListener*)OHOS::CalculatorPresenter::GetInstance();
+    if (dragListener == nullptr) {
+
+        return;
+    }
+    group->SetOnDragListener(dragListener);
+    AddViewToRootContainer(group);
+
+    if(!button_init())
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CallingView::UIViewGroup::new group error");
+        return;
+    }
+    if(!Label_init())
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CallingView::UIViewGroup::new group error");
+        return;
+    }
+
+
+}
+
+
+
+
+}
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveBatPresenter.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveBatPresenter.h
new file mode 100644 (file)
index 0000000..9b02bd0
--- /dev/null
@@ -0,0 +1,59 @@
+/***\r
+ * @Date: 2024-04-15 10:55:58\r
+ * @LastEditors: Caisking 3449750381@qq.com\r
+ * @LastEditTime: 2024-09-06 17:43:45\r
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/saveele/include/SaveBatPresenter.h\r
+ */\r
+\r
+#ifndef _SAVEBAT_PRESENTER_H\r
+#define _SAVEBAT_PRESENTER_H\r
+\r
+#include "Presenter.h"\r
+#include "saveele/include/SaveBatPresenter.h"\r
+#include "saveele/include/SaveEleModel.h"\r
+#include "saveele/include/SaveBatView.h"\r
+#include "ModelListenerSample.h"\r
+#include "MainModel.h"\r
+\r
+namespace OHOS\r
+{\r
+    class SaveBatView;\r
+\r
+    class SaveBatPresenter : public Presenter<SaveBatView>,\r
+                             public UIView::OnClickListener,\r
+                             public UIView::OnDragListener,\r
+                             public UIView::OnLongPressListener,\r
+                             public ModelListenerSample,\r
+                             public UIView::OnTouchListener,\r
+                             public RootView::OnKeyActListener\r
+    {\r
+    public:\r
+        SaveBatPresenter();\r
+        virtual ~SaveBatPresenter();\r
+\r
+        void OnStart() override;\r
+\r
+        static SaveBatPresenter *GetInstance();\r
+\r
+        void OnTickEvent() override;\r
+        void Notify() override {}\r
+        void ResetTickTimer();\r
+\r
+        void ExitView(void);\r
+        void Refresh_Back_View();\r
+\r
+    private:\r
+        bool OnPress(UIView &view, const PressEvent &event);\r
+        bool OnRelease(UIView &view, const ReleaseEvent &event);\r
+        bool OnKeyAct(UIView &view, const KeyEvent &event) override; // 增加按键事件\r
+        \r
+        uint64_t startTime{0};\r
+        int count = 3;         // 初始计数\r
+        int progressValue = 0; // 初始进度值\r
+        uint16_t drag_x = 0;\r
+        uint16_t drag_y = 0;\r
+    };\r
+\r
+} // namespace OHOS\r
+\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveBatView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveBatView.h
new file mode 100644 (file)
index 0000000..79bbe43
--- /dev/null
@@ -0,0 +1,137 @@
+/***\r
+ * @Date: 2024-04-15 10:55:58\r
+ * @LastEditors: Caisking 3449750381@qq.com\r
+ * @LastEditTime: 2024-08-19 15:07:03\r
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/saveele/include/SaveBatView.h\r
+ */\r
+/***\r
+ * @Date: 2024-04-15 10:55:58\r
+ * @LastEditors: Caisking 3449750381@qq.com\r
+ * @LastEditTime: 2024-08-17 10:30:26\r
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/saveele/include/SaveBatView.h\r
+ */\r
+\r
+#ifndef _SAVEBAT_VIEW_H\r
+#define _SAVEBAT_VIEW_H\r
+\r
+//#include "BaseView.h"\r
+#include "View.h"\r
+#include <ui_scroll_view.h>\r
+#include "components/ui_view_group.h"\r
+#include "components/ui_label.h"\r
+#include "components/ui_label_ext.h"\r
+#include "components/ui_image_view.h"\r
+#include "components/ui_button.h"\r
+#include "components/ui_digital_clock.h"\r
+#include "components/ui_box_progress.h"\r
+#include "components/ui_circle_progress.h"\r
+\r
+#include "SaveBatPresenter.h"\r
+#include <thread>\r
+#include "components/ui_canvas.h"\r
+#include "components/ui_scroll_view.h"\r
+#include "components/ui_canvas_ext.h"\r
+#include "components/ui_label_button.h"\r
+#include "hal_tick.h"\r
+namespace OHOS\r
+{\r
+    enum class countStage\r
+    {\r
+        STAGE_GRADUAL_CIRCLE = 0,\r
+        STAGE_COUNTING_DOWN,\r
+        STAGE_FADE_OUT,\r
+        STAGE_NONE\r
+    };\r
+    class CountdownBackAnimatorCallback : public AnimatorCallback\r
+    {\r
+    public:\r
+        explicit CountdownBackAnimatorCallback(UICanvasExt *canvas) : canvas_(canvas) {}\r
+        ~CountdownBackAnimatorCallback() override {}\r
+        void Callback(UIView *view) override;\r
+        void NotifyStart();\r
+        void CancelCountdown();\r
+        void SetInfo(UILabel *label, int counts);\r
+\r
+    private:\r
+        void CountingDown();\r
+        void UpdatePath(int16_t start, int16_t end, bool needDrawCircle);\r
+        void UpdateLable(uint32_t curTime);\r
+        void CircleFadeOut();\r
+        void GradualCircle();\r
+        UICanvasExt *canvas_ = nullptr;\r
+        UILabel *label_ = nullptr;\r
+        bool updateText_ = false;\r
+        bool firstArc_ = false;\r
+        countStage stage_ = countStage::STAGE_NONE;\r
+        int16_t endAngle_ = 0;\r
+        int16_t easeDegree_ = 0;\r
+        uint16_t idleTime_ = 0;\r
+        int16_t counts_ = 0;\r
+        uint32_t lastTime_ = 0;\r
+        uint32_t degreePerSecond_ = 0;\r
+        uint32_t surplusDegree = 0;\r
+    };\r
+\r
+    class SaveBatPresenter;\r
+    class SaveBatView : public View<SaveBatPresenter>\r
+    {\r
+\r
+    public:\r
+        SaveBatView();\r
+        virtual ~SaveBatView();\r
+        static SaveBatView *GetInstance(void);\r
+        void updateClock();\r
+\r
+        void OnStart() override;\r
+\r
+        void Init();\r
+        void DeInit();\r
+        UIView *GetView();\r
+\r
+        void Refresh_Dial_View();\r
+        void Refresh_Back_View();\r
+\r
+        void InitBatteryView();\r
+        void InitTimeView();\r
+        void InitButtonView();\r
+        void InitShowBackView();\r
+\r
+        void UpdateView();\r
+        void StartCanvas();\r
+        void StopCanvas();\r
+        UILabel *GetCountlabel()\r
+        {\r
+            return countlabel;\r
+        }\r
+        UICircleProgress *GetBackprogress()\r
+        {\r
+            return backprogress;\r
+        }\r
+\r
+    private:\r
+        UIView::OnDragListener *draglistener{nullptr};\r
+\r
+        SaveBatView(SaveBatView &&) = delete;\r
+        SaveBatView &operator=(SaveBatView &&) = delete;\r
+        /*省电界面*/\r
+        UILabel *timelabel = nullptr;            // 时间\r
+        UILabel *datelabel = nullptr;            // 日期标签\r
+        UILabel *batterylabel = nullptr;         // 电量标签\r
+        UIBoxProgress *batteryprogress{nullptr}; // 电池进度条\r
+        UIImageView *batteryiamge = nullptr;     // 电池框图标\r
+        UIButton *button_exit = nullptr;         // 退出按键\r
+        /*退出界面*/\r
+        UILabel *curren_label{nullptr};\r
+        UILabel *countlabel{nullptr};\r
+        UIImageView *wathchiamge{nullptr};\r
+        UICircleProgress *backprogress{nullptr};\r
+        /*test*/\r
+        CountdownBackAnimatorCallback *callBack_ = nullptr;\r
+        Animator *CountdownBackAnimator_ = nullptr;\r
+        UICanvasExt *canvas_ = nullptr;\r
+        UILabelButton *restart_ = nullptr;\r
+        UILabel *label_ = nullptr;\r
+    };\r
+} // namespace OHOS\r
+\r
+#endif // SLEEPDETAIL_PRESENTER_H
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveEleModel.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveEleModel.h
new file mode 100644 (file)
index 0000000..9ed43c9
--- /dev/null
@@ -0,0 +1,43 @@
+/***
+ * @Date: 2024-08-21 16:18:26
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-09-06 18:19:25
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/saveele/include/SaveEleModel.h
+ */
+#ifndef SAVE_ELE_MODEL_H
+#define SAVE_ELE_MODEL_H
+
+namespace OHOS
+{
+    class SaveEleModel
+    {
+    public:
+        // 获取单例实例
+        static SaveEleModel *GetInstance();
+
+        // 获取充电状态
+        bool GetChargeStatus();
+        void SetChargeStatus(bool chargeStatus);
+
+        // 设置视图状态
+        bool GetViewState() const { return viewState; }
+        void SetViewState(bool state) { viewState = state; }
+
+        // 设置退出状态
+        bool GetBackState() const { return backStatus_; }
+        void SetBackState(bool state) { backStatus_ = state; }
+
+    private:
+        SaveEleModel() = default; // 默认构造函数
+        ~SaveEleModel() {}        // 默认析构函数
+
+        SaveEleModel(const SaveEleModel &) = delete;            // 禁止拷贝构造
+        SaveEleModel &operator=(const SaveEleModel &) = delete; // 禁止赋值操作
+
+        bool chargeStatus_{false}; // 充电状态
+        bool backStatus_{false};   // 退出状态
+        bool viewState{false};     // 视图状态
+    };
+}
+
+#endif // SAVE_ELE_MODEL_H
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveElePresenter.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveElePresenter.h
new file mode 100644 (file)
index 0000000..6bc3ae9
--- /dev/null
@@ -0,0 +1,41 @@
+/***\r
+ * @Date: 2024-04-15 10:55:58\r
+ * @LastEditors: Caisking 3449750381@qq.com\r
+ * @LastEditTime: 2024-08-09 15:01:58\r
+ * @FilePath:\r
+ * /FD230/code/sdk/application/wearable/fd230app/nativeui/saveele/include/SaveElePresenter.h\r
+ */\r
+#ifndef _SAVEELE_PRESENTER_H\r
+#define _SAVEELE_PRESENTER_H\r
+\r
+#include "Presenter.h"\r
+#include "SaveEleView.h"\r
+\r
+namespace OHOS {\r
+static constexpr const char *SAVEBUTTONOK = "buttonok";\r
+static constexpr const char *SAVEBUTTONNO = "buttonno";\r
+\r
+class SaveEleView;\r
+class SaveElePresenter : public Presenter<SaveEleView>,\r
+                         public UIView::OnClickListener,\r
+                         public UIView::OnDragListener,\r
+                         public UIView::OnRotateListener,\r
+                         public RootView::OnKeyActListener {\r
+public:\r
+  SaveElePresenter();\r
+  virtual ~SaveElePresenter();\r
+\r
+  void OnStart() override;\r
+\r
+  static SaveElePresenter *GetInstance();\r
+\r
+private:\r
+  // 因为继承了OnClickListener,所以有OnClick属性,至于参数,原函数也这样直接继承;\r
+  bool OnClick(UIView &view, const ClickEvent &event) override;\r
+  bool OnDrag(UIView &view, const DragEvent &event) override;\r
+  bool OnKeyAct(UIView &view, const KeyEvent &event) override; // 增加按键事件\r
+  bool OnRotateEnd(UIView &view, const RotateEvent &event);\r
+};\r
+} // namespace OHOS\r
+\r
+#endif // SLEEPDETAIL_PRESENTER_H
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveEleView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/include/SaveEleView.h
new file mode 100644 (file)
index 0000000..dde0ca7
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef _SAVEELE_VIEW_H\r
+#define _SAVEELE_VIEW_H\r
+\r
+//#include "BaseView.h"\r
+#include "View.h"\r
+#include "components/ui_view_group.h"\r
+#include "components/ui_label.h"\r
+#include "components/ui_label_ext.h"\r
+#include "components/ui_image_view.h"\r
+#include "components/ui_button.h"\r
+\r
+#include "components/ui_scroll_view.h"\r
+#include "uicomponents/UIComponents.h"\r
+#include "SaveElePresenter.h"\r
+\r
+#include "SaveElePresenter.h"\r
+namespace OHOS\r
+{\r
+    class SaveElePresenter;\r
+    class SaveEleView : public View<SaveElePresenter>\r
+    {\r
+\r
+    public:\r
+        SaveEleView();\r
+        virtual ~SaveEleView();\r
+        static SaveEleView *GetInstance(void);\r
+\r
+        void OnStart() override;\r
+        void InitView();\r
+        void DeInit();\r
+\r
+    private:\r
+        UIView::OnDragListener *draglistener{nullptr};\r
+        \r
+\r
+        SaveEleView(SaveEleView &&) = delete;\r
+        SaveEleView &operator=(SaveEleView &&) = delete;\r
+\r
+        UILabelExt *labeltitle = nullptr;\r
+        UILabelExt *labelnote = nullptr;\r
+        UILabelExt *labelkown = nullptr;\r
+        UIButton *buttonok = nullptr;\r
+        UIButton *buttonno = nullptr;\r
+        UIImageView *iamgeicon = nullptr;\r
+        UIScrollView *scrollview_ = nullptr;\r
+        UIScrollView *SaveEleView_ = nullptr;\r
+        \r
+    };\r
+} // namespace OHOS\r
+#endif // SaveEle_PRESENTER_H\r
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveBatPresenter.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveBatPresenter.cpp
new file mode 100644 (file)
index 0000000..c4be16f
--- /dev/null
@@ -0,0 +1,148 @@
+\r
+#include "AppViewIDs.h"\r
+#include "KeyInputListener.h"\r
+#include "MainModel.h"\r
+#include "NativeAbility.h"\r
+#include "common/key_code.h"\r
+#include "cmsis_os.h"\r
+//#include "battery_hal.h"\r
+#include "custom_utils.h"\r
+#include "saveele/include/SaveBatPresenter.h"\r
+#include "saveele/include/SaveBatView.h"\r
+#include "saveele/include/SaveEleModel.h"\r
+#include "string.h"\r
+#include "time.h"\r
+#include "NativeRegisterManager.h"\r
+\r
+\r
+namespace OHOS {\r
+\r
+ REGIST_SLICE(VIEW_SAVEBAT, SaveBatView, SaveBatPresenter);\r
+\r
+// 当前Presenter属性实例化的内存指针\r
+static SaveBatPresenter *g_pSaveBatPresenter = nullptr;\r
+\r
+// 时间间隔宏定义(以毫秒为单位)\r
+#define ONE_SECOND 1000\r
+#define TWO_SECONDS 2000\r
+#define THREE_SECONDS 3000\r
+#define TIME_THRESHOLD 3000\r
+\r
+// 判断时间条件的宏\r
+#define IS_TIME_MATCH(startTime, current_time, interval)                       \\r
+  ((startTime != 0) && ((current_time - startTime) >= (interval)))\r
+#define IS_TIME_EXCEED(startTime, current_time)                                \\r
+  ((startTime != 0) && ((current_time - startTime) > (TIME_THRESHOLD)))\r
+\r
+SaveBatPresenter::SaveBatPresenter() { g_pSaveBatPresenter = this; }\r
+\r
+SaveBatPresenter::~SaveBatPresenter() { g_pSaveBatPresenter = nullptr; }\r
+\r
+SaveBatPresenter *SaveBatPresenter::GetInstance() {\r
+  return g_pSaveBatPresenter;\r
+}\r
+\r
+/*\r
+  void enable_drag(uint8_t direction, uint8_t enable);\r
+  void set_drag_limit(uint8_t direction, uint16_t limit);\r
+  uint16_t get_drag_limit(uint8_t direction);\r
+*/\r
+void SaveBatPresenter::OnStart() {\r
+  Presenter<SaveBatView>::OnStart();\r
+  // 1.获取原drag\r
+  #ifdef CUSTOM_UTILS\r
+  drag_x = get_drag_limit(0);\r
+  drag_y = get_drag_limit(1);\r
+ \r
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "drag_x:%d,drag_y:%d", drag_x, drag_y);\r
+  // 2.设置drag\r
+  enable_drag(0, 0);\r
+  enable_drag(1, 0);\r
+  #endif\r
+}\r
+\r
+\r
+\r
+bool SaveBatPresenter::OnPress(UIView &view, const PressEvent &event) {\r
+  if (strcmp(view.GetViewId(), "button_exit") == 0) {\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "进行按下");\r
+    if (SaveEleModel::GetInstance()->GetViewState() == false) {\r
+      SaveEleModel::GetInstance()->SetViewState(true);\r
+      SaveBatView::GetInstance()->UpdateView();\r
+      SaveBatView::GetInstance()->StartCanvas();\r
+    }\r
+  }\r
+  return true;\r
+}\r
+bool SaveBatPresenter::OnRelease(UIView &view, const ReleaseEvent &event) {\r
+  if (strcmp(view.GetViewId(), "button_exit") == 0) {\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "进行松开");\r
+    if (SaveEleModel::GetInstance()->GetViewState() == true) {\r
+      SaveBatView::GetInstance()->StopCanvas();\r
+      SaveEleModel::GetInstance()->SetViewState(false);\r
+      SaveBatView::GetInstance()->UpdateView();\r
+    }\r
+  }\r
+  return true;\r
+}\r
+void SaveBatPresenter::ExitView(void) {\r
+  NativeAbility::GetInstance().ChangeSlice(VIEW_MAIN);\r
+}\r
+\r
+void SaveBatPresenter::OnTickEvent() {\r
+  /*省电表盘界面*/\r
+  if (SaveEleModel::GetInstance()->GetViewState() == false) {\r
+    SaveBatView::GetInstance()->Refresh_Dial_View();\r
+  }\r
+  /*退出判断*/\r
+  bool chargeStatus = SaveEleModel::GetInstance()->GetChargeStatus();\r
+  bool backState = SaveEleModel::GetInstance()->GetBackState();\r
+  if (chargeStatus || backState) {\r
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP,\r
+                  "退出省电模式 Charge_Status: %d, Back_State: %d",\r
+                  chargeStatus, backState);\r
+    SaveEleModel::GetInstance()->SetBackState(false);\r
+    ExitView();\r
+  }\r
+}\r
+void SaveBatPresenter::ResetTickTimer(void) {\r
+  startTime = osKernelGetTick2ms();\r
+}\r
+/* 更新退出UI */\r
+void SaveBatPresenter::Refresh_Back_View() {\r
+  if (SaveBatView::GetInstance()->GetCountlabel() == nullptr ||\r
+      SaveBatView::GetInstance()->GetBackprogress() == nullptr) {\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+                  "Refresh_Back_View: countlabel or backprogress is null.");\r
+    return;\r
+  }\r
+\r
+  if (count > 0) // 确保不会减少到负数\r
+  {\r
+    // 每次调用时尝试更新进度值\r
+    progressValue++;\r
+\r
+    // 更新计数并检查进度值\r
+    if (progressValue == 50 || progressValue == 75 || progressValue == 100) {\r
+      count--;\r
+      SaveBatView::GetInstance()->GetCountlabel()->SetText(\r
+          std::to_string(count).c_str());\r
+    }\r
+\r
+    // 根据最大值进行检查以避免进度条越界\r
+    if (progressValue >= 100) // 假设进度最大值为100\r
+    {\r
+      NativeAbility::GetInstance().ChangeSlice(VIEW_MAIN);\r
+    } else {\r
+      SaveBatView::GetInstance()->GetBackprogress()->SetValue(progressValue);\r
+    }\r
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,\r
+                  "Refresh_Back_View: 当前计数: %d, 当前进度值: %d", count,\r
+                  progressValue);\r
+  }\r
+}\r
+bool SaveBatPresenter::OnKeyAct(UIView &view, const KeyEvent &event) {\r
+  /*消耗按键事件*/\r
+  return true;\r
+}\r
+} // namespace OHOS\r
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveBatView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveBatView.cpp
new file mode 100644 (file)
index 0000000..96410bf
--- /dev/null
@@ -0,0 +1,855 @@
+\r
+\r
+#include "saveele/include/SaveBatView.h"\r
+#include "saveele/include/SaveEleModel.h"\r
+\r
+#include "common/image_cache_manager.h"\r
+#include "UiConfig.h"\r
+#include "ui_resource_image.h"\r
+#include <ui_scroll_view.h>\r
+#include <iostream>\r
+#include <chrono>\r
+#include <thread>\r
+//#include "battery_hal.h"\r
+#include "string"\r
+#include "custom_utils.h"\r
+#include "UiConfig.h"\r
+#include "wearable_log.h"\r
+\r
+#include "custom_runtime.h"\r
+#include "ConfigModel.h"\r
+#include "languagecode/LanguageInit.h"\r
+\r
+#define ANIMATION_TEST 0\r
+extern "C"\r
+{\r
+    void uapi_exit_power_saving_mode(void);\r
+    void uapi_enter_power_saving_mode(void);\r
+}\r
+\r
+std::string Cnweekday[] = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};  \r
+std::string Enweekday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};  \r
+\r
+static constexpr const char *WHITE_BATTERY = "/user/res/Battery/Battery_White.bin";\r
+static constexpr const char *SAVE_BUTTON = "/user/res/Save_Ele/finger.bin";\r
+static constexpr const char *BACK_BUTTON = "/user/res/Save_Ele/finger2.bin";\r
+static constexpr const char *SAVE_WATHCH = "/user/res/Save_Ele/wathch.bin";\r
+\r
+namespace OHOS\r
+{\r
+    /*动画类实现*/\r
+    const static int16_t CENTER_X = 233;\r
+    const static int16_t CENTER_Y = 233;\r
+    const static int16_t LABEL_X = 140;\r
+    const static int16_t LABEL_Y = 170;\r
+    const static int16_t RADIUS = 90; // 半径 90\r
+    const static int16_t STROKE_WIDTH = 20;\r
+    const static int16_t CIRCLE_BASE_WIDTH = 4;\r
+    const static uint32_t LIGHT_GREEN = 0xff007700;\r
+    static const uint16_t LABEL_FONT_SIZE = 80;\r
+    static const uint16_t ANIMATE_TIME = 500;\r
+    static const uint16_t SECOND_TO_MINISECOND = 1000;\r
+    static const uint16_t CIRCLE_FADE_OUT = 200;\r
+    static const uint16_t DEGREES_PER_CIRCLE = 360;\r
+    void CountdownBackAnimatorCallback::Callback(UIView *view)\r
+    {\r
+        // 根据当前阶段调用相应的功能,控制动画状态\r
+        switch (stage_)\r
+        {\r
+        case countStage::STAGE_GRADUAL_CIRCLE:\r
+        {\r
+            // 处理渐变圆圈绘制\r
+            GradualCircle();\r
+            break;\r
+        }\r
+        case countStage::STAGE_COUNTING_DOWN:\r
+        {\r
+            // 处理倒计时逻辑\r
+            CountingDown();\r
+            break;\r
+        }\r
+        case countStage::STAGE_FADE_OUT:\r
+        {\r
+            // 处理圆圈淡出效果\r
+            CircleFadeOut();\r
+            break;\r
+        }\r
+        default:\r
+            break;\r
+        }\r
+    }\r
+\r
+    void CountdownBackAnimatorCallback::CircleFadeOut()\r
+    {\r
+        // 计算当前时间与上次更新时间的差值\r
+        uint32_t diffTime = HALTick::GetInstance().GetTime() - lastTime_;\r
+\r
+        // 如果尚未达到空闲时间,则什么也不做\r
+        if (diffTime < idleTime_)\r
+        {\r
+            return;\r
+        }\r
+\r
+        // 清空画布以准备绘制\r
+        canvas_->Clear();\r
+\r
+        // 计算当前的圆圈宽度\r
+        uint32_t curTime = diffTime - idleTime_;\r
+        uint16_t width;\r
+\r
+        // 判断是否已经达到淡出持续时间\r
+        if (curTime >= CIRCLE_FADE_OUT)\r
+        {\r
+            curTime = CIRCLE_FADE_OUT;       // 限制为最大淡出时间\r
+            stage_ = countStage::STAGE_NONE; // 设置为无状态\r
+        }\r
+\r
+        // 使用缓动方程计算当前宽度\r
+        width = EasingEquation::QuadEaseInOut(STROKE_WIDTH, CIRCLE_BASE_WIDTH, curTime, CIRCLE_FADE_OUT);\r
+\r
+        // 绘制中心圆圈\r
+        Point center = {CENTER_X, CENTER_Y};\r
+        ColorType lightGreen;\r
+        lightGreen.full = LIGHT_GREEN;\r
+        PaintExt paint;\r
+        paint.SetStyle(Paint::PaintStyle::STROKE_STYLE);\r
+        paint.SetCapType(CAP_ROUND);\r
+        paint.SetAntialiased(true);\r
+        paint.SetStrokeColor(lightGreen);\r
+        paint.SetStrokeWidth(width);\r
+        canvas_->DrawCircle(center, RADIUS, paint);\r
+\r
+        // 更新标签的字体大小和透明度\r
+        uint16_t fontSize = LABEL_FONT_SIZE * width / STROKE_WIDTH; // 根据笔画宽度调整字体大小\r
+        uint16_t opa = OPA_OPAQUE * width / STROKE_WIDTH;           // 根据笔画宽度调整透明度\r
+        if (stage_ == countStage::STAGE_NONE)\r
+        {\r
+            opa = OPA_TRANSPARENT; // 如果处于无状态,设置为完全透明\r
+        }\r
+\r
+        label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, fontSize);\r
+        label_->SetStyle(STYLE_TEXT_OPA, opa); // 更新标签样式\r
+    }\r
+\r
+    void CountdownBackAnimatorCallback::UpdateLable(uint32_t curTime)\r
+    {\r
+        char buf[2] = {0}; // 字符缓冲区,用于格式化标签文本\r
+        uint16_t fontSize; // 字体大小\r
+        uint16_t opa;      // 透明度\r
+\r
+        // 前半段动画,字体逐渐变小\r
+        if (curTime < ANIMATE_TIME / 2)\r
+        {\r
+            fontSize = LABEL_FONT_SIZE - LABEL_FONT_SIZE * curTime * 2 / ANIMATE_TIME; // 计算当前字体大小\r
+            opa = OPA_OPAQUE * fontSize / LABEL_FONT_SIZE;                             // 计算当前透明度\r
+            if (firstArc_)\r
+            {\r
+                fontSize = fontSize / 2; // 如果是第一弧,字体设置为一半大小\r
+            }\r
+        }\r
+        else\r
+        {\r
+            // 后半段动画,字体逐渐增大\r
+            fontSize = LABEL_FONT_SIZE * curTime * 2 / ANIMATE_TIME - LABEL_FONT_SIZE;\r
+            opa = OPA_OPAQUE * fontSize / LABEL_FONT_SIZE;\r
+\r
+            // 更新标签文本\r
+            if (updateText_)\r
+            {\r
+                if (sprintf_s(buf, sizeof(buf), "%u", (endAngle_ + easeDegree_) / degreePerSecond_) < 0)\r
+                {\r
+                    return; // 如果 sprintf_s 出错,返回\r
+                }\r
+                label_->SetText(buf); // 设置标签文本为当前倒计时数字\r
+                updateText_ = false;  // 更新文本之后将标志置为false\r
+            }\r
+        }\r
+\r
+        // 更新标签的字体和样式\r
+        label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, fontSize);\r
+        label_->SetStyle(STYLE_TEXT_OPA, opa);\r
+    }\r
+\r
+    void CountdownBackAnimatorCallback::UpdatePath(int16_t start, int16_t end, bool needDrawCircle)\r
+    {\r
+        // 计算绘制的圆心和颜色\r
+        Point center = {CENTER_X, CENTER_Y};\r
+        ColorType lightGreen;\r
+        lightGreen.full = LIGHT_GREEN;\r
+        PaintExt paint;\r
+        paint.SetStyle(Paint::PaintStyle::STROKE_STYLE);\r
+        paint.SetStrokeWidth(STROKE_WIDTH);\r
+        paint.SetCapType(CAP_ROUND);\r
+        paint.SetAntialiased(true);\r
+        paint.SetStrokeColor(lightGreen);\r
+\r
+        // 清空画布\r
+        canvas_->Clear();\r
+        // 如果需要绘制基础圆圈,则绘制\r
+        if (needDrawCircle)\r
+        {\r
+            canvas_->DrawCircle(center, RADIUS, paint);\r
+        }\r
+\r
+        // 如果起始角度与结束角度不相同,则绘制弧线\r
+        if (start != end)\r
+        {\r
+            paint.SetStrokeColor(Color::Green()); // 设置弧线颜色为绿色\r
+            // 如果起始角和结束角相差完整的一圈,则绘制完整的圆圈\r
+            if (end - start == DEGREES_PER_CIRCLE)\r
+            {\r
+                canvas_->DrawCircle(center, RADIUS, paint);\r
+            }\r
+            else\r
+            {\r
+                // 绘制从起始角到结束角\r
+                // 绘制从起始角到结束角的弧线\r
+                canvas_->DrawArc(center, RADIUS, start, end, paint);\r
+            }\r
+        }\r
+    }\r
+\r
+    void CountdownBackAnimatorCallback::CountingDown()\r
+    {\r
+        // 计算当前时间与上次更新时间的差值\r
+        uint32_t diffTime = HALTick::GetInstance().GetTime() - lastTime_;\r
+\r
+        // 如果时间差达到1秒,则更新倒计时\r
+        if (diffTime >= SECOND_TO_MINISECOND)\r
+        {\r
+            lastTime_ = HALTick::GetInstance().GetTime(); // 更新最后时间\r
+            // 判断是否是第一次绘制弧线\r
+            if (endAngle_ == DEGREES_PER_CIRCLE)\r
+            {\r
+                firstArc_ = true; // 如果是第一次,设置标志\r
+            }\r
+            else\r
+            {\r
+                firstArc_ = false; // 否则,设置为非第一次\r
+            }\r
+            // 更新路径和标签\r
+            UpdatePath(0, endAngle_, true);\r
+            UpdateLable(0);\r
+\r
+            // 如果倒计时结束,切换到淡出阶段\r
+            if (endAngle_ == 0)\r
+            {\r
+                stage_ = countStage::STAGE_FADE_OUT;\r
+                idleTime_ = SECOND_TO_MINISECOND - CIRCLE_FADE_OUT; // 设置空闲时间\r
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "倒计时结束");\r
+                OHOS::SaveEleModel::GetInstance()->SetBackState(true); // 进行界面弹出\r
+                return;\r
+            }\r
+\r
+            // 更新结束角度和缓动角度\r
+            easeDegree_ = degreePerSecond_;\r
+            endAngle_ -= degreePerSecond_; // 减少结束角度\r
+            // 如果结束角度小于等于剩余角度,则重置结束角度\r
+            if (endAngle_ <= surplusDegree)\r
+            {\r
+                endAngle_ = 0;\r
+                easeDegree_ += surplusDegree; // 增加缓动角度\r
+            }\r
+            updateText_ = true; // 标记需要更新文本\r
+        }\r
+        else if (diffTime >= idleTime_)\r
+        {\r
+            // 如果时间差超过空闲时间,更新路径和标签\r
+            uint32_t curTime = diffTime - idleTime_;\r
+            int16_t arcCurr = EasingEquation::QuadEaseInOut(0, easeDegree_, curTime, ANIMATE_TIME);\r
+            UpdatePath(0, endAngle_ + easeDegree_ - arcCurr, true);\r
+            UpdateLable(curTime);\r
+        }\r
+    }\r
+\r
+    void CountdownBackAnimatorCallback::GradualCircle()\r
+    {\r
+        // 计算当前时间与上次更新时间的差值\r
+        uint32_t diffTime = HALTick::GetInstance().GetTime() - lastTime_;\r
+\r
+        // 如果时间差达到1秒,则切换到倒计时阶段\r
+        if (diffTime >= SECOND_TO_MINISECOND)\r
+        {\r
+            stage_ = countStage::STAGE_COUNTING_DOWN;        // 切换阶段\r
+            idleTime_ = SECOND_TO_MINISECOND - ANIMATE_TIME; // 设置空闲时间\r
+        }\r
+        else if (diffTime >= idleTime_)\r
+        {\r
+            // 如果时间差超过空闲时间,绘制渐变圆圈\r
+            uint32_t curTime = diffTime - idleTime_;\r
+            int16_t arcCurr = EasingEquation::QuadEaseInOut(0, DEGREES_PER_CIRCLE,\r
+                                                            curTime, SECOND_TO_MINISECOND - idleTime_);\r
+            UpdatePath(180, arcCurr + 180, false); // 从180度开始绘制\r
+        }\r
+    }\r
+\r
+    void CountdownBackAnimatorCallback::SetInfo(UILabel *label, int counts)\r
+    {\r
+        // 设置标签和计数值\r
+        counts_ = counts; // 记录倒计时的总次数\r
+        label_ = label;   // 记录UILabel对象\r
+    }\r
+\r
+    void CountdownBackAnimatorCallback::NotifyStart()\r
+    {\r
+        // 初始化倒计时动画的状态\r
+        stage_ = countStage::STAGE_GRADUAL_CIRCLE;                       // 设置为渐变圆圈阶段\r
+        endAngle_ = DEGREES_PER_CIRCLE;                                  // 设置结束角度为完整一圈\r
+        idleTime_ = 200;                                                 // 设置初始空闲时间\r
+        degreePerSecond_ = DEGREES_PER_CIRCLE / counts_;                 // 计算每秒减少的角度\r
+        surplusDegree = DEGREES_PER_CIRCLE - degreePerSecond_ * counts_; // 计算剩余角度\r
+        lastTime_ = HALTick::GetInstance().GetTime();                    // 记录当前时间\r
+\r
+        // 初始化标签文本和样式\r
+        label_->SetText(" ");\r
+        label_->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, LABEL_FONT_SIZE / 2); // 设置字体为一半大小\r
+        label_->SetStyle(STYLE_TEXT_OPA, OPA_OPAQUE);                       // 设置标签为不透明\r
+    }\r
+\r
+    void CountdownBackAnimatorCallback::CancelCountdown()\r
+    {\r
+        // 设置阶段为淡出\r
+        stage_ = countStage::STAGE_FADE_OUT;\r
+\r
+        // 重置时间以立即开始淡出\r
+        lastTime_ = HALTick::GetInstance().GetTime(); // 记录当前时间\r
+        idleTime_ = 0;                                // 设置空闲时间为零,以跳过任何等待时间\r
+\r
+        endAngle_ = 0; // 设置结束角度为0,表示取消倒计时\r
+    }\r
+\r
+    static SaveBatView *g_pSaveBatView{nullptr};\r
+\r
+    SaveBatView::SaveBatView()\r
+    {\r
+        /*开启省电模式*/\r
+        uapi_enter_power_saving_mode();\r
+\r
+        g_pSaveBatView = this;\r
+    }\r
+\r
+\r
+    SaveBatView::~SaveBatView()  \r
+    {  \r
+        /* 关闭省电模式 */  \r
+        uapi_exit_power_saving_mode();\r
+\r
+        // UIViewGroup *tmpGroup = dynamic_cast<UIViewGroup *>(container_);\r
+        // UIViewGroup::RemoveAndDeleteAllRecursively(tmpGroup);\r
+\r
+        // 释放所有动态分配的成员变量  \r
+        if (timelabel) {  \r
+            delete timelabel;  \r
+            timelabel = nullptr;  \r
+        }  \r
+        if (datelabel) {  \r
+            delete datelabel;  \r
+            datelabel = nullptr;  \r
+        }  \r
+        if (batterylabel) {  \r
+            delete batterylabel;  \r
+            batterylabel = nullptr;  \r
+        }  \r
+        if (batteryprogress) {  \r
+            delete batteryprogress;  \r
+            batteryprogress = nullptr;  \r
+        }  \r
+        if (batteryiamge) {  \r
+            delete batteryiamge;  \r
+            batteryiamge = nullptr;  \r
+        }  \r
+        if (button_exit) {  \r
+            delete button_exit;  \r
+            button_exit = nullptr;  \r
+        }  \r
+\r
+        // 退出界面的成员变量  \r
+        if (curren_label) {  \r
+            delete curren_label;  \r
+            curren_label = nullptr;  \r
+        }  \r
+        if (countlabel) {  \r
+            delete countlabel;  \r
+            countlabel = nullptr;  \r
+        }  \r
+        if (wathchiamge) {  \r
+            delete wathchiamge;  \r
+            wathchiamge = nullptr;  \r
+        }  \r
+        if (backprogress) {  \r
+            delete backprogress;  \r
+            backprogress = nullptr;  \r
+        }  \r
+\r
+        // 测试相关的成员变量  \r
+        if (CountdownBackAnimator_) {\r
+            CountdownBackAnimator_->Stop();\r
+        }\r
+        if (callBack_) {  \r
+            delete callBack_;  \r
+            callBack_ = nullptr;\r
+        }\r
+        \r
+        delete CountdownBackAnimator_;\r
+        CountdownBackAnimator_ = nullptr;\r
+        \r
+        if (canvas_) {  \r
+            delete canvas_;  \r
+            canvas_ = nullptr;  \r
+        }  \r
+        if (restart_) {  \r
+            delete restart_;  \r
+            restart_ = nullptr;  \r
+        }  \r
+     \r
+        if (label_) {  \r
+            delete label_;  \r
+            label_ = nullptr;  \r
+        }  \r
+\r
+        // 将全局指针设为 nullptr  \r
+        g_pSaveBatView = nullptr;  \r
+    }\r
+\r
+    SaveBatView *SaveBatView::GetInstance()\r
+    {\r
+        return g_pSaveBatView;\r
+    }\r
+\r
+    /* 更新主界面数据 */\r
+    void SaveBatView::Refresh_Dial_View()\r
+    {\r
+        /*\r
+          日期样式 04-22 周五\r
+          时间样式 09:10\r
+        */\r
+        if (timelabel == nullptr || datelabel == nullptr || batterylabel == nullptr || batteryprogress == nullptr)\r
+            return;\r
+\r
+        // 获取当前时间\r
+        time_t seconds;\r
+        time(&seconds);\r
+        struct tm pTM;\r
+        localtime_r(&seconds, &pTM);\r
+\r
+        // 解析时间\r
+        int hour = pTM.tm_hour;\r
+        int minute = pTM.tm_min;\r
+        int day = pTM.tm_mday;\r
+        int month = pTM.tm_mon + 1; // 月份范围 [1, 12]\r
+        std::string weekStr;\r
+         if (ConfigModel::GetInstance()->GetLanguage() == ZH_CN)\r
+           weekStr = Cnweekday[pTM.tm_wday];\r
+         else\r
+           weekStr = Enweekday[pTM.tm_wday];\r
+         \r
+        // 构建日期和时间字符串\r
+        std::string dateStr =\r
+            (month < 10 ? "0" : "") + std::to_string(month) + "-" +\r
+            (day < 10 ? "0" : "") + std::to_string(day) + " " + weekStr;\r
+\r
+        //需要判断显示的格式\r
+        if (uapi_dev_runtime_get_time_hour_show_model() ==  12)\r
+        {\r
+            if (pTM.tm_hour > 12)\r
+                hour = pTM.tm_hour - 12 ;\r
+        }\r
+        \r
+        std::string stringtime =\r
+            (hour < 10 ? "0" : "") + std::to_string(hour) + ":" +\r
+            (minute < 10 ? "0" : "") + std::to_string(minute);\r
+\r
+        // 获取电量值\r
+        float voltage = 0.0F;\r
+        //uint8_t value = battery_get_voltage(&voltage);\r
+        uint8_t  value = 0;\r
+\r
+        \r
+        // 更新界面组件\r
+        timelabel->SetText(stringtime.c_str());\r
+        datelabel->SetText(dateStr.c_str());\r
+        batterylabel->SetText((std::to_string(value) + "%").c_str());\r
+        batteryprogress->SetValue(value);\r
+    }\r
+\r
+    void SaveBatView::InitBatteryView()\r
+    {\r
+        // 创建电池框图像\r
+        batteryiamge = new UIImageView();\r
+        if (!batteryiamge)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batteryiamge creation failed");\r
+            return;\r
+        }\r
+\r
+        // 创建电池进度条\r
+        batteryprogress = new UIBoxProgress();\r
+        if (!batteryprogress)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batteryprogress creation failed");\r
+            return;\r
+        }\r
+\r
+        // 创建电池标签\r
+        batterylabel = new UILabel();\r
+        if (!batterylabel)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batterylabel creation failed");\r
+            return;\r
+        }\r
+\r
+        // 设置位置\r
+        batteryiamge->SetPosition(176, 52, 100, 100);\r
+        batteryiamge->SetSrc(WHITE_BATTERY);\r
+\r
+        batteryprogress->SetPosition(182, 58, 30, 18);\r
+        batteryprogress->SetStyle(STYLE_BORDER_RADIUS, 20);\r
+        batteryprogress->SetViewId("batteryprogress");\r
+        batteryprogress->SetStyle(STYLE_BACKGROUND_OPA, 0xff);\r
+\r
+        batterylabel->SetPosition(228, 54, 200, 60);\r
+        batterylabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 26);\r
+        batterylabel->SetTextColor(Color::White());\r
+        batteryprogress->SetForegroundStyle(STYLE_BACKGROUND_COLOR, 0xffffc300);\r
+\r
+        AddViewToRootContainer(batteryiamge);\r
+        AddViewToRootContainer(batterylabel);\r
+        AddViewToRootContainer(batteryprogress);\r
+    }\r
+    void SaveBatView::InitTimeView()\r
+    {\r
+        /*时间time*/\r
+        timelabel = new UILabel();\r
+        if (timelabel == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "timelabel creation failed");\r
+            return;\r
+        }\r
+        timelabel->SetPosition(0, 148);\r
+        timelabel->Resize(466, 100);\r
+        timelabel->SetViewId("label1");\r
+        timelabel->SetStyle(STYLE_TEXT_FONT, 100);\r
+        timelabel->SetText("11:00");\r
+        timelabel->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS);\r
+        timelabel->SetTextColor(Color::GetColorFromRGBA(0x49, 0xef, 0x13, 0xff));\r
+        timelabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);\r
+        timelabel->SetRollSpeed(0);\r
+        timelabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 100);\r
+        AddViewToRootContainer(timelabel);\r
+\r
+        /*日期*/\r
+        datelabel = new UILabel();\r
+        if (datelabel == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "datelabel creation failed");\r
+            return;\r
+        }\r
+        datelabel->SetPosition(83, 258);\r
+        datelabel->Resize(300, 60);\r
+        datelabel->SetViewId("label2");\r
+        datelabel->SetStyle(STYLE_TEXT_FONT, 30);\r
+\r
+        // datelabel->SetText("04-22 周五");\r
+        datelabel->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS);\r
+        datelabel->SetTextColor(Color::GetColorFromRGBA(0x66, 0x66, 0x66, 0xff));\r
+        datelabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);\r
+        datelabel->SetRollSpeed(0);\r
+        datelabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 30);\r
+        AddViewToRootContainer(datelabel);\r
+    }\r
+    void SaveBatView::InitButtonView()\r
+    {\r
+        // 初始化按键\r
+        button_exit = new UIButton();\r
+        if (button_exit == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "button_exit creation failed");\r
+            return;\r
+        }\r
+        button_exit->SetPosition(204, 350);\r
+        button_exit->Resize(100, 100);\r
+        button_exit->SetViewId("button_exit");\r
+        button_exit->SetStyle(STYLE_BACKGROUND_COLOR, 0xff000000);\r
+        button_exit->SetStyle(STYLE_BACKGROUND_OPA, 0x00);\r
+\r
+        button_exit->SetImageSrc(SAVE_BUTTON, SAVE_BUTTON);\r
+        button_exit->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff000000, UIButton::PRESSED);\r
+\r
+        button_exit->SetOnTouchListener(presenter_);\r
+        AddViewToRootContainer(button_exit);\r
+    }\r
+    void SaveBatView::InitShowBackView()\r
+    {\r
+        // 时间\r
+        time_t seconds;\r
+        time(&seconds);\r
+        struct tm pTM;\r
+        localtime_r(&seconds, &pTM);\r
+\r
+        int hour = pTM.tm_hour;\r
+        int minute = pTM.tm_min;\r
+        std::string stringtime =\r
+            (hour < 10 ? "0" : "") + std::to_string(hour) + ":" +\r
+            (minute < 10 ? "0" : "") + std::to_string(minute);\r
+\r
+        curren_label = new UILabel();\r
+        if (curren_label == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "curren_label creation failed");\r
+            return;\r
+        }\r
+        curren_label->SetPosition(181, 52);\r
+        curren_label->Resize(200, 60);\r
+        curren_label->SetViewId("label4");\r
+        curren_label->SetStyle(STYLE_TEXT_FONT, 40);\r
+        curren_label->SetText(stringtime.c_str());\r
+        curren_label->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);\r
+        curren_label->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);\r
+        curren_label->SetRollSpeed(0);\r
+        curren_label->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 40);\r
+        AddViewToRootContainer(curren_label);\r
+        curren_label->SetVisible(false);\r
+#if ANIMATION_TEST\r
+        // 圆形进度条\r
+        backprogress = new UICircleProgress();\r
+        if (backprogress == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "backprogress creation failed");\r
+            return;\r
+        }\r
+        backprogress->SetPosition(143, 143);\r
+        backprogress->Resize(183, 186);\r
+        backprogress->SetViewId("circleProgress1");\r
+        backprogress->SetStyle(STYLE_BACKGROUND_OPA, 0x00);                   // 确保背景透明\r
+        backprogress->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, 0x00000000); // 背景颜色设置为完全透明\r
+        backprogress->SetBackgroundStyle(STYLE_LINE_WIDTH, 20);\r
+        backprogress->SetForegroundStyle(STYLE_BACKGROUND_COLOR, 0xff000000);\r
+        backprogress->SetForegroundStyle(STYLE_BORDER_COLOR, 0xff000000);\r
+        backprogress->SetForegroundStyle(STYLE_LINE_COLOR, 0xff18ef05);\r
+        backprogress->SetForegroundStyle(STYLE_LINE_WIDTH, 20);\r
+        backprogress->SetCenterPosition(92, 93);\r
+        backprogress->SetRadius(90);\r
+        backprogress->SetEndAngle(359);\r
+        backprogress->SetValue(0);\r
+        container_->Add(backprogress);\r
+        backprogress->SetVisible(false);\r
+\r
+        // 手表image\r
+        wathchiamge = new UIImageView();\r
+        if (wathchiamge == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "wathchiamge creation failed");\r
+            return;\r
+        }\r
+        wathchiamge->SetPosition(191, 182);\r
+        wathchiamge->Resize(100, 100);\r
+        wathchiamge->SetViewId("image1");\r
+        wathchiamge->SetSrc(SAVE_WATHCH);\r
+        container_->Add(wathchiamge);\r
+        wathchiamge->SetVisible(false);\r
+\r
+        // 倒计时\r
+        countlabel = new UILabel();\r
+        if (countlabel == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "countlabel creation failed");\r
+            return;\r
+        }\r
+        countlabel->SetPosition(221, 212);\r
+        countlabel->Resize(200, 60);\r
+        countlabel->SetViewId("label3");\r
+        countlabel->SetStyle(STYLE_TEXT_FONT, 40);\r
+        countlabel->SetText("3");\r
+        countlabel->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);\r
+        countlabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);\r
+        countlabel->SetRollSpeed(0);\r
+        countlabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME_EN, 40);\r
+        container_->Add(countlabel);\r
+        countlabel->SetVisible(false);\r
+#else\r
+        if (canvas_ == nullptr)\r
+        {\r
+            canvas_ = new UICanvasExt();\r
+        }\r
+        canvas_->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());\r
+        canvas_->SetStyle(STYLE_BACKGROUND_OPA, OPA_TRANSPARENT);\r
+        AddViewToRootContainer(canvas_);\r
+        canvas_->SetVisible(false);\r
+\r
+        if (label_ == nullptr)\r
+        {\r
+            label_ = new UILabel();\r
+        }\r
+        label_->SetPosition(LABEL_X, LABEL_Y, 180, 120);\r
+        label_->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);\r
+        AddViewToRootContainer(label_);\r
+        label_->SetVisible(false);\r
+\r
+        PaintExt paint;\r
+        ColorType lightGreen;\r
+        lightGreen.full = LIGHT_GREEN;\r
+        paint.SetStyle(Paint::PaintStyle::STROKE_STYLE);\r
+        paint.SetStrokeWidth(CIRCLE_BASE_WIDTH);\r
+        paint.SetAntialiased(true);\r
+        paint.SetStrokeColor(lightGreen);\r
+        canvas_->DrawCircle({CENTER_X, CENTER_Y}, RADIUS, paint);\r
+\r
+        callBack_ = new CountdownBackAnimatorCallback(canvas_);\r
+        if (callBack_ == nullptr)\r
+        {\r
+            GRAPHIC_LOGE("CallBack new fail");\r
+            return;\r
+        }\r
+        CountdownBackAnimator_ = new Animator(callBack_, canvas_, 0, true);\r
+        if (CountdownBackAnimator_ == nullptr)\r
+        {\r
+            delete callBack_;\r
+            callBack_ = nullptr;\r
+            GRAPHIC_LOGE("Animator new fail");\r
+            return;\r
+        }\r
+        CountdownBackAnimator_->Start();\r
+        callBack_->SetInfo(label_, 3); // 3: countdown numbers\r
+#endif\r
+    }\r
+\r
+    // 更新当前界面状态\r
+    void SaveBatView::UpdateView()\r
+    {\r
+        bool state = SaveEleModel::GetInstance()->GetViewState();\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateView state %d", state);\r
+\r
+        // 检查每个组件是否为空,并记录具体信息\r
+        if (timelabel == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "timelabel is null");\r
+            return;\r
+        }\r
+        if (datelabel == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "datelabel is null");\r
+            return;\r
+        }\r
+        if (batterylabel == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batterylabel is null");\r
+            return;\r
+        }\r
+        if (batteryprogress == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batteryprogress is null");\r
+            return;\r
+        }\r
+        if (batteryiamge == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batteryiamge is null");\r
+            return;\r
+        }\r
+        if (curren_label == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "curren_label is null");\r
+            return;\r
+        }\r
+#if ANIMATION_TEST\r
+        if (countlabel == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "countlabel is null");\r
+            return;\r
+        }\r
+        if (wathchiamge == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "wathchiamge is null");\r
+            return;\r
+        }\r
+        if (backprogress == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "backprogress is null");\r
+            return;\r
+        }\r
+#endif\r
+        if (button_exit == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "button_exit is null");\r
+            return;\r
+        }\r
+\r
+        // 显示/隐藏原界面组件\r
+        bool showPrimaryView = !state;\r
+        timelabel->SetVisible(showPrimaryView);\r
+        datelabel->SetVisible(showPrimaryView);\r
+        batterylabel->SetVisible(showPrimaryView);\r
+        batteryprogress->SetVisible(showPrimaryView);\r
+        batteryiamge->SetVisible(showPrimaryView);\r
+\r
+#if ANIMATION_TEST\r
+        // 初始化计数器\r
+        int count = 3;\r
+        int progressValue = 0;\r
+        countlabel->SetText(std::to_string(count).c_str());\r
+        backprogress->SetValue(progressValue);\r
+\r
+        /* 退出界面 */\r
+        curren_label->SetVisible(state);\r
+        countlabel->SetVisible(state);\r
+        wathchiamge->SetVisible(state);\r
+        backprogress->SetVisible(state);\r
+\r
+#else\r
+        /* 退出界面 */\r
+        curren_label->SetVisible(state);\r
+\r
+        // 显示当前时间\r
+        time_t seconds;\r
+        time(&seconds);\r
+        struct tm pTM;\r
+        localtime_r(&seconds, &pTM);\r
+\r
+        int hour = pTM.tm_hour;\r
+        int minute = pTM.tm_min;\r
+        std::string stringtime =\r
+            (hour < 10 ? "0" : "") + std::to_string(hour) + ":" +\r
+            (minute < 10 ? "0" : "") + std::to_string(minute);\r
+        curren_label->SetText(stringtime.c_str());\r
+        label_->SetVisible(state);\r
+        canvas_->SetVisible(state);\r
+\r
+#endif\r
+\r
+        // 设置退出按钮图像\r
+        const char *buttonImage = state ? BACK_BUTTON : SAVE_BUTTON;\r
+        button_exit->SetImageSrc(buttonImage, buttonImage);\r
+    }\r
+\r
+    /*动画的控制*/\r
+    void SaveBatView::StartCanvas()\r
+    {\r
+        callBack_->NotifyStart();\r
+    }\r
+    void SaveBatView::StopCanvas()\r
+    {\r
+        callBack_->CancelCountdown();\r
+    }\r
+\r
+    void SaveBatView::OnStart()\r
+    {\r
+       \r
+\r
+        GetRootContainer()->SetPosition(0, 0);\r
+        GetRootContainer()->SetWidth(Screen::GetInstance().GetWidth());\r
+        GetRootContainer()->SetHeight(Screen::GetInstance().GetHeight());\r
+        GetRootContainer()->SetTouchable(true);\r
+        GetRootContainer()->SetDraggable(true);\r
+\r
+        InitBatteryView();\r
+        InitTimeView();\r
+        InitButtonView();\r
+        InitShowBackView();\r
+\r
+        Draw();\r
+\r
+        //SetContainerView(container_);\r
+        //RootView::GetInstance()->SetOnKeyActListener(presenter_);\r
+    }\r
+\r
+    \r
+}
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveEleModel.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveEleModel.cpp
new file mode 100644 (file)
index 0000000..990c500
--- /dev/null
@@ -0,0 +1,20 @@
+
+#include "saveele/include/SaveEleModel.h"
+
+namespace OHOS
+{
+
+    SaveEleModel *SaveEleModel::GetInstance(void)
+    {
+        static SaveEleModel instance;
+        return &instance;
+    }
+    bool SaveEleModel::GetChargeStatus()
+    {
+        return chargeStatus_;
+    }
+    void SaveEleModel::SetChargeStatus(bool chargeStatus)
+    {
+        chargeStatus_ = chargeStatus;
+    }
+}
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveElePresenter.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveElePresenter.cpp
new file mode 100644 (file)
index 0000000..8c4460c
--- /dev/null
@@ -0,0 +1,83 @@
+\r
+#include "AppViewIDs.h"\r
+#include "KeyInputListener.h"\r
+#include "NativeAbility.h"\r
+#include "common/key_code.h"\r
+#include "components/ui_label_ext.h"\r
+#include "custom_utils.h"\r
+#include "ui_resource_string.h"\r
+\r
+#include "gfx_utils/mem_check.h"\r
+#include "saveele/include/SaveElePresenter.h"\r
+#include "vibrator_service.h"\r
+#include "NativeRegisterManager.h"\r
+\r
+\r
+namespace OHOS {\r
+  \r
+  REGIST_MENU_PRO(VIEW_SAVEELE, SaveEleView, SaveElePresenter,\r
+    PNG_APPLIST_BRIGHTNESSLEVEL_IMAGE_BIG, PNG_APPLIST_BRIGHTNESSLEVEL_IMAGE, PNG_APPLIST_BRIGHTNESSLEVEL_IMAGE, "省电模式", STR_POWER_SAVE_MODE);\r
+\r
+// 当前Presenter属性实例化的内存指针\r
+static SaveElePresenter *g_pSaveElePresenter = nullptr;\r
+\r
+SaveElePresenter::SaveElePresenter() {\r
+#ifdef MEM_CHECK\r
+  MemCheck::GetInstance()->EnableLeakCheck(true);\r
+#endif\r
+  g_pSaveElePresenter = this;\r
+}\r
+\r
+SaveElePresenter::~SaveElePresenter() {\r
+#ifdef MEM_CHECK\r
+  MemCheck::GetInstance()->EnableLeakCheck(false);\r
+#endif\r
+  g_pSaveElePresenter = nullptr;\r
+}\r
+\r
+SaveElePresenter *SaveElePresenter::GetInstance() {\r
+\r
+  return g_pSaveElePresenter;\r
+}\r
+\r
+void SaveElePresenter::OnStart() { Presenter<SaveEleView>::OnStart(); }\r
+\r
+\r
+bool SaveElePresenter::OnDrag(UIView &view, const DragEvent &event) {\r
+\r
+  if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT &&\r
+      (event.GetDeltaX() > 20) &&\r
+      (event.GetDeltaX() > (2 * MATH_ABS(event.GetDeltaY())))) {\r
+    NativeAbility::GetInstance().Back();\r
+  }\r
+  UNUSED(view);\r
+  return true;\r
+}\r
+\r
+bool SaveElePresenter::OnClick(UIView &view, const ClickEvent &event) {\r
+  if (strcmp(view.GetViewId(), SAVEBUTTONNO) == 0) {\r
+    NativeAbility::GetInstance().Back();\r
+  }\r
+  if (strcmp(view.GetViewId(), SAVEBUTTONOK) == 0) {\r
+    NativeAbility::GetInstance().ChangeSlice(VIEW_SAVEBAT);\r
+  }\r
+  return true;\r
+}\r
+bool SaveElePresenter::OnKeyAct(UIView &view, const KeyEvent &event) {\r
+  unsigned short keyID = event.GetKeyId();\r
+  unsigned short keyState = event.GetState();\r
+  // 如果是power键,且是亮屏状态,按键释放就返回上一级\r
+  if (keyID == static_cast<uint16_t>(ZliteKeyCode::ZLITE_KEY_POWER) &&\r
+      keyState == 1 && uapi_get_screen_state() == 0) {\r
+    NativeAbility::GetInstance().Back();\r
+  }\r
+  return true;\r
+}\r
+\r
+bool SaveElePresenter::OnRotateEnd(UIView &view, const RotateEvent &event) {\r
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,\r
+                "VolumeSliderEventListener::OnRotateEnd");\r
+//   ui_api_vibrate_once_func(); \r
+  return true;\r
+}\r
+} // namespace OHOS
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveEleView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/saveele/src/SaveEleView.cpp
new file mode 100644 (file)
index 0000000..2bf54c6
--- /dev/null
@@ -0,0 +1,149 @@
+/***\r
+ * @Date: 2024-04-15 10:55:58\r
+ * @LastEditors: Caisking 3449750381@qq.com\r
+ * @LastEditTime: 2024-08-09 14:41:32\r
+ * @FilePath:\r
+ * /FD230/code/sdk/application/wearable/fd230app/nativeui/saveele/src/SaveEleView.cpp\r
+ */\r
+\r
+#include "saveele/include/SaveEleView.h"\r
+#include "saveele/include/SaveElePresenter.h"\r
+\r
+#include "UiConfig.h"\r
+#include "common/image_cache_manager.h"\r
+#include "components/ui_button.h"\r
+#include "components/ui_scroll_view.h"\r
+#include "ui_resource_image.h"\r
+#include "ui_resource_string.h"\r
+#include "uicomponents/UIComponents.h"\r
+#include "components/ui_scroll_view.h"\r
+\r
+namespace OHOS {\r
+\r
+static SaveEleView *g_pSaveEleView{nullptr};\r
+static const uint32_t BACK_GROUND_COLOR = 0xfff6f6f6;\r
+\r
+static constexpr char *iconImgPath = "/user/res/Save_Ele/SaveEle.bin";\r
+static constexpr char *butnoImgPath = "/user/res/Save_Ele/Save_Error.bin";\r
+static constexpr char *butokImgPath = "/user/res/Save_Ele/Save_Right.bin";\r
+\r
+SaveEleView::SaveEleView() { g_pSaveEleView = this; }\r
+\r
+SaveEleView::~SaveEleView() {\r
+\r
+  // UIViewGroup *tmpGroup = dynamic_cast<UIViewGroup *>(container_);\r
+  // UIViewGroup::RemoveAndDeleteAllRecursively(tmpGroup);\r
+\r
+  if (scrollview_ != nullptr) {\r
+    scrollview_->RemoveAll();\r
+    delete scrollview_;\r
+    scrollview_ = nullptr;\r
+  }\r
+  RootView::GetInstance()->RemoveAll();\r
+ \r
+  if (labeltitle) {\r
+    delete labeltitle;\r
+    labeltitle = nullptr;\r
+  }\r
+  if (labelnote) {\r
+    delete labelnote;\r
+    labelnote = nullptr;\r
+  }\r
+  if (labelkown) {\r
+    delete labelkown;\r
+    labelkown = nullptr;\r
+  }\r
+  if (iamgeicon) {\r
+    delete iamgeicon;\r
+    iamgeicon = nullptr;\r
+  }\r
+  if (buttonno) {\r
+    delete buttonno;\r
+    buttonno = nullptr;\r
+  }\r
+  if (buttonok) {\r
+    delete buttonok;\r
+    buttonok = nullptr;\r
+  }\r
+\r
+  g_pSaveEleView = nullptr;\r
+}\r
+\r
+SaveEleView *SaveEleView::GetInstance() { return g_pSaveEleView; }\r
+\r
+void SaveEleView::InitView() {\r
+  \r
+    SaveEleView_ = new UIScrollView();\r
+    SaveEleView_->SetPosition(0, 0, 466, 466);\r
+    SaveEleView_->SetStyle(STYLE_BACKGROUND_OPA, 0);\r
+  \r
+\r
+  /*初始化label*/\r
+  InitRollLabel(labeltitle, 83, 50, 300, 35, "labletitle", STR_POWER_SAVE_MODE,\r
+                DEFAULT_VECTOR_FONT_FILENAME, 30);\r
+  // TODO:多国语言\r
+  InitLabelExt(labelnote, 53, 217, 360, 200, "labletitle", STR_SAVENOTE,\r
+               DEFAULT_VECTOR_FONT_FILENAME, 30);\r
+  labelnote->SetLineBreakMode(UILabel::LINE_BREAK_WRAP);\r
+\r
+  InitLabelExt(labelkown, 53, labelnote->GetY() + labelnote->GetHeight() + 20,\r
+               360, 100, "labelrecord", STR_SAVEBACK,\r
+               DEFAULT_VECTOR_FONT_FILENAME, 30);\r
+  labelkown->SetLineBreakMode(UILabel::LINE_BREAK_WRAP);\r
+  labelkown->SetTextColor(Color::Orange());\r
+\r
+  /*初始化图片*/\r
+  InitImageView(iamgeicon, 188, 121, 80, 90, "saveicon", iconImgPath);\r
+\r
+  /*初始化按键*/\r
+  InitButton(buttonno, 110, labelkown->GetY() + labelkown->GetHeight() + 40,\r
+             100, 100, SAVEBUTTONNO);\r
+  buttonno->SetImageSrc(butnoImgPath, butnoImgPath);\r
+  buttonno->SetOnClickListener(presenter_);\r
+\r
+  InitButton(buttonok, 255, labelkown->GetY() + labelkown->GetHeight() + 40,\r
+             100, 100, SAVEBUTTONOK);\r
+  buttonok->SetImageSrc(butokImgPath, butokImgPath);\r
+  buttonok->SetOnClickListener(presenter_);\r
+\r
+  SaveEleView_->Add(labeltitle);\r
+  SaveEleView_->Add(labelnote);\r
+  SaveEleView_->Add(labelkown);\r
+  SaveEleView_->Add(iamgeicon);\r
+  SaveEleView_->Add(buttonno);\r
+  SaveEleView_->Add(buttonok);\r
+  scrollview_->Add(SaveEleView_);\r
+  \r
+}\r
+\r
+void SaveEleView::OnStart() {\r
+\r
+  View<SaveElePresenter>::OnStart();\r
+  \r
+  scrollview_ = new UIScrollView();\r
+  if (scrollview_ == nullptr) {\r
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "scrollview_ new fail");\r
+    return;\r
+  }\r
+  scrollview_->SetScrollBlankSize(35);\r
+  scrollview_->SetReboundSize(50);\r
+  scrollview_->SetPosition(0, 0, Screen::GetInstance().GetWidth(),\r
+                          Screen::GetInstance().GetHeight());\r
+\r
+  scrollview_->SetOnDragListener(presenter_);\r
+  scrollview_->SetOnRotateListener(presenter_);\r
+  scrollview_->SetRotateFactor(2);\r
+  scrollview_->RequestFocus();\r
+  scrollview_->SetTouchable(true);\r
+  scrollview_->SetDraggable(true);\r
+  scrollview_->SetStyle(STYLE_BACKGROUND_COLOR, BACK_GROUND_COLOR);\r
+  scrollview_->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);\r
+\r
+\r
+  AddViewToRootContainer(scrollview_);\r
+  InitView();\r
+  \r
+}\r
+\r
+\r
+} // namespace OHOS\r
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepCardView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepCardView.h
new file mode 100644 (file)
index 0000000..624d489
--- /dev/null
@@ -0,0 +1,37 @@
+/***\r
+ * @Date: 2024-06-25 10:41:32\r
+ * @LastEditors: Caisking 3449750381@qq.com\r
+ * @LastEditTime: 2024-09-03 15:10:21\r
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/include/SleepCardView.h\r
+ */\r
+#ifndef SLEEP_CARD_VIEW_H\r
+#define SLEEP_CARD_VIEW_H\r
+\r
+#include "components/root_view.h"\r
+#include "components/ui_card_page.h"\r
+#include "wearable_log.h"\r
+#include "sleep/include/SleepControlView.h"\r
+namespace OHOS\r
+{\r
+    class SleepControlView;\r
+    class SleepCardView : public UICardPage\r
+    {\r
+    public:\r
+        SleepCardView();\r
+        virtual ~SleepCardView();\r
+        static SleepCardView *GetInstance(void);\r
+\r
+        bool InitView(void);\r
+        void PreLoad(void) override;\r
+        void UnLoad(void) override;\r
+        UISwipeView *GetSleepCardView();\r
+\r
+    private:\r
+        void ClearAll(void);\r
+        SleepControlView *sleepcontrolView{nullptr};\r
+        UISwipeView *SleepSwipView{nullptr};\r
+        UISwipeView::OnSwipeListener *sleepOnSwipeListener{nullptr};\r
+        bool viewiInitStatus{false};\r
+    };\r
+}\r
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepControlPresenter.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepControlPresenter.h
new file mode 100644 (file)
index 0000000..29cfd42
--- /dev/null
@@ -0,0 +1,55 @@
+
+/***
+ * @Date: 2024-06-25 10:32:53
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-06-25 15:31:40
+ * @FilePath: /XTS_FD230/FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/include/SleepControlPresenter.h
+ */
+#ifndef Sleep_CONTROL_PRESENTER_H
+#define Sleep_CONTROL_PRESENTER_H
+
+#include "Presenter.h"
+#include "View.h"
+#include "sleep/include/SleepView.h"
+#include "sleep/include/SleepModel.h"
+#include "sleep/include/SleepControlView.h"
+namespace OHOS
+{
+    class SleepOnSwipeListener : public UISwipeView::OnSwipeListener
+    {
+    public:
+        SleepOnSwipeListener() {}
+        ~SleepOnSwipeListener() {}
+        void OnSwipe(UISwipeView &view) override;
+    };
+
+    class SleepControlView;
+    class SleepControlPresenter : public Presenter<SleepControlView>,
+                                  public UIView::OnClickListener,
+                                  public RootView::OnKeyActListener,
+                                  public UIView::OnDragListener,
+                                  public UISwipeView::OnSwipeListener
+    {
+    public:
+        SleepControlPresenter();
+        virtual ~SleepControlPresenter();
+
+        void OnStart() override;
+        void OnPause() override;
+        void OnResume() override;
+        void OnStop() override;
+
+        static SleepControlPresenter *GetInstance();
+
+    private:
+        bool OnClick(UIView &view, const ClickEvent &event) override;
+        bool OnDrag(UIView &view, const DragEvent &event) override;
+        bool OnDragEnd(UIView &view, const DragEvent &event) override;
+        bool OnKeyAct(UIView &view, const KeyEvent &event) override;
+        void OnSwipe(UISwipeView &view) override;
+
+        bool X_DRAG_FLAG{false};
+    };
+} // namespace OHOS
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepControlView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepControlView.h
new file mode 100644 (file)
index 0000000..4c43d18
--- /dev/null
@@ -0,0 +1,74 @@
+/***
+ * @Date: 2024-06-25 10:41:08
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-09-02 09:22:33
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/include/SleepControlView.h
+ */
+/***
+ * @Date: 2024-06-25 10:41:08
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-06-25 17:26:24
+ * @FilePath: /XTS_FD230/FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/include/SleepControlView.h
+ */
+
+#ifndef SleepControl_VIEW_H
+#define SleepControl_VIEW_H
+
+//#include "BaseView.h"
+#include "View.h"
+#include "components/ui_swipe_view.h"
+#include "sleep/include/SleepControlView.h"
+#include "sleep/include/SleepTimeView.h"
+# include "sleep/include/SleepNapView.h"
+#include "sleep/include/SleepControlPresenter.h"
+
+namespace OHOS
+{
+    typedef enum
+    {
+        MAINSLEEPVIEW = 0, // 主视图
+        SLEEPTIMEVIEW,     // 详细视图
+        SLEEPNAPVIEW,       //小睡 
+        MAX_SLEEPVIEW,
+    } SleepControlPageId;
+
+#define SLEEPVIEW "sleepview"
+
+    class SleepControlPresenter;
+    class SleepControlView : public View<SleepControlPresenter>
+    {
+
+    public:
+        SleepControlView();
+        virtual ~SleepControlView();
+        static SleepControlView *GetInstance(void);
+        UISwipeView *SleepControlViewInit(void);
+        void ClearAll(void);
+
+        AppGroupView *SleepPageInit(void);
+        AppGroupView *SleepTimePageInit(void);
+        AppGroupView *SleepNapPageInit(void);
+
+        SleepView *GetSleepView(void);
+        SleepTimeView *GetSleepTimeView(void);
+        SleepNapView *GetSleepNapView(void);
+
+        UISwipeView *GetSleepControlPageView(void);
+        void ChangeView(int16_t hideView, int16_t showView);
+
+    public:
+        void OnStart() override;
+
+    private:
+        SleepView *sleepView{nullptr};
+        SleepTimeView *sleeptimeView{nullptr};
+        SleepNapView *sleepnapView{nullptr};
+
+    private:
+        int16_t maxPage = MAX_SLEEPVIEW;
+        UISwipeView *SleepSwipeViewList{nullptr};
+        AppGroupView *recordCard[MAX_SLEEPVIEW]{nullptr};
+        AppGroupView *CreatePage(uint8_t SleepControlPageId);
+    };
+} // namespace OHOS
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepModel.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepModel.h
new file mode 100644 (file)
index 0000000..2a4f8fa
--- /dev/null
@@ -0,0 +1,170 @@
+
+
+#ifndef Sleep_MODEL_H
+#define Sleep_MODEL_H
+
+#include <cstdint>
+#include <map>
+// #include "AppViewIDs.h"
+// #include "UiConfig.h"
+// #include "sleep/include/SleepView.h"
+// #include "sleep/include/SleepControlPresenter.h"
+#include "string"
+
+#define SLEEP_TIME_PATH "/user/userdata/sleep/%s/sleep_time.bin"
+#define SLEEP_STATUS_PATH "/user/userdata/sleep/%s/sleep_status.bin"
+
+#define NAP_PATH "/user/userdata/sleep/%s/nap.bin"
+#define SLEEP_DIR_PATH "/user/userdata/sleep/%s"
+
+#define SLEEP_DATA_DIR "/user/userdata/sleep/"
+
+#define SLEEP_STATUS_LENGTH 80
+
+namespace OHOS
+{
+#pragma pack(push, 1)
+    typedef struct
+    {
+        uint32_t fall_asleep_timestamp; // 入睡
+        uint32_t wake_up_timestamp;     // 出睡
+        uint16_t total_time;            // 总时长
+    } NAP_T;
+
+    typedef struct
+    {
+        uint32_t fall_asleep_timestamp; // 入睡
+        uint32_t wake_up_timestamp;     // 出睡
+        uint16_t total_time;            // 总时长
+    } SLEEP_T;
+
+    typedef struct
+    {
+        uint32_t timestamp; //时间戳
+        uint8_t stat;       // 状态
+    } SLEEP_STAT_T;
+
+#pragma pack (pop)
+
+    // bool save_nap_data(NAP_T *data);
+    // uint32_t get_nap_data_size(void);
+    // bool sleep_mutex_init(void);
+    uint32_t read_sleep_nap_data(char *data, uint32_t size, FILE *fp);
+    void set_nap_data(NAP_T *data);
+    void set_sleep_data(SLEEP_T *data);
+    // bool save_sleep_data(SLEEP_T *data);
+    bool read_sleep_data(SLEEP_T *data);
+    void read_wear_data(void);
+    bool read_nap_data(NAP_T *data);
+    // void clean_sleep_data(void);
+    // bool create_sleep_folder(void);
+    std::string get_sleep_asleep_time_str(void);
+    std::string get_sleep_wake_time_str(void);
+    std::string get_wear_status_str(void);
+    std::string get_sleep_star_str(void);
+    //void clean_sleep_file(void);
+    // 睡眠状态
+    enum class SLEEPSTATE
+    {
+        WAKE = 0,
+        SLEEPNOTIFY,
+        SLEPP,
+    };
+    // 睡眠存储数据
+    typedef struct
+    {
+        std::string sleeptime;    // 睡眠时间
+        std::string waketime;     // 醒来时间
+        uint32_t sleep_timestamp; // 睡眠时间戳
+        uint32_t wake_timestamp;  // 醒来时间戳
+        int totaltime;            // 睡眠总时间
+    } SleepDataUI;
+    class SleepModel
+    {
+    public:
+        static SleepModel &GetInstance(void);
+        void update_time_info(uint32_t timestamp, std::string &timeStr);
+        void update_sleep(SLEEP_T *data);
+        void ReInitData(); // 重新刷新UI
+        void Msg_ReInitData();
+        void read_sleep_file_data();
+        void msg_save_sleep_data();
+
+        void set_sleep_goal();
+        int get_sleep_hour();
+        int get_sleep_min();
+        int get_sleep_goal();
+        int get_sleep_total();
+
+        //清除睡眠数据
+        void clean_sleep_data(void);
+        
+        std::string get_rest_str();      // 解析入睡时间
+        std::string get_wake_str();      // 解析醒来时间
+        std::string get_goal_str();      // 解析目标休息时间
+        std::string get_notifiy();       // 获取提醒时间
+        std::string get_sleep_notifiy(); // 获取睡眠时间
+        std::string get_wake_notifiy();  // 获取起床时间
+
+        //小睡数据
+        int get_nap_hour();
+        int get_nap_min();
+        std::string get_napsleep_str();      // 解析入睡时间
+        std::string get_napwake_str();       // 解析醒来时间
+
+
+        void set_sleep_state(SLEEPSTATE state);
+        SLEEPSTATE get_sleep_state();
+        SleepDataUI *ReadSleepData();                // 读取睡眠数据
+        bool SaveSleepData(const SleepDataUI &data); // 更新睡眠数据
+        bool DeleteSleepData();                      // 清空睡眠文件
+
+        bool CheckSleepTime();//对睡眠时间进行校验
+
+        void UpdateSleepView();
+        std::string GetUpdateSleepTime();
+
+        /*定时器相关*/
+        void Sleep_StartTimer(uint32_t interval);
+        void Sleep_StopTimer(void);
+
+        /*主界面卡片相关*/
+        void SetCardId(int cardid)
+        {
+            CradId = cardid;
+        }
+        int GetCardId()
+        {
+            return CradId;
+        }
+
+    private:
+        SleepModel();
+        SleepModel(const SleepModel &);
+        SleepModel &operator=(const SleepModel &);
+        virtual ~SleepModel();
+
+        std::string sleepStr{"--"};
+        std::string wakeStr{"--"};
+        std::string goalStr{"--"};
+        std::string napsleepStr{"--"};
+        std::string napwakeStr{"--"};
+
+        std::string goalnotifyStr{"--"};
+        std::string goalsleepStr{"--"};
+        std::string goalwakeStr{"--"};
+
+        std ::string sleep_time_str{"--"};
+
+        int sleep_total_time = 0;
+        int goal_total_time = 0;
+        int nap_total_time = 0;
+
+        uint32_t sleep_update_time{0};
+
+        SLEEPSTATE sleepstate_ = SLEEPSTATE::WAKE;
+        int CradId = 0; // 主界面状态
+    };
+}
+
+#endif // Sleep_MODEL_H
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepModelC.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepModelC.h
new file mode 100644 (file)
index 0000000..9a28746
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2024-10-03 17:09:01
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2024-10-03 18:12:11
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/include/SleepModelC.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+#ifndef SLEEPMODELC_H
+#define SLEEPMODELC_H
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C"
+{
+#endif
+#endif
+    void custom_save_sleep_data(void);
+    void custom_save_nap_data(void);
+    void custom_read_sleep_data(void);
+    void custom_read_nap_data(void);
+    void custom_sleep_model_updata(void);
+    void update_sleep_data(uint32_t sleep_timestamp,uint32_t wake_timestamp,uint32_t totaltime);
+    void update_nap_data(uint32_t sleep_timestamp,uint32_t wake_timestamp,uint32_t totaltime);
+    void custom_read_wear_data(void);
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif
+#endif
+#endif
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepNapView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepNapView.h
new file mode 100644 (file)
index 0000000..82d1cdd
--- /dev/null
@@ -0,0 +1,69 @@
+/***
+ * @Date: 2024-06-25 14:50:26
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditNap: 2024-07-01 15:10:12
+ * @FilePath:
+ * /FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/include/SleepNapView.h
+ */
+/***
+ * @Date: 2024-06-25 14:50:26
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditNap: 2024-06-25 17:29:03
+ * @FilePath:
+ * /XTS_FD230/FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/include/SleepNapView.h
+ */
+/***
+ * @Date: 2024-06-25 14:50:26
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditNap: 2024-06-25 16:30:55
+ * @FilePath:
+ * /XTS_FD230/FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/include/SleepNapView.h
+ */
+
+#ifndef Sleep_Nap_VIEW_H
+#define Sleep_Nap_VIEW_H
+
+//#include "BaseView.h"
+#include "View.h"
+
+#include "components/root_view.h"
+#include "components/ui_circle_progress.h"
+#include "components/ui_image_animator.h"
+#include "components/ui_image_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_scroll_view.h"
+#include "components/ui_view_group.h"
+
+#include "AppGroupView.h"
+#include "wearable_log.h"
+#include <iostream>
+
+namespace OHOS {
+class SleepNapView : public AppGroupView {
+
+public:
+  SleepNapView();
+  virtual ~SleepNapView();
+  static SleepNapView *GetInstance(void);
+  bool InitPage(void);
+  virtual bool InitView(void *caller) override;
+  void ClearAll();
+  bool GetInitViewState(void);
+  void SleepDataRefresh();
+
+private:
+  UILabelExt *napsleeptitle{nullptr};
+  UILabelExt *napwaketitle{nullptr};
+  UILabelExt *naptitle{nullptr};
+  UILabelExt *napsleep{nullptr};
+  UILabelExt *napwake{nullptr};
+  UILabelExt *apptitle{nullptr}; // 详情
+
+  UIImageView *transverseline_1{nullptr}; // 横线1
+  UIImageView *transverseline_2{nullptr}; // 横线2
+  UIImageView *verticalline{nullptr};     // 竖线
+  bool viewInitStatus{false};
+};
+} // namespace OHOS
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepTimeView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepTimeView.h
new file mode 100644 (file)
index 0000000..41404f9
--- /dev/null
@@ -0,0 +1,73 @@
+/***
+ * @Date: 2024-06-25 14:50:26
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-07-01 15:10:12
+ * @FilePath:
+ * /FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/include/SleepTimeView.h
+ */
+/***
+ * @Date: 2024-06-25 14:50:26
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-06-25 17:29:03
+ * @FilePath:
+ * /XTS_FD230/FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/include/SleepTimeView.h
+ */
+/***
+ * @Date: 2024-06-25 14:50:26
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-06-25 16:30:55
+ * @FilePath:
+ * /XTS_FD230/FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/include/SleepTimeView.h
+ */
+
+#ifndef Sleep_Time_VIEW_H
+#define Sleep_Time_VIEW_H
+
+//#include "BaseView.h"
+#include "View.h"
+
+#include "components/root_view.h"
+#include "components/ui_circle_progress.h"
+#include "components/ui_image_animator.h"
+#include "components/ui_image_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_scroll_view.h"
+#include "components/ui_view_group.h"
+
+#include "AppGroupView.h"
+#include "wearable_log.h"
+#include <iostream>
+
+namespace OHOS {
+class SleepTimeView : public AppGroupView {
+
+public:
+  SleepTimeView();
+  virtual ~SleepTimeView();
+  static SleepTimeView *GetInstance(void);
+  bool InitPage(void);
+  virtual bool InitView(void *caller) override;
+  void ClearAll();
+  bool GetInitViewState(void);
+  void SleepDataRefresh();
+
+private:
+  void DumpWeatherInfo();
+
+private:
+  UILabelExt *resttitle{nullptr};         // 作息时间标题
+  UILabelExt *sleeptitle{nullptr};        // 入睡时间标题
+  UILabelExt *waketitle{nullptr};         // 醒来标题
+  UILabelExt *goaltime{nullptr};          // 目标时长
+  UILabelExt *goal{nullptr};              // 作息时间
+  UILabelExt *sleep{nullptr};             // 入睡时间
+  UILabelExt *wake{nullptr};              // 醒来时间
+  UIImageView *transverseline_1{nullptr}; // 横线1
+  UIImageView *transverseline_2{nullptr}; // 横线2
+  UIImageView *verticalline{nullptr};     // 竖线
+  UIImageView *upiconimage{nullptr};
+  bool viewInitStatus{false};
+};
+} // namespace OHOS
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepView.h b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/include/SleepView.h
new file mode 100644 (file)
index 0000000..b506f39
--- /dev/null
@@ -0,0 +1,60 @@
+/*** 
+ * @Date: 2024-06-25 10:32:22
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-06-25 17:52:16
+ * @FilePath: /XTS_FD230/FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/include/SleepView.h
+ */
+
+#ifndef Sleep_VIEW_H
+#define Sleep_VIEW_H
+
+//#include "BaseView.h"
+#include "View.h"
+
+#include "components/root_view.h"
+#include "components/ui_view_group.h"
+#include "components/ui_scroll_view.h"
+#include "components/ui_label_ext.h"
+#include "components/ui_image_view.h"
+#include "components/ui_image_animator.h"
+#include "components/ui_circle_progress.h"
+
+#include "wearable_log.h"
+#include "AppGroupView.h"
+#include <iostream>
+
+namespace OHOS
+{
+    class SleepView : public AppGroupView
+    {
+    public:
+        SleepView();
+        virtual ~SleepView();
+        static SleepView *GetInstance(void);
+        bool InitPage(void);
+        virtual bool InitView(void *caller) override;
+        void ClearAll();
+        bool GetInitViewState(void);
+        void SleepDataRefresh(); // 刷新睡眠数据
+
+    private:
+        UICircleProgress *circleProgress_{nullptr}; // 进度条
+
+        UILabelExt *title{nullptr};
+        UILabelExt *hour{nullptr};
+        UILabelExt *minute{nullptr};
+
+        UILabel *time_hour{nullptr};   // 睡眠时间[小时]
+        UILabel *time_minute{nullptr}; // 睡眠时间[分钟]
+
+        UILabelExt *sleep_update_time{nullptr}; // 目标时间
+
+        UIImageView *roomimage{nullptr};
+        UIImageView *upiconimage{nullptr};
+        UIImageView *progress_image = nullptr;
+
+        bool viewInitStatus{false};
+    };
+} // namespace OHOS
+
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepCardView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepCardView.cpp
new file mode 100644 (file)
index 0000000..97ce35c
--- /dev/null
@@ -0,0 +1,103 @@
+/***\r
+ * @Date: 2024-06-25 10:41:40\r
+ * @LastEditors: Caisking 3449750381@qq.com\r
+ * @LastEditTime: 2024-06-26 11:27:04\r
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/src/SleepCardView.cpp\r
+ */\r
+#include "sleep/include/SleepCardView.h"\r
+#include "sleep/include/SleepControlView.h"\r
+#include "sleep/include/SleepControlPresenter.h"\r
+namespace OHOS\r
+{\r
+    static SleepCardView *g_pSleepCardView = nullptr;\r
+    SleepCardView::SleepCardView()\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SleepCardView::SleepCardView");\r
+        SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);\r
+        g_pSleepCardView = this;\r
+    }\r
+    SleepCardView::~SleepCardView()\r
+    {\r
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SleepCardView::~SleepCardView");\r
+        ClearAll();\r
+        g_pSleepCardView = nullptr;\r
+    }\r
+    SleepCardView *SleepCardView::GetInstance()\r
+    {\r
+        return g_pSleepCardView;\r
+    }\r
+    void SleepCardView::ClearAll(void)\r
+    {\r
+        if (viewiInitStatus == true)\r
+        {\r
+            RemoveAll();\r
+            if (sleepcontrolView != nullptr)\r
+            {\r
+                if (sleepOnSwipeListener != nullptr)\r
+                {\r
+                    delete sleepOnSwipeListener;\r
+                    sleepOnSwipeListener = nullptr;\r
+                }\r
+\r
+                if (sleepcontrolView != nullptr)\r
+                {\r
+                    delete sleepcontrolView;\r
+                    sleepcontrolView = nullptr;\r
+                }\r
+                if(SleepSwipView)\r
+                {\r
+                    delete SleepSwipView;\r
+                    SleepSwipView = nullptr;\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    bool SleepCardView::InitView(void)\r
+    {\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepCardView::InitView");\r
+        sleepcontrolView = new SleepControlView();\r
+        if (sleepcontrolView == nullptr)\r
+        {\r
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SleepView::new SleepView fail!");\r
+            return false;\r
+        }\r
+\r
+        SleepSwipView = dynamic_cast<UISwipeView *>(sleepcontrolView->GetSleepControlPageView());\r
+        if (SleepSwipView == nullptr)\r
+        {\r
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SleepView->SleepViewInit() == nullptr!!");\r
+            return false;\r
+        }\r
+\r
+        sleepOnSwipeListener = static_cast<UISwipeView::OnSwipeListener *>(new SleepOnSwipeListener());\r
+        if (sleepOnSwipeListener == nullptr)\r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sleepOnSwipeListener new fail");\r
+            return false;\r
+        }\r
+        SleepSwipView->SetOnSwipeListener(sleepOnSwipeListener);\r
+        Add(SleepSwipView);\r
+\r
+        return true;\r
+    }\r
+    UISwipeView *SleepCardView::GetSleepCardView()\r
+    {\r
+        return SleepSwipView;\r
+    }\r
+    void SleepCardView::PreLoad(void)\r
+    {\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepCardView::PreLoad viewiInitStatus %d",viewiInitStatus);\r
+        if (!viewiInitStatus)\r
+        {\r
+            InitView();\r
+            viewiInitStatus = true;\r
+        }\r
+    }\r
+\r
+    void SleepCardView::UnLoad(void)\r
+    {\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepCardView::UnLoad");\r
+    }\r
+\r
+}
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepControlPresenter.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepControlPresenter.cpp
new file mode 100644 (file)
index 0000000..1dcecc1
--- /dev/null
@@ -0,0 +1,121 @@
+/***
+ * @Date: 2024-06-25 10:33:08
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-07-12 20:00:41
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/src/SleepControlPresenter.cpp
+ */
+#include "AppViewIDs.h"
+#include "NativeAbility.h"
+#include "sleep/include/SleepControlPresenter.h"
+#include "common/key_code.h"
+#include "common/key_code.h"
+#include <custom_utils.h>
+#include <ohos_types.h>
+#include "UiConfig.h"
+#include "string.h"
+#include "gfx_utils/mem_check.h"
+#include "NativeRegisterManager.h"
+#include "uicomponents/UIComponents.h"
+namespace OHOS
+{
+
+    REGIST_MENU_PRO(VIEW_SLEEP, SleepControlView, SleepControlPresenter,
+        PNG_APPLIST_SLEEP_IMAGE_BIG, PNG_APPLIST_SLEEP_IMAGE, PNG_APPLIST_SLEEP_IMAGE, "睡眠", STR_REMOTE_SHOOTING);
+
+    // 当前Presenter属性实例化的内存指针
+    static SleepControlPresenter *g_pSleepControlPresenter = nullptr;
+
+    SleepControlPresenter::SleepControlPresenter()
+    {
+        // SleepModel = &SleepModel::GetInstance();
+        g_pSleepControlPresenter = this;
+#ifdef MEM_CHECK
+        MemCheck::GetInstance()->EnableLeakCheck(true);
+#endif
+    }
+
+    SleepControlPresenter::~SleepControlPresenter()
+    {
+        g_pSleepControlPresenter = nullptr;
+#ifdef MEM_CHECK
+        MemCheck::GetInstance()->EnableLeakCheck(false);
+#endif
+    }
+
+    SleepControlPresenter *SleepControlPresenter::GetInstance()
+    {
+
+        return g_pSleepControlPresenter;
+    }
+
+    void SleepControlPresenter::OnStart()
+    {
+        Presenter<SleepControlView>::OnStart();
+    }
+
+    void SleepControlPresenter::OnPause(void)
+    {
+        Presenter<SleepControlView>::OnPause();
+    }
+
+    void SleepControlPresenter::OnResume(void)
+    {
+        Presenter<SleepControlView>::OnResume();
+    }
+
+    void SleepControlPresenter::OnStop(void)
+    {
+        Presenter<SleepControlView>::OnStop();
+    }
+
+    bool SleepControlPresenter::OnDrag(UIView &view, const DragEvent &event)
+    {
+        UNUSED(view);
+        if ((event.GetDeltaX() > X_DRAG_OFFSET) && (event.GetDeltaX() > (DOUBLES * MATH_ABS(event.GetDeltaY())))) // 拖动过程中判断是否是水平滑动
+        {
+            SleepControlPresenter::X_DRAG_FLAG = true;
+        }
+        return true;
+    }
+
+    bool SleepControlPresenter::OnDragEnd(UIView &view, const DragEvent &event)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " SleepControlPresenter::OnDragEnd");
+        UNUSED(view);
+        if (event.GetDragDirection() == DragEvent::DIRECTION_LEFT_TO_RIGHT && SleepControlPresenter::X_DRAG_FLAG)
+        {
+            NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+        }
+        return true;
+    }
+
+    bool SleepControlPresenter::OnClick(UIView &view, const ClickEvent &event)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, " SleepControlPresenter::OnClick");
+
+        UNUSED(view);
+        UNUSED(event);
+        return true;
+    }
+
+    // 增加按键事件
+    bool SleepControlPresenter::OnKeyAct(UIView &view, const KeyEvent &event)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SettingPresenter::OnKeyAct");
+        uint16 keyID = event.GetKeyId();
+        uint16_t keyState = event.GetState();
+        // 如果是power键就返回上一级
+        if (keyID == static_cast<uint16_t>(ZliteKeyCode::ZLITE_KEY_POWER) && keyState == 1 && uapi_get_screen_state() == 0)
+        {
+            NativeAbility::GetInstance().Back(TransitionType::TRANSITION_BACK_TO_HEXAGONS);
+        }
+        return true;
+    }
+
+    void SleepControlPresenter::OnSwipe(UISwipeView &view) {}
+    void SleepOnSwipeListener::OnSwipe(UISwipeView &view)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepOnSwipeListener::OnSwipe,current tab index = %d", view.GetCurrentPage());
+        return;
+    }
+}
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepControlView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepControlView.cpp
new file mode 100644 (file)
index 0000000..dd1492e
--- /dev/null
@@ -0,0 +1,217 @@
+/***
+ * @Date: 2024-09-02 14:46:10
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-09-03 16:01:25
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/src/SleepControlView.cpp
+ */
+/***
+ * @Date: 2024-06-25 10:41:15
+ * @LastEditors: Caisking 3449750381@qq.com
+ * @LastEditTime: 2024-06-25 14:54:49
+ * @FilePath: /XTS_FD230/FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/src/SleepControlControlView.cpp
+ */
+
+#include "sleep/include/SleepControlView.h"
+#include "sleep/include/SleepControlPresenter.h"
+#include "sleep/include/SleepModel.h"
+#include "wearable_log.h"
+namespace OHOS
+{
+    static SleepControlView *g_pSleepControlView{nullptr};
+    SleepControlView::SleepControlView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SleepControlView::SleepControlView");
+        g_pSleepControlView = this;
+    }
+
+    SleepControlView::~SleepControlView()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "SleepControlView::~SleepControlView");
+        ClearAll();
+        g_pSleepControlView = nullptr;
+    }
+
+    SleepControlView *SleepControlView::GetInstance(void)
+    {
+        return g_pSleepControlView;
+    }
+
+    void SleepControlView::ClearAll(void)
+    {
+        if (SleepSwipeViewList != nullptr)
+        {
+            for (int32_t i = 0; i < maxPage; i++)
+            {
+                recordCard[i] = nullptr;
+            }
+            
+            SleepSwipeViewList->RemoveAll();
+
+            delete sleepView;
+            sleepView = nullptr;
+
+            delete sleeptimeView;
+            sleeptimeView = nullptr;
+
+            delete sleepnapView;
+            sleepnapView = nullptr;
+
+            delete SleepSwipeViewList;
+            SleepSwipeViewList = nullptr;
+        }
+    }
+    /*初始化主睡眠界面VIEW*/
+    UISwipeView *SleepControlView::SleepControlViewInit(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepControlView::SleepControlViewInit");
+        SleepSwipeViewList = new UISwipeView(UISwipeView::VERTICAL);
+        if (nullptr == SleepSwipeViewList)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepSwipeViewList new fail!!");
+            return nullptr;
+        }
+
+        SleepSwipeViewList->SetStyle(STYLE_BACKGROUND_COLOR, Color::Black().full);
+        SleepSwipeViewList->SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);
+        // SleepSwipeViewList->SetAnimatorTime(50);
+        SleepSwipeViewList->SetDraggable(true);
+        SleepSwipeViewList->SetTouchable(true);
+        for (uint16_t i = 0; i < maxPage; i++)
+        {
+            recordCard[i] = CreatePage(i);
+            if (nullptr == recordCard[i])
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "recordCard[%d] is nullptr!!", i);
+                return nullptr;
+            }
+            recordCard[i]->InitView(this);
+            SleepSwipeViewList->Add(recordCard[i]);
+        }
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepControlView InitPage over!!");
+        return SleepSwipeViewList;
+    }
+
+    /*获取睡眠主界面*/
+    UISwipeView *SleepControlView::GetSleepControlPageView()
+    {
+        return SleepControlViewInit();
+    }
+
+    /*OnStart 增加界面控制*/
+    void SleepControlView::OnStart()
+    {
+        View<SleepControlPresenter>::OnStart();
+        AddViewToRootContainer(new UIViewGroup());
+        GetRootContainer()->SetPosition(0, 0, Screen::GetInstance().GetWidth(), Screen::GetInstance().GetHeight());
+        GetRootContainer()->SetTouchable(true);
+        GetRootContainer()->SetDraggable(true);
+        AddViewToRootContainer(GetSleepControlPageView());
+        // RootView::GetInstance()->Add(GetSleepControlPageView());
+
+        if (SleepSwipeViewList == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepSwipeViewList is nullptr!");
+            return;
+        }
+
+        auto sleepPresenter = dynamic_cast<OHOS::SleepControlPresenter *>(OHOS::SleepControlPresenter::GetInstance());
+        if (sleepPresenter == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to get SleepControlPresenter instance");
+            return;
+        }
+
+        SleepSwipeViewList->SetOnClickListener(sleepPresenter);
+        SleepSwipeViewList->SetOnDragListener(sleepPresenter);
+        SleepSwipeViewList->SetOnSwipeListener(sleepPresenter);
+
+        RootView::OnKeyActListener *keyactListener = dynamic_cast<RootView::OnKeyActListener *>(sleepPresenter);
+        if (keyactListener == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to set key act listener");
+            return;
+        }
+
+        RootView::GetInstance()->SetOnKeyActListener(keyactListener);
+    }
+   
+
+    SleepView *SleepControlView::GetSleepView(void)
+    {
+        return sleepView;
+    }
+
+    SleepTimeView *SleepControlView::GetSleepTimeView(void)
+    {
+        return sleeptimeView;
+    }
+    SleepNapView *SleepControlView::GetSleepNapView(void)
+    {
+        return sleepnapView;
+    }
+    AppGroupView *SleepControlView::SleepPageInit(void)
+    {
+        sleepView = new SleepView();
+        if (sleepView == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sleepView::new SleepView fail!");
+            return nullptr;
+        }
+
+        return sleepView;
+    }
+
+    AppGroupView *SleepControlView::SleepTimePageInit(void)
+    {
+        sleeptimeView = new SleepTimeView();
+        if (sleeptimeView == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sleeptimeView::new SleepTimeView fail!");
+            return nullptr;
+        }
+
+        return sleeptimeView;
+    }
+    AppGroupView *SleepControlView::SleepNapPageInit(void)
+    {
+        sleepnapView = new SleepNapView();
+        if (sleepnapView == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sleepnapView::new SleepNapView fail!");
+            return nullptr;
+        }
+
+        return sleepnapView;
+    }
+
+    struct SleepControlViewMapper
+    {
+        const int16_t viewId;
+        AppGroupView *(SleepControlView::*func)(void);
+    };
+
+    static const SleepControlViewMapper g_pageMapper[] = {
+        {MAINSLEEPVIEW, &SleepControlView::SleepPageInit},
+        {SLEEPTIMEVIEW, &SleepControlView::SleepTimePageInit},
+        {SLEEPNAPVIEW, &SleepControlView::SleepNapPageInit},
+    };
+
+    AppGroupView *SleepControlView::CreatePage(uint8_t SleepControlPageId)
+    {
+        uint16_t i;
+        AppGroupView *view = nullptr;
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CreatePage SleepControlPageId:%d", SleepControlPageId);
+
+        for (i = 0; i < sizeof(g_pageMapper) / sizeof(g_pageMapper[0]); i++)
+        {
+            if (g_pageMapper[i].viewId == SleepControlPageId)
+            {                                             // 正确使用 SleepControlPageId 来匹配视图ID
+                view = (this->*(g_pageMapper[i].func))(); // 如果找到匹配项,则调用相应的函数创建视图
+                WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "CreatePage view:%p", view);
+                return view; // 返回创建的视图
+            }
+        }
+        return nullptr; // 如果没有找到匹配的视图ID,返回 nullptr
+    }
+
+}
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepModel.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepModel.cpp
new file mode 100644 (file)
index 0000000..b4024fd
--- /dev/null
@@ -0,0 +1,1019 @@
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: SLEPPNOTIFY24-06-26 19:36:48
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2024-11-27 11:15:14
+ * @FilePath:
+ * /FD230/code/sdk/application/wearable/fd230app/nativeui/sleep/src/SleepModel.cpp
+ * @Description:
+ *
+ * Copyright (c) SLEPPNOTIFY24 by ${git_name_email}, All Rights Reserved.
+ */
+
+#include "sleep/include/SleepModel.h"
+#include "ConfigModel.h"
+#include "UiConfig.h"
+#include "custom_utils.h"
+#include "heart_blood/health_service/health_service.h"
+#include "kv_store.h"
+#include "samgr_lite.h"
+#include "securec.h"
+#include "sleep/include/SleepControlPresenter.h"
+#include "ui_resource_image.h"
+#include "wearable_log.h"
+#include <dirent.h>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <string>
+#include <sys/stat.h>
+#include <vector>
+
+#include "ConfigModelC.h"
+#include "MainModel.h"
+#include "broadcast_feature.h"
+#include "broadcast_service.h"
+#include "cmsis_os.h"
+#include "custom_runtime.h"
+//#include "cywee_service.h"
+#include "power_display_service.h"
+#include "sleep/include/SleepModelC.h"
+#include "thread_adapter.h"
+#include "ui_service.h"
+#include <cmsis_os2.h>
+#include <service/graphic_service.h>
+
+extern "C" errcode_t uapi_get_TIME_STR(uint32_t time, char *p_time,
+                                       char date_separator, char time_separator,
+                                       date_format_t format);
+extern "C" int get_sleep_time_from_config_model(void);
+extern "C" int get_wake_up_time_from_config_model();
+
+
+static uint32_t len = 0;
+static OHOS::SLEEP_STAT_T *wear_stat;
+namespace OHOS
+{
+#define SLEPPNOTIFY 20
+
+  static NAP_T nap_data = {0};
+  static SLEEP_T sleep_data = {0};
+
+  static uint32_t sleep_update_timestamp = 0;
+  static uint32_t nap_update_timestamp = 0;
+
+  void SleepModel::clean_sleep_data(void)
+  {
+      sleep_update_timestamp = 0;
+      nap_update_timestamp = 0;
+      memset(&sleep_data,0,sizeof(SLEEP_T));
+      memset(&nap_data, 0, sizeof(NAP_T));
+  }
+
+  /*获取最新睡眠时间戳*/
+  uint32_t get_sleep_update_timestamp(void)
+  {
+    if (nap_update_timestamp <= sleep_update_timestamp)
+      return sleep_update_timestamp;
+    else
+      return nap_update_timestamp;
+  }
+
+  static char nap_file_path[64] = {0};
+  
+
+  bool is_regular_file(const std::string &file_name)
+  {
+    struct stat file_stat;
+    if (stat(file_name.c_str(), &file_stat) != 0)
+    {
+      return false;
+    }
+
+    return S_ISREG(file_stat.st_mode); // 检查文件是否为普通文件
+  }
+
+  std::string get_wear_status_str(void) 
+  {
+      std::string result;
+      std::string wear_status;
+        // 进行文件读取
+        do_custom_fileoperate_service_check_msg(  
+            CUSTOM_FILEOPERATE_MSG_TYPE_WEAR_DATA_READ, nullptr, 0);  
+        LOS_Msleep(100); // 等待文件系统准备  
+
+        if(len == 0)
+            return result;
+
+        for(int i = 0; i < len/5; i++)
+        {
+            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,"data.timestamp : %d , data.stat : %d", wear_stat[i].timestamp,wear_stat[i].stat);
+            if(wear_stat[i].stat)
+                wear_status = "已配戴";
+            else
+                wear_status = "未配戴";
+
+            std::string timestr;
+            char labelTime[20] = {0};
+
+            if (uapi_get_TIME_STR(wear_stat[i].timestamp, labelTime, '.', ':', DATE_Y_M_D_H_M) != ERRCODE_SUCC)  
+            {  
+                timestr = "--";  
+            }  
+            else  
+            {  
+                timestr = labelTime;  
+            } 
+
+            result += wear_status + ":"+ timestr + "\n";
+        }
+        free(wear_stat);
+        return result; // 返回结果字符串  
+    } 
+
+  std::string get_sleep_star_str(void)
+  {
+
+      std::string result;
+
+      uint16_t datelen = 0;
+      uint8_t sleep_data[256] = {0}; 
+      
+      uint32_t asleep_time = 0;
+      uint32_t wake_up_time = 0;
+      uint16_t total_time = 0;
+      uint16_t total_deep_sleep_time = 0;
+      uint16_t total_mild_sleep_time = 0;
+      uint16_t total_rem_sleep_time = 0;
+      uint16_t total_wake_time = 0;
+      uint32_t timestampe = 0;
+      int status = -1;
+      uint8_t index = 0;
+      char timestampe_str[10] = {0};
+      char status_str[20] = {0};
+
+      char day[12] = {0};
+      uapi_get_YYMMDD_Time(day, '\0');
+
+      char file_path[64] = {0};
+      sprintf_s(file_path, 64, SLEEP_TIME_PATH, day);
+
+      uapi_get_file_data(file_path,sleep_data,&datelen);
+
+      if(datelen == 0)
+      {
+          PRINT("fread error datelen == 0 \n");
+          return "没有文件";
+      }
+
+      asleep_time = *(uint32_t*)&sleep_data[1];
+      wake_up_time = *(uint32_t*)&sleep_data[5];
+
+      total_time = sleep_data[9] * 60 + sleep_data[10];
+      total_deep_sleep_time = sleep_data[11]  * 60 + sleep_data[12];
+      total_mild_sleep_time = sleep_data[13]  * 60 + sleep_data[14];
+      total_rem_sleep_time = sleep_data[15] * 60 + sleep_data[16];
+      total_wake_time = sleep_data[17] * 60 + sleep_data[18];
+
+      char asleep_time_str[10] = {0};
+      uapi_get_TIME_STR(asleep_time,asleep_time_str, '.', ':',DATE_H_M);
+
+      char wake_up_time_str[10] = {0};
+      uapi_get_TIME_STR(wake_up_time,wake_up_time_str, '.', ':',DATE_H_M);
+
+
+      result += std::string("入睡时间: ") + asleep_time_str + " " + std::to_string(asleep_time) + "\n";  
+      result += std::string("出睡时间: ") + wake_up_time_str + " " + std::to_string(wake_up_time) + "\n";  
+      result += std::string("总时长: ") + std::to_string(total_time) +  "\n";  
+      result += std::string("深睡时长: ") + std::to_string(total_deep_sleep_time) +  "\n";  
+      result += std::string("浅睡时长: ") + std::to_string(total_mild_sleep_time) +  "\n";  
+      result += std::string("快速眼动时长: ") + std::to_string(total_rem_sleep_time) +  "\n";  
+      result += std::string("清醒时长: ") + std::to_string(total_wake_time) +  "\n";   
+
+      // PRINT("入睡时间 : %s %d \n",asleep_time_str,asleep_time);
+      // PRINT("出睡时间 : %s %d \n",wake_up_time_str,wake_up_time);
+      // PRINT("总时长 : %d 分钟\n",total_time);
+      // PRINT("深睡时长 : %d 分钟\n",total_deep_sleep_time);
+      // PRINT("浅睡时长 : %d 分钟\n",total_mild_sleep_time);
+      // PRINT("快速眼动时长 : %d 分钟\n",total_rem_sleep_time);
+      // PRINT("清醒时长 : %d 分钟\n",total_wake_time);
+
+      char statuspath[64] = {0};
+      uapi_get_YYMMDD_Time(day, '\0');
+      sprintf_s(statuspath, 64, SLEEP_STATUS_PATH, day);
+
+
+      memset(sleep_data,0,sizeof(sleep_data));
+      datelen = 0;
+      uapi_get_file_data(statuspath,sleep_data,&datelen);
+      
+      if(datelen == 0)
+      {
+          PRINT("fread error datelen == 0 \n");
+          return result += "\n 没有状态文件";
+      }
+
+      while(datelen)
+      {
+          memset(timestampe_str,0,sizeof(timestampe_str));
+          memset(status_str,0,sizeof(status_str));
+          timestampe = *(uint32_t*)&sleep_data[index];
+          uapi_get_TIME_STR(timestampe,timestampe_str, '.', ':',DATE_H_M);
+          status = sleep_data[index + 4];
+          //0进入睡眠  1潜睡 2深睡 3清醒 4结束睡眠 6入睡 7出睡最后一笔输出 8未出睡最后一笔输出 12快速动眼 13取消入睡
+          switch(status)
+          {
+              case 0:
+                  strcpy(status_str,"进入睡眠");
+                  break;
+              case 1:
+                  strcpy(status_str,"浅睡");
+                  break;
+              case 2:
+                  strcpy(status_str,"深睡");
+                  break;
+              case 3:
+                  strcpy(status_str,"清醒");
+                  break;
+              case 4:
+                  strcpy(status_str,"结束睡眠");
+                  break;
+              case 6:
+                  strcpy(status_str,"入睡通知");
+                  break;
+              case 7:
+                  strcpy(status_str,"出睡最后一笔输出");
+                  break;
+              case 9:
+                  strcpy(status_str,"未出睡最后一笔输出");
+                  break;
+              case 12:
+                  strcpy(status_str,"快速动眼");
+                  break;
+              case 13:
+                  strcpy(status_str,"取消入睡");
+                  break;
+              default:
+                  break;
+
+          }
+
+          // PRINT("时间 :  %d %s  状态:%s\n",timestampe,timestampe_str,status_str);
+
+          result += std::string(status_str) + std::to_string(timestampe) +  "\n"; 
+
+          index+=5;
+          datelen -= 5;
+      }
+      return result;
+  }
+
+  std::string get_sleep_asleep_time_str(void)
+  {
+      std::string timestr;
+      char labelTime[20] = {0};
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sleep_data.fall_asleep_timestamp : %d",sleep_data.fall_asleep_timestamp);
+      if (uapi_get_TIME_STR(sleep_data.fall_asleep_timestamp, labelTime, '.', ':', DATE_Y_M_D_H_M) != ERRCODE_SUCC || !sleep_data.fall_asleep_timestamp)  
+      {  
+          timestr = "--";  
+      }  
+      else  
+      {  
+          timestr = labelTime;  
+      } 
+      return timestr;
+  }
+
+  std::string get_sleep_wake_time_str(void)
+  {
+      std::string timestr;
+      char labelTime[20] = {0};
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sleep_data.wake_up_timestamp : %d",sleep_data.wake_up_timestamp);
+      if (uapi_get_TIME_STR(sleep_data.wake_up_timestamp, labelTime, '.', ':', DATE_Y_M_D_H_M) != ERRCODE_SUCC || !sleep_data.wake_up_timestamp)  
+      {  
+          timestr = "--";  
+      }  
+      else  
+      {  
+          timestr = labelTime;  
+      } 
+      return timestr;
+  }
+
+  void read_wear_data(void)   
+  {
+      uint32_t size = 0;
+      len = uapi_get_file_size("user/userdata/wear.bin");
+      if(!len)
+        return;
+
+      wear_stat = (SLEEP_STAT_T *)malloc(len);
+      FILE *fp;
+
+      fp = fopen("user/userdata/wear.bin", "rb"); 
+      if (fp == NULL) 
+      {
+          WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "wear file open failed");
+          free(wear_stat);
+          return;
+      }
+
+      size = fread(wear_stat, 1, len, fp);
+      if(size != len)
+      {
+          free(wear_stat);
+          WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "wear file read failed");
+      }
+      fclose(fp);
+  }
+  
+  bool read_sleep_data(SLEEP_T *data)
+  {
+    char day[12] = {0};
+    uapi_get_YYMMDD_Time(day, '\0');
+
+    char file_path[64] = {0};
+    sprintf_s(file_path, 64, SLEEP_TIME_PATH, day);
+
+    FILE *fp = fopen(file_path, "rb");
+    if (fp == NULL)
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "read_sleep_data fopen fail %s \n",file_path);
+      // osal_mutex_unlock(&sleep_mutex);
+      return false;
+    }
+
+    // 读取睡眠类型
+    uint8_t sleep_type;
+    fread(&sleep_type, 1, 1, fp);
+
+    if (sleep_type == 0)
+    {
+      fclose(fp);
+      // osal_mutex_unlock(&sleep_mutex);
+      return false;
+    }
+
+    // 入睡时间
+    uint32_t fall_asleep_timestamp;
+    fread(&fall_asleep_timestamp, 1, 4, fp);
+
+    // 起床时间
+    uint32_t wake_up_timestamp;
+    fread(&wake_up_timestamp, 1, 4, fp);
+
+    // 睡眠总时间
+    uint8_t total_time_hour, total_time_minute;
+    fread(&total_time_hour, 1, 1, fp);
+    fread(&total_time_minute, 1, 1, fp);
+    uint16_t total_time = total_time_hour * 60 + total_time_minute;
+
+    // 累加睡眠数据
+    data->fall_asleep_timestamp = fall_asleep_timestamp;
+    data->wake_up_timestamp = wake_up_timestamp;
+    data->total_time = total_time;
+
+    sleep_update_timestamp = wake_up_timestamp;
+
+    fclose(fp);
+
+    // osal_mutex_unlock(&sleep_mutex);
+
+    return true;
+  }
+
+  bool read_nap_data(NAP_T *data)
+  {
+    char day[12] = {0};
+    uapi_get_YYMMDD_Time(day, '\0');
+
+    sprintf_s(nap_file_path, 64, NAP_PATH, day);
+
+    FILE *fp = fopen(nap_file_path, "rb");
+    if (fp == NULL)
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "read_nap_data  %s fopen fail", nap_file_path);
+      return false;
+    }
+
+    if(uapi_get_file_size(nap_file_path) > 14) //存在多段小睡 UI显示最新的一次数据
+       fseek(fp, -14, SEEK_END);//移到最后一段数据
+
+    fseek(fp, 3, SEEK_CUR); // 将文件指针移动到睡眠类型
+
+    //读取睡眠类型
+    uint8_t sleep_type;
+    fread(&sleep_type, 1, 1, fp);
+
+    if (sleep_type == 1)
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sleep_type error!!!");
+      fclose(fp);
+      return false;
+    }
+    // 入睡时间
+    uint32_t fall_asleep_timestamp;
+    fread(&fall_asleep_timestamp, 1, 4, fp);
+
+    // 起床时间
+    uint32_t wake_up_timestamp;
+    fread(&wake_up_timestamp, 1, 4, fp);
+
+    // 睡眠总时间
+    uint8_t total_time_hour, total_time_minute;
+    fread(&total_time_hour, 1, 1, fp);
+    fread(&total_time_minute, 1, 1, fp);
+    uint16_t total_time = total_time_hour * 60 + total_time_minute;
+
+    // 累加睡眠数据
+    data->fall_asleep_timestamp = fall_asleep_timestamp;
+    data->wake_up_timestamp = wake_up_timestamp;
+    data->total_time = total_time;
+
+    nap_update_timestamp = wake_up_timestamp;
+
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "fall_asleep_timestamp : %d  wake_up_timestamp : %d  total_time : %d ", data->fall_asleep_timestamp, data->wake_up_timestamp, data->total_time);
+
+    fclose(fp);
+
+    return true;
+  }
+  void set_sleep_data(SLEEP_T *data)
+  {
+    memset(&sleep_data, 0, sizeof(SLEEP_T));
+    memcpy_s(&sleep_data, sizeof(SLEEP_T), data, sizeof(SLEEP_T));
+    // 刷新model里面的数据
+    // SleepModel::GetInstance().update_sleep(&sleep_data);
+  }
+  /* -------------------------------------------------------------------------- */
+  SleepModel::SleepModel()
+  {
+    // 初始化配置睡眠目标
+    set_sleep_goal();
+    // 刷新数据
+    Msg_ReInitData();
+  }
+  SleepModel::~SleepModel() {}
+  SleepModel &SleepModel::GetInstance()
+  {
+    static SleepModel instance;
+    return instance;
+  }
+  void SleepModel::Msg_ReInitData() {
+      do_custom_fileoperate_service_check_msg(
+  CUSTOM_FILEOPERATE_MSG_TYPE_SLEEPMODLE_UPDATE, nullptr, 0);
+  }
+
+
+  //更新睡眠model数据
+  void SleepModel::ReInitData()
+  {
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "ReadSleepData sleepStr %u  wakeStr %u sleep_total_time %d",
+                    sleep_data.fall_asleep_timestamp,
+                    sleep_data.wake_up_timestamp, sleep_data.total_time);
+      if (sleep_data.fall_asleep_timestamp)
+      {
+        update_time_info(sleep_data.fall_asleep_timestamp, sleepStr);
+        update_time_info(sleep_data.wake_up_timestamp, wakeStr);
+      }
+      else
+      {
+        sleepStr = "--";
+        wakeStr = "--";
+      }
+      sleep_total_time = sleep_data.total_time;
+    }
+    {
+      if (nap_data.fall_asleep_timestamp)
+      {
+        update_time_info(nap_data.fall_asleep_timestamp, napsleepStr);
+        update_time_info(nap_data.wake_up_timestamp, napwakeStr);
+      }
+      else
+      {
+        napsleepStr = "--";
+        napwakeStr = "--";
+      }
+      nap_total_time = nap_data.total_time;
+    }
+
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                  "ReadSleepData sleepStr %s  wakeStr %s sleep_total_time %d nap_total_time %d napsleepStr %s napwakeStr %s",
+                  sleepStr.c_str(), wakeStr.c_str(), sleep_total_time, nap_total_time, napsleepStr.c_str(), napwakeStr.c_str());
+
+    // delete data; // 释放内存
+  }
+
+  // 开机读取
+  void SleepModel::read_sleep_file_data() {
+    custom_read_sleep_data();
+    custom_read_nap_data();
+
+  }
+  // 保存睡眠数据
+ void SleepModel::msg_save_sleep_data() {
+    // 配置睡眠数据
+    int cmd = 0;
+   // do_cywee_service_check_msg(CYWEE_SERVICE_CMD_GET_SLEEP_DATA,&cmd); // 获取睡眠数据 但不中止睡眠
+ }
+
+  void SleepModel::UpdateSleepView()
+  {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "睡眠数据更新");
+    SleepControlView *p_SleepControlView = SleepControlView::GetInstance();
+    if (p_SleepControlView != nullptr)
+    {
+      if (p_SleepControlView->GetSleepView())
+      {
+        p_SleepControlView->GetSleepView()->SleepDataRefresh();
+      }
+      if (p_SleepControlView->GetSleepTimeView())
+      {
+        p_SleepControlView->GetSleepTimeView()->SleepDataRefresh();
+      }
+      if (p_SleepControlView->GetSleepNapView())
+      {
+        p_SleepControlView->GetSleepNapView()->SleepDataRefresh();
+      }
+    }
+  }
+  static constexpr const char *SLEEP_JSON_PATH =
+      "/user/userdata/health/sleep.json";
+  // 读取睡眠数据
+  SleepDataUI *SleepModel::ReadSleepData()
+  {
+
+    // 判断文件夹是否存在
+    if (!HealthService::GetInstance()->CreateHealthFolder())
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file");
+      return nullptr;
+    }
+
+    // 读取文件
+    std::ifstream inFile(SLEEP_JSON_PATH);
+    if (!inFile.is_open())
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to open JSON file");
+      return nullptr;
+    }
+
+    // 读取文件内容到字符串
+    std::stringstream buffer;
+    buffer << inFile.rdbuf();
+    std::string jsonDataString = buffer.str();
+    const char *jsonData = jsonDataString.c_str();
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonData: %s", jsonData);
+
+    // 关闭文件
+    inFile.close();
+    if (jsonDataString.empty())
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "jsonDataString is empty");
+      return nullptr;
+    }
+
+    cJSON *sleep_root = cJSON_Parse(jsonData);
+    if (sleep_root == NULL)
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "sleep_root is empty");
+      return nullptr;
+    }
+
+    SleepDataUI *data = new SleepDataUI();
+
+    cJSON *sleeptime_item = cJSON_GetObjectItem(sleep_root, "sleeptime");
+    cJSON *waketime_item = cJSON_GetObjectItem(sleep_root, "waketime");
+    cJSON *totaltime_item = cJSON_GetObjectItem(sleep_root, "totaltime");
+    cJSON *sleep_timestamp_item =
+        cJSON_GetObjectItem(sleep_root, "sleep_timestamp");
+    cJSON *wake_timestamp_item =
+        cJSON_GetObjectItem(sleep_root, "wake_timestamp");
+
+    if (sleeptime_item && waketime_item && totaltime_item)
+    {
+      data->sleeptime = sleeptime_item->valuestring;
+      data->waketime = waketime_item->valuestring;
+      data->totaltime = totaltime_item->valueint;
+      // 增加时间戳
+      data->sleep_timestamp = sleep_timestamp_item->valueint;
+      data->wake_timestamp = wake_timestamp_item->valueint;
+    }
+    else
+    {
+      // 读取的数据异常
+      cJSON_Delete(sleep_root);
+      delete data;
+      return nullptr;
+    }
+
+    cJSON_Delete(sleep_root);
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ReadSleepData is ok!");
+
+    // 返回结构体
+    return data;
+  }
+
+  // 更新睡眠数据
+  bool SleepModel::SaveSleepData(const SleepDataUI &data)
+  {
+    // 判断文件夹是否存在
+    if (!HealthService::GetInstance()->CreateHealthFolder())
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CreateHealthFolder file");
+      return false;
+    }
+
+    // 覆盖存储
+    std::ofstream outFile(SLEEP_JSON_PATH, std::ios::trunc);
+    if (!outFile.is_open())
+    {
+      // 文件创建失败
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "Failed to create or open JSON file for writing");
+      return false;
+    }
+
+    // 创建一个 JSON 对象
+    cJSON *sleep_root = cJSON_CreateObject();
+    if (sleep_root == NULL)
+    {
+      outFile.close();
+      return false;
+    }
+
+    cJSON_AddItemToObject(sleep_root, "sleeptime",
+                          cJSON_CreateString(data.sleeptime.c_str()));
+    cJSON_AddItemToObject(sleep_root, "waketime",
+                          cJSON_CreateString(data.waketime.c_str()));
+    cJSON_AddItemToObject(sleep_root, "totaltime",
+                          cJSON_CreateNumber(data.totaltime));
+    cJSON_AddItemToObject(sleep_root, "sleep_timestamp",
+                          cJSON_CreateNumber(data.sleep_timestamp));
+    cJSON_AddItemToObject(sleep_root, "wake_timestamp",
+                          cJSON_CreateNumber(data.wake_timestamp));
+
+    char *jsonData = cJSON_Print(sleep_root);
+    if (jsonData == NULL)
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to generate JSON data");
+      cJSON_free(sleep_root);
+      outFile.close();
+      return false;
+    }
+
+    // 写入 JSON 数据到文件
+    outFile << jsonData;
+
+    cJSON_free(sleep_root);
+    free(jsonData);
+    outFile.close();
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "UpdateHealthData JSON is ok");
+
+    return true;
+  }
+  std::string SleepModel::GetUpdateSleepTime()
+  {
+    sleep_time_str.clear();
+    // 获取睡眠最新时间
+    sleep_update_time = get_sleep_update_timestamp();
+    // 获取时间戳
+    update_time_info(sleep_update_time, sleep_time_str);
+    return sleep_time_str;
+  }
+  //校验时间更新
+  bool SleepModel::CheckSleepTime() {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "CheckSleepTime %d",sleep_update_time);
+    // 获取睡眠最新时间
+    if (sleep_update_time != 0) {
+      return true;
+      }
+    return false;
+  }
+  void SleepModel::update_sleep(SLEEP_T *data)
+  {
+    if (data == nullptr)
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Invalid input data");
+      return;
+    }
+
+    WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP,
+                  "fall_asleep_timestamp:%d wake_up_timestamp:%d total_time:%d",
+                  data->fall_asleep_timestamp, data->wake_up_timestamp,
+                  data->total_time);
+
+    SleepDataUI *UIdata = ReadSleepData();
+    if (UIdata != nullptr)
+    {
+      // 入睡时间是最早时间
+      if (data->fall_asleep_timestamp < UIdata->sleep_timestamp ||
+          UIdata->sleep_timestamp == 0)
+      {
+        UIdata->sleep_timestamp = data->fall_asleep_timestamp;
+      }
+      // 起床时间是最晚时间
+      if (data->wake_up_timestamp > UIdata->wake_timestamp ||
+          UIdata->wake_timestamp == 0)
+      {
+        UIdata->wake_timestamp = data->wake_up_timestamp;
+      }
+      // 总时间需要累加
+      UIdata->totaltime += data->total_time;
+
+      update_time_info(UIdata->sleep_timestamp, sleepStr);
+      update_time_info(UIdata->wake_timestamp, wakeStr);
+      UIdata->sleeptime = sleepStr;
+      UIdata->waketime = wakeStr;
+
+      sleep_total_time = UIdata->totaltime;
+
+      SaveSleepData(*UIdata);
+    }
+    delete UIdata; // Free memory if dynamically allocated
+  }
+
+  // 清空睡眠数据
+  bool SleepModel::DeleteSleepData()
+  {
+    // ReInitData(); // 刷新
+    do_custom_fileoperate_service_check_msg(CUSTOM_FILEOPERATE_MSG_TYPE_SLEEPMODLE_UPDATE, nullptr, 0);
+    return true;
+  }
+
+  // 时间戳->字符串
+  void SleepModel::update_time_info(uint32_t timestamp, std::string &timeStr)
+  {
+    // 如果时间戳为0,设置时间字符串为默认值
+    if (timestamp == 0)
+    {
+      timeStr = "--";
+      return;
+    }
+    // 解析时间戳
+    char labelTime[20];
+    if (uapi_get_TIME_STR(timestamp, labelTime, '.', ':', DATE_H_M) ==
+        ERRCODE_SUCC)
+    {
+      timeStr.assign(labelTime);
+    }
+    else
+    {
+      timeStr = "--"; // 如果获取失败,设置为默认值
+    }
+  }
+
+  /*
+      设置睡眠目标
+      前2个字节是显示睡眠小时
+      后2个字节显示睡眠分钟
+      需要单独解析出来。
+  */
+  void SleepModel::set_sleep_goal()
+  {
+    // 将原3个字符串清空
+    goalnotifyStr.clear();
+    goalsleepStr.clear();
+    goalwakeStr.clear();
+
+    int goal_sleep = get_sleep_time_from_config_model();
+    int goal_wake = get_wake_up_time_from_config_model();
+
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "goal_sleep:%d goal_wake:%d",
+                  goal_sleep, goal_wake);
+    /* --------------------------------------------------------------------------
+     */
+    // 提取小时部分(前2字节)
+    int goal_sleep_hour = goal_sleep >> 16;
+    // 提取分钟部分(后2字节)
+    int goal_sleep_min = goal_sleep & 0x00FF;
+    std::ostringstream sleeposs;
+    sleeposs << std::setfill('0') << std::setw(2) << goal_sleep_hour << ":"
+             << std::setw(2) << goal_sleep_min;
+    // 睡眠时间点字符串
+    goalsleepStr = sleeposs.str();
+
+    /* --------------------------------------------------------------------------
+     */
+    // 需要配置提醒字符串 减去SLEPPNOTIFY分钟的计算
+    int notify_min =
+        (goal_sleep_min >= SLEPPNOTIFY)
+            ? goal_sleep_min - SLEPPNOTIFY
+            : ((goal_sleep_min + 60) - SLEPPNOTIFY); // 避免分钟数为负
+    int notify_hour = goal_sleep_hour;
+    if (goal_sleep_min < SLEPPNOTIFY)
+    {                   // 如果需要借位
+      notify_hour -= 1; // 小时减1
+    }
+    // 确保小时数正确
+    notify_hour =
+        (notify_hour < 0)
+            ? 23
+            : notify_hour; // 处理从0点前SLEPPNOTIFY分钟的情况,变为前一天的23点40分
+    // 格式化提醒时间字符串
+    std::ostringstream notifyoss;
+    notifyoss << std::setfill('0') << std::setw(2) << notify_hour << ":"
+              << std::setw(2) << notify_min;
+    // 设置提醒字符串
+    goalnotifyStr = notifyoss.str();
+    /* --------------------------------------------------------------------------
+     */
+
+    int goal_wake_hour = goal_wake >> 16;
+    int goal_wake_min = goal_wake & 0x00FF;
+    std::ostringstream wakeoss;
+    wakeoss << std::setfill('0') << std::setw(2) << goal_wake_hour << ":"
+            << std::setw(2) << goal_wake_min;
+    // 起床时间点字符串
+    goalwakeStr = wakeoss.str();
+    /* --------------------------------------------------------------------------
+     */
+
+    // 睡眠字符串 以及总时长
+    goalStr = goalsleepStr + "-" + goalwakeStr;
+    // goal_total_time 计算
+    int total_hours;
+    if (goal_wake_hour < goal_sleep_hour)
+    {
+      total_hours = (goal_wake_hour + 24) - goal_sleep_hour; // 跨天情况
+    }
+    else
+    {
+      total_hours = goal_wake_hour - goal_sleep_hour;
+    }
+
+    int total_minutes = goal_wake_min - goal_sleep_min;
+    if (total_minutes < 0)
+    {
+      total_hours--;       // 如果分钟差为负数,小时差减1
+      total_minutes += 60; // 转换为正数,加60分钟
+    }
+    goal_total_time = total_hours; // 确保最小时间为0小时
+
+    /*通知界面更新*/
+   // SendMsgToUIService(UI_UPDATE_SLEEP_DATA, 0, nullptr, 0);
+  }
+  // 获取睡眠总时长(小时)
+  int SleepModel::get_sleep_hour() { return sleep_total_time / 60; }
+  // 获取睡眠总时长(分钟)
+  int SleepModel::get_sleep_min() { return sleep_total_time % 60; }
+  // 获取睡眠总时长(目标)
+  int SleepModel::get_sleep_goal() { return goal_total_time; }
+  // 获取睡眠总时长(实际)
+  int SleepModel::get_sleep_total() { return sleep_total_time; }
+  // 获取实际入睡时间str
+  std::string SleepModel::get_rest_str() { return sleepStr; }
+  // 获取实际醒来时间str
+  std::string SleepModel::get_wake_str() { return wakeStr; }
+  // 获取目标休息时间str
+  std::string SleepModel::get_goal_str() { return goalStr; }
+  // 获取 目标睡眠提醒 时间点str
+  std::string SleepModel::get_notifiy() { return goalnotifyStr; }
+  // 获取 目标睡眠 时间点str
+  std::string SleepModel::get_sleep_notifiy() { return goalsleepStr; }
+
+  // 获取 目标起床 时间点str
+  std::string SleepModel::get_wake_notifiy() { return goalwakeStr; }
+  // 设置睡眠状态
+  void SleepModel::set_sleep_state(SLEEPSTATE state) { sleepstate_ = state; }
+  // 获取睡眠状态
+  SLEEPSTATE SleepModel::get_sleep_state() { return sleepstate_; }
+  // 小睡数据
+  int SleepModel::get_nap_hour() { return nap_total_time / 60; }
+  int SleepModel::get_nap_min() { return nap_total_time % 60; }
+  // 小睡数据字符串
+  std::string SleepModel::get_napsleep_str() { return napsleepStr; }
+  std::string SleepModel::get_napwake_str() { return napwakeStr; }
+  /* ---------------------------------- 睡眠定时器
+   * --------------------------------- */
+
+  // 声明定时器变量
+  static osTimerId_t g_timer = NULL;
+
+  /*定时器到期时的处理*/
+  static void Sleep_TimerCallbackProc(int data)
+  {
+    // 发起新闹钟
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Sleep_TimerCallbackProc");
+    SleepModel::GetInstance().Sleep_StopTimer();        // 关闭定时器
+    CustomEventPublish(TOPIC_EVENT_SLEEPNOTE, NULL, 0); // 发送睡眠弹窗
+  }
+
+  static void Sleep_TimerCallback(int data)
+  {
+    GraphicService::GetInstance()->PostGraphicEvent(
+        std::bind(Sleep_TimerCallbackProc, data));
+  }
+
+  void SleepModel::Sleep_StartTimer(uint32_t interval)
+  {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepModel::Sleep_StartTimer");
+    if (g_timer != NULL)
+    {
+      WEARABLE_LOGE(
+          WEARABLE_LOG_MODULE_APP,
+          "CountDownModel::CountDown_StartTimer Timer already exists!!");
+      return;
+    }
+    g_timer =
+        osTimerNew((osTimerFunc_t)Sleep_TimerCallback, osTimerOnce, NULL, NULL);
+    if (g_timer == NULL)
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "CountDownModel::CountDown_StartTimer Timer create failed!!");
+      return;
+    }
+    int tick = osMs2Tick(interval);
+    osStatus_t ret = osTimerStart(g_timer, tick);
+    if (ret != osOK)
+    {
+      WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                    "[CountDown_StartTimer] osTimerDelete failed, ret = %lx!!",
+                    ret);
+      if (g_timer != NULL)
+      {
+        ret = osTimerDelete(g_timer);
+      }
+      g_timer = NULL;
+      return;
+    }
+    return;
+  }
+
+  void SleepModel::Sleep_StopTimer(void)
+  {
+    // 检查定时器是否存在
+    if (g_timer != NULL)
+    {
+      // 删除定时器并置为 NULL
+      osTimerStop(g_timer);
+      osStatus_t ret = osTimerDelete(g_timer);
+      if (ret != osOK)
+      {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                      "osTimerDelete failed, ret = %lx!!", ret);
+      }
+      g_timer = NULL;
+    }
+  }
+  /* -------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+#if __cplusplus
+  extern "C"
+  {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+    void custom_read_sleep_data(void)
+    {
+      memset(&sleep_data, 0, sizeof(SLEEP_T));
+      read_sleep_data(&sleep_data);
+    }
+
+    void custom_read_nap_data(void)
+    {
+      memset(&nap_data, 0, sizeof(NAP_T));
+      read_nap_data(&nap_data);
+    }
+
+    void custom_read_wear_data(void)
+    {
+        read_wear_data();
+    }
+
+    void custom_sleep_model_updata(void)
+    {
+      OHOS::SleepModel::GetInstance().ReInitData();
+    }
+    // 更新睡眠数据
+    void update_sleep_data(uint32_t sleep_timestamp, uint32_t wake_timestamp,
+                           uint32_t totaltime) {
+      sleep_data.fall_asleep_timestamp = sleep_timestamp;
+      sleep_data.wake_up_timestamp = wake_timestamp;
+      sleep_data.total_time = totaltime;
+      sleep_update_timestamp = sleep_data.wake_up_timestamp;
+    }
+    // 更新小睡数据
+    void update_nap_data(uint32_t sleep_timestamp, uint32_t wake_timestamp,
+                         uint32_t totaltime) {
+      nap_data.fall_asleep_timestamp = sleep_timestamp;  
+      nap_data.wake_up_timestamp = wake_timestamp;  
+      nap_data.total_time = totaltime;  
+      nap_update_timestamp = nap_data.wake_up_timestamp;
+    }
+
+  
+#ifdef __cplusplus
+#if __cplusplus
+  }
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+} // namespace OHOS
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepNapView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepNapView.cpp
new file mode 100644 (file)
index 0000000..d11921f
--- /dev/null
@@ -0,0 +1,149 @@
+#include "sleep/include/SleepNapView.h"
+#include "ConfigModel.h"
+#include "common/image_cache_manager.h"
+#include "sleep/include/SleepModel.h"
+#include "string"
+#include "uicomponents/UIComponents.h"
+namespace OHOS {
+
+static SleepNapView *g_pSleepNapView{nullptr};
+static std::string restStr;
+static std::string sleepStr;
+static std::string wakeStr;
+static std::string napsleepStr;
+static std::string napwakeStr;
+SleepNapView::SleepNapView() {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepNapView::SleepNapView");
+  SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);
+  SetViewIndex(0); // 视图索引
+
+  g_pSleepNapView = this;
+}
+
+SleepNapView::~SleepNapView() {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " SleepNapView::~SleepNapView");
+  ClearAll();
+
+  g_pSleepNapView = nullptr;
+}
+
+void SleepNapView::SleepDataRefresh() {
+
+  int nap_hour = SleepModel::GetInstance().get_nap_hour();
+  int nap_min = SleepModel::GetInstance().get_nap_min();
+
+  //小睡数据
+  if (nap_hour != 0 || nap_min != 0) {
+    if (napsleep != nullptr && napwake != nullptr) {
+      napsleep->SetText((SleepModel::GetInstance().get_napsleep_str()).c_str());
+      napwake->SetText((SleepModel::GetInstance().get_napwake_str()).c_str());
+    }
+  }
+}
+
+void SleepNapView::ClearAll() {
+  RemoveAll();
+
+  if (transverseline_1 != nullptr) {
+    delete transverseline_1;
+    transverseline_1 = nullptr;
+  }
+  if (transverseline_2 != nullptr) {
+    delete transverseline_2;
+    transverseline_2 = nullptr;
+  }
+  if (verticalline != nullptr) {
+    delete verticalline;
+    verticalline = nullptr;
+  }
+
+  if (napsleeptitle != nullptr) {
+    delete napsleeptitle;
+    napsleeptitle = nullptr;
+  }
+  if (napwaketitle != nullptr) {
+    delete napwaketitle;
+    napwaketitle = nullptr;
+  }
+  if (napwake != nullptr) {
+    delete napwake;
+    napwake = nullptr;
+  }
+  if (napsleep != nullptr) {
+    delete napsleep;
+    napsleep = nullptr;
+  }
+  if (naptitle != nullptr) {
+    delete naptitle;
+    naptitle = nullptr;
+  }
+  if (apptitle != nullptr) {
+    delete apptitle;
+    apptitle = nullptr;
+  }
+}
+
+SleepNapView *SleepNapView::GetInstance() { return g_pSleepNapView; }
+
+
+bool SleepNapView::InitPage(void) {
+  /* ---------------------------------- 线条初始化
+   * --------------------------------- */
+  CreateLine(transverseline_1, 0, 169, 466, 2, "transverseline_1");
+  CreateLine(transverseline_2, 0, 296, 466, 2, "transverseline_2");
+  CreateLine(verticalline, 232, 191, 2, 82, "verticalline");
+  /* -------------------------------- title初始化
+   * -------------------------------- */
+  //TODO:多国语言
+  InitLabelExt(naptitle, 83, 90, 300, 35, "resttitle",STR_NAP,
+            DEFAULT_VECTOR_FONT_FILENAME_EN, 30);
+  InitLabelExt(napsleeptitle, 21, 203, 200, 35, "sleeptitle", STR_SLEEPTIME,
+               DEFAULT_VECTOR_FONT_FILENAME, 30);
+  InitLabelExt(napwaketitle, 213, 203, 300, 35, "waketitle", STR_WALKTIME,
+               DEFAULT_VECTOR_FONT_FILENAME, 30);
+  InitLabelExt(apptitle, 93, 300, 300, 200, "apptitle", STR_APPMORE,
+               DEFAULT_VECTOR_FONT_FILENAME, 26);
+  apptitle->SetTextColor(Color::Gray());
+  /* ------------------------------- 数据label初始化
+   * ------------------------------- */
+  napsleepStr = "--";
+  InitLabel(napsleep, 10, 238, 230, 47, "sleeplabel", napsleepStr.c_str(),
+            DEFAULT_VECTOR_FONT_FILENAME_EN, 40);
+  napsleep->SetTextColor(Color::GetColorFromRGBA(0x53, 0x20, 0xE2, 0xff));
+  napwakeStr = "--";
+  InitLabel(napwake, 245, 238, 230, 47, "wakelabel", napwakeStr.c_str(),
+            DEFAULT_VECTOR_FONT_FILENAME_EN, 40);
+  napwake->SetTextColor(Color::GetColorFromRGBA(0x53, 0x20, 0xE2, 0xff));
+  /* --------------------------------------------------------------------------
+   */
+  /* -------------------------------- 将组件添加到根视图
+   * ------------------------------- */
+  Add(transverseline_1);
+  Add(transverseline_2);
+  Add(verticalline);
+
+  Add(naptitle);
+  Add(napsleeptitle);
+  Add(napwaketitle);
+  Add(napsleep);
+  Add(napwake);
+  Add(apptitle);
+
+  return true;
+}
+
+bool SleepNapView::InitView(void *caller) {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepNapView InitView %p", caller);
+  if (InitPage() == false) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepNapView::InitPage fail");
+    return false;
+  }
+  SetDraggable(true);
+  SetTouchable(true);
+  SleepDataRefresh();
+  return true;
+}
+
+// 获取视图初始化状态
+bool SleepNapView::GetInitViewState(void) { return viewInitStatus; }
+} // namespace OHOS
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepTimeView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepTimeView.cpp
new file mode 100644 (file)
index 0000000..292c1d1
--- /dev/null
@@ -0,0 +1,194 @@
+#include "sleep/include/SleepTimeView.h"
+#include "ConfigModel.h"
+#include "common/image_cache_manager.h"
+#include "sleep/include/SleepModel.h"
+#include "string"
+#include "uicomponents/UIComponents.h"
+namespace OHOS {
+
+static SleepTimeView *g_pSleepView{nullptr};
+static std::string restStr;
+static std::string sleepStr;
+static std::string wakeStr;
+static constexpr char *upimagePath = "/user/res/Sleep/up.bin";
+SleepTimeView::SleepTimeView() {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepTimeView::SleepTimeView");
+  SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);
+  SetViewIndex(0); // 视图索引
+
+  g_pSleepView = this;
+}
+
+SleepTimeView::~SleepTimeView() {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " SleepTimeView::~SleepTimeView");
+  ClearAll();
+
+  g_pSleepView = nullptr;
+}
+
+void SleepTimeView::SleepDataRefresh() {
+  
+  int sleep_hour = SleepModel::GetInstance().get_sleep_hour();
+  int sleep_min = SleepModel::GetInstance().get_sleep_min();
+  int sleep_goal = SleepModel::GetInstance().get_sleep_goal();
+
+  // 有数据则刷新
+  if (sleep_hour != 0 || sleep_min != 0) {
+    if (sleep != nullptr && wake != nullptr) {
+      sleep->SetText((SleepModel::GetInstance().get_rest_str()).c_str());
+      wake->SetText((SleepModel::GetInstance().get_wake_str()).c_str());
+    }
+  }
+  if (goal != nullptr) {
+    goal->SetText((SleepModel::GetInstance().get_goal_str()).c_str());
+  }
+  // 更新目标时间
+  if (goaltime != nullptr) {
+    UpdateLabel(goaltime, sleep_goal, STR_SLEEPMGOAL);
+  }
+}
+
+void SleepTimeView::ClearAll() {
+  RemoveAll();
+  if (resttitle != nullptr) {
+    delete resttitle;
+    resttitle = nullptr;
+  }
+  if (sleeptitle != nullptr) {
+    delete sleeptitle;
+    sleeptitle = nullptr;
+  }
+  if (waketitle != nullptr) {
+    delete waketitle;
+    waketitle = nullptr;
+  }
+  if (goaltime != nullptr) {
+    delete goaltime;
+    goaltime = nullptr;
+  }
+  if (goal != nullptr) {
+    delete goal;
+    goal = nullptr;
+  }
+
+  if (sleep != nullptr) {
+    delete sleep;
+    sleep = nullptr;
+  }
+  if (wake != nullptr) {
+    delete wake;
+    wake = nullptr;
+  }
+  if (upiconimage != nullptr) {
+    delete upiconimage;
+    upiconimage = nullptr;
+  }
+  if (transverseline_1 != nullptr) {
+    delete transverseline_1;
+    transverseline_1 = nullptr;
+  }
+  if (transverseline_2 != nullptr) {
+    delete transverseline_2;
+    transverseline_2 = nullptr;
+  }
+  if (verticalline != nullptr) {
+    delete verticalline;
+    verticalline = nullptr;
+  }
+}
+
+SleepTimeView *SleepTimeView::GetInstance() { return g_pSleepView; }
+
+bool SleepTimeView::InitPage(void) {
+  /* ---------------------------------- 线条初始化
+   * --------------------------------- */
+  if (transverseline_1 == nullptr) {
+    transverseline_1 = new UIImageView();
+  }
+  transverseline_1->SetPosition(0, 169);
+  transverseline_1->Resize(466, 2);
+  transverseline_1->SetViewId("image1");
+  transverseline_1->SetStyle(STYLE_BACKGROUND_COLOR, 0xff333333);
+  transverseline_1->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+  transverseline_1->SetVisible(true);
+
+  if (transverseline_2 == nullptr) {
+    transverseline_2 = new UIImageView();
+  }
+  transverseline_2->SetPosition(232, 191);
+  transverseline_2->Resize(2, 82);
+  transverseline_2->SetViewId("image2");
+  transverseline_2->SetStyle(STYLE_BACKGROUND_COLOR, 0xff333333);
+  transverseline_2->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+  transverseline_2->SetVisible(true);
+
+  if (verticalline == nullptr) {
+    verticalline = new UIImageView();
+  }
+  verticalline->SetPosition(0, 296);
+  verticalline->Resize(466, 2);
+  verticalline->SetViewId("image1");
+  verticalline->SetStyle(STYLE_BACKGROUND_COLOR, 0xff333333);
+  verticalline->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+  verticalline->SetVisible(true);
+  InitImageView(upiconimage, 213, 420, 40, 40, "image", upimagePath);
+
+  /* -------------------------------- title初始化
+   * -------------------------------- */
+  InitLabelExt(resttitle, 83, 50, 300, 35, "resttitle", STR_REATTIME,
+               DEFAULT_VECTOR_FONT_FILENAME, 30);
+  InitLabelExt(sleeptitle, 21, 203, 200, 35, "sleeptitle", STR_SLEEPTIME,
+               DEFAULT_VECTOR_FONT_FILENAME, 30);
+  InitLabelExt(waketitle, 213, 203, 300, 35, "waketitle", STR_WALKTIME,
+               DEFAULT_VECTOR_FONT_FILENAME, 30);
+  InitLabelExt(goaltime, 83, 350, 300, 50, "lablegoal", STR_SLEEPMGOAL,
+               DEFAULT_VECTOR_FONT_FILENAME, 30);
+  goaltime->SetTextColor(Color::Gray());
+  /* ------------------------------- 数据label初始化
+   * ------------------------------- */
+  //DEFAULT_VECTOR_FONT_FILENAME_EN
+  restStr = "--";
+  InitLabel(goal, 83, 90, 300, 50, "restlabel", restStr.c_str(),
+            DEFAULT_VECTOR_FONT_FILENAME_EN, 40);
+  // goal->SetLineBreakMode(UILabel::LINE_BREAK_ELLIPSIS);
+  goal->SetTextColor(Color::Gray());
+  sleepStr = "--";
+  InitLabel(sleep, 10, 238, 230, 47, "sleeplabel", sleepStr.c_str(),
+            DEFAULT_VECTOR_FONT_FILENAME_EN, 40);
+  sleep->SetTextColor(Color::GetColorFromRGBA(0x53, 0x20, 0xE2, 0xff));
+  wakeStr = "--";
+  InitLabel(wake, 245, 238, 230, 47, "wakelabel", wakeStr.c_str(),
+            DEFAULT_VECTOR_FONT_FILENAME_EN, 40);
+  wake->SetTextColor(Color::GetColorFromRGBA(0x53, 0x20, 0xE2, 0xff));
+
+  /* -------------------------------- 将组件添加到根视图
+   * ------------------------------- */
+  Add(resttitle);
+  Add(sleeptitle);
+  Add(waketitle);
+  Add(goaltime);
+  Add(goal);
+  Add(sleep);
+  Add(wake);
+  Add(transverseline_1);
+  Add(transverseline_2);
+  Add(verticalline);
+  Add(upiconimage);
+  return true;
+}
+
+bool SleepTimeView::InitView(void *caller) {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepTimeView InitView %p", caller);
+  if (InitPage() == false) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepTimeView::InitPage fail");
+    return false;
+  }
+  SetDraggable(true);
+  SetTouchable(true);
+  SleepDataRefresh();
+  return true;
+}
+
+// 获取视图初始化状态
+bool SleepTimeView::GetInitViewState(void) { return viewInitStatus; }
+} // namespace OHOS
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepView.cpp b/code/sdk/application/wearable/fd230/nativeapp/nativeui/sleep/src/SleepView.cpp
new file mode 100644 (file)
index 0000000..cbc8169
--- /dev/null
@@ -0,0 +1,254 @@
+#include "sleep/include/SleepView.h"
+#include "ConfigModel.h"
+#include "common/image_cache_manager.h"
+#include "languagecode/LanguageInit.h"
+#include "sleep/include/SleepModel.h"
+#include "uicomponents/UIComponents.h"
+namespace OHOS {
+static constexpr char *roomimagePath = "/user/res/Sleep/room.bin";
+static constexpr char *upimagePath = "/user/res/Sleep/up.bin";
+static constexpr const char *prossimagePath = "/user/res/step/step_b.bin";
+
+static SleepView *g_pSleepView{nullptr};
+SleepView::SleepView() {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepView::SleepView");
+  SetPosition(0, 0, HORIZONTAL_RESOLUTION, VERTICAL_RESOLUTION);
+  SetViewIndex(0); // 视图索引
+
+  g_pSleepView = this;
+}
+
+SleepView::~SleepView() {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " SleepView::~SleepView");
+  ClearAll();
+
+  g_pSleepView = nullptr;
+}
+
+void SleepView::SleepDataRefresh() {
+  // 获取睡眠数据内存
+  SleepModel &sleepModel = SleepModel::GetInstance();
+  sleepModel.ReInitData();
+
+  int sleep_hour = sleepModel.get_sleep_hour();
+  int sleep_min = sleepModel.get_sleep_min();
+  int total_sleep = sleepModel.get_sleep_total();
+  int sleep_goal = sleepModel.get_sleep_goal();
+
+  // 检查是否超过24小时
+  if (sleep_hour >= 24) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "异常:睡眠时长超过24小时");
+    return;
+  }
+
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,
+                "SleepDataRefresh %d %d sleep_goal:%d total_sleep:%d",
+                sleep_hour, sleep_min, sleep_goal * 60, total_sleep);
+
+  // 补零操作
+  std::string hour_str = (sleep_hour < 10) ? "0" + std::to_string(sleep_hour)
+                                           : std::to_string(sleep_hour);
+  std::string min_str = (sleep_min < 10) ? "0" + std::to_string(sleep_min)
+                                         : std::to_string(sleep_min);
+
+  // 有数据才刷新
+  if (sleep_hour != 0 || sleep_min != 0) {
+    // 更新时间显示
+    if (time_hour != nullptr) {
+      time_hour->SetText(hour_str.c_str());
+    }
+    if (time_minute != nullptr) {
+      time_minute->SetText(min_str.c_str());
+    }
+
+    // 计算进度百分比,确保目标睡眠时间不为零
+    float progress_value = 0.0f;
+    if (sleep_goal > 0) {
+      progress_value =
+          static_cast<float>(total_sleep) / (sleep_goal * 60); // 计算进度
+    }
+
+    // 日志输出进度百分比
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Progress value: %.2f%%",
+                  progress_value * 100); // 显示为百分比
+
+    // 更新进度条
+    circleProgress_->SetValue(progress_value *
+                              100); // 更新进度条值,范围为 0 到 100
+    circleProgress_->SetCapType(CAP_ROUND);
+  }
+
+  // 更新时间
+  if (sleep_update_time != nullptr) {
+    std::string update_time = sleepModel.GetUpdateSleepTime();
+    if (!update_time.empty()) // 检查返回值是否有效
+    {
+      std::string update_time_str;
+      // TODO:多国语言
+      if (ConfigModel::GetInstance()->GetLanguage() == ZH_CN) {
+        update_time_str = update_time + " 更新";
+      } else {
+        update_time_str = update_time + " update";
+      }
+      sleep_update_time->SetText(update_time_str.c_str());
+      // UpdateLabel(sleep_update_time, sleep_goal, STR_SLEEPMGOAL); // TODO:
+      // 多国语言支持
+    }
+  }
+
+  // 刷新视图
+  RootView::GetInstance()->Invalidate();
+}
+
+void SleepView::ClearAll() {
+  RemoveAll();
+  if (circleProgress_ != nullptr) {
+    delete circleProgress_;
+    circleProgress_ = nullptr;
+  }
+  if (title != nullptr) {
+    delete title;
+    title = nullptr;
+  }
+  if (hour != nullptr) {
+    delete hour;
+    hour = nullptr;
+  }
+  if (minute != nullptr) {
+    delete minute;
+    minute = nullptr;
+  }
+  if (time_hour != nullptr) {
+    delete time_hour;
+    time_hour = nullptr;
+  }
+  if (time_minute != nullptr) {
+    delete time_minute;
+    time_minute = nullptr;
+  }
+  if (sleep_update_time != nullptr) {
+    delete sleep_update_time;
+    sleep_update_time = nullptr;
+  }
+  if (roomimage != nullptr) {
+    delete roomimage;
+    roomimage = nullptr;
+  }
+  if (upiconimage != nullptr) {
+    delete upiconimage;
+    upiconimage = nullptr;
+  }
+  if (progress_image != nullptr) {
+    delete progress_image;
+    progress_image = nullptr;
+  }
+}
+
+SleepView *SleepView::GetInstance() { return g_pSleepView; }
+
+/*初始化界面*/
+bool SleepView::InitPage(void) {
+  /*初始化title*/
+  InitLabelExt(title, 83, 50, 300, 35, "labletitle", STR_SLEEP_YESTERDAY,
+               DEFAULT_VECTOR_FONT_FILENAME, 30);
+  /*初始化单位*/
+  InitLabelExt(hour, 157, 246, 75, 75, "lablehour", STR_HOUR,
+               DEFAULT_VECTOR_FONT_FILENAME, 26);
+  hour->SetTextColor(Color::Gray());
+  InitLabelExt(minute, 295, 246, 100, 75, "lableminute", STR_MIN,
+               DEFAULT_VECTOR_FONT_FILENAME, 26);
+  minute->SetTextColor(Color::Gray());
+  if (ConfigModel::GetInstance()->GetLanguage() != ZH_CN) {
+    //需要缩小
+    title->SetFont(DEFAULT_VECTOR_FONT_FILENAME,26);
+    hour->SetFont(DEFAULT_VECTOR_FONT_FILENAME,24);
+    minute->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 24);
+
+    minute->SetText("Min");//多国语言
+    hour->SetText("Hour");
+  } else {
+    minute->SetText("分钟");
+    hour->SetText("小时");
+    }
+  /*初始化image*/
+  InitImageView(roomimage, 192, 127, 82, 82, "image", roomimagePath);
+  InitImageView(upiconimage, 213, 420, 40, 40, "image", upimagePath);
+  InitImageView(progress_image, 28, 80, 100, 100, "image", prossimagePath);
+  /*初始化目标时间*/
+  // DEFAULT_VECTOR_FONT_FILENAME_EN
+  InitLabelExt(sleep_update_time, 83, 330, 300, 35, "lablegoal", STR_SLEEPMGOAL,
+               DEFAULT_VECTOR_FONT_FILENAME_EN, 30);
+  sleep_update_time->SetTextColor(Color::Gray());
+  /*初始化睡眠时间*/
+  time_hour = new UILabel();
+  time_hour->SetPosition(84, 237);
+  time_hour->Resize(40, 75);
+  time_hour->SetViewId("time_hour");
+  time_hour->SetText("--");
+  time_hour->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);
+  time_hour->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+  time_hour->SetFont(GILROY_BOLD_FONT, 65);
+
+  time_minute = new UILabel();
+  time_minute->SetPosition(240, 237);
+  time_minute->Resize(40, 75);
+  time_minute->SetViewId("time_minute");
+  time_minute->SetText("--");
+  time_minute->SetLineBreakMode(UILabel::LINE_BREAK_ADAPT);
+  time_minute->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+  time_minute->SetFont(GILROY_BOLD_FONT, 65);
+  /* --------------------------------- 初始化进度条
+   * --------------------------------- */
+  circleProgress_ = new UICircleProgress();
+  if (circleProgress_ == nullptr) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "circleProgress new fail");
+    return false;
+  }
+  circleProgress_->SetPosition(0, 0);
+  circleProgress_->Resize(466, 466);
+  circleProgress_->SetViewId("circleProgress1");
+  circleProgress_->SetStyle(STYLE_BACKGROUND_OPA, 0x00);
+  circleProgress_->SetBackgroundStyle(STYLE_BACKGROUND_COLOR, 0xff000000);
+  circleProgress_->SetBackgroundStyle(STYLE_BACKGROUND_OPA, 0x00);
+  circleProgress_->SetBackgroundStyle(STYLE_BORDER_OPA, 0x00);
+  circleProgress_->SetBackgroundStyle(STYLE_LINE_OPA, 0x00);
+  circleProgress_->SetForegroundStyle(STYLE_BACKGROUND_COLOR, 0xff2195F6);
+  circleProgress_->SetForegroundStyle(STYLE_BORDER_COLOR, 0xff000000);
+  circleProgress_->SetForegroundStyle(STYLE_LINE_COLOR, 0xff5320e2);
+  circleProgress_->SetForegroundStyle(STYLE_LINE_WIDTH, 20);
+  circleProgress_->SetCenterPosition(233, 229);
+  circleProgress_->SetRadius(205);
+  circleProgress_->SetStartAngle(320);
+  circleProgress_->SetEndAngle(40);
+  circleProgress_->SetCapType(CAP_ROUND);
+  /* -------------------------------- 将组件添加到根视图
+   * ------------------------------- */
+  Add(progress_image);
+  Add(circleProgress_);
+  Add(title);
+  Add(hour);
+  Add(minute);
+  Add(time_hour);
+  Add(time_minute);
+  Add(sleep_update_time);
+  Add(upiconimage);
+  Add(roomimage);
+
+  viewInitStatus = true;
+  return true;
+}
+
+bool SleepView::InitView(void *caller) {
+  WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepView InitView %p", caller);
+  if (InitPage() == false) {
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "SleepView::InitPage fail");
+    return false;
+  }
+  SleepDataRefresh(); // 刷新数据
+  SetDraggable(true);
+  SetTouchable(true);
+  return true;
+}
+
+bool SleepView::GetInitViewState(void) { return viewInitStatus; }
+} // namespace OHOS
\ No newline at end of file
index 124d6a5..b8a32b9 100644 (file)
@@ -337,6 +337,7 @@ target = {
             'BOARD_FD230',
             'FT_SINGLE_UART',
             'CONFIG_EFUSE_READ_TO_RAM',
+            # 'CUSTOM_UTILS',
             # 'CUSTOM_HID_SERVICE',
             # 'WEARABLE_LOG_DEBUG',
             'SUPPORT_RC_CALIBRATION',
index 2daeb32..374f8ca 100644 (file)
@@ -57,12 +57,12 @@ void store_sport_data(void){}
 //进行心率列表存储
 void custom_save_sleep_data(void){}
 void custom_save_nap_data(void){}
-void custom_read_sleep_data(void){}
-void custom_read_nap_data(void){}
-void custom_sleep_model_updata(void){}
-void update_sleep_data(uint32_t sleep_timestamp,uint32_t wake_timestamp,uint32_t totaltime){}
-void update_nap_data(uint32_t sleep_timestamp,uint32_t wake_timestamp,uint32_t totaltime){}
-void custom_read_wear_data(void){}
+//void custom_read_sleep_data(void){}
+//void custom_read_nap_data(void){}
+//void custom_sleep_model_updata(void){}
+//void update_sleep_data(uint32_t sleep_timestamp,uint32_t wake_timestamp,uint32_t totaltime){}
+//void update_nap_data(uint32_t sleep_timestamp,uint32_t wake_timestamp,uint32_t totaltime){}
+//void custom_read_wear_data(void){}
 #ifndef FACTORYTEST_SERVICE
 // void factorytest_save_aging_data(void){}
 // void factorytest_read_aging_data(void){}