123b3eb3cSopenharmony_ci/*
223b3eb3cSopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
323b3eb3cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
423b3eb3cSopenharmony_ci * you may not use this file except in compliance with the License.
523b3eb3cSopenharmony_ci * You may obtain a copy of the License at
623b3eb3cSopenharmony_ci *
723b3eb3cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
823b3eb3cSopenharmony_ci *
923b3eb3cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1023b3eb3cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1123b3eb3cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1223b3eb3cSopenharmony_ci * See the License for the specific language governing permissions and
1323b3eb3cSopenharmony_ci * limitations under the License.
1423b3eb3cSopenharmony_ci */
1523b3eb3cSopenharmony_ci
1623b3eb3cSopenharmony_ci#include "core/common/ai/ai_write_adapter.h"
1723b3eb3cSopenharmony_ci
1823b3eb3cSopenharmony_ci#include "array_wrapper.h"
1923b3eb3cSopenharmony_ci#include "bool_wrapper.h"
2023b3eb3cSopenharmony_ci#include "int_wrapper.h"
2123b3eb3cSopenharmony_ci#include "want.h"
2223b3eb3cSopenharmony_ci#include "want_params.h"
2323b3eb3cSopenharmony_ci#include "core/components_ng/layout/layout_property.h"
2423b3eb3cSopenharmony_ci#include "core/components_ng/pattern/text/span/span_string.h"
2523b3eb3cSopenharmony_ci#include "core/components_ng/pattern/ui_extension/session_wrapper.h"
2623b3eb3cSopenharmony_ci#include "core/components_ng/pattern/ui_extension/session_wrapper_factory.h"
2723b3eb3cSopenharmony_ci#include "core/components_ng/pattern/ui_extension/ui_extension_pattern.h"
2823b3eb3cSopenharmony_ci#include "core/components_ng/pattern/ui_extension/modal_ui_extension_proxy_impl.h"
2923b3eb3cSopenharmony_ci
3023b3eb3cSopenharmony_cinamespace OHOS::Ace {
3123b3eb3cSopenharmony_ciconst std::pair<std::string, std::string> UI_ENTENSION_TYPE = {"ability.want.params.uiExtensionType", "sys/commonUI"};
3223b3eb3cSopenharmony_ciconst std::wstring BOUNDARY_SYMBOLS = L",.?,。?!";
3323b3eb3cSopenharmony_ciconst std::string API_VERSION = "apiVersion";
3423b3eb3cSopenharmony_ciconst std::string RESULT_BUFFER = "resultBuffer";
3523b3eb3cSopenharmony_ciconst std::string SHEET_DISMISS = "sheetDismiss";
3623b3eb3cSopenharmony_ciconst std::string PROCESS_ID = "processId";
3723b3eb3cSopenharmony_ciconst std::string MAX_CONTENT_LENGTH = "maxContentLength";
3823b3eb3cSopenharmony_ciconst std::string FIRST_HANDLE_RECT = "firstHandleRect";
3923b3eb3cSopenharmony_ciconst std::string SECOND_HANDLE_RECT = "secondHandleRect";
4023b3eb3cSopenharmony_ciconst std::string IS_AI_SUPPORT_METADATA = "isAiSupport";
4123b3eb3cSopenharmony_ciconst std::string SELECT_CONTENT_LENGTH = "selectContentLength";
4223b3eb3cSopenharmony_ciconst std::string REQUEST_LONG_CONTENT = "requestLongContent";
4323b3eb3cSopenharmony_ciconst std::string LONG_SENTENCE_BUFFER = "longSentenceBuffer";
4423b3eb3cSopenharmony_ciconst std::string LONG_SELECT_START = "longSelectStart";
4523b3eb3cSopenharmony_ciconst std::string LONG_SELECT_END = "longSelectEnd";
4623b3eb3cSopenharmony_ciconst std::string KEY_PACKAGE_NAME = "keyPackageApp";
4723b3eb3cSopenharmony_ciconst std::string START_COMPONONT_TYPE = "startComponentType";
4823b3eb3cSopenharmony_ci
4923b3eb3cSopenharmony_cibool AIWriteAdapter::IsSentenceBoundary(const wchar_t value)
5023b3eb3cSopenharmony_ci{
5123b3eb3cSopenharmony_ci    for (wchar_t item: BOUNDARY_SYMBOLS) {
5223b3eb3cSopenharmony_ci        if (value == item) {
5323b3eb3cSopenharmony_ci            return true;
5423b3eb3cSopenharmony_ci        }
5523b3eb3cSopenharmony_ci    }
5623b3eb3cSopenharmony_ci    return false;
5723b3eb3cSopenharmony_ci}
5823b3eb3cSopenharmony_ci
5923b3eb3cSopenharmony_ciuint32_t AIWriteAdapter::GetSelectLengthOnlyText(const std::wstring& content)
6023b3eb3cSopenharmony_ci{
6123b3eb3cSopenharmony_ci    uint32_t length = 0;
6223b3eb3cSopenharmony_ci    for (uint32_t i = 0; i < content.length(); i++) {
6323b3eb3cSopenharmony_ci        if (content[i] != L' ' && content[i] != L'\n') {
6423b3eb3cSopenharmony_ci            length++;
6523b3eb3cSopenharmony_ci        }
6623b3eb3cSopenharmony_ci    }
6723b3eb3cSopenharmony_ci    return length;
6823b3eb3cSopenharmony_ci}
6923b3eb3cSopenharmony_ci
7023b3eb3cSopenharmony_civoid AIWriteAdapter::CloseModalUIExtension()
7123b3eb3cSopenharmony_ci{
7223b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_RICH_TEXT, "CloseModalUIExtension.");
7323b3eb3cSopenharmony_ci    auto context = pipelineContext_.Upgrade();
7423b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
7523b3eb3cSopenharmony_ci    auto overlayManager = context->GetOverlayManager();
7623b3eb3cSopenharmony_ci    CHECK_NULL_VOID(overlayManager);
7723b3eb3cSopenharmony_ci    overlayManager->CloseModalUIExtension(sessionId_);
7823b3eb3cSopenharmony_ci    SetAIWrite(false);
7923b3eb3cSopenharmony_ci}
8023b3eb3cSopenharmony_ci
8123b3eb3cSopenharmony_civoid AIWriteAdapter::ShowModalUIExtension(const AIWriteInfo& info,
8223b3eb3cSopenharmony_ci    std::function<void(std::vector<uint8_t>&)> resultCallback)
8323b3eb3cSopenharmony_ci{
8423b3eb3cSopenharmony_ci    TAG_LOGI(AceLogTag::ACE_RICH_TEXT, "ShowModalUIExtension.");
8523b3eb3cSopenharmony_ci    AAFwk::Want want;
8623b3eb3cSopenharmony_ci    SetWantParams(info, want);
8723b3eb3cSopenharmony_ci    Ace::ModalUIExtensionCallbacks callbacks;
8823b3eb3cSopenharmony_ci    BindModalUIExtensionCallback(callbacks, resultCallback);
8923b3eb3cSopenharmony_ci
9023b3eb3cSopenharmony_ci    auto context = pipelineContext_.Upgrade();
9123b3eb3cSopenharmony_ci    CHECK_NULL_VOID(context);
9223b3eb3cSopenharmony_ci    auto overlayManager = context->GetOverlayManager();
9323b3eb3cSopenharmony_ci    CHECK_NULL_VOID(overlayManager);
9423b3eb3cSopenharmony_ci    Ace::ModalUIExtensionConfig config;
9523b3eb3cSopenharmony_ci    sessionId_ = overlayManager->CreateModalUIExtension(want, callbacks, config);
9623b3eb3cSopenharmony_ci    aiWriteInfo_ = info;
9723b3eb3cSopenharmony_ci}
9823b3eb3cSopenharmony_ci
9923b3eb3cSopenharmony_civoid AIWriteAdapter::SetWantParams(const AIWriteInfo& info, AAFwk::Want& want)
10023b3eb3cSopenharmony_ci{
10123b3eb3cSopenharmony_ci    auto apiVersion = AceApplicationInfo::GetInstance().GetApiTargetVersion();
10223b3eb3cSopenharmony_ci    want.SetElementName(bundleName_, abilityName_);
10323b3eb3cSopenharmony_ci    want.SetParam(UI_ENTENSION_TYPE.first, UI_ENTENSION_TYPE.second);
10423b3eb3cSopenharmony_ci    want.SetParam(API_VERSION, static_cast<int>(apiVersion));
10523b3eb3cSopenharmony_ci    want.SetParam(PROCESS_ID, getpid());
10623b3eb3cSopenharmony_ci    want.SetParam(MAX_CONTENT_LENGTH, info.maxLength);
10723b3eb3cSopenharmony_ci    want.SetParam(SELECT_CONTENT_LENGTH, info.selectLength);
10823b3eb3cSopenharmony_ci    want.SetParam(FIRST_HANDLE_RECT, info.firstHandle);
10923b3eb3cSopenharmony_ci    want.SetParam(SECOND_HANDLE_RECT, info.secondHandle);
11023b3eb3cSopenharmony_ci    want.SetParam(KEY_PACKAGE_NAME, AceApplicationInfo::GetInstance().GetPackageName());
11123b3eb3cSopenharmony_ci    want.SetParam(START_COMPONONT_TYPE, info.componentType);
11223b3eb3cSopenharmony_ci}
11323b3eb3cSopenharmony_ci
11423b3eb3cSopenharmony_civoid AIWriteAdapter::BindModalUIExtensionCallback(
11523b3eb3cSopenharmony_ci    Ace::ModalUIExtensionCallbacks& callbacks, std::function<void(std::vector<uint8_t>&)> resultCallback)
11623b3eb3cSopenharmony_ci{
11723b3eb3cSopenharmony_ci    callbacks.onResult = [](int32_t code, const AAFwk::Want& want) {
11823b3eb3cSopenharmony_ci        TAG_LOGD(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "UIExtension onResult, code: %{public}d", code);
11923b3eb3cSopenharmony_ci    };
12023b3eb3cSopenharmony_ci    callbacks.onDestroy = [weak = WeakClaim(this)]() {
12123b3eb3cSopenharmony_ci        TAG_LOGD(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "UIExtension onDestroy.");
12223b3eb3cSopenharmony_ci        auto aiWriteAdapter = weak.Upgrade();
12323b3eb3cSopenharmony_ci        CHECK_NULL_VOID(aiWriteAdapter);
12423b3eb3cSopenharmony_ci        aiWriteAdapter->CloseModalUIExtension();
12523b3eb3cSopenharmony_ci    };
12623b3eb3cSopenharmony_ci    callbacks.onError = [weak = WeakClaim(this)](int32_t code, const std::string& name, const std::string& message) {
12723b3eb3cSopenharmony_ci        TAG_LOGE(AceLogTag::ACE_UIEXTENSIONCOMPONENT,
12823b3eb3cSopenharmony_ci            "UIExtension onError, code: %{public}d, name: %{public}s, message: %{public}s",
12923b3eb3cSopenharmony_ci            code, name.c_str(), message.c_str());
13023b3eb3cSopenharmony_ci        auto aiWriteAdapter = weak.Upgrade();
13123b3eb3cSopenharmony_ci        CHECK_NULL_VOID(aiWriteAdapter);
13223b3eb3cSopenharmony_ci        aiWriteAdapter->CloseModalUIExtension();
13323b3eb3cSopenharmony_ci    };
13423b3eb3cSopenharmony_ci    callbacks.onRelease = [](int32_t code) {
13523b3eb3cSopenharmony_ci        TAG_LOGD(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "UIExtension onRelease, code: %{public}d", code);
13623b3eb3cSopenharmony_ci    };
13723b3eb3cSopenharmony_ci    callbacks.onRemoteReady = [weak = WeakClaim(this)](const std::shared_ptr<Ace::ModalUIExtensionProxy>& proxy) {
13823b3eb3cSopenharmony_ci        TAG_LOGD(AceLogTag::ACE_UIEXTENSIONCOMPONENT, "UIExtension onRemoteReady.");
13923b3eb3cSopenharmony_ci        auto aiWriteAdapter = weak.Upgrade();
14023b3eb3cSopenharmony_ci        CHECK_NULL_VOID(aiWriteAdapter);
14123b3eb3cSopenharmony_ci        aiWriteAdapter->SetModalUIExtensionProxy(proxy);
14223b3eb3cSopenharmony_ci    };
14323b3eb3cSopenharmony_ci    callbacks.onReceive = [weak = WeakClaim(this), cb = std::move(resultCallback)]
14423b3eb3cSopenharmony_ci        (const AAFwk::WantParams& wantParams) {
14523b3eb3cSopenharmony_ci        auto aiWriteAdapter = weak.Upgrade();
14623b3eb3cSopenharmony_ci        CHECK_NULL_VOID(aiWriteAdapter);
14723b3eb3cSopenharmony_ci        auto isSheetClose = false;
14823b3eb3cSopenharmony_ci        auto isRequest = false;
14923b3eb3cSopenharmony_ci        auto result = aiWriteAdapter->GetBufferParam(RESULT_BUFFER, wantParams);
15023b3eb3cSopenharmony_ci        isSheetClose = aiWriteAdapter->GetBoolParam(SHEET_DISMISS, wantParams);
15123b3eb3cSopenharmony_ci        isRequest = aiWriteAdapter->GetBoolParam(REQUEST_LONG_CONTENT, wantParams);
15223b3eb3cSopenharmony_ci        if (isRequest) {
15323b3eb3cSopenharmony_ci            aiWriteAdapter->SendData();
15423b3eb3cSopenharmony_ci            return;
15523b3eb3cSopenharmony_ci        }
15623b3eb3cSopenharmony_ci        if (cb && !result.empty()) {
15723b3eb3cSopenharmony_ci            cb(result);
15823b3eb3cSopenharmony_ci            return;
15923b3eb3cSopenharmony_ci        }
16023b3eb3cSopenharmony_ci        if (isSheetClose) {
16123b3eb3cSopenharmony_ci            aiWriteAdapter->CloseModalUIExtension();
16223b3eb3cSopenharmony_ci        }
16323b3eb3cSopenharmony_ci    };
16423b3eb3cSopenharmony_ci}
16523b3eb3cSopenharmony_ci
16623b3eb3cSopenharmony_civoid AIWriteAdapter::SendData()
16723b3eb3cSopenharmony_ci{
16823b3eb3cSopenharmony_ci    auto proxy = GetModalUIExtensionProxy();
16923b3eb3cSopenharmony_ci    AAFwk::WantParams wantParams;
17023b3eb3cSopenharmony_ci    SetArrayParam(wantParams, LONG_SENTENCE_BUFFER, aiWriteInfo_.sentenceBuffer);
17123b3eb3cSopenharmony_ci    wantParams.SetParam(LONG_SELECT_START, AAFwk::Integer::Box(aiWriteInfo_.start));
17223b3eb3cSopenharmony_ci    wantParams.SetParam(LONG_SELECT_END, AAFwk::Integer::Box(aiWriteInfo_.end));
17323b3eb3cSopenharmony_ci    proxy->SendData(wantParams);
17423b3eb3cSopenharmony_ci}
17523b3eb3cSopenharmony_ci
17623b3eb3cSopenharmony_civoid AIWriteAdapter::SetArrayParam(
17723b3eb3cSopenharmony_ci    AAFwk::WantParams& wantParams, const std::string& key, const std::vector<uint8_t>& value)
17823b3eb3cSopenharmony_ci{
17923b3eb3cSopenharmony_ci    std::vector<int> valueVec(value.size());
18023b3eb3cSopenharmony_ci    std::transform(value.begin(), value.end(), valueVec.begin(),
18123b3eb3cSopenharmony_ci        [](uint8_t x) { return static_cast<int>(x); });
18223b3eb3cSopenharmony_ci    size_t size = valueVec.size();
18323b3eb3cSopenharmony_ci    sptr<AAFwk::IArray> ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IInteger);
18423b3eb3cSopenharmony_ci    if (ao == nullptr) {
18523b3eb3cSopenharmony_ci        return;
18623b3eb3cSopenharmony_ci    }
18723b3eb3cSopenharmony_ci    for (size_t i = 0; i < size; i++) {
18823b3eb3cSopenharmony_ci        ao->Set(i, AAFwk::Integer::Box(value[i]));
18923b3eb3cSopenharmony_ci    }
19023b3eb3cSopenharmony_ci    wantParams.SetParam(key, ao);
19123b3eb3cSopenharmony_ci}
19223b3eb3cSopenharmony_ci
19323b3eb3cSopenharmony_cistd::vector<uint8_t> AIWriteAdapter::GetBufferParam(const std::string& key, const AAFwk::WantParams& wantParams)
19423b3eb3cSopenharmony_ci{
19523b3eb3cSopenharmony_ci    std::vector<uint8_t> array;
19623b3eb3cSopenharmony_ci    auto value = wantParams.GetParam(key);
19723b3eb3cSopenharmony_ci    AAFwk::IArray *ao = AAFwk::IArray::Query(value);
19823b3eb3cSopenharmony_ci    if (ao != nullptr && AAFwk::Array::IsIntegerArray(ao)) {
19923b3eb3cSopenharmony_ci        auto func = [&](AAFwk::IInterface *object) {
20023b3eb3cSopenharmony_ci            CHECK_NULL_VOID(object);
20123b3eb3cSopenharmony_ci            AAFwk::IInteger *value = AAFwk::IInteger::Query(object);
20223b3eb3cSopenharmony_ci            CHECK_NULL_VOID(value);
20323b3eb3cSopenharmony_ci            array.emplace_back(AAFwk::Integer::Unbox(value));
20423b3eb3cSopenharmony_ci        };
20523b3eb3cSopenharmony_ci        AAFwk::Array::ForEach(ao, func);
20623b3eb3cSopenharmony_ci    }
20723b3eb3cSopenharmony_ci    return array;
20823b3eb3cSopenharmony_ci}
20923b3eb3cSopenharmony_ci
21023b3eb3cSopenharmony_cibool AIWriteAdapter::GetBoolParam(const std::string& key, const AAFwk::WantParams& wantParams)
21123b3eb3cSopenharmony_ci{
21223b3eb3cSopenharmony_ci    auto value = wantParams.GetParam(key);
21323b3eb3cSopenharmony_ci    AAFwk::IBoolean *bo = AAFwk::IBoolean::Query(value);
21423b3eb3cSopenharmony_ci    if (bo != nullptr) {
21523b3eb3cSopenharmony_ci        return AAFwk::Boolean::Unbox(bo);
21623b3eb3cSopenharmony_ci    }
21723b3eb3cSopenharmony_ci    return false;
21823b3eb3cSopenharmony_ci}
21923b3eb3cSopenharmony_ci}