OSDN Git Service

Notify the user when an unsupported accessory is attached
authorBadhri Jagan Sridharan <Badhri@google.com>
Wed, 19 Apr 2017 01:13:39 +0000 (18:13 -0700)
committerBadhri Jagan Sridharan <Badhri@google.com>
Mon, 1 May 2017 17:30:49 +0000 (10:30 -0700)
This CL pops up a notification to the user when the device does not
support Analog Type-C headphones but the user connects one.
i.e when the Usb port status reports currentMode=audio_acc, but
audio_acc is not present in the supportedModes list.

Bug: 36604276
Test: Manually test inserting an Audio accessory
Change-Id: If514b9f238da196a7157e1aacb6d7690fde66f21

core/res/res/values/strings.xml
core/res/res/values/symbols.xml
proto/src/system_messages.proto
services/usb/java/com/android/server/usb/UsbDeviceManager.java

index e633d66..9848485 100644 (file)
     <string name="usb_accessory_notification_title">Connected to a USB accessory</string>
     <!-- See USB_PREFERENCES. This is the message. -->
     <string name="usb_notification_message">Tap for more options.</string>
+    <!-- USB_PREFERENCES: Notification for when a type-c USB audio accessory is attached but not supported.  This is the title -->
+    <string name="usb_unsupported_audio_accessory_title">Audio accessory not supported</string>
+    <!-- Message of notification shown when a type-c USB audio accessory is attached but not supported. -->
+    <string name="usb_unsupported_audio_accessory_message">Tap for more info</string>
+
 
     <!-- Title of notification shown when ADB is actively connected to the phone. -->
     <string name="adb_active_notification_title">USB debugging connected</string>
index bd70ca8..ca78efd 100644 (file)
   <java-symbol type="string" name="usb_ptp_notification_title" />
   <java-symbol type="string" name="usb_midi_notification_title" />
   <java-symbol type="string" name="usb_supplying_notification_title" />
+  <java-symbol type="string" name="usb_unsupported_audio_accessory_title" />
+  <java-symbol type="string" name="usb_unsupported_audio_accessory_message" />
   <java-symbol type="string" name="config_UsbDeviceConnectionHandling_component" />
   <java-symbol type="string" name="vpn_text" />
   <java-symbol type="string" name="vpn_text_long" />
index 53b3fe9..ac544e8 100644 (file)
@@ -180,6 +180,9 @@ message SystemMessage {
     // Package: android
     NOTE_FOREGROUND_SERVICES = 40;
 
+    // Inform the user that the connected audio accessory is not supported
+    NOTE_USB_AUDIO_ACCESSORY_NOT_SUPPORTED = 41;
+
     // ADD_NEW_IDS_ABOVE_THIS_LINE
     // Legacy IDs with arbitrary values appear below
     // Legacy IDs existed as stable non-conflicting constants prior to the O release
index 3b4fd04..84a2e8b 100644 (file)
@@ -424,6 +424,8 @@ public class UsbDeviceManager {
         private boolean mSinkPower;
         private boolean mConfigured;
         private boolean mUsbDataUnlocked;
+        private boolean mAudioAccessoryConnected;
+        private boolean mAudioAccessorySupported;
         private String mCurrentFunctions;
         private boolean mCurrentFunctionsApplied;
         private UsbAccessory mCurrentAccessory;
@@ -534,30 +536,13 @@ public class UsbDeviceManager {
         }
 
         public void updateHostState(UsbPort port, UsbPortStatus status) {
-            boolean hostConnected = status.getCurrentDataRole() == UsbPort.DATA_ROLE_HOST;
-            boolean sourcePower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE;
-            boolean sinkPower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SINK;
-            // 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.
-            boolean supportsAllCombinations = status.isRoleCombinationSupported(
-                    UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST)
-                    && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK,
-                    UsbPort.DATA_ROLE_HOST)
-                    && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE,
-                    UsbPort.DATA_ROLE_DEVICE)
-                    && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK,
-                    UsbPort.DATA_ROLE_HOST);
-
             if (DEBUG) {
                 Slog.i(TAG, "updateHostState " + port + " status=" + status);
             }
 
             SomeArgs args = SomeArgs.obtain();
-            args.argi1 = hostConnected ? 1 : 0;
-            args.argi2 = sourcePower ? 1 : 0;
-            args.argi3 = sinkPower ? 1 : 0;
-            args.argi4 = supportsAllCombinations ? 1 : 0;
+            args.arg1 = port;
+            args.arg2 = status;
 
             removeMessages(MSG_UPDATE_PORT_STATE);
             Message msg = obtainMessage(MSG_UPDATE_PORT_STATE, args);
