From afa5f4609736355416667c8b0aeb0567dab1fdfb Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Mon, 4 May 2020 22:24:54 -0700 Subject: [PATCH] Fix null pointer exception if USBPort is removed If for some reason a USB port instance is removed, UsbPortManager handles this by broadcasting a UsbManager.ACTION_USB_PORT_CHANGED intent with null as the UsbPortStatus argument, leading to a null pointer exception after UsbDeviceManager receives it. Take care of this by checking for null in UsbHandler.updateHostState(). Bug: 156230008 Change-Id: Ia8936358c61af5b537d1eb722a55851e0061b381 --- .../android/server/usb/UsbDeviceManager.java | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 121a5b57a69cf..b459c33879b30 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -832,20 +832,31 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser boolean prevHostConnected = mHostConnected; UsbPort port = (UsbPort) args.arg1; UsbPortStatus status = (UsbPortStatus) args.arg2; - mHostConnected = status.getCurrentDataRole() == DATA_ROLE_HOST; - mSourcePower = status.getCurrentPowerRole() == POWER_ROLE_SOURCE; - mSinkPower = status.getCurrentPowerRole() == POWER_ROLE_SINK; - mAudioAccessoryConnected = (status.getCurrentMode() == MODE_AUDIO_ACCESSORY); + + if (status != null) { + mHostConnected = status.getCurrentDataRole() == DATA_ROLE_HOST; + mSourcePower = status.getCurrentPowerRole() == POWER_ROLE_SOURCE; + mSinkPower = status.getCurrentPowerRole() == POWER_ROLE_SINK; + mAudioAccessoryConnected = (status.getCurrentMode() == MODE_AUDIO_ACCESSORY); + + // Ideally we want to see if PR_SWAP and DR_SWAP is supported. + // But, this should be suffice, since, all four combinations are only supported + // when PR_SWAP and DR_SWAP are supported. + mSupportsAllCombinations = status.isRoleCombinationSupported( + POWER_ROLE_SOURCE, DATA_ROLE_HOST) + && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_HOST) + && status.isRoleCombinationSupported(POWER_ROLE_SOURCE, + DATA_ROLE_DEVICE) + && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_DEVICE); + } else { + mHostConnected = false; + mSourcePower = false; + mSinkPower = false; + mAudioAccessoryConnected = false; + mSupportsAllCombinations = false; + } + mAudioAccessorySupported = port.isModeSupported(MODE_AUDIO_ACCESSORY); - // Ideally we want to see if PR_SWAP and DR_SWAP is supported. - // But, this should be suffice, since, all four combinations are only supported - // when PR_SWAP and DR_SWAP are supported. - mSupportsAllCombinations = status.isRoleCombinationSupported( - POWER_ROLE_SOURCE, DATA_ROLE_HOST) - && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_HOST) - && status.isRoleCombinationSupported(POWER_ROLE_SOURCE, - DATA_ROLE_DEVICE) - && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_DEVICE); args.recycle(); updateUsbNotification(false);