* 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 "interaction_impl.h"
#include "adapter/android/stage/uicontent/ace_container_sg.h"
#include "base/log/log.h"
#include "core/common/container.h"
#include "core/common/interaction/interaction_data.h"
#ifdef ENABLE_DRAG_FRAMEWORK
#include "drag_data.h"
#include "interaction_manager.h"
#endif
#ifdef ENABLE_DRAG_FRAMEWORK
using namespace OHOS::Msdp::DeviceStatus;
#endif
namespace OHOS::Ace {
#ifdef ENABLE_DRAG_FRAMEWORK
Msdp::DeviceStatus::DragCursorStyle TranslateDragCursorStyle(OHOS::Ace::DragCursorStyleCore style);
Msdp::DeviceStatus::DragResult TranslateDragResult(DragRet dragResult);
DragRet TranslateDragResult(Msdp::DeviceStatus::DragResult dragResult);
Msdp::DeviceStatus::DragBehavior TranslateDragBehavior(OHOS::Ace::DragBehavior dragBehavior);
OHOS::Ace::DragBehavior TranslateDragBehavior(Msdp::DeviceStatus::DragBehavior dragBehavior);
#endif
bool g_dragging = false;
#ifdef ENABLE_DRAG_FRAMEWORK
std::function<void(const OHOS::Ace::DragNotifyMsg&)> callback_;
#endif
InteractionInterface* InteractionInterface::GetInstance()
{
static InteractionImpl instance;
return &instance;
}
int32_t InteractionImpl::UpdateShadowPic(const OHOS::Ace::ShadowInfoCore& shadowInfo)
{
#ifdef ENABLE_DRAG_FRAMEWORK
auto pixelMap = shadowInfo.pixelMap;
if (!pixelMap) {
Msdp::DeviceStatus::ShadowInfo msdpShadowInfo { nullptr, shadowInfo.x, shadowInfo.y };
return InteractionManager::GetInstance()->UpdateShadowPic(msdpShadowInfo);
}
Msdp::DeviceStatus::ShadowInfo msdpShadowInfo { shadowInfo.pixelMap->GetPixelMapSharedPtr(), shadowInfo.x,
shadowInfo.y };
return InteractionManager::GetInstance()->UpdateShadowPic(msdpShadowInfo);
#endif
return -1;
}
int32_t InteractionImpl::SetDragWindowVisible(bool visible, const std::shared_ptr<Rosen::RSTransaction>& rSTransaction)
{
#ifdef ENABLE_DRAG_FRAMEWORK
return InteractionManager::GetInstance()->SetDragWindowVisible(visible);
#endif
return -1;
}
int32_t InteractionImpl::SetMouseDragMonitorState(bool state)
{
return -1;
}
int32_t InteractionImpl::StartDrag(
const DragDataCore& dragData, std::function<void(const OHOS::Ace::DragNotifyMsg&)> callback)
{
#ifdef ENABLE_DRAG_FRAMEWORK
callback_ = callback;
RegisterDragWindow();
SetSVGFilePath();
std::shared_ptr<OHOS::Rosen::Window> window = GetDragWindow();
if (!window) {
LOGE("InteractionImpl::StartDrag get drag window failed");
return -1;
}
surfaceNodeListener_ = new SurfaceNodeListener(window, dragData);
window->RegisterSurfaceNodeListener(surfaceNodeListener_);
window->ShowWindow();
g_dragging = true;
#endif
return 0;
}
int32_t InteractionImpl::GetDragBundleInfo(DragBundleInfo& dragBundleInfo)
{
return -1;
}
int32_t InteractionImpl::UpdateDragStyle(OHOS::Ace::DragCursorStyleCore style, const int32_t eventId)
{
#ifdef ENABLE_DRAG_FRAMEWORK
return InteractionManager::GetInstance()->UpdateDragStyle(TranslateDragCursorStyle(style));
#endif
return -1;
}
int32_t InteractionImpl::UpdatePreviewStyle(const OHOS::Ace::PreviewStyle& previewStyle)
{
return -1;
}
int32_t InteractionImpl::UpdatePreviewStyleWithAnimation(
const OHOS::Ace::PreviewStyle& previewStyle, const OHOS::Ace::PreviewAnimation& animation)
{
return -1;
}
int32_t InteractionImpl::StopDrag(DragDropRet result, std::function<void()> callback)
{
#ifdef ENABLE_DRAG_FRAMEWORK
Msdp::DeviceStatus::DragDropResult dragDropResult { TranslateDragResult(result.result), result.hasCustomAnimation,
result.mainWindow, TranslateDragBehavior(result.dragBehavior) };
int32_t ret = InteractionManager::GetInstance()->StopDrag(dragDropResult);
g_dragging = false;
OHOS::Ace::DragNotifyMsg msg { 0, 0, InteractionManager::GetInstance()->GetDragTargetPid(),
TranslateDragResult(dragDropResult.result), TranslateDragBehavior(dragDropResult.dragBehavior) };
if (callback_) {
callback_(msg);
}
return ret;
#endif
return -1;
}
int32_t InteractionImpl::GetUdKey(std::string& udKey)
{
#ifdef ENABLE_DRAG_FRAMEWORK
return InteractionManager::GetInstance()->GetUdKey(udKey);
#endif
return -1;
}
int32_t InteractionImpl::GetShadowOffset(ShadowOffsetData& shadowOffsetData)
{
#ifdef ENABLE_DRAG_FRAMEWORK
return InteractionManager::GetInstance()->GetShadowOffset(
shadowOffsetData.offsetX, shadowOffsetData.offsetY, shadowOffsetData.width, shadowOffsetData.height);
#endif
return -1;
}
int32_t InteractionImpl::GetDragSummary(std::map<std::string, int64_t>& summary,
std::map<std::string, int64_t>& detailedSummary, std::map<std::string, std::vector<int32_t>>& summaryFormat,
int32_t& version, int64_t& totalSize, std::string& tag)
{
#ifdef ENABLE_DRAG_FRAMEWORK
Msdp::DeviceStatus::DragSummaryInfo dragSummary;
auto ret = InteractionManager::GetInstance()->GetDragSummaryInfo(dragSummary);
if (ret != 0) {
return ret;
}
summary = dragSummary.summarys;
detailedSummary = dragSummary.detailedSummarys;
summaryFormat = dragSummary.summaryFormat;
version = dragSummary.version;
totalSize = dragSummary.totalSize;
return ret;
#endif
return -1;
}
int32_t InteractionImpl::GetDragExtraInfo(std::string& extraInfo)
{
#ifdef ENABLE_DRAG_FRAMEWORK
return InteractionManager::GetInstance()->GetExtraInfo(extraInfo);
#endif
return -1;
}
int32_t InteractionImpl::EnterTextEditorArea(bool enable)
{
#ifdef ENABLE_DRAG_FRAMEWORK
return InteractionManager::GetInstance()->EnterTextEditorArea(enable);
#endif
return -1;
}
int32_t InteractionImpl::GetDragState(DragState& dragState) const
{
#ifdef ENABLE_DRAG_FRAMEWORK
Msdp::DeviceStatus::DragState state;
int32_t ret = InteractionManager::GetInstance()->GetDragState(state);
switch (state) {
case Msdp::DeviceStatus::DragState::ERROR:
dragState = DragState::ERROR;
break;
case Msdp::DeviceStatus::DragState::START:
dragState = DragState::START;
break;
case Msdp::DeviceStatus::DragState::STOP:
dragState = DragState::STOP;
break;
case Msdp::DeviceStatus::DragState::CANCEL:
dragState = DragState::CANCEL;
break;
case Msdp::DeviceStatus::DragState::MOTION_DRAGGING:
dragState = DragState::MOTION_DRAGGING;
break;
default:
dragState = DragState::ERROR;
LOGW("unknow msdp drag state: %d", state);
break;
}
return ret;
#endif
return -1;
}
int32_t InteractionImpl::AddPrivilege(const std::string& signature, const DragEventData& dragEventData)
{
return -1;
}
int32_t InteractionImpl::RegisterCoordinationListener(std::function<void()> dragOutCallback)
{
return -1;
}
int32_t InteractionImpl::UnRegisterCoordinationListener()
{
return -1;
}
int32_t InteractionImpl::EnableInternalDropAnimation(const std::string& animationInfo)
{
return -1;
}
bool InteractionImpl::IsDragStart() const
{
#if defined(ENABLE_DRAG_FRAMEWORK)
return InteractionManager::GetInstance()->IsDragStart();
#endif
return false;
}
#ifdef ENABLE_DRAG_FRAMEWORK
Msdp::DeviceStatus::DragCursorStyle TranslateDragCursorStyle(OHOS::Ace::DragCursorStyleCore style)
{
switch (style) {
case OHOS::Ace::DragCursorStyleCore::DEFAULT:
return Msdp::DeviceStatus::DragCursorStyle::DEFAULT;
case OHOS::Ace::DragCursorStyleCore::FORBIDDEN:
return Msdp::DeviceStatus::DragCursorStyle::FORBIDDEN;
case OHOS::Ace::DragCursorStyleCore::COPY:
return Msdp::DeviceStatus::DragCursorStyle::COPY;
case OHOS::Ace::DragCursorStyleCore::MOVE:
return Msdp::DeviceStatus::DragCursorStyle::MOVE;
default:
return Msdp::DeviceStatus::DragCursorStyle::DEFAULT;
}
}
Msdp::DeviceStatus::DragResult TranslateDragResult(DragRet dragResult)
{
switch (dragResult) {
case DragRet::DRAG_SUCCESS:
return Msdp::DeviceStatus::DragResult::DRAG_SUCCESS;
case DragRet::DRAG_FAIL:
return Msdp::DeviceStatus::DragResult::DRAG_FAIL;
case DragRet::DRAG_CANCEL:
return Msdp::DeviceStatus::DragResult::DRAG_CANCEL;
default:
return Msdp::DeviceStatus::DragResult::DRAG_SUCCESS;
}
}
DragRet TranslateDragResult(Msdp::DeviceStatus::DragResult dragResult)
{
switch (dragResult) {
case Msdp::DeviceStatus::DragResult::DRAG_SUCCESS:
return DragRet::DRAG_SUCCESS;
case Msdp::DeviceStatus::DragResult::DRAG_FAIL:
return DragRet::DRAG_FAIL;
case Msdp::DeviceStatus::DragResult::DRAG_CANCEL:
return DragRet::DRAG_CANCEL;
default:
return DragRet::DRAG_SUCCESS;
}
}
Msdp::DeviceStatus::DragBehavior TranslateDragBehavior(OHOS::Ace::DragBehavior dragBehavior)
{
switch (dragBehavior) {
case OHOS::Ace::DragBehavior::COPY:
return Msdp::DeviceStatus::DragBehavior::COPY;
case OHOS::Ace::DragBehavior::MOVE:
return Msdp::DeviceStatus::DragBehavior::MOVE;
default:
return Msdp::DeviceStatus::DragBehavior::UNKNOWN;
}
}
OHOS::Ace::DragBehavior TranslateDragBehavior(Msdp::DeviceStatus::DragBehavior dragBehavior)
{
switch (dragBehavior) {
case Msdp::DeviceStatus::DragBehavior::COPY:
return OHOS::Ace::DragBehavior::COPY;
case Msdp::DeviceStatus::DragBehavior::MOVE:
return OHOS::Ace::DragBehavior::MOVE;
default:
return OHOS::Ace::DragBehavior::UNKNOWN;
}
}
#endif
int32_t InteractionImpl::UpdatePointAction(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
{
#ifdef ENABLE_DRAG_FRAMEWORK
return InteractionManager::GetInstance()->UpdatePointerAction(pointerEvent);
#endif
return -1;
}
void InteractionImpl::RegisterDragWindow()
{
auto containerId = Container::CurrentId();
auto interactionPtr = AceType::Claim(this);
auto Destroycallback = [interactionPtr, containerId] {
auto container = Platform::AceContainerSG::GetContainer(containerId);
CHECK_NULL_VOID(container);
auto taskExecutor = container->GetTaskExecutor();
CHECK_NULL_VOID(taskExecutor);
ContainerScope scope(containerId);
auto task = [interactionPtr] {
CHECK_NULL_VOID(interactionPtr);
CHECK_NULL_VOID(interactionPtr->surfaceNodeListener_);
auto window = interactionPtr->surfaceNodeListener_->dragWindow_;
CHECK_NULL_VOID(window);
window->UnregisterSurfaceNodeListener(interactionPtr->surfaceNodeListener_);
window->Destroy();
interactionPtr->surfaceNodeListener_->dragWindow_ = nullptr;
};
taskExecutor->PostTask(task, TaskExecutor::TaskType::UI, "ArkUI-XInteractionImplStopDrag");
};
#ifdef ENABLE_DRAG_FRAMEWORK
InteractionManager::GetInstance()->RegisterDragWindow(Destroycallback);
#endif
}
void InteractionImpl::SetSVGFilePath()
{
auto containerId = Container::CurrentId();
auto container = Platform::AceContainerSG::GetContainer(containerId);
CHECK_NULL_VOID(container);
std::string packagePath = container->GetPackagePathStr();
std::string filePath = packagePath + "/systemres" + "/resources";
#ifdef ENABLE_DRAG_FRAMEWORK
InteractionManager::GetInstance()->SetSVGFilePath(filePath);
#endif
}
std::shared_ptr<OHOS::Rosen::Window> InteractionImpl::GetDragWindow()
{
auto containerId = Container::CurrentId();
auto container = Platform::AceContainerSG::GetContainer(containerId);
CHECK_NULL_RETURN(container, nullptr);
sptr<Rosen::Window> window = container->GetUIWindow(containerId);
CHECK_NULL_RETURN(window, nullptr);
auto dragWindow = Rosen::Window::CreateDragWindow(window->GetContext());
return dragWindow;
}
void SurfaceNodeListener::OnSurfaceNodeChanged(int32_t width, int32_t height, float density)
{
#ifdef ENABLE_DRAG_FRAMEWORK
if (g_dragging) {
InteractionManager::GetInstance()->SetDragWindow(dragWindow_);
Msdp::DeviceStatus::DragData msdpDragData { {}, dragData.buffer, dragData.udKey, dragData.extraInfo,
dragData.filterInfo, dragData.sourceType, dragData.dragNum, dragData.pointerId,
dragData.displayX, dragData.displayY, dragData.displayId, dragData.mainWindow,
dragData.hasCanceledAnimation, dragData.hasCoordinateCorrected, dragData.summarys };
for (auto& shadowInfo : dragData.shadowInfos) {
if (shadowInfo.pixelMap) {
msdpDragData.shadowInfos.push_back(
{ shadowInfo.pixelMap->GetPixelMapSharedPtr(), shadowInfo.x, shadowInfo.y });
} else {
msdpDragData.shadowInfos.push_back({ nullptr, shadowInfo.x, shadowInfo.y });
}
}
InteractionManager::GetInstance()->StartDrag(msdpDragData);
g_dragging = false;
}
#endif
}
}