nativeabilityfwk文件夹合并提交
authorluozheng <1732036298@qq.com>
Fri, 18 Jul 2025 09:09:24 +0000 (17:09 +0800)
committerluozheng <1732036298@qq.com>
Mon, 28 Jul 2025 06:42:10 +0000 (14:42 +0800)
20 files changed:
code/sdk/application/wearable/fd230/nativeabilityfwk/CMakeLists.txt
code/sdk/application/wearable/fd230/nativeabilityfwk/include/Ability.h
code/sdk/application/wearable/fd230/nativeabilityfwk/include/AbilitySlice.h
code/sdk/application/wearable/fd230/nativeabilityfwk/include/AbilitySliceProxy.h
code/sdk/application/wearable/fd230/nativeabilityfwk/include/BackDragListener.h
code/sdk/application/wearable/fd230/nativeabilityfwk/include/NativeAbility.h
code/sdk/application/wearable/fd230/nativeabilityfwk/include/PageTransitionMgr.h
code/sdk/application/wearable/fd230/nativeabilityfwk/include/Presenter.h
code/sdk/application/wearable/fd230/nativeabilityfwk/include/RecentManager.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeabilityfwk/include/Slice.h
code/sdk/application/wearable/fd230/nativeabilityfwk/include/SlicePage.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeabilityfwk/include/SlicePageFactory.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeabilityfwk/include/SlicePageManager.h [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeabilityfwk/include/SliceProxy.h
code/sdk/application/wearable/fd230/nativeabilityfwk/include/View.h
code/sdk/application/wearable/fd230/nativeabilityfwk/src/Ability.cpp
code/sdk/application/wearable/fd230/nativeabilityfwk/src/AbilitySlice.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230/nativeabilityfwk/src/NativeAbility.cpp
code/sdk/application/wearable/fd230/nativeabilityfwk/src/transition/BackToHexagonsTransition.cpp
code/sdk/application/wearable/fd230/nativeabilityfwk/src/transition/BackToWaterfallTransition.cpp

index e98bcf6..63e56e8 100644 (file)
@@ -19,12 +19,12 @@ set(PRIVATE_HEADER
     ${ROOT_DIR}/middleware/services/gui/uikit/surface/interfaces/kits
     ${ROOT_DIR}/middleware/services/gui/uikit/ui/interfaces/innerkits
     ${ROOT_DIR}/middleware/services/gui/uikit/ui/frameworks
-    ${ROOT_DIR}/application/wearable/nativeapp/nativeui/applist/include/
     ${ROOT_DIR}/open_source/openharmony/drivers/peripheral/display/interfaces/include
 )
 
 set(SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/src/Ability.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/AbilitySlice.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/src/NativeAbility.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/src/StartNative.cpp
     ${CMAKE_CURRENT_SOURCE_DIR}/src/transition/ZoomTransition.cpp
index cfa5dd9..876c5b0 100644 (file)
 #ifndef NATIVEABILITYFWK_ABILITY_H
 #define NATIVEABILITYFWK_ABILITY_H
 #include <cstdint>
-#include "SliceProxy.h"
-#include "Slice.h"
 #include "wearable_log.h"
 #include "TransitionType.h"
 #include "soc_osal.h"
 #include "gfx_utils/vector.h"
 #include "graphic_mutex.h"
+#include "Slice.h"
+#include "SliceProxy.h"
+#include "SlicePageManager.h"
 
 #include "utils/utils_list.h"
 #include <vector>
 #include "stack"
 #include "AppViewIDs.h"
 namespace OHOS {
-const static uint16_t gSliceInvalid = 0;         
+const static uint16_t gSliceInvalid = 0;
+const static uint16_t gPageInvalid = 0;         
 const static uint16_t gSliceDefaultPriority = 4;  // 页面默认是最低优先级
-const static uint16_t gMaxHistorySlices = 10;  // 默认最多保存三个历史记录
 
 class Ability {
 public:
-    void AddSliceProxy(const uint16_t sliceId, SliceProxy* proxy);
-    void ChangeSlice(const uint16_t targetSliceId, TransitionType type = TransitionType::TRANSITION_INVALID,
-        const uint16_t priority = gSliceDefaultPriority, bool enableSlideBack = false);
-    void SetDefaultSliceId(const uint16_t defaultSliceId) {
-        defaultSliceId_ = defaultSliceId;
+    void AddSliceProxy(uint16_t sliceId, SliceProxy* proxy);
+
+    /**
+     * @brief Switch to specified page in the current slice, matched page will be created, and current slice will not be
+     *        recreated. if slices or pages is being switched, this operation will be canceled
+     * @param pageId Indicates the specified id of the page in the current slice, it should not be zero
+     * @param data Indicates the data which will be transfered to next page, default value is nullptr
+     * @param type Indicates Transition animation type, which is declared in TransitionType.h. The matched
+     *        Transitioncallback should have params: enableCurrentSnapshot_ = false enableTargetSnapshot_ = false
+     * @param canBack Indicates whether current page should be cached and can be back from target page
+     * @return Returns <b>true</b> if the pages is switched successfully, returns <b>false</b> otherwise.
+     */
+    bool SwitchPageInSlice(uint16_t pageId, void* data = nullptr,
+        TransitionType type = TransitionType::TRANSITION_INVALID, bool canBack = false);
+
+    /**
+     * @brief Switch to specified slice. matched slice will be created.
+     *         1. If pageId is valid or default page is exist, matched page will also be created
+     *         2. If slices is being switched, this operation will be cached and run later.
+     * @param sliceId Indicates the specified id of the slice
+     * @param pageId Indicates the specified id of the slice, if pageId is invalid, default page will be used.
+     * @param type Indicates Transition animation type, which is declared in TransitionType.h
+     * @param enableSliceBack Indicates whether can return to current slice from target slice by sliding
+     */
+    void SwitchSlice(uint16_t sliceId, uint16_t pageId = gPageInvalid,
+        TransitionType type = TransitionType::TRANSITION_INVALID, bool enableSlideBack = false);
+
+    /**
+     * @brief Switch to specified slice. matched slice will be created.
+     *         1. If default page is exist, default page will also be created
+     *         2. If slices is being switched, this operation will be cached and run later.
+     *        Note: Method SwitchSlice is recommended, this method is reserved for compatibility.
+     * @param sliceId Indicates the specified id of the slice
+     * @param type Indicates Transition animation type, which is declared in TransitionType.h
+     * @param priority Indicates the priority of slice, default value is used currently. if needed, config it in
+     *        XXXPresenter::OnResume using method SetCurSlicePriority
+     * @param enableSliceBack Indicates whether can return to current slice from target slice by sliding
+     */
+    void ChangeSlice(uint16_t sliceId, TransitionType type = TransitionType::TRANSITION_INVALID,
+        uint16_t priority = gSliceDefaultPriority, bool enableSlideBack = false);
+
+    /**
+     * @brief Get SlicePageManager of currrent slice. you can Use SlicePageManager to get page info in the slice.
+     * @return Returns <b>nullptr</b> if slices is being switched, or js ability is running
+     */
+    SlicePageManager* GetCurSlicePageManager();
+
+    void SetDefaultSliceId(uint16_t defaultSliceId, uint16_t pageId = gPageInvalid)
+    {
+        defaultTargetId_ = defaultSliceId | (static_cast<uint32_t>(pageId) << PAGE_OFFSET);
     }
-    uint16_t GetCurSliceId(void) {
+
+    /**
+     * @brief Get current slice id
+     * @return Returns <b>0</b> if js ability is running, detail refer to comments of variable allSlices_
+     */
+    uint16_t GetCurSliceId(void)
+    {
+        if (allSlices_.IsEmpty()) {
+            return gSliceInvalid;
+        }
+        return static_cast<uint16_t>(allSlices_[allSlices_.Size() - 1] & SLICE_MASK);
+    }
+
+    /**
+     * @brief Get prevoius slice id in the slice vector, detail refer to comments of variable allSlices_
+     */
+    uint16_t GetPreSliceId(void)
+    {
+        if (allSlices_.Size() < 2) {
+            return gSliceInvalid;
+        }
+        return static_cast<uint16_t>(allSlices_[allSlices_.Size() - 2] & SLICE_MASK);
+    }
+
+    void UpdateCurSlicePageId(uint16_t pageId);
+
+    uint32_t GetCurTargetId(void)
+    {
         if (allSlices_.IsEmpty()) {
             return gSliceInvalid;
         }
@@ -51,26 +124,27 @@ public:
         return allSlices_[allSlices_.Size() - 1];
     }
 
-    uint16_t GetPreSliceId(void) {
-        if (allSlices_.Size() < 2) {
+    uint32_t GetPreTargetId(void)
+    {
+        if (allSlices_.Size() < 2) { // 2, minimum count if contains previous target
             return gSliceInvalid;
         }
-        return allSlices_[allSlices_.Size() - 2];
+
+        return allSlices_[allSlices_.Size() - 2]; // 2, index offset
     }
 
-    void SetCurSlicePriority(const uint16_t priority) {
+    void SetCurSlicePriority(uint16_t priority)
+    {
         curSlicePriority_ = priority;
     }
 
-    uint16_t GetCurSlicePriority(void) {
+    uint16_t GetCurSlicePriority(void)
+    {
         return curSlicePriority_;
     }
-    void StartSlice(const uint16_t sliceId, const uint16_t priority);
-    void ResumeSliceWithoutJS();
+
     void ResumeSlice();
     void PauseSlice();
-    void StopSlice();
-    void StopPrevSlice();
     void StopSliceTransition();
     void BackToPreSlice();
                
@@ -83,7 +157,7 @@ public:
         const uint16_t priority = gSliceDefaultPriority,bool enableSlideBack = false) {
         // 获取当前SliceID
         uint16_t curSliceId = GetCurSliceId();
-        if (curSliceId != defaultSliceId_) { // 假定defaultSliceId_是“主页”或启动Slice的ID
+        if (curSliceId != defaultTargetId_) { // 假定defaultSliceId_是“主页”或启动Slice的ID
             backStack_.push(curSliceId);
         }
         ChangeSlice(sliceId,transitionId,priority,enableSlideBack); // 切换到新的Slice
@@ -113,9 +187,9 @@ public:
         }
         else
         {
-            backStack_.push(defaultSliceId_); // 将默认主界面的 ID 推入栈中
+            backStack_.push(defaultTargetId_); // 将默认主界面的 ID 推入栈中
             // 退回到defaultSliceId_
-            ChangeSlice(defaultSliceId_, transitionId, priority,enableSlideBack);
+            ChangeSlice(defaultTargetId_, transitionId, priority,enableSlideBack);
             return false; // 返回false表示无前一个slice,退回到默认slice
         }
     }
@@ -146,7 +220,7 @@ public:
         else
         {
             //如果 backStack_ 栈为空,切换到默认切片,返回 false 。
-            ChangeSlice(defaultSliceId_, transitionId, priority);
+            ChangeSlice(defaultTargetId_, transitionId, priority);
             return false; // 返回false表示无前一个slice,退回到默认slice
         }
     }
@@ -178,7 +252,7 @@ public:
             backStack_.pop();
         }
         if (backStack_.empty()) {
-        backStack_.push(defaultSliceId_); // 将默认主界面的 ID 推入栈中
+            backStack_.push(defaultTargetId_); // 将默认主界面的 ID 推入栈中
         }
     }
 
@@ -199,6 +273,10 @@ public:
     /* -------------------------------------------------------------------------- */
 
 protected:
+    // targetId consists of slice id and page id
+    void StartSlice(uint32_t targetId);
+    void ResumeSliceWithoutJS();
+    void StopSlice();
     Ability() = default;
     virtual ~Ability() = default;
     struct ProxyStruct {
@@ -214,17 +292,20 @@ protected:
     // 预加载的所有slices
     Graphic::Vector<ProxyStruct> allSlicesProxy_{16};
 
-    // 历史记录的所有slices, 当前只使用了id
-    // TODO:: 整页面的能力恢复功能待考虑扩展
-    Graphic::Vector<uint16_t> allSlices_;
+    /** Processing rule of allSlices_, its item value consists of slice and page. slice | page << 16.
+     *    1. When switch slice A to main slice, clear slice vector, and then push back main slice into slice vector
+     *    2. When switch slice A to slice B (not main), push back slice B into slice vector
+     *    3. When switch js to slice A, clear slice vector, and then push back slice A into slice vector
+     *    4. When switch slice A to js, push back 0 into slice vector. You Can get slice A by method GetPreSliceId()
+     */
+    Graphic::Vector<uint32_t> allSlices_;
 
     SliceStruct curSlice_;
-    SliceStruct prevSlice_;
-    uint16_t targetSliceIdFromJS_ = 0;
-    uint16_t defaultSliceId_ = gSliceInvalid;
+    SliceStruct nextSlice_;
+    uint32_t targetIdFromJS_ = 0;
+    uint32_t defaultTargetId_ = gSliceInvalid;
     uint16_t curSlicePriority_ = gSliceDefaultPriority;
-    void PostChangeSlice(const uint16_t targetSliceId, TransitionType type,
-        const uint16_t priority, bool enableSlideBack);
+    void PostChangeSlice(uint32_t targetId, TransitionType type);
     Ability::ProxyStruct* Find(const uint16_t sliceId);
 private:
     std::stack<uint16_t> backStack_;//这个栈会在每次进入一个新的Slice时将其ID压入栈顶,当用户请求后退时,栈顶的Slice ID会被弹出,以此来访问前一个Slice。
index a4acb09..09a8c81 100644 (file)
@@ -17,7 +17,9 @@
 #define NATIVEABILITYFWK_ABILITY_SLICE_H
 #include <typeinfo>
 #include "Slice.h"
-#include "wearable_log.h"
+#include "Presenter.h"
+#include "View.h"
+#include "SlicePageManager.h"
 
 namespace OHOS {
 enum class SliceState : uint8_t {
@@ -27,93 +29,33 @@ enum class SliceState : uint8_t {
     PAUSE,
     STOP
 };
-template<class V, class P, class M = void>
 class AbilitySlice : public Slice {
 public:
-    AbilitySlice<V, P, M>()
-        :view_(nullptr), presenter_(nullptr), state_(SliceState::UNINITIALIZED) {}
-    ~AbilitySlice() {}
+    AbilitySlice(ViewBase* viewBase, PresenterBase* presenterBase, uint32_t targetId)
+        : sliceId_(targetId & SLICE_MASK), view_(viewBase), presenter_(presenterBase),
+          slicePageMgr_(targetId), state_(SliceState::UNINITIALIZED) {}
 
-    void OnStart() override
-    {
-        if ((presenter_ != nullptr) || (view_ != nullptr)) {
-            return;
-        }
+    void OnStart() override;
 
-        presenter_ = new P();
-        view_ = new V();
+    void OnResume() override;
 
-        presenter_->Attach(view_);
-        view_->Attach(presenter_);
+    void OnPause() override;
 
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Slice %s OnStart", typeid(view_).name());
-        view_->SetupView();
-        view_->OnStart();
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Slice %s OnStart", typeid(presenter_).name());
-        presenter_->OnStart();
-        state_ = SliceState::START;
-    }
+    void OnStop() override;
 
-    void OnResume() override
-    {
-        if ((state_ != SliceState::START) && (state_ != SliceState::PAUSE)) { // avoid repeated resume
-            return;
-        }
-        if (presenter_ != nullptr) {
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Slice %s OnResume", typeid(presenter_).name());
-            presenter_->OnResume();
-        }
-        if (view_ != nullptr) {
-            view_->Draw();
-        }
-        state_ = SliceState::RESUME;
-    }
+    UIViewGroup* GetSliceContainer() override;
 
-    void OnPause() override
-    {
-        if (state_ != SliceState::RESUME) { // avoid repeated pause
-            return;
-        }
-        if (presenter_ != nullptr) {
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Slice %s OnPause", typeid(presenter_).name());
-            presenter_->OnPause();
-        }
-        state_ = SliceState::PAUSE;
-    }
+    bool ChangeSlicePage(uint16_t pageId, void* data, TransitionType type, bool canBack);
 
-    void OnStop() override
+    SlicePageManager* GetSlicePageManger()
     {
-        if (view_ != nullptr) {
-            view_->TearDownView();
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Slice %s OnStop", typeid(view_).name());
-            view_->OnStop();
-            delete view_;
-            view_ = nullptr;
-        }
-        if (presenter_ != nullptr) {
-            WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Slice %s OnStop", typeid(presenter_).name());
-            presenter_->OnStop();
-            delete presenter_;
-            presenter_ = nullptr;
-        }
-        state_ = SliceState::STOP;
+        return &slicePageMgr_;
     }
-
-    UIViewGroup* GetSliceContainer() override
-    {
-        if (view_ != nullptr) {
-            return view_->GetRootContainer();
-        } else {
-            return nullptr;
-        }
-    }
-
 private:
-    AbilitySlice(const AbilitySlice &);
-    AbilitySlice &operator=(const AbilitySlice &);
-
-    V* view_;
-    P* presenter_;
+    uint16_t sliceId_;
+    ViewBase* view_;
+    PresenterBase* presenter_;
+    SlicePageManager slicePageMgr_;
     SliceState state_;
 };
 } // namespace OHOS
index d942f0c..1cb8f89 100644 (file)
 #define NATIVEABILITYFWK_ABILITY_SLICE_PROXY_H
 
 #include "AbilitySlice.h"
-
 #include "wearable_log.h"
+#include "Presenter.h"
 
 namespace OHOS {
 template <class V, class P>
-
 class AbilitySliceProxy : public SliceProxy {
 public:
-    AbilitySliceProxy<V, P>() {}
-    ~AbilitySliceProxy() {}
-
-    Slice* CreateSlice() override
+    Slice* CreateSlice(uint32_t targetId) override
     {
-        return new AbilitySlice<V, P>();
+        V* v = new V();
+        if (v == nullptr) {
+            return nullptr;
+        }
+        P* p = new P();
+        if (p == nullptr) {
+            delete v;
+            return nullptr;
+        }
+        return new AbilitySlice(v, p, targetId);
     }
-
-private:
-    AbilitySliceProxy(const AbilitySliceProxy &);
-    AbilitySliceProxy &operator=(const AbilitySliceProxy &);
 };
 } // namespace OHOS
 #endif // NATIVEABILITYFWK_ABILITY_SLICE_PROXY_H
index a851b55..4cca1df 100644 (file)
@@ -9,16 +9,21 @@
 #define BACK_DRAG_LISTENER_H
 #include <functional>
 #include "animator/animator.h"
-#include "components/ui_view.h"
+#include "components/ui_view_group.h"
 
 namespace OHOS {
 class BackDragListener : public UIView::OnDragListener {
 public:
-    static BackDragListener* GetInstance();
+    BackDragListener() = default;
+    ~BackDragListener() override;
     bool OnDragStart(UIView& view, const DragEvent& event) override;
     bool OnDrag(UIView& view, const DragEvent& event) override;
     bool OnDragEnd(UIView& view, const DragEvent& event) override;
-    void ClearStatus();
+    void ClearDragState();
+    void SetParentView(UIViewGroup* view)
+    {
+        parentView_ = view;
+    }
     void SetCurrentAndTargetView(UIView *cur, UIView *tar)
     {
         curView_ = cur;
@@ -39,74 +44,46 @@ public:
     {
         time_ = time;
     }
+    BackDragListener(const BackDragListener &) = delete;
+    BackDragListener &operator=(const BackDragListener &) = delete;
+    BackDragListener(BackDragListener &&) = delete;
+    BackDragListener &operator=(BackDragListener &&) = delete;
 
 private:
-    BackDragListener() {};
-    ~BackDragListener() {};
     class BackAnimatorCallback : public AnimatorCallback {
     public:
+        BackAnimatorCallback(BackDragListener* listener, uint16_t duration)
+            : dragListener_(listener), curtTime_(0), duration_(duration) {}
         void Callback(UIView* view) override;
-        void OnStop(UIView& view) override;
-        void SetDragParam(int16_t startX, int16_t endX, uint16_t dragTimes)
-        {
-            startValueX_ = startX;
-            endValueX_ = endX;
-            dragTimes_ = dragTimes;
-        }
-
-        void SetAnimator(Animator *ani)
-        {
-            ani_ = ani;
-        }
-
-        void SetGoToTarget(bool goToTarget)
-        {
-            goToTarget_ = goToTarget;
-        }
-
-        void SetStopAction(const std::function<void()> &action)
-        {
-            stopAct_ = action;
-        }
-
-        void SetTargetView(UIView *target)
-        {
-            targetView_ = target;
-        }
-
-        void ResetStatus()
+        void OnStop(UIView& view) override
         {
             curtTime_ = 0;
-            dragTimes_ = 0;
-            startValueX_ = 0;
-            endValueX_ = 0;
-            ani_ = nullptr;
-            stopAct_ = nullptr;
-            targetView_ = nullptr;
-            goToTarget_ = false;
         }
-    private:
 
-        Animator *ani_ = nullptr;
-        UIView *targetView_ = nullptr;
-        uint16_t curtTime_ = 0;
-        uint16_t dragTimes_ = 0;
-        int16_t startValueX_ = 0;
-        int16_t endValueX_ = 0;
-        bool goToTarget_ = false;
-        std::function<void()> stopAct_;
+    private:
+        BackDragListener* dragListener_;
+        uint16_t curtTime_;
+        uint16_t duration_;
     };
 
+    bool StartAnimator();
+    void StopDragging();
     Animator *backAnimator_ = nullptr;
-    BackAnimatorCallback backCallback_;
+    BackAnimatorCallback* backCallback_ = nullptr;
     UIView *targetView_ = nullptr;
     UIView *curView_ = nullptr;
+    UIViewGroup* parentView_ = nullptr;
     int16_t left_ = 0;
     int16_t right_ = 0;
     std::function<void()> targetAction_;
     std::function<void()> curAction_;
     const static uint16_t DEFAULT_TIME = 200;
     uint16_t time_ = DEFAULT_TIME;
+    bool goToTarget_ = false;
+    int16_t animStartX_ = 0;
+    int16_t animEndX_ = 0;
+    bool isDragging_ = false;
+    bool isTargetViewAdded_ = false;
 }; // BackDragListener
 
 } // namespace OHOS
index 2b1a268..5ccd53d 100644 (file)
@@ -41,14 +41,9 @@ class NativeAbility : public Ability
 {
 public:
     static NativeAbility &GetInstance(void);
-
 #ifdef JS_ENABLE
     void InstallAbility(void);
 #endif
-    void ResumeAbility(uint16_t targetSliceId, uint16_t priority);
-    void PauseAbility();
-    void StopAbility();
-
     // SliteAbility, AMS控制的应用生命周期
     void OnStart(const Want &want) OVERRIDE;
     void OnActive(const Want &want) OVERRIDE;
@@ -57,7 +52,12 @@ public:
 
     void OnStop() OVERRIDE;
     int GetNativeAbilityState() const;
+
 private:
+    // targetId consists of slice id and page id
+    void ResumeAbility(uint32_t targetId);
+    void PauseAbility();
+    void StopAbility();
     NativeAbility() {}
     void ResumeSliceWithJS();
     ~NativeAbility() override {}
index 6e64f4b..ee3302b 100644 (file)
@@ -14,6 +14,7 @@
 #include "graphic_mutex.h"
 #include "TransitionCallback.h"
 #include "TransitionType.h"
+#include "gfx_utils/image_info.h"
 
 namespace OHOS {
 using TransitionAnimatorStopCallback = std::function<void()>;
@@ -75,6 +76,15 @@ public:
     // this function is called by application when slice is on pause phase if it need to custom its slideback snapshot
     void SaveSlideBackSnapShotIfNecessary(UIView* view);
     UIImageView* GetTopSlideBackImage();
+    /**
+     * @brief Check whether slide back is enabled currently, equivalent to:
+     *             View::GetBackDragListener()
+     *        Note: Don't use canSlideBack_ because it will be reset after transition
+     */
+    bool CanSlideBack()
+    {
+        return (GetTopSlideBackImage() != nullptr);
+    }
     // remove top slice back image from rootview and delete it
     void ClearTopSlideBackImage();
     void SaveCurrentSourceIfNecessary(UIView* view);
@@ -83,7 +93,6 @@ public:
     void SyncStopAnimator();
     void AsyncStopAnimator();
     void EndTransition(bool success);
-    void SetRunDirectlyTransition(TransitionCaller caller, TransitionTarget target);
     bool IsCurrentSnapshotEnabled()
     {
         return isCurrentSnapShotEnabled_;
@@ -106,6 +115,16 @@ public:
         return transitionCaller_ == TransitionCaller::BACK_TRANSITION;
     }
 
+    /**
+     * @brief   Set current app's recent img source. Should be invoked in OnResume method.
+     */
+    void SetRecentAppImg(uint32_t resId, std::string file);
+
+    /**
+     * @brief   Set min lasting period of an app so that it could be added to recent manager.
+     */
+    void SetRecentMinPeriod(uint32_t minPeriod);
+
 private:
     PageTransitionMgr() {};
     ~PageTransitionMgr() {};
@@ -113,11 +132,17 @@ private:
     void SaveSlideBackSnapShotInner(UIView* view, bool custom);
     void SaveCurrentSnapShotInner(UIView* view);
     void ClearSlideBackHistory();
+    bool SnapshotRecentSource(UIView* view);
+    void AddRecentAppIfNecessary();
+    bool FillRecentSnapshot(bool& needToFreeSnapshot);
     Animator* animator_ = nullptr;
     PageTransAnimCallback* animatorCallback_ = nullptr;
     std::shared_ptr<UIImageViewWithInfo> currentSlideBackSnapshot_ = nullptr;
     std::shared_ptr<UIImageViewWithInfo> currentSnapshot_ = nullptr;
     std::shared_ptr<UIImageViewWithInfo> targetSnapshot_ = nullptr;
+    ImageInfo recentSnapshot_ = {0};
+    uint32_t recentAppResId_ = 0;
+    std::string recentAppFile_ = "";
     std::shared_ptr<UIImageViewWithInfo> slideBackHistroy_[MAX_SLIDE_BACK_NUM] = {nullptr};
     uint8_t curSlideBackNum_ = 0;
     UIViewGroup* currentView_ = nullptr;
@@ -138,6 +163,12 @@ private:
     GraphicMutex operationLock_;
     void ClearTransitionResource();
     ImageInfo RectifySnapshot(ImageInfo& dstInfo);
+    uint32_t lastTransitionTime_ = 0;
+    uint32_t recentMinPeriod_ = 0;
+    bool recentMinPeriodSatisfied_ = true;
+    bool isSnapshotRecent_ = false;
+    uint16_t recentSliceId_ = 0; // invalid slice
+    uint32_t recentTargetId_ = 0; // invalid slice
 };
 } // namespace OHOS
 #endif // PAGE_TRANSITION_MGR_H
index 4057024..b8cbc7a 100644 (file)
 #ifndef APPFWK_PRESENTER_H
 #define APPFWK_PRESENTER_H
 
-#include "components/root_view.h"
-#include "KeyInputListener.h"
-#include "dock/focus_manager.h"
-#include "PageTransitionMgr.h"
-#include "NativeAbility.h"
-#include "BackDragListener.h"
+#include "View.h"
 
 namespace OHOS {
-template<class V, class M = void>
-
-class Presenter {
+class PresenterBase {
 public:
-    Presenter() : view_(nullptr), model_(nullptr) {}
-    virtual ~Presenter() {}
+    PresenterBase() : viewBase_(nullptr) {}
+    virtual ~PresenterBase() = default;
 
     /**
      * @brief Scheduled by slice when it is started and before transition animator starts if exsit
@@ -42,40 +35,15 @@ public:
      * @brief Scheduled by slice when it will be visiable and after transition animator ends if exsit
      *
      *        You can set custom input event listener, request focus, and start its own animator here.
-     *        Please call Presenter::OnResume in your implemention
      */
-    virtual void OnResume()
-    {
-        // make sure root container was added because it maybe removed during transition when current snap is false
-        if (view_->GetRootContainer()->GetParent() == nullptr) {
-            RootView::GetInstance()->Add(view_->GetRootContainer());
-        }
-        // Reset the default key listener
-        if(NativeAbility::GetInstance().GetCurSliceId() == VIEW_MAIN || NativeAbility::GetInstance().GetCurSliceId() == VIEW_APPLIST)
-            RootView::GetInstance()->SetOnKeyActListener(KeyInputListener::GetInstance());//加判断条件是解决其他界面按键监听被覆盖的问题
-        UIView* backView = PageTransitionMgr::GetInstance().GetTopSlideBackImage();
-        if (backView == nullptr) {
-            return;
-        }
-        BackDragListener::GetInstance()->ClearStatus();
-        BackDragListener::GetInstance()->SetCurrentAndTargetView(view_->GetRootContainer(), backView);
-        BackDragListener::GetInstance()->SetDragToTargetAction([]() { NativeAbility::GetInstance().BackToPreSlice(); });
-        view_->GetRootContainer()->SetOnDragListener(BackDragListener::GetInstance());
-    }
+    virtual void OnResume() {}
 
     /**
      * @brief Scheduled by slice when another slice will be started and before slice transition animator starts if exsit
      *
      *        You can clear input event listener, clear focus, and stop animator here.
-     *        Please call Presenter::OnPause in your implemention if default key listener need to be cleared.
      */
-    virtual void OnPause()
-    {
-        // Ensure that key listener is disabled during transition if exist
-        RootView::GetInstance()->ClearOnKeyActListener();
-        view_->GetRootContainer()->SetOnDragListener(nullptr);
-        FocusManager::GetInstance()->ClearFocus();
-    }
+    virtual void OnPause() {}
 
     /**
      * @brief Presenter lifecycle scheduled by slice when it will be invisible and another slice will be visible
@@ -83,14 +51,39 @@ public:
      *        You can destroy non-ui resources here
      */
     virtual void OnStop() {}
+
+    /**
+     * @brief This function will attach view to this presenter
+     *
+     * @param view view pointer defined by developer
+     */
+    virtual void Attach(ViewBase* view)
+    {
+        viewBase_ = view;
+    }
+
+    PresenterBase(const PresenterBase&) = delete;
+    PresenterBase& operator=(const PresenterBase&) = delete;
+    PresenterBase(PresenterBase&&) = delete;
+    PresenterBase& operator=(PresenterBase&&) = delete;
+protected:
+    ViewBase* viewBase_;
+};
+
+template<class V, class M = void>
+class Presenter : public PresenterBase {
+public:
+    Presenter() : model_(nullptr) {}
+
     /**
      * @brief This function will attach view to this presenter
      *
      * @param view view pointer defined by developer
      */
-    void Attach(V* view)
+    void Attach(ViewBase* view) override
     {
-        view_ = view;
+        PresenterBase::Attach(view);
+        view_ = dynamic_cast<V*>(viewBase_);
     }
 
     /**
@@ -106,13 +99,6 @@ public:
 protected:
     V* view_;
     M* model_;
-    BackDragListener* backDragListener_ = nullptr;
-
-private:
-    Presenter(const Presenter&) = delete;
-    Presenter& operator=(const Presenter&) = delete;
-    Presenter(Presenter&&) = delete;
-    Presenter& operator=(Presenter&&) = delete;
 };
 }
 #endif
diff --git a/code/sdk/application/wearable/fd230/nativeabilityfwk/include/RecentManager.h b/code/sdk/application/wearable/fd230/nativeabilityfwk/include/RecentManager.h
new file mode 100644 (file)
index 0000000..76e9598
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) CompanyNameMagicTag.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RECENT_MANAGER_H
+#define RECENT_MANAGER_H
+
+#include <cstdio>
+#include <string>
+#include "gfx_utils/image_info.h"
+#include "gfx_utils/list.h"
+#include "graphic_mutex.h"
+
+namespace OHOS {
+#define RECENT_APP_BUNDLE_NAME_MAX_LEN 127
+
+typedef struct {
+    bool isNativeSlice; // true: native; false: js
+    union {
+        uint32_t targetId;
+        char bundleName[RECENT_APP_BUNDLE_NAME_MAX_LEN];
+    };
+    ImageInfo* snapshot;
+} RecentAppInfo;
+
+class RecentManager {
+public:
+
+    /**
+     * @brief   Get <b>RecentManager*</b> instance.
+     */
+    static RecentManager* GetInstance();
+
+    /**
+     * @brief   Set max recent app size. Once current size > max, the oldest will be removed.
+     *          Default value is 0, and it will not record any recent app.
+     */
+    void SetMaxSize(uint32_t max);
+
+    /**
+     * @brief   Get max recent app size.
+     */
+    uint32_t GetMaxSize();
+
+    /**
+     * @brief   Get current recent app size.
+     */
+    uint32_t GetCurrentSize();
+
+    /**
+     * @brief   Add a native app to recent manager with its snapshot to be cached.
+     */
+    void AddRecentApp(uint32_t targetId, const ImageInfo* snapshot);
+
+    /**
+     * @brief   Add a js app to recent manager with its snapshot to be cached.
+     */
+    void AddRecentApp(const char* bundleName, const ImageInfo* snapshot);
+
+    /**
+     * @brief   Remove a native app with given targetId.
+     */
+    bool RemoveRecentApp(uint32_t targetId, bool deleteFile = true);
+
+    /**
+     * @brief   Remove a js app with given bundleName.
+     */
+    bool RemoveRecentApp(const char* bundleName, bool deleteFile = true);
+
+    /**
+     * @brief   Remove all recent apps.
+     */
+    void RemoveAllRecentApps();
+
+    /**
+     * @brief   Get a list of RecentAppInfo.
+     */
+    const List<RecentAppInfo*>& GetRecentApps();
+
+    /**
+     * @brief   Set scale ratio. When an app is added, its snapshot could be scaled and cached. Default value is 0.5f.
+     */
+    void SetScaleRatio(float ratio);
+
+    /**
+     * @brief   Get scale ratio.
+     */
+    float GetScaleRatio();
+
+    /**
+     * @brief   Add a sliceId to black list so that it will not be saved as a recent app.
+     */
+    void AddToBlackList(uint32_t sliceId);
+
+    /**
+     * @brief   Remove a sliceId from black list so that it can be saved as a recent app.
+     */
+    void RemoveFromBlackList(uint32_t sliceId);
+
+    /**
+     * @brief   Clear black list.
+     */
+    void ClearBlackList();
+
+    /**
+     * @brief   Return whether the sliceId is on black list.
+     */
+    bool IsOnBlackList(uint32_t sliceId);
+
+    /**
+     * @brief   Return whether it is updated.
+     */
+    bool IsUpdateCompleted();
+
+    /**
+     * @brief   Set dir path to save recent snapshots.
+     */
+    void SetDirPath(std::string path);
+
+    /**
+     * @brief   Return dir path to save recent snapshots.
+     */
+    std::string GetDirPath();
+
+    /**
+     * @brief   Return whether it is enabled. It is enabled when max size is a valid value and dir path is set.
+     */
+    bool IsEnabled();
+
+    /**
+     * @brief   Used internally.
+     */
+    void PushRecentApp(RecentAppInfo* info);
+
+    /**
+     * @brief   Used internally.
+     */
+    void RemoveOldest();
+
+    /**
+     * @brief   Used internally.
+     */
+    void DecLoadingCnt();
+
+    /**
+     * @brief   Used internally.
+     */
+    uint32_t GetLoadingCnt();
+
+private:
+    RecentManager();
+    virtual ~RecentManager();
+
+    void AddRecentAppWithSourceInfo(RecentAppInfo* appInfo, const ImageInfo* snapshot);
+    void AddRecentAppInner(RecentAppInfo* appInfo, const ImageInfo* snapshot);
+    void RemoveRecentAppNode(ListNode<RecentAppInfo*>* node, bool deleteFile);
+    bool ScaleSnapshot(const ImageInfo* src, ImageInfo* dst);
+    ListNode<RecentAppInfo*>* FindRecentAppInfo(List<RecentAppInfo*>& list,
+        bool isNativeSlice, uint32_t sliceId, const char* bundleName);
+    void AddPersistingTask(RecentAppInfo* info);
+    static void AsyncPersisterRunnable(void* args);
+    static void FreeRecentAppInfo(void* data);
+    void AsyncFreeRecentAppInfo(RecentAppInfo* info);
+    void ProcessPersistingTasks();
+    void ProcessTask(RecentAppInfo* info);
+    static void LoadRecentApp(void* data);
+    List<RecentAppInfo*> recentApps_;
+    List<RecentAppInfo*> persistingTasks_;
+    List<uint32_t> blackList_;
+    static GraphicMutex recentAppsMutex_;
+    static GraphicMutex persistingTaskMutex_;
+    static GraphicCond newPersistingTaskCond_;
+    static GraphicCond persistingTaskDoneCond_;
+    uint32_t maxSize_ = 0;
+    float scaleRatio_ = 0.5f;
+    std::string dirPath_;
+    uint32_t loadingCnt_ = 0;
+};
+} // namespace OHOS
+
+#endif // RECENT_MANAGER_H
index 9e87062..047cc60 100644 (file)
 #include "components/ui_view_group.h"
 
 namespace OHOS {
+extern const uint16_t SLICE_MASK;
+extern const uint32_t PAGE_OFFSET;
 class Slice {
 public:
-    Slice() {}
-    virtual ~Slice() {}
+    Slice() = default;
+    virtual ~Slice() = default;
     /**
      * @brief Called when the Slice is started and before transition animator starts if exits.
      *
@@ -54,9 +56,10 @@ public:
     virtual void OnStop() = 0;
     virtual UIViewGroup* GetSliceContainer() = 0;
 
-private:
-    Slice(const Slice &);
-    Slice &operator=(const Slice &);
+    Slice(const Slice &) = delete;
+    Slice &operator=(const Slice &) = delete;
+    Slice(Slice &&) = delete;
+    Slice &operator=(Slice &&) = delete;
 };
 } // namespace OHOS
 
diff --git a/code/sdk/application/wearable/fd230/nativeabilityfwk/include/SlicePage.h b/code/sdk/application/wearable/fd230/nativeabilityfwk/include/SlicePage.h
new file mode 100644 (file)
index 0000000..127f329
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2025. All rights reserved.
+ * Description: Slice Page
+ * Author: Hisi Graphic Team
+ * Create: 2025-4
+ */
+#ifndef SLICE_PAGE_H
+#define SLICE_PAGE_H
+#include "components/ui_view_group.h"
+#include "Presenter.h"
+
+namespace OHOS {
+class SlicePageBase {
+public:
+    SlicePageBase() : pageContainer_(nullptr), backDragListener_(nullptr) {}
+
+    virtual ~SlicePageBase() = default;
+
+    virtual void OnStart(void* data) = 0;
+
+    virtual void OnResume() {}
+
+    virtual void OnPause() {}
+
+    virtual void OnStop() {}
+
+    UIViewGroup* GetSlicePageContainer()
+    {
+        return pageContainer_;
+    }
+
+    BackDragListener* GetBackDragListener()
+    {
+        return backDragListener_;
+    }
+
+    void AddViewToPageContainer(UIView* view);
+
+    virtual void AttachPresenter(PresenterBase* p) = 0;
+
+    SlicePageBase(const SlicePageBase&) = delete;
+    SlicePageBase& operator=(const SlicePageBase&) = delete;
+    SlicePageBase(SlicePageBase&&) = delete;
+    SlicePageBase& operator=(SlicePageBase&&) = delete;
+    uint16_t pageId_;
+
+private:
+    friend class SlicePageManager;
+    void SetupView(bool canBack);
+    void TearDownView();
+    UIViewGroup* pageContainer_;
+    BackDragListener* backDragListener_;
+};
+
+template<class P>
+class SlicePage : public SlicePageBase {
+public:
+    void AttachPresenter(PresenterBase* p) override
+    {
+        presenter_ = dynamic_cast<P*>(p);
+    }
+protected:
+    P* presenter_ = nullptr;
+};
+}
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeabilityfwk/include/SlicePageFactory.h b/code/sdk/application/wearable/fd230/nativeabilityfwk/include/SlicePageFactory.h
new file mode 100644 (file)
index 0000000..49dd1c7
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2025. All rights reserved.
+ * Description: SlicePageFactory
+ * Author: Hisi Graphic Team
+ * Create: 2025-4
+ */
+#ifndef SLICE_PAGE_FACTORY_H
+#define SLICE_PAGE_FACTORY_H
+#include <unordered_map>
+#include "SlicePage.h"
+
+namespace OHOS {
+class SlicePageProxyInterface;
+class SlicePageFactory : public HeapBase {
+public:
+    static SlicePageFactory& GetInstance()
+    {
+        static SlicePageFactory instance;
+        return instance;
+    }
+
+    bool IsSlicePageExist(uint16_t sliceId, uint16_t pageId);
+
+    SlicePageBase* CreateSlicePage(uint16_t sliceId, uint16_t pageId);
+
+    SlicePageBase* GetDefaultSlicePage(uint16_t sliceId, uint16_t& defaultPageId);
+
+    void RegisterPage(uint16_t sliceId, uint16_t pageId, SlicePageProxyInterface* proxy, bool isMainPage);
+
+private:
+    SlicePageFactory() {};
+    ~SlicePageFactory() {};
+    SlicePageFactory(const SlicePageFactory &) = delete;
+    SlicePageFactory &operator=(const SlicePageFactory &) = delete;
+    std::unordered_map<uint32_t, SlicePageProxyInterface*> pageProxyMap_;
+    std::unordered_map<uint16_t, SlicePageProxyInterface*> mainPageMap_;
+    std::unordered_map<uint16_t, uint16_t> mainPageIdMap_;
+};
+
+class SlicePageProxyInterface : public HeapBase {
+public:
+    virtual SlicePageBase* CreateSlicePage(uint16_t pageId) = 0;
+};
+
+class SlicePageRegister : public HeapBase {
+public:
+    SlicePageRegister(uint16_t sliceId, uint16_t pageId, SlicePageProxyInterface* proxy, bool isMainPage);
+};
+
+template<class V>
+class SlicePageProxy : public SlicePageProxyInterface {
+public:
+    SlicePageBase* CreateSlicePage(uint16_t pageId) override
+    {
+        V* v = new V();
+        SlicePageBase* page = dynamic_cast<SlicePageBase*>(v);
+        if (page == nullptr) {
+            delete v;
+        } else {
+            page->pageId_ = pageId;
+        }
+        return page;
+    }
+};
+}
+
+#define REGIST_SLICE_PAGE(sliceId, pageId, V, isMainPage) \
+    const static OHOS::SlicePageRegister (STATIC_VAR)(sliceId, pageId, new OHOS::SlicePageProxy<V>(), isMainPage)
+#endif
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230/nativeabilityfwk/include/SlicePageManager.h b/code/sdk/application/wearable/fd230/nativeabilityfwk/include/SlicePageManager.h
new file mode 100644 (file)
index 0000000..c69ef48
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2025. All rights reserved.
+ * Description: SlicePageManager
+ * Author: Hisi Graphic Team
+ * Create: 2025-4
+ */
+#ifndef SLICE_PAGE_MANAGER_H
+#define SLICE_PAGE_MANAGER_H
+#include "animator/animator.h"
+#include "Presenter.h"
+#include "Slice.h"
+#include "SlicePage.h"
+#include "gfx_utils/vector.h"
+#include "TransitionType.h"
+#include "TransitionCallback.h"
+
+namespace OHOS {
+class SlicePageManager;
+class SlicePageSwitchCallback : public AnimatorCallback {
+public:
+    SlicePageSwitchCallback(SlicePageManager* transMgr)
+        : isStarted_(false), startTime_(0), pageTransMgr_(transMgr) {}
+    void Callback(UIView* view) override;
+    void OnStop(UIView& view) override;
+
+private:
+    bool isStarted_;
+    uint32_t startTime_;
+    SlicePageManager* pageTransMgr_;
+};
+
+class SlicePageManager : public HeapBase {
+public:
+    SlicePageManager(uint32_t targetId)
+        : isPageBeingSwitched_(false), sliceId_(static_cast<uint16_t>(targetId & SLICE_MASK)),
+          targetPageId_(static_cast<uint16_t>(targetId >> PAGE_OFFSET)),
+          curPage_(nullptr), nextPage_(nullptr), pagesInBackQueue_(4), // 4, default queue size
+          presenter_(nullptr), view_{nullptr}, transitionCallback_(nullptr), canBack_(false) {}
+
+    ~SlicePageManager();
+
+    // Get current page which is display on the screen
+    SlicePageBase* GetCurSlicePage()
+    {
+        return curPage_;
+    }
+
+    // Get specified page in the back queue
+    SlicePageBase* GetSlicePageInBackQueue(uint16_t sliceId);
+
+    // Get previous page before current page in the back queue
+    SlicePageBase* GetLastPageInBackQueue()
+    {
+        return pagesInBackQueue_.Back();
+    }
+
+    void ClearBackQueue();
+
+    bool ChangeSlicePage(uint16_t pageId, void* data, TransitionType type, bool canBack);
+
+    bool IsAnimatorRunning()
+    {
+        return ((animator_ != nullptr) && (animator_->GetState() != Animator::STOP));
+    }
+
+    void BackToPrevSlicePage();
+
+    SlicePageManager(const SlicePageManager&) = delete;
+    SlicePageManager& operator=(const SlicePageManager&) = delete;
+    SlicePageManager(SlicePageManager&&) = delete;
+    SlicePageManager& operator=(SlicePageManager&&) = delete;
+
+private:
+    friend class AbilitySlice;
+    friend class SlicePageSwitchCallback;
+    void AttachVP(PresenterBase* p, ViewBase* v)
+    {
+        presenter_ = p;
+        view_ = v;
+    }
+    void StartSlicePage(void* data = nullptr);
+    void ResumeSlicePage();
+    void PauseSlicePage();
+    void StopSlicePage(bool clearBackQueue = true);
+    void StartSwitchAnimator();
+    void StopSwitchAnimator();
+
+    Animator* animator_ = nullptr;
+    SlicePageSwitchCallback* switchCallback_ = nullptr;
+    bool isPageBeingSwitched_;
+    uint16_t sliceId_;
+    uint16_t targetPageId_;
+    SlicePageBase* curPage_;
+    SlicePageBase* nextPage_;
+    Graphic::Vector<SlicePageBase*> pagesInBackQueue_;
+    PresenterBase* presenter_;
+    ViewBase* view_;
+    TransitionCallback* transitionCallback_;
+    bool canBack_;
+};
+}
+#endif
\ No newline at end of file
index 7d1cc3b..ccbf2be 100644 (file)
 namespace OHOS {
 class SliceProxy {
 public:
-    SliceProxy() {}
-    ~SliceProxy() {}
-    virtual Slice* CreateSlice() = 0;
-
-private:
-    SliceProxy(const SliceProxy &);
-    SliceProxy &operator=(const SliceProxy &);
+    virtual Slice* CreateSlice(uint32_t targetId) = 0;
+    SliceProxy() = default;
+    virtual ~SliceProxy() = default;
+    SliceProxy(const SliceProxy&) = delete;
+    SliceProxy& operator=(const SliceProxy&) = delete;
+    SliceProxy(SliceProxy&&) = delete;
+    SliceProxy& operator=(SliceProxy&&) = delete;
 };
 } // namespace OHOS
 #endif // SLICE_PROXY_H
index 1243e46..2079266 100644 (file)
 #define APPFWK_VIEW_H
 
 #include "components/ui_view_group.h"
-#include "components/root_view.h"
-#include "common/screen.h"
+#include "BackDragListener.h"
 
 namespace OHOS {
-template<class P>
-class View {
+class PresenterBase;
+class ViewBase {
 public:
-    View() : presenter_(nullptr), rootContainer_(nullptr) {}
-    virtual ~View() {}
+    ViewBase() : rootContainer_(nullptr), backDragListener_(nullptr) {}
+    virtual ~ViewBase() = default;
 
     /**
-     * @brief get container view
-     *
-     * @returns container
+     * @brief Get container view
+     * @returns rootContainer_
      */
-    UIViewGroup* GetRootContainer() const
+    UIViewGroup* GetRootContainer()
     {
         return rootContainer_;
     }
 
+    /**
+     * @brief Get back drag listener
+     *        This method can be used in AbilitySlice.cpp, and also can be used in XXXView.cpp
+     *        If used in XXXView.cpp, you can use it to check whether default OnDragListener is configured.
+     * @returns backDragListener_
+     */
+    BackDragListener* GetBackDragListener()
+    {
+        return backDragListener_;
+    }
+
     /**
      * @brief Scheduled by slice after funtion SetupView and before transition animator starts if exits.
      *
@@ -65,76 +74,50 @@ public:
     virtual void OnStop() {}
 
     /**
-     * @brief Scheduled by slice to create root container add it to root view
+     * @brief draw container
      *
-     *        This method is called by system class AbilitySlice, you should not override it.
      */
-    void SetupView()
-    {
-        if (rootContainer_ != nullptr) {
-            printf("OnStart Error: rootContainer_ already exist");
-        } else {
-            rootContainer_ = new UIViewGroup();
-        }
-        rootContainer_->SetPosition(0, 0, RootView::GetInstance()->GetWidth(), RootView::GetInstance()->GetHeight());
-        RootView::GetInstance()->Add(rootContainer_);
-    }
+    void Draw();
 
     /**
-     * @brief Scheduled by slice to remove and delete root container from root view
+     * @brief This function will attach presenter to this view
      *
-     *        This method is called by by system class AbilitySlice, you should not override it.
+     * @param presenter presenter pointer defined by developer
      */
-    void TearDownView()
-    {
-        // Todo: Only remove root container, and application should remove other children in its own implemention
-        RootView::GetInstance()->Remove(rootContainer_);
-        if (rootContainer_ != nullptr) {
-            rootContainer_->RemoveAll();
-            delete rootContainer_;
-            rootContainer_ = nullptr;
-        } else {
-            printf("TearDownView Error: rootContainer_ was not initialized !!!");
-        }
-    }
+    virtual void Attach(PresenterBase* presenter) = 0;
 
-    /**
-     * @brief draw container
-     *
-     */
-    void Draw()
-    {
-        RootView::GetInstance()->Invalidate();
-    }
+    void AddViewToRootContainer(UIView* view);
+
+    ViewBase(const ViewBase&) = delete;
+    ViewBase& operator=(const ViewBase&) = delete;
+    ViewBase(ViewBase&&) = delete;
+    ViewBase& operator=(ViewBase&&) = delete;
+
+private:
+    friend class AbilitySlice;
+    void SetupView();
+    void TearDownView();
+    UIViewGroup* rootContainer_;
+    BackDragListener* backDragListener_;
+};
+
+template<class P>
+class View : public ViewBase {
+public:
+    View() : presenter_(nullptr) {}
 
     /**
      * @brief This function will attach presenter to this view
      *
      * @param presenter presenter pointer defined by developer
      */
-    void Attach(P* presenter)
-    {
-        presenter_ = presenter;
-    }
-
-    void AddViewToRootContainer(UIView* view)
+    void Attach(PresenterBase* presenter) override
     {
-        if (rootContainer_ == nullptr) {
-            printf("AddViewToContainer Error: rootContainer_ is nullptr");
-            return;
-        }
-        rootContainer_->Add(view);
+        presenter_ = dynamic_cast<P*>(presenter);
     }
 
 protected:
     P* presenter_;
-
-private:
-    UIViewGroup* rootContainer_ = nullptr;
-    View(const View&) = delete;
-    View& operator=(const View&) = delete;
-    View(View&&) = delete;
-    View& operator=(View&&) = delete;
 };
 }
 #endif
index ff8ce55..a28bd30 100644 (file)
 #include "common/graphic_utils.h"
 #include "PageTransitionMgr.h"
 #include "gfx_utils/list.h"
+#include "AbilitySlice.h"
 
 namespace OHOS {
-const uint8_t MAX_SLICE_ID_LENGTH = 16;
-struct SliceOperation {
-    uint16_t targetSliceId;
-    TransitionType type;
-};
-
 void Ability::AddSliceProxy(const uint16_t sliceId, SliceProxy* proxy)
 {
     WEARABLE_LOGD(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability AddSliceProxy sliceId = %d", sliceId);
@@ -47,49 +42,39 @@ void Ability::AddSliceProxy(const uint16_t sliceId, SliceProxy* proxy)
     allSlicesProxy_.PushBack(proxyPair);
 }
 
-void Ability::StartSlice(const uint16_t sliceId, const uint16_t priority)
+void Ability::StartSlice(uint32_t targetId)
 {
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability StartSlice %d", sliceId);
-    if (sliceId <= gSliceInvalid) {
+    if (targetId <= gSliceInvalid) {
         return;
     }
-
+    uint16_t sliceId = static_cast<uint16_t>(targetId & SLICE_MASK);
     Ability::ProxyStruct* proxyStruct = Find(sliceId);
     if (proxyStruct == nullptr) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "no slice %d was found", sliceId);
         return;
     }
     InputDeviceManager::GetInstance()->ClearInputDeviceState();
-    Slice* nextSlice = proxyStruct->proxy->CreateSlice();
-    if (nextSlice == nullptr) {
+
+    Slice* newSlice = proxyStruct->proxy->CreateSlice(targetId);
+    if (newSlice == nullptr) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "create slice %u failed", sliceId);
         return;
     }
-    WEARABLE_LOGD(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability::StartSlice Size = %d", allSlices_.Size());
-    // 记录最多gMaxHistorySlices个页面id
 
-    if (PageTransitionMgr::GetInstance().IsBackTransitionRunning()) {
-        PageTransitionMgr::GetInstance().ClearTopSlideBackImage();
-    }
-    if (sliceId == defaultSliceId_) {
-        allSlices_.Clear(); // clear slice history when return to home
-        allSlices_.PushBack(defaultSliceId_);
+    if (sliceId == defaultTargetId_) {
+        allSlices_.Clear(); // clear slice history when return to main slice
+        allSlices_.PushBack(defaultTargetId_);
     } else if (PageTransitionMgr::GetInstance().IsBackTransitionRunning()) {
         allSlices_.PopBack();
     } else {
-        allSlices_.PushBack(sliceId);
+        allSlices_.PushBack(targetId);
     }
-    if (curSlice_.slice != nullptr) {
-        prevSlice_.sliceId = curSlice_.sliceId;
-        prevSlice_.slice = curSlice_.slice;
-    } else {
-        prevSlice_.sliceId = gSliceInvalid;
-        prevSlice_.slice = nullptr;
-    }
-
-    curSlice_.sliceId = sliceId;
-    curSlice_.slice = nextSlice;
-    curSlicePriority_ = priority;
 
-    nextSlice->OnStart();
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability StartSlice %d page %d size:%d", sliceId,
+        targetId >> PAGE_OFFSET, allSlices_.Size());
+    nextSlice_.sliceId = sliceId;
+    nextSlice_.slice = newSlice;
+    newSlice->OnStart();
 }
 
 Ability::ProxyStruct* Ability::Find(const uint16_t sliceId)
@@ -110,14 +95,59 @@ Ability::ProxyStruct* Ability::Find(const uint16_t sliceId)
     return nullptr;
 }
 
-void Ability::ChangeSlice(const uint16_t targetSliceId, TransitionType type,
-    const uint16_t priority, bool enableSlideBack)
+SlicePageManager* Ability::GetCurSlicePageManager()
 {
+    if (PageTransitionMgr::GetInstance().IsTransitionRunning())
+    {
+        WEARABLE_LOGW(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "No valid SlicePageManager during slice switching");
+        return nullptr;
+    }
+    AbilitySlice* slice = dynamic_cast<AbilitySlice*>(curSlice_.slice);
+    if (slice == nullptr) {
+        WEARABLE_LOGW(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "No valid SlicePageManager when js is running");
+        return nullptr;
+    }
+    return slice->GetSlicePageManger();
+}
+
+void Ability::UpdateCurSlicePageId(uint16_t pageId)
+{
+    if (allSlices_.IsEmpty()) {
+        return;
+    }
+    uint32_t sliceId = allSlices_[allSlices_.Size() - 1] & SLICE_MASK;
+    allSlices_[allSlices_.Size() - 1] = sliceId | (static_cast<uint32_t>(pageId) << PAGE_OFFSET);
+}
+
+bool Ability::SwitchPageInSlice(uint16_t pageId, void* data, TransitionType type, bool canBack)
+{
+    if (pageId == 0) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "page id should be valid but no zero");
+        return false;
+    }
+    if (PageTransitionMgr::GetInstance().IsTransitionRunning()) {
+        WEARABLE_LOGW(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "page can't be switched during transition");
+        return false;
+    }
+    AbilitySlice* slice = dynamic_cast<AbilitySlice*>(curSlice_.slice);
+    if (slice == nullptr) {
+        WEARABLE_LOGW(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "page can't be switched because current slice is nullptr");
+        return false;
+    }
+    return slice->ChangeSlicePage(pageId, data, type, canBack);
+}
+
+void Ability::SwitchSlice(uint16_t sliceId, uint16_t pageId, TransitionType type, bool enableSlideBack)
+{
+    if (Find(sliceId) == nullptr) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "slice %d is not registered", sliceId);
+        return;
+    }
 #ifdef JS_ENABLE
     ElementName *elementName = OHOS::AbilityMsClient::GetInstance().GetTopAbility();
     if (elementName != nullptr && strcmp(elementName->bundleName, "com.huawei.launcher") != 0) {
         OHOS::AbilityMsClient::GetInstance().ForceStop(elementName->bundleName, type);
-        targetSliceIdFromJS_ = targetSliceId;
+        targetIdFromJS_ = sliceId | (static_cast<uint32_t>(pageId) << PAGE_OFFSET);
         FreeElement(elementName);
         return;
     }
@@ -143,32 +173,43 @@ void Ability::ChangeSlice(const uint16_t targetSliceId, TransitionType type,
     }
     #endif
     TransitionTarget target;
-    target.sliceInfo = targetSliceId | (priority << 16);
+    target.sliceInfo = sliceId | (static_cast<uint32_t>(pageId) << PAGE_OFFSET);
     bool runImmed = PageTransitionMgr::GetInstance().BeginTransition(TransitionCaller::CHANGE_SLICE, target,
         type, enableSlideBack);
     if (!runImmed) {
-        printf("pending change slice id:%d type:%d enableSlideBack:%d\n", targetSliceId, type, enableSlideBack);
+        printf("pending change slice id:%d type:%d enableSlideBack:%d\n", target.sliceInfo, type, enableSlideBack);
         return;
     }
-    GraphicService::GetInstance()->PostGraphicEvent(std::bind(&Ability::PostChangeSlice, this, targetSliceId,
-        type, priority, enableSlideBack));
+    GraphicService::GetInstance()->PostGraphicEvent(std::bind(&Ability::PostChangeSlice, this, target.sliceInfo, type));
 }
 
-void Ability::PostChangeSlice(const uint16_t targetSliceId, TransitionType type,
+void Ability::ChangeSlice(uint16_t sliceId, TransitionType type,
     const uint16_t priority, bool enableSlideBack)
+{
+    (void)(priority);
+    SwitchSlice(sliceId, gPageInvalid, type, enableSlideBack);
+}
+
+void Ability::PostChangeSlice(uint32_t targetId, TransitionType type)
 {
     PauseSlice();
+    if (allSlices_.Size() > 0 && allSlices_[allSlices_.Size() - 1] == VIEW_AOD) {
+        allSlices_.PopBack();
+        if (allSlices_.Size() > 0 && (allSlices_[allSlices_.Size() - 1] & SLICE_MASK) == (targetId & SLICE_MASK)) {
+            allSlices_.PopBack();
+        }
+    }
     PageTransitionMgr::GetInstance().SaveCurrentSourceIfNecessary(curSlice_.slice->GetSliceContainer());
     if (!PageTransitionMgr::GetInstance().IsTransAnimNeeded() ||
         PageTransitionMgr::GetInstance().IsCurrentSnapshotEnabled()) {
         StopSlice();
     }
-    StartSlice(targetSliceId, priority);
+    StartSlice(targetId);
 
     if (!PageTransitionMgr::GetInstance().IsTransAnimNeeded()) {
         ResumeSliceWithoutJS();
     } else {
-        PageTransitionMgr::GetInstance().SaveTargetSource(curSlice_.slice->GetSliceContainer());
+        PageTransitionMgr::GetInstance().SaveTargetSource(nextSlice_.slice->GetSliceContainer());
         PageTransitionMgr::GetInstance().StartTransAnim(std::bind(&Ability::ResumeSliceWithoutJS, this));
     }
 }
@@ -177,7 +218,7 @@ void Ability::ResumeSliceWithoutJS()
 {
     if (PageTransitionMgr::GetInstance().IsTransAnimNeeded() &&
         !PageTransitionMgr::GetInstance().IsCurrentSnapshotEnabled()) {
-        StopPrevSlice();
+        StopSlice();
     }
     ResumeSlice();
     PageTransitionMgr::GetInstance().EndTransition(true);
@@ -185,6 +226,17 @@ void Ability::ResumeSliceWithoutJS()
 
 void Ability::ResumeSlice()
 {
+    // if new slice was created, set is as current slice and resume it
+    if (nextSlice_.slice != nullptr) {
+        if (curSlice_.slice != nullptr) {
+            GRAPHIC_LOGE("Both slice %d and %d is valid during resume", curSlice_.sliceId, nextSlice_.sliceId);
+        }
+        curSlice_.sliceId = nextSlice_.sliceId;
+        curSlice_.slice = nextSlice_.slice;
+        nextSlice_.sliceId = gSliceInvalid;
+        nextSlice_.slice = nullptr;
+    }
+
     if (curSlice_.slice != nullptr) {
         WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability ResumeSlice %d", curSlice_.sliceId);
         curSlice_.slice->OnResume();
@@ -196,8 +248,8 @@ void Ability::ResumeSlice()
 void Ability::PauseSlice()
 {
     if (curSlice_.slice != nullptr) {
-        WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability PauseSlice %d", curSlice_.sliceId);
         InputDeviceManager::GetInstance()->ClearInputDeviceState();
+        WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability PauseSlice %d", curSlice_.sliceId);
         curSlice_.slice->OnPause();
     } else {
         GRAPHIC_LOGE("No valid slice to pause");
@@ -218,21 +270,6 @@ void Ability::StopSlice()
     }
 }
 
-void Ability::StopPrevSlice()
-{
-    if (prevSlice_.slice != nullptr) {
-        WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability StopPrevSlice %d", prevSlice_.sliceId);
-        prevSlice_.slice->OnStop();
-        if (prevSlice_.slice != nullptr) {
-            prevSlice_.sliceId = gSliceInvalid;
-            delete prevSlice_.slice;
-            prevSlice_.slice = nullptr;
-        }
-    } else {
-        GRAPHIC_LOGE("No valid prev slice to stop");
-    }
-}
-
 void Ability::StopSliceTransition()
 {
     PageTransitionMgr::GetInstance().SyncStopAnimator();
@@ -240,15 +277,17 @@ void Ability::StopSliceTransition()
 
 void Ability::BackToPreSlice()
 {
-    uint16_t targetSliceId = GetPreSliceId();
-    WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability BackToPreSlice %d", targetSliceId);
-    if (targetSliceId == gSliceInvalid) {
+    uint32_t targetId = GetPreTargetId();
+    WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Ability BackToPreSlice %d", targetId);
+    if (targetId == gSliceInvalid) {
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "previous slice is invalid");
         return;
     }
     TransitionTarget target;
-    target.sliceInfo = targetSliceId | (gSliceDefaultPriority << 16);
+    target.sliceInfo = targetId;
+    uint16_t sliceId = static_cast<uint16_t>(targetId & SLICE_MASK);
+    uint16_t pageId = static_cast<uint16_t>(targetId >> PAGE_OFFSET);
     PageTransitionMgr::GetInstance().BeginBackTransition(TransitionCaller::CHANGE_SLICE, target);
-    ChangeSlice(targetSliceId);
+    SwitchSlice(sliceId, pageId);
 }
 } // namespace OHOS
diff --git a/code/sdk/application/wearable/fd230/nativeabilityfwk/src/AbilitySlice.cpp b/code/sdk/application/wearable/fd230/nativeabilityfwk/src/AbilitySlice.cpp
new file mode 100644 (file)
index 0000000..37810c7
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) CompanyNameMagicTag 2025. All rights reserved.
+ * Description: AbilitySlice
+ * Author: Hisi Graphic Team
+ * Create: 2025-4
+ */
+
+#include "AbilitySlice.h"
+#include "components/root_view.h"
+#include "dock/focus_manager.h"
+#include "wearable_log.h"
+#include "PageTransitionMgr.h"
+#include "NativeAbility.h"
+#include "View.h"
+#include "Presenter.h"
+#include "key/KeyInputListener.h"
+
+namespace OHOS {
+const uint16_t SLICE_MASK = 0xFFFF;
+const uint32_t PAGE_OFFSET = 16;
+
+void AbilitySlice::OnStart()
+{
+    if ((presenter_ == nullptr) || (view_ == nullptr)) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "Presenter or View  was nullptr for slice %s", sliceId_);
+        return;
+    }
+
+    // if back to current slice, delete slide back ImageView of current slice firstly
+    if (PageTransitionMgr::GetInstance().IsBackTransitionRunning()) {
+        PageTransitionMgr::GetInstance().ClearTopSlideBackImage();
+    }
+    presenter_->Attach(view_);
+    view_->Attach(presenter_);
+    slicePageMgr_.AttachVP(presenter_, view_);
+
+    view_->SetupView();
+    view_->OnStart();
+    slicePageMgr_.StartSlicePage();
+    presenter_->OnStart();
+    state_ = SliceState::START;
+}
+
+void AbilitySlice::OnResume()
+{
+    if ((state_ != SliceState::START) && (state_ != SliceState::PAUSE)) { // avoid repeated resume
+        return;
+    }
+    if ((presenter_ == nullptr) || (view_ == nullptr)) {
+        return;
+    }
+
+    if (view_->GetRootContainer()->GetParent() == nullptr) {
+        RootView::GetInstance()->Add(view_->GetRootContainer());
+    }
+    // Reset the default key listener
+    RootView::GetInstance()->SetOnKeyActListener(KeyInputListener::GetInstance());
+    NativeAbility::GetInstance().SetCurSlicePriority(gSliceDefaultPriority);
+
+    UIView* backView = PageTransitionMgr::GetInstance().GetTopSlideBackImage();
+    BackDragListener* backDragListener = view_->GetBackDragListener();
+    if ((backView != nullptr) && ((backDragListener != nullptr))) {
+        backDragListener->SetCurrentAndTargetView(view_->GetRootContainer(), backView);
+        backDragListener->SetParentView(RootView::GetInstance());
+        backDragListener->SetDragToTargetAction([]() { NativeAbility::GetInstance().BackToPreSlice(); });
+        view_->GetRootContainer()->SetTouchable(true);
+        view_->GetRootContainer()->SetDraggable(true);
+        view_->GetRootContainer()->SetOnDragListener(backDragListener);
+    }
+
+    slicePageMgr_.ResumeSlicePage();
+    presenter_->OnResume();
+    view_->Draw();
+    state_ = SliceState::RESUME;
+}
+
+void AbilitySlice::OnPause()
+{
+    if (state_ != SliceState::RESUME) { // avoid repeated pause
+        return;
+    }
+    if ((presenter_ == nullptr) || (view_ == nullptr)) {
+        return;
+    }
+
+    if (slicePageMgr_.IsAnimatorRunning()) {
+        slicePageMgr_.StopSwitchAnimator();
+    }
+    slicePageMgr_.PauseSlicePage();
+    RootView::GetInstance()->ClearOnKeyActListener();
+    BackDragListener* backDragListener = view_->GetBackDragListener();
+    if (backDragListener != nullptr) {
+        backDragListener->ClearDragState();
+    }
+    view_->GetRootContainer()->SetOnDragListener(nullptr);
+
+    FocusManager::GetInstance()->ClearFocus();
+    presenter_->OnPause();
+    state_ = SliceState::PAUSE;
+}
+
+void AbilitySlice::OnStop()
+{
+    if ((presenter_ == nullptr) || (view_ == nullptr)) {
+        return;
+    }
+
+    slicePageMgr_.StopSlicePage();
+    view_->TearDownView();
+    view_->OnStop();
+    delete view_;
+    view_ = nullptr;
+
+    presenter_->OnStop();
+    delete presenter_;
+    presenter_ = nullptr;
+
+    state_ = SliceState::STOP;
+}
+
+UIViewGroup* AbilitySlice::GetSliceContainer()
+{
+    if (view_ != nullptr) {
+        return view_->GetRootContainer();
+    } else {
+        return nullptr;
+    }
+}
+
+bool AbilitySlice::ChangeSlicePage(uint16_t pageId, void* data, TransitionType type, bool canBack)
+{
+    return slicePageMgr_.ChangeSlicePage(pageId, data, type, canBack);
+}
+}
\ No newline at end of file
index f488664..b885efe 100644 (file)
@@ -86,37 +86,40 @@ void NativeAbility::ResumeSliceWithJS()
 #endif
 }
 
-void NativeAbility::ResumeAbility(uint16_t targetSliceId, uint16_t priority)
+void NativeAbility::ResumeAbility(uint32_t targetId)
 {
     GraphicService::GetInstance()->SetNativeUIRunning(true);
     NotificationManager::GetInstance()->SetNativeUIRunning(true);
-    if (curSlice_.slice == nullptr) {
+    if ((targetId & SLICE_MASK) != VIEW_AOD) {
         allSlices_.Clear(); // clear slice history when jump from js to native
-        StartSlice(targetSliceId, priority);
     } else {
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "NativeAbility ResumeAbility with slice %d", curSlice_.sliceId);
+        allSlices_.PopBack(); // clear invalid slice id
+    }
+    StartSlice(targetId);
+    if (nextSlice_.slice == nullptr) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "NativeAbility ResumeAbility %d failed", targetId);
+        return;
     }
-
     if (!PageTransitionMgr::GetInstance().IsTransAnimNeeded()) {
         ResumeSliceWithJS();
     } else {
-        PageTransitionMgr::GetInstance().SaveTargetSource(curSlice_.slice->GetSliceContainer());
+        PageTransitionMgr::GetInstance().SaveTargetSource(nextSlice_.slice->GetSliceContainer());
         PageTransitionMgr::GetInstance().StartTransAnim(std::bind(&NativeAbility::ResumeSliceWithJS, this));
     }
 }
 
 void NativeAbility::OnActive(const Want &want)
 {
-    uint16_t targetSliceId = gSliceInvalid;
-    if (targetSliceIdFromJS_ != gSliceInvalid) {
-        targetSliceId = targetSliceIdFromJS_;
-        targetSliceIdFromJS_ = gSliceInvalid;
-    } else if (GetPreSliceId() != gSliceInvalid) {
-        targetSliceId = GetPreSliceId();
-    } else if (GetCurSliceId() != gSliceInvalid) {
-        targetSliceId = GetCurSliceId();
+    uint32_t targetId = gSliceInvalid;
+    if (targetIdFromJS_ != gSliceInvalid) {
+        targetId = targetIdFromJS_;
+        targetIdFromJS_ = gSliceInvalid;
+    } else if (GetPreTargetId() != gSliceInvalid) {
+        targetId = GetPreTargetId(); // for forcestop or ternimate js
+    } else if (GetCurTargetId() != gSliceInvalid) {
+        targetId = GetCurTargetId();
     }
-    targetSliceId = (targetSliceId == gSliceInvalid) ? defaultSliceId_ : targetSliceId;
+    targetId = (targetId == gSliceInvalid) ? defaultTargetId_ : targetId;
 
 #ifdef JS_ENABLE
     if ((GetState() == STATE_ACTIVE)) {
@@ -125,7 +128,7 @@ void NativeAbility::OnActive(const Want &want)
 #endif
     WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "NativeAbility OnActive");
     GraphicService::GetInstance()->PostGraphicEvent(std::bind(&NativeAbility::ResumeAbility, this,
-        targetSliceId, gSliceDefaultPriority));
+        targetId));
 }
 
 void NativeAbility::PauseAbility()
@@ -161,6 +164,9 @@ void NativeAbility::StopAbility()
         !PageTransitionMgr::GetInstance().IsCurrentSnapshotEnabled()) {
         StopSlice();
     }
+    if (allSlices_.Size() > 0 && allSlices_[allSlices_.Size() - 1] == VIEW_AOD) {
+        allSlices_.PopBack();
+    }
     allSlices_.PushBack(gSliceInvalid);
     nativeAbilityState_ = STATE_UNINITIALIZED;
 #ifdef JS_ENABLE
index afe3c79..da9c421 100644 (file)
@@ -9,7 +9,7 @@
 #include "TransitionManager.h"
 #include "NativeAbility.h"
 #include "components/root_view.h"
-#include "AppItemView.h"
+#include "applist/AppItemView.h"
 #include "hal_tick.h"
 #include "wearable_log.h"
 #ifdef JS_ENABLE
index 18331af..a5bb730 100644 (file)
@@ -9,7 +9,7 @@
 #include "TransitionManager.h"
 #include "NativeAbility.h"
 #include "components/root_view.h"
-#include "AppItemView.h"
+#include "applist/AppItemView.h"
 #include "hal_tick.h"
 #include "wearable_log.h"
 #ifdef JS_ENABLE
@@ -47,6 +47,12 @@ void BackToWaterfallTransition::OnTransitionStart(UIImageView* current, UIViewGr
             focusView_ = itemView;
             break;
         }
+#else
+        if (itemView->GetViewId() == sliceId) {
+            focusIndex_ = itemView->GetViewIndex();
+            focusView_ = itemView;
+            break;
+        }
 #endif
         childView = childView->GetNextSibling();
     }