${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
#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;
}
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();
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
}
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
}
}
else
{
//如果 backStack_ 栈为空,切换到默认切片,返回 false 。
- ChangeSlice(defaultSliceId_, transitionId, priority);
+ ChangeSlice(defaultTargetId_, transitionId, priority);
return false; // 返回false表示无前一个slice,退回到默认slice
}
}
backStack_.pop();
}
if (backStack_.empty()) {
- backStack_.push(defaultSliceId_); // 将默认主界面的 ID 推入栈中
+ backStack_.push(defaultTargetId_); // 将默认主界面的 ID 推入栈中
}
}
/* -------------------------------------------------------------------------- */
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 {
// 预加载的所有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。
#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 {
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
#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
#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;
{
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
{
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;
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 {}
#include "graphic_mutex.h"
#include "TransitionCallback.h"
#include "TransitionType.h"
+#include "gfx_utils/image_info.h"
namespace OHOS {
using TransitionAnimatorStopCallback = std::function<void()>;
// 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);
void SyncStopAnimator();
void AsyncStopAnimator();
void EndTransition(bool success);
- void SetRunDirectlyTransition(TransitionCaller caller, TransitionTarget target);
bool IsCurrentSnapshotEnabled()
{
return isCurrentSnapShotEnabled_;
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() {};
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;
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
#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
* @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
* 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_);
}
/**
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
--- /dev/null
+/*
+ * 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
#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.
*
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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
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
#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.
*
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
#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);
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)
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;
}
}
#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));
}
}
{
if (PageTransitionMgr::GetInstance().IsTransAnimNeeded() &&
!PageTransitionMgr::GetInstance().IsCurrentSnapshotEnabled()) {
- StopPrevSlice();
+ StopSlice();
}
ResumeSlice();
PageTransitionMgr::GetInstance().EndTransition(true);
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();
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");
}
}
-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();
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
--- /dev/null
+/*
+ * 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
#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)) {
#endif
WEARABLE_LOGI(WEARABLE_LOG_MODULE_LAUNCHER_FWK, "NativeAbility OnActive");
GraphicService::GetInstance()->PostGraphicEvent(std::bind(&NativeAbility::ResumeAbility, this,
- targetSliceId, gSliceDefaultPriority));
+ targetId));
}
void NativeAbility::PauseAbility()
!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
#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
#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
focusView_ = itemView;
break;
}
+#else
+ if (itemView->GetViewId() == sliceId) {
+ focusIndex_ = itemView->GetViewIndex();
+ focusView_ = itemView;
+ break;
+ }
#endif
childView = childView->GetNextSibling();
}