diff options
author | 2025-01-15 13:47:34 -0800 | |
---|---|---|
committer | 2025-01-15 13:47:34 -0800 | |
commit | 8c94e02daf94d325b34a772c3a865fc885c9731c (patch) | |
tree | e60c6155b15cd704997a26ca0510466dfd4312a6 | |
parent | 3e3cc268e0bfcd3e1d857f359142b1a043e51f0c (diff) | |
parent | 9b74fc87eecd4da64e09392e4208c18ea2673341 (diff) |
Merge "Update the logic of determining if a peripheral is input headset or not." into main
-rw-r--r-- | services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java | 7 | ||||
-rw-r--r-- | services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java | 62 |
2 files changed, 50 insertions, 19 deletions
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java b/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java index 819e73df955b..6dda7ea3eb59 100644 --- a/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java +++ b/services/usb/java/com/android/server/usb/descriptors/UsbACTerminal.java @@ -48,6 +48,13 @@ public abstract class UsbACTerminal extends UsbACInterface { return mAssocTerminal; } + public boolean isInputTerminal() { + return mTerminalType == UsbTerminalTypes.TERMINAL_IN_MIC + || mTerminalType == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET + || mTerminalType == UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED + || mTerminalType == UsbTerminalTypes.TERMINAL_EXTERN_LINE; + } + @Override public int parseRawDescriptors(ByteStream stream) { mTerminalID = stream.getByte(); diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java index ba178845a536..bfa4ecd71f5a 100644 --- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java +++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java @@ -524,27 +524,21 @@ public final class UsbDescriptorParser { * @hide */ public boolean hasMic() { - boolean hasMic = false; - ArrayList<UsbDescriptor> acDescriptors = getACInterfaceDescriptors(UsbACInterface.ACI_INPUT_TERMINAL, UsbACInterface.AUDIO_AUDIOCONTROL); for (UsbDescriptor descriptor : acDescriptors) { if (descriptor instanceof UsbACTerminal) { UsbACTerminal inDescr = (UsbACTerminal) descriptor; - if (inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_IN_MIC - || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_HEADSET - || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_BIDIR_UNDEFINED - || inDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_EXTERN_LINE) { - hasMic = true; - break; + if (inDescr.isInputTerminal()) { + return true; } } else { Log.w(TAG, "Undefined Audio Input terminal l: " + descriptor.getLength() + " t:0x" + Integer.toHexString(descriptor.getType())); } } - return hasMic; + return false; } /** @@ -913,18 +907,20 @@ public final class UsbDescriptorParser { float probability = 0.0f; - // Look for a microphone - boolean hasMic = hasMic(); - // Look for a "speaker" boolean hasSpeaker = hasSpeaker(); - if (hasMic && hasSpeaker) { - probability += 0.75f; - } - - if (hasMic && hasHIDInterface()) { - probability += 0.25f; + if (hasMic()) { + if (hasSpeaker) { + probability += 0.75f; + } + if (hasHIDInterface()) { + probability += 0.25f; + } + if (getMaximumInputChannelCount() > 1) { + // A headset is more likely to only support mono capture. + probability -= 0.25f; + } } return probability; @@ -935,9 +931,11 @@ public final class UsbDescriptorParser { * headset. The probability range is between 0.0f (definitely NOT a headset) and * 1.0f (definitely IS a headset). A probability of 0.75f seems sufficient * to count on the peripheral being a headset. + * To align with the output device type, only treat the device as input headset if it is + * an output headset. */ public boolean isInputHeadset() { - return getInputHeadsetProbability() >= IN_HEADSET_TRIGGER; + return getInputHeadsetProbability() >= IN_HEADSET_TRIGGER && isOutputHeadset(); } // TODO: Up/Downmix process descriptor is not yet parsed, which may affect the result here. @@ -952,6 +950,32 @@ public final class UsbDescriptorParser { return maxChannelCount; } + private int getMaximumInputChannelCount() { + int maxChannelCount = 0; + ArrayList<UsbDescriptor> acDescriptors = + getACInterfaceDescriptors(UsbACInterface.ACI_INPUT_TERMINAL, + UsbACInterface.AUDIO_AUDIOCONTROL); + for (UsbDescriptor descriptor : acDescriptors) { + if (!(descriptor instanceof UsbACTerminal)) { + continue; + } + UsbACTerminal inDescr = (UsbACTerminal) descriptor; + if (!inDescr.isInputTerminal()) { + continue; + } + // For an input terminal, it should at lease has 1 channel. + // Comparing the max channel count with 1 here in case the USB device doesn't report + // audio channel cluster. + maxChannelCount = Math.max(maxChannelCount, 1); + if (!(descriptor instanceof UsbAudioChannelCluster)) { + continue; + } + maxChannelCount = Math.max(maxChannelCount, + ((UsbAudioChannelCluster) descriptor).getChannelCount()); + } + return maxChannelCount; + } + /** * @hide */ |