11401458bSopenharmony_ci/*
21401458bSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
31401458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
41401458bSopenharmony_ci * you may not use this file except in compliance with the License.
51401458bSopenharmony_ci * You may obtain a copy of the License at
61401458bSopenharmony_ci *
71401458bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
81401458bSopenharmony_ci *
91401458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
101401458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
111401458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121401458bSopenharmony_ci * See the License for the specific language governing permissions and
131401458bSopenharmony_ci * limitations under the License.
141401458bSopenharmony_ci */
151401458bSopenharmony_ci
161401458bSopenharmony_ci#include "ash_mem_utils.h"
171401458bSopenharmony_ci
181401458bSopenharmony_ci#include <string>
191401458bSopenharmony_ci
201401458bSopenharmony_ci#include "hilog/log.h"
211401458bSopenharmony_ci#include "string_ex.h"
221401458bSopenharmony_ci
231401458bSopenharmony_ci#undef LOG_DOMAIN
241401458bSopenharmony_ci#define LOG_DOMAIN 0xD002D08
251401458bSopenharmony_ci
261401458bSopenharmony_ci#undef LOG_TAG
271401458bSopenharmony_ci#define LOG_TAG "HISYSEVENT_MEMORY_UTILS"
281401458bSopenharmony_ci
291401458bSopenharmony_cinamespace OHOS {
301401458bSopenharmony_cinamespace HiviewDFX {
311401458bSopenharmony_cinamespace {
321401458bSopenharmony_ciconstexpr char ASH_MEM_NAME[] = "HiSysEventService SharedMemory";
331401458bSopenharmony_ciconstexpr int32_t ASH_MEM_SIZE = 1024 * 769; // 769k
341401458bSopenharmony_ci
351401458bSopenharmony_civoid ParseAllStringItemSize(const std::vector<std::u16string>& data, std::vector<std::string>& translatedData,
361401458bSopenharmony_ci    std::vector<uint32_t>& allSize)
371401458bSopenharmony_ci{
381401458bSopenharmony_ci    for (auto& item : data) {
391401458bSopenharmony_ci        auto translated = Str16ToStr8(item);
401401458bSopenharmony_ci        translatedData.emplace_back(translated);
411401458bSopenharmony_ci        allSize.emplace_back(strlen(translated.c_str()) + 1);
421401458bSopenharmony_ci    }
431401458bSopenharmony_ci}
441401458bSopenharmony_ci}
451401458bSopenharmony_ci
461401458bSopenharmony_cisptr<Ashmem> AshMemUtils::GetAshmem()
471401458bSopenharmony_ci{
481401458bSopenharmony_ci    auto ashmem = Ashmem::CreateAshmem(ASH_MEM_NAME, ASH_MEM_SIZE);
491401458bSopenharmony_ci    if (ashmem == nullptr) {
501401458bSopenharmony_ci        HILOG_ERROR(LOG_CORE, "ashmem init failed.");
511401458bSopenharmony_ci        return ashmem;
521401458bSopenharmony_ci    }
531401458bSopenharmony_ci    if (!ashmem->MapReadAndWriteAshmem()) {
541401458bSopenharmony_ci        HILOG_ERROR(LOG_CORE, "ashmem map failed.");
551401458bSopenharmony_ci        return ashmem;
561401458bSopenharmony_ci    }
571401458bSopenharmony_ci    HILOG_DEBUG(LOG_CORE, "ashmem init succeed.");
581401458bSopenharmony_ci    return ashmem;
591401458bSopenharmony_ci}
601401458bSopenharmony_ci
611401458bSopenharmony_civoid AshMemUtils::CloseAshmem(sptr<Ashmem> ashmem)
621401458bSopenharmony_ci{
631401458bSopenharmony_ci    if (ashmem != nullptr) {
641401458bSopenharmony_ci        ashmem->UnmapAshmem();
651401458bSopenharmony_ci        ashmem->CloseAshmem();
661401458bSopenharmony_ci    }
671401458bSopenharmony_ci    HILOG_DEBUG(LOG_CORE, "ashmem closed.");
681401458bSopenharmony_ci}
691401458bSopenharmony_ci
701401458bSopenharmony_cisptr<Ashmem> AshMemUtils::WriteBulkData(MessageParcel& parcel, const std::vector<std::u16string>& src)
711401458bSopenharmony_ci{
721401458bSopenharmony_ci    std::vector<std::string> allData;
731401458bSopenharmony_ci    std::vector<uint32_t> allSize;
741401458bSopenharmony_ci    ParseAllStringItemSize(src, allData, allSize);
751401458bSopenharmony_ci    if (!parcel.WriteUInt32Vector(allSize)) {
761401458bSopenharmony_ci        HILOG_ERROR(LOG_CORE, "writing allSize array failed.");
771401458bSopenharmony_ci        return nullptr;
781401458bSopenharmony_ci    }
791401458bSopenharmony_ci    auto ashmem = GetAshmem();
801401458bSopenharmony_ci    if (ashmem == nullptr) {
811401458bSopenharmony_ci        return nullptr;
821401458bSopenharmony_ci    }
831401458bSopenharmony_ci    uint32_t offset = 0;
841401458bSopenharmony_ci    for (uint32_t i = 0; i < allData.size(); i++) {
851401458bSopenharmony_ci        auto translated = allData[i].c_str();
861401458bSopenharmony_ci        if (!ashmem->WriteToAshmem(translated, strlen(translated), offset)) {
871401458bSopenharmony_ci            HILOG_ERROR(LOG_CORE, "writing ashmem failed.");
881401458bSopenharmony_ci            CloseAshmem(ashmem);
891401458bSopenharmony_ci            return nullptr;
901401458bSopenharmony_ci        }
911401458bSopenharmony_ci        offset += allSize[i];
921401458bSopenharmony_ci    }
931401458bSopenharmony_ci    if (!parcel.WriteAshmem(ashmem)) {
941401458bSopenharmony_ci        HILOG_ERROR(LOG_CORE, "writing ashmem failed.");
951401458bSopenharmony_ci        CloseAshmem(ashmem);
961401458bSopenharmony_ci        return nullptr;
971401458bSopenharmony_ci    }
981401458bSopenharmony_ci    return ashmem;
991401458bSopenharmony_ci}
1001401458bSopenharmony_ci
1011401458bSopenharmony_cibool AshMemUtils::ReadBulkData(MessageParcel& parcel, std::vector<std::u16string>& dest)
1021401458bSopenharmony_ci{
1031401458bSopenharmony_ci    std::vector<uint32_t> allSize;
1041401458bSopenharmony_ci    if (!parcel.ReadUInt32Vector(&allSize)) {
1051401458bSopenharmony_ci        HILOG_ERROR(LOG_CORE, "reading allSize array failed.");
1061401458bSopenharmony_ci        return false;
1071401458bSopenharmony_ci    }
1081401458bSopenharmony_ci    auto ashmem = parcel.ReadAshmem();
1091401458bSopenharmony_ci    if (ashmem == nullptr) {
1101401458bSopenharmony_ci        HILOG_ERROR(LOG_CORE, "reading ashmem failed.");
1111401458bSopenharmony_ci        return false;
1121401458bSopenharmony_ci    }
1131401458bSopenharmony_ci    bool ret = ashmem->MapReadAndWriteAshmem();
1141401458bSopenharmony_ci    if (!ret) {
1151401458bSopenharmony_ci        HILOG_ERROR(LOG_CORE, "mapping read only ashmem failed.");
1161401458bSopenharmony_ci        CloseAshmem(ashmem);
1171401458bSopenharmony_ci        return false;
1181401458bSopenharmony_ci    }
1191401458bSopenharmony_ci    uint32_t offset = 0;
1201401458bSopenharmony_ci    for (uint32_t i = 0; i < allSize.size(); i++) {
1211401458bSopenharmony_ci        auto origin = ashmem->ReadFromAshmem(allSize[i], offset);
1221401458bSopenharmony_ci        dest.emplace_back(Str8ToStr16(std::string(reinterpret_cast<const char*>(origin))));
1231401458bSopenharmony_ci        offset += allSize[i];
1241401458bSopenharmony_ci    }
1251401458bSopenharmony_ci    CloseAshmem(ashmem);
1261401458bSopenharmony_ci    return true;
1271401458bSopenharmony_ci}
1281401458bSopenharmony_ci} // namespace HiviewDFX
1291401458bSopenharmony_ci} // namespace OHOS
130