1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.soundtrigger_middleware;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.hardware.audio.common.V2_0.Uuid;
22 import android.hardware.soundtrigger.V2_1.ISoundTriggerHwCallback;
23 import android.hardware.soundtrigger.V2_3.ISoundTriggerHw;
24 import android.media.audio.common.AidlConversion;
25 import android.media.audio.common.AudioConfig;
26 import android.media.audio.common.AudioConfigBase;
27 import android.media.audio.common.AudioOffloadInfo;
28 import android.media.soundtrigger.AudioCapabilities;
29 import android.media.soundtrigger.ConfidenceLevel;
30 import android.media.soundtrigger.ModelParameter;
31 import android.media.soundtrigger.ModelParameterRange;
32 import android.media.soundtrigger.Phrase;
33 import android.media.soundtrigger.PhraseRecognitionEvent;
34 import android.media.soundtrigger.PhraseRecognitionExtra;
35 import android.media.soundtrigger.PhraseSoundModel;
36 import android.media.soundtrigger.Properties;
37 import android.media.soundtrigger.RecognitionConfig;
38 import android.media.soundtrigger.RecognitionEvent;
39 import android.media.soundtrigger.RecognitionMode;
40 import android.media.soundtrigger.RecognitionStatus;
41 import android.media.soundtrigger.SoundModel;
42 import android.media.soundtrigger.SoundModelType;
43 import android.os.HidlMemory;
44 import android.os.HidlMemoryUtil;
45 import android.os.ParcelFileDescriptor;
46 
47 import java.io.FileDescriptor;
48 import java.io.IOException;
49 import java.util.regex.Matcher;
50 
51 /**
52  * Utilities for type conversion between SoundTrigger HAL types and SoundTriggerMiddleware service
53  * types.
54  *
55  * @hide
56  */
57 class ConversionUtil {
58     static @NonNull
hidl2aidlProperties( @onNull ISoundTriggerHw.Properties hidlProperties)59     Properties hidl2aidlProperties(
60             @NonNull ISoundTriggerHw.Properties hidlProperties) {
61         Properties aidlProperties = new Properties();
62         aidlProperties.implementor = hidlProperties.implementor;
63         aidlProperties.description = hidlProperties.description;
64         aidlProperties.version = hidlProperties.version;
65         aidlProperties.uuid = hidl2aidlUuid(hidlProperties.uuid);
66         aidlProperties.maxSoundModels = hidlProperties.maxSoundModels;
67         aidlProperties.maxKeyPhrases = hidlProperties.maxKeyPhrases;
68         aidlProperties.maxUsers = hidlProperties.maxUsers;
69         aidlProperties.recognitionModes =
70                 hidl2aidlRecognitionModes(hidlProperties.recognitionModes);
71         aidlProperties.captureTransition = hidlProperties.captureTransition;
72         aidlProperties.maxBufferMs = hidlProperties.maxBufferMs;
73         aidlProperties.concurrentCapture = hidlProperties.concurrentCapture;
74         aidlProperties.triggerInEvent = hidlProperties.triggerInEvent;
75         aidlProperties.powerConsumptionMw = hidlProperties.powerConsumptionMw;
76         return aidlProperties;
77     }
78 
hidl2aidlProperties( @onNull android.hardware.soundtrigger.V2_3.Properties hidlProperties)79     static @NonNull Properties hidl2aidlProperties(
80             @NonNull android.hardware.soundtrigger.V2_3.Properties hidlProperties) {
81         Properties aidlProperties = hidl2aidlProperties(hidlProperties.base);
82         aidlProperties.supportedModelArch = hidlProperties.supportedModelArch;
83         aidlProperties.audioCapabilities =
84                 hidl2aidlAudioCapabilities(hidlProperties.audioCapabilities);
85         return aidlProperties;
86     }
87 
88     static @NonNull
hidl2aidlUuid(@onNull Uuid hidlUuid)89     String hidl2aidlUuid(@NonNull Uuid hidlUuid) {
90         if (hidlUuid.node == null || hidlUuid.node.length != 6) {
91             throw new IllegalArgumentException("UUID.node must be of length 6.");
92         }
93         return String.format(UuidUtil.FORMAT,
94                 hidlUuid.timeLow,
95                 hidlUuid.timeMid,
96                 hidlUuid.versionAndTimeHigh,
97                 hidlUuid.variantAndClockSeqHigh,
98                 hidlUuid.node[0],
99                 hidlUuid.node[1],
100                 hidlUuid.node[2],
101                 hidlUuid.node[3],
102                 hidlUuid.node[4],
103                 hidlUuid.node[5]);
104     }
105 
106     static @NonNull
aidl2hidlUuid(@onNull String aidlUuid)107     Uuid aidl2hidlUuid(@NonNull String aidlUuid) {
108         Matcher matcher = UuidUtil.PATTERN.matcher(aidlUuid);
109         if (!matcher.matches()) {
110             throw new IllegalArgumentException("Illegal format for UUID: " + aidlUuid);
111         }
112         Uuid hidlUuid = new Uuid();
113         hidlUuid.timeLow = Integer.parseUnsignedInt(matcher.group(1), 16);
114         hidlUuid.timeMid = (short) Integer.parseUnsignedInt(matcher.group(2), 16);
115         hidlUuid.versionAndTimeHigh = (short) Integer.parseUnsignedInt(matcher.group(3), 16);
116         hidlUuid.variantAndClockSeqHigh = (short) Integer.parseUnsignedInt(matcher.group(4), 16);
117         hidlUuid.node = new byte[]{(byte) Integer.parseUnsignedInt(matcher.group(5), 16),
118                 (byte) Integer.parseUnsignedInt(matcher.group(6), 16),
119                 (byte) Integer.parseUnsignedInt(matcher.group(7), 16),
120                 (byte) Integer.parseUnsignedInt(matcher.group(8), 16),
121                 (byte) Integer.parseUnsignedInt(matcher.group(9), 16),
122                 (byte) Integer.parseUnsignedInt(matcher.group(10), 16)};
123         return hidlUuid;
124     }
125 
aidl2hidlSoundModelType(int aidlType)126     static int aidl2hidlSoundModelType(int aidlType) {
127         switch (aidlType) {
128             case SoundModelType.GENERIC:
129                 return android.hardware.soundtrigger.V2_0.SoundModelType.GENERIC;
130             case SoundModelType.KEYPHRASE:
131                 return android.hardware.soundtrigger.V2_0.SoundModelType.KEYPHRASE;
132             default:
133                 throw new IllegalArgumentException("Unknown sound model type: " + aidlType);
134         }
135     }
136 
hidl2aidlSoundModelType(int hidlType)137     static int hidl2aidlSoundModelType(int hidlType) {
138         switch (hidlType) {
139             case android.hardware.soundtrigger.V2_0.SoundModelType.GENERIC:
140                 return SoundModelType.GENERIC;
141             case android.hardware.soundtrigger.V2_0.SoundModelType.KEYPHRASE:
142                 return SoundModelType.KEYPHRASE;
143             default:
144                 throw new IllegalArgumentException("Unknown sound model type: " + hidlType);
145         }
146     }
147 
148     static @NonNull
aidl2hidlPhrase(@onNull Phrase aidlPhrase)149     ISoundTriggerHw.Phrase aidl2hidlPhrase(@NonNull Phrase aidlPhrase) {
150         ISoundTriggerHw.Phrase hidlPhrase = new ISoundTriggerHw.Phrase();
151         hidlPhrase.id = aidlPhrase.id;
152         hidlPhrase.recognitionModes = aidl2hidlRecognitionModes(aidlPhrase.recognitionModes);
153         for (int aidlUser : aidlPhrase.users) {
154             hidlPhrase.users.add(aidlUser);
155         }
156         hidlPhrase.locale = aidlPhrase.locale;
157         hidlPhrase.text = aidlPhrase.text;
158         return hidlPhrase;
159     }
160 
aidl2hidlRecognitionModes(int aidlModes)161     static int aidl2hidlRecognitionModes(int aidlModes) {
162         int hidlModes = 0;
163 
164         if ((aidlModes & RecognitionMode.VOICE_TRIGGER) != 0) {
165             hidlModes |= android.hardware.soundtrigger.V2_0.RecognitionMode.VOICE_TRIGGER;
166         }
167         if ((aidlModes & RecognitionMode.USER_IDENTIFICATION) != 0) {
168             hidlModes |= android.hardware.soundtrigger.V2_0.RecognitionMode.USER_IDENTIFICATION;
169         }
170         if ((aidlModes & RecognitionMode.USER_AUTHENTICATION) != 0) {
171             hidlModes |= android.hardware.soundtrigger.V2_0.RecognitionMode.USER_AUTHENTICATION;
172         }
173         if ((aidlModes & RecognitionMode.GENERIC_TRIGGER) != 0) {
174             hidlModes |= android.hardware.soundtrigger.V2_0.RecognitionMode.GENERIC_TRIGGER;
175         }
176         return hidlModes;
177     }
178 
hidl2aidlRecognitionModes(int hidlModes)179     static int hidl2aidlRecognitionModes(int hidlModes) {
180         int aidlModes = 0;
181         if ((hidlModes & android.hardware.soundtrigger.V2_0.RecognitionMode.VOICE_TRIGGER) != 0) {
182             aidlModes |= RecognitionMode.VOICE_TRIGGER;
183         }
184         if ((hidlModes & android.hardware.soundtrigger.V2_0.RecognitionMode.USER_IDENTIFICATION)
185                 != 0) {
186             aidlModes |= RecognitionMode.USER_IDENTIFICATION;
187         }
188         if ((hidlModes & android.hardware.soundtrigger.V2_0.RecognitionMode.USER_AUTHENTICATION)
189                 != 0) {
190             aidlModes |= RecognitionMode.USER_AUTHENTICATION;
191         }
192         if ((hidlModes & android.hardware.soundtrigger.V2_0.RecognitionMode.GENERIC_TRIGGER) != 0) {
193             aidlModes |= RecognitionMode.GENERIC_TRIGGER;
194         }
195         return aidlModes;
196     }
197 
198     static @NonNull
aidl2hidlSoundModel(@onNull SoundModel aidlModel)199     ISoundTriggerHw.SoundModel aidl2hidlSoundModel(@NonNull SoundModel aidlModel) {
200         ISoundTriggerHw.SoundModel hidlModel = new ISoundTriggerHw.SoundModel();
201         hidlModel.header.type = aidl2hidlSoundModelType(aidlModel.type);
202         hidlModel.header.uuid = aidl2hidlUuid(aidlModel.uuid);
203         hidlModel.header.vendorUuid = aidl2hidlUuid(aidlModel.vendorUuid);
204         hidlModel.data = parcelFileDescriptorToHidlMemory(aidlModel.data, aidlModel.dataSize);
205         return hidlModel;
206     }
207 
208     static @NonNull
aidl2hidlPhraseSoundModel( @onNull PhraseSoundModel aidlModel)209     ISoundTriggerHw.PhraseSoundModel aidl2hidlPhraseSoundModel(
210             @NonNull PhraseSoundModel aidlModel) {
211         ISoundTriggerHw.PhraseSoundModel hidlModel = new ISoundTriggerHw.PhraseSoundModel();
212         hidlModel.common = aidl2hidlSoundModel(aidlModel.common);
213         for (Phrase aidlPhrase : aidlModel.phrases) {
214             hidlModel.phrases.add(aidl2hidlPhrase(aidlPhrase));
215         }
216         return hidlModel;
217     }
218 
aidl2hidlRecognitionConfig( @onNull RecognitionConfig aidlConfig, int deviceHandle, int ioHandle)219     static @NonNull android.hardware.soundtrigger.V2_3.RecognitionConfig aidl2hidlRecognitionConfig(
220             @NonNull RecognitionConfig aidlConfig, int deviceHandle, int ioHandle) {
221         android.hardware.soundtrigger.V2_3.RecognitionConfig hidlConfig =
222                 new android.hardware.soundtrigger.V2_3.RecognitionConfig();
223         hidlConfig.base.header.captureDevice = deviceHandle;
224         hidlConfig.base.header.captureHandle = ioHandle;
225         hidlConfig.base.header.captureRequested = aidlConfig.captureRequested;
226         for (PhraseRecognitionExtra aidlPhraseExtra : aidlConfig.phraseRecognitionExtras) {
227             hidlConfig.base.header.phrases.add(aidl2hidlPhraseRecognitionExtra(aidlPhraseExtra));
228         }
229         hidlConfig.base.data = HidlMemoryUtil.byteArrayToHidlMemory(aidlConfig.data,
230                 "SoundTrigger RecognitionConfig");
231         hidlConfig.audioCapabilities = aidlConfig.audioCapabilities;
232         return hidlConfig;
233     }
234 
235     static @NonNull
aidl2hidlPhraseRecognitionExtra( @onNull PhraseRecognitionExtra aidlExtra)236     android.hardware.soundtrigger.V2_0.PhraseRecognitionExtra aidl2hidlPhraseRecognitionExtra(
237             @NonNull PhraseRecognitionExtra aidlExtra) {
238         android.hardware.soundtrigger.V2_0.PhraseRecognitionExtra hidlExtra =
239                 new android.hardware.soundtrigger.V2_0.PhraseRecognitionExtra();
240         hidlExtra.id = aidlExtra.id;
241         hidlExtra.recognitionModes = aidl2hidlRecognitionModes(aidlExtra.recognitionModes);
242         hidlExtra.confidenceLevel = aidlExtra.confidenceLevel;
243         hidlExtra.levels.ensureCapacity(aidlExtra.levels.length);
244         for (ConfidenceLevel aidlLevel : aidlExtra.levels) {
245             hidlExtra.levels.add(aidl2hidlConfidenceLevel(aidlLevel));
246         }
247         return hidlExtra;
248     }
249 
250     static @NonNull
hidl2aidlPhraseRecognitionExtra( @onNull android.hardware.soundtrigger.V2_0.PhraseRecognitionExtra hidlExtra)251     PhraseRecognitionExtra hidl2aidlPhraseRecognitionExtra(
252             @NonNull android.hardware.soundtrigger.V2_0.PhraseRecognitionExtra hidlExtra) {
253         PhraseRecognitionExtra aidlExtra = new PhraseRecognitionExtra();
254         aidlExtra.id = hidlExtra.id;
255         aidlExtra.recognitionModes = hidl2aidlRecognitionModes(hidlExtra.recognitionModes);
256         aidlExtra.confidenceLevel = hidlExtra.confidenceLevel;
257         aidlExtra.levels = new ConfidenceLevel[hidlExtra.levels.size()];
258         for (int i = 0; i < hidlExtra.levels.size(); ++i) {
259             aidlExtra.levels[i] = hidl2aidlConfidenceLevel(hidlExtra.levels.get(i));
260         }
261         return aidlExtra;
262     }
263 
264     static @NonNull
aidl2hidlConfidenceLevel( @onNull ConfidenceLevel aidlLevel)265     android.hardware.soundtrigger.V2_0.ConfidenceLevel aidl2hidlConfidenceLevel(
266             @NonNull ConfidenceLevel aidlLevel) {
267         android.hardware.soundtrigger.V2_0.ConfidenceLevel hidlLevel =
268                 new android.hardware.soundtrigger.V2_0.ConfidenceLevel();
269         hidlLevel.userId = aidlLevel.userId;
270         hidlLevel.levelPercent = aidlLevel.levelPercent;
271         return hidlLevel;
272     }
273 
274     static @NonNull
hidl2aidlConfidenceLevel( @onNull android.hardware.soundtrigger.V2_0.ConfidenceLevel hidlLevel)275     ConfidenceLevel hidl2aidlConfidenceLevel(
276             @NonNull android.hardware.soundtrigger.V2_0.ConfidenceLevel hidlLevel) {
277         ConfidenceLevel aidlLevel = new ConfidenceLevel();
278         aidlLevel.userId = hidlLevel.userId;
279         aidlLevel.levelPercent = hidlLevel.levelPercent;
280         return aidlLevel;
281     }
282 
hidl2aidlRecognitionStatus(int hidlStatus)283     static int hidl2aidlRecognitionStatus(int hidlStatus) {
284         switch (hidlStatus) {
285             case ISoundTriggerHwCallback.RecognitionStatus.SUCCESS:
286                 return RecognitionStatus.SUCCESS;
287             case ISoundTriggerHwCallback.RecognitionStatus.ABORT:
288                 return RecognitionStatus.ABORTED;
289             case ISoundTriggerHwCallback.RecognitionStatus.FAILURE:
290                 return RecognitionStatus.FAILURE;
291             case 3: // This doesn't have a constant in HIDL.
292                 return RecognitionStatus.FORCED;
293             default:
294                 throw new IllegalArgumentException("Unknown recognition status: " + hidlStatus);
295         }
296     }
297 
298     static @NonNull
hidl2aidlRecognitionEvent(@onNull android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionEvent hidlEvent)299     RecognitionEvent hidl2aidlRecognitionEvent(@NonNull
300             android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.RecognitionEvent hidlEvent) {
301         RecognitionEvent aidlEvent = new RecognitionEvent();
302         aidlEvent.status = hidl2aidlRecognitionStatus(hidlEvent.status);
303         aidlEvent.type = hidl2aidlSoundModelType(hidlEvent.type);
304         aidlEvent.captureAvailable = hidlEvent.captureAvailable;
305         aidlEvent.captureDelayMs = hidlEvent.captureDelayMs;
306         aidlEvent.capturePreambleMs = hidlEvent.capturePreambleMs;
307         aidlEvent.triggerInData = hidlEvent.triggerInData;
308         aidlEvent.audioConfig = hidl2aidlAudioConfig(hidlEvent.audioConfig, true /*isInput*/);
309         aidlEvent.data = new byte[hidlEvent.data.size()];
310         for (int i = 0; i < aidlEvent.data.length; ++i) {
311             aidlEvent.data[i] = hidlEvent.data.get(i);
312         }
313         aidlEvent.recognitionStillActive = aidlEvent.status == RecognitionStatus.FORCED;
314         return aidlEvent;
315     }
316 
317     static @NonNull
hidl2aidlRecognitionEvent( @onNull ISoundTriggerHwCallback.RecognitionEvent hidlEvent)318     RecognitionEvent hidl2aidlRecognitionEvent(
319             @NonNull ISoundTriggerHwCallback.RecognitionEvent hidlEvent) {
320         RecognitionEvent aidlEvent = hidl2aidlRecognitionEvent(hidlEvent.header);
321         // Data needs to get overridden with 2.1 data.
322         aidlEvent.data = HidlMemoryUtil.hidlMemoryToByteArray(hidlEvent.data);
323         return aidlEvent;
324     }
325 
326     static @NonNull
hidl2aidlPhraseRecognitionEvent(@onNull android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.PhraseRecognitionEvent hidlEvent)327     PhraseRecognitionEvent hidl2aidlPhraseRecognitionEvent(@NonNull
328             android.hardware.soundtrigger.V2_0.ISoundTriggerHwCallback.PhraseRecognitionEvent hidlEvent) {
329         PhraseRecognitionEvent aidlEvent = new PhraseRecognitionEvent();
330         aidlEvent.common = hidl2aidlRecognitionEvent(hidlEvent.common);
331         aidlEvent.phraseExtras = new PhraseRecognitionExtra[hidlEvent.phraseExtras.size()];
332         for (int i = 0; i < hidlEvent.phraseExtras.size(); ++i) {
333             aidlEvent.phraseExtras[i] = hidl2aidlPhraseRecognitionExtra(
334                     hidlEvent.phraseExtras.get(i));
335         }
336         return aidlEvent;
337     }
338 
339     static @NonNull
hidl2aidlPhraseRecognitionEvent( @onNull ISoundTriggerHwCallback.PhraseRecognitionEvent hidlEvent)340     PhraseRecognitionEvent hidl2aidlPhraseRecognitionEvent(
341             @NonNull ISoundTriggerHwCallback.PhraseRecognitionEvent hidlEvent) {
342         PhraseRecognitionEvent aidlEvent = new PhraseRecognitionEvent();
343         aidlEvent.common = hidl2aidlRecognitionEvent(hidlEvent.common);
344         aidlEvent.phraseExtras = new PhraseRecognitionExtra[hidlEvent.phraseExtras.size()];
345         for (int i = 0; i < hidlEvent.phraseExtras.size(); ++i) {
346             aidlEvent.phraseExtras[i] = hidl2aidlPhraseRecognitionExtra(
347                     hidlEvent.phraseExtras.get(i));
348         }
349         return aidlEvent;
350     }
351 
352     static @NonNull
hidl2aidlAudioConfig( @onNull android.hardware.audio.common.V2_0.AudioConfig hidlConfig, boolean isInput)353     AudioConfig hidl2aidlAudioConfig(
354             @NonNull android.hardware.audio.common.V2_0.AudioConfig hidlConfig, boolean isInput) {
355         AudioConfig aidlConfig = new AudioConfig();
356         aidlConfig.base = hidl2aidlAudioConfigBase(hidlConfig.sampleRateHz, hidlConfig.channelMask,
357                 hidlConfig.format, isInput);
358         aidlConfig.offloadInfo = hidl2aidlOffloadInfo(hidlConfig.offloadInfo);
359         aidlConfig.frameCount = hidlConfig.frameCount;
360         return aidlConfig;
361     }
362 
363     static @NonNull
hidl2aidlOffloadInfo( @onNull android.hardware.audio.common.V2_0.AudioOffloadInfo hidlInfo)364     AudioOffloadInfo hidl2aidlOffloadInfo(
365             @NonNull android.hardware.audio.common.V2_0.AudioOffloadInfo hidlInfo) {
366         AudioOffloadInfo aidlInfo = new AudioOffloadInfo();
367         aidlInfo.base = hidl2aidlAudioConfigBase(hidlInfo.sampleRateHz, hidlInfo.channelMask,
368                 hidlInfo.format, false /*isInput*/);
369         aidlInfo.streamType = AidlConversion.legacy2aidl_audio_stream_type_t_AudioStreamType(
370                 hidlInfo.streamType);
371         aidlInfo.bitRatePerSecond = hidlInfo.bitRatePerSecond;
372         aidlInfo.durationUs = hidlInfo.durationMicroseconds;
373         aidlInfo.hasVideo = hidlInfo.hasVideo;
374         aidlInfo.isStreaming = hidlInfo.isStreaming;
375         aidlInfo.bitWidth = hidlInfo.bitWidth;
376         aidlInfo.offloadBufferSize = hidlInfo.bufferSize;
377         aidlInfo.usage = AidlConversion.legacy2aidl_audio_usage_t_AudioUsage(hidlInfo.usage);
378         return aidlInfo;
379     }
380 
381     // Ideally we would want to convert AudioConfigBase as a unit, however
382     // HIDL V2 lacks this type, so convert by field instead.
383     static @NonNull
hidl2aidlAudioConfigBase(int sampleRateHz, int channelMask, int format, boolean isInput)384     AudioConfigBase hidl2aidlAudioConfigBase(int sampleRateHz, int channelMask, int format,
385             boolean isInput) {
386         AudioConfigBase aidlBase = new AudioConfigBase();
387         aidlBase.sampleRate = sampleRateHz;
388         // Relies on the fact that HIDL AudioChannelMask uses the same constant values as
389         // system/audio.h.
390         aidlBase.channelMask = AidlConversion.legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
391                 channelMask, isInput);
392         // Relies on the fact that HIDL AudioFormat uses the same constant values as system/audio.h.
393         aidlBase.format = AidlConversion.legacy2aidl_audio_format_t_AudioFormatDescription(format);
394         return aidlBase;
395     }
396 
397     @Nullable
hidl2aidlModelParameterRange( android.hardware.soundtrigger.V2_3.ModelParameterRange hidlRange)398     static ModelParameterRange hidl2aidlModelParameterRange(
399             android.hardware.soundtrigger.V2_3.ModelParameterRange hidlRange) {
400         if (hidlRange == null) {
401             return null;
402         }
403         ModelParameterRange aidlRange = new ModelParameterRange();
404         aidlRange.minInclusive = hidlRange.start;
405         aidlRange.maxInclusive = hidlRange.end;
406         return aidlRange;
407     }
408 
aidl2hidlModelParameter(int aidlParam)409     static int aidl2hidlModelParameter(int aidlParam) {
410         switch (aidlParam) {
411             case ModelParameter.THRESHOLD_FACTOR:
412                 return android.hardware.soundtrigger.V2_3.ModelParameter.THRESHOLD_FACTOR;
413 
414             default:
415                 return android.hardware.soundtrigger.V2_3.ModelParameter.INVALID;
416         }
417     }
418 
hidl2aidlAudioCapabilities(int hidlCapabilities)419     static int hidl2aidlAudioCapabilities(int hidlCapabilities) {
420         int aidlCapabilities = 0;
421         if ((hidlCapabilities
422                 & android.hardware.soundtrigger.V2_3.AudioCapabilities.ECHO_CANCELLATION) != 0) {
423             aidlCapabilities |= AudioCapabilities.ECHO_CANCELLATION;
424         }
425         if ((hidlCapabilities
426                 & android.hardware.soundtrigger.V2_3.AudioCapabilities.NOISE_SUPPRESSION) != 0) {
427             aidlCapabilities |= AudioCapabilities.NOISE_SUPPRESSION;
428         }
429         return aidlCapabilities;
430     }
431 
432     /**
433      * Convert an AIDL representation of a shared memory block (ParcelFileDescriptor + size) to the
434      * HIDL representation (HidlMemory). Will not change the incoming data or any ownership
435      * semantics, but rather duplicate the underlying FD.
436      *
437      * @param data     The incoming memory block. May be null if dataSize is 0.
438      * @param dataSize The number of bytes in the block.
439      * @return A HidlMemory representation of the memory block. Will be non-null even for an empty
440      *         block.
441      */
442     private static @NonNull
parcelFileDescriptorToHidlMemory(@ullable ParcelFileDescriptor data, int dataSize)443     HidlMemory parcelFileDescriptorToHidlMemory(@Nullable ParcelFileDescriptor data, int dataSize) {
444         if (dataSize > 0) {
445             return HidlMemoryUtil.fileDescriptorToHidlMemory(data.getFileDescriptor(), dataSize);
446         } else {
447             return HidlMemoryUtil.fileDescriptorToHidlMemory(null, 0);
448         }
449     }
450 }
451