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:
chenxuankai1
2022-03-31 12:00:37 +08:00
parent f5923af5cc
commit ecb70f2dd9
14 changed files with 194 additions and 17 deletions
@@ -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
+14 -2
View File
@@ -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
{
+1
View File
@@ -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()
{
+1 -1
View File
@@ -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()) {