@@ -931,10 +916,26 @@ public class UsbDeviceManager {
                 case MSG_UPDATE_PORT_STATE:
                     SomeArgs args = (SomeArgs) msg.obj;
                     boolean prevHostConnected = mHostConnected;
-                    mHostConnected = (args.argi1 == 1);
-                    mSourcePower = (args.argi2 == 1);
-                    mSinkPower = (args.argi3 == 1);
-                    mSupportsAllCombinations = (args.argi4 == 1);
+                    UsbPort port = (UsbPort) args.arg1;
+                    UsbPortStatus status = (UsbPortStatus) args.arg2;
+                    mHostConnected = status.getCurrentDataRole() == UsbPort.DATA_ROLE_HOST;
+                    mSourcePower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE;
+                    mSinkPower = status.getCurrentPowerRole() == UsbPort.POWER_ROLE_SINK;
+                    mAudioAccessoryConnected =
+                            (status.getCurrentMode() == UsbPort.MODE_AUDIO_ACCESSORY);
+                    mAudioAccessorySupported = port.isModeSupported(UsbPort.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(
+                            UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST)
+                            && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK,
+                            UsbPort.DATA_ROLE_HOST)
+                            && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE,
+                            UsbPort.DATA_ROLE_DEVICE)
+                            && status.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK,
+                            UsbPort.DATA_ROLE_HOST);
+
                     args.recycle();
                     updateUsbNotification(false);
                     if (mBootCompleted) {
@@ -1076,7 +1077,10 @@ public class UsbDeviceManager {
             int id = 0;
             int titleRes = 0;
             Resources r = mContext.getResources();
-            if (mConnected) {
+            if (mAudioAccessoryConnected && !mAudioAccessorySupported) {
+                titleRes = com.android.internal.R.string.usb_unsupported_audio_accessory_title;
+                id = SystemMessage.NOTE_USB_AUDIO_ACCESSORY_NOT_SUPPORTED;
+            } else if (mConnected) {
                 if (!mUsbDataUnlocked) {
                     if (mSourcePower) {
                         titleRes = com.android.internal.R.string.usb_supplying_notification_title;
@@ -1123,18 +1127,43 @@ public class UsbDeviceManager {
                     mUsbNotificationId = 0;
                 }
                 if (id != 0) {
-                    CharSequence message = r.getText(
-                            com.android.internal.R.string.usb_notification_message);
+                    CharSequence message;
                     CharSequence title = r.getText(titleRes);
+                    PendingIntent pi;
+                    String channel;
+
+                    if (titleRes
+                            != com.android.internal.R.string
+                            .usb_unsupported_audio_accessory_title) {
+                        Intent intent = Intent.makeRestartActivityTask(
+                                new ComponentName("com.android.settings",
+                                        "com.android.settings.deviceinfo.UsbModeChooserActivity"));
+                        pi = PendingIntent.getActivityAsUser(mContext, 0,
+                                intent, 0, null, UserHandle.CURRENT);
+                        channel = SystemNotificationChannels.USB;
+                        message = r.getText(
+                                com.android.internal.R.string.usb_notification_message);
+                    } else {
+                        final Intent intent = new Intent();
+                        intent.setClassName("com.android.settings",
+                                "com.android.settings.HelpTrampoline");
+                        intent.putExtra(Intent.EXTRA_TEXT,
+                                "help_url_audio_accessory_not_supported");
+
+                        if (mContext.getPackageManager().resolveActivity(intent, 0) != null) {
+                            pi = PendingIntent.getActivity(mContext, 0, intent, 0);
+                        } else {
+                            pi = null;
+                        }
 
-                    Intent intent = Intent.makeRestartActivityTask(
-                            new ComponentName("com.android.settings",
-                                    "com.android.settings.deviceinfo.UsbModeChooserActivity"));
-                    PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
-                            intent, 0, null, UserHandle.CURRENT);
+                        channel = SystemNotificationChannels.ALERTS;
+                        message = r.getText(
+                                com.android.internal.R.string
+                                        .usb_unsupported_audio_accessory_message);
+                    }
 
                     Notification notification =
-                            new Notification.Builder(mContext, SystemNotificationChannels.USB)
+                            new Notification.Builder(mContext, channel)
                                     .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
                                     .setWhen(0)
                                     .setOngoing(true)
@@ -1148,6 +1177,7 @@ public class UsbDeviceManager {
                                     .setContentIntent(pi)
                                     .setVisibility(Notification.VISIBILITY_PUBLIC)
                                     .build();
+
                     mNotificationManager.notifyAsUser(null, id, notification,
                             UserHandle.ALL);
                     mUsbNotificationId = id;
@@ -1230,6 +1260,8 @@ public class UsbDeviceManager {
             pw.println("  mSinkPower: " + mSinkPower);
             pw.println("  mUsbCharging: " + mUsbCharging);
             pw.println("  mHideUsbNotification: " + mHideUsbNotification);
+            pw.println("  mAudioAccessoryConnected: " + mAudioAccessoryConnected);
+
             try {
                 pw.println("  Kernel state: "
                         + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim());