1 /*
2  * Copyright (C) 2015 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 android.hardware.usb;
18 
19 import android.annotation.CheckResult;
20 import android.annotation.FlaggedApi;
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.SystemApi;
25 import android.hardware.usb.flags.Flags;
26 import android.os.Parcel;
27 import android.os.Parcelable;
28 
29 import com.android.internal.annotations.Immutable;
30 
31 import java.lang.annotation.Retention;
32 import java.lang.annotation.RetentionPolicy;
33 
34 /**
35  * Describes the status of a USB port.
36  *
37  * @hide
38  */
39 @Immutable
40 @SystemApi
41 public final class UsbPortStatus implements Parcelable {
42     private static final String TAG = "UsbPortStatus";
43     private final int mCurrentMode;
44     private final @UsbPowerRole int mCurrentPowerRole;
45     private final @UsbDataRole int mCurrentDataRole;
46     private final int mSupportedRoleCombinations;
47     private final @ContaminantProtectionStatus int mContaminantProtectionStatus;
48     private final @ContaminantDetectionStatus int mContaminantDetectionStatus;
49     private final boolean mPowerTransferLimited;
50     private final @UsbDataStatus int mUsbDataStatus;
51     private final @PowerBrickConnectionStatus int mPowerBrickConnectionStatus;
52     private final @NonNull @ComplianceWarning int[] mComplianceWarnings;
53     private final @PlugState int mPlugState;
54     /**
55      * Holds the DisplayPort Alt Mode info for the Port. This field
56      * is null if the device does not support DisplayPort Alt Mode.
57      */
58     private final @Nullable DisplayPortAltModeInfo mDisplayPortAltModeInfo;
59 
60 
61     /**
62      * Power role: This USB port does not have a power role.
63      */
64     public static final int POWER_ROLE_NONE = 0;
65 
66     /**
67      * Power role: This USB port can act as a source (provide power).
68      */
69     public static final int POWER_ROLE_SOURCE = 1;
70 
71     /**
72      * Power role: This USB port can act as a sink (receive power).
73      */
74     public static final int POWER_ROLE_SINK = 2;
75 
76     @IntDef(prefix = { "POWER_ROLE_" }, value = {
77             POWER_ROLE_NONE,
78             POWER_ROLE_SOURCE,
79             POWER_ROLE_SINK
80     })
81     @Retention(RetentionPolicy.SOURCE)
82     @interface UsbPowerRole{}
83 
84     /**
85      * Power role: This USB port does not have a data role.
86      */
87     public static final int DATA_ROLE_NONE = 0;
88 
89     /**
90      * Data role: This USB port can act as a host (access data services).
91      */
92     public static final int DATA_ROLE_HOST = 1;
93 
94     /**
95      * Data role: This USB port can act as a device (offer data services).
96      */
97     public static final int DATA_ROLE_DEVICE = 2;
98 
99     @IntDef(prefix = { "DATA_ROLE_" }, value = {
100             DATA_ROLE_NONE,
101             DATA_ROLE_HOST,
102             DATA_ROLE_DEVICE
103     })
104     @Retention(RetentionPolicy.SOURCE)
105     @interface UsbDataRole{}
106 
107     /**
108      * There is currently nothing connected to this USB port.
109      */
110     public static final int MODE_NONE = 0;
111 
112     /**
113      * This USB port can act as an upstream facing port (device).
114      *
115      * <p> Implies that the port supports the {@link #POWER_ROLE_SINK} and
116      * {@link #DATA_ROLE_DEVICE} combination of roles (and possibly others as well).
117      */
118     public static final int MODE_UFP = 1 << 0;
119 
120     /**
121      * This USB port can act as a downstream facing port (host).
122      *
123      * <p> Implies that the port supports the {@link #POWER_ROLE_SOURCE} and
124      * {@link #DATA_ROLE_HOST} combination of roles (and possibly others as well).
125      */
126     public static final int MODE_DFP = 1 << 1;
127 
128     /**
129      * This USB port can act either as an downstream facing port (host) or as
130      * an upstream facing port (device).
131      *
132      * <p> Implies that the port supports the {@link #POWER_ROLE_SOURCE} and
133      * {@link #DATA_ROLE_HOST} combination of roles and the {@link #POWER_ROLE_SINK} and
134      * {@link #DATA_ROLE_DEVICE} combination of roles (and possibly others as well).
135      *
136      * @hide
137      */
138     public static final int MODE_DUAL = MODE_UFP | MODE_DFP;
139 
140     /**
141      * This USB port can support USB Type-C Audio accessory.
142      */
143     public static final int MODE_AUDIO_ACCESSORY = 1 << 2;
144 
145     /**
146      * This USB port can support USB Type-C debug accessory.
147      */
148     public static final int MODE_DEBUG_ACCESSORY = 1 << 3;
149 
150    /**
151      * Contaminant presence detection not supported by the device.
152      * @hide
153      */
154     public static final int CONTAMINANT_DETECTION_NOT_SUPPORTED = 0;
155 
156     /**
157      * Contaminant presence detection supported but disabled.
158      * @hide
159      */
160     public static final int CONTAMINANT_DETECTION_DISABLED = 1;
161 
162     /**
163      * Contaminant presence enabled but not detected.
164      * @hide
165      */
166     public static final int CONTAMINANT_DETECTION_NOT_DETECTED = 2;
167 
168     /**
169      * Contaminant presence enabled and detected.
170      * @hide
171      */
172     public static final int CONTAMINANT_DETECTION_DETECTED = 3;
173 
174     /**
175      * Contaminant protection - No action performed upon detection of
176      * contaminant presence.
177      * @hide
178      */
179     public static final int CONTAMINANT_PROTECTION_NONE = 0;
180 
181     /**
182      * Contaminant protection - Port is forced to sink upon detection of
183      * contaminant presence.
184      * @hide
185      */
186     public static final int CONTAMINANT_PROTECTION_SINK = 1 << 0;
187 
188     /**
189      * Contaminant protection - Port is forced to source upon detection of
190      * contaminant presence.
191      * @hide
192      */
193     public static final int CONTAMINANT_PROTECTION_SOURCE = 1 << 1;
194 
195     /**
196      * Contaminant protection - Port is disabled upon detection of
197      * contaminant presence.
198      * @hide
199      */
200     public static final int CONTAMINANT_PROTECTION_FORCE_DISABLE = 1 << 2;
201 
202     /**
203      * Contaminant protection - Port is disabled upon detection of
204      * contaminant presence.
205      * @hide
206      */
207     public static final int CONTAMINANT_PROTECTION_DISABLED = 1 << 3;
208 
209     /**
210      * USB data status is not known.
211      */
212     public static final int DATA_STATUS_UNKNOWN = 0;
213 
214     /**
215      * USB data is enabled.
216      */
217     public static final int DATA_STATUS_ENABLED = 1 << 0;
218 
219     /**
220      * USB data is disabled as the port is too hot.
221      */
222     public static final int DATA_STATUS_DISABLED_OVERHEAT = 1 << 1;
223 
224     /**
225      * USB data is disabled due to contaminated port.
226      */
227     public static final int DATA_STATUS_DISABLED_CONTAMINANT = 1 << 2;
228 
229     /**
230      * This flag indicates that some or all data modes are disabled
231      * due to docking event, and the specific sub-statuses viz.,
232      * {@link #DATA_STATUS_DISABLED_DOCK_HOST_MODE},
233      * {@link #DATA_STATUS_DISABLED_DOCK_DEVICE_MODE}
234      * can be checked for individual modes.
235      */
236     public static final int DATA_STATUS_DISABLED_DOCK = 1 << 3;
237 
238     /**
239      * USB data is disabled by
240      * {@link UsbPort#enableUsbData UsbPort.enableUsbData}.
241      */
242     public static final int DATA_STATUS_DISABLED_FORCE = 1 << 4;
243 
244     /**
245      * USB data is disabled for debug.
246      */
247     public static final int DATA_STATUS_DISABLED_DEBUG = 1 << 5;
248 
249     /**
250      * USB host mode is disabled due to docking event.
251      * {@link #DATA_STATUS_DISABLED_DOCK} will be set as well.
252      */
253     public static final int DATA_STATUS_DISABLED_DOCK_HOST_MODE = 1 << 6;
254 
255     /**
256      * USB device mode is disabled due to docking event.
257      * {@link #DATA_STATUS_DISABLED_DOCK} will be set as well.
258      */
259     public static final int DATA_STATUS_DISABLED_DOCK_DEVICE_MODE = 1 << 7;
260 
261     /**
262      * Unknown whether a power brick is connected.
263      */
264     public static final int POWER_BRICK_STATUS_UNKNOWN = 0;
265 
266     /**
267      * The connected device is a power brick.
268      */
269     public static final int POWER_BRICK_STATUS_CONNECTED = 1;
270 
271     /**
272      * The connected device is not power brick.
273      */
274     public static final int POWER_BRICK_STATUS_DISCONNECTED = 2;
275 
276     /**
277      * Used to indicate attached sources/cables/accessories/ports
278      * that do not match the other warnings below and do not meet the
279      * requirements of specifications including but not limited to
280      * USB Type-C Cable and Connector, Universal Serial Bus
281      * Power Delivery, and Universal Serial Bus 1.x/2.0/3.x/4.0.
282      * In addition, constants introduced after the target sdk will be
283      * remapped into COMPLIANCE_WARNING_OTHER.
284      */
285     public static final int COMPLIANCE_WARNING_OTHER = 1;
286 
287     /**
288      * Used to indicate Type-C port partner
289      * (cable/accessory/source) that identifies itself as debug
290      * accessory source as defined in USB Type-C Cable and
291      * Connector Specification. However, the specification states
292      * that this is meant for debug only and shall not be used for
293      * with commercial products.
294      */
295     public static final int COMPLIANCE_WARNING_DEBUG_ACCESSORY = 2;
296 
297     /**
298      * Used to indicate USB ports that does not
299      * identify itself as one of the charging port types (SDP/CDP
300      * DCP etc) as defined by Battery Charging v1.2 Specification.
301      */
302     public static final int COMPLIANCE_WARNING_BC_1_2 = 3;
303 
304     /**
305      * Used to indicate Type-C sources/cables that are missing pull
306      * up resistors on the CC pins as required by USB Type-C Cable
307      * and Connector Specification.
308      */
309     public static final int COMPLIANCE_WARNING_MISSING_RP = 4;
310 
311     /**
312      * Used to indicate the charging setups on the USB ports are unable to
313      * deliver negotiated power. Introduced in Android V (API level 35)
314      * and client applicantions that target API levels lower than 35 will
315      * receive {@link #COMPLIANCE_WARNING_OTHER} instead.
316      */
317     @FlaggedApi(Flags.FLAG_ENABLE_USB_DATA_COMPLIANCE_WARNING)
318     public static final int COMPLIANCE_WARNING_INPUT_POWER_LIMITED = 5;
319 
320     /**
321      * Used to indicate the cable/connector on the USB ports are missing
322      * the required wires on the data pins to make data transfer.
323      * Introduced in Android V (API level 35) and client applicantions that
324      * target API levels lower than 35 will receive
325      * {@link #COMPLIANCE_WARNING_OTHER} instead.
326      */
327     @FlaggedApi(Flags.FLAG_ENABLE_USB_DATA_COMPLIANCE_WARNING)
328     public static final int COMPLIANCE_WARNING_MISSING_DATA_LINES = 6;
329 
330     /**
331      * Used to indicate enumeration failures on the USB ports, potentially due to
332      * signal integrity issues or other causes. Introduced in Android V
333      * (API level 35) and client applicantions that target API levels lower
334      * than 35 will receive {@link #COMPLIANCE_WARNING_OTHER} instead.
335      */
336     @FlaggedApi(Flags.FLAG_ENABLE_USB_DATA_COMPLIANCE_WARNING)
337     public static final int COMPLIANCE_WARNING_ENUMERATION_FAIL = 7;
338 
339     /**
340      * Used to indicate unexpected data disconnection on the USB ports,
341      * potentially due to signal integrity issues or other causes.
342      * Introduced in Android V (API level 35) and client applicantions that
343      * target API levels lower than 35 will receive
344      * {@link #COMPLIANCE_WARNING_OTHER} instead.
345      */
346     @FlaggedApi(Flags.FLAG_ENABLE_USB_DATA_COMPLIANCE_WARNING)
347     public static final int COMPLIANCE_WARNING_FLAKY_CONNECTION = 8;
348 
349     /**
350      * Used to indicate unreliable or slow data transfer on the USB ports,
351      * potentially due to signal integrity issues or other causes.
352      * Introduced in Android V (API level 35) and client applicantions that
353      * target API levels lower than 35 will receive
354      * {@link #COMPLIANCE_WARNING_OTHER} instead.
355      */
356     @FlaggedApi(Flags.FLAG_ENABLE_USB_DATA_COMPLIANCE_WARNING)
357     public static final int COMPLIANCE_WARNING_UNRELIABLE_IO = 9;
358 
359     /**
360      * Indicates that the Type-C plug orientation cannot be
361      * determined because the connected state of the device is unknown.
362      */
363     public static final int PLUG_STATE_UNKNOWN = 0;
364 
365     /**
366      * Indicates no Type-C plug is inserted into the device.
367      */
368     public static final int PLUG_STATE_UNPLUGGED = 1;
369 
370     /**
371      * Indicates a Type-C plug is inserted into the device, but
372      * the orientation cannot be determined.
373      */
374     public static final int PLUG_STATE_PLUGGED_ORIENTATION_UNKNOWN = 2;
375 
376     /**
377      * Indicates that the connected plug uses its CC1
378      * pin to manage the Source-to-Sink connection.
379      */
380     public static final int PLUG_STATE_PLUGGED_ORIENTATION_NORMAL = 3;
381 
382     /**
383      * Indicates that the connected plug uses its CC2
384      * pin to manage the Source-to-Sink connection.
385      */
386     public static final int PLUG_STATE_PLUGGED_ORIENTATION_FLIPPED = 4;
387 
388     @IntDef(prefix = { "CONTAMINANT_DETECTION_" }, value = {
389             CONTAMINANT_DETECTION_NOT_SUPPORTED,
390             CONTAMINANT_DETECTION_DISABLED,
391             CONTAMINANT_DETECTION_NOT_DETECTED,
392             CONTAMINANT_DETECTION_DETECTED,
393     })
394     @Retention(RetentionPolicy.SOURCE)
395     @interface ContaminantDetectionStatus{}
396 
397     @IntDef(prefix = { "CONTAMINANT_PROTECTION_" }, flag = true, value = {
398             CONTAMINANT_PROTECTION_NONE,
399             CONTAMINANT_PROTECTION_SINK,
400             CONTAMINANT_PROTECTION_SOURCE,
401             CONTAMINANT_PROTECTION_FORCE_DISABLE,
402             CONTAMINANT_PROTECTION_DISABLED,
403     })
404     @Retention(RetentionPolicy.SOURCE)
405     @interface ContaminantProtectionStatus{}
406 
407     @IntDef(prefix = { "MODE_" }, value = {
408             MODE_NONE,
409             MODE_DFP,
410             MODE_UFP,
411             MODE_AUDIO_ACCESSORY,
412             MODE_DEBUG_ACCESSORY,
413     })
414     @Retention(RetentionPolicy.SOURCE)
415     @interface UsbPortMode{}
416 
417     @IntDef(prefix = { "COMPLIANCE_WARNING_" }, value = {
418             COMPLIANCE_WARNING_OTHER,
419             COMPLIANCE_WARNING_DEBUG_ACCESSORY,
420             COMPLIANCE_WARNING_BC_1_2,
421             COMPLIANCE_WARNING_MISSING_RP,
422             COMPLIANCE_WARNING_INPUT_POWER_LIMITED,
423             COMPLIANCE_WARNING_MISSING_DATA_LINES,
424             COMPLIANCE_WARNING_ENUMERATION_FAIL,
425             COMPLIANCE_WARNING_FLAKY_CONNECTION,
426             COMPLIANCE_WARNING_UNRELIABLE_IO,
427     })
428     @Retention(RetentionPolicy.SOURCE)
429     @interface ComplianceWarning{}
430 
431     @IntDef(prefix = { "PLUG_STATE_" }, value = {
432             PLUG_STATE_UNKNOWN,
433             PLUG_STATE_UNPLUGGED,
434             PLUG_STATE_PLUGGED_ORIENTATION_UNKNOWN,
435             PLUG_STATE_PLUGGED_ORIENTATION_NORMAL,
436             PLUG_STATE_PLUGGED_ORIENTATION_FLIPPED,
437     })
438     @Retention(RetentionPolicy.SOURCE)
439     @interface PlugState{}
440 
441     /** @hide */
442     @IntDef(prefix = { "DATA_STATUS_" }, flag = true, value = {
443             DATA_STATUS_UNKNOWN,
444             DATA_STATUS_ENABLED,
445             DATA_STATUS_DISABLED_OVERHEAT,
446             DATA_STATUS_DISABLED_CONTAMINANT,
447             DATA_STATUS_DISABLED_DOCK,
448             DATA_STATUS_DISABLED_DOCK_HOST_MODE,
449             DATA_STATUS_DISABLED_DOCK_DEVICE_MODE,
450             DATA_STATUS_DISABLED_FORCE,
451             DATA_STATUS_DISABLED_DEBUG,
452     })
453     @Retention(RetentionPolicy.SOURCE)
454     @interface UsbDataStatus{}
455 
456     /** @hide */
457     @IntDef(prefix = { "POWER_BRICK_STATUS_" }, value = {
458             POWER_BRICK_STATUS_UNKNOWN,
459             POWER_BRICK_STATUS_DISCONNECTED,
460             POWER_BRICK_STATUS_CONNECTED,
461     })
462     @Retention(RetentionPolicy.SOURCE)
463     @interface PowerBrickConnectionStatus{}
464 
465     /** @hide */
UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole, int supportedRoleCombinations, int contaminantProtectionStatus, int contaminantDetectionStatus, @UsbDataStatus int usbDataStatus, boolean powerTransferLimited, @PowerBrickConnectionStatus int powerBrickConnectionStatus, @NonNull @ComplianceWarning int[] complianceWarnings, int plugState, @Nullable DisplayPortAltModeInfo displayPortAltModeInfo)466     public UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole,
467             int supportedRoleCombinations, int contaminantProtectionStatus,
468             int contaminantDetectionStatus, @UsbDataStatus int usbDataStatus,
469             boolean powerTransferLimited,
470             @PowerBrickConnectionStatus int powerBrickConnectionStatus,
471             @NonNull @ComplianceWarning int[] complianceWarnings,
472             int plugState,
473             @Nullable DisplayPortAltModeInfo displayPortAltModeInfo) {
474         mCurrentMode = currentMode;
475         mCurrentPowerRole = currentPowerRole;
476         mCurrentDataRole = currentDataRole;
477         mSupportedRoleCombinations = supportedRoleCombinations;
478         mContaminantProtectionStatus = contaminantProtectionStatus;
479         mContaminantDetectionStatus = contaminantDetectionStatus;
480 
481         // Older implementations that only set the DISABLED_DOCK_MODE will have the other two
482         // set at the HAL interface level, so the "dock mode only" state shouldn't be visible here.
483         // But the semantics are ensured here.
484         int disabledDockModes = (usbDataStatus &
485             (DATA_STATUS_DISABLED_DOCK_HOST_MODE | DATA_STATUS_DISABLED_DOCK_DEVICE_MODE));
486         if (disabledDockModes != 0) {
487             // Set DATA_STATUS_DISABLED_DOCK when one of DATA_STATUS_DISABLED_DOCK_*_MODE is set
488             usbDataStatus |= DATA_STATUS_DISABLED_DOCK;
489         } else {
490             // Clear DATA_STATUS_DISABLED_DOCK when none of DATA_STATUS_DISABLED_DOCK_*_MODE is set
491             usbDataStatus &= ~DATA_STATUS_DISABLED_DOCK;
492         }
493 
494         mUsbDataStatus = usbDataStatus;
495         mPowerTransferLimited = powerTransferLimited;
496         mPowerBrickConnectionStatus = powerBrickConnectionStatus;
497         mComplianceWarnings = complianceWarnings;
498         mPlugState = plugState;
499         mDisplayPortAltModeInfo = displayPortAltModeInfo;
500     }
501 
502     /** @hide */
UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole, int supportedRoleCombinations, int contaminantProtectionStatus, int contaminantDetectionStatus, @UsbDataStatus int usbDataStatus, boolean powerTransferLimited, @PowerBrickConnectionStatus int powerBrickConnectionStatus)503     public UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole,
504             int supportedRoleCombinations, int contaminantProtectionStatus,
505             int contaminantDetectionStatus, @UsbDataStatus int usbDataStatus,
506             boolean powerTransferLimited,
507             @PowerBrickConnectionStatus int powerBrickConnectionStatus) {
508         this(currentMode, currentPowerRole, currentDataRole, supportedRoleCombinations,
509                 contaminantProtectionStatus, contaminantDetectionStatus,
510                 usbDataStatus, powerTransferLimited, powerBrickConnectionStatus,
511                 new int[] {}, PLUG_STATE_UNKNOWN, null);
512     }
513 
514     /** @hide */
UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole, int supportedRoleCombinations, int contaminantProtectionStatus, int contaminantDetectionStatus)515     public UsbPortStatus(int currentMode, int currentPowerRole, int currentDataRole,
516             int supportedRoleCombinations, int contaminantProtectionStatus,
517             int contaminantDetectionStatus) {
518         this(currentMode, currentPowerRole, currentDataRole, supportedRoleCombinations,
519                 contaminantProtectionStatus, contaminantDetectionStatus,
520                 DATA_STATUS_UNKNOWN, false, POWER_BRICK_STATUS_UNKNOWN,
521                 new int[] {}, PLUG_STATE_UNKNOWN, null);
522     }
523 
524     /**
525      * Returns true if there is anything connected to the port.
526      *
527      * @return {@code true} iff there is anything connected to the port.
528      */
isConnected()529     public boolean isConnected() {
530         return mCurrentMode != 0;
531     }
532 
533     /**
534      * Gets the current mode of the port.
535      *
536      * @return The current mode: {@link #MODE_DFP}, {@link #MODE_UFP},
537      * {@link #MODE_AUDIO_ACCESSORY}, {@link #MODE_DEBUG_ACCESSORY}, or {@link {@link #MODE_NONE} if
538      * nothing is connected.
539      */
getCurrentMode()540     public @UsbPortMode int getCurrentMode() {
541         return mCurrentMode;
542     }
543 
544     /**
545      * Gets the current power role of the port.
546      *
547      * @return The current power role: {@link #POWER_ROLE_SOURCE}, {@link #POWER_ROLE_SINK}, or
548      * {@link #POWER_ROLE_NONE} if nothing is connected.
549      */
getCurrentPowerRole()550     public @UsbPowerRole int getCurrentPowerRole() {
551         return mCurrentPowerRole;
552     }
553 
554     /**
555      * Gets the current data role of the port.
556      *
557      * @return The current data role: {@link #DATA_ROLE_HOST}, {@link #DATA_ROLE_DEVICE}, or
558      * {@link #DATA_ROLE_NONE} if nothing is connected.
559      */
getCurrentDataRole()560     public @UsbDataRole int getCurrentDataRole() {
561         return mCurrentDataRole;
562     }
563 
564     /**
565      * Returns true if the specified power and data role combination is supported
566      * given what is currently connected to the port.
567      *
568      * @param powerRole The power role to check: {@link #POWER_ROLE_SOURCE}  or
569      *                  {@link #POWER_ROLE_SINK}, or {@link #POWER_ROLE_NONE} if no power role.
570      * @param dataRole  The data role to check: either {@link #DATA_ROLE_HOST} or
571      *                  {@link #DATA_ROLE_DEVICE}, or {@link #DATA_ROLE_NONE} if no data role.
572      */
isRoleCombinationSupported(@sbPowerRole int powerRole, @UsbDataRole int dataRole)573     public boolean isRoleCombinationSupported(@UsbPowerRole int powerRole,
574             @UsbDataRole int dataRole) {
575         return (mSupportedRoleCombinations &
576                 UsbPort.combineRolesAsBit(powerRole, dataRole)) != 0;
577     }
578 
579     /**
580      * This function checks if the port is USB Power Delivery (PD) compliant -
581      * https://www.usb.org/usb-charger-pd. All of the power and data roles must be supported for a
582      * port to be PD compliant.
583      *
584      * @return true if the port is PD compliant.
585      */
586     @FlaggedApi(Flags.FLAG_ENABLE_IS_PD_COMPLIANT_API)
isPdCompliant()587     public boolean isPdCompliant() {
588         return isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_DEVICE)
589                 && isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_HOST)
590                 && isRoleCombinationSupported(POWER_ROLE_SOURCE, DATA_ROLE_DEVICE)
591                 && isRoleCombinationSupported(POWER_ROLE_SOURCE, DATA_ROLE_HOST);
592     }
593 
594     /**
595      * Get the supported role combinations.
596      */
getSupportedRoleCombinations()597     public int getSupportedRoleCombinations() {
598         return mSupportedRoleCombinations;
599     }
600 
601     /**
602      * Returns contaminant detection status.
603      *
604      * @hide
605      */
getContaminantDetectionStatus()606     public @ContaminantDetectionStatus int getContaminantDetectionStatus() {
607         return mContaminantDetectionStatus;
608     }
609 
610     /**
611      * Returns contamiant protection status.
612      *
613      * @hide
614      */
getContaminantProtectionStatus()615     public @ContaminantProtectionStatus int getContaminantProtectionStatus() {
616         return mContaminantProtectionStatus;
617     }
618 
619     /**
620      * Returns UsbData status.
621      *
622      * @return Current USB data status of the port with one or more of the following values
623      *         {@link #DATA_STATUS_UNKNOWN}, {@link #DATA_STATUS_ENABLED},
624      *         {@link #DATA_STATUS_DISABLED_OVERHEAT}, {@link #DATA_STATUS_DISABLED_CONTAMINANT},
625      *         {@link #DATA_STATUS_DISABLED_DOCK}, {@link #DATA_STATUS_DISABLED_FORCE},
626      *         {@link #DATA_STATUS_DISABLED_DEBUG}, {@link #DATA_STATUS_DISABLED_DOCK_HOST_MODE},
627      *         {@link #DATA_STATUS_DISABLED_DOCK_DEVICE_MODE}
628      */
getUsbDataStatus()629     public @UsbDataStatus int getUsbDataStatus() {
630         return mUsbDataStatus;
631     }
632 
633     /**
634      * Returns whether power transfer is limited.
635      *
636      * @return true when power transfer is limited.
637      *         false otherwise.
638      */
isPowerTransferLimited()639     public boolean isPowerTransferLimited() {
640         return mPowerTransferLimited;
641     }
642 
643     /**
644      * Returns the connection status of the power brick.
645      *
646      * @return {@link #POWER_BRICK_STATUS_UNKNOWN}
647      *         or {@link #POWER_BRICK_STATUS_CONNECTED}
648      *         or {@link #POWER_BRICK_STATUS_DISCONNECTED}
649      */
getPowerBrickConnectionStatus()650     public @PowerBrickConnectionStatus int getPowerBrickConnectionStatus() {
651         return mPowerBrickConnectionStatus;
652     }
653 
654     /**
655      * Returns non compliant reasons, if any, for the connected
656      * charger/cable/accessory/USB port.
657      *
658      * @return array including {@link #COMPLIANCE_WARNING_OTHER},
659      *         {@link #COMPLIANCE_WARNING_DEBUG_ACCESSORY},
660      *         {@link #COMPLIANCE_WARNING_BC_1_2},
661      *         {@link #COMPLIANCE_WARNING_MISSING_RP}.
662      */
663     @CheckResult
664     @NonNull
getComplianceWarnings()665     public @ComplianceWarning int[] getComplianceWarnings() {
666         return mComplianceWarnings;
667     }
668 
669     /**
670      * Returns the plug state of the attached cable/adapter.
671      *
672      */
getPlugState()673     public @PlugState int getPlugState() {
674         return mPlugState;
675     }
676 
677     /**
678      * Returns the DisplayPortInfo of the USB Port, if applicable.
679      *
680      * @return an instance of type DisplayPortInfo
681      *         or null if not applicable.
682      */
683     @Nullable
getDisplayPortAltModeInfo()684     public DisplayPortAltModeInfo getDisplayPortAltModeInfo() {
685         return (mDisplayPortAltModeInfo == null) ? null : mDisplayPortAltModeInfo;
686     }
687 
688     @NonNull
689     @Override
toString()690     public String toString() {
691         StringBuilder mString = new StringBuilder("UsbPortStatus{connected=" + isConnected()
692                 + ", currentMode=" + UsbPort.modeToString(mCurrentMode)
693                 + ", currentPowerRole=" + UsbPort.powerRoleToString(mCurrentPowerRole)
694                 + ", currentDataRole=" + UsbPort.dataRoleToString(mCurrentDataRole)
695                 + ", supportedRoleCombinations="
696                         + UsbPort.roleCombinationsToString(mSupportedRoleCombinations)
697                 + ", contaminantDetectionStatus="
698                         + getContaminantDetectionStatus()
699                 + ", contaminantProtectionStatus="
700                         + getContaminantProtectionStatus()
701                 + ", usbDataStatus="
702                         + UsbPort.usbDataStatusToString(getUsbDataStatus())
703                 + ", isPowerTransferLimited="
704                         + isPowerTransferLimited()
705                 + ", powerBrickConnectionStatus="
706                         + UsbPort
707                             .powerBrickConnectionStatusToString(getPowerBrickConnectionStatus())
708                 + ", complianceWarnings="
709                         + UsbPort.complianceWarningsToString(getComplianceWarnings())
710                 + ", plugState="
711                         + getPlugState()
712                 + ", displayPortAltModeInfo="
713                         + mDisplayPortAltModeInfo
714                 + "}");
715         return mString.toString();
716     }
717 
718     @Override
describeContents()719     public int describeContents() {
720         return 0;
721     }
722 
723     @Override
writeToParcel(Parcel dest, int flags)724     public void writeToParcel(Parcel dest, int flags) {
725         dest.writeInt(mCurrentMode);
726         dest.writeInt(mCurrentPowerRole);
727         dest.writeInt(mCurrentDataRole);
728         dest.writeInt(mSupportedRoleCombinations);
729         dest.writeInt(mContaminantProtectionStatus);
730         dest.writeInt(mContaminantDetectionStatus);
731         dest.writeInt(mUsbDataStatus);
732         dest.writeBoolean(mPowerTransferLimited);
733         dest.writeInt(mPowerBrickConnectionStatus);
734         dest.writeIntArray(mComplianceWarnings);
735         dest.writeInt(mPlugState);
736         if (mDisplayPortAltModeInfo == null) {
737             dest.writeBoolean(false);
738         } else {
739             dest.writeBoolean(true);
740             mDisplayPortAltModeInfo.writeToParcel(dest, 0);
741         }
742     }
743 
744     public static final @NonNull Parcelable.Creator<UsbPortStatus> CREATOR =
745             new Parcelable.Creator<UsbPortStatus>() {
746         @Override
747         public UsbPortStatus createFromParcel(Parcel in) {
748             int currentMode = in.readInt();
749             int currentPowerRole = in.readInt();
750             int currentDataRole = in.readInt();
751             int supportedRoleCombinations = in.readInt();
752             int contaminantProtectionStatus = in.readInt();
753             int contaminantDetectionStatus = in.readInt();
754             int usbDataStatus = in.readInt();
755             boolean powerTransferLimited = in.readBoolean();
756             int powerBrickConnectionStatus = in.readInt();
757             @ComplianceWarning int[] complianceWarnings = in.createIntArray();
758             int plugState = in.readInt();
759             boolean supportsDisplayPortAltMode = in.readBoolean();
760             DisplayPortAltModeInfo displayPortAltModeInfo;
761             if (supportsDisplayPortAltMode) {
762                 displayPortAltModeInfo = DisplayPortAltModeInfo.CREATOR.createFromParcel(in);
763             } else {
764                 displayPortAltModeInfo = null;
765             }
766             return new UsbPortStatus(currentMode, currentPowerRole, currentDataRole,
767                     supportedRoleCombinations, contaminantProtectionStatus,
768                     contaminantDetectionStatus, usbDataStatus, powerTransferLimited,
769                     powerBrickConnectionStatus,
770                     complianceWarnings, plugState, displayPortAltModeInfo);
771         }
772 
773         @Override
774         public UsbPortStatus[] newArray(int size) {
775             return new UsbPortStatus[size];
776         }
777     };
778 
779     /**
780      * Builder is used to create {@link UsbPortStatus} objects.
781      *
782      * @hide
783      */
784     public static final class Builder {
785         private @UsbPortMode int mCurrentMode;
786         private @UsbPowerRole int mCurrentPowerRole;
787         private @UsbDataRole int mCurrentDataRole;
788         private int mSupportedRoleCombinations;
789         private @ContaminantProtectionStatus int mContaminantProtectionStatus;
790         private @ContaminantDetectionStatus int mContaminantDetectionStatus;
791         private boolean mPowerTransferLimited;
792         private @UsbDataStatus int mUsbDataStatus;
793         private @PowerBrickConnectionStatus int mPowerBrickConnectionStatus;
794         private @ComplianceWarning int[] mComplianceWarnings;
795         private @PlugState int mPlugState;
796         private @Nullable DisplayPortAltModeInfo mDisplayPortAltModeInfo;
797 
Builder()798         public Builder() {
799             mCurrentMode = MODE_NONE;
800             mCurrentPowerRole = POWER_ROLE_NONE;
801             mCurrentDataRole = DATA_ROLE_NONE;
802             mContaminantProtectionStatus = CONTAMINANT_PROTECTION_NONE;
803             mContaminantDetectionStatus = CONTAMINANT_DETECTION_NOT_SUPPORTED;
804             mUsbDataStatus = DATA_STATUS_UNKNOWN;
805             mPowerBrickConnectionStatus = POWER_BRICK_STATUS_UNKNOWN;
806             mComplianceWarnings = new int[] {};
807             mPlugState = PLUG_STATE_UNKNOWN;
808             mDisplayPortAltModeInfo = null;
809         }
810 
811         /**
812          * Sets the current mode of {@link UsbPortStatus}
813          *
814          * @return Instance of {@link Builder}
815          */
816         @NonNull
setCurrentMode(@sbPortMode int currentMode)817         public Builder setCurrentMode(@UsbPortMode int currentMode) {
818             mCurrentMode = currentMode;
819             return this;
820         }
821 
822         /**
823          * Sets the current power role and data role of {@link UsbPortStatus}
824          *
825          * @return Instance of {@link Builder}
826          */
827         @NonNull
setCurrentRoles(@sbPowerRole int currentPowerRole, @UsbDataRole int currentDataRole)828         public Builder setCurrentRoles(@UsbPowerRole int currentPowerRole,
829                 @UsbDataRole int currentDataRole) {
830             mCurrentPowerRole = currentPowerRole;
831             mCurrentDataRole = currentDataRole;
832             return this;
833         }
834 
835         /**
836          * Sets supported role combinations of {@link UsbPortStatus}
837          *
838          * @return Instance of {@link Builder}
839          */
840         @NonNull
setSupportedRoleCombinations(int supportedRoleCombinations)841         public Builder setSupportedRoleCombinations(int supportedRoleCombinations) {
842             mSupportedRoleCombinations = supportedRoleCombinations;
843             return this;
844         }
845 
846         /**
847          * Sets current contaminant status of {@link UsbPortStatus}
848          *
849          * @return Instance of {@link Builder}
850          */
851         @NonNull
setContaminantStatus( @ontaminantProtectionStatus int contaminantProtectionStatus, @ContaminantDetectionStatus int contaminantDetectionStatus)852         public Builder setContaminantStatus(
853                 @ContaminantProtectionStatus int contaminantProtectionStatus,
854                 @ContaminantDetectionStatus int contaminantDetectionStatus) {
855             mContaminantProtectionStatus = contaminantProtectionStatus;
856             mContaminantDetectionStatus = contaminantDetectionStatus;
857             return this;
858         }
859 
860         /**
861          * Sets power limit power transfer of {@link UsbPortStatus}
862          *
863          * @return Instance of {@link Builder}
864          */
865         @NonNull
setPowerTransferLimited(boolean powerTransferLimited)866         public Builder setPowerTransferLimited(boolean powerTransferLimited) {
867             mPowerTransferLimited = powerTransferLimited;
868             return this;
869         }
870 
871         /**
872          * Sets the USB data status of {@link UsbPortStatus}
873          *
874          * @return Instance of {@link Builder}
875          */
876         @NonNull
setUsbDataStatus(@sbDataStatus int usbDataStatus)877         public Builder setUsbDataStatus(@UsbDataStatus int usbDataStatus) {
878             mUsbDataStatus = usbDataStatus;
879             return this;
880         }
881 
882         /**
883          * Sets the power brick connection status of {@link UsbPortStatus}
884          *
885          * @return Instance of {@link Builder}
886          */
887         @NonNull
setPowerBrickConnectionStatus( @owerBrickConnectionStatus int powerBrickConnectionStatus)888         public Builder setPowerBrickConnectionStatus(
889                 @PowerBrickConnectionStatus int powerBrickConnectionStatus) {
890             mPowerBrickConnectionStatus = powerBrickConnectionStatus;
891             return this;
892         }
893 
894         /**
895          * Sets the non-compliant charger reasons of {@link UsbPortStatus}
896          *
897          * @return Instance of {@link Builder}
898          */
899         @NonNull
setComplianceWarnings( @onNull int[] complianceWarnings)900         public Builder setComplianceWarnings(
901                 @NonNull int[] complianceWarnings) {
902             mComplianceWarnings = complianceWarnings == null ? new int[] {} :
903                     complianceWarnings;
904             return this;
905         }
906 
907         /**
908          * Sets the plug orientation of {@link UsbPortStatus}
909          *
910          * @return Instance of {@link Builder}
911          */
912         @NonNull
setPlugState(int plugState)913         public Builder setPlugState(int plugState) {
914             mPlugState = plugState;
915             return this;
916         }
917 
918         /**
919          * Sets the plug orientation of {@link UsbPortStatus}
920          *
921          * @return Instance of {@link Builder}
922          */
923         @NonNull
setDisplayPortAltModeInfo( @ullable DisplayPortAltModeInfo displayPortAltModeInfo)924         public Builder setDisplayPortAltModeInfo(
925                 @Nullable DisplayPortAltModeInfo displayPortAltModeInfo) {
926             mDisplayPortAltModeInfo = displayPortAltModeInfo;
927             return this;
928         }
929 
930         /**
931          * Creates the {@link UsbPortStatus} object.
932          */
933         @NonNull
build()934         public UsbPortStatus build() {
935             UsbPortStatus status = new UsbPortStatus(mCurrentMode, mCurrentPowerRole,
936                     mCurrentDataRole, mSupportedRoleCombinations, mContaminantProtectionStatus,
937                     mContaminantDetectionStatus, mUsbDataStatus, mPowerTransferLimited,
938                     mPowerBrickConnectionStatus, mComplianceWarnings,
939                     mPlugState, mDisplayPortAltModeInfo);
940             return status;
941         }
942     };
943 }
944