* 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 "securec.h"
#include "global.h"
#include "native_inputmethod_types.h"
#include "string_utils.h"
#ifdef __cplusplus
extern "C" {
#endif
using namespace OHOS::MiscServices;
InputMethod_TextConfig *OH_TextConfig_Create(void)
{
return new (std::nothrow) InputMethod_TextConfig();
}
void OH_TextConfig_Destroy(InputMethod_TextConfig *config)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return;
}
delete config;
}
InputMethod_ErrorCode OH_TextConfig_SetInputType(InputMethod_TextConfig *config, InputMethod_TextInputType inputType)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
config->inputType = inputType;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_SetEnterKeyType(
InputMethod_TextConfig *config, InputMethod_EnterKeyType enterKeyType)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
config->enterKeyType = enterKeyType;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_SetPreviewTextSupport(InputMethod_TextConfig *config, bool supported)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
config->previewTextSupported = supported;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_SetSelection(InputMethod_TextConfig *config, int32_t start, int32_t end)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
config->selectionStart = start;
config->selectionEnd = end;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_SetWindowId(InputMethod_TextConfig *config, int32_t windowId)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
config->windowId = windowId;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_SetPlaceholder(InputMethod_TextConfig *config, const char16_t *placeholder,
size_t length)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
if (length <= 0 || placeholder == nullptr) {
config->placeholderLength = ENDING_SYMBOL_SIZE;
config->placeholder[0] = UTF16_ENDING_SYMBOL;
return IME_ERR_OK;
}
if (length == 1 && placeholder[length - 1] == UTF16_ENDING_SYMBOL) {
config->placeholderLength = ENDING_SYMBOL_SIZE;
config->placeholder[0] = UTF16_ENDING_SYMBOL;
return IME_ERR_OK;
}
if (length > MAX_PLACEHOLDER_INPUT_SIZE) {
IMSA_HILOGW("chars length exceeds limit inputLen:%{public}zu, limit len:%{public}zu", length,
MAX_PLACEHOLDER_INPUT_SIZE);
length = MAX_PLACEHOLDER_INPUT_SIZE;
}
std::u16string u16Placeholder(placeholder, length);
StringUtils::TruncateUtf16String(u16Placeholder, MAX_PLACEHOLDER_SIZE);
IMSA_HILOGD("memcpy_s begin dest len:%{public}zu, src len:%{public}zu",
MAX_PLACEHOLDER_INPUT_SIZE, u16Placeholder.size());
if (u16Placeholder.size() > MAX_PLACEHOLDER_INPUT_SIZE) {
IMSA_HILOGE("function truncateUtf16String error");
return IME_ERR_NULL_POINTER;
}
errno_t err = memcpy_s(config->placeholder, MAX_PLACEHOLDER_INPUT_SIZE * sizeof(char16_t),
u16Placeholder.data(), u16Placeholder.size() * sizeof(char16_t));
if (err != EOK) {
IMSA_HILOGE("placeholder content copy error:%{public}d", (int32_t)err);
return IME_ERR_NULL_POINTER;
}
config->placeholderLength = u16Placeholder.size();
if (config->placeholder[config->placeholderLength - 1] != UTF16_ENDING_SYMBOL &&
config->placeholderLength < MAX_PLACEHOLDER_INPUT_SIZE) {
config->placeholder[config->placeholderLength] = UTF16_ENDING_SYMBOL;
config->placeholderLength = config->placeholderLength + 1;
}
IMSA_HILOGD("placeholderLength:%{public}zu,length:%{public}zu,lastChar16_t:%{public}u",
config->placeholderLength, length,
static_cast<uint32_t>(config->placeholder[config->placeholderLength - 1]));
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_SetAbilityName(InputMethod_TextConfig *config, const char16_t *abilityName,
size_t length)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
if (length <= 0 || abilityName == nullptr) {
config->abilityNameLength = ENDING_SYMBOL_SIZE;
config->abilityName[0] = UTF16_ENDING_SYMBOL;
return IME_ERR_OK;
}
if (length == 1 && abilityName[length - 1] == UTF16_ENDING_SYMBOL) {
config->abilityNameLength = ENDING_SYMBOL_SIZE;
config->abilityName[0] = UTF16_ENDING_SYMBOL;
return IME_ERR_OK;
}
if (length > MAX_ABILITY_NAME_INPUT_SIZE) {
IMSA_HILOGW("chars length exceeds limit inputLen:%{public}zu, limit len:%{public}zu", length,
MAX_ABILITY_NAME_INPUT_SIZE);
length = MAX_ABILITY_NAME_INPUT_SIZE;
}
std::u16string u16abilityName(abilityName, length);
StringUtils::TruncateUtf16String(u16abilityName, MAX_ABILITY_NAME_SIZE);
IMSA_HILOGD("memcpy_s begin dest len:%{public}zu, src len:%{public}zu",
MAX_ABILITY_NAME_INPUT_SIZE, u16abilityName.size());
if (u16abilityName.size() > MAX_ABILITY_NAME_INPUT_SIZE) {
IMSA_HILOGE("function truncateUtf16String error");
return IME_ERR_NULL_POINTER;
}
errno_t err = memcpy_s(config->abilityName, MAX_ABILITY_NAME_INPUT_SIZE * sizeof(char16_t),
u16abilityName.data(), u16abilityName.size() * sizeof(char16_t));
if (err != EOK) {
IMSA_HILOGE("abilityName content copy error:%{public}d", (int32_t)err);
return IME_ERR_NULL_POINTER;
}
config->abilityNameLength = u16abilityName.size();
if (config->abilityName[config->abilityNameLength - 1] != UTF16_ENDING_SYMBOL &&
config->abilityNameLength < MAX_ABILITY_NAME_INPUT_SIZE) {
config->abilityName[config->abilityNameLength] = UTF16_ENDING_SYMBOL;
config->abilityNameLength = config->abilityNameLength + 1;
}
IMSA_HILOGD("abilityNameLength:%{public}zu,length:%{public}zu,lastChar16_t:%{public}u",
config->abilityNameLength, length,
static_cast<uint32_t>(config->abilityName[config->abilityNameLength - 1]));
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_SetConsumeKeyEvents(InputMethod_TextConfig *config, bool consumeKeyEvents)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
config->consumeKeyEvents = consumeKeyEvents;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_GetInputType(InputMethod_TextConfig *config, InputMethod_TextInputType *inputType)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
if (inputType == nullptr) {
IMSA_HILOGE("inputType is nullptr");
return IME_ERR_NULL_POINTER;
}
*inputType = config->inputType;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_GetEnterKeyType(
InputMethod_TextConfig *config, InputMethod_EnterKeyType *enterKeyType)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
if (enterKeyType == nullptr) {
IMSA_HILOGE("enterKeyType is nullptr");
return IME_ERR_NULL_POINTER;
}
*enterKeyType = config->enterKeyType;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_IsPreviewTextSupported(InputMethod_TextConfig *config, bool *supported)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
if (supported == nullptr) {
IMSA_HILOGE("supported is nullptr");
return IME_ERR_NULL_POINTER;
}
*supported = config->previewTextSupported;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_GetCursorInfo(InputMethod_TextConfig *config, InputMethod_CursorInfo **cursorInfo)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
if (cursorInfo == nullptr) {
IMSA_HILOGE("cursorInfo is nullptr");
return IME_ERR_NULL_POINTER;
}
*cursorInfo = &config->cursorInfo;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_GetTextAvoidInfo(
InputMethod_TextConfig *config, InputMethod_TextAvoidInfo **avoidInfo)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
if (avoidInfo == nullptr) {
IMSA_HILOGE("avoidInfo is nullptr");
return IME_ERR_NULL_POINTER;
}
*avoidInfo = &config->avoidInfo;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_GetSelection(InputMethod_TextConfig *config, int32_t *start, int32_t *end)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
if (start == nullptr) {
IMSA_HILOGE("start is nullptr");
return IME_ERR_NULL_POINTER;
}
if (end == nullptr) {
IMSA_HILOGE("end is nullptr");
return IME_ERR_NULL_POINTER;
}
*start = config->selectionStart;
*end = config->selectionEnd;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_GetWindowId(InputMethod_TextConfig *config, int32_t *windowId)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
if (windowId == nullptr) {
IMSA_HILOGE("windowId is nullptr");
return IME_ERR_NULL_POINTER;
}
*windowId = config->windowId;
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_GetPlaceholder(InputMethod_TextConfig *config, char16_t *placeholder,
size_t *length)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
if (length == nullptr) {
IMSA_HILOGE("length is nullptr");
return IME_ERR_NULL_POINTER;
}
if (config->placeholderLength <= ENDING_SYMBOL_SIZE) {
config->placeholderLength = ENDING_SYMBOL_SIZE;
config->placeholder[0] = UTF16_ENDING_SYMBOL;
}
IMSA_HILOGD("curLen:%{public}zu,inputLen:%{public}zu", config->placeholderLength, *length);
if (placeholder == nullptr) {
IMSA_HILOGE("placeholder is nullptr");
*length = config->placeholderLength;
return IME_ERR_NULL_POINTER;
}
if ((*length) < config->placeholderLength) {
IMSA_HILOGE("input memory is less than the length of the obtained memory. actual length:%{public}zu",
config->placeholderLength);
*length = config->placeholderLength;
return IME_ERR_PARAMCHECK;
}
auto byteLen = (*length) * sizeof(char16_t);
*length = config->placeholderLength;
errno_t err = memcpy_s(placeholder, byteLen, config->placeholder, config->placeholderLength * sizeof(char16_t));
if (err != EOK) {
IMSA_HILOGE("placeholder content copy error:%{public}d", (int32_t)err);
return IME_ERR_PARAMCHECK;
}
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_GetAbilityName(InputMethod_TextConfig *config, char16_t *abilityName,
size_t *length)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
if (length == nullptr) {
IMSA_HILOGE("length is nullptr");
return IME_ERR_NULL_POINTER;
}
if (abilityName == nullptr) {
IMSA_HILOGE("abilityName is nullptr");
*length = config->abilityNameLength;
return IME_ERR_NULL_POINTER;
}
if (config->abilityNameLength <= ENDING_SYMBOL_SIZE) {
config->abilityNameLength = ENDING_SYMBOL_SIZE;
config->abilityName[0] = UTF16_ENDING_SYMBOL;
}
IMSA_HILOGD("curLen:%{public}zu,inputLen:%{public}zu", config->abilityNameLength, *length);
if ((*length) < config->abilityNameLength) {
IMSA_HILOGE("input memory is less than the length of the obtained memory. actual length:%{public}zu",
config->abilityNameLength);
*length = config->abilityNameLength;
return IME_ERR_PARAMCHECK;
}
auto byteLen = (*length) * sizeof(char16_t);
*length = config->abilityNameLength;
errno_t err = memcpy_s(abilityName, byteLen, config->abilityName, config->abilityNameLength * sizeof(char16_t));
if (err != EOK) {
IMSA_HILOGE("abilityName content copy error:%{public}d", (int32_t)err);
return IME_ERR_PARAMCHECK;
}
return IME_ERR_OK;
}
InputMethod_ErrorCode OH_TextConfig_GetConsumeKeyEvents(InputMethod_TextConfig *config, bool *consumeKeyEvents)
{
if (config == nullptr) {
IMSA_HILOGE("config is nullptr");
return IME_ERR_NULL_POINTER;
}
if (consumeKeyEvents == nullptr) {
IMSA_HILOGE("supported is nullptr");
return IME_ERR_NULL_POINTER;
}
*consumeKeyEvents = config->consumeKeyEvents;
return IME_ERR_OK;
}
#ifdef __cplusplus
}
#endif