Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d85ef285 authored by Jerry Zhang's avatar Jerry Zhang Committed by Android (Google) Code Review
Browse files

Merge "Update USB settings screen" into pi-dev

parents ef0278ae 55d10dff
Loading
Loading
Loading
Loading
+21 −11
Original line number Original line Diff line number Diff line
@@ -8135,7 +8135,7 @@
    <!-- Title of one of the choices in a dialog (with title defined in usb_use) that lets the user
    <!-- Title of one of the choices in a dialog (with title defined in usb_use) that lets the user
         select what the USB connection for this device should be used for. This choice
         select what the USB connection for this device should be used for. This choice
         is for charging only. -->
         is for charging only. -->
    <string name="usb_use_charging_only">Charge this device</string>
    <string name="usb_use_charging_only">No data transfer</string>
    <!-- Decription of one of the choices in a dialog (with title defined in usb_use) that lets the
    <!-- Decription of one of the choices in a dialog (with title defined in usb_use) that lets the
         user select what the USB connection for this device should be used for. This choice
         user select what the USB connection for this device should be used for. This choice
         is for charging only. -->
         is for charging only. -->
@@ -8143,11 +8143,7 @@
    <!-- Title of one of the choices in a dialog (with title defined in usb_use) that lets the user
    <!-- Title of one of the choices in a dialog (with title defined in usb_use) that lets the user
         select what the USB connection for this device should be used for. This choice
         select what the USB connection for this device should be used for. This choice
         is for powering the other device only. -->
         is for powering the other device only. -->
    <string name="usb_use_power_only">Charging connected device</string>
    <string name="usb_use_power_only">Charge connected device</string>
    <!-- Decription of one of the choices in a dialog (with title defined in usb_use) that lets the
         user select what the USB connection for this device should be used for. This choice
         is for powering the other device. -->
    <string name="usb_use_power_only_desc">Other settings unavailable when turned on</string>
    <!-- Title of one of the choices in a dialog (with title defined in usb_use) that lets the user
    <!-- Title of one of the choices in a dialog (with title defined in usb_use) that lets the user
         select what the USB connection for this device should be used for. This choice
         select what the USB connection for this device should be used for. This choice
         is for transferring files via MTP. -->
         is for transferring files via MTP. -->
@@ -8180,17 +8176,31 @@
         for this device should be used for. These options are more commonly used.
         for this device should be used for. These options are more commonly used.
         Choices are usb_use_file_transfer.-->
         Choices are usb_use_file_transfer.-->
    <string name="usb_use">Use USB for</string>
    <string name="usb_use">Use USB for</string>
    <!-- The title used in a dialog which lets the user select what the USB connection
         for this device should be used for. These options are less commonly used.
         Choices are usb_use_tethering, usb_use_photo_transfers, usb_use_MIDI, and usb_use_power_only.-->
    <string name="usb_use_also">Also use USB for</string>
    <!-- The label that leads to the Default USB configuration window. -->
    <!-- The label that leads to the Default USB configuration window. -->
    <string name="usb_default_label">Default USB Configuration</string>
    <string name="usb_default_label">Default USB configuration</string>
    <!-- Description at the footer of the default USB configuration window that describes how the setting works. -->
    <!-- Description at the footer of the default USB configuration window that describes how the setting works. -->
    <string name="usb_default_info">When another device is connected and your phone is unlocked, these settings will be applied. Only connect to trusted devices.</string>
    <string name="usb_default_info">When another device is connected and your phone is unlocked, these settings will be applied. Only connect to trusted devices.</string>
    <!-- Settings item title for USB preference [CHAR LIMIT=35] -->
    <!-- Settings item title for USB preference [CHAR LIMIT=35] -->
    <string name="usb_pref">USB</string>
    <string name="usb_pref">USB</string>
    <!-- Settings screen title for USB preference [CHAR LIMIT=35] -->
    <string name="usb_preference">USB Preferences</string>
    <!-- The title used in USB Preferences which lets the user select whether USB
         should be in host or device mode. -->
    <string name="usb_control_title">USB controlled by</string>
    <!-- The option in USB Preferences for selecting USB to be in host mode. This allows
         the user to connect peripherals such as a mouse or flash drive to the device. -->
    <string name="usb_control_host">Connected device</string>
    <!-- The option in USB Preferences for selecting USB to be in device mode. This allows
         the device to provide services such as file transfer or tethering to another device. -->
    <string name="usb_control_device">This device</string>
    <!-- The summary text that appears under a USB control option while it is in the process of
         switching control or power. -->
    <string name="usb_switching">Switching...</string>
    <!-- The summary text that appears under a USB control option when switching control or power has
         failed. -->
    <string name="usb_switching_failed">Couldn\'t switch</string>
    <!-- Settings item summary for USB preference when set to charging only [CHAR LIMIT=NONE] -->
    <!-- Settings item summary for USB preference when set to charging only [CHAR LIMIT=NONE] -->
    <string name="usb_summary_charging_only">Charging this device</string>
    <string name="usb_summary_charging_only">Charging this device</string>
