mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-11-23 07:01:24 +00:00
add tdd for image file cache
Signed-off-by: zhujingru <zhujingru2@huawei.com>
This commit is contained in:
parent
a0304e3ee0
commit
2004351986
@ -49,7 +49,6 @@ RefPtr<ImageSource> ImageSource::Create(const uint8_t* data, uint32_t size)
|
||||
RefPtr<ImageSource> ImageSource::Create(const std::string& filePath)
|
||||
{
|
||||
Media::SourceOptions opts;
|
||||
opts.formatHint = "image/svg+xml";
|
||||
uint32_t errorCode = 0;
|
||||
auto src = Media::ImageSource::CreateImageSource(filePath, opts, errorCode);
|
||||
if (errorCode != Media::SUCCESS) {
|
||||
@ -138,4 +137,15 @@ uint32_t ImageSourceOhos::GetFrameCount()
|
||||
}
|
||||
return frameCount;
|
||||
}
|
||||
|
||||
std::string ImageSourceOhos::GetEncodedFormat()
|
||||
{
|
||||
uint32_t errorCode;
|
||||
auto sourceInfo = imageSource_->GetSourceInfo(errorCode);
|
||||
if (errorCode != Media::SUCCESS) {
|
||||
TAG_LOGW(AceLogTag::ACE_IMAGE, "Get image source info failed, errorCode = %{public}u", errorCode);
|
||||
return "";
|
||||
}
|
||||
return sourceInfo.encodedFormat;
|
||||
}
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -34,6 +34,7 @@ public:
|
||||
RefPtr<PixelMap> CreatePixelMap() override;
|
||||
Size GetImageSize() override;
|
||||
uint32_t GetFrameCount() override;
|
||||
std::string GetEncodedFormat() override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<Media::ImageSource> imageSource_;
|
||||
|
@ -62,6 +62,7 @@ std::shared_mutex mutex_;
|
||||
constexpr char DISABLE_ROSEN_FILE_PATH[] = "/etc/disablerosen";
|
||||
constexpr char DISABLE_WINDOW_ANIMATION_PATH[] = "/etc/disable_window_size_animation";
|
||||
#endif
|
||||
constexpr int32_t CONVERT_ASTC_THRESHOLD = 2;
|
||||
|
||||
using RsOrientation = Rosen::DisplayOrientation;
|
||||
|
||||
@ -257,6 +258,11 @@ bool GetImageFileCacheConvertToAstcEnabled()
|
||||
return system::GetParameter("persist.image.filecache.astc.enable", "false") == "true";
|
||||
}
|
||||
|
||||
int32_t GetImageFileCacheConvertAstcThresholdProp()
|
||||
{
|
||||
return system::GetIntParameter<int>("persist.image.filecache.astc.threshold", CONVERT_ASTC_THRESHOLD);
|
||||
}
|
||||
|
||||
bool IsUseMemoryMonitor()
|
||||
{
|
||||
return (system::GetParameter("persist.ace.memorymonitor.enabled", "0") == "1");
|
||||
@ -336,6 +342,7 @@ bool SystemProperties::astcEnabled_ = GetAstcEnabled();
|
||||
int32_t SystemProperties::astcMax_ = GetAstcMaxErrorProp();
|
||||
int32_t SystemProperties::astcPsnr_ = GetAstcPsnrProp();
|
||||
bool SystemProperties::imageFileCacheConvertAstc_ = GetImageFileCacheConvertToAstcEnabled();
|
||||
int32_t SystemProperties::imageFileCacheConvertAstcThreshold_ = GetImageFileCacheConvertAstcThresholdProp();
|
||||
ACE_WEAK_SYM bool SystemProperties::extSurfaceEnabled_ = IsExtSurfaceEnabled();
|
||||
ACE_WEAK_SYM uint32_t SystemProperties::dumpFrameCount_ = GetSysDumpFrameCount();
|
||||
bool SystemProperties::enableScrollableItemPool_ = IsEnableScrollableItemPool();
|
||||
|
@ -71,4 +71,9 @@ uint32_t ImageSourcePreview::GetFrameCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string ImageSourcePreview::GetEncodedFormat()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -29,6 +29,7 @@ public:
|
||||
RefPtr<PixelMap> CreatePixelMap() override;
|
||||
Size GetImageSize() override;
|
||||
uint32_t GetFrameCount() override;
|
||||
std::string GetEncodedFormat() override;
|
||||
};
|
||||
} // namespace OHOS::Ace
|
||||
#endif // FOUNDATION_ACE_ADAPTER_PREVIEW_OSAL_IMAGE_SOURCE_PREVIEW_H
|
||||
|
@ -79,6 +79,7 @@ bool SystemProperties::astcEnabled_ = false;
|
||||
int SystemProperties::astcMax_ = 0;
|
||||
int SystemProperties::astcPsnr_ = 0;
|
||||
bool SystemProperties::imageFileCacheConvertAstc_ = false;
|
||||
int32_t SystemProperties::imageFileCacheConvertAstcThreshold_ = 2;
|
||||
bool SystemProperties::extSurfaceEnabled_ = false;
|
||||
uint32_t SystemProperties::dumpFrameCount_ = 0;
|
||||
bool SystemProperties::resourceDecoupling_ = true;
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
virtual RefPtr<PixelMap> CreatePixelMap() = 0;
|
||||
virtual Size GetImageSize() = 0;
|
||||
virtual uint32_t GetFrameCount() = 0;
|
||||
virtual std::string GetEncodedFormat() = 0;
|
||||
};
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
|
@ -416,6 +416,11 @@ public:
|
||||
return imageFileCacheConvertAstc_;
|
||||
}
|
||||
|
||||
static int32_t GetImageFileCacheConvertAstcThreshold()
|
||||
{
|
||||
return imageFileCacheConvertAstcThreshold_;
|
||||
}
|
||||
|
||||
static void SetExtSurfaceEnabled(bool extSurfaceEnabled)
|
||||
{
|
||||
extSurfaceEnabled_ = extSurfaceEnabled;
|
||||
@ -532,6 +537,7 @@ private:
|
||||
static int32_t astcMax_;
|
||||
static int32_t astcPsnr_;
|
||||
static bool imageFileCacheConvertAstc_;
|
||||
static int32_t imageFileCacheConvertAstcThreshold_;
|
||||
static bool extSurfaceEnabled_;
|
||||
static uint32_t dumpFrameCount_;
|
||||
static bool resourceDecoupling_;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "base/log/ace_trace.h"
|
||||
#include "base/log/dump_log.h"
|
||||
#include "base/log/log_wrapper.h"
|
||||
#include "base/thread/background_task_executor.h"
|
||||
#include "base/utils/system_properties.h"
|
||||
#include "core/image/image_loader.h"
|
||||
#include "core/image/image_source_info.h"
|
||||
@ -40,11 +41,17 @@ const std::string ASTC_SUFFIX = ".astc";
|
||||
const std::string CONVERT_ASTC_FORMAT = "image/astc/4*4";
|
||||
const std::string SLASH = "/";
|
||||
const std::string BACKSLASH = "\\";
|
||||
static const uint32_t ASTC_MAGIC_ID = 0x5CA1AB13;
|
||||
const mode_t CHOWN_RW_UG = 0660;
|
||||
const std::string SVG_FORMAT = "image/svg+xml";
|
||||
bool EndsWith(const std::string& str, const std::string& substr)
|
||||
{
|
||||
return str.rfind(substr) == (str.length() - substr.length());
|
||||
}
|
||||
bool IsAstcFile(const char fileName[])
|
||||
{
|
||||
auto fileNameStr = std::string(fileName);
|
||||
return (fileNameStr.length() >= ASTC_SUFFIX.length()) && EndsWith(fileNameStr, ASTC_SUFFIX);
|
||||
}
|
||||
}
|
||||
|
||||
void ImageFileCache::SetImageCacheFilePath(const std::string& cacheFilePath)
|
||||
@ -83,6 +90,31 @@ std::string ImageFileCache::ConstructCacheFilePath(const std::string& fileName)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ImageFileCache::WriteFile(const std::string& url, const void* const data, size_t size,
|
||||
const std::string& fileCacheKey, const std::string& suffix)
|
||||
{
|
||||
std::string writeFilePath = ConstructCacheFilePath(fileCacheKey + suffix);
|
||||
#ifdef WINDOWS_PLATFORM
|
||||
std::ofstream outFile(writeFilePath, std::ios::binary);
|
||||
#else
|
||||
std::ofstream outFile(writeFilePath, std::fstream::out);
|
||||
#endif
|
||||
if (!outFile.is_open()) {
|
||||
TAG_LOGW(AceLogTag::ACE_IMAGE, "open cache file failed, cannot write.");
|
||||
return false;
|
||||
}
|
||||
outFile.write(reinterpret_cast<const char*>(data), size);
|
||||
TAG_LOGI(
|
||||
AceLogTag::ACE_IMAGE, "write image cache: %{public}s %{private}s", url.c_str(), writeFilePath.c_str());
|
||||
#ifndef WINDOWS_PLATFORM
|
||||
if (chmod(writeFilePath.c_str(), CHOWN_RW_UG) != 0) {
|
||||
TAG_LOGW(AceLogTag::ACE_IMAGE, "write image cache chmod failed: %{public}s %{private}s",
|
||||
url.c_str(), writeFilePath.c_str());
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string ImageFileCache::GetImageCacheKey(const std::string& fileName)
|
||||
{
|
||||
size_t suffixStartAt = fileName.find_last_of(".");
|
||||
@ -126,22 +158,38 @@ void ImageFileCache::SaveCacheInner(const std::string& cacheKey, const std::stri
|
||||
std::vector<std::string>& removeVector)
|
||||
{
|
||||
auto cacheFileName = cacheKey + suffix;
|
||||
cacheFileInfo_.emplace_front(cacheFileName, cacheSize, time(nullptr));
|
||||
fileNameToFileInfoPos_[cacheKey] = cacheFileInfo_.begin();
|
||||
cacheFileSize_ += cacheSize;
|
||||
auto iter = fileNameToFileInfoPos_.find(cacheKey);
|
||||
auto cacheTime = time(nullptr);
|
||||
auto convertAstcThreshold = SystemProperties::GetImageFileCacheConvertAstcThreshold();
|
||||
if (iter != fileNameToFileInfoPos_.end()) {
|
||||
auto infoIter = iter->second;
|
||||
cacheFileInfo_.splice(cacheFileInfo_.begin(), cacheFileInfo_, infoIter);
|
||||
cacheFileSize_ = cacheFileSize_ + cacheSize - infoIter->fileSize;
|
||||
removeVector.push_back(ConstructCacheFilePath(infoIter->fileName));
|
||||
|
||||
infoIter->fileName = cacheFileName;
|
||||
infoIter->fileSize = cacheSize;
|
||||
infoIter->accessTime = cacheTime;
|
||||
infoIter->accessCount = suffix == ASTC_SUFFIX ? convertAstcThreshold : 1;
|
||||
} else {
|
||||
cacheFileInfo_.emplace_front(cacheFileName, cacheSize, cacheTime,
|
||||
suffix == ASTC_SUFFIX ? convertAstcThreshold : 1);
|
||||
fileNameToFileInfoPos_[cacheKey] = cacheFileInfo_.begin();
|
||||
cacheFileSize_ += cacheSize;
|
||||
}
|
||||
// check if cache files too big.
|
||||
if (cacheFileSize_ > static_cast<int32_t>(fileLimit_)) {
|
||||
auto removeSizeTarget = static_cast<int32_t>(fileLimit_ * clearCacheFileRatio_);
|
||||
int32_t removeSize = 0;
|
||||
if (cacheFileSize_ > fileLimit_) {
|
||||
auto removeSizeTarget = fileLimit_ * clearCacheFileRatio_;
|
||||
size_t removeSize = 0;
|
||||
auto iter = cacheFileInfo_.rbegin();
|
||||
while (removeSize < removeSizeTarget && iter != cacheFileInfo_.rend()) {
|
||||
removeSize += static_cast<int32_t>(iter->fileSize);
|
||||
removeSize += iter->fileSize;
|
||||
removeVector.push_back(ConstructCacheFilePath(iter->fileName));
|
||||
fileNameToFileInfoPos_.erase(GetImageCacheKey(iter->fileName));
|
||||
iter++;
|
||||
}
|
||||
cacheFileInfo_.erase(iter.base(), cacheFileInfo_.end());
|
||||
cacheFileSize_ -= static_cast<int32_t>(removeSize);
|
||||
cacheFileSize_ -= removeSize;
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,52 +237,38 @@ void ImageFileCache::WriteCacheFile(
|
||||
}
|
||||
}
|
||||
|
||||
bool convertToAstc = false;
|
||||
size_t astcSize = 0;
|
||||
unsigned int magicVal = static_cast<const uint8_t*>(data)[0] + (static_cast<const uint8_t*>(data)[1] << 8) +
|
||||
(static_cast<const uint8_t*>(data)[2] << 16) + (static_cast<const uint8_t*>(data)[3] << 24);
|
||||
if (SystemProperties::IsImageFileCacheConvertAstcEnabled() && suffix == "" && magicVal != ASTC_MAGIC_ID) {
|
||||
if (ConvertToAstcAndWriteToFile(data, size, fileCacheKey, astcSize, url)) {
|
||||
convertToAstc = true;
|
||||
}
|
||||
#ifndef ACE_UNITTEST
|
||||
// 2. if not in dist, write file into disk.
|
||||
if (!WriteFile(url, data, size, fileCacheKey, suffix)) {
|
||||
return;
|
||||
}
|
||||
if (!convertToAstc) {
|
||||
// 2. if not in dist, write file into disk.
|
||||
std::string writeFilePath = ConstructCacheFilePath(fileCacheKey + suffix);
|
||||
#ifdef WINDOWS_PLATFORM
|
||||
std::ofstream outFile(writeFilePath, std::ios::binary);
|
||||
#else
|
||||
std::ofstream outFile(writeFilePath, std::fstream::out);
|
||||
#endif
|
||||
if (!outFile.is_open()) {
|
||||
TAG_LOGW(AceLogTag::ACE_IMAGE, "open cache file failed, cannot write.");
|
||||
return;
|
||||
}
|
||||
outFile.write(reinterpret_cast<const char*>(data), size);
|
||||
TAG_LOGI(
|
||||
AceLogTag::ACE_IMAGE, "write image cache: %{public}s %{private}s", url.c_str(), writeFilePath.c_str());
|
||||
}
|
||||
|
||||
std::vector<std::string> removeVector;
|
||||
{
|
||||
std::scoped_lock<std::mutex> lock(cacheFileInfoMutex_);
|
||||
SaveCacheInner(fileCacheKey, convertToAstc ? ASTC_SUFFIX : suffix, convertToAstc ? astcSize : size,
|
||||
removeVector);
|
||||
SaveCacheInner(fileCacheKey, suffix, size, removeVector);
|
||||
}
|
||||
// 3. clear files removed from cache list.
|
||||
ClearCacheFile(removeVector);
|
||||
}
|
||||
|
||||
bool ImageFileCache::ConvertToAstcAndWriteToFile(const void* const data, size_t size, const std::string& fileCacheKey,
|
||||
size_t& astcSize, const std::string& url)
|
||||
void ImageFileCache::ConvertToAstcAndWriteToFile(const std::string& fileCacheKey, const std::string& filePath,
|
||||
const std::string& url)
|
||||
{
|
||||
ACE_FUNCTION_TRACE();
|
||||
RefPtr<ImageSource> imageSource = ImageSource::Create(static_cast<const uint8_t*>(data), size);
|
||||
RefPtr<ImageSource> imageSource = ImageSource::Create(filePath);
|
||||
if (!imageSource || imageSource->GetFrameCount() != 1) {
|
||||
TAG_LOGI(AceLogTag::ACE_IMAGE, "Image frame count is not 1, will not convert to astc. %{public}s",
|
||||
fileCacheKey.c_str());
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
if (imageSource->GetEncodedFormat() == SVG_FORMAT) {
|
||||
TAG_LOGI(AceLogTag::ACE_IMAGE, "Image is svg, will not convert to astc. %{public}s",
|
||||
fileCacheKey.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<ImagePacker> imagePacker = ImagePacker::Create();
|
||||
PackOption option;
|
||||
option.format = CONVERT_ASTC_FORMAT;
|
||||
@ -242,31 +276,50 @@ bool ImageFileCache::ConvertToAstcAndWriteToFile(const void* const data, size_t
|
||||
if (pixelMap == nullptr) {
|
||||
TAG_LOGW(AceLogTag::ACE_IMAGE, "Get pixel map failed, will not convert to astc. %{public}s",
|
||||
fileCacheKey.c_str());
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
auto astcFilePath = ConstructCacheFilePath(fileCacheKey + ASTC_SUFFIX);
|
||||
auto astcFileName = fileCacheKey + ASTC_SUFFIX;
|
||||
auto astcFilePath = ConstructCacheFilePath(astcFileName);
|
||||
imagePacker->StartPacking(astcFilePath, option);
|
||||
imagePacker->AddImage(*pixelMap);
|
||||
int64_t packedSize = 0;
|
||||
if (imagePacker->FinalizePacking(packedSize)) {
|
||||
TAG_LOGW(AceLogTag::ACE_IMAGE, "convert to astc failed. %{public}s", fileCacheKey.c_str());
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
#if !defined(WINDOWS_PLATFORM) && !defined(ACE_UNITTEST)
|
||||
if (chmod(astcFilePath.c_str(), CHOWN_RW_UG) != 0) {
|
||||
TAG_LOGW(AceLogTag::ACE_IMAGE, "convert to astc chmod failed: %{public}s %{private}s",
|
||||
url.c_str(), astcFilePath.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
astcSize = packedSize;
|
||||
std::vector<std::string> removeVector;
|
||||
{
|
||||
std::scoped_lock<std::mutex> lock(cacheFileInfoMutex_);
|
||||
removeVector.push_back(filePath);
|
||||
|
||||
auto infoIter = fileNameToFileInfoPos_[fileCacheKey];
|
||||
cacheFileSize_ = cacheFileSize_ + packedSize - infoIter->fileSize;
|
||||
infoIter->fileName = astcFileName;
|
||||
infoIter->fileSize = packedSize;
|
||||
}
|
||||
// remove the old file before convert
|
||||
ClearCacheFile(removeVector);
|
||||
TAG_LOGI(AceLogTag::ACE_IMAGE, "write image astc cache: %{public}s %{private}s", url.c_str(), astcFilePath.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImageFileCache::ClearCacheFile(const std::vector<std::string>& removeFiles)
|
||||
{
|
||||
#ifndef ACE_UNITTEST
|
||||
for (auto&& iter : removeFiles) {
|
||||
if (remove(iter.c_str()) != 0) {
|
||||
TAG_LOGW(AceLogTag::ACE_IMAGE, "remove file %{private}s failed.", iter.c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string ImageFileCache::GetCacheFilePath(const std::string& url)
|
||||
@ -279,14 +332,22 @@ std::string ImageFileCache::GetCacheFilePathInner(const std::string& url, const
|
||||
{
|
||||
auto fileCacheKey = std::to_string(std::hash<std::string> {}(url));
|
||||
auto iter = fileNameToFileInfoPos_.find(fileCacheKey);
|
||||
if (iter != fileNameToFileInfoPos_.end()) {
|
||||
// either suffix not specified, or fileName ends with the suffix
|
||||
if (iter != fileNameToFileInfoPos_.end() && (suffix == "" || EndsWith(iter->second->fileName, suffix))) {
|
||||
auto infoIter = iter->second;
|
||||
// either suffix not specified, or fileName ends with the suffix
|
||||
if (suffix == "" || EndsWith(infoIter->fileName, suffix)) {
|
||||
cacheFileInfo_.splice(cacheFileInfo_.begin(), cacheFileInfo_, infoIter);
|
||||
infoIter->accessTime = time(nullptr);
|
||||
return ConstructCacheFilePath(infoIter->fileName);
|
||||
cacheFileInfo_.splice(cacheFileInfo_.begin(), cacheFileInfo_, infoIter);
|
||||
infoIter->accessTime = time(nullptr);
|
||||
infoIter->accessCount++;
|
||||
auto filePath = ConstructCacheFilePath(infoIter->fileName);
|
||||
if (SystemProperties::IsImageFileCacheConvertAstcEnabled() &&
|
||||
infoIter->accessCount == SystemProperties::GetImageFileCacheConvertAstcThreshold()) {
|
||||
BackgroundTaskExecutor::GetInstance().PostTask(
|
||||
[this, fileCacheKey, filePath, url] () {
|
||||
ConvertToAstcAndWriteToFile(fileCacheKey, filePath, url);
|
||||
},
|
||||
BgTaskPriority::LOW);
|
||||
}
|
||||
return filePath;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@ -304,7 +365,7 @@ void ImageFileCache::SetCacheFileInfo()
|
||||
TAG_LOGW(AceLogTag::ACE_IMAGE, "cache file path wrong! maybe it is not set.");
|
||||
return;
|
||||
}
|
||||
int64_t cacheFileSize = 0;
|
||||
size_t cacheFileSize = 0;
|
||||
dirent* filePtr = readdir(dir.get());
|
||||
while (filePtr != nullptr) {
|
||||
// skip . or ..
|
||||
@ -315,10 +376,11 @@ void ImageFileCache::SetCacheFileInfo()
|
||||
filePtr = readdir(dir.get());
|
||||
continue;
|
||||
}
|
||||
cacheFileInfo_.emplace_front(filePtr->d_name, fileStatus.st_size, fileStatus.st_atime);
|
||||
cacheFileInfo_.emplace_front(filePtr->d_name, fileStatus.st_size, fileStatus.st_atime,
|
||||
IsAstcFile(filePtr->d_name) ? SystemProperties::GetImageFileCacheConvertAstcThreshold() : 1);
|
||||
std::string fileCacheKey = GetImageCacheKey(std::string(filePtr->d_name));
|
||||
fileNameToFileInfoPos_[fileCacheKey] = cacheFileInfo_.begin();
|
||||
cacheFileSize += static_cast<int64_t>(fileStatus.st_size);
|
||||
cacheFileSize += fileStatus.st_size;
|
||||
}
|
||||
filePtr = readdir(dir.get());
|
||||
}
|
||||
@ -344,7 +406,8 @@ void ImageFileCache::DumpCacheInfo()
|
||||
auto fileSize = item.fileSize;
|
||||
totalCount += fileSize;
|
||||
DumpLog::GetInstance().Print(
|
||||
"fileCache Obj of filePath: " + filePath + ", fileSize" + std::to_string(fileSize) + "(B)");
|
||||
"fileCache Obj of filePath: " + filePath + ", fileSize: " + std::to_string(fileSize) + "(B)" +
|
||||
", accessCount: " + std::to_string(item.accessCount));
|
||||
}
|
||||
DumpLog::GetInstance().Print("FileCache total size: " + std::to_string(totalCount) + "(B)");
|
||||
}
|
||||
|
@ -27,8 +27,8 @@
|
||||
|
||||
namespace OHOS::Ace {
|
||||
struct FileInfo {
|
||||
FileInfo(std::string name, size_t size, time_t time)
|
||||
: fileName(std::move(name)), fileSize(size), accessTime(time) {}
|
||||
FileInfo(std::string name, size_t size, time_t time, size_t cnt)
|
||||
: fileName(std::move(name)), fileSize(size), accessTime(time), accessCount(cnt) {}
|
||||
|
||||
// file information will be sort by access time.
|
||||
bool operator<(const FileInfo& otherFile) const
|
||||
@ -38,6 +38,7 @@ struct FileInfo {
|
||||
std::string fileName;
|
||||
size_t fileSize;
|
||||
time_t accessTime;
|
||||
size_t accessCount;
|
||||
};
|
||||
|
||||
class ImageFileCache : public Singleton<ImageFileCache> {
|
||||
@ -67,8 +68,10 @@ private:
|
||||
void SaveCacheInner(const std::string& cacheKey, const std::string& suffix, size_t cacheSize,
|
||||
std::vector<std::string>& removeVector);
|
||||
std::string GetCacheFilePathInner(const std::string& url, const std::string& suffix);
|
||||
bool ConvertToAstcAndWriteToFile(const void* const data, size_t size, const std::string& fileCacheKey,
|
||||
size_t& astcSize, const std::string& url);
|
||||
void ConvertToAstcAndWriteToFile(const std::string& fileCacheKey, const std::string& filePath,
|
||||
const std::string& url);
|
||||
bool WriteFile(const std::string& url, const void* const data, size_t size,
|
||||
const std::string& fileCacheKey, const std::string& suffix);
|
||||
|
||||
std::shared_mutex cacheFilePathMutex_;
|
||||
std::string cacheFilePath_;
|
||||
@ -78,7 +81,7 @@ private:
|
||||
std::atomic<float> clearCacheFileRatio_ = 0.5f; // default clear ratio is 0.5
|
||||
|
||||
std::mutex cacheFileSizeMutex_;
|
||||
int64_t cacheFileSize_ = 0;
|
||||
size_t cacheFileSize_ = 0;
|
||||
|
||||
std::mutex cacheFileInfoMutex_;
|
||||
// lru
|
||||
|
25
test/mock/base/mock_image_packer.cpp
Normal file
25
test/mock/base/mock_image_packer.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 "test/mock/base/mock_image_packer.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
RefPtr<MockImagePacker> MockImagePacker::mockImagePacker_ = nullptr;
|
||||
|
||||
RefPtr<ImagePacker> ImagePacker::Create()
|
||||
{
|
||||
return MockImagePacker::mockImagePacker_;
|
||||
}
|
||||
} // namespace OHOS::Ace
|
33
test/mock/base/mock_image_packer.h
Normal file
33
test/mock/base/mock_image_packer.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_TEST_MOCK_BASE_MOCK_IMAGE_PACKER_H
|
||||
#define FOUNDATION_ACE_TEST_MOCK_BASE_MOCK_IMAGE_PACKER_H
|
||||
#include "gmock/gmock.h"
|
||||
#include "base/image/image_packer.h"
|
||||
#include "base/image/pixel_map.h"
|
||||
namespace OHOS::Ace {
|
||||
class MockImagePacker : public ImagePacker {
|
||||
DECLARE_ACE_TYPE(MockImagePacker, ImagePacker)
|
||||
public:
|
||||
MOCK_METHOD3(StartPacking, uint32_t(uint8_t*, uint32_t, const PackOption&));
|
||||
MOCK_METHOD2(StartPacking, uint32_t(const std::string&, const PackOption&));
|
||||
MOCK_METHOD1(AddImage, uint32_t(PixelMap&));
|
||||
MOCK_METHOD1(FinalizePacking, uint32_t(int64_t&));
|
||||
|
||||
static RefPtr<MockImagePacker> mockImagePacker_;
|
||||
};
|
||||
} // namespace OHOS::Ace
|
||||
#endif // FOUNDATION_ACE_TEST_MOCK_BASE_MOCK_IMAGE_PACKER_H
|
@ -14,19 +14,21 @@
|
||||
*/
|
||||
#include "test/mock/base/mock_image_source.h"
|
||||
namespace OHOS::Ace {
|
||||
RefPtr<MockImageSource> MockImageSource::mockImageSource_ = nullptr;
|
||||
|
||||
RefPtr<ImageSource> ImageSource::Create(int32_t fd)
|
||||
{
|
||||
return nullptr;
|
||||
return MockImageSource::mockImageSource_;
|
||||
}
|
||||
|
||||
RefPtr<ImageSource> ImageSource::Create(const uint8_t* data, uint32_t size)
|
||||
{
|
||||
return nullptr;
|
||||
return MockImageSource::mockImageSource_;
|
||||
}
|
||||
|
||||
RefPtr<ImageSource> ImageSource::Create(const std::string& filePath)
|
||||
{
|
||||
return nullptr;
|
||||
return MockImageSource::mockImageSource_;
|
||||
}
|
||||
|
||||
bool ImageSource::IsAstc(const uint8_t* data, size_t size)
|
||||
@ -34,7 +36,7 @@ bool ImageSource::IsAstc(const uint8_t* data, size_t size)
|
||||
return true;
|
||||
}
|
||||
|
||||
Size ImageSource::GetASTCInfo(const uint8_t* data, size_t size)
|
||||
ImageSource::Size ImageSource::GetASTCInfo(const uint8_t* data, size_t size)
|
||||
{
|
||||
return {0, 0};
|
||||
}
|
||||
|
@ -19,17 +19,20 @@
|
||||
#include "base/image/image_source.h"
|
||||
#include "base/image/pixel_map.h"
|
||||
namespace OHOS::Ace {
|
||||
using Size = std::pair<int32_t, int32_t>;
|
||||
class MockImageSource : public ImageSource {
|
||||
DECLARE_ACE_TYPE(MockImageSource, ImageSource)
|
||||
|
||||
public:
|
||||
|
||||
MOCK_METHOD1(GetProperty, std::string(const std::string& key));
|
||||
MOCK_METHOD1(CreatePixelMap, RefPtr<PixelMap>(const Size& size));
|
||||
MOCK_METHOD2(CreatePixelMap, RefPtr<PixelMap>(uint32_t index, const Size& size));
|
||||
MOCK_METHOD1(CreatePixelMap, RefPtr<PixelMap>(const ImageSource::Size& size));
|
||||
MOCK_METHOD2(CreatePixelMap, RefPtr<PixelMap>(uint32_t index, const ImageSource::Size& size));
|
||||
MOCK_METHOD0(CreatePixelMap, RefPtr<PixelMap>());
|
||||
MOCK_METHOD0(GetImageSize, Size());
|
||||
MOCK_METHOD0(GetImageSize, ImageSource::Size());
|
||||
MOCK_METHOD0(GetFrameCount, uint32_t());
|
||||
MOCK_METHOD0(GetEncodedFormat, std::string());
|
||||
|
||||
static RefPtr<MockImageSource> mockImageSource_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -62,6 +62,8 @@ bool SystemProperties::acePerformanceMonitorEnable_ = false;
|
||||
bool SystemProperties::debugBoundaryEnabled_ = false;
|
||||
bool SystemProperties::developerModeOn_ = false;
|
||||
bool SystemProperties::faultInjectEnabled_ = false;
|
||||
bool SystemProperties::imageFileCacheConvertAstc_ = true;
|
||||
int32_t SystemProperties::imageFileCacheConvertAstcThreshold_ = 3;
|
||||
|
||||
bool g_irregularGrid = true;
|
||||
bool g_segmentedWaterflow = true;
|
||||
|
@ -20,6 +20,7 @@ group("core_unittest") {
|
||||
"common:core_common_unittest",
|
||||
"event:core_event_unittest",
|
||||
"gestures:gestures_test_ng",
|
||||
"image_file_cache:image_file_cache_test_ng",
|
||||
"image_provider:image_provider_test_ng",
|
||||
"layout:core_layout_unittest",
|
||||
"manager:core_manager_unittest",
|
||||
|
39
test/unittest/core/image_file_cache/BUILD.gn
Normal file
39
test/unittest/core/image_file_cache/BUILD.gn
Normal file
@ -0,0 +1,39 @@
|
||||
# Copyright (c) 2024 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.
|
||||
|
||||
import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni")
|
||||
|
||||
ohos_unittest("image_file_cache_test_ng") {
|
||||
module_out_path = image_test_output_path
|
||||
|
||||
sources = [
|
||||
"$ace_root/frameworks/core/image/image_file_cache.cpp",
|
||||
"$ace_root/test/mock/base/mock_frame_trace_adapter.cpp",
|
||||
"$ace_root/test/mock/base/mock_image_packer.cpp",
|
||||
"$ace_root/test/mock/base/mock_image_source.cpp",
|
||||
"$ace_root/test/mock/base/mock_system_properties.cpp",
|
||||
"$ace_root/test/mock/core/image_provider/mock_skia_image_data.cpp",
|
||||
"image_file_cache_test_ng.cpp",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"$ace_root/test/unittest:ace_base",
|
||||
"$ace_root/test/unittest:ace_core_extra",
|
||||
"$ace_root/test/unittest:ace_engine_unittest_flutter_deps",
|
||||
"$ace_root/test/unittest:ace_unittest_log",
|
||||
"$ace_root/test/unittest:ace_unittest_trace",
|
||||
"//third_party/googletest:gmock_main",
|
||||
]
|
||||
|
||||
configs = [ "$ace_root/test/unittest:ace_unittest_config" ]
|
||||
}
|
269
test/unittest/core/image_file_cache/image_file_cache_test_ng.cpp
Normal file
269
test/unittest/core/image_file_cache/image_file_cache_test_ng.cpp
Normal file
@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 <vector>
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#define protected public
|
||||
#define private public
|
||||
|
||||
#include "core/image/image_file_cache.h"
|
||||
#include "base/utils/system_properties.h"
|
||||
|
||||
#include "test/mock/base/mock_image_packer.h"
|
||||
#include "test/mock/base/mock_image_source.h"
|
||||
#include "test/mock/base/mock_pixel_map.h"
|
||||
|
||||
using namespace testing;
|
||||
using namespace testing::ext;
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
const std::string ASTC_SUFFIX = ".astc";
|
||||
const std::string CACHE_FILE_PATH = "/data/test/resource/imagecache/images";
|
||||
const std::string SVG_FORMAT = "image/svg+xml";
|
||||
class ImageFileCacheTestNg : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestSuite();
|
||||
static void TearDownTestSuite();
|
||||
static void WaitForAsyncTasks();
|
||||
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
};
|
||||
|
||||
void ImageFileCacheTestNg::SetUpTestSuite()
|
||||
{
|
||||
ImageFileCache::GetInstance().SetImageCacheFilePath(CACHE_FILE_PATH);
|
||||
}
|
||||
|
||||
void ImageFileCacheTestNg::SetUp()
|
||||
{
|
||||
SystemProperties::imageFileCacheConvertAstc_ = true;
|
||||
ImageFileCache::GetInstance().fileNameToFileInfoPos_.clear();
|
||||
ImageFileCache::GetInstance().cacheFileInfo_.clear();
|
||||
ImageFileCache::GetInstance().cacheFileSize_ = 0;
|
||||
}
|
||||
|
||||
void ImageFileCacheTestNg::TearDown()
|
||||
{
|
||||
}
|
||||
|
||||
void ImageFileCacheTestNg::TearDownTestSuite()
|
||||
{
|
||||
MockImagePacker::mockImagePacker_ = nullptr;
|
||||
MockImageSource::mockImageSource_ = nullptr;
|
||||
}
|
||||
|
||||
// wait for load task to finish
|
||||
void ImageFileCacheTestNg::WaitForAsyncTasks()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: WriteCacheFileFunc001
|
||||
* @tc.desc: Test WriteCacheFileFun with convert astc enabled.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ImageFileCacheTestNg, WriteCacheFileFunc001, TestSize.Level1)
|
||||
{
|
||||
RefPtr<MockImagePacker> mockImagePacker = AceType::MakeRefPtr<MockImagePacker>();
|
||||
RefPtr<MockImageSource> mockImageSource = AceType::MakeRefPtr<MockImageSource>();
|
||||
RefPtr<MockPixelMap> mockPixelMap = AceType::MakeRefPtr<MockPixelMap>();
|
||||
MockImagePacker::mockImagePacker_ = mockImagePacker;
|
||||
MockImageSource::mockImageSource_ = mockImageSource;
|
||||
/**
|
||||
* @tc.steps: step1. construct a data.
|
||||
*/
|
||||
std::vector<uint8_t> imageData = {1, 2, 3, 4, 5, 6};
|
||||
std::string url = "http:/testfilecache002/image";
|
||||
std::string fileCacheKey = std::to_string(std::hash<std::string> {}(url));
|
||||
|
||||
/**
|
||||
* @tc.steps: step2. call WriteCacheFile().
|
||||
*/
|
||||
ImageFileCache::GetInstance().WriteCacheFile(url, imageData.data(), imageData.size());
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileSize_, static_cast<int32_t>(imageData.size()));
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileInfo_.size(), 1);
|
||||
FileInfo fileInfo = ImageFileCache::GetInstance().cacheFileInfo_.front();
|
||||
size_t accessCount = fileInfo.accessCount;
|
||||
ASSERT_EQ(accessCount, 1);
|
||||
|
||||
/**
|
||||
* @tc.steps: step3. call GetCacheFilePathInner(), each call will increase accessCount by one,
|
||||
* when accessCount reaches convertAstcThreshold, ConvertToAstcAndWriteToFile() will be called.
|
||||
* @tc.expected: after ConvertToAstcAndWriteToFile() is called, fileInfo get updated, fileName contains ASTC_SUFFIX.
|
||||
*/
|
||||
std::string filePath;
|
||||
auto convertAstcThreshold = SystemProperties::GetImageFileCacheConvertAstcThreshold();
|
||||
while (accessCount < convertAstcThreshold) {
|
||||
accessCount++;
|
||||
bool convertToAstc = accessCount == convertAstcThreshold;
|
||||
if (convertToAstc) {
|
||||
EXPECT_CALL(*mockImageSource, GetFrameCount()).WillOnce(Return(1));
|
||||
EXPECT_CALL(*mockImageSource, CreatePixelMap(_)).WillOnce(Return(mockPixelMap));
|
||||
EXPECT_CALL(*mockImagePacker,
|
||||
FinalizePacking(_)).WillOnce(DoAll(SetArgReferee<0>(imageData.size()), Return(0)));
|
||||
}
|
||||
filePath = ImageFileCache::GetInstance().GetCacheFilePathInner(url, "");
|
||||
ASSERT_EQ(filePath, ImageFileCache::GetInstance().ConstructCacheFilePath(fileCacheKey));
|
||||
if (convertToAstc) {
|
||||
sleep(1);
|
||||
}
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileSize_, static_cast<int32_t>(imageData.size()));
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileInfo_.size(), 1);
|
||||
fileInfo = ImageFileCache::GetInstance().cacheFileInfo_.front();
|
||||
ASSERT_EQ(fileInfo.fileName, convertToAstc ? fileCacheKey + ASTC_SUFFIX : fileCacheKey);
|
||||
ASSERT_EQ(fileInfo.accessCount, accessCount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: WriteCacheFileFunc002
|
||||
* @tc.desc: Test WriteCacheFileFun with convert astc disabled.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ImageFileCacheTestNg, WriteCacheFileFunc002, TestSize.Level1)
|
||||
{
|
||||
SystemProperties::imageFileCacheConvertAstc_ = false;
|
||||
|
||||
/**
|
||||
* @tc.steps: step1. construct a data.
|
||||
*/
|
||||
std::vector<uint8_t> imageData = {1, 2, 3, 4, 5, 6};
|
||||
std::string url = "http:/testfilecache002/image";
|
||||
std::string fileCacheKey = std::to_string(std::hash<std::string> {}(url));
|
||||
|
||||
/**
|
||||
* @tc.steps: step2. call WriteCacheFile().
|
||||
*/
|
||||
ImageFileCache::GetInstance().WriteCacheFile(url, imageData.data(), imageData.size());
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileSize_, static_cast<int32_t>(imageData.size()));
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileInfo_.size(), 1);
|
||||
FileInfo fileInfo = ImageFileCache::GetInstance().cacheFileInfo_.front();
|
||||
size_t accessCount = fileInfo.accessCount;
|
||||
ASSERT_EQ(accessCount, 1);
|
||||
|
||||
/**
|
||||
* @tc.steps: step3. call GetCacheFilePathInner(), each call will increase accessCount by one,
|
||||
* when accessCount reaches convertAstcThreshold, ConvertToAstcAndWriteToFile() will not be called.
|
||||
* @tc.expected: fileInfo will not update, fileName does not contain ASTC_SUFFIX.
|
||||
*/
|
||||
std::string filePath;
|
||||
auto convertAstcThreshold = SystemProperties::GetImageFileCacheConvertAstcThreshold();
|
||||
while (accessCount < convertAstcThreshold) {
|
||||
accessCount++;
|
||||
filePath = ImageFileCache::GetInstance().GetCacheFilePathInner(url, "");
|
||||
ASSERT_EQ(filePath, ImageFileCache::GetInstance().ConstructCacheFilePath(fileCacheKey));
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileSize_, static_cast<int32_t>(imageData.size()));
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileInfo_.size(), 1);
|
||||
fileInfo = ImageFileCache::GetInstance().cacheFileInfo_.front();
|
||||
ASSERT_EQ(fileInfo.fileName, fileCacheKey);
|
||||
ASSERT_EQ(fileInfo.accessCount, accessCount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: WriteCacheFileFunc003
|
||||
* @tc.desc: Test WriteCacheFileFun with suffix.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ImageFileCacheTestNg, WriteCacheFileFunc003, TestSize.Level1)
|
||||
{
|
||||
/**
|
||||
* @tc.steps: step1. construct a data.
|
||||
*/
|
||||
std::vector<uint8_t> imageData = {1, 2, 3, 4, 5, 6};
|
||||
std::vector<uint8_t> imageDataWithSuffix = {1, 2, 3, 4, 5, 6, 7};
|
||||
std::string url = "http:/testfilecache002/image";
|
||||
std::string fileCacheKey = std::to_string(std::hash<std::string> {}(url));
|
||||
|
||||
/**
|
||||
* @tc.steps: step2. call WriteCacheFile().
|
||||
*/
|
||||
ImageFileCache::GetInstance().WriteCacheFile(url, imageData.data(), imageData.size());
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileSize_, static_cast<int32_t>(imageData.size()));
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileInfo_.size(), 1);
|
||||
FileInfo fileInfo = ImageFileCache::GetInstance().cacheFileInfo_.front();
|
||||
ASSERT_EQ(fileInfo.fileName, fileCacheKey);
|
||||
ASSERT_EQ(fileInfo.accessCount, 1);
|
||||
|
||||
/**
|
||||
* @tc.steps: step3. call WriteCacheFile() with suffix.
|
||||
* @tc.expected: fileInfo will update to imageDataWithSuffix.
|
||||
*/
|
||||
std::string suffix = ".jpg";
|
||||
ImageFileCache::GetInstance().WriteCacheFile(url, imageDataWithSuffix.data(), imageDataWithSuffix.size(), suffix);
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileSize_, static_cast<int32_t>(imageDataWithSuffix.size()));
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileInfo_.size(), 1);
|
||||
fileInfo = ImageFileCache::GetInstance().cacheFileInfo_.front();
|
||||
ASSERT_EQ(fileInfo.fileName, fileCacheKey + suffix);
|
||||
ASSERT_EQ(fileInfo.accessCount, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: WriteCacheFileFunc004
|
||||
* @tc.desc: Test WriteCacheFileFun with svg.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(ImageFileCacheTestNg, WriteCacheFileFunc004, TestSize.Level1)
|
||||
{
|
||||
RefPtr<MockImageSource> mockImageSource = AceType::MakeRefPtr<MockImageSource>();
|
||||
MockImageSource::mockImageSource_ = mockImageSource;
|
||||
/**
|
||||
* @tc.steps: step1. construct a data.
|
||||
*/
|
||||
std::vector<uint8_t> imageData = {1, 2, 3, 4, 5, 6};
|
||||
std::string url = "http:/testfilecache002/image";
|
||||
std::string fileCacheKey = std::to_string(std::hash<std::string> {}(url));
|
||||
|
||||
/**
|
||||
* @tc.steps: step2. call WriteCacheFile().
|
||||
*/
|
||||
ImageFileCache::GetInstance().WriteCacheFile(url, imageData.data(), imageData.size());
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileSize_, static_cast<int32_t>(imageData.size()));
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileInfo_.size(), 1);
|
||||
FileInfo fileInfo = ImageFileCache::GetInstance().cacheFileInfo_.front();
|
||||
size_t accessCount = fileInfo.accessCount;
|
||||
ASSERT_EQ(accessCount, 1);
|
||||
|
||||
/**
|
||||
* @tc.steps: step3. call GetCacheFilePathInner(), each call will increase accessCount by one,
|
||||
* when accessCount reaches convertAstcThreshold, ConvertToAstcAndWriteToFile() will be called.
|
||||
* @tc.expected: because image is svg format, will not do the convert, fileInfo will not update,
|
||||
* fileName does not contain ASTC_SUFFIX.
|
||||
*/
|
||||
std::string filePath;
|
||||
auto convertAstcThreshold = SystemProperties::GetImageFileCacheConvertAstcThreshold();
|
||||
while (accessCount <= convertAstcThreshold) {
|
||||
accessCount++;
|
||||
bool convertToAstc = accessCount == convertAstcThreshold;
|
||||
if (convertToAstc) {
|
||||
EXPECT_CALL(*mockImageSource, GetFrameCount()).WillOnce(Return(1));
|
||||
EXPECT_CALL(*mockImageSource, GetEncodedFormat()).WillOnce(Return(SVG_FORMAT));
|
||||
}
|
||||
filePath = ImageFileCache::GetInstance().GetCacheFilePathInner(url, "");
|
||||
ASSERT_EQ(filePath, ImageFileCache::GetInstance().ConstructCacheFilePath(fileCacheKey));
|
||||
if (convertToAstc) {
|
||||
sleep(1);
|
||||
}
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileSize_, static_cast<int32_t>(imageData.size()));
|
||||
ASSERT_EQ(ImageFileCache::GetInstance().cacheFileInfo_.size(), 1);
|
||||
fileInfo = ImageFileCache::GetInstance().cacheFileInfo_.front();
|
||||
ASSERT_EQ(fileInfo.fileName, fileCacheKey);
|
||||
ASSERT_EQ(fileInfo.accessCount, accessCount);
|
||||
}
|
||||
}
|
||||
} // namespace OHOS::Ace::NG
|
Loading…
Reference in New Issue
Block a user