From 7dee1a6347bf2c2eb90359399178f07e0d75e6be Mon Sep 17 00:00:00 2001 From: Badhri Jagan Sridharan Date: Sat, 1 Apr 2017 18:19:05 -0700 Subject: [PATCH] Do not display USB charging dialogue for AUDIO class devices The CL prevents the "Supplying power to the attached device" notification from showing up when USB digital headphones are connected. Although, the phone is actually powering the headphones here, there seems to be an opinion that this might confuse the users. So, disabling the notification for better user experience. Also, the mode chooser activity might not be applicable here as the headphones are not expected to be a dual role device in the near future. When connected through a hub, the power management of the Type-c link is expected to be managed by the Type-C stack in the hub and phone's kernel. So user might not have to manage the direction of power flow. Bug: 36141499 Test: Manually tested that USB dialog doesnt show up when digital usb headphones are connected but shows up otherwise. Change-Id: I187da9c77e294cbbceb633365adbb4623fc14a3d --- .../android/server/usb/UsbDeviceManager.java | 81 +++++++++++++++++-- 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index fb8c5cfbcc7ac..ff79a551c5c9f 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -30,6 +30,10 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.ContentObserver; import android.hardware.usb.UsbAccessory; +import android.hardware.usb.UsbConfiguration; +import android.hardware.usb.UsbConstants; +import android.hardware.usb.UsbDevice; +import android.hardware.usb.UsbInterface; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPortStatus; @@ -61,6 +65,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashMap; +import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Scanner; @@ -125,9 +130,10 @@ public class UsbDeviceManager { private static final int MSG_BOOT_COMPLETED = 4; private static final int MSG_USER_SWITCHED = 5; private static final int MSG_UPDATE_USER_RESTRICTIONS = 6; - private static final int MSG_UPDATE_HOST_STATE = 7; + private static final int MSG_UPDATE_PORT_STATE = 7; private static final int MSG_ACCESSORY_MODE_ENTER_TIMEOUT = 8; private static final int MSG_UPDATE_CHARGING_STATE = 9; + private static final int MSG_UPDATE_HOST_STATE = 10; private static final int AUDIO_MODE_SOURCE = 1; @@ -201,7 +207,7 @@ public class UsbDeviceManager { } }; - private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() { + private final BroadcastReceiver mPortReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { UsbPort port = intent.getParcelableExtra(UsbManager.EXTRA_PORT); @@ -219,6 +225,19 @@ public class UsbDeviceManager { } }; + private final BroadcastReceiver mHostReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + Iterator devices = ((UsbManager) context.getSystemService(Context.USB_SERVICE)) + .getDeviceList().entrySet().iterator(); + if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) { + mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, true); + } else { + mHandler.sendMessage(MSG_UPDATE_HOST_STATE, devices, false); + } + } + }; + public UsbDeviceManager(Context context, UsbAlsaManager alsaManager, UsbSettingsManager settingsManager) { mContext = context; @@ -243,10 +262,15 @@ public class UsbDeviceManager { if (secureAdbEnabled && !dataEncrypted) { mDebuggingManager = new UsbDebuggingManager(context); } - mContext.registerReceiver(mHostReceiver, + mContext.registerReceiver(mPortReceiver, new IntentFilter(UsbManager.ACTION_USB_PORT_CHANGED)); mContext.registerReceiver(mChargingReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); + + IntentFilter filter = + new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED); + filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); + mContext.registerReceiver(mHostReceiver, filter); } private UsbProfileGroupSettingsManager getCurrentSettings() { @@ -379,6 +403,7 @@ public class UsbDeviceManager { private int mCurrentUser = UserHandle.USER_NULL; private boolean mUsbCharging; private String mCurrentOemFunctions; + private boolean mHideUsbNotification; public UsbHandler(Looper looper) { super(looper); @@ -492,8 +517,8 @@ public class UsbDeviceManager { args.argi2 = sourcePower ? 1 : 0; args.argi3 = sinkPower ? 1 : 0; - removeMessages(MSG_UPDATE_HOST_STATE); - Message msg = obtainMessage(MSG_UPDATE_HOST_STATE, args); + removeMessages(MSG_UPDATE_PORT_STATE); + Message msg = obtainMessage(MSG_UPDATE_PORT_STATE, args); // debounce rapid transitions of connect/disconnect on type-c ports sendMessageDelayed(msg, UPDATE_DELAY); } @@ -855,7 +880,7 @@ public class UsbDeviceManager { mPendingBootBroadcast = true; } break; - case MSG_UPDATE_HOST_STATE: + case MSG_UPDATE_PORT_STATE: SomeArgs args = (SomeArgs) msg.obj; mHostConnected = (args.argi1 == 1); mSourcePower = (args.argi2 == 1); @@ -872,6 +897,46 @@ public class UsbDeviceManager { mUsbCharging = (msg.arg1 == 1); updateUsbNotification(); break; + case MSG_UPDATE_HOST_STATE: + Iterator devices = (Iterator) msg.obj; + boolean connected = (msg.arg1 == 1); + + if (DEBUG) { + Slog.i(TAG, "HOST_STATE connected:" + connected); + } + + if ((mHideUsbNotification && connected) + || (!mHideUsbNotification && !connected)) { + break; + } + + mHideUsbNotification = false; + while (devices.hasNext()) { + Map.Entry pair = (Map.Entry) devices.next(); + if (DEBUG) { + Slog.i(TAG, pair.getKey() + " = " + pair.getValue()); + } + UsbDevice device = (UsbDevice) pair.getValue(); + int configurationCount = device.getConfigurationCount(); + while (configurationCount != 0) { + UsbConfiguration config = device.getConfiguration(configurationCount); + configurationCount--; + int interfaceCount = config.getInterfaceCount(); + while (interfaceCount != 0) { + UsbInterface intrface = config.getInterface(interfaceCount); + interfaceCount--; + if (intrface.getInterfaceClass() == UsbConstants.USB_CLASS_AUDIO) { + if (DEBUG) { + Slog.i(TAG, device + " is an Audio device"); + } + mHideUsbNotification = true; + break; + } + } + } + } + updateUsbNotification(); + break; case MSG_ENABLE_ADB: setAdbEnabled(msg.arg1 == 1); break; @@ -944,7 +1009,8 @@ public class UsbDeviceManager { private void updateUsbNotification() { if (mNotificationManager == null || !mUseUsbNotification - || ("0".equals(SystemProperties.get("persist.charging.notify")))) { + || ("0".equals(SystemProperties.get("persist.charging.notify"))) + || mHideUsbNotification) { return; } int id = 0; @@ -1097,6 +1163,7 @@ public class UsbDeviceManager { pw.println(" mSourcePower: " + mSourcePower); pw.println(" mSinkPower: " + mSinkPower); pw.println(" mUsbCharging: " + mUsbCharging); + pw.println(" mHideUsbNotification: " + mHideUsbNotification); try { pw.println(" Kernel state: " + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim());