/* * 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 "parameter_parse.h" #include "native_log.h" #include "int_wrapper.h" #include "double_wrapper.h" #include "string_wrapper.h" #include "bool_wrapper.h" #include "long_wrapper.h" #include "array_wrapper.h" #include "want_params_wrapper.h" #include "securec.h" #include namespace OHOS::CommonEventManager { const char *FD = "FD"; const char *REMOTE_OBJECT = "RemoteObject"; const char *TYPE_PROPERTY = "type"; const char *VALUE_PROPERTY = "value"; const int8_t I32_TYPE = 0; const int8_t DOUBLE_TYPE = 1; const int8_t STR_TYPE = 2; const int8_t BOOL_TYPE = 3; const int8_t FD_TYPE = 4; const int8_t STR_PTR_TYPE = 5; const int8_t I32_PTR_TYPE = 6; const int8_t I64_PTR_TYPE = 7; const int8_t BOOL_PTR_TYPE = 8; const int8_t DOUBLE_PTR_TYPE = 9; const int8_t FD_PTR_TYPE = 10; const int32_t NONE_VALUE = 1; using Want = OHOS::AAFwk::Want; using WantParams = OHOS::AAFwk::WantParams; void charPtrToVector(char **charPtr, int size, std::vector &result) { for (int i = 0; i < size; i++) { result.push_back(std::string(charPtr[i])); } } void SetFdData(std::string key, int *value, WantParams &wantP) { WantParams wp; wp.SetParam(TYPE_PROPERTY, OHOS::AAFwk::String::Box(FD)); wp.SetParam(VALUE_PROPERTY, OHOS::AAFwk::Integer::Box(*value)); sptr pWantParams = OHOS::AAFwk::WantParamWrapper::Box(wp); wantP.SetParam(key, pWantParams); } bool InnerSetWantParamsArrayString( const std::string &key, const std::vector &value, AAFwk::WantParams &wantParams) { size_t size = value.size(); sptr ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IString); if (ao != nullptr) { for (size_t i = 0; i < size; i++) { ao->Set(i, AAFwk::String::Box(value[i])); } wantParams.SetParam(key, ao); return true; } else { return false; } } bool InnerSetWantParamsArrayInt(const std::string &key, const std::vector &value, AAFwk::WantParams &wantParams) { size_t size = value.size(); sptr ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IInteger); if (ao != nullptr) { for (size_t i = 0; i < size; i++) { ao->Set(i, AAFwk::Integer::Box(value[i])); } wantParams.SetParam(key, ao); return true; } else { return false; } } bool InnerSetWantParamsArrayLong(const std::string &key, const std::vector &value, AAFwk::WantParams &wantParams) { size_t size = value.size(); sptr ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_ILong); if (ao != nullptr) { for (size_t i = 0; i < size; i++) { ao->Set(i, AAFwk::Long::Box(value[i])); } wantParams.SetParam(key, ao); return true; } else { return false; } } bool InnerSetWantParamsArrayBool(const std::string &key, const std::vector &value, AAFwk::WantParams &wantParams) { size_t size = value.size(); sptr ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IBoolean); if (ao != nullptr) { for (size_t i = 0; i < size; i++) { ao->Set(i, AAFwk::Boolean::Box(value[i])); } wantParams.SetParam(key, ao); return true; } else { return false; } } bool InnerSetWantParamsArrayDouble( const std::string &key, const std::vector &value, AAFwk::WantParams &wantParams) { size_t size = value.size(); sptr ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IDouble); if (ao != nullptr) { for (size_t i = 0; i < size; i++) { ao->Set(i, AAFwk::Double::Box(value[i])); } wantParams.SetParam(key, ao); return true; } else { return false; } } void InnerSetWantParamsArrayFD(CParameters* head, int64_t size, AAFwk::WantParams &wantParams) { sptr ao = new (std::nothrow) AAFwk::Array(size, AAFwk::g_IID_IWantParams); if (ao != nullptr) { for (size_t i = 0; i < static_cast(size); i++) { WantParams wp; SetFdData(std::string(head->key), static_cast(head->value) + i, wp); wp.DumpInfo(0); ao->Set(i, OHOS::AAFwk::WantParamWrapper::Box(wp)); } wantParams.SetParam(std::string(head->key), ao); } return; } void SetDataParameters(CArrParameters parameters, WantParams &wantP) { for (int i = 0; i < parameters.size; i++) { auto head = parameters.head + i; auto key = std::string(head->key); if (head->valueType == I32_TYPE) { // int32_t wantP.SetParam(key, OHOS::AAFwk::Integer::Box(*static_cast(head->value))); } else if (head->valueType == DOUBLE_TYPE) { // double wantP.SetParam(key, OHOS::AAFwk::Double::Box(*static_cast(head->value))); } else if (head->valueType == STR_TYPE) { // std::string wantP.SetParam(key, OHOS::AAFwk::String::Box(std::string(static_cast(head->value)))); } else if (head->valueType == BOOL_TYPE) { // bool wantP.SetParam(key, OHOS::AAFwk::Boolean::Box(*static_cast(head->value))); } else if (head->valueType == FD_TYPE) { // "FD" SetFdData(key, static_cast(head->value), wantP); } else if (head->valueType == STR_PTR_TYPE) { // char** char **strPtr = static_cast(head->value); std::vector strVec; charPtrToVector(strPtr, head->size, strVec); InnerSetWantParamsArrayString(key, strVec, wantP); } else if (head->valueType == I32_PTR_TYPE) { // int32_t* int *intArr = static_cast(head->value); std::vector intVec(intArr, intArr + head->size); InnerSetWantParamsArrayInt(key, intVec, wantP); } else if (head->valueType == I64_PTR_TYPE) { // int64_t* long *longArr = static_cast(head->value); std::vector longVec(longArr, longArr + head->size); InnerSetWantParamsArrayLong(key, longVec, wantP); } else if (head->valueType == BOOL_PTR_TYPE) { // bool* bool *boolArr = static_cast(head->value); std::vector boolVec(boolArr, boolArr + head->size); InnerSetWantParamsArrayBool(key, boolVec, wantP); } else if (head->valueType == DOUBLE_PTR_TYPE) { // double* double *doubleArr = static_cast(head->value); std::vector doubleVec(doubleArr, doubleArr + head->size); InnerSetWantParamsArrayDouble(key, doubleVec, wantP); } else if (head->valueType == FD_PTR_TYPE) { // FD* InnerSetWantParamsArrayFD(head, head->size, wantP); } else { LOGE("Wrong type!"); } } } char *MallocCString(const std::string &origin) { if (origin.empty()) { return nullptr; } auto len = origin.length() + 1; char *res = static_cast(malloc(sizeof(char) * len)); if (res == nullptr) { return nullptr; } return std::char_traits::copy(res, origin.c_str(), len); } char *MallocCString(const std::string &origin, int32_t &code) { if (origin.empty() || code != NO_ERROR) { return nullptr; } auto len = origin.length() + 1; char *res = static_cast(malloc(sizeof(char) * len)); if (res == nullptr) { code = ERR_NO_MEMORY; return nullptr; } return std::char_traits::copy(res, origin.c_str(), len); } // WantParameters -> CArrParameters int32_t InnerWrapWantParamsString(WantParams &wantParams, CParameters *p) { auto value = wantParams.GetParam(p->key); AAFwk::IString *ao = AAFwk::IString::Query(value); if (ao == nullptr) { LOGE("No value"); return NONE_VALUE; } std::string natValue = OHOS::AAFwk::String::Unbox(ao); p->value = MallocCString(natValue); p->size = static_cast(natValue.length()) + 1; p->valueType = STR_TYPE; return NO_ERROR; } template int32_t InnerWrapWantParamsT(WantParams &wantParams, CParameters *p) { auto value = wantParams.GetParam(p->key); TBase *ao = TBase::Query(value); if (ao == nullptr) { LOGE("No value"); return NONE_VALUE; } NativeT natValue = T::Unbox(ao); NativeT *ptr = static_cast(malloc(sizeof(NativeT))); if (ptr == nullptr) { return ERR_NO_MEMORY; } *ptr = natValue; p->value = static_cast(ptr); p->size = sizeof(NativeT); return NO_ERROR; } int32_t InnerWrapWantParamsArrayString(sptr &ao, CParameters *p) { long size = 0; if (ao->GetLength(size) != ERR_OK) { LOGE("fail to get length"); return ERR_CES_FAILED; } if (size == 0) { return ERR_CES_FAILED; } char **arrP = static_cast(malloc(sizeof(char *) * size)); if (arrP == nullptr) { LOGE("fail to malloc"); return ERR_NO_MEMORY; } for (long i = 0; i < size; i++) { sptr iface = nullptr; if (ao->Get(i, iface) == ERR_OK) { AAFwk::IString *iValue = AAFwk::IString::Query(iface); if (iValue != nullptr) { auto val = AAFwk::String::Unbox(iValue); arrP[i] = MallocCString(val); } } } p->size = size; p->value = static_cast(arrP); return NO_ERROR; } void ClearParametersPtr(CParameters **ptr, int count, bool isKey) { CParameters *p = *ptr; for (int i = 0; i < count; i++) { free(p[i].key); free(p[i].value); p[i].key = nullptr; p[i].value = nullptr; } if (!isKey) { free(p[count].key); p[count].key = nullptr; } free(*ptr); *ptr = nullptr; } template int32_t InnerWrapWantParamsArrayT(sptr &ao, CParameters *p) { long size = 0; if (ao->GetLength(size) != ERR_OK) { LOGE("fail to get length"); return ERR_CES_FAILED; } if (size == 0) { return ERR_CES_FAILED; } NativeT *arrP = static_cast(malloc(sizeof(NativeT) * size)); if (arrP == nullptr) { LOGE("fail to malloc"); return ERR_NO_MEMORY; } for (long i = 0; i < size; i++) { sptr iface = nullptr; if (ao->Get(i, iface) == ERR_OK) { TBase *iValue = TBase::Query(iface); if (iValue != nullptr) { arrP[i] = T::Unbox(iValue); } } } p->size = size; p->value = static_cast(arrP); return NO_ERROR; } int32_t GetFDValue(WantParams &wantParams, std::string key, int *ptr) { auto value = wantParams.GetParam(key); AAFwk::IWantParams *o = AAFwk::IWantParams::Query(value); if (o == nullptr) { return NONE_VALUE; } AAFwk::WantParams wp = AAFwk::WantParamWrapper::Unbox(o); value = wp.GetParam(VALUE_PROPERTY); AAFwk::IInteger *ao = AAFwk::IInteger::Query(value); if (ao == nullptr) { LOGE("No value"); return NONE_VALUE; } *ptr = OHOS::AAFwk::Integer::Unbox(ao); return NO_ERROR; } int32_t InnerWrapWantParamsFd(WantParams &wantParams, CParameters *p) { int *ptr = static_cast(malloc(sizeof(int))); if (ptr == nullptr) { return ERR_NO_MEMORY; } int error = GetFDValue(wantParams, std::string(p->key), ptr); if (error != NO_ERROR) { free(ptr); return error; } p->value = static_cast(ptr); p->size = sizeof(int32_t); p->valueType = FD_TYPE; return NO_ERROR; } int32_t InnerWrapWantParamsArrayFd(sptr &ao, CParameters *p) { long size = 0; if (ao->GetLength(size) != ERR_OK) { LOGE("fail to get length"); return ERR_CES_FAILED; } if (size == 0) { return ERR_CES_FAILED; } int *arrP = static_cast(malloc(sizeof(int) * size)); if (arrP == nullptr) { LOGE("fail to malloc"); return ERR_NO_MEMORY; } for (long i = 0; i < size; i++) { sptr iface = nullptr; if (ao->Get(i, iface) == ERR_OK) { AAFwk::IWantParams *iValue = AAFwk::IWantParams::Query(iface); if (iValue == nullptr) { free(arrP); return ERR_CES_FAILED; } WantParams wantP = AAFwk::WantParamWrapper::Unbox(iValue); int ret = GetFDValue(wantP, std::string(p->key), arrP + i); if (ret != NO_ERROR) { free(arrP); return ret; } } } p->size = size; p->value = arrP; p->valueType = FD_PTR_TYPE; return NO_ERROR; } int32_t InnerWrapWantParamsArray(WantParams &wantParams, sptr &ao, CParameters *p) { LOGI("%{public}s called. key=%{public}s", __func__, p->key); if (AAFwk::Array::IsStringArray(ao)) { p->valueType = STR_PTR_TYPE; return InnerWrapWantParamsArrayString(ao, p); } else if (AAFwk::Array::IsBooleanArray(ao)) { p->valueType = BOOL_PTR_TYPE; return InnerWrapWantParamsArrayT(ao, p); } else if (AAFwk::Array::IsIntegerArray(ao)) { p->valueType = I32_PTR_TYPE; return InnerWrapWantParamsArrayT(ao, p); } else if (AAFwk::Array::IsLongArray(ao)) { p->valueType = I64_PTR_TYPE; return InnerWrapWantParamsArrayT(ao, p); } else if (AAFwk::Array::IsDoubleArray(ao)) { p->valueType = DOUBLE_PTR_TYPE; return InnerWrapWantParamsArrayT(ao, p); } else { p->valueType = FD_PTR_TYPE; return InnerWrapWantParamsArrayFd(ao, p); } } void ParseParameters(Want &want, CCommonEventData &cData, int32_t &code) { if (code != NO_ERROR) { return; } WantParams wantP = want.GetParams(); std::map> paramsMap = wantP.GetParams(); int count = 0; auto size = static_cast(paramsMap.size()); LOGD("paramsMap size = %{public}" PRId64, size); if (size == 0) { return; } cData.parameters.head = static_cast(malloc(sizeof(CParameters) * size)); if (cData.parameters.head == nullptr) { return; } cData.parameters.size = size; for (auto iter = paramsMap.begin(); iter != paramsMap.end(); iter++) { auto ptr = cData.parameters.head + count; ptr->key = MallocCString(iter->first); if (ptr->key == nullptr) { code = ERR_NO_MEMORY; return ClearParametersPtr(&cData.parameters.head, count, true); } ptr->value = nullptr; ptr->size = 0; if (AAFwk::IString::Query(iter->second) != nullptr) { code = InnerWrapWantParamsString(wantP, ptr); } else if (AAFwk::IBoolean::Query(iter->second) != nullptr) { ptr->valueType = BOOL_TYPE; code = InnerWrapWantParamsT(wantP, ptr); } else if (AAFwk::IInteger::Query(iter->second) != nullptr) { ptr->valueType = I32_TYPE; code = InnerWrapWantParamsT(wantP, ptr); } else if (AAFwk::IDouble::Query(iter->second) != nullptr) { ptr->valueType = DOUBLE_TYPE; code = InnerWrapWantParamsT(wantP, ptr); } else if (AAFwk::IWantParams::Query(iter->second) != nullptr) { code = InnerWrapWantParamsFd(wantP, ptr); } else if (AAFwk::IArray::Query(iter->second) != nullptr) { AAFwk::IArray *ao = AAFwk::IArray::Query(iter->second); sptr array(ao); code = InnerWrapWantParamsArray(wantP, array, ptr); } if (code == ERR_NO_MEMORY || code == ERR_CES_FAILED) { return ClearParametersPtr(&cData.parameters.head, count, true); } count++; } } void FreeCCommonEventDataCharPtr(CCommonEventData &cData) { free(cData.data); free(cData.event); free(cData.bundleName); cData.data = nullptr; cData.event = nullptr; cData.bundleName = nullptr; } int32_t GetCommonEventData(const CommonEventData &data, CCommonEventData &cData) { auto want = data.GetWant(); cData.code = data.GetCode(); int32_t code = NO_ERROR; cData.data = MallocCString(data.GetData(), code); cData.event = MallocCString(want.GetAction(), code); cData.bundleName = MallocCString(want.GetBundle(), code); ParseParameters(want, cData, code); if (code == ERR_NO_MEMORY || code == ERR_CES_FAILED) { FreeCCommonEventDataCharPtr(cData); } return code; } }