1 /* 2 * Copyright (C) 2018 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.usb; 18 19 /** 20 * Detects and reports ALSA jack state and events. 21 */ 22 public final class UsbAlsaJackDetector implements Runnable { 23 private static final String TAG = "UsbAlsaJackDetector"; 24 nativeHasJackDetect(int card)25 private static native boolean nativeHasJackDetect(int card); nativeJackDetect(int card)26 private native boolean nativeJackDetect(int card); nativeOutputJackConnected(int card)27 private native boolean nativeOutputJackConnected(int card); nativeInputJackConnected(int card)28 private native boolean nativeInputJackConnected(int card); 29 30 private boolean mStopJackDetect = false; 31 private UsbAlsaDevice mAlsaDevice; 32 33 /* use startJackDetect to create a UsbAlsaJackDetector */ UsbAlsaJackDetector(UsbAlsaDevice device)34 private UsbAlsaJackDetector(UsbAlsaDevice device) { 35 mAlsaDevice = device; 36 } 37 38 /** If jack detection is detected on the given Alsa Device, 39 * create and return a UsbAlsaJackDetector which will update wired device state 40 * each time a jack detection event is registered. 41 * 42 * @returns UsbAlsaJackDetector if jack detect is supported, or null. 43 */ startJackDetect(UsbAlsaDevice device)44 public static UsbAlsaJackDetector startJackDetect(UsbAlsaDevice device) { 45 if (!nativeHasJackDetect(device.getCardNum())) { 46 return null; 47 } 48 UsbAlsaJackDetector jackDetector = new UsbAlsaJackDetector(device); 49 50 // This thread will exit once the USB device disappears. 51 // It can also be convinced to stop with pleaseStop(). 52 new Thread(jackDetector, "USB jack detect thread").start(); 53 return jackDetector; 54 } 55 isInputJackConnected()56 public boolean isInputJackConnected() { 57 return nativeInputJackConnected(mAlsaDevice.getCardNum()); 58 } 59 isOutputJackConnected()60 public boolean isOutputJackConnected() { 61 return nativeOutputJackConnected(mAlsaDevice.getCardNum()); 62 } 63 64 /** 65 * Stop the jack detect thread from calling back into UsbAlsaDevice. 66 * This doesn't force the thread to stop (which is deprecated in java and dangerous due to 67 * locking issues), but will cause the thread to exit at the next safe opportunity. 68 */ pleaseStop()69 public void pleaseStop() { 70 synchronized (this) { 71 mStopJackDetect = true; 72 } 73 } 74 75 /** 76 * Called by nativeJackDetect each time a jack detect event is reported. 77 * @return false when the jackDetect thread should stop. true otherwise. 78 */ jackDetectCallback()79 public boolean jackDetectCallback() { 80 synchronized (this) { 81 if (mStopJackDetect) { 82 return false; 83 } 84 mAlsaDevice.updateWiredDeviceConnectionState(true); 85 } 86 return true; 87 } 88 89 /** 90 * This will call jackDetectCallback each time it detects a jack detect event. 91 * If jackDetectCallback returns false, this function will return. 92 */ run()93 public void run() { 94 nativeJackDetect(mAlsaDevice.getCardNum()); 95 } 96 } 97 98