mirror of
https://github.com/openharmony/ace_ace_engine.git
synced 2026-07-19 14:43:36 -04:00
image support thumbnail
Signed-off-by: chenxuankai1 <chenxuankai1@huawei.com> Change-Id: Id5c7fd2db2abfa9e4715febd80be7709ead4ffdc Signed-off-by: chenxuankai1 <chenxuankai1@huawei.com>
This commit is contained in:
@@ -12,12 +12,51 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include "adapter/ohos/entrance/data_ability_helper_standard.h"
|
||||
|
||||
#include "data_ability_helper.h"
|
||||
|
||||
#include "pixel_map.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
namespace {
|
||||
|
||||
#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
|
||||
using ThumbnaiNapiEntry = void* (*)(const char*, void*);
|
||||
ThumbnaiNapiEntry GetThumbnailNapiEntry()
|
||||
{
|
||||
static ThumbnaiNapiEntry thumbnailNapiEntry = nullptr;
|
||||
if (!thumbnailNapiEntry) {
|
||||
#ifdef _ARM64_
|
||||
std::string prefix = "/system/lib64/module/";
|
||||
#else
|
||||
std::string prefix = "/system/lib/module/";
|
||||
#endif
|
||||
#ifdef OHOS_STANDARD_SYSTEM
|
||||
std::string napiPluginName = "multimedia/libmedialibrary.z.so";
|
||||
#endif
|
||||
auto napiPluginPath = prefix.append(napiPluginName);
|
||||
void* handle = dlopen(napiPluginPath.c_str(), RTLD_LAZY);
|
||||
if (handle == nullptr) {
|
||||
LOGE("Failed to open shared library %{public}s, reason: %{public}s", napiPluginPath.c_str(), dlerror());
|
||||
return nullptr;
|
||||
}
|
||||
thumbnailNapiEntry = reinterpret_cast<ThumbnaiNapiEntry>(dlsym(handle, "OHOS_MEDIA_NativeGetThumbnail"));
|
||||
if (thumbnailNapiEntry == nullptr) {
|
||||
dlclose(handle);
|
||||
LOGE("Failed to get symbol OHOS_MEDIA_NativeGetThumbnail in %{public}s", napiPluginPath.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return thumbnailNapiEntry;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
DataAbilityHelperStandard::DataAbilityHelperStandard(const std::shared_ptr<OHOS::AppExecFwk::Context>& context,
|
||||
const std::shared_ptr<OHOS::AbilityRuntime::Context>& runtimeContext, bool useStageModel)
|
||||
@@ -25,10 +64,46 @@ DataAbilityHelperStandard::DataAbilityHelperStandard(const std::shared_ptr<OHOS:
|
||||
useStageModel_ = useStageModel;
|
||||
if (useStageModel) {
|
||||
runtimeContext_ = runtimeContext;
|
||||
#if !defined(WINDOWS_PLATFORM) and !defined(MAC_PLATFORM)
|
||||
dataAbilityThumbnailQueryImpl_ =
|
||||
[runtimeContextWp = runtimeContext_] (const std::string& uri) -> std::unique_ptr<Media::PixelMap> {
|
||||
ThumbnaiNapiEntry thumbnailNapiEntry = GetThumbnailNapiEntry();
|
||||
if (!thumbnailNapiEntry) {
|
||||
LOGE("thumbnailNapiEntry is null");
|
||||
return nullptr;
|
||||
}
|
||||
auto runtimeContextSptr = runtimeContextWp.lock();
|
||||
if (runtimeContextSptr == nullptr) {
|
||||
LOGE("runtimeContext lock fail, uri: %{private}s", uri.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
void* resPtr = thumbnailNapiEntry(uri.c_str(), &runtimeContextSptr);
|
||||
if (resPtr == nullptr) {
|
||||
LOGW("resPtr from native thumbnail is nullptr, uri: %{private}s", uri.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
return std::unique_ptr<Media::PixelMap>(reinterpret_cast<Media::PixelMap*>(resPtr));
|
||||
};
|
||||
#endif
|
||||
} else {
|
||||
dataAbilityHelper_ = AppExecFwk::DataAbilityHelper::Creator(context);
|
||||
}
|
||||
}
|
||||
|
||||
void* DataAbilityHelperStandard::QueryThumbnailResFromDataAbility(const std::string& uri)
|
||||
{
|
||||
if (!dataAbilityThumbnailQueryImpl_) {
|
||||
LOGW("no impl for thumbnail data query, please make sure you are using thumbnail resource on stage mode. "
|
||||
"uri: %{private}s", uri.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
pixmap_ = dataAbilityThumbnailQueryImpl_(uri);
|
||||
if (!pixmap_) {
|
||||
LOGW("pixel map from thumb nail is nullptr, uri: %{public}s", uri.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<void*>(&pixmap_);
|
||||
}
|
||||
|
||||
int32_t DataAbilityHelperStandard::OpenFile(const std::string& uriStr, const std::string& mode)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include "base/resource/data_ability_helper.h"
|
||||
|
||||
#include "pixel_map.h"
|
||||
|
||||
namespace OHOS::AppExecFwk {
|
||||
class DataAbilityHelper;
|
||||
class Context;
|
||||
@@ -33,6 +35,7 @@ namespace OHOS {
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
using DataAbilityThumbnailQueryImpl = std::function<std::unique_ptr<Media::PixelMap>(const std::string&)>;
|
||||
class DataAbilityHelperStandard : public DataAbilityHelper {
|
||||
DECLARE_ACE_TYPE(DataAbilityHelperStandard, DataAbilityHelper)
|
||||
|
||||
@@ -42,12 +45,15 @@ public:
|
||||
~DataAbilityHelperStandard() override = default;
|
||||
|
||||
int32_t OpenFile(const std::string& uriStr, const std::string& mode) override;
|
||||
void* QueryThumbnailResFromDataAbility(const std::string& uri) override;
|
||||
|
||||
private:
|
||||
bool useStageModel_ = false;
|
||||
std::shared_ptr<AppExecFwk::DataAbilityHelper> dataAbilityHelper_;
|
||||
std::weak_ptr<OHOS::AbilityRuntime::Context> runtimeContext_;
|
||||
std::shared_ptr<OHOS::Uri> uri_;
|
||||
DataAbilityThumbnailQueryImpl dataAbilityThumbnailQueryImpl_;
|
||||
std::unique_ptr<Media::PixelMap> pixmap_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -68,11 +68,23 @@ AlphaType PixelMapOhos::AlphaTypeConverter(Media::AlphaType alphaType)
|
||||
RefPtr<PixelMap> PixelMap::CreatePixelMap(void* rawPtr)
|
||||
{
|
||||
std::shared_ptr<Media::PixelMap>* pixmapPtr = reinterpret_cast<std::shared_ptr<Media::PixelMap>*>(rawPtr);
|
||||
if (*pixmapPtr == nullptr) {
|
||||
LOGE("pixmap pointer is nullptr.");
|
||||
if (pixmapPtr == nullptr || *pixmapPtr == nullptr) {
|
||||
LOGW("pixmap pointer is nullptr when CreatePixelMap.");
|
||||
return nullptr;
|
||||
}
|
||||
return AceType::MakeRefPtr<PixelMapOhos>(*pixmapPtr);
|
||||
}
|
||||
|
||||
RefPtr<PixelMap> PixelMap::CreatePixelMapFromDataAbility(void* uniquePtr)
|
||||
{
|
||||
std::unique_ptr<Media::PixelMap>* pixmapPtr = reinterpret_cast<std::unique_ptr<Media::PixelMap>*>(uniquePtr);
|
||||
if (pixmapPtr == nullptr || *pixmapPtr == nullptr) {
|
||||
LOGW("pixmap pointer is nullptr when CreatePixelMapFromDataAbility.");
|
||||
return nullptr;
|
||||
}
|
||||
auto rawPtr = (*pixmapPtr).release();
|
||||
return AceType::MakeRefPtr<PixelMapOhos>(std::shared_ptr<Media::PixelMap>(rawPtr));
|
||||
}
|
||||
|
||||
int32_t PixelMapOhos::GetWidth() const
|
||||
{
|
||||
|
||||
@@ -46,6 +46,7 @@ class ACE_EXPORT PixelMap : public AceType {
|
||||
|
||||
public:
|
||||
static RefPtr<PixelMap> CreatePixelMap(void* sptrAddr);
|
||||
static RefPtr<PixelMap> CreatePixelMapFromDataAbility(void* uniquePtr);
|
||||
virtual int32_t GetWidth() const = 0;
|
||||
virtual int32_t GetHeight() const = 0;
|
||||
virtual const uint8_t* GetPixels() const = 0;
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
~DataAbilityHelper() override = default;
|
||||
|
||||
virtual int32_t OpenFile(const std::string& uriStr, const std::string& mode) = 0;
|
||||
virtual void* QueryThumbnailResFromDataAbility(const std::string& uri) = 0;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
@@ -28,6 +28,16 @@ std::unique_ptr<DataProviderRes> DataProviderManager::GetDataProviderResFromUri(
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* DataProviderManagerStandard::GetDataProviderThumbnailResFromUri(const std::string& uriStr)
|
||||
{
|
||||
InitHelper();
|
||||
if (!helper_) {
|
||||
LOGE("data ability helper is null when try query thumbnail resource, uri: %{private}s", uriStr.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
return helper_->QueryThumbnailResFromDataAbility(uriStr);
|
||||
}
|
||||
|
||||
std::unique_ptr<DataProviderRes> DataProviderManagerStandard::GetDataProviderResFromUri(const std::string& uriStr)
|
||||
{
|
||||
|
||||
@@ -48,6 +48,7 @@ public:
|
||||
~DataProviderManagerInterface() override = default;
|
||||
|
||||
virtual std::unique_ptr<DataProviderRes> GetDataProviderResFromUri(const std::string& uriStr) = 0;
|
||||
virtual void* GetDataProviderThumbnailResFromUri(const std::string& uriStr) = 0;
|
||||
};
|
||||
|
||||
using DataProviderImpl = std::function<std::unique_ptr<DataProviderRes>(const std::string& uriStr)>;
|
||||
@@ -58,6 +59,10 @@ public:
|
||||
~DataProviderManager() override = default;
|
||||
|
||||
std::unique_ptr<DataProviderRes> GetDataProviderResFromUri(const std::string& uriStr) override;
|
||||
void* GetDataProviderThumbnailResFromUri(const std::string& uriStr) override
|
||||
{
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
private:
|
||||
DataProviderImpl platformImpl_;
|
||||
@@ -73,6 +78,7 @@ public:
|
||||
~DataProviderManagerStandard() override = default;
|
||||
|
||||
std::unique_ptr<DataProviderRes> GetDataProviderResFromUri(const std::string& uriStr) override;
|
||||
void* GetDataProviderThumbnailResFromUri(const std::string& uriStr) override;
|
||||
|
||||
const RefPtr<DataAbilityHelper>& GetDataAbilityHelper()
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ Window::Window(std::unique_ptr<PlatformWindow> platformWindow) : platformWindow_
|
||||
void Window::RequestFrame()
|
||||
{
|
||||
if (!onShow_) {
|
||||
LOGI("window is not show, stop request frame");
|
||||
LOGD("window is not show, stop request frame");
|
||||
return;
|
||||
}
|
||||
if (!isRequestVsync_ && platformWindow_ != nullptr) {
|
||||
|
||||
@@ -304,6 +304,7 @@ enum class SrcType {
|
||||
INTERNAL, // internal cached file resource
|
||||
RESOURCE,
|
||||
DATA_ABILITY,
|
||||
DATA_ABILITY_DECODED,
|
||||
RESOURCE_ID, // default resource which src is internal resource id
|
||||
PIXMAP,
|
||||
};
|
||||
|
||||
@@ -22,7 +22,10 @@
|
||||
#include "third_party/skia/include/core/SkRect.h"
|
||||
#include "third_party/skia/include/core/SkShader.h"
|
||||
|
||||
#include "base/image/pixel_map.h"
|
||||
#include "base/thread/background_task_executor.h"
|
||||
#include "base/utils/utils.h"
|
||||
#include "core/common/container.h"
|
||||
#include "core/common/frontend.h"
|
||||
#include "core/components/align/render_align.h"
|
||||
#include "core/components/common/properties/radius.h"
|
||||
@@ -298,6 +301,60 @@ void RosenRenderImage::Update(const RefPtr<Component>& component)
|
||||
FetchImageObject();
|
||||
}
|
||||
|
||||
std::function<void()> RosenRenderImage::GenerateThumbnailLoadTask()
|
||||
{
|
||||
return [sourceInfo = sourceInfo_, pipelineContext = GetContext(), weak = AceType::WeakClaim(this),
|
||||
id = Container::CurrentId()]() {
|
||||
ContainerScope scope(id);
|
||||
auto context = pipelineContext.Upgrade();
|
||||
if (!context) {
|
||||
LOGE("pipeline context is null when try start thumbnailLoadTask, uri: %{private}s",
|
||||
sourceInfo.GetSrc().c_str());
|
||||
return;
|
||||
}
|
||||
auto dataProvider = context->GetDataProviderManager();
|
||||
if (!dataProvider) {
|
||||
LOGE("the data provider is null when try load thumbnail resource, uri: %{private}s",
|
||||
sourceInfo.GetSrc().c_str());
|
||||
return;
|
||||
}
|
||||
void* pixmapMediaUniquePtr = dataProvider->GetDataProviderThumbnailResFromUri(sourceInfo.GetSrc());
|
||||
auto pixmapOhos = PixelMap::CreatePixelMapFromDataAbility(pixmapMediaUniquePtr);
|
||||
auto taskExecutor = context->GetTaskExecutor();
|
||||
if (!taskExecutor) {
|
||||
return;
|
||||
}
|
||||
if (!pixmapOhos) {
|
||||
LOGW("pixmapOhos is null, uri: %{private}s", sourceInfo.GetSrc().c_str());
|
||||
taskExecutor->PostTask(
|
||||
[weak, sourceInfo] {
|
||||
auto renderImage = weak.Upgrade();
|
||||
if (!renderImage) {
|
||||
LOGE("renderImage is null when try trigger load thumbnail fail event, "
|
||||
"uri: %{private}s",
|
||||
sourceInfo.GetSrc().c_str());
|
||||
return;
|
||||
}
|
||||
renderImage->failedCallback_(sourceInfo);
|
||||
},
|
||||
TaskExecutor::TaskType::UI);
|
||||
return;
|
||||
}
|
||||
taskExecutor->PostTask(
|
||||
[weak, pixmapOhos, sourceInfo] {
|
||||
auto renderImage = weak.Upgrade();
|
||||
if (!renderImage) {
|
||||
LOGE("renderImage is null when try load thumbnail data ability, "
|
||||
"uri: %{private}s",
|
||||
sourceInfo.GetSrc().c_str());
|
||||
return;
|
||||
}
|
||||
renderImage->UpdatePixmap(pixmapOhos);
|
||||
},
|
||||
TaskExecutor::TaskType::UI);
|
||||
};
|
||||
}
|
||||
|
||||
void RosenRenderImage::FetchImageObject()
|
||||
{
|
||||
LOGD("fetch obj : %{public}s", sourceInfo_.ToString().c_str());
|
||||
@@ -321,6 +378,10 @@ void RosenRenderImage::FetchImageObject()
|
||||
rawImageSizeUpdated_ = false;
|
||||
SrcType srcType = sourceInfo_.GetSrcType();
|
||||
switch (srcType) {
|
||||
case SrcType::DATA_ABILITY_DECODED: {
|
||||
BackgroundTaskExecutor::GetInstance().PostTask(GenerateThumbnailLoadTask());
|
||||
break;
|
||||
}
|
||||
case SrcType::PIXMAP: {
|
||||
UpdatePixmap(sourceInfo_.GetPixmap());
|
||||
break;
|
||||
@@ -330,19 +391,11 @@ void RosenRenderImage::FetchImageObject()
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
bool syncMode = (context->IsBuildingFirstPage() &&
|
||||
frontend->GetType() == FrontendType::JS_CARD &&
|
||||
sourceInfo_.GetSrcType() != SrcType::NETWORK) || syncMode_;
|
||||
ImageProvider::FetchImageObject(
|
||||
sourceInfo_,
|
||||
imageObjSuccessCallback_,
|
||||
uploadSuccessCallback_,
|
||||
failedCallback_,
|
||||
GetContext(),
|
||||
syncMode,
|
||||
useSkiaSvg_,
|
||||
autoResize_,
|
||||
renderTaskHolder_,
|
||||
bool syncMode = (context->IsBuildingFirstPage() && frontend->GetType() == FrontendType::JS_CARD &&
|
||||
sourceInfo_.GetSrcType() != SrcType::NETWORK) ||
|
||||
syncMode_;
|
||||
ImageProvider::FetchImageObject(sourceInfo_, imageObjSuccessCallback_, uploadSuccessCallback_,
|
||||
failedCallback_, GetContext(), syncMode, useSkiaSvg_, autoResize_, renderTaskHolder_,
|
||||
onPostBackgroundTask_);
|
||||
break;
|
||||
}
|
||||
@@ -411,6 +464,7 @@ void RosenRenderImage::ProcessPixmapForPaint()
|
||||
return;
|
||||
}
|
||||
FireLoadEvent(rawImageSize_);
|
||||
RemoveChild(renderAltImage_);
|
||||
renderAltImage_ = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ private:
|
||||
void UpdatePixmap(const RefPtr<PixelMap>& pixmap);
|
||||
void UpdateSharedMemoryImage(const RefPtr<PipelineContext>& context);
|
||||
void ProcessPixmapForPaint();
|
||||
std::function<void()> GenerateThumbnailLoadTask();
|
||||
|
||||
sk_sp<SkSVGDOM> skiaDom_;
|
||||
RefPtr<SvgDom> svgDom_;
|
||||
|
||||
@@ -40,6 +40,12 @@ bool ImageSourceInfo::IsValidBase64Head(const std::string& uri, const std::strin
|
||||
return std::regex_match(base64Head, regular);
|
||||
}
|
||||
|
||||
bool ImageSourceInfo::IsUriOfDataAbilityEncoded(const std::string& uri, const std::string& pattern)
|
||||
{
|
||||
std::regex regular(pattern);
|
||||
return std::regex_match(uri, regular);
|
||||
}
|
||||
|
||||
SrcType ImageSourceInfo::ResolveURIType(const std::string& uri)
|
||||
{
|
||||
if (uri.empty()) {
|
||||
@@ -68,6 +74,9 @@ SrcType ImageSourceInfo::ResolveURIType(const std::string& uri)
|
||||
} else if (head == "resource") {
|
||||
return SrcType::RESOURCE;
|
||||
} else if (head == "dataability") {
|
||||
if (IsUriOfDataAbilityEncoded(uri, "^dataability://.*?/media/.*/thumbnail/.*$")) {
|
||||
return SrcType::DATA_ABILITY_DECODED;
|
||||
}
|
||||
return SrcType::DATA_ABILITY;
|
||||
} else {
|
||||
return SrcType::UNSUPPORTED;
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
static bool IsSVGSource(const std::string& imageSrc, InternalResource::ResourceId resourceId);
|
||||
static SrcType ResolveURIType(const std::string& uri);
|
||||
static bool IsValidBase64Head(const std::string& uri, const std::string& pattern);
|
||||
static bool IsUriOfDataAbilityEncoded(const std::string& uri, const std::string& pattern);
|
||||
|
||||
explicit ImageSourceInfo(
|
||||
const std::string& imageSrc,
|
||||
|
||||
@@ -2037,7 +2037,7 @@ void RenderNode::RSNodeAddChild(const RefPtr<RenderNode>& child)
|
||||
{
|
||||
#ifdef ENABLE_ROSEN_BACKEND
|
||||
if (!rsNode_) {
|
||||
LOGW("Parent render_node has no RSNode, creating now.");
|
||||
LOGD("Parent render_node has no RSNode, creating now.");
|
||||
SyncRSNodeBoundary(true, true);
|
||||
}
|
||||
if (IsTailRenderNode()) {
|
||||
|
||||
Reference in New Issue
Block a user