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