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 #ifndef LOG_TAG
16 #define LOG_TAG "ProcessConfig"
17 #endif
18 
19 #include "audio_process_config.h"
20 
21 #include <map>
22 #include <sstream>
23 
24 #include "audio_errors.h"
25 #include "audio_service_log.h"
26 
27 namespace OHOS {
28 namespace AudioStandard {
29 namespace {
30 static const uint32_t MAX_VALID_USAGE_SIZE = 30; // 128 for pids
31 static const uint32_t MAX_VALID_PIDS_SIZE = 128; // 128 for pids
32 static std::map<StreamUsage, std::string> USAGE_TO_STRING_MAP = {
33     {STREAM_USAGE_INVALID, "INVALID"},
34     {STREAM_USAGE_UNKNOWN, "UNKNOWN"},
35     {STREAM_USAGE_MEDIA, "MEDIA"},
36     {STREAM_USAGE_MUSIC, "MUSIC"},
37     {STREAM_USAGE_VOICE_COMMUNICATION, "VOICE_COMMUNICATION"},
38     {STREAM_USAGE_VOICE_ASSISTANT, "VOICE_ASSISTANT"},
39     {STREAM_USAGE_ALARM, "ALARM"},
40     {STREAM_USAGE_VOICE_MESSAGE, "VOICE_MESSAGE"},
41     {STREAM_USAGE_NOTIFICATION_RINGTONE, "NOTIFICATION_RINGTONE"},
42     {STREAM_USAGE_RINGTONE, "RINGTONE"},
43     {STREAM_USAGE_NOTIFICATION, "NOTIFICATION"},
44     {STREAM_USAGE_ACCESSIBILITY, "ACCESSIBILITY"},
45     {STREAM_USAGE_SYSTEM, "SYSTEM"},
46     {STREAM_USAGE_MOVIE, "MOVIE"},
47     {STREAM_USAGE_GAME, "GAME"},
48     {STREAM_USAGE_AUDIOBOOK, "AUDIOBOOK"},
49     {STREAM_USAGE_NAVIGATION, "NAVIGATION"},
50     {STREAM_USAGE_DTMF, "DTMF"},
51     {STREAM_USAGE_ENFORCED_TONE, "ENFORCED_TONE"},
52     {STREAM_USAGE_ULTRASONIC, "ULTRASONIC"},
53     {STREAM_USAGE_VIDEO_COMMUNICATION, "VIDEO_COMMUNICATION"},
54     {STREAM_USAGE_RANGING, "RANGING"},
55     {STREAM_USAGE_VOICE_CALL_ASSISTANT, "VOICE_CALL_ASSISTANT"},
56     {STREAM_USAGE_VOICE_MODEM_COMMUNICATION, "VOICE_MODEM_COMMUNICATION"}
57 };
58 }
59 
WriteInnerCapConfigToParcel(const AudioPlaybackCaptureConfig & config,MessageParcel & parcel)60 int32_t ProcessConfig::WriteInnerCapConfigToParcel(const AudioPlaybackCaptureConfig &config, MessageParcel &parcel)
61 {
62     // filterOptions.usages
63     size_t usageSize = config.filterOptions.usages.size();
64     CHECK_AND_RETURN_RET_LOG(usageSize < MAX_VALID_USAGE_SIZE, ERR_INVALID_PARAM, "usageSize is too large");
65     parcel.WriteUint32(usageSize);
66     for (size_t i = 0; i < usageSize; i++) {
67         parcel.WriteInt32(static_cast<int32_t>(config.filterOptions.usages[i]));
68     }
69 
70     // filterOptions.usageFilterMode
71     parcel.WriteUint32(config.filterOptions.usageFilterMode);
72 
73     // filterOptions.pids
74     size_t pidSize = config.filterOptions.pids.size();
75     CHECK_AND_RETURN_RET_LOG(pidSize <= MAX_VALID_PIDS_SIZE, ERR_INVALID_PARAM, "pidSize is too large");
76     parcel.WriteUint32(pidSize);
77     for (size_t i = 0; i < pidSize; i++) {
78         parcel.WriteUint32(config.filterOptions.pids[i]);
79     }
80 
81     // filterOptions.pidFilterMode
82     parcel.WriteUint32(config.filterOptions.pidFilterMode);
83 
84     // silentCapture
85     parcel.WriteBool(config.silentCapture);
86     return SUCCESS;
87 }
88 
ReadInnerCapConfigFromParcel(AudioPlaybackCaptureConfig & config,MessageParcel & parcel)89 int32_t ProcessConfig::ReadInnerCapConfigFromParcel(AudioPlaybackCaptureConfig &config, MessageParcel &parcel)
90 {
91     // filterOptions.usages
92     uint32_t usageSize = parcel.ReadUint32();
93     if (usageSize > MAX_VALID_USAGE_SIZE) {
94         AUDIO_ERR_LOG("Invalid param, usageSize is too large: %{public}u", usageSize);
95         return ERR_INVALID_PARAM;
96     }
97     std::vector<StreamUsage> usages = {};
98     for (uint32_t i = 0; i < usageSize; i++) {
99         int32_t tmpUsage = parcel.ReadInt32();
100         if (std::find(AUDIO_SUPPORTED_STREAM_USAGES.begin(), AUDIO_SUPPORTED_STREAM_USAGES.end(), tmpUsage) ==
101             AUDIO_SUPPORTED_STREAM_USAGES.end()) {
102             AUDIO_ERR_LOG("Invalid param, usage: %{public}d", tmpUsage);
103             return ERR_INVALID_PARAM;
104         }
105         usages.push_back(static_cast<StreamUsage>(tmpUsage));
106     }
107     config.filterOptions.usages = usages;
108 
109     // filterOptions.usageFilterMode
110     uint32_t tempMode = parcel.ReadUint32();
111     if (tempMode >= FilterMode::MAX_FILTER_MODE) {
112         AUDIO_ERR_LOG("Invalid param, usageFilterMode : %{public}u", tempMode);
113         return ERR_INVALID_PARAM;
114     }
115     config.filterOptions.usageFilterMode = static_cast<FilterMode>(tempMode);
116 
117     // filterOptions.pids
118     uint32_t pidSize = parcel.ReadUint32();
119     if (pidSize > MAX_VALID_PIDS_SIZE) {
120         AUDIO_ERR_LOG("Invalid param, pidSize is too large: %{public}u", pidSize);
121         return ERR_INVALID_PARAM;
122     }
123     std::vector<int32_t> pids = {};
124     for (uint32_t i = 0; i < pidSize; i++) {
125         int32_t tmpPid = parcel.ReadInt32();
126         if (tmpPid <= 0) {
127             AUDIO_ERR_LOG("Invalid param, pid: %{public}d", tmpPid);
128             return ERR_INVALID_PARAM;
129         }
130         pids.push_back(tmpPid);
131     }
132     config.filterOptions.pids = pids;
133 
134     // filterOptions.pidFilterMode
135     tempMode = parcel.ReadUint32();
136     if (tempMode >= FilterMode::MAX_FILTER_MODE) {
137         AUDIO_ERR_LOG("Invalid param, pidFilterMode : %{public}u", tempMode);
138         return ERR_INVALID_PARAM;
139     }
140     config.filterOptions.pidFilterMode = static_cast<FilterMode>(tempMode);
141 
142     // silentCapture
143     config.silentCapture = parcel.ReadBool();
144 
145     return SUCCESS;
146 }
147 
148 // INCLUDE 3 usages { 1 2 4 } && EXCLUDE 1 pids { 1234 }
DumpInnerCapConfig(const AudioPlaybackCaptureConfig & config)149 std::string ProcessConfig::DumpInnerCapConfig(const AudioPlaybackCaptureConfig &config)
150 {
151     std::stringstream temp;
152 
153     // filterOptions
154     switch (config.filterOptions.usageFilterMode) {
155         case FilterMode::INCLUDE:
156             temp << "INCLUDE";
157             break;
158         case FilterMode::EXCLUDE:
159             temp << "EXCLUDE";
160             break;
161         default:
162             temp << "INVALID";
163             break;
164     }
165     temp << " " << config.filterOptions.usages.size() << " usages { ";
166     for (size_t i = 0; i < config.filterOptions.usages.size(); i++) {
167         StreamUsage usage = config.filterOptions.usages[i];
168         temp << USAGE_TO_STRING_MAP[usage] << " ";
169     }
170     temp << "} && ";
171 
172     // INCLUDE 3 pids { 1 2 4 }
173     switch (config.filterOptions.pidFilterMode) {
174         case FilterMode::INCLUDE:
175             temp << "INCLUDE";
176             break;
177         case FilterMode::EXCLUDE:
178             temp << "EXCLUDE";
179             break;
180         default:
181             temp << "INVALID";
182             break;
183     }
184     temp << " " << config.filterOptions.pids.size() << " pids { ";
185     for (size_t i = 0; i < config.filterOptions.pids.size(); i++) {
186         temp << config.filterOptions.pids[i] << " ";
187     }
188     temp << "}";
189     // silentCapture will not be dumped.
190 
191     return temp.str();
192 }
193 
WriteConfigToParcel(const AudioProcessConfig & config,MessageParcel & parcel)194 int32_t ProcessConfig::WriteConfigToParcel(const AudioProcessConfig &config, MessageParcel &parcel)
195 {
196     // AppInfo
197     parcel.WriteInt32(config.appInfo.appUid);
198     parcel.WriteUint32(config.appInfo.appTokenId);
199     parcel.WriteInt32(config.appInfo.appPid);
200     parcel.WriteUint64(config.appInfo.appFullTokenId);
201 
202     // AudioStreamInfo
203     parcel.WriteInt32(config.streamInfo.samplingRate);
204     parcel.WriteInt32(config.streamInfo.encoding);
205     parcel.WriteInt32(config.streamInfo.format);
206     parcel.WriteInt32(config.streamInfo.channels);
207     parcel.WriteUint64(config.streamInfo.channelLayout);
208 
209     // AudioMode
210     parcel.WriteInt32(config.audioMode);
211 
212     // AudioRendererInfo
213     parcel.WriteInt32(config.rendererInfo.contentType);
214     parcel.WriteInt32(config.rendererInfo.streamUsage);
215     parcel.WriteInt32(config.rendererInfo.rendererFlags);
216     parcel.WriteInt32(config.rendererInfo.originalFlag);
217     parcel.WriteString(config.rendererInfo.sceneType);
218     parcel.WriteBool(config.rendererInfo.spatializationEnabled);
219     parcel.WriteBool(config.rendererInfo.headTrackingEnabled);
220     parcel.WriteInt32(config.rendererInfo.pipeType);
221 
222     //AudioPrivacyType
223     parcel.WriteInt32(config.privacyType);
224 
225     // AudioCapturerInfo
226     parcel.WriteInt32(config.capturerInfo.sourceType);
227     parcel.WriteInt32(config.capturerInfo.capturerFlags);
228     parcel.WriteInt32(config.capturerInfo.originalFlag);
229     parcel.WriteInt32(config.capturerInfo.pipeType);
230 
231     // streamType
232     parcel.WriteInt32(config.streamType);
233 
234     // deviceType
235     parcel.WriteInt32(config.deviceType);
236 
237     // Recorder only
238     parcel.WriteBool(config.isInnerCapturer);
239     parcel.WriteBool(config.isWakeupCapturer);
240 
241     // Original session id for re-create stream
242     parcel.WriteUint32(config.originalSessionId);
243 
244     return SUCCESS;
245 }
246 
ReadConfigFromParcel(AudioProcessConfig & config,MessageParcel & parcel)247 int32_t ProcessConfig::ReadConfigFromParcel(AudioProcessConfig &config, MessageParcel &parcel)
248 {
249     // AppInfo
250     config.appInfo.appUid = parcel.ReadInt32();
251     config.appInfo.appTokenId = parcel.ReadUint32();
252     config.appInfo.appPid = parcel.ReadInt32();
253     config.appInfo.appFullTokenId = parcel.ReadUint64();
254 
255     // AudioStreamInfo
256     config.streamInfo.samplingRate = static_cast<AudioSamplingRate>(parcel.ReadInt32());
257     config.streamInfo.encoding = static_cast<AudioEncodingType>(parcel.ReadInt32());
258     config.streamInfo.format = static_cast<AudioSampleFormat>(parcel.ReadInt32());
259     config.streamInfo.channels = static_cast<AudioChannel>(parcel.ReadInt32());
260     config.streamInfo.channelLayout = static_cast<AudioChannelLayout>(parcel.ReadUint64());
261 
262     // AudioMode
263     config.audioMode = static_cast<AudioMode>(parcel.ReadInt32());
264 
265     // AudioRendererInfo
266     config.rendererInfo.contentType = static_cast<ContentType>(parcel.ReadInt32());
267     config.rendererInfo.streamUsage = static_cast<StreamUsage>(parcel.ReadInt32());
268     config.rendererInfo.rendererFlags = parcel.ReadInt32();
269     config.rendererInfo.originalFlag = parcel.ReadInt32();
270     config.rendererInfo.sceneType = parcel.ReadString();
271     config.rendererInfo.spatializationEnabled = parcel.ReadBool();
272     config.rendererInfo.headTrackingEnabled = parcel.ReadBool();
273     config.rendererInfo.pipeType = static_cast<AudioPipeType>(parcel.ReadInt32());
274 
275     //AudioPrivacyType
276     config.privacyType = static_cast<AudioPrivacyType>(parcel.ReadInt32());
277 
278     // AudioCapturerInfo
279     config.capturerInfo.sourceType = static_cast<SourceType>(parcel.ReadInt32());
280     config.capturerInfo.capturerFlags = parcel.ReadInt32();
281     config.capturerInfo.originalFlag = parcel.ReadInt32();
282     config.capturerInfo.pipeType = static_cast<AudioPipeType>(parcel.ReadInt32());
283 
284     // streamType
285     config.streamType = static_cast<AudioStreamType>(parcel.ReadInt32());
286 
287     // deviceType
288     config.deviceType = static_cast<DeviceType>(parcel.ReadInt32());
289 
290     // Recorder only
291     config.isInnerCapturer = parcel.ReadBool();
292     config.isWakeupCapturer = parcel.ReadBool();
293 
294     // Original session id for re-create stream
295     config.originalSessionId = parcel.ReadUint32();
296     return SUCCESS;
297 }
298 
DumpProcessConfig(const AudioProcessConfig & config)299 std::string ProcessConfig::DumpProcessConfig(const AudioProcessConfig &config)
300 {
301     std::stringstream temp;
302 
303     // AppInfo
304     temp << "appInfo:pid<" << config.appInfo.appPid << "> uid<" << config.appInfo.appUid << "> tokenId<" <<
305         config.appInfo.appTokenId << "> ";
306 
307     // streamInfo
308     temp << "streamInfo:format(" << config.streamInfo.format << ") encoding(" << config.streamInfo.encoding <<
309         ") channels(" << config.streamInfo.channels << ") samplingRate(" << config.streamInfo.samplingRate << ") ";
310 
311     // audioMode
312     if (config.audioMode == AudioMode::AUDIO_MODE_PLAYBACK) {
313         temp << "[rendererInfo]:streamUsage(" << config.rendererInfo.streamUsage << ") contentType(" <<
314             config.rendererInfo.contentType << ") flag(" << config.rendererInfo.rendererFlags << ") ";
315     } else {
316         temp << "[capturerInfo]:sourceType(" << config.capturerInfo.sourceType << ") flag(" <<
317             config.capturerInfo.capturerFlags << ") ";
318     }
319 
320     temp << "streamType<" << config.streamType << ">";
321 
322     return temp.str();
323 }
324 } // namespace AudioStandard
325 } // namespace OHOS
326 
327