1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "data_operation_callback.h"
16 #include "intell_voice_log.h"
17 #include "huks_aes_adapter.h"
18 #include "scope_guard.h"
19
20 #define LOG_TAG "DataOperationCb"
21
22 using namespace OHOS::IntellVoiceUtils;
23
24 namespace OHOS {
25 namespace IntellVoiceEngine {
OnIntellVoiceDataOprEvent(OHOS::HDI::IntelligentVoice::Engine::V1_1::IntellVoiceDataOprType type,const sptr<Ashmem> & inBuffer,sptr<Ashmem> & outBuffer)26 int32_t DataOperationCallback::OnIntellVoiceDataOprEvent(
27 OHOS::HDI::IntelligentVoice::Engine::V1_1::IntellVoiceDataOprType type,
28 const sptr<Ashmem> &inBuffer,
29 sptr<Ashmem> &outBuffer)
30 {
31 INTELL_VOICE_LOG_INFO("enter, type:%{public}d", type);
32 if (inBuffer == nullptr) {
33 INTELL_VOICE_LOG_ERROR("in buffer is nullptr");
34 return -1;
35 }
36
37 ON_SCOPE_EXIT {
38 INTELL_VOICE_LOG_INFO("clear ashmem");
39 inBuffer->UnmapAshmem();
40 inBuffer->CloseAshmem();
41 };
42
43 if ((type < OHOS::HDI::IntelligentVoice::Engine::V1_1::ENCRYPT_TYPE) ||
44 (type > OHOS::HDI::IntelligentVoice::Engine::V1_1::DECRYPT_TYPE)) {
45 INTELL_VOICE_LOG_ERROR("invalid type:%{public}d", type);
46 return -1;
47 }
48
49 auto inData = CreateArrayBufferFromAshmem(inBuffer);
50 if (inData == nullptr) {
51 INTELL_VOICE_LOG_ERROR("create in data failed");
52 return -1;
53 }
54
55 int32_t ret = HKS_SUCCESS;
56 std::unique_ptr<OHOS::IntellVoiceUtils::Uint8ArrayBuffer> outData = nullptr;
57
58 if (type == OHOS::HDI::IntelligentVoice::Engine::V1_1::ENCRYPT_TYPE) {
59 ret = HuksAesAdapter::Encrypt(inData, outData);
60 if (ret != HKS_SUCCESS) {
61 INTELL_VOICE_LOG_ERROR("encrypt failed, ret:%{public}d", ret);
62 return -1;
63 }
64 outBuffer = CreateAshmemFromArrayBuffer(outData, "EnryptOutIntellVoiceData");
65 } else if (type == OHOS::HDI::IntelligentVoice::Engine::V1_1::DECRYPT_TYPE) {
66 ret = HuksAesAdapter::Decrypt(inData, outData);
67 if (ret != HKS_SUCCESS) {
68 INTELL_VOICE_LOG_ERROR("decrypt failed, ret:%{public}d", ret);
69 return -1;
70 }
71 outBuffer = CreateAshmemFromArrayBuffer(outData, "DeryptOutIntellVoiceData");
72 }
73
74 if (outBuffer == nullptr) {
75 INTELL_VOICE_LOG_ERROR("out buffer is nullptr");
76 return -1;
77 }
78
79 INTELL_VOICE_LOG_INFO("exit");
80 return 0;
81 }
82
CreateArrayBufferFromAshmem(const sptr<Ashmem> & ashmem)83 std::unique_ptr<OHOS::IntellVoiceUtils::Uint8ArrayBuffer> DataOperationCallback::CreateArrayBufferFromAshmem(
84 const sptr<Ashmem> &ashmem)
85 {
86 if (ashmem == nullptr) {
87 INTELL_VOICE_LOG_ERROR("ashmem is nullptr");
88 return nullptr;
89 }
90
91 uint32_t size = static_cast<uint32_t>(ashmem->GetAshmemSize());
92 if (size == 0) {
93 INTELL_VOICE_LOG_ERROR("size is zero");
94 return nullptr;
95 }
96
97 if (!ashmem->MapReadOnlyAshmem()) {
98 INTELL_VOICE_LOG_ERROR("map ashmem failed");
99 return nullptr;
100 }
101
102 const uint8_t *mem = static_cast<const uint8_t *>(ashmem->ReadFromAshmem(size, 0));
103 if (mem == nullptr) {
104 INTELL_VOICE_LOG_ERROR("read from ashmem failed");
105 return nullptr;
106 }
107
108 return CreateArrayBuffer<uint8_t>(size, mem);
109 }
110
CreateAshmemFromArrayBuffer(const std::unique_ptr<OHOS::IntellVoiceUtils::Uint8ArrayBuffer> & buffer,const std::string & name)111 sptr<Ashmem> DataOperationCallback::CreateAshmemFromArrayBuffer(
112 const std::unique_ptr<OHOS::IntellVoiceUtils::Uint8ArrayBuffer> &buffer, const std::string &name)
113 {
114 if (buffer == nullptr) {
115 INTELL_VOICE_LOG_ERROR("buffer is nullptr");
116 return nullptr;
117 }
118
119 if ((buffer->GetSize() == 0) || (buffer->GetData() == nullptr)) {
120 INTELL_VOICE_LOG_ERROR("data is empty");
121 return nullptr;
122 }
123
124 sptr<Ashmem> ashmem = OHOS::Ashmem::CreateAshmem(name.c_str(), buffer->GetSize() * sizeof(uint8_t));
125 if (ashmem == nullptr) {
126 INTELL_VOICE_LOG_ERROR("failed to create ashmem");
127 return nullptr;
128 }
129
130 ON_SCOPE_EXIT {
131 ashmem->UnmapAshmem();
132 ashmem->CloseAshmem();
133 ashmem = nullptr;
134 };
135
136 if (!ashmem->MapReadAndWriteAshmem()) {
137 INTELL_VOICE_LOG_ERROR("failed to map ashmem");
138 return nullptr;
139 }
140
141 if (!ashmem->WriteToAshmem(buffer->GetData(), buffer->GetSize() * sizeof(uint8_t), 0)) {
142 INTELL_VOICE_LOG_ERROR("failed to write ashmem");
143 return nullptr;
144 }
145
146 CANCEL_SCOPE_EXIT;
147 INTELL_VOICE_LOG_INFO("create ashmem success, size:%{public}u",
148 static_cast<uint32_t>(buffer->GetSize() * sizeof(uint8_t)));
149 return ashmem;
150 }
151 }
152 }
153