+9 −5
Original line number Original line Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<!--
<!--
  Copyright (C) 2017 The Android Open Source Project
  Copyright (C) 2018 The Android Open Source Project


  Licensed under the Apache License, Version 2.0 (the "License");
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  you may not use this file except in compliance with the License.
@@ -17,7 +17,8 @@
<PreferenceScreen
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res-auto"
    xmlns:settings="http://schemas.android.com/apk/res-auto"
    android:title="@string/device_details_title">
    android:title="@string/usb_preference"
    android:key="usb_details_fragment">


    <com.android.settings.applications.LayoutPreference
    <com.android.settings.applications.LayoutPreference
        android:key="usb_device_header"
        android:key="usb_device_header"
@@ -25,11 +26,14 @@
        android:selectable="false"/>
        android:selectable="false"/>


    <PreferenceCategory
    <PreferenceCategory
        android:key="usb_main_options"
        android:key="usb_details_data_role"
        android:title="@string/usb_control_title"/>

    <PreferenceCategory
        android:key="usb_details_functions"
        android:title="@string/usb_use"/>
        android:title="@string/usb_use"/>


    <PreferenceCategory
    <PreferenceCategory
        android:key="usb_secondary_options"
        android:key="usb_details_power_role"/>
        android:title="@string/usb_use_also"/>


</PreferenceScreen>
</PreferenceScreen>
+31 −24
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@
package com.android.settings.connecteddevice.usb;
package com.android.settings.connecteddevice.usb;


import android.content.Context;
import android.content.Context;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbPort;
import android.support.annotation.VisibleForTesting;
import android.support.annotation.VisibleForTesting;


