* Copyright (c) 2025 Huawei Device Co., Ltd.
* 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.
*/
#include "img_view_adapter.h"
#include <sstream>
#include <unistd.h>
#include "core/render_manager.h"
#include "language/language_ui.h"
#include "log/log.h"
#include "page/view_proxy.h"
#include "updater/updater_const.h"
#include "updater_ui_const.h"
#include "updater_ui_env.h"
#include "utils.h"
#include "view_api.h"
namespace Updater {
class ImgViewAdapter::ImgAnimatorCallback final : public OHOS::AnimatorCallback {
DISALLOW_COPY_MOVE(ImgAnimatorCallback);
public:
explicit ImgAnimatorCallback(ImgViewAdapter *view)
: animator_(nullptr), stop_(true)
{
view_ = view;
if (view_ == nullptr) {
static ImgViewAdapter dummy;
view_ = &dummy;
}
}
~ImgAnimatorCallback() = default;
void Init()
{
animator_ = std::make_unique<OHOS::Animator>(this, view_, 0, true);
}
void Callback(OHOS::UIView *view) override
{
if (stop_) {
return;
}
view_->ShowNextImage();
}
void Start()
{
view_->SetVisible(true);
stop_ = false;
}
void Stop()
{
view_->SetVisible(false);
stop_ = true;
}
OHOS::Animator *GetAnimator() const
{
return animator_.get();
}
protected:
ImgViewAdapter *view_;
std::unique_ptr<OHOS::Animator> animator_;
bool stop_;
};
ImgViewAdapter::~ImgViewAdapter() = default;
ImgViewAdapter::ImgViewAdapter() = default;
ImgViewAdapter::ImgViewAdapter(const UxViewInfo &info)
{
const UxImageInfo &spec = AsSpecific(info.specificInfo);
dir_ = spec.resPath;
imgCnt_ = spec.imgCnt;
interval_ = spec.updInterval;
filePrefix_ = spec.filePrefix;
currId_ = 0;
valid_ = true;
this->SetAutoEnable(false);
this->SetTouchable(true);
SetViewCommonInfo(info.commonInfo);
LOG(DEBUG) << "dir:" << dir_ << ", imgCnt:" << imgCnt_ << ", interval:" << interval_;
if (interval_ == 0) {
GetRealImgPath();
this->SetSrc(dir_.c_str());
this->SetResizeMode(OHOS::UIImageView::ImageResizeMode::FILL);
} else {
cb_ = std::make_unique<ImgAnimatorCallback>(this);
cb_->Init();
}
}
bool ImgViewAdapter::IsValid(const UxImageInfo &info)
{
if (info.updInterval == 0) {
return IsValidForStaticImg(info);
}
return IsValidForAnimator(info);
}
void ImgViewAdapter::GetRealImgPath()
{
using namespace Lang;
std::error_code errorCode;
if (Fs::exists(dir_, errorCode)) {
return;
}
const static std::unordered_map<Language, std::string> postFixMap {
{Language::CHINESE, "chn"},
{Language::ENGLISH, "eng"},
{Language::SPANISH, "esp"},
};
auto iter = postFixMap.find(LanguageUI::GetInstance().GetCurLanguage());
if (iter == postFixMap.end()) {
return;
}
std::string newPath = dir_ + "_" + iter->second + ".png";
if (!Fs::exists(newPath, errorCode)) {
LOG(WARNING) << "newPath not existed " << newPath;
return;
}
dir_ = newPath;
return;
}
bool ImgViewAdapter::IsValidForStaticImg(const UxImageInfo &info)
{
if (info.resPath.empty()) {
LOG(ERROR) << "img viewinfo check failed, resPath is empty when this is a static image";
return false;
}
return true;
}
bool ImgViewAdapter::IsValidForAnimator(const UxImageInfo &info)
{
if (info.filePrefix.empty() || info.resPath.empty()) {
LOG(ERROR) << "img viewinfo check failed, filePrefix is empty when this is a animator";
return false;
}
if ((info.imgCnt > MAX_IMG_CNT) || (info.imgCnt == 0)) {
LOG(ERROR) << "img viewinfo check failed, imgCnt: " << info.imgCnt;
return false;
}
if (info.updInterval > MAX_INTERVAL_MS) {
LOG(ERROR) << "img viewinfo check failed, updInterval: " << info.updInterval;
return false;
}
return true;
}
bool ImgViewAdapter::Start()
{
if (!valid_ || !animatorStop_) {
return false;
}
if (cb_ == nullptr) {
LOG(ERROR) << "cb_ is null";
return false;
}
cb_->Start();
cb_->GetAnimator()->Start();
animatorStop_ = false;
return true;
}
bool ImgViewAdapter::Stop()
{
if (!valid_ || animatorStop_) {
return false;
}
if (cb_ == nullptr) {
LOG(ERROR) << "cb_ is null";
return false;
}
cb_->GetAnimator()->Stop();
cb_->Stop();
animatorStop_ = true;
return true;
}
void ImgViewAdapter::ShowNextImage()
{
std::stringstream ss;
ss << dir_ << filePrefix_ << std::setw(ANIMATION_FILE_NAME_LENGTH) << std::setfill('0') << currId_ << ".png";
currPath_ = ss.str();
if (access(currPath_.c_str(), F_OK) == -1) {
LOG(ERROR) << "not exist: " << currPath_;
}
this->SetSrc(currPath_.c_str());
this->SetResizeMode(OHOS::UIImageView::ImageResizeMode::FILL);
currId_ = (currId_ + 1) % imgCnt_;
Utils::UsSleep(interval_ * USECOND_TO_MSECOND);
}
#ifdef UPDATER_UT
const ImgViewAdapter::ImgAnimatorCallback *ImgViewAdapter::GetAnimatorCallback() const
{
return cb_.get();
}
const OHOS::Animator *ImgViewAdapter::GetAnimator() const
{
if (!cb_) {
return nullptr;
}
return cb_->GetAnimator();
}
uint32_t ImgViewAdapter::GetCurrId() const
{
return currId_;
}
#endif
}