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