import com.android.settings.R;
import com.android.settings.R;
@@ -38,9 +40,10 @@ public class ConnectedUsbDeviceUpdater {


    @VisibleForTesting
    @VisibleForTesting
    UsbConnectionBroadcastReceiver.UsbConnectionListener mUsbConnectionListener =
    UsbConnectionBroadcastReceiver.UsbConnectionListener mUsbConnectionListener =
            (connected, newMode) -> {
            (connected, functions, powerRole, dataRole) -> {
                if (connected) {
                if (connected) {
                    mUsbPreference.setSummary(getSummary(mUsbBackend.getCurrentMode()));
                    mUsbPreference.setSummary(getSummary(mUsbBackend.getCurrentFunctions(),
                            mUsbBackend.getPowerRole()));
                    mDevicePreferenceCallback.onDeviceAdded(mUsbPreference);
                    mDevicePreferenceCallback.onDeviceAdded(mUsbPreference);
                } else {
                } else {
                    mDevicePreferenceCallback.onDeviceRemoved(mUsbPreference);
                    mDevicePreferenceCallback.onDeviceRemoved(mUsbPreference);
@@ -94,28 +97,32 @@ public class ConnectedUsbDeviceUpdater {
        mUsbReceiver.register();
        mUsbReceiver.register();
    }
    }


    public static int getSummary(int mode) {
    public static int getSummary(long functions, int power) {
        switch (mode) {
        switch (power) {
            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_NONE:
            case UsbPort.POWER_ROLE_SINK:
                return R.string.usb_summary_charging_only;
                if (functions == UsbManager.FUNCTION_MTP) {
            case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_NONE:
                return R.string.usb_summary_power_only;
            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MTP:
                    return R.string.usb_summary_file_transfers;
                    return R.string.usb_summary_file_transfers;
            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_PTP:
                } else if (functions == UsbManager.FUNCTION_RNDIS) {
                    return R.string.usb_summary_tether;
                } else if (functions == UsbManager.FUNCTION_PTP) {
                    return R.string.usb_summary_photo_transfers;
                    return R.string.usb_summary_photo_transfers;
            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MIDI:
                } else if (functions == UsbManager.FUNCTION_MIDI) {
                    return R.string.usb_summary_MIDI;
                    return R.string.usb_summary_MIDI;
            case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_TETHER:
                } else {
                return R.string.usb_summary_tether;
                    return R.string.usb_summary_charging_only;
            case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_MTP:
                }
            case UsbPort.POWER_ROLE_SOURCE:
                if (functions == UsbManager.FUNCTION_MTP) {
                    return R.string.usb_summary_file_transfers_power;
                    return R.string.usb_summary_file_transfers_power;
            case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_PTP:
                } else if (functions == UsbManager.FUNCTION_RNDIS) {
                    return R.string.usb_summary_tether_power;
                } else if (functions == UsbManager.FUNCTION_PTP) {
                    return R.string.usb_summary_photo_transfers_power;
                    return R.string.usb_summary_photo_transfers_power;
            case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_MIDI:
                } else if (functions == UsbManager.FUNCTION_MIDI) {
                    return R.string.usb_summary_MIDI_power;
                    return R.string.usb_summary_MIDI_power;
            case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_TETHER:
                } else {
                return R.string.usb_summary_tether_power;
                    return R.string.usb_summary_power_only;
                }
            default:
            default:
                return R.string.usb_summary_charging_only;
                return R.string.usb_summary_charging_only;
        }
        }
+120 −121
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@
 */
 */
package com.android.settings.connecteddevice.usb;
package com.android.settings.connecteddevice.usb;


import android.annotation.Nullable;
import android.content.Context;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbManager;
@@ -27,18 +28,13 @@ import android.support.annotation.VisibleForTesting;
import com.android.settings.wrapper.UsbManagerWrapper;
import com.android.settings.wrapper.UsbManagerWrapper;
import com.android.settings.wrapper.UserManagerWrapper;
import com.android.settings.wrapper.UserManagerWrapper;


/**
 * Provides access to underlying system USB functionality.
 */
public class UsbBackend {
public class UsbBackend {


    public static final int MODE_POWER_MASK  = 0x01;
    static final int PD_ROLE_SWAP_TIMEOUT_MS = 3000;
    public static final int MODE_POWER_SINK   = 0x00;
    static final int NONPD_ROLE_SWAP_TIMEOUT_MS = 15000;
    public static final int MODE_POWER_SOURCE = 0x01;

    public static final int MODE_DATA_MASK  = 0x0f << 1;
    public static final int MODE_DATA_NONE   = 0;
    public static final int MODE_DATA_MTP    = 0x01 << 1;
    public static final int MODE_DATA_PTP    = 0x01 << 2;
    public static final int MODE_DATA_MIDI   = 0x01 << 3;
    public static final int MODE_DATA_TETHER   = 0x01 << 4;


    private final boolean mFileTransferRestricted;
    private final boolean mFileTransferRestricted;
    private final boolean mFileTransferRestrictedBySystem;
    private final boolean mFileTransferRestrictedBySystem;
@@ -48,13 +44,13 @@ public class UsbBackend {
    private final boolean mTetheringSupported;
    private final boolean mTetheringSupported;


    private UsbManager mUsbManager;
    private UsbManager mUsbManager;
    @VisibleForTesting
    private UsbManagerWrapper mUsbManagerWrapper;
    UsbManagerWrapper mUsbManagerWrapper;

    @Nullable
    private UsbPort mPort;
    private UsbPort mPort;
    @Nullable
    private UsbPortStatus mPortStatus;
    private UsbPortStatus mPortStatus;


    private Context mContext;

    public UsbBackend(Context context) {
    public UsbBackend(Context context) {
        this(context, new UserManagerWrapper(UserManager.get(context)), null);
        this(context, new UserManagerWrapper(UserManager.get(context)), null);
    }
    }
@@ -62,7 +58,6 @@ public class UsbBackend {
    @VisibleForTesting
    @VisibleForTesting
    public UsbBackend(Context context, UserManagerWrapper userManagerWrapper,
    public UsbBackend(Context context, UserManagerWrapper userManagerWrapper,
            UsbManagerWrapper usbManagerWrapper) {
            UsbManagerWrapper usbManagerWrapper) {
        mContext = context;
        mUsbManager = context.getSystemService(UsbManager.class);
        mUsbManager = context.getSystemService(UsbManager.class);


        mUsbManagerWrapper = usbManagerWrapper;
        mUsbManagerWrapper = usbManagerWrapper;
@@ -77,139 +72,143 @@ public class UsbBackend {


        mMidiSupported = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI);
        mMidiSupported = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI);
        ConnectivityManager cm =
        ConnectivityManager cm =
                (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        mTetheringSupported = cm.isTetheringSupported();
        mTetheringSupported = cm.isTetheringSupported();


        UsbPort[] ports = mUsbManager.getPorts();
        updatePorts();
        if (ports == null) {
            return;
        }
        // For now look for a connected port, in the future we should identify port in the
        // notification and pick based on that.
        final int N = ports.length;
        for (int i = 0; i < N; i++) {
            UsbPortStatus status = mUsbManager.getPortStatus(ports[i]);
            if (status.isConnected()) {
                mPort = ports[i];
                mPortStatus = status;
                break;
    }
    }

    public long getCurrentFunctions() {
        return mUsbManagerWrapper.getCurrentFunctions();
    }
    }

    public void setCurrentFunctions(long functions) {
        mUsbManager.setCurrentFunctions(functions);
    }
    }


    public int getCurrentMode() {
    public long getDefaultUsbFunctions() {
        if (mPort != null) {
        return mUsbManager.getScreenUnlockedFunctions();
            int power = mPortStatus.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE
                    && mPortStatus.isConnected()
                    ? MODE_POWER_SOURCE : MODE_POWER_SINK;
            return power | getUsbDataMode();
    }
    }
        return MODE_POWER_SINK | getUsbDataMode();

    public void setDefaultUsbFunctions(long functions) {
        mUsbManager.setScreenUnlockedFunctions(functions);
    }
    }


    public int getUsbDataMode() {
    public boolean areFunctionsSupported(long functions) {
        return usbFunctionToMode(mUsbManagerWrapper.getCurrentFunctions());
        if ((!mMidiSupported && (functions & UsbManager.FUNCTION_MIDI) != 0)
                || (!mTetheringSupported && (functions & UsbManager.FUNCTION_RNDIS) != 0)) {
            return false;
        }
        return !(areFunctionDisallowed(functions) || areFunctionsDisallowedBySystem(functions));
    }
    }


    public void setDefaultUsbMode(int mode) {
    public int getPowerRole() {
        mUsbManager.setScreenUnlockedFunctions(modeToUsbFunction(mode & MODE_DATA_MASK));
        updatePorts();
        return mPortStatus == null ? UsbPort.POWER_ROLE_NONE : mPortStatus.getCurrentPowerRole();
    }
    }


    public int getDefaultUsbMode() {
    public int getDataRole() {
        return usbFunctionToMode(mUsbManager.getScreenUnlockedFunctions());
        updatePorts();
        return mPortStatus == null ? UsbPort.DATA_ROLE_NONE : mPortStatus.getCurrentDataRole();
    }
    }


    public void setMode(int mode) {
    public void setPowerRole(int role) {
        int newDataRole = getDataRole();
        if (!areAllRolesSupported()) {
            switch (role) {
                case UsbPort.POWER_ROLE_SINK:
                    newDataRole = UsbPort.DATA_ROLE_DEVICE;
                    break;
                case UsbPort.POWER_ROLE_SOURCE:
                    newDataRole = UsbPort.DATA_ROLE_HOST;
                    break;
                default:
                    newDataRole = UsbPort.DATA_ROLE_NONE;
            }
        }
        if (mPort != null) {
        if (mPort != null) {
            int powerRole = modeToPower(mode);
            mUsbManager.setPortRoles(mPort, role, newDataRole);
            // If we aren't using any data modes and we support host mode, then go to host mode
            // so maybe? the other device can provide data if it wants, otherwise go into device
            // mode because we have no choice.
            int dataRole = (mode & MODE_DATA_MASK) == MODE_DATA_NONE
                    && mPortStatus.isRoleCombinationSupported(powerRole, UsbPort.DATA_ROLE_HOST)
                    ? UsbPort.DATA_ROLE_HOST : UsbPort.DATA_ROLE_DEVICE;
            mUsbManager.setPortRoles(mPort, powerRole, dataRole);
        }
        }
        setUsbFunction(mode & MODE_DATA_MASK);
    }
    }


    public boolean isModeDisallowed(int mode) {
    public void setDataRole(int role) {
        if (mFileTransferRestricted && ((mode & MODE_DATA_MASK) == MODE_DATA_MTP
        int newPowerRole = getPowerRole();
                || (mode & MODE_DATA_MASK) == MODE_DATA_PTP)) {
        if (!areAllRolesSupported()) {
            return true;
            switch (role) {
        } else if (mTetheringRestricted && ((mode & MODE_DATA_MASK) == MODE_DATA_TETHER)) {
                case UsbPort.DATA_ROLE_DEVICE:
            return true;
                    newPowerRole = UsbPort.POWER_ROLE_SINK;
                    break;
                case UsbPort.DATA_ROLE_HOST:
                    newPowerRole = UsbPort.POWER_ROLE_SOURCE;
                    break;
                default:
                    newPowerRole = UsbPort.POWER_ROLE_NONE;
            }
        }
        if (mPort != null) {
            mUsbManager.setPortRoles(mPort, newPowerRole, role);
        }
        }
        return false;
    }
    }


    public boolean isModeDisallowedBySystem(int mode) {
    public boolean areAllRolesSupported() {
        if (mFileTransferRestrictedBySystem && ((mode & MODE_DATA_MASK) == MODE_DATA_MTP
        return mPort != null && mPortStatus != null
                || (mode & MODE_DATA_MASK) == MODE_DATA_PTP)) {
                && mPortStatus
            return true;
                .isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE)
        } else if (mTetheringRestrictedBySystem && ((mode & MODE_DATA_MASK) == MODE_DATA_TETHER)) {
                && mPortStatus
            return true;
                .isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_HOST)
                && mPortStatus
                .isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_DEVICE)
                && mPortStatus
                .isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST);
    }
    }
        return false;

    public static String usbFunctionsToString(long functions) {
        // TODO replace with UsbManager.usbFunctionsToString once supported by Roboelectric
        return Long.toBinaryString(functions);
    }
    }


    public boolean isModeSupported(int mode) {
    public static long usbFunctionsFromString(String functions) {
        if (!mMidiSupported && (mode & MODE_DATA_MASK) == MODE_DATA_MIDI) {
        // TODO replace with UsbManager.usbFunctionsFromString once supported by Roboelectric
            return false;
        return Long.parseLong(functions, 2);
    }
    }
        if (!mTetheringSupported && (mode & MODE_DATA_MASK) == MODE_DATA_TETHER) {

                return false;
    public static String dataRoleToString(int role) {
        return Integer.toString(role);
    }
    }
        if (mPort != null) {

            int power = modeToPower(mode);
    public static int dataRoleFromString(String role) {
            if ((mode & MODE_DATA_MASK) != 0) {
        return Integer.parseInt(role);
                // We have a port and data, need to be in device mode.
                return mPortStatus.isRoleCombinationSupported(power,
                        UsbPort.DATA_ROLE_DEVICE);
            } else {
                // No data needed, we can do this power mode in either device or host.
                return mPortStatus.isRoleCombinationSupported(power, UsbPort.DATA_ROLE_DEVICE)
                        || mPortStatus.isRoleCombinationSupported(power, UsbPort.DATA_ROLE_HOST);
            }
        }
        // No port, support sink modes only.
        return (mode & MODE_POWER_MASK) != MODE_POWER_SOURCE;
    }

    private static int usbFunctionToMode(long functions) {
        if (functions == UsbManager.FUNCTION_MTP) {
            return MODE_DATA_MTP;
        } else if (functions == UsbManager.FUNCTION_PTP) {
            return MODE_DATA_PTP;
        } else if (functions == UsbManager.FUNCTION_MIDI) {
            return MODE_DATA_MIDI;
        } else if (functions == UsbManager.FUNCTION_RNDIS) {
            return MODE_DATA_TETHER;
        }
        return MODE_DATA_NONE;
    }

    private static long modeToUsbFunction(int mode) {
        switch (mode) {
            case MODE_DATA_MTP:
                return UsbManager.FUNCTION_MTP;
            case MODE_DATA_PTP:
                return UsbManager.FUNCTION_PTP;
            case MODE_DATA_MIDI:
                return UsbManager.FUNCTION_MIDI;
            case MODE_DATA_TETHER:
                return UsbManager.FUNCTION_RNDIS;
            default:
                return UsbManager.FUNCTION_NONE;
    }
    }

    private boolean areFunctionDisallowed(long functions) {
        return (mFileTransferRestricted && ((functions & UsbManager.FUNCTION_MTP) != 0
                || (functions & UsbManager.FUNCTION_PTP) != 0))
                || (mTetheringRestricted && ((functions & UsbManager.FUNCTION_RNDIS) != 0));
    }
    }


    private static int modeToPower(int mode) {
    private boolean areFunctionsDisallowedBySystem(long functions) {
        return (mode & MODE_POWER_MASK) == MODE_POWER_SOURCE
        return (mFileTransferRestrictedBySystem && ((functions & UsbManager.FUNCTION_MTP) != 0
                ? UsbPort.POWER_ROLE_SOURCE : UsbPort.POWER_ROLE_SINK;
                || (functions & UsbManager.FUNCTION_PTP) != 0))
                || (mTetheringRestrictedBySystem && ((functions & UsbManager.FUNCTION_RNDIS) != 0));
    }
    }


    private void setUsbFunction(int mode) {
    private void updatePorts() {
        mUsbManager.setCurrentFunctions(modeToUsbFunction(mode));
        mPort = null;
        mPortStatus = null;
        UsbPort[] ports = mUsbManager.getPorts();
        if (ports == null) {
            return;
        }
        // For now look for a connected port, in the future we should identify port in the
        // notification and pick based on that.
        final int N = ports.length;
        for (int i = 0; i < N; i++) {
            UsbPortStatus status = mUsbManager.getPortStatus(ports[i]);
            if (status.isConnected()) {
                mPort = ports[i];
                mPortStatus = status;
                break;
            }
        }
    }
    }
}
}
+22 −18
Original line number Original line Diff line number Diff line
@@ -15,8 +15,6 @@
 */
 */
package com.android.settings.connecteddevice.usb;
package com.android.settings.connecteddevice.usb;




import android.content.BroadcastReceiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
@@ -37,15 +35,22 @@ public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements
    private Context mContext;
    private Context mContext;
    private UsbConnectionListener mUsbConnectionListener;
    private UsbConnectionListener mUsbConnectionListener;
    private boolean mListeningToUsbEvents;
    private boolean mListeningToUsbEvents;
    private int mMode;
    private boolean mConnected;
    private UsbBackend mUsbBackend;
    private UsbBackend mUsbBackend;


    private boolean mConnected;
    private long mFunctions;
    private int mDataRole;
    private int mPowerRole;

    public UsbConnectionBroadcastReceiver(Context context,
    public UsbConnectionBroadcastReceiver(Context context,
            UsbConnectionListener usbConnectionListener, UsbBackend backend) {
            UsbConnectionListener usbConnectionListener, UsbBackend backend) {
        mContext = context;
        mContext = context;
        mUsbConnectionListener = usbConnectionListener;
        mUsbConnectionListener = usbConnectionListener;
        mUsbBackend = backend;
        mUsbBackend = backend;

        mFunctions = UsbManager.FUNCTION_NONE;
        mDataRole = UsbPort.DATA_ROLE_NONE;
        mPowerRole = UsbPort.POWER_ROLE_NONE;
    }
    }


    @Override
    @Override
@@ -54,42 +59,41 @@ public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements
            mConnected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED)
            mConnected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED)
                    || intent.getExtras().getBoolean(UsbManager.USB_HOST_CONNECTED);
                    || intent.getExtras().getBoolean(UsbManager.USB_HOST_CONNECTED);
            if (mConnected) {
            if (mConnected) {
                mMode &= UsbBackend.MODE_POWER_MASK;
                long functions = UsbManager.FUNCTION_NONE;
                if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MTP)
                if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MTP)
                        && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) {
                        && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) {
                    mMode |= UsbBackend.MODE_DATA_MTP;
                    functions |= UsbManager.FUNCTION_MTP;
                }
                }
                if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_PTP)
                if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_PTP)
                        && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) {
                        && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) {
                    mMode |= UsbBackend.MODE_DATA_PTP;
                    functions |= UsbManager.FUNCTION_PTP;
                }
                }
                if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MIDI)) {
                if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MIDI)) {
                    mMode |= UsbBackend.MODE_DATA_MIDI;
                    functions |= UsbManager.FUNCTION_MIDI;
                }
                }
                if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_RNDIS)) {
                if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_RNDIS)) {
                    mMode |= UsbBackend.MODE_DATA_TETHER;
                    functions |= UsbManager.FUNCTION_RNDIS;
                }
                }
                mFunctions = functions;
                mDataRole = mUsbBackend.getDataRole();
                mPowerRole = mUsbBackend.getPowerRole();
            }
            }
        } else if (UsbManager.ACTION_USB_PORT_CHANGED.equals(intent.getAction())) {
        } else if (UsbManager.ACTION_USB_PORT_CHANGED.equals(intent.getAction())) {
            mMode &= UsbBackend.MODE_DATA_MASK;
            UsbPortStatus portStatus = intent.getExtras()
            UsbPortStatus portStatus = intent.getExtras()
                    .getParcelable(UsbManager.EXTRA_PORT_STATUS);
                    .getParcelable(UsbManager.EXTRA_PORT_STATUS);
            if (portStatus != null) {
            if (portStatus != null) {
                mConnected = portStatus.isConnected();
                mDataRole = portStatus.getCurrentDataRole();
                if (mConnected) {
                mPowerRole = portStatus.getCurrentPowerRole();
                    mMode |= portStatus.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE
                            ? UsbBackend.MODE_POWER_SOURCE : UsbBackend.MODE_POWER_SINK;
                }
            }
            }
        }
        }
        if (mUsbConnectionListener != null) {
        if (mUsbConnectionListener != null) {
            mUsbConnectionListener.onUsbConnectionChanged(mConnected, mMode);
            mUsbConnectionListener.onUsbConnectionChanged(mConnected, mFunctions, mPowerRole,
                    mDataRole);
        }
        }
    }
    }


    public void register() {
    public void register() {
        if (!mListeningToUsbEvents) {
        if (!mListeningToUsbEvents) {
            mMode = mUsbBackend.getCurrentMode();
            mConnected = false;
            mConnected = false;
            final IntentFilter intentFilter = new IntentFilter();
            final IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(UsbManager.ACTION_USB_STATE);
            intentFilter.addAction(UsbManager.ACTION_USB_STATE);
@@ -124,6 +128,6 @@ public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements
     * Interface definition for a callback to be invoked when usb connection is changed.
     * Interface definition for a callback to be invoked when usb connection is changed.
     */
     */
    interface UsbConnectionListener {
    interface UsbConnectionListener {
        void onUsbConnectionChanged(boolean connected, int newMode);
        void onUsbConnectionChanged(boolean connected, long functions, int powerRole, int dataRole);
    }
    }
}
}
Loading