10a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean/* 20a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean * Copyright (C) 2014 The Android Open Source Project 30a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean * 40a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean * Licensed under the Apache License, Version 2.0 (the "License"); 50a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean * you may not use this file except in compliance with the License. 60a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean * You may obtain a copy of the License at 70a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean * 80a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean * http://www.apache.org/licenses/LICENSE-2.0 90a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean * 100a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean * Unless required by applicable law or agreed to in writing, software 110a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean * distributed under the License is distributed on an "AS IS" BASIS, 120a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1350c00924d8483ea04ab64bc1d9775d6147afb591Paul McLean * See the License for the specific language governing permissions and 140a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean * limitations under the License. 150a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean */ 160a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean 170a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLeanpackage com.android.server.usb; 180a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean 19371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmannimport android.annotation.NonNull; 2007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chantimport android.media.AudioSystem; 2107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chantimport android.media.IAudioService; 2207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chantimport android.os.RemoteException; 23371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmannimport android.service.usb.UsbAlsaDeviceProto; 2454b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chantimport android.util.Slog; 25371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann 26371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmannimport com.android.internal.util.dump.DualDumpOutputStream; 2754b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chantimport com.android.server.audio.AudioService; 28371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann 2950c00924d8483ea04ab64bc1d9775d6147afb591Paul McLean/** 3016d7913d982dd74bc4309128c4562c816e683bd7Paul McLean * Represents the ALSA specification, and attributes of an ALSA device. 3150c00924d8483ea04ab64bc1d9775d6147afb591Paul McLean */ 3250c00924d8483ea04ab64bc1d9775d6147afb591Paul McLeanpublic final class UsbAlsaDevice { 3350c00924d8483ea04ab64bc1d9775d6147afb591Paul McLean private static final String TAG = "UsbAlsaDevice"; 340a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean protected static final boolean DEBUG = false; 350a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean 3616d7913d982dd74bc4309128c4562c816e683bd7Paul McLean private final int mCardNum; 3716d7913d982dd74bc4309128c4562c816e683bd7Paul McLean private final int mDeviceNum; 3807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private final String mDeviceAddress; 3954b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant private final boolean mHasOutput; 4054b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant private final boolean mHasInput; 4116d7913d982dd74bc4309128c4562c816e683bd7Paul McLean 4216d7913d982dd74bc4309128c4562c816e683bd7Paul McLean private final boolean mIsInputHeadset; 4316d7913d982dd74bc4309128c4562c816e683bd7Paul McLean private final boolean mIsOutputHeadset; 4416d7913d982dd74bc4309128c4562c816e683bd7Paul McLean 4507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private boolean mSelected = false; 4607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private int mOutputState; 4707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private int mInputState; 4807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private UsbAlsaJackDetector mJackDetector; 4907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private IAudioService mAudioService; 500a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean 5120137dc1481e8efec47d45d8ee0828623b5af8f9Glenn Kasten private String mDeviceName = ""; 5220137dc1481e8efec47d45d8ee0828623b5af8f9Glenn Kasten private String mDeviceDescription = ""; 530a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean 5407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant public UsbAlsaDevice(IAudioService audioService, int card, int device, String deviceAddress, 5554b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant boolean hasOutput, boolean hasInput, 5616d7913d982dd74bc4309128c4562c816e683bd7Paul McLean boolean isInputHeadset, boolean isOutputHeadset) { 5707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mAudioService = audioService; 5816d7913d982dd74bc4309128c4562c816e683bd7Paul McLean mCardNum = card; 5916d7913d982dd74bc4309128c4562c816e683bd7Paul McLean mDeviceNum = device; 6016d7913d982dd74bc4309128c4562c816e683bd7Paul McLean mDeviceAddress = deviceAddress; 6154b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant mHasOutput = hasOutput; 6254b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant mHasInput = hasInput; 6316d7913d982dd74bc4309128c4562c816e683bd7Paul McLean mIsInputHeadset = isInputHeadset; 6416d7913d982dd74bc4309128c4562c816e683bd7Paul McLean mIsOutputHeadset = isOutputHeadset; 6516d7913d982dd74bc4309128c4562c816e683bd7Paul McLean } 6616d7913d982dd74bc4309128c4562c816e683bd7Paul McLean 6716d7913d982dd74bc4309128c4562c816e683bd7Paul McLean /** 6816d7913d982dd74bc4309128c4562c816e683bd7Paul McLean * @returns the ALSA card number associated with this peripheral. 6916d7913d982dd74bc4309128c4562c816e683bd7Paul McLean */ 7016d7913d982dd74bc4309128c4562c816e683bd7Paul McLean public int getCardNum() { 7116d7913d982dd74bc4309128c4562c816e683bd7Paul McLean return mCardNum; 7216d7913d982dd74bc4309128c4562c816e683bd7Paul McLean } 7316d7913d982dd74bc4309128c4562c816e683bd7Paul McLean 7416d7913d982dd74bc4309128c4562c816e683bd7Paul McLean /** 7516d7913d982dd74bc4309128c4562c816e683bd7Paul McLean * @returns the ALSA device number associated with this peripheral. 7616d7913d982dd74bc4309128c4562c816e683bd7Paul McLean */ 7716d7913d982dd74bc4309128c4562c816e683bd7Paul McLean public int getDeviceNum() { 7816d7913d982dd74bc4309128c4562c816e683bd7Paul McLean return mDeviceNum; 7916d7913d982dd74bc4309128c4562c816e683bd7Paul McLean } 8016d7913d982dd74bc4309128c4562c816e683bd7Paul McLean 8116d7913d982dd74bc4309128c4562c816e683bd7Paul McLean /** 8216d7913d982dd74bc4309128c4562c816e683bd7Paul McLean * @returns the USB device device address associated with this peripheral. 8316d7913d982dd74bc4309128c4562c816e683bd7Paul McLean */ 8416d7913d982dd74bc4309128c4562c816e683bd7Paul McLean public String getDeviceAddress() { 8516d7913d982dd74bc4309128c4562c816e683bd7Paul McLean return mDeviceAddress; 8616d7913d982dd74bc4309128c4562c816e683bd7Paul McLean } 8716d7913d982dd74bc4309128c4562c816e683bd7Paul McLean 8816d7913d982dd74bc4309128c4562c816e683bd7Paul McLean /** 8954b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant * @returns the ALSA card/device address string. 9016d7913d982dd74bc4309128c4562c816e683bd7Paul McLean */ 9154b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant public String getAlsaCardDeviceString() { 9254b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant if (mCardNum < 0 || mDeviceNum < 0) { 9354b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant Slog.e(TAG, "Invalid alsa card or device alsaCard: " + mCardNum 9454b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant + " alsaDevice: " + mDeviceNum); 9554b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant return null; 9654b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant } 9754b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant return AudioService.makeAlsaAddressString(mCardNum, mDeviceNum); 9854b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant } 9954b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant 10054b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant /** 10154b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant * @returns true if the device supports output. 10254b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant */ 10354b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant public boolean hasOutput() { 10454b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant return mHasOutput; 10516d7913d982dd74bc4309128c4562c816e683bd7Paul McLean } 10616d7913d982dd74bc4309128c4562c816e683bd7Paul McLean 10716d7913d982dd74bc4309128c4562c816e683bd7Paul McLean /** 10854b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant * @returns true if the device supports input (recording). 10916d7913d982dd74bc4309128c4562c816e683bd7Paul McLean */ 11054b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant public boolean hasInput() { 11154b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant return mHasInput; 11216d7913d982dd74bc4309128c4562c816e683bd7Paul McLean } 11316d7913d982dd74bc4309128c4562c816e683bd7Paul McLean 11416d7913d982dd74bc4309128c4562c816e683bd7Paul McLean /** 11554b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant * @returns true if the device is a headset for purposes of input. 11616d7913d982dd74bc4309128c4562c816e683bd7Paul McLean */ 11716d7913d982dd74bc4309128c4562c816e683bd7Paul McLean public boolean isInputHeadset() { 11816d7913d982dd74bc4309128c4562c816e683bd7Paul McLean return mIsInputHeadset; 11916d7913d982dd74bc4309128c4562c816e683bd7Paul McLean } 12016d7913d982dd74bc4309128c4562c816e683bd7Paul McLean 12116d7913d982dd74bc4309128c4562c816e683bd7Paul McLean /** 12254b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant * @returns true if the device is a headset for purposes of output. 12316d7913d982dd74bc4309128c4562c816e683bd7Paul McLean */ 12416d7913d982dd74bc4309128c4562c816e683bd7Paul McLean public boolean isOutputHeadset() { 12516d7913d982dd74bc4309128c4562c816e683bd7Paul McLean return mIsOutputHeadset; 1260a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean } 1270a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean 12850c00924d8483ea04ab64bc1d9775d6147afb591Paul McLean /** 12907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * @returns true if input jack is detected or jack detection is not supported. 13007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant */ 13107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private synchronized boolean isInputJackConnected() { 13207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant if (mJackDetector == null) { 13307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant return true; // If jack detect isn't supported, say it's connected. 13407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 13507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant return mJackDetector.isInputJackConnected(); 13607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 13707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 13807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant /** 13907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * @returns true if input jack is detected or jack detection is not supported. 14007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant */ 14107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private synchronized boolean isOutputJackConnected() { 14207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant if (mJackDetector == null) { 14307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant return true; // if jack detect isn't supported, say it's connected. 14407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 14507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant return mJackDetector.isOutputJackConnected(); 14607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 14707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 14807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant /** Begins a jack-detection thread. */ 14907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private synchronized void startJackDetect() { 15007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant // If no jack detect capabilities exist, mJackDetector will be null. 15107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mJackDetector = UsbAlsaJackDetector.startJackDetect(this); 15207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 15307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 15407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant /** Stops a jack-detection thread. */ 15507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private synchronized void stopJackDetect() { 15607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant if (mJackDetector != null) { 15707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mJackDetector.pleaseStop(); 15807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 15907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mJackDetector = null; 16007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 16107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 16207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant /** Start using this device as the selected USB Audio Device. */ 16307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant public synchronized void start() { 16407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mSelected = true; 16507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mInputState = 0; 16607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mOutputState = 0; 16707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant startJackDetect(); 16807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant updateWiredDeviceConnectionState(true); 16907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 17007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 17107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant /** Stop using this device as the selected USB Audio Device. */ 17207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant public synchronized void stop() { 17307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant stopJackDetect(); 17407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant updateWiredDeviceConnectionState(false); 17507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mSelected = false; 17607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 17707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 17807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant /** Updates AudioService with the connection state of the alsaDevice. 17907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * Checks ALSA Jack state for inputs and outputs before reporting. 18007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant */ 18107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant public synchronized void updateWiredDeviceConnectionState(boolean enable) { 18207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant if (!mSelected) { 18307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant Slog.e(TAG, "updateWiredDeviceConnectionState on unselected AlsaDevice!"); 18407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant return; 18507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 18607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant String alsaCardDeviceString = getAlsaCardDeviceString(); 18707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant if (alsaCardDeviceString == null) { 18807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant return; 18907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 19007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant try { 19107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant // Output Device 19207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant if (mHasOutput) { 19307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant int device = mIsOutputHeadset 19407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant ? AudioSystem.DEVICE_OUT_USB_HEADSET 19507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant : AudioSystem.DEVICE_OUT_USB_DEVICE; 19607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant if (DEBUG) { 19707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant Slog.d(TAG, "pre-call device:0x" + Integer.toHexString(device) 19807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant + " addr:" + alsaCardDeviceString 19907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant + " name:" + mDeviceName); 20007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 20107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant boolean connected = isOutputJackConnected(); 20207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant Slog.i(TAG, "OUTPUT JACK connected: " + connected); 20307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant int outputState = (enable && connected) ? 1 : 0; 20407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant if (outputState != mOutputState) { 20507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mOutputState = outputState; 20607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mAudioService.setWiredDeviceConnectionState(device, outputState, 20707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant alsaCardDeviceString, 20807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mDeviceName, TAG); 20907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 21007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 21107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 21207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant // Input Device 21307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant if (mHasInput) { 21407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant int device = mIsInputHeadset ? AudioSystem.DEVICE_IN_USB_HEADSET 21507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant : AudioSystem.DEVICE_IN_USB_DEVICE; 21607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant boolean connected = isInputJackConnected(); 21707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant Slog.i(TAG, "INPUT JACK connected: " + connected); 21807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant int inputState = (enable && connected) ? 1 : 0; 21907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant if (inputState != mInputState) { 22007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mInputState = inputState; 22107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mAudioService.setWiredDeviceConnectionState( 22207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant device, inputState, alsaCardDeviceString, 22307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mDeviceName, TAG); 22407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 22507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 22607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } catch (RemoteException e) { 22707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant Slog.e(TAG, "RemoteException in setWiredDeviceConnectionState"); 22807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 22907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 23007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 23107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 23207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant /** 23350c00924d8483ea04ab64bc1d9775d6147afb591Paul McLean * @Override 23416d7913d982dd74bc4309128c4562c816e683bd7Paul McLean * @returns a string representation of the object. 23550c00924d8483ea04ab64bc1d9775d6147afb591Paul McLean */ 23654b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant public synchronized String toString() { 23716d7913d982dd74bc4309128c4562c816e683bd7Paul McLean return "UsbAlsaDevice: [card: " + mCardNum 23816d7913d982dd74bc4309128c4562c816e683bd7Paul McLean + ", device: " + mDeviceNum 23916d7913d982dd74bc4309128c4562c816e683bd7Paul McLean + ", name: " + mDeviceName 24054b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant + ", hasOutput: " + mHasOutput 24154b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant + ", hasInput: " + mHasInput + "]"; 2420a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean } 2430a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean 244371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann /** 245371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann * Write a description of the device to a dump stream. 246371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann */ 24754b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant public synchronized void dump(@NonNull DualDumpOutputStream dump, String idName, long id) { 248371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann long token = dump.start(idName, id); 249371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann 250371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann dump.write("card", UsbAlsaDeviceProto.CARD, mCardNum); 251371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann dump.write("device", UsbAlsaDeviceProto.DEVICE, mDeviceNum); 252371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann dump.write("name", UsbAlsaDeviceProto.NAME, mDeviceName); 25354b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant dump.write("has_output", UsbAlsaDeviceProto.HAS_PLAYBACK, mHasOutput); 25454b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant dump.write("has_input", UsbAlsaDeviceProto.HAS_CAPTURE, mHasInput); 255371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann dump.write("address", UsbAlsaDeviceProto.ADDRESS, mDeviceAddress); 256371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann 257371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann dump.end(token); 258371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann } 259371a3b879ba82bbe5a4d914328a20659131d0220Philip P. Moltmann 26019d6c7a9cd8c3a623fe76e3239be583ad0014b6fGlenn Kasten // called by logDevices 26154b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant synchronized String toShortString() { 26216d7913d982dd74bc4309128c4562c816e683bd7Paul McLean return "[card:" + mCardNum + " device:" + mDeviceNum + " " + mDeviceName + "]"; 2630a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean } 26420137dc1481e8efec47d45d8ee0828623b5af8f9Glenn Kasten 26554b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant synchronized String getDeviceName() { 26620137dc1481e8efec47d45d8ee0828623b5af8f9Glenn Kasten return mDeviceName; 26720137dc1481e8efec47d45d8ee0828623b5af8f9Glenn Kasten } 26820137dc1481e8efec47d45d8ee0828623b5af8f9Glenn Kasten 26954b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant synchronized void setDeviceNameAndDescription(String deviceName, String deviceDescription) { 27020137dc1481e8efec47d45d8ee0828623b5af8f9Glenn Kasten mDeviceName = deviceName; 27120137dc1481e8efec47d45d8ee0828623b5af8f9Glenn Kasten mDeviceDescription = deviceDescription; 27220137dc1481e8efec47d45d8ee0828623b5af8f9Glenn Kasten } 27320137dc1481e8efec47d45d8ee0828623b5af8f9Glenn Kasten 27416d7913d982dd74bc4309128c4562c816e683bd7Paul McLean /** 27516d7913d982dd74bc4309128c4562c816e683bd7Paul McLean * @Override 27616d7913d982dd74bc4309128c4562c816e683bd7Paul McLean * @returns true if the objects are equivalent. 27716d7913d982dd74bc4309128c4562c816e683bd7Paul McLean */ 27816d7913d982dd74bc4309128c4562c816e683bd7Paul McLean public boolean equals(Object obj) { 27916d7913d982dd74bc4309128c4562c816e683bd7Paul McLean if (!(obj instanceof UsbAlsaDevice)) { 28016d7913d982dd74bc4309128c4562c816e683bd7Paul McLean return false; 28116d7913d982dd74bc4309128c4562c816e683bd7Paul McLean } 28216d7913d982dd74bc4309128c4562c816e683bd7Paul McLean UsbAlsaDevice other = (UsbAlsaDevice) obj; 28316d7913d982dd74bc4309128c4562c816e683bd7Paul McLean return (mCardNum == other.mCardNum 28416d7913d982dd74bc4309128c4562c816e683bd7Paul McLean && mDeviceNum == other.mDeviceNum 28554b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant && mHasOutput == other.mHasOutput 28654b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant && mHasInput == other.mHasInput 28716d7913d982dd74bc4309128c4562c816e683bd7Paul McLean && mIsInputHeadset == other.mIsInputHeadset 28816d7913d982dd74bc4309128c4562c816e683bd7Paul McLean && mIsOutputHeadset == other.mIsOutputHeadset); 28916d7913d982dd74bc4309128c4562c816e683bd7Paul McLean } 29016d7913d982dd74bc4309128c4562c816e683bd7Paul McLean 29116d7913d982dd74bc4309128c4562c816e683bd7Paul McLean /** 29216d7913d982dd74bc4309128c4562c816e683bd7Paul McLean * @Override 29316d7913d982dd74bc4309128c4562c816e683bd7Paul McLean * @returns a hash code generated from the object contents. 29416d7913d982dd74bc4309128c4562c816e683bd7Paul McLean */ 29516d7913d982dd74bc4309128c4562c816e683bd7Paul McLean public int hashCode() { 29616d7913d982dd74bc4309128c4562c816e683bd7Paul McLean final int prime = 31; 29716d7913d982dd74bc4309128c4562c816e683bd7Paul McLean int result = 1; 29816d7913d982dd74bc4309128c4562c816e683bd7Paul McLean result = prime * result + mCardNum; 29916d7913d982dd74bc4309128c4562c816e683bd7Paul McLean result = prime * result + mDeviceNum; 30054b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant result = prime * result + (mHasOutput ? 0 : 1); 30154b15e98cdb40969929fa23ce42e6817a4b8392cAndrew Chant result = prime * result + (mHasInput ? 0 : 1); 30216d7913d982dd74bc4309128c4562c816e683bd7Paul McLean result = prime * result + (mIsInputHeadset ? 0 : 1); 30316d7913d982dd74bc4309128c4562c816e683bd7Paul McLean result = prime * result + (mIsOutputHeadset ? 0 : 1); 30416d7913d982dd74bc4309128c4562c816e683bd7Paul McLean 30516d7913d982dd74bc4309128c4562c816e683bd7Paul McLean return result; 30616d7913d982dd74bc4309128c4562c816e683bd7Paul McLean } 3070a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean} 3080a8f06922f288bfa4a22a7cd45dd5b89a9563e54Paul McLean 309