107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant/* 207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * Copyright (C) 2018 The Android Open Source Project 307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * 407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * Licensed under the Apache License, Version 2.0 (the "License"); 507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * you may not use this file except in compliance with the License. 607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * You may obtain a copy of the License at 707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * 807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * http://www.apache.org/licenses/LICENSE-2.0 907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * 1007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * Unless required by applicable law or agreed to in writing, software 1107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * distributed under the License is distributed on an "AS IS" BASIS, 1207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * See the License for the specific language governing permissions and 1407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * limitations under the License. 1507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant */ 1607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 1707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chantpackage com.android.server.usb; 1807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 1907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant/** 2007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * Detects and reports ALSA jack state and events. 2107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant */ 2207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chantpublic final class UsbAlsaJackDetector implements Runnable { 2307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private static final String TAG = "UsbAlsaJackDetector"; 2407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 2507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private static native boolean nativeHasJackDetect(int card); 2607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private native boolean nativeJackDetect(int card); 2707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private native boolean nativeOutputJackConnected(int card); 2807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private native boolean nativeInputJackConnected(int card); 2907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 3007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private boolean mStopJackDetect = false; 3107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private UsbAlsaDevice mAlsaDevice; 3207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 3307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant /* use startJackDetect to create a UsbAlsaJackDetector */ 3407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant private UsbAlsaJackDetector(UsbAlsaDevice device) { 3507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mAlsaDevice = device; 3607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 3707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 3807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant /** If jack detection is detected on the given Alsa Device, 3907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * create and return a UsbAlsaJackDetector which will update wired device state 4007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * each time a jack detection event is registered. 4107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * 4207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * @returns UsbAlsaJackDetector if jack detect is supported, or null. 4307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant */ 4407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant public static UsbAlsaJackDetector startJackDetect(UsbAlsaDevice device) { 4507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant if (!nativeHasJackDetect(device.getCardNum())) { 4607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant return null; 4707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 4807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant UsbAlsaJackDetector jackDetector = new UsbAlsaJackDetector(device); 4907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 5007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant // This thread will exit once the USB device disappears. 5107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant // It can also be convinced to stop with pleaseStop(). 5207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant new Thread(jackDetector, "USB jack detect thread").start(); 5307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant return jackDetector; 5407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 5507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 5607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant public boolean isInputJackConnected() { 5707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant return nativeInputJackConnected(mAlsaDevice.getCardNum()); 5807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 5907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 6007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant public boolean isOutputJackConnected() { 6107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant return nativeOutputJackConnected(mAlsaDevice.getCardNum()); 6207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 6307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 6407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant /** 6507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * Stop the jack detect thread from calling back into UsbAlsaDevice. 6607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * This doesn't force the thread to stop (which is deprecated in java and dangerous due to 6707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * locking issues), but will cause the thread to exit at the next safe opportunity. 6807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant */ 6907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant public void pleaseStop() { 7007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant synchronized (this) { 7107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mStopJackDetect = true; 7207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 7307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 7407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 7507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant /** 7607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * Called by nativeJackDetect each time a jack detect event is reported. 7707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * @return false when the jackDetect thread should stop. true otherwise. 7807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant */ 7907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant public boolean jackDetectCallback() { 8007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant synchronized (this) { 8107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant if (mStopJackDetect) { 8207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant return false; 8307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 8407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant mAlsaDevice.updateWiredDeviceConnectionState(true); 8507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 8607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant return true; 8707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 8807a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 8907a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant /** 9007a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * This will call jackDetectCallback each time it detects a jack detect event. 9107a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant * If jackDetectCallback returns false, this function will return. 9207a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant */ 9307a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant public void run() { 9407a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant nativeJackDetect(mAlsaDevice.getCardNum()); 9507a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant } 9607a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant} 9707a97da51fc7d43db9903d793d614340b1cf3b67Andrew Chant 98