From c227aec278593412f3edab579832109886503428 Mon Sep 17 00:00:00 2001 From: Badhri Jagan Sridharan Date: Wed, 6 Feb 2019 20:19:09 -0800 Subject: [PATCH 1/4] Add option to "Enable USB" Under the updated flow, the user is given an option to re-enable USB port and disable contaminant detection until the next unplug of the USB accessory. Also, display a Toast message conveying that the USB port has been re-enabled. Bug: 128534822 Test: Tested with the mock circuit. Change-Id: Ifd0a6658a443ae8966ae9128a20e827ed5b03380 --- packages/SystemUI/res/values/strings.xml | 6 ++++++ .../systemui/usb/UsbContaminantActivity.java | 19 ++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 16222f7ebd8d1..9779e53a91610 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -165,6 +165,12 @@ To protect your device from liquid or debris, the USB port is disabled and won\u2019t detect any accessories.\n\nYou\u2019ll be notified when it\u2019s safe to use the USB port again. + + USB port enabled to detect chargers and accessories + + + Enable USB + Zoom to fill screen diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java index fa4b3fe4be18d..ecf608beb91cd 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java @@ -16,14 +16,17 @@ package com.android.systemui.usb; +import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.hardware.usb.ParcelableUsbPort; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbPort; import android.os.Bundle; +import android.util.Log; import android.view.Window; import android.view.WindowManager; +import android.widget.Toast; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; @@ -36,7 +39,6 @@ public class UsbContaminantActivity extends AlertActivity implements DialogInterface.OnClickListener { private static final String TAG = "UsbContaminantActivity"; - private UsbDisconnectedReceiver mDisconnectedReceiver; private UsbPort mUsbPort; @Override @@ -55,8 +57,10 @@ public class UsbContaminantActivity extends AlertActivity final AlertController.AlertParams ap = mAlertParams; ap.mTitle = getString(R.string.usb_contaminant_title); ap.mMessage = getString(R.string.usb_contaminant_message); - ap.mPositiveButtonText = getString(android.R.string.ok); - ap.mPositiveButtonListener = this; + ap.mNegativeButtonText = getString(android.R.string.ok); + ap.mNeutralButtonText = getString(R.string.usb_disable_contaminant_detection); + ap.mNegativeButtonListener = this; + ap.mNeutralButtonListener = this; setupAlert(); } @@ -68,6 +72,15 @@ public class UsbContaminantActivity extends AlertActivity @Override public void onClick(DialogInterface dialog, int which) { + if (which == AlertDialog.BUTTON_NEUTRAL) { + try { + mUsbPort.enableContaminantDetection(false); + Toast.makeText(this, R.string.usb_port_enabled, + Toast.LENGTH_SHORT).show(); + } catch (Exception e) { + Log.e(TAG, "Unable to notify Usb service", e); + } + } finish(); } } From 397a98c806c86e6f978672916063c704962f5f47 Mon Sep 17 00:00:00 2001 From: Badhri Jagan Sridharan Date: Wed, 6 Feb 2019 20:19:24 -0800 Subject: [PATCH 2/4] Refactor actions that are needed to be taken during port status changes. For any change in port status, the following needs to be done: 1. Send port changed Broadcast 2. Log to statsd 3. Update contaminant notification. Bug: 128534822 Test: Tested with the mock circuit. Change-Id: I2c279a2ea0255a69c0a74a98ebf5bf680cae1fe1 --- .../android/server/usb/UsbPortManager.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index ae05750eed9fc..b972b5f10a39a 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -948,22 +948,25 @@ public class UsbPortManager { } } + private void handlePortLocked(PortInfo portInfo, IndentingPrintWriter pw) { + sendPortChangedBroadcastLocked(portInfo); + logToStatsd(portInfo); + updateContaminantNotification(); + } + private void handlePortAddedLocked(PortInfo portInfo, IndentingPrintWriter pw) { logAndPrint(Log.INFO, pw, "USB port added: " + portInfo); - sendPortChangedBroadcastLocked(portInfo); - updateContaminantNotification(); + handlePortLocked(portInfo, pw); } private void handlePortChangedLocked(PortInfo portInfo, IndentingPrintWriter pw) { logAndPrint(Log.INFO, pw, "USB port changed: " + portInfo); - sendPortChangedBroadcastLocked(portInfo); - updateContaminantNotification(); + handlePortLocked(portInfo, pw); } private void handlePortRemovedLocked(PortInfo portInfo, IndentingPrintWriter pw) { logAndPrint(Log.INFO, pw, "USB port removed: " + portInfo); - sendPortChangedBroadcastLocked(portInfo); - updateContaminantNotification(); + handlePortLocked(portInfo, pw); } // Constants have to be converted between USB HAL V1.2 ContaminantDetectionStatus @@ -996,9 +999,9 @@ public class UsbPortManager { // instead of from within the critical section. mHandler.post(() -> mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.MANAGE_USB)); + } - // Log to statsd - + private void logToStatsd(PortInfo portInfo) { // Port is removed if (portInfo.mUsbPortStatus == null) { if (mConnected.containsKey(portInfo.mUsbPort.getId())) { From 26c490c568e88ac38cf203e06fa5ccd4cbfe0dcd Mon Sep 17 00:00:00 2001 From: Badhri Jagan Sridharan Date: Thu, 7 Feb 2019 14:27:18 -0800 Subject: [PATCH 3/4] Support contaminant detection disable workflow Do not show "Safe to use USB port" when contaminant detection is disabled by the user. Bug: 128534822 Test: Tested with the mock circuit. Change-Id: Iebd12f04a6d8bfd7be5d673cf5a6742cf3d6f281 --- .../android/server/usb/UsbPortManager.java | 81 ++++++++++++------- 1 file changed, 51 insertions(+), 30 deletions(-) diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index b972b5f10a39a..aec85d37bf093 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -150,8 +150,8 @@ public class UsbPortManager { private NotificationManager mNotificationManager; /** - * If there currently is a notification about contaminated USB port shown the id of the - * notification, or 0 if there is none. + * If there currently is a notification related to contaminated USB port management + * shown the id of the notification, or 0 if there is none. */ private int mIsPortContaminatedNotificationId; @@ -191,18 +191,24 @@ public class UsbPortManager { private void updateContaminantNotification() { PortInfo currentPortInfo = null; Resources r = mContext.getResources(); + int contaminantStatus = UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED; // Not handling multiple ports here. Showing the notification // for the first port that returns CONTAMINANT_PRESENCE_DETECTED. for (PortInfo portInfo : mPorts.values()) { - if (portInfo.mUsbPortStatus.getContaminantDetectionStatus() - == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED) { + contaminantStatus = portInfo.mUsbPortStatus.getContaminantDetectionStatus(); + if (contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED + || contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_DISABLED) { currentPortInfo = portInfo; break; } } - if (currentPortInfo != null && mIsPortContaminatedNotificationId + // Current contminant status is detected while "safe to use usb port" + // notification is displayed. Remove safe to use usb port notification + // and push contaminant detected notification. + if (contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED + && mIsPortContaminatedNotificationId != SystemMessage.NOTE_USB_CONTAMINANT_DETECTED) { if (mIsPortContaminatedNotificationId == SystemMessage.NOTE_USB_CONTAMINANT_NOT_DETECTED) { @@ -242,32 +248,41 @@ public class UsbPortManager { Notification notification = builder.build(); mNotificationManager.notifyAsUser(null, mIsPortContaminatedNotificationId, notification, UserHandle.ALL); - } else if (currentPortInfo == null && mIsPortContaminatedNotificationId + // No contaminant is detected but contaminant detection notification is displayed. + // Remove contaminant detection notification and push safe to use USB port notification. + } else if (contaminantStatus != UsbPortStatus.CONTAMINANT_DETECTION_DETECTED + && mIsPortContaminatedNotificationId == SystemMessage.NOTE_USB_CONTAMINANT_DETECTED) { mNotificationManager.cancelAsUser(null, mIsPortContaminatedNotificationId, UserHandle.ALL); + mIsPortContaminatedNotificationId = 0; - mIsPortContaminatedNotificationId = SystemMessage.NOTE_USB_CONTAMINANT_NOT_DETECTED; - int titleRes = com.android.internal.R.string.usb_contaminant_not_detected_title; - CharSequence title = r.getText(titleRes); - String channel = SystemNotificationChannels.ALERTS; - CharSequence message = r.getText( - com.android.internal.R.string.usb_contaminant_not_detected_message); + // Dont show safe to use notification when contaminant detection is disabled. + // Show only when the status is changing from detected to not detected. + if (contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED) { + mIsPortContaminatedNotificationId = + SystemMessage.NOTE_USB_CONTAMINANT_NOT_DETECTED; + int titleRes = com.android.internal.R.string.usb_contaminant_not_detected_title; + CharSequence title = r.getText(titleRes); + String channel = SystemNotificationChannels.ALERTS; + CharSequence message = r.getText( + com.android.internal.R.string.usb_contaminant_not_detected_message); - Notification.Builder builder = new Notification.Builder(mContext, channel) - .setSmallIcon(com.android.internal.R.drawable.ic_usb_48dp) - .setTicker(title) - .setColor(mContext.getColor( - com.android.internal.R.color - .system_notification_accent_color)) - .setContentTitle(title) - .setContentText(message) - .setVisibility(Notification.VISIBILITY_PUBLIC) - .setStyle(new Notification.BigTextStyle() - .bigText(message)); - Notification notification = builder.build(); - mNotificationManager.notifyAsUser(null, mIsPortContaminatedNotificationId, notification, - UserHandle.ALL); + Notification.Builder builder = new Notification.Builder(mContext, channel) + .setSmallIcon(com.android.internal.R.drawable.ic_usb_48dp) + .setTicker(title) + .setColor(mContext.getColor( + com.android.internal.R.color + .system_notification_accent_color)) + .setContentTitle(title) + .setContentText(message) + .setVisibility(Notification.VISIBILITY_PUBLIC) + .setStyle(new Notification.BigTextStyle() + .bigText(message)); + Notification notification = builder.build(); + mNotificationManager.notifyAsUser(null, mIsPortContaminatedNotificationId, + notification, UserHandle.ALL); + } } } @@ -319,8 +334,8 @@ public class UsbPortManager { } try { - // Oneway call into the hal - android.hardware.usb.V1_2.IUsb proxy = (android.hardware.usb.V1_2.IUsb) mProxy; + // Oneway call into the hal. Use the castFrom method from HIDL. + android.hardware.usb.V1_2.IUsb proxy = android.hardware.usb.V1_2.IUsb.castFrom(mProxy); proxy.enableContaminantPresenceDetection(portId, enable); } catch (RemoteException e) { logAndPrintException(pw, "Failed to set contaminant detection", e); @@ -950,7 +965,7 @@ public class UsbPortManager { private void handlePortLocked(PortInfo portInfo, IndentingPrintWriter pw) { sendPortChangedBroadcastLocked(portInfo); - logToStatsd(portInfo); + logToStatsd(portInfo, pw); updateContaminantNotification(); } @@ -1001,7 +1016,7 @@ public class UsbPortManager { Manifest.permission.MANAGE_USB)); } - private void logToStatsd(PortInfo portInfo) { + private void logToStatsd(PortInfo portInfo, IndentingPrintWriter pw) { // Port is removed if (portInfo.mUsbPortStatus == null) { if (mConnected.containsKey(portInfo.mUsbPort.getId())) { @@ -1037,6 +1052,12 @@ public class UsbPortManager { ? StatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_CONNECTED : StatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_DISCONNECTED, portInfo.mUsbPort.getId(), portInfo.mLastConnectDurationMillis); + // Contaminant detection might have been temporarily disabled by the user + // through SystemUI. + // Re-enable contaminant detection when the accessory is unplugged. + if (!portInfo.mUsbPortStatus.isConnected()) { + enableContaminantDetection(portInfo.mUsbPort.getId(), true, pw); + } } if (!mContaminantStatus.containsKey(portInfo.mUsbPort.getId()) From 3df511319c2f8fe8b3184e46f9157e9996be1cac Mon Sep 17 00:00:00 2001 From: Badhri Jagan Sridharan Date: Thu, 14 Mar 2019 15:26:19 -0700 Subject: [PATCH 4/4] UsbPortManager: Re-enable contaminant detection when port is unplugged SystemUI disables contaminant detection when user wants to continue using the port. Re-enable contaminant detection when the accessory is unplugged. Bug: 128534822 Test: Tested with the mock circuit. Change-Id: I22a3c839264876409c68c6a3145c9fcc6278f381 --- .../android/server/usb/UsbPortManager.java | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index aec85d37bf093..96e12ce837cad 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -965,6 +965,7 @@ public class UsbPortManager { private void handlePortLocked(PortInfo portInfo, IndentingPrintWriter pw) { sendPortChangedBroadcastLocked(portInfo); + enableContaminantDetectionIfNeeded(portInfo, pw); logToStatsd(portInfo, pw); updateContaminantNotification(); } @@ -1016,6 +1017,22 @@ public class UsbPortManager { Manifest.permission.MANAGE_USB)); } + private void enableContaminantDetectionIfNeeded(PortInfo portInfo, IndentingPrintWriter pw) { + if (!mConnected.containsKey(portInfo.mUsbPort.getId())) { + return; + } + + if (mConnected.get(portInfo.mUsbPort.getId()) + && !portInfo.mUsbPortStatus.isConnected() + && portInfo.mUsbPortStatus.getContaminantDetectionStatus() + == UsbPortStatus.CONTAMINANT_DETECTION_DISABLED) { + // Contaminant detection might have been temporarily disabled by the user + // through SystemUI. + // Re-enable contaminant detection when the accessory is unplugged. + enableContaminantDetection(portInfo.mUsbPort.getId(), true, pw); + } + } + private void logToStatsd(PortInfo portInfo, IndentingPrintWriter pw) { // Port is removed if (portInfo.mUsbPortStatus == null) { @@ -1052,12 +1069,6 @@ public class UsbPortManager { ? StatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_CONNECTED : StatsLog.USB_CONNECTOR_STATE_CHANGED__STATE__STATE_DISCONNECTED, portInfo.mUsbPort.getId(), portInfo.mLastConnectDurationMillis); - // Contaminant detection might have been temporarily disabled by the user - // through SystemUI. - // Re-enable contaminant detection when the accessory is unplugged. - if (!portInfo.mUsbPortStatus.isConnected()) { - enableContaminantDetection(portInfo.mUsbPort.getId(), true, pw); - } } if (!mContaminantStatus.containsKey(portInfo.mUsbPort.getId())