Update USB settings screen
Screen now handles data role and power
role switching as separate categories.
Change the UsbBackend api to use predefined
constants. Split out data and power direction
changes into separate functions.
Add tests for new controllers and new backend
functionality.
Bug: 72829348
Test: passes
Change-Id: I28b96cf49463fa4f3a4b6be41c57d5841731fbd6
This commit is contained in:
@@ -8130,7 +8130,7 @@
|
||||
<!-- 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
|
||||
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
|
||||
user select what the USB connection for this device should be used for. This choice
|
||||
is for charging only. -->
|
||||
@@ -8138,11 +8138,7 @@
|
||||
<!-- 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
|
||||
is for powering the other device only. -->
|
||||
<string name="usb_use_power_only">Charging 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>
|
||||
<string name="usb_use_power_only">Charge connected device</string>
|
||||
<!-- 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
|
||||
is for transferring files via MTP. -->
|
||||
@@ -8175,17 +8171,31 @@
|
||||
for this device should be used for. These options are more commonly used.
|
||||
Choices are usb_use_file_transfer.-->
|
||||
<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. -->
|
||||
<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. -->
|
||||
<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] -->
|
||||
<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] -->
|
||||
<string name="usb_summary_charging_only">Charging this device</string>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?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");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -17,7 +17,8 @@
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
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
|
||||
android:key="usb_device_header"
|
||||
@@ -25,11 +26,14 @@
|
||||
android:selectable="false"/>
|
||||
|
||||
<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"/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="usb_secondary_options"
|
||||
android:title="@string/usb_use_also"/>
|
||||
android:key="usb_details_power_role"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
@@ -16,6 +16,8 @@
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.hardware.usb.UsbPort;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -38,9 +40,10 @@ public class ConnectedUsbDeviceUpdater {
|
||||
|
||||
@VisibleForTesting
|
||||
UsbConnectionBroadcastReceiver.UsbConnectionListener mUsbConnectionListener =
|
||||
(connected, newMode) -> {
|
||||
(connected, functions, powerRole, dataRole) -> {
|
||||
if (connected) {
|
||||
mUsbPreference.setSummary(getSummary(mUsbBackend.getCurrentMode()));
|
||||
mUsbPreference.setSummary(getSummary(mUsbBackend.getCurrentFunctions(),
|
||||
mUsbBackend.getPowerRole()));
|
||||
mDevicePreferenceCallback.onDeviceAdded(mUsbPreference);
|
||||
} else {
|
||||
mDevicePreferenceCallback.onDeviceRemoved(mUsbPreference);
|
||||
@@ -94,28 +97,32 @@ public class ConnectedUsbDeviceUpdater {
|
||||
mUsbReceiver.register();
|
||||
}
|
||||
|
||||
public static int getSummary(int mode) {
|
||||
switch (mode) {
|
||||
case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_NONE:
|
||||
return R.string.usb_summary_charging_only;
|
||||
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;
|
||||
case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_PTP:
|
||||
return R.string.usb_summary_photo_transfers;
|
||||
case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_MIDI:
|
||||
return R.string.usb_summary_MIDI;
|
||||
case UsbBackend.MODE_POWER_SINK | UsbBackend.MODE_DATA_TETHER:
|
||||
return R.string.usb_summary_tether;
|
||||
case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_MTP:
|
||||
return R.string.usb_summary_file_transfers_power;
|
||||
case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_PTP:
|
||||
return R.string.usb_summary_photo_transfers_power;
|
||||
case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_MIDI:
|
||||
return R.string.usb_summary_MIDI_power;
|
||||
case UsbBackend.MODE_POWER_SOURCE | UsbBackend.MODE_DATA_TETHER:
|
||||
return R.string.usb_summary_tether_power;
|
||||
public static int getSummary(long functions, int power) {
|
||||
switch (power) {
|
||||
case UsbPort.POWER_ROLE_SINK:
|
||||
if (functions == UsbManager.FUNCTION_MTP) {
|
||||
return R.string.usb_summary_file_transfers;
|
||||
} 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;
|
||||
} else if (functions == UsbManager.FUNCTION_MIDI) {
|
||||
return R.string.usb_summary_MIDI;
|
||||
} else {
|
||||
return R.string.usb_summary_charging_only;
|
||||
}
|
||||
case UsbPort.POWER_ROLE_SOURCE:
|
||||
if (functions == UsbManager.FUNCTION_MTP) {
|
||||
return R.string.usb_summary_file_transfers_power;
|
||||
} 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;
|
||||
} else if (functions == UsbManager.FUNCTION_MIDI) {
|
||||
return R.string.usb_summary_MIDI_power;
|
||||
} else {
|
||||
return R.string.usb_summary_power_only;
|
||||
}
|
||||
default:
|
||||
return R.string.usb_summary_charging_only;
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
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.UserManagerWrapper;
|
||||
|
||||
/**
|
||||
* Provides access to underlying system USB functionality.
|
||||
*/
|
||||
public class UsbBackend {
|
||||
|
||||
public static final int MODE_POWER_MASK = 0x01;
|
||||
public static final int MODE_POWER_SINK = 0x00;
|
||||
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;
|
||||
static final int PD_ROLE_SWAP_TIMEOUT_MS = 3000;
|
||||
static final int NONPD_ROLE_SWAP_TIMEOUT_MS = 15000;
|
||||
|
||||
private final boolean mFileTransferRestricted;
|
||||
private final boolean mFileTransferRestrictedBySystem;
|
||||
@@ -48,12 +44,12 @@ public class UsbBackend {
|
||||
private final boolean mTetheringSupported;
|
||||
|
||||
private UsbManager mUsbManager;
|
||||
@VisibleForTesting
|
||||
UsbManagerWrapper mUsbManagerWrapper;
|
||||
private UsbPort mPort;
|
||||
private UsbPortStatus mPortStatus;
|
||||
private UsbManagerWrapper mUsbManagerWrapper;
|
||||
|
||||
private Context mContext;
|
||||
@Nullable
|
||||
private UsbPort mPort;
|
||||
@Nullable
|
||||
private UsbPortStatus mPortStatus;
|
||||
|
||||
public UsbBackend(Context context) {
|
||||
this(context, new UserManagerWrapper(UserManager.get(context)), null);
|
||||
@@ -62,7 +58,6 @@ public class UsbBackend {
|
||||
@VisibleForTesting
|
||||
public UsbBackend(Context context, UserManagerWrapper userManagerWrapper,
|
||||
UsbManagerWrapper usbManagerWrapper) {
|
||||
mContext = context;
|
||||
mUsbManager = context.getSystemService(UsbManager.class);
|
||||
|
||||
mUsbManagerWrapper = usbManagerWrapper;
|
||||
@@ -77,9 +72,129 @@ public class UsbBackend {
|
||||
|
||||
mMidiSupported = context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MIDI);
|
||||
ConnectivityManager cm =
|
||||
(ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
mTetheringSupported = cm.isTetheringSupported();
|
||||
|
||||
updatePorts();
|
||||
}
|
||||
|
||||
public long getCurrentFunctions() {
|
||||
return mUsbManagerWrapper.getCurrentFunctions();
|
||||
}
|
||||
|
||||
public void setCurrentFunctions(long functions) {
|
||||
mUsbManager.setCurrentFunctions(functions);
|
||||
}
|
||||
|
||||
public long getDefaultUsbFunctions() {
|
||||
return mUsbManager.getScreenUnlockedFunctions();
|
||||
}
|
||||
|
||||
public void setDefaultUsbFunctions(long functions) {
|
||||
mUsbManager.setScreenUnlockedFunctions(functions);
|
||||
}
|
||||
|
||||
public boolean areFunctionsSupported(long functions) {
|
||||
if ((!mMidiSupported && (functions & UsbManager.FUNCTION_MIDI) != 0)
|
||||
|| (!mTetheringSupported && (functions & UsbManager.FUNCTION_RNDIS) != 0)) {
|
||||
return false;
|
||||
}
|
||||
return !(areFunctionDisallowed(functions) || areFunctionsDisallowedBySystem(functions));
|
||||
}
|
||||
|
||||
public int getPowerRole() {
|
||||
updatePorts();
|
||||
return mPortStatus == null ? UsbPort.POWER_ROLE_NONE : mPortStatus.getCurrentPowerRole();
|
||||
}
|
||||
|
||||
public int getDataRole() {
|
||||
updatePorts();
|
||||
return mPortStatus == null ? UsbPort.DATA_ROLE_NONE : mPortStatus.getCurrentDataRole();
|
||||
}
|
||||
|
||||
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) {
|
||||
mUsbManager.setPortRoles(mPort, role, newDataRole);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDataRole(int role) {
|
||||
int newPowerRole = getPowerRole();
|
||||
if (!areAllRolesSupported()) {
|
||||
switch (role) {
|
||||
case UsbPort.DATA_ROLE_DEVICE:
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean areAllRolesSupported() {
|
||||
return mPort != null && mPortStatus != null
|
||||
&& mPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE)
|
||||
&& mPortStatus
|
||||
.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);
|
||||
}
|
||||
|
||||
public static String usbFunctionsToString(long functions) {
|
||||
// TODO replace with UsbManager.usbFunctionsToString once supported by Roboelectric
|
||||
return Long.toBinaryString(functions);
|
||||
}
|
||||
|
||||
public static long usbFunctionsFromString(String functions) {
|
||||
// TODO replace with UsbManager.usbFunctionsFromString once supported by Roboelectric
|
||||
return Long.parseLong(functions, 2);
|
||||
}
|
||||
|
||||
public static String dataRoleToString(int role) {
|
||||
return Integer.toString(role);
|
||||
}
|
||||
|
||||
public static int dataRoleFromString(String role) {
|
||||
return Integer.parseInt(role);
|
||||
}
|
||||
|
||||
private boolean areFunctionDisallowed(long functions) {
|
||||
return (mFileTransferRestricted && ((functions & UsbManager.FUNCTION_MTP) != 0
|
||||
|| (functions & UsbManager.FUNCTION_PTP) != 0))
|
||||
|| (mTetheringRestricted && ((functions & UsbManager.FUNCTION_RNDIS) != 0));
|
||||
}
|
||||
|
||||
private boolean areFunctionsDisallowedBySystem(long functions) {
|
||||
return (mFileTransferRestrictedBySystem && ((functions & UsbManager.FUNCTION_MTP) != 0
|
||||
|| (functions & UsbManager.FUNCTION_PTP) != 0))
|
||||
|| (mTetheringRestrictedBySystem && ((functions & UsbManager.FUNCTION_RNDIS) != 0));
|
||||
}
|
||||
|
||||
private void updatePorts() {
|
||||
mPort = null;
|
||||
mPortStatus = null;
|
||||
UsbPort[] ports = mUsbManager.getPorts();
|
||||
if (ports == null) {
|
||||
return;
|
||||
@@ -96,120 +211,4 @@ public class UsbBackend {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurrentMode() {
|
||||
if (mPort != null) {
|
||||
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 int getUsbDataMode() {
|
||||
return usbFunctionToMode(mUsbManagerWrapper.getCurrentFunctions());
|
||||
}
|
||||
|
||||
public void setDefaultUsbMode(int mode) {
|
||||
mUsbManager.setScreenUnlockedFunctions(modeToUsbFunction(mode & MODE_DATA_MASK));
|
||||
}
|
||||
|
||||
public int getDefaultUsbMode() {
|
||||
return usbFunctionToMode(mUsbManager.getScreenUnlockedFunctions());
|
||||
}
|
||||
|
||||
public void setMode(int mode) {
|
||||
if (mPort != null) {
|
||||
int powerRole = modeToPower(mode);
|
||||
// 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) {
|
||||
if (mFileTransferRestricted && ((mode & MODE_DATA_MASK) == MODE_DATA_MTP
|
||||
|| (mode & MODE_DATA_MASK) == MODE_DATA_PTP)) {
|
||||
return true;
|
||||
} else if (mTetheringRestricted && ((mode & MODE_DATA_MASK) == MODE_DATA_TETHER)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isModeDisallowedBySystem(int mode) {
|
||||
if (mFileTransferRestrictedBySystem && ((mode & MODE_DATA_MASK) == MODE_DATA_MTP
|
||||
|| (mode & MODE_DATA_MASK) == MODE_DATA_PTP)) {
|
||||
return true;
|
||||
} else if (mTetheringRestrictedBySystem && ((mode & MODE_DATA_MASK) == MODE_DATA_TETHER)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isModeSupported(int mode) {
|
||||
if (!mMidiSupported && (mode & MODE_DATA_MASK) == MODE_DATA_MIDI) {
|
||||
return false;
|
||||
}
|
||||
if (!mTetheringSupported && (mode & MODE_DATA_MASK) == MODE_DATA_TETHER) {
|
||||
return false;
|
||||
}
|
||||
if (mPort != null) {
|
||||
int power = modeToPower(mode);
|
||||
if ((mode & MODE_DATA_MASK) != 0) {
|
||||
// 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 static int modeToPower(int mode) {
|
||||
return (mode & MODE_POWER_MASK) == MODE_POWER_SOURCE
|
||||
? UsbPort.POWER_ROLE_SOURCE : UsbPort.POWER_ROLE_SINK;
|
||||
}
|
||||
|
||||
private void setUsbFunction(int mode) {
|
||||
mUsbManager.setCurrentFunctions(modeToUsbFunction(mode));
|
||||
}
|
||||
}
|
||||
|
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -37,15 +35,22 @@ public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements
|
||||
private Context mContext;
|
||||
private UsbConnectionListener mUsbConnectionListener;
|
||||
private boolean mListeningToUsbEvents;
|
||||
private int mMode;
|
||||
private boolean mConnected;
|
||||
private UsbBackend mUsbBackend;
|
||||
|
||||
private boolean mConnected;
|
||||
private long mFunctions;
|
||||
private int mDataRole;
|
||||
private int mPowerRole;
|
||||
|
||||
public UsbConnectionBroadcastReceiver(Context context,
|
||||
UsbConnectionListener usbConnectionListener, UsbBackend backend) {
|
||||
mContext = context;
|
||||
mUsbConnectionListener = usbConnectionListener;
|
||||
mUsbBackend = backend;
|
||||
|
||||
mFunctions = UsbManager.FUNCTION_NONE;
|
||||
mDataRole = UsbPort.DATA_ROLE_NONE;
|
||||
mPowerRole = UsbPort.POWER_ROLE_NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,42 +59,41 @@ public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements
|
||||
mConnected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED)
|
||||
|| intent.getExtras().getBoolean(UsbManager.USB_HOST_CONNECTED);
|
||||
if (mConnected) {
|
||||
mMode &= UsbBackend.MODE_POWER_MASK;
|
||||
long functions = UsbManager.FUNCTION_NONE;
|
||||
if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MTP)
|
||||
&& 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)
|
||||
&& 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)) {
|
||||
mMode |= UsbBackend.MODE_DATA_MIDI;
|
||||
functions |= UsbManager.FUNCTION_MIDI;
|
||||
}
|
||||
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())) {
|
||||
mMode &= UsbBackend.MODE_DATA_MASK;
|
||||
UsbPortStatus portStatus = intent.getExtras()
|
||||
.getParcelable(UsbManager.EXTRA_PORT_STATUS);
|
||||
if (portStatus != null) {
|
||||
mConnected = portStatus.isConnected();
|
||||
if (mConnected) {
|
||||
mMode |= portStatus.getCurrentPowerRole() == UsbPort.POWER_ROLE_SOURCE
|
||||
? UsbBackend.MODE_POWER_SOURCE : UsbBackend.MODE_POWER_SINK;
|
||||
}
|
||||
mDataRole = portStatus.getCurrentDataRole();
|
||||
mPowerRole = portStatus.getCurrentPowerRole();
|
||||
}
|
||||
}
|
||||
if (mUsbConnectionListener != null) {
|
||||
mUsbConnectionListener.onUsbConnectionChanged(mConnected, mMode);
|
||||
mUsbConnectionListener.onUsbConnectionChanged(mConnected, mFunctions, mPowerRole,
|
||||
mDataRole);
|
||||
}
|
||||
}
|
||||
|
||||
public void register() {
|
||||
if (!mListeningToUsbEvents) {
|
||||
mMode = mUsbBackend.getCurrentMode();
|
||||
mConnected = false;
|
||||
final IntentFilter intentFilter = new IntentFilter();
|
||||
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 UsbConnectionListener {
|
||||
void onUsbConnectionChanged(boolean connected, int newMode);
|
||||
void onUsbConnectionChanged(boolean connected, long functions, int powerRole, int dataRole);
|
||||
}
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@ package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
@@ -41,14 +40,6 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment {
|
||||
@VisibleForTesting
|
||||
UsbBackend mUsbBackend;
|
||||
|
||||
private static final String[] FUNCTIONS_LIST = {
|
||||
UsbManager.USB_FUNCTION_NONE,
|
||||
UsbManager.USB_FUNCTION_MTP,
|
||||
UsbManager.USB_FUNCTION_RNDIS,
|
||||
UsbManager.USB_FUNCTION_MIDI,
|
||||
UsbManager.USB_FUNCTION_PTP
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
@@ -76,33 +67,13 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment {
|
||||
@Override
|
||||
protected List<? extends CandidateInfo> getCandidates() {
|
||||
List<CandidateInfo> ret = Lists.newArrayList();
|
||||
for (final String option : FUNCTIONS_LIST) {
|
||||
int newMode = 0;
|
||||
final String title;
|
||||
final Context context = getContext();
|
||||
if (option.equals(UsbManager.USB_FUNCTION_MTP)) {
|
||||
newMode = UsbBackend.MODE_DATA_MTP;
|
||||
title = context.getString(R.string.usb_use_file_transfers);
|
||||
} else if (option.equals(UsbManager.USB_FUNCTION_PTP)) {
|
||||
newMode = UsbBackend.MODE_DATA_PTP;
|
||||
title = context.getString(R.string.usb_use_photo_transfers);
|
||||
} else if (option.equals(UsbManager.USB_FUNCTION_MIDI)) {
|
||||
newMode = UsbBackend.MODE_DATA_MIDI;
|
||||
title = context.getString(R.string.usb_use_MIDI);
|
||||
} else if (option.equals(UsbManager.USB_FUNCTION_RNDIS)) {
|
||||
newMode = UsbBackend.MODE_DATA_TETHER;
|
||||
title = context.getString(R.string.usb_use_tethering);
|
||||
} else if (option.equals(UsbManager.USB_FUNCTION_NONE)) {
|
||||
newMode = UsbBackend.MODE_DATA_NONE;
|
||||
title = context.getString(R.string.usb_use_charging_only);
|
||||
} else {
|
||||
title = "";
|
||||
}
|
||||
for (final long option : UsbDetailsFunctionsController.FUNCTIONS_MAP.keySet()) {
|
||||
final String title = getContext().getString(
|
||||
UsbDetailsFunctionsController.FUNCTIONS_MAP.get(option));
|
||||
final String key = UsbBackend.usbFunctionsToString(option);
|
||||
|
||||
// Only show supported and allowed options
|
||||
if (mUsbBackend.isModeSupported(newMode)
|
||||
&& !mUsbBackend.isModeDisallowedBySystem(newMode)
|
||||
&& !mUsbBackend.isModeDisallowed(newMode)) {
|
||||
// Only show supported functions
|
||||
if (mUsbBackend.areFunctionsSupported(option)) {
|
||||
ret.add(new CandidateInfo(true /* enabled */) {
|
||||
@Override
|
||||
public CharSequence loadLabel() {
|
||||
@@ -116,7 +87,7 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment {
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return option;
|
||||
return key;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -126,34 +97,14 @@ public class UsbDefaultFragment extends RadioButtonPickerFragment {
|
||||
|
||||
@Override
|
||||
protected String getDefaultKey() {
|
||||
switch (mUsbBackend.getDefaultUsbMode()) {
|
||||
case UsbBackend.MODE_DATA_MTP:
|
||||
return UsbManager.USB_FUNCTION_MTP;
|
||||
case UsbBackend.MODE_DATA_PTP:
|
||||
return UsbManager.USB_FUNCTION_PTP;
|
||||
case UsbBackend.MODE_DATA_TETHER:
|
||||
return UsbManager.USB_FUNCTION_RNDIS;
|
||||
case UsbBackend.MODE_DATA_MIDI:
|
||||
return UsbManager.USB_FUNCTION_MIDI;
|
||||
default:
|
||||
return UsbManager.USB_FUNCTION_NONE;
|
||||
}
|
||||
return UsbBackend.usbFunctionsToString(mUsbBackend.getDefaultUsbFunctions());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setDefaultKey(String key) {
|
||||
int thisMode = UsbBackend.MODE_DATA_NONE;
|
||||
if (key.equals(UsbManager.USB_FUNCTION_MTP)) {
|
||||
thisMode = UsbBackend.MODE_DATA_MTP;
|
||||
} else if (key.equals(UsbManager.USB_FUNCTION_PTP)) {
|
||||
thisMode = UsbBackend.MODE_DATA_PTP;
|
||||
} else if (key.equals(UsbManager.USB_FUNCTION_RNDIS)) {
|
||||
thisMode = UsbBackend.MODE_DATA_TETHER;
|
||||
} else if (key.equals(UsbManager.USB_FUNCTION_MIDI)) {
|
||||
thisMode = UsbBackend.MODE_DATA_MIDI;
|
||||
}
|
||||
long functions = UsbBackend.usbFunctionsFromString(key);
|
||||
if (!Utils.isMonkeyRunning()) {
|
||||
mUsbBackend.setDefaultUsbMode(thisMode);
|
||||
mUsbBackend.setDefaultUsbFunctions(functions);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@@ -17,9 +17,10 @@
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v14.preference.PreferenceFragment;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
|
||||
@@ -30,14 +31,18 @@ public abstract class UsbDetailsController extends AbstractPreferenceController
|
||||
implements PreferenceControllerMixin {
|
||||
|
||||
protected final Context mContext;
|
||||
protected final PreferenceFragment mFragment;
|
||||
protected final UsbDetailsFragment mFragment;
|
||||
protected final UsbBackend mUsbBackend;
|
||||
|
||||
public UsbDetailsController(Context context, PreferenceFragment fragment, UsbBackend backend) {
|
||||
@VisibleForTesting
|
||||
Handler mHandler;
|
||||
|
||||
public UsbDetailsController(Context context, UsbDetailsFragment fragment, UsbBackend backend) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
mFragment = fragment;
|
||||
mUsbBackend = backend;
|
||||
mHandler = new Handler(context.getMainLooper());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,9 +51,13 @@ public abstract class UsbDetailsController extends AbstractPreferenceController
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when the USB mode has changed and the controller needs to update.
|
||||
* @param newMode the new mode, made up of OR'd values from UsbBackend
|
||||
* Called when the USB state has changed, so that this component can be refreshed.
|
||||
*
|
||||
* @param connected Whether USB is connected
|
||||
* @param functions A mask of the currently enabled functions
|
||||
* @param powerRole The current power role
|
||||
* @param dataRole The current data role
|
||||
*/
|
||||
@UiThread
|
||||
protected abstract void refresh(int newMode);
|
||||
protected abstract void refresh(boolean connected, long functions, int powerRole, int dataRole);
|
||||
}
|
||||
|
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbPort;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.widget.RadioButtonPreference;
|
||||
|
||||
/**
|
||||
* This class controls the radio buttons for switching between
|
||||
* USB device and host mode.
|
||||
*/
|
||||
public class UsbDetailsDataRoleController extends UsbDetailsController
|
||||
implements RadioButtonPreference.OnClickListener {
|
||||
|
||||
private PreferenceCategory mPreferenceCategory;
|
||||
private RadioButtonPreference mDevicePref;
|
||||
private RadioButtonPreference mHostPref;
|
||||
|
||||
private RadioButtonPreference mNextRolePref;
|
||||
|
||||
private final Runnable mFailureCallback = () -> {
|
||||
if (mNextRolePref != null) {
|
||||
mNextRolePref.setSummary(R.string.usb_switching_failed);
|
||||
mNextRolePref = null;
|
||||
}
|
||||
};
|
||||
|
||||
public UsbDetailsDataRoleController(Context context, UsbDetailsFragment fragment,
|
||||
UsbBackend backend) {
|
||||
super(context, fragment, backend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreferenceCategory = (PreferenceCategory) screen.findPreference(getPreferenceKey());
|
||||
mHostPref = makeRadioPreference(UsbBackend.dataRoleToString(UsbPort.DATA_ROLE_HOST),
|
||||
R.string.usb_control_host);
|
||||
mDevicePref = makeRadioPreference(UsbBackend.dataRoleToString(UsbPort.DATA_ROLE_DEVICE),
|
||||
R.string.usb_control_device);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refresh(boolean connected, long functions, int powerRole, int dataRole) {
|
||||
if (dataRole == UsbPort.DATA_ROLE_DEVICE) {
|
||||
mDevicePref.setChecked(true);
|
||||
mHostPref.setChecked(false);
|
||||
mPreferenceCategory.setEnabled(true);
|
||||
} else if (dataRole == UsbPort.DATA_ROLE_HOST) {
|
||||
mDevicePref.setChecked(false);
|
||||
mHostPref.setChecked(true);
|
||||
mPreferenceCategory.setEnabled(true);
|
||||
} else if (!connected || dataRole == UsbPort.DATA_ROLE_NONE){
|
||||
mPreferenceCategory.setEnabled(false);
|
||||
if (mNextRolePref == null) {
|
||||
// Disconnected with no operation pending, so clear subtexts
|
||||
mHostPref.setSummary("");
|
||||
mDevicePref.setSummary("");
|
||||
}
|
||||
}
|
||||
|
||||
if (mNextRolePref != null && dataRole != UsbPort.DATA_ROLE_NONE) {
|
||||
if (UsbBackend.dataRoleFromString(mNextRolePref.getKey()) == dataRole) {
|
||||
// Clear switching text if switch succeeded
|
||||
mNextRolePref.setSummary("");
|
||||
} else {
|
||||
// Set failure text if switch failed
|
||||
mNextRolePref.setSummary(R.string.usb_switching_failed);
|
||||
}
|
||||
mNextRolePref = null;
|
||||
mHandler.removeCallbacks(mFailureCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRadioButtonClicked(RadioButtonPreference preference) {
|
||||
int role = UsbBackend.dataRoleFromString(preference.getKey());
|
||||
if (role != mUsbBackend.getDataRole() && mNextRolePref == null
|
||||
&& !Utils.isMonkeyRunning()) {
|
||||
mUsbBackend.setDataRole(role);
|
||||
mNextRolePref = preference;
|
||||
preference.setSummary(R.string.usb_switching);
|
||||
|
||||
mHandler.postDelayed(mFailureCallback,
|
||||
mUsbBackend.areAllRolesSupported() ? UsbBackend.PD_ROLE_SWAP_TIMEOUT_MS
|
||||
: UsbBackend.NONPD_ROLE_SWAP_TIMEOUT_MS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return !Utils.isMonkeyRunning();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return "usb_details_data_role";
|
||||
}
|
||||
|
||||
private RadioButtonPreference makeRadioPreference(String key, int titleId) {
|
||||
RadioButtonPreference pref = new RadioButtonPreference(mPreferenceCategory.getContext());
|
||||
pref.setKey(key);
|
||||
pref.setTitle(titleId);
|
||||
pref.setOnClickListener(this);
|
||||
mPreferenceCategory.addPreference(pref);
|
||||
return pref;
|
||||
}
|
||||
}
|
@@ -17,14 +17,12 @@
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.os.Bundle;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
@@ -48,13 +46,9 @@ public class UsbDetailsFragment extends DashboardFragment {
|
||||
UsbConnectionBroadcastReceiver mUsbReceiver;
|
||||
|
||||
private UsbConnectionBroadcastReceiver.UsbConnectionListener mUsbConnectionListener =
|
||||
(connected, newMode) -> {
|
||||
if (!connected) {
|
||||
this.finish();
|
||||
} else {
|
||||
for (UsbDetailsController controller : mControllers) {
|
||||
controller.refresh(newMode);
|
||||
}
|
||||
(connected, functions, powerRole, dataRole) -> {
|
||||
for (UsbDetailsController controller : mControllers) {
|
||||
controller.refresh(connected, functions, powerRole, dataRole);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -78,6 +72,10 @@ public class UsbDetailsFragment extends DashboardFragment {
|
||||
super.onCreatePreferences(savedInstanceState, rootKey);
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return mUsbReceiver.isConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
|
||||
mUsbBackend = new UsbBackend(context);
|
||||
@@ -86,21 +84,16 @@ public class UsbDetailsFragment extends DashboardFragment {
|
||||
mUsbBackend);
|
||||
this.getLifecycle().addObserver(mUsbReceiver);
|
||||
|
||||
List<AbstractPreferenceController> ret = new ArrayList<>();
|
||||
ret.addAll(mControllers);
|
||||
return ret;
|
||||
return new ArrayList<>(mControllers);
|
||||
}
|
||||
|
||||
private static List<UsbDetailsController> createControllerList(Context context,
|
||||
UsbBackend usbBackend, DashboardFragment fragment) {
|
||||
UsbBackend usbBackend, UsbDetailsFragment fragment) {
|
||||
List<UsbDetailsController> ret = new ArrayList<>();
|
||||
ret.add(new UsbDetailsHeaderController(context, fragment, usbBackend));
|
||||
ret.add(new UsbDetailsProfilesController(context, fragment,
|
||||
usbBackend, Lists.newArrayList(UsbManager.USB_FUNCTION_MTP), "usb_main_options"));
|
||||
ret.add(new UsbDetailsProfilesController(context, fragment,
|
||||
usbBackend, Lists.newArrayList(UsbDetailsProfilesController.KEY_POWER,
|
||||
UsbManager.USB_FUNCTION_RNDIS, UsbManager.USB_FUNCTION_MIDI,
|
||||
UsbManager.USB_FUNCTION_PTP), "usb_secondary_options"));
|
||||
ret.add(new UsbDetailsDataRoleController(context, fragment, usbBackend));
|
||||
ret.add(new UsbDetailsFunctionsController(context, fragment, usbBackend));
|
||||
ret.add(new UsbDetailsPowerRoleController(context, fragment, usbBackend));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -112,7 +105,9 @@ public class UsbDetailsFragment extends DashboardFragment {
|
||||
@Override
|
||||
public List<SearchIndexableResource> getXmlResourcesToIndex(
|
||||
Context context, boolean enabled) {
|
||||
return new ArrayList<>();
|
||||
SearchIndexableResource res = new SearchIndexableResource(context);
|
||||
res.xmlResId = R.xml.usb_details_fragment;
|
||||
return Lists.newArrayList(res);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -123,9 +118,8 @@ public class UsbDetailsFragment extends DashboardFragment {
|
||||
@Override
|
||||
public List<AbstractPreferenceController> createPreferenceControllers(
|
||||
Context context) {
|
||||
List<AbstractPreferenceController> ret = new ArrayList<>();
|
||||
ret.addAll(createControllerList(context, new UsbBackend(context), null));
|
||||
return ret;
|
||||
return new ArrayList<>(
|
||||
createControllerList(context, new UsbBackend(context), null));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.hardware.usb.UsbPort;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.widget.RadioButtonPreference;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This class controls the radio buttons for choosing between different USB functions.
|
||||
*/
|
||||
public class UsbDetailsFunctionsController extends UsbDetailsController
|
||||
implements RadioButtonPreference.OnClickListener {
|
||||
|
||||
static final Map<Long, Integer> FUNCTIONS_MAP = new LinkedHashMap<>();
|
||||
|
||||
static {
|
||||
FUNCTIONS_MAP.put(UsbManager.FUNCTION_MTP, R.string.usb_use_file_transfers);
|
||||
FUNCTIONS_MAP.put(UsbManager.FUNCTION_RNDIS, R.string.usb_use_tethering);
|
||||
FUNCTIONS_MAP.put(UsbManager.FUNCTION_MIDI, R.string.usb_use_MIDI);
|
||||
FUNCTIONS_MAP.put(UsbManager.FUNCTION_PTP, R.string.usb_use_photo_transfers);
|
||||
FUNCTIONS_MAP.put(UsbManager.FUNCTION_NONE, R.string.usb_use_charging_only);
|
||||
}
|
||||
|
||||
private PreferenceCategory mProfilesContainer;
|
||||
|
||||
public UsbDetailsFunctionsController(Context context, UsbDetailsFragment fragment,
|
||||
UsbBackend backend) {
|
||||
super(context, fragment, backend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mProfilesContainer = (PreferenceCategory) screen.findPreference(getPreferenceKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a switch preference for the particular option, creating it if needed.
|
||||
*/
|
||||
private RadioButtonPreference getProfilePreference(String key, int titleId) {
|
||||
RadioButtonPreference pref = (RadioButtonPreference) mProfilesContainer.findPreference(key);
|
||||
if (pref == null) {
|
||||
pref = new RadioButtonPreference(mProfilesContainer.getContext());
|
||||
pref.setKey(key);
|
||||
pref.setTitle(titleId);
|
||||
pref.setOnClickListener(this);
|
||||
mProfilesContainer.addPreference(pref);
|
||||
}
|
||||
return pref;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refresh(boolean connected, long functions, int powerRole, int dataRole) {
|
||||
if (!connected || dataRole != UsbPort.DATA_ROLE_DEVICE) {
|
||||
mProfilesContainer.setEnabled(false);
|
||||
} else {
|
||||
// Functions are only available in device mode
|
||||
mProfilesContainer.setEnabled(true);
|
||||
}
|
||||
RadioButtonPreference pref;
|
||||
for (long option : FUNCTIONS_MAP.keySet()) {
|
||||
int title = FUNCTIONS_MAP.get(option);
|
||||
pref = getProfilePreference(UsbBackend.usbFunctionsToString(option), title);
|
||||
// Only show supported options
|
||||
if (mUsbBackend.areFunctionsSupported(option)) {
|
||||
pref.setChecked(functions == option);
|
||||
} else {
|
||||
mProfilesContainer.removePreference(pref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRadioButtonClicked(RadioButtonPreference preference) {
|
||||
long function = UsbBackend.usbFunctionsFromString(preference.getKey());
|
||||
if (function != mUsbBackend.getCurrentFunctions() && !Utils.isMonkeyRunning()) {
|
||||
mUsbBackend.setCurrentFunctions(function);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return !Utils.isMonkeyRunning();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return "usb_details_functions";
|
||||
}
|
||||
}
|
@@ -17,7 +17,6 @@
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v14.preference.PreferenceFragment;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -25,14 +24,14 @@ import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
|
||||
/**
|
||||
* This class adds a header with device name and current function.
|
||||
* This class adds a header with device name.
|
||||
*/
|
||||
public class UsbDetailsHeaderController extends UsbDetailsController {
|
||||
private static final String KEY_DEVICE_HEADER = "usb_device_header";
|
||||
|
||||
private EntityHeaderController mHeaderController;
|
||||
|
||||
public UsbDetailsHeaderController(Context context, PreferenceFragment fragment,
|
||||
public UsbDetailsHeaderController(Context context, UsbDetailsFragment fragment,
|
||||
UsbBackend backend) {
|
||||
super(context, fragment, backend);
|
||||
}
|
||||
@@ -44,16 +43,13 @@ public class UsbDetailsHeaderController extends UsbDetailsController {
|
||||
(LayoutPreference) screen.findPreference(KEY_DEVICE_HEADER);
|
||||
mHeaderController = EntityHeaderController.newInstance(mFragment.getActivity(), mFragment,
|
||||
headerPreference.findViewById(R.id.entity_header));
|
||||
screen.addPreference(headerPreference);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void refresh(int newMode) {
|
||||
protected void refresh(boolean connected, long functions, int powerRole, int dataRole) {
|
||||
mHeaderController.setLabel(mContext.getString(R.string.usb_pref));
|
||||
mHeaderController.setIcon(mContext.getDrawable(R.drawable.ic_usb));
|
||||
mHeaderController.setSummary(
|
||||
mContext.getString(ConnectedUsbDeviceUpdater.getSummary(newMode)));
|
||||
mHeaderController.done(mFragment.getActivity(), true /* rebindActions */);
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbPort;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.Preference.OnPreferenceClickListener;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
|
||||
/**
|
||||
* This class controls the switch for changing USB power direction.
|
||||
*/
|
||||
public class UsbDetailsPowerRoleController extends UsbDetailsController
|
||||
implements OnPreferenceClickListener {
|
||||
|
||||
private PreferenceCategory mPreferenceCategory;
|
||||
private SwitchPreference mSwitchPreference;
|
||||
|
||||
private int mNextPowerRole;
|
||||
|
||||
private final Runnable mFailureCallback = () -> {
|
||||
if (mNextPowerRole != UsbPort.POWER_ROLE_NONE) {
|
||||
mSwitchPreference.setSummary(R.string.usb_switching_failed);
|
||||
mNextPowerRole = UsbPort.POWER_ROLE_NONE;
|
||||
}
|
||||
};
|
||||
|
||||
public UsbDetailsPowerRoleController(Context context, UsbDetailsFragment fragment,
|
||||
UsbBackend backend) {
|
||||
super(context, fragment, backend);
|
||||
mNextPowerRole = UsbPort.POWER_ROLE_NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreferenceCategory = (PreferenceCategory) screen.findPreference(getPreferenceKey());
|
||||
mSwitchPreference = new SwitchPreference(mPreferenceCategory.getContext());
|
||||
mSwitchPreference.setTitle(R.string.usb_use_power_only);
|
||||
mSwitchPreference.setOnPreferenceClickListener(this);
|
||||
mPreferenceCategory.addPreference(mSwitchPreference);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refresh(boolean connected, long functions, int powerRole, int dataRole) {
|
||||
// Hide this option if this is not a PD compatible connection
|
||||
if (connected && !mUsbBackend.areAllRolesSupported()) {
|
||||
mFragment.getPreferenceScreen().removePreference(mPreferenceCategory);
|
||||
} else if (connected && mUsbBackend.areAllRolesSupported()){
|
||||
mFragment.getPreferenceScreen().addPreference(mPreferenceCategory);
|
||||
}
|
||||
if (powerRole == UsbPort.POWER_ROLE_SOURCE) {
|
||||
mSwitchPreference.setChecked(true);
|
||||
mPreferenceCategory.setEnabled(true);
|
||||
} else if (powerRole == UsbPort.POWER_ROLE_SINK) {
|
||||
mSwitchPreference.setChecked(false);
|
||||
mPreferenceCategory.setEnabled(true);
|
||||
} else if (!connected || powerRole == UsbPort.POWER_ROLE_NONE){
|
||||
mPreferenceCategory.setEnabled(false);
|
||||
if (mNextPowerRole == UsbPort.POWER_ROLE_NONE) {
|
||||
mSwitchPreference.setSummary("");
|
||||
}
|
||||
}
|
||||
|
||||
if (mNextPowerRole != UsbPort.POWER_ROLE_NONE && powerRole != UsbPort.POWER_ROLE_NONE) {
|
||||
if (mNextPowerRole == powerRole) {
|
||||
// Clear switching text if switch succeeded
|
||||
mSwitchPreference.setSummary("");
|
||||
} else {
|
||||
// Set failure text if switch failed
|
||||
mSwitchPreference.setSummary(R.string.usb_switching_failed);
|
||||
}
|
||||
mNextPowerRole = UsbPort.POWER_ROLE_NONE;
|
||||
mHandler.removeCallbacks(mFailureCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
int newRole = mSwitchPreference.isChecked() ? UsbPort.POWER_ROLE_SOURCE
|
||||
: UsbPort.POWER_ROLE_SINK;
|
||||
if (mUsbBackend.getPowerRole() != newRole && mNextPowerRole == UsbPort.POWER_ROLE_NONE
|
||||
&& !Utils.isMonkeyRunning()) {
|
||||
mUsbBackend.setPowerRole(newRole);
|
||||
|
||||
mNextPowerRole = newRole;
|
||||
mSwitchPreference.setSummary(R.string.usb_switching);
|
||||
|
||||
mHandler.postDelayed(mFailureCallback,
|
||||
mUsbBackend.areAllRolesSupported() ? UsbBackend.PD_ROLE_SWAP_TIMEOUT_MS
|
||||
: UsbBackend.NONPD_ROLE_SWAP_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
// We don't know that the action succeeded until called back in refresh()
|
||||
mSwitchPreference.setChecked(!mSwitchPreference.isChecked());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return !Utils.isMonkeyRunning();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return "usb_details_power_role";
|
||||
}
|
||||
}
|
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.support.v14.preference.PreferenceFragment;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class adds switches for toggling individual USB options, such as "transfer files",
|
||||
* "supply power", "usb tethering", etc.
|
||||
*/
|
||||
public class UsbDetailsProfilesController extends UsbDetailsController
|
||||
implements Preference.OnPreferenceClickListener {
|
||||
|
||||
static final String KEY_POWER = "power";
|
||||
|
||||
private PreferenceCategory mProfilesContainer;
|
||||
private List<String> mOptions;
|
||||
private String mKey;
|
||||
|
||||
public UsbDetailsProfilesController(Context context, PreferenceFragment fragment,
|
||||
UsbBackend backend, List<String> options, String key) {
|
||||
super(context, fragment, backend);
|
||||
mOptions = options;
|
||||
mKey = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mProfilesContainer = (PreferenceCategory) screen.findPreference(getPreferenceKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a switch preference for the particular option, creating it if needed.
|
||||
*/
|
||||
private SwitchPreference getProfilePreference(String key, int titleId) {
|
||||
SwitchPreference pref = (SwitchPreference) mProfilesContainer.findPreference(key);
|
||||
if (pref == null) {
|
||||
pref = new SwitchPreference(mProfilesContainer.getContext());
|
||||
pref.setKey(key);
|
||||
pref.setTitle(titleId);
|
||||
pref.setOnPreferenceClickListener(this);
|
||||
mProfilesContainer.addPreference(pref);
|
||||
}
|
||||
return pref;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void refresh(int mode) {
|
||||
SwitchPreference pref;
|
||||
for (String option : mOptions) {
|
||||
int newMode;
|
||||
int summary = -1;
|
||||
int title;
|
||||
if (option.equals(UsbManager.USB_FUNCTION_MTP)) {
|
||||
newMode = UsbBackend.MODE_DATA_MTP;
|
||||
title = R.string.usb_use_file_transfers;
|
||||
} else if (option.equals(KEY_POWER)) {
|
||||
newMode = UsbBackend.MODE_POWER_SOURCE;
|
||||
title = R.string.usb_use_power_only;
|
||||
summary = R.string.usb_use_power_only_desc;
|
||||
} else if (option.equals(UsbManager.USB_FUNCTION_PTP)) {
|
||||
newMode = UsbBackend.MODE_DATA_PTP;
|
||||
title = R.string.usb_use_photo_transfers;
|
||||
} else if (option.equals(UsbManager.USB_FUNCTION_MIDI)) {
|
||||
newMode = UsbBackend.MODE_DATA_MIDI;
|
||||
title = R.string.usb_use_MIDI;
|
||||
} else if (option.equals(UsbManager.USB_FUNCTION_RNDIS)) {
|
||||
newMode = UsbBackend.MODE_DATA_TETHER;
|
||||
title = R.string.usb_use_tethering;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
pref = getProfilePreference(option, title);
|
||||
// Only show supported and allowed options
|
||||
if (mUsbBackend.isModeSupported(newMode)
|
||||
&& !mUsbBackend.isModeDisallowedBySystem(newMode)
|
||||
&& !mUsbBackend.isModeDisallowed(newMode)) {
|
||||
if (summary != -1) {
|
||||
pref.setSummary(summary);
|
||||
}
|
||||
pref.setChecked((mode & newMode) != 0);
|
||||
} else {
|
||||
mProfilesContainer.removePreference(pref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
SwitchPreference profilePref = (SwitchPreference) preference;
|
||||
String key = profilePref.getKey();
|
||||
int mode = mUsbBackend.getCurrentMode();
|
||||
int thisMode = 0;
|
||||
if (key.equals(KEY_POWER)) {
|
||||
thisMode = UsbBackend.MODE_POWER_SOURCE;
|
||||
} else if (key.equals(UsbManager.USB_FUNCTION_MTP)) {
|
||||
thisMode = UsbBackend.MODE_DATA_MTP;
|
||||
} else if (key.equals(UsbManager.USB_FUNCTION_PTP)) {
|
||||
thisMode = UsbBackend.MODE_DATA_PTP;
|
||||
} else if (key.equals(UsbManager.USB_FUNCTION_RNDIS)) {
|
||||
thisMode = UsbBackend.MODE_DATA_TETHER;
|
||||
} else if (key.equals(UsbManager.USB_FUNCTION_MIDI)) {
|
||||
thisMode = UsbBackend.MODE_DATA_MIDI;
|
||||
}
|
||||
if (profilePref.isChecked()) {
|
||||
if (!key.equals(KEY_POWER)) {
|
||||
// Only one non power mode can currently be set at once.
|
||||
mode &= UsbBackend.MODE_POWER_MASK;
|
||||
}
|
||||
mode |= thisMode;
|
||||
} else {
|
||||
mode &= ~thisMode;
|
||||
}
|
||||
if (!Utils.isMonkeyRunning()) {
|
||||
mUsbBackend.setMode(mode);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return !Utils.isMonkeyRunning();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return mKey;
|
||||
}
|
||||
}
|
@@ -27,8 +27,4 @@ public class UsbManagerWrapper {
|
||||
public long getCurrentFunctions() {
|
||||
return mUsbManager.getCurrentFunctions();
|
||||
}
|
||||
|
||||
public long usbFunctionsFromString(String str) {
|
||||
return UsbManager.usbFunctionsFromString(str);
|
||||
}
|
||||
}
|
||||
|
@@ -16,10 +16,13 @@
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.hardware.usb.UsbPort;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.connecteddevice.DevicePreferenceCallback;
|
||||
@@ -60,7 +63,7 @@ public class ConnectedUsbDeviceUpdaterTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitUsbPreference_preferenceInit() {
|
||||
public void initUsbPreference_preferenceInit() {
|
||||
mDeviceUpdater.initUsbPreference(mContext);
|
||||
|
||||
assertThat(mDeviceUpdater.mUsbPreference.getTitle()).isEqualTo("USB");
|
||||
@@ -70,19 +73,19 @@ public class ConnectedUsbDeviceUpdaterTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitUsbPreference_usbConnected_preferenceAdded() {
|
||||
public void initUsbPreference_usbConnected_preferenceAdded() {
|
||||
mDeviceUpdater.initUsbPreference(mContext);
|
||||
mDeviceUpdater.mUsbConnectionListener
|
||||
.onUsbConnectionChanged(true /* connected */, UsbBackend.MODE_DATA_NONE);
|
||||
mDeviceUpdater.mUsbConnectionListener.onUsbConnectionChanged(true /* connected */,
|
||||
UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE);
|
||||
|
||||
verify(mDevicePreferenceCallback).onDeviceAdded(mDeviceUpdater.mUsbPreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitUsbPreference_usbDisconnected_preferenceRemoved() {
|
||||
public void initUsbPreference_usbDisconnected_preferenceRemoved() {
|
||||
mDeviceUpdater.initUsbPreference(mContext);
|
||||
mDeviceUpdater.mUsbConnectionListener
|
||||
.onUsbConnectionChanged(false /* connected */, UsbBackend.MODE_DATA_NONE);
|
||||
mDeviceUpdater.mUsbConnectionListener.onUsbConnectionChanged(false /* connected */,
|
||||
UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_NONE, UsbPort.DATA_ROLE_NONE);
|
||||
|
||||
verify(mDevicePreferenceCallback).onDeviceRemoved(mDeviceUpdater.mUsbPreference);
|
||||
}
|
||||
|
@@ -16,15 +16,22 @@
|
||||
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.hardware.usb.UsbPort;
|
||||
import android.hardware.usb.UsbPortStatus;
|
||||
import android.net.ConnectivityManager;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.wrapper.UsbManagerWrapper;
|
||||
import com.android.settings.wrapper.UserManagerWrapper;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -43,7 +50,13 @@ public class UsbBackendTest {
|
||||
@Mock
|
||||
private UserManagerWrapper mUserManagerWrapper;
|
||||
@Mock
|
||||
private UsbManagerWrapper mUsbManagerWrapper;
|
||||
@Mock
|
||||
private ConnectivityManager mConnectivityManager;
|
||||
@Mock
|
||||
private UsbPort mUsbPort;
|
||||
@Mock
|
||||
private UsbPortStatus mUsbPortStatus;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -53,11 +66,124 @@ public class UsbBackendTest {
|
||||
when((Object)mContext.getSystemService(UsbManager.class)).thenReturn(mUsbManager);
|
||||
when(mContext.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||
.thenReturn(mConnectivityManager);
|
||||
when(mUsbManager.getPorts()).thenReturn(new UsbPort[]{ mUsbPort });
|
||||
when(mUsbPortStatus.isConnected()).thenReturn(true);
|
||||
when(mUsbManager.getPortStatus(mUsbPort)).thenReturn(mUsbPortStatus);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructor_noUsbPort_shouldNotCrash() {
|
||||
UsbBackend usbBackend = new UsbBackend(mContext, mUserManagerWrapper, null);
|
||||
final UsbBackend usbBackend =
|
||||
new UsbBackend(mContext, mUserManagerWrapper, mUsbManagerWrapper);
|
||||
// Should not crash
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDataRole_allRolesSupported_shouldSetDataRole() {
|
||||
final UsbBackend usbBackend =
|
||||
new UsbBackend(mContext, mUserManagerWrapper, mUsbManagerWrapper);
|
||||
|
||||
when(mUsbPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE))
|
||||
.thenReturn(true);
|
||||
when(mUsbPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_HOST))
|
||||
.thenReturn(true);
|
||||
when(mUsbPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_DEVICE))
|
||||
.thenReturn(true);
|
||||
when(mUsbPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST))
|
||||
.thenReturn(true);
|
||||
when(mUsbPortStatus.getCurrentPowerRole()).thenReturn(UsbPort.POWER_ROLE_SINK);
|
||||
|
||||
usbBackend.setDataRole(UsbPort.DATA_ROLE_HOST);
|
||||
|
||||
verify(mUsbManager).setPortRoles(mUsbPort, UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_HOST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDataRole_notAllRolesSupported_shouldSetDataAndPowerRole() {
|
||||
final UsbBackend usbBackend =
|
||||
new UsbBackend(mContext, mUserManagerWrapper, mUsbManagerWrapper);
|
||||
|
||||
when(mUsbPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE))
|
||||
.thenReturn(true);
|
||||
when(mUsbPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST))
|
||||
.thenReturn(true);
|
||||
when(mUsbPortStatus.getCurrentPowerRole()).thenReturn(UsbPort.POWER_ROLE_SINK);
|
||||
|
||||
usbBackend.setDataRole(UsbPort.DATA_ROLE_HOST);
|
||||
|
||||
verify(mUsbManager)
|
||||
.setPortRoles(mUsbPort, UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setPowerRole_allRolesSupported_shouldSetPowerRole() {
|
||||
final UsbBackend usbBackend =
|
||||
new UsbBackend(mContext, mUserManagerWrapper, mUsbManagerWrapper);
|
||||
|
||||
when(mUsbPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE))
|
||||
.thenReturn(true);
|
||||
when(mUsbPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_HOST))
|
||||
.thenReturn(true);
|
||||
when(mUsbPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_DEVICE))
|
||||
.thenReturn(true);
|
||||
when(mUsbPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST))
|
||||
.thenReturn(true);
|
||||
when(mUsbPortStatus.getCurrentDataRole()).thenReturn(UsbPort.DATA_ROLE_DEVICE);
|
||||
|
||||
usbBackend.setPowerRole(UsbPort.POWER_ROLE_SOURCE);
|
||||
|
||||
verify(mUsbManager)
|
||||
.setPortRoles(mUsbPort, UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setPowerRole_notAllRolesSupported_shouldSetDataAndPowerRole() {
|
||||
final UsbBackend usbBackend =
|
||||
new UsbBackend(mContext, mUserManagerWrapper, mUsbManagerWrapper);
|
||||
|
||||
when(mUsbPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE))
|
||||
.thenReturn(true);
|
||||
when(mUsbPortStatus
|
||||
.isRoleCombinationSupported(UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST))
|
||||
.thenReturn(true);
|
||||
when(mUsbPortStatus.getCurrentDataRole()).thenReturn(UsbPort.DATA_ROLE_DEVICE);
|
||||
|
||||
usbBackend.setPowerRole(UsbPort.POWER_ROLE_SOURCE);
|
||||
|
||||
verify(mUsbManager)
|
||||
.setPortRoles(mUsbPort, UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void areFunctionsSupported_fileTransferDisallowed_shouldReturnFalse() {
|
||||
when(mUserManagerWrapper.isUsbFileTransferRestricted()).thenReturn(true);
|
||||
when(mUserManagerWrapper.isUsbFileTransferRestrictedBySystem()).thenReturn(true);
|
||||
|
||||
final UsbBackend usbBackend =
|
||||
new UsbBackend(mContext, mUserManagerWrapper, mUsbManagerWrapper);
|
||||
|
||||
assertThat(usbBackend.areFunctionsSupported(UsbManager.FUNCTION_MTP)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void areFunctionsSupported_fileTransferAllowed_shouldReturnTrue() {
|
||||
when(mUserManagerWrapper.isUsbFileTransferRestricted()).thenReturn(false);
|
||||
when(mUserManagerWrapper.isUsbFileTransferRestrictedBySystem()).thenReturn(false);
|
||||
|
||||
final UsbBackend usbBackend =
|
||||
new UsbBackend(mContext, mUserManagerWrapper, mUsbManagerWrapper);
|
||||
|
||||
assertThat(usbBackend.areFunctionsSupported(UsbManager.FUNCTION_MTP)).isTrue();
|
||||
}
|
||||
}
|
||||
|
@@ -16,11 +16,14 @@
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.hardware.usb.UsbPort;
|
||||
import android.hardware.usb.UsbPortStatus;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
|
||||
@@ -53,29 +56,31 @@ public class UsbConnectionBroadcastReceiverTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnReceive_usbConnected_invokeCallback() {
|
||||
public void onReceive_usbConnected_invokeCallback() {
|
||||
final Intent intent = new Intent();
|
||||
intent.setAction(UsbManager.ACTION_USB_STATE);
|
||||
intent.putExtra(UsbManager.USB_CONNECTED, true);
|
||||
|
||||
mReceiver.onReceive(mContext, intent);
|
||||
|
||||
verify(mListener).onUsbConnectionChanged(true /* connected */, UsbBackend.MODE_DATA_NONE);
|
||||
verify(mListener).onUsbConnectionChanged(true /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_NONE, UsbPort.DATA_ROLE_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnReceive_usbDisconnected_invokeCallback() {
|
||||
public void onReceive_usbDisconnected_invokeCallback() {
|
||||
final Intent intent = new Intent();
|
||||
intent.setAction(UsbManager.ACTION_USB_STATE);
|
||||
intent.putExtra(UsbManager.USB_CONNECTED, false);
|
||||
|
||||
mReceiver.onReceive(mContext, intent);
|
||||
|
||||
verify(mListener).onUsbConnectionChanged(false /* connected */, UsbBackend.MODE_DATA_NONE);
|
||||
verify(mListener).onUsbConnectionChanged(false /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_NONE, UsbPort.DATA_ROLE_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnReceive_usbConnectedMtpEnabled_invokeCallback() {
|
||||
public void onReceive_usbConnectedMtpEnabled_invokeCallback() {
|
||||
final Intent intent = new Intent();
|
||||
intent.setAction(UsbManager.ACTION_USB_STATE);
|
||||
intent.putExtra(UsbManager.USB_CONNECTED, true);
|
||||
@@ -84,11 +89,26 @@ public class UsbConnectionBroadcastReceiverTest {
|
||||
|
||||
mReceiver.onReceive(mContext, intent);
|
||||
|
||||
verify(mListener).onUsbConnectionChanged(true /* connected */, UsbBackend.MODE_DATA_MTP);
|
||||
verify(mListener).onUsbConnectionChanged(true /* connected */, UsbManager.FUNCTION_MTP,
|
||||
UsbPort.POWER_ROLE_NONE, UsbPort.DATA_ROLE_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegister_invokeMethodTwice_registerOnce() {
|
||||
public void onReceive_usbPortStatus_invokeCallback() {
|
||||
final Intent intent = new Intent();
|
||||
intent.setAction(UsbManager.ACTION_USB_PORT_CHANGED);
|
||||
final UsbPortStatus status = new UsbPortStatus(0, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE, 0);
|
||||
intent.putExtra(UsbManager.EXTRA_PORT_STATUS, status);
|
||||
|
||||
mReceiver.onReceive(mContext, intent);
|
||||
|
||||
verify(mListener).onUsbConnectionChanged(false /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void register_invokeMethodTwice_registerOnce() {
|
||||
mReceiver.register();
|
||||
mReceiver.register();
|
||||
|
||||
@@ -96,7 +116,7 @@ public class UsbConnectionBroadcastReceiverTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnregister_invokeMethodTwice_unregisterOnce() {
|
||||
public void unregister_invokeMethodTwice_unregisterOnce() {
|
||||
mReceiver.register();
|
||||
mReceiver.unregister();
|
||||
mReceiver.unregister();
|
||||
|
@@ -18,17 +18,20 @@ package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.hardware.usb.UsbManager;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class UsbDefaultFragmentTest {
|
||||
@@ -46,62 +49,75 @@ public class UsbDefaultFragmentTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefaultKey_isNone_shouldReturnNone() {
|
||||
when(mUsbBackend.getDefaultUsbMode()).thenReturn(UsbBackend.MODE_DATA_NONE);
|
||||
assertThat(mFragment.getDefaultKey()).isEqualTo(UsbManager.USB_FUNCTION_NONE);
|
||||
public void getDefaultKey_isNone_shouldReturnNone() {
|
||||
when(mUsbBackend.getDefaultUsbFunctions()).thenReturn(UsbManager.FUNCTION_NONE);
|
||||
assertThat(mFragment.getDefaultKey())
|
||||
.isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_NONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefaultKey_isMtp_shouldReturnMtp() {
|
||||
when(mUsbBackend.getDefaultUsbMode()).thenReturn(UsbBackend.MODE_DATA_MTP);
|
||||
assertThat(mFragment.getDefaultKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
|
||||
public void getDefaultKey_isMtp_shouldReturnMtp() {
|
||||
when(mUsbBackend.getDefaultUsbFunctions()).thenReturn(UsbManager.FUNCTION_MTP);
|
||||
assertThat(mFragment.getDefaultKey())
|
||||
.isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MTP));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefaultKey_isPtp_shouldReturnPtp() {
|
||||
when(mUsbBackend.getDefaultUsbMode()).thenReturn(UsbBackend.MODE_DATA_PTP);
|
||||
assertThat(mFragment.getDefaultKey()).isEqualTo(UsbManager.USB_FUNCTION_PTP);
|
||||
public void getDefaultKey_isPtp_shouldReturnPtp() {
|
||||
when(mUsbBackend.getDefaultUsbFunctions()).thenReturn(UsbManager.FUNCTION_PTP);
|
||||
assertThat(mFragment.getDefaultKey())
|
||||
.isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_PTP));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefaultKey_isRndis_shouldReturnRndis() {
|
||||
when(mUsbBackend.getDefaultUsbMode()).thenReturn(UsbBackend.MODE_DATA_TETHER);
|
||||
assertThat(mFragment.getDefaultKey()).isEqualTo(UsbManager.USB_FUNCTION_RNDIS);
|
||||
public void getDefaultKey_isRndis_shouldReturnRndis() {
|
||||
when(mUsbBackend.getDefaultUsbFunctions()).thenReturn(UsbManager.FUNCTION_RNDIS);
|
||||
assertThat(mFragment.getDefaultKey())
|
||||
.isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_RNDIS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDefaultKey_isMidi_shouldReturnMidi() {
|
||||
when(mUsbBackend.getDefaultUsbMode()).thenReturn(UsbBackend.MODE_DATA_MIDI);
|
||||
assertThat(mFragment.getDefaultKey()).isEqualTo(UsbManager.USB_FUNCTION_MIDI);
|
||||
public void getDefaultKey_isMidi_shouldReturnMidi() {
|
||||
when(mUsbBackend.getDefaultUsbFunctions()).thenReturn(UsbManager.FUNCTION_MIDI);
|
||||
assertThat(mFragment.getDefaultKey())
|
||||
.isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MIDI));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetDefaultKey_isNone_shouldSetNone() {
|
||||
mFragment.setDefaultKey(UsbManager.USB_FUNCTION_NONE);
|
||||
verify(mUsbBackend).setDefaultUsbMode(UsbBackend.MODE_DATA_NONE);
|
||||
public void setDefaultKey_isNone_shouldSetNone() {
|
||||
mFragment.setDefaultKey(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_NONE));
|
||||
verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetDefaultKey_isMtp_shouldSetMtp() {
|
||||
mFragment.setDefaultKey(UsbManager.USB_FUNCTION_MTP);
|
||||
verify(mUsbBackend).setDefaultUsbMode(UsbBackend.MODE_DATA_MTP);
|
||||
public void setDefaultKey_isMtp_shouldSetMtp() {
|
||||
mFragment.setDefaultKey(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MTP));
|
||||
verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_MTP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetDefaultKey_isPtp_shouldSetPtp() {
|
||||
mFragment.setDefaultKey(UsbManager.USB_FUNCTION_PTP);
|
||||
verify(mUsbBackend).setDefaultUsbMode(UsbBackend.MODE_DATA_PTP);
|
||||
public void setDefaultKey_isPtp_shouldSetPtp() {
|
||||
mFragment.setDefaultKey(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_PTP));
|
||||
verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_PTP);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetDefaultKey_isRndis_shouldSetRndis() {
|
||||
mFragment.setDefaultKey(UsbManager.USB_FUNCTION_RNDIS);
|
||||
verify(mUsbBackend).setDefaultUsbMode(UsbBackend.MODE_DATA_TETHER);
|
||||
public void setDefaultKey_isRndis_shouldSetRndis() {
|
||||
mFragment.setDefaultKey(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_RNDIS));
|
||||
verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_RNDIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetDefaultKey_isMidi_shouldSetMidi() {
|
||||
mFragment.setDefaultKey(UsbManager.USB_FUNCTION_MIDI);
|
||||
verify(mUsbBackend).setDefaultUsbMode(UsbBackend.MODE_DATA_MIDI);
|
||||
public void setDefaultKey_isMidi_shouldSetMidi() {
|
||||
mFragment.setDefaultKey(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MIDI));
|
||||
verify(mUsbBackend).setDefaultUsbFunctions(UsbManager.FUNCTION_MIDI);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowUtils.class)
|
||||
public void setDefaultKey_isMonkey_shouldDoNothing() {
|
||||
ShadowUtils.setIsUserAMonkey(true);
|
||||
mFragment.setDefaultKey(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MTP));
|
||||
verifyZeroInteractions(mUsbBackend);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.hardware.usb.UsbPort;
|
||||
import android.os.Handler;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.widget.RadioButtonPreference;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class UsbDetailsDataRoleControllerTest {
|
||||
|
||||
private UsbDetailsDataRoleController mDetailsDataRoleController;
|
||||
private Context mContext;
|
||||
private Lifecycle mLifecycle;
|
||||
private PreferenceCategory mPreference;
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private PreferenceScreen mScreen;
|
||||
|
||||
@Mock
|
||||
private UsbBackend mUsbBackend;
|
||||
@Mock
|
||||
private UsbDetailsFragment mFragment;
|
||||
@Mock
|
||||
private Activity mActivity;
|
||||
@Mock
|
||||
private Handler mHandler;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mLifecycle = new Lifecycle(() -> mLifecycle);
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
mScreen = mPreferenceManager.createPreferenceScreen(mContext);
|
||||
|
||||
when(mFragment.getActivity()).thenReturn(mActivity);
|
||||
when(mActivity.getApplicationContext()).thenReturn(mContext);
|
||||
when(mFragment.getContext()).thenReturn(mContext);
|
||||
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
|
||||
|
||||
mDetailsDataRoleController = new UsbDetailsDataRoleController(mContext, mFragment,
|
||||
mUsbBackend);
|
||||
mPreference = new PreferenceCategory(mContext);
|
||||
mPreference.setKey(mDetailsDataRoleController.getPreferenceKey());
|
||||
mScreen.addPreference(mPreference);
|
||||
|
||||
mDetailsDataRoleController.mHandler = mHandler;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_deviceRole_shouldCheckDevice() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
|
||||
mDetailsDataRoleController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
|
||||
final RadioButtonPreference devicePref = getRadioPreference(UsbPort.DATA_ROLE_DEVICE);
|
||||
final RadioButtonPreference hostPref = getRadioPreference(UsbPort.DATA_ROLE_HOST);
|
||||
assertThat(devicePref.isChecked()).isTrue();
|
||||
assertThat(hostPref.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_hostRole_shouldCheckHost() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
|
||||
mDetailsDataRoleController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_HOST);
|
||||
|
||||
final RadioButtonPreference devicePref = getRadioPreference(UsbPort.DATA_ROLE_DEVICE);
|
||||
final RadioButtonPreference hostPref = getRadioPreference(UsbPort.DATA_ROLE_HOST);
|
||||
assertThat(devicePref.isChecked()).isFalse();
|
||||
assertThat(hostPref.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_disconnected_shouldDisable() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
|
||||
mDetailsDataRoleController.refresh(false, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClickDevice_hostEnabled_shouldSetDevice() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getDataRole()).thenReturn(UsbPort.DATA_ROLE_HOST);
|
||||
|
||||
final RadioButtonPreference devicePref = getRadioPreference(UsbPort.DATA_ROLE_DEVICE);
|
||||
devicePref.performClick();
|
||||
|
||||
verify(mUsbBackend).setDataRole(UsbPort.DATA_ROLE_DEVICE);
|
||||
assertThat(devicePref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClickDeviceTwice_hostEnabled_shouldSetDeviceOnce() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getDataRole()).thenReturn(UsbPort.DATA_ROLE_HOST);
|
||||
|
||||
final RadioButtonPreference devicePref = getRadioPreference(UsbPort.DATA_ROLE_DEVICE);
|
||||
devicePref.performClick();
|
||||
|
||||
assertThat(devicePref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching));
|
||||
devicePref.performClick();
|
||||
verify(mUsbBackend).setDataRole(UsbPort.DATA_ROLE_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClickDeviceAndRefresh_success_shouldClearSubtext() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getDataRole()).thenReturn(UsbPort.DATA_ROLE_HOST);
|
||||
|
||||
final RadioButtonPreference devicePref = getRadioPreference(UsbPort.DATA_ROLE_DEVICE);
|
||||
devicePref.performClick();
|
||||
|
||||
verify(mUsbBackend).setDataRole(UsbPort.DATA_ROLE_DEVICE);
|
||||
assertThat(devicePref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching));
|
||||
mDetailsDataRoleController.refresh(false /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_NONE, UsbPort.DATA_ROLE_NONE);
|
||||
mDetailsDataRoleController.refresh(true /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE);
|
||||
assertThat(devicePref.getSummary()).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClickDeviceAndRefresh_failed_shouldShowFailureText() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getDataRole()).thenReturn(UsbPort.DATA_ROLE_HOST);
|
||||
|
||||
final RadioButtonPreference devicePref = getRadioPreference(UsbPort.DATA_ROLE_DEVICE);
|
||||
devicePref.performClick();
|
||||
|
||||
verify(mUsbBackend).setDataRole(UsbPort.DATA_ROLE_DEVICE);
|
||||
assertThat(devicePref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching));
|
||||
mDetailsDataRoleController.refresh(false /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_NONE, UsbPort.DATA_ROLE_NONE);
|
||||
mDetailsDataRoleController.refresh(true /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_HOST);
|
||||
assertThat(devicePref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching_failed));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClickDevice_timedOut_shouldShowFailureText() {
|
||||
mDetailsDataRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getDataRole()).thenReturn(UsbPort.DATA_ROLE_HOST);
|
||||
|
||||
final RadioButtonPreference devicePref = getRadioPreference(UsbPort.DATA_ROLE_DEVICE);
|
||||
devicePref.performClick();
|
||||
|
||||
verify(mUsbBackend).setDataRole(UsbPort.DATA_ROLE_DEVICE);
|
||||
ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
|
||||
verify(mHandler).postDelayed(captor.capture(), anyLong());
|
||||
assertThat(devicePref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching));
|
||||
mDetailsDataRoleController.refresh(false /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_NONE, UsbPort.DATA_ROLE_NONE);
|
||||
captor.getValue().run();
|
||||
|
||||
assertThat(devicePref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching_failed));
|
||||
}
|
||||
|
||||
private RadioButtonPreference getRadioPreference(int role) {
|
||||
return (RadioButtonPreference)
|
||||
mPreference.findPreference(UsbBackend.dataRoleToString(role));
|
||||
}
|
||||
}
|
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.hardware.usb.UsbPort;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
import com.android.settings.widget.RadioButtonPreference;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class UsbDetailsFunctionsControllerTest {
|
||||
|
||||
private UsbDetailsFunctionsController mDetailsFunctionsController;
|
||||
private Context mContext;
|
||||
private Lifecycle mLifecycle;
|
||||
private PreferenceCategory mPreference;
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private PreferenceScreen mScreen;
|
||||
|
||||
@Mock
|
||||
private UsbBackend mUsbBackend;
|
||||
@Mock
|
||||
private UsbDetailsFragment mFragment;
|
||||
@Mock
|
||||
private Activity mActivity;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mLifecycle = new Lifecycle(() -> mLifecycle);
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
mScreen = mPreferenceManager.createPreferenceScreen(mContext);
|
||||
|
||||
when(mFragment.getActivity()).thenReturn(mActivity);
|
||||
when(mActivity.getApplicationContext()).thenReturn(mContext);
|
||||
when(mFragment.getContext()).thenReturn(mContext);
|
||||
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
|
||||
|
||||
mDetailsFunctionsController = new UsbDetailsFunctionsController(mContext, mFragment,
|
||||
mUsbBackend);
|
||||
mPreference = new PreferenceCategory(mContext);
|
||||
mPreference.setKey(mDetailsFunctionsController.getPreferenceKey());
|
||||
mScreen.addPreference(mPreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_allAllowed_shouldCreatePrefs() {
|
||||
when(mUsbBackend.areFunctionsSupported(anyLong())).thenReturn(true);
|
||||
|
||||
mDetailsFunctionsController.displayPreference(mScreen);
|
||||
mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
List<RadioButtonPreference> prefs = getRadioPreferences();
|
||||
Iterator<Long> iter = UsbDetailsFunctionsController.FUNCTIONS_MAP.keySet().iterator();
|
||||
|
||||
for (RadioButtonPreference pref : prefs) {
|
||||
assertThat(pref.getKey()).isEqualTo(UsbBackend.usbFunctionsToString(iter.next()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_disconnected_shouldDisable() {
|
||||
when(mUsbBackend.areFunctionsSupported(anyLong())).thenReturn(true);
|
||||
|
||||
mDetailsFunctionsController.displayPreference(mScreen);
|
||||
mDetailsFunctionsController.refresh(false, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE);
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_onlyMidiAllowed_shouldCreateOnlyMidiPref() {
|
||||
when(mUsbBackend.areFunctionsSupported(UsbManager.FUNCTION_MIDI)).thenReturn(true);
|
||||
when(mUsbBackend.areFunctionsSupported(UsbManager.FUNCTION_MTP)).thenReturn(false);
|
||||
when(mUsbBackend.areFunctionsSupported(UsbManager.FUNCTION_PTP)).thenReturn(false);
|
||||
when(mUsbBackend.areFunctionsSupported(UsbManager.FUNCTION_RNDIS)).thenReturn(false);
|
||||
|
||||
mDetailsFunctionsController.displayPreference(mScreen);
|
||||
mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
List<RadioButtonPreference> prefs = getRadioPreferences();
|
||||
assertThat(prefs.size()).isEqualTo(1);
|
||||
assertThat(prefs.get(0).getKey())
|
||||
.isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MIDI));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_mtpEnabled_shouldCheckSwitches() {
|
||||
when(mUsbBackend.areFunctionsSupported(anyLong())).thenReturn(true);
|
||||
|
||||
mDetailsFunctionsController.displayPreference(mScreen);
|
||||
mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_MTP, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
List<RadioButtonPreference> prefs = getRadioPreferences();
|
||||
|
||||
assertThat(prefs.get(0).getKey())
|
||||
.isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MTP));
|
||||
assertThat(prefs.get(0).isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClickMtp_noneEnabled_shouldEnableMtp() {
|
||||
when(mUsbBackend.areFunctionsSupported(anyLong())).thenReturn(true);
|
||||
|
||||
mDetailsFunctionsController.displayPreference(mScreen);
|
||||
mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
when(mUsbBackend.getCurrentFunctions()).thenReturn(UsbManager.FUNCTION_NONE);
|
||||
List<RadioButtonPreference> prefs = getRadioPreferences();
|
||||
prefs.get(0).performClick();
|
||||
|
||||
assertThat(prefs.get(0).getKey())
|
||||
.isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MTP));
|
||||
verify(mUsbBackend).setCurrentFunctions(UsbManager.FUNCTION_MTP);
|
||||
mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_MTP, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
assertThat(prefs.get(0).isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClickMtp_ptpEnabled_shouldEnableMtp() {
|
||||
when(mUsbBackend.areFunctionsSupported(anyLong())).thenReturn(true);
|
||||
|
||||
mDetailsFunctionsController.displayPreference(mScreen);
|
||||
mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_PTP, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
when(mUsbBackend.getCurrentFunctions()).thenReturn(UsbManager.FUNCTION_PTP);
|
||||
List<RadioButtonPreference> prefs = getRadioPreferences();
|
||||
prefs.get(0).performClick();
|
||||
|
||||
assertThat(prefs.get(0).getKey())
|
||||
.isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_MTP));
|
||||
verify(mUsbBackend).setCurrentFunctions(UsbManager.FUNCTION_MTP);
|
||||
mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_MTP, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
assertThat(prefs.get(0).isChecked()).isTrue();
|
||||
assertThat(prefs.get(3).getKey())
|
||||
.isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_PTP));
|
||||
assertThat(prefs.get(3).isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClickNone_mtpEnabled_shouldDisableMtp() {
|
||||
when(mUsbBackend.areFunctionsSupported(anyLong())).thenReturn(true);
|
||||
|
||||
mDetailsFunctionsController.displayPreference(mScreen);
|
||||
mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_MTP, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
when(mUsbBackend.getCurrentFunctions()).thenReturn(UsbManager.FUNCTION_MTP);
|
||||
List<RadioButtonPreference> prefs = getRadioPreferences();
|
||||
prefs.get(4).performClick();
|
||||
|
||||
assertThat(prefs.get(4).getKey())
|
||||
.isEqualTo(UsbBackend.usbFunctionsToString(UsbManager.FUNCTION_NONE));
|
||||
verify(mUsbBackend).setCurrentFunctions(UsbManager.FUNCTION_NONE);
|
||||
mDetailsFunctionsController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
assertThat(prefs.get(0).isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowUtils.class)
|
||||
public void isAvailable_isMonkey_shouldReturnFalse() {
|
||||
ShadowUtils.setIsUserAMonkey(true);
|
||||
assertThat(mDetailsFunctionsController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
private List<RadioButtonPreference> getRadioPreferences() {
|
||||
ArrayList<RadioButtonPreference> result = new ArrayList<>();
|
||||
for (int i = 0; i < mPreference.getPreferenceCount(); i++) {
|
||||
result.add((RadioButtonPreference) mPreference.getPreference(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@@ -23,6 +23,8 @@ import android.app.Activity;
|
||||
import android.arch.lifecycle.LifecycleOwner;
|
||||
import android.content.Context;
|
||||
import android.support.v14.preference.PreferenceFragment;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.hardware.usb.UsbPort;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
@@ -58,7 +60,7 @@ public class UsbDetailsHeaderControllerTest {
|
||||
@Mock
|
||||
private UsbBackend mUsbBackend;
|
||||
@Mock
|
||||
private PreferenceFragment mFragment;
|
||||
private UsbDetailsFragment mFragment;
|
||||
@Mock
|
||||
private Activity mActivity;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
@@ -95,22 +97,10 @@ public class UsbDetailsHeaderControllerTest {
|
||||
@Test
|
||||
public void displayRefresh_charging_shouldSetHeader() {
|
||||
mDetailsHeaderController.displayPreference(mScreen);
|
||||
mDetailsHeaderController.refresh(UsbBackend.MODE_DATA_NONE);
|
||||
mDetailsHeaderController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
verify(mHeaderController).setLabel(mContext.getString(R.string.usb_pref));
|
||||
verify(mHeaderController).setIcon(mContext.getDrawable(R.drawable.ic_usb));
|
||||
verify(mHeaderController)
|
||||
.setSummary(mContext.getString(R.string.usb_summary_charging_only));
|
||||
verify(mHeaderController).done(mActivity, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_mtp_shouldSetHeader() {
|
||||
mDetailsHeaderController.displayPreference(mScreen);
|
||||
mDetailsHeaderController.refresh(UsbBackend.MODE_DATA_MTP);
|
||||
verify(mHeaderController).setLabel(mContext.getString(R.string.usb_pref));
|
||||
verify(mHeaderController).setIcon(mContext.getDrawable(R.drawable.ic_usb));
|
||||
verify(mHeaderController)
|
||||
.setSummary(mContext.getString(R.string.usb_summary_file_transfers));
|
||||
verify(mHeaderController).done(mActivity, true);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.hardware.usb.UsbPort;
|
||||
import android.os.Handler;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class UsbDetailsPowerRoleControllerTest {
|
||||
|
||||
private UsbDetailsPowerRoleController mDetailsPowerRoleController;
|
||||
private Context mContext;
|
||||
private Lifecycle mLifecycle;
|
||||
private PreferenceCategory mPreference;
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private PreferenceScreen mScreen;
|
||||
|
||||
@Mock
|
||||
private UsbBackend mUsbBackend;
|
||||
@Mock
|
||||
private UsbDetailsFragment mFragment;
|
||||
@Mock
|
||||
private Activity mActivity;
|
||||
@Mock
|
||||
private Handler mHandler;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mLifecycle = new Lifecycle(() -> mLifecycle);
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
mScreen = mPreferenceManager.createPreferenceScreen(mContext);
|
||||
|
||||
when(mFragment.getActivity()).thenReturn(mActivity);
|
||||
when(mActivity.getApplicationContext()).thenReturn(mContext);
|
||||
when(mFragment.getContext()).thenReturn(mContext);
|
||||
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
|
||||
|
||||
mDetailsPowerRoleController = new UsbDetailsPowerRoleController(mContext, mFragment,
|
||||
mUsbBackend);
|
||||
mPreference = new PreferenceCategory(mContext);
|
||||
mPreference.setKey(mDetailsPowerRoleController.getPreferenceKey());
|
||||
mScreen.addPreference(mPreference);
|
||||
|
||||
mDetailsPowerRoleController.mHandler = mHandler;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_sink_shouldUncheck() {
|
||||
mDetailsPowerRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.areAllRolesSupported()).thenReturn(true);
|
||||
|
||||
mDetailsPowerRoleController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
|
||||
SwitchPreference pref = getPreference();
|
||||
assertThat(pref.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_source_shouldCheck() {
|
||||
mDetailsPowerRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.areAllRolesSupported()).thenReturn(true);
|
||||
|
||||
mDetailsPowerRoleController.refresh(true, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_HOST);
|
||||
|
||||
SwitchPreference pref = getPreference();
|
||||
assertThat(pref.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_disconnected_shouldDisable() {
|
||||
mDetailsPowerRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.areAllRolesSupported()).thenReturn(true);
|
||||
|
||||
mDetailsPowerRoleController.refresh(false, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE);
|
||||
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
assertThat(mScreen.findPreference(mDetailsPowerRoleController.getPreferenceKey()))
|
||||
.isEqualTo(mPreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayRefresh_notSupported_shouldRemove() {
|
||||
mDetailsPowerRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.areAllRolesSupported()).thenReturn(false);
|
||||
|
||||
mDetailsPowerRoleController.refresh(true, UsbManager.FUNCTION_NONE, UsbPort.POWER_ROLE_SINK,
|
||||
UsbPort.DATA_ROLE_DEVICE);
|
||||
|
||||
assertThat(mScreen.findPreference(mDetailsPowerRoleController.getPreferenceKey())).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClick_sink_shouldSetSource() {
|
||||
mDetailsPowerRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getPowerRole()).thenReturn(UsbPort.POWER_ROLE_SINK);
|
||||
|
||||
SwitchPreference pref = getPreference();
|
||||
pref.performClick();
|
||||
|
||||
verify(mUsbBackend).setPowerRole(UsbPort.POWER_ROLE_SOURCE);
|
||||
assertThat(pref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClickTwice_sink_shouldSetSourceOnce() {
|
||||
mDetailsPowerRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getPowerRole()).thenReturn(UsbPort.POWER_ROLE_SINK);
|
||||
|
||||
SwitchPreference pref = getPreference();
|
||||
pref.performClick();
|
||||
|
||||
assertThat(pref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching));
|
||||
pref.performClick();
|
||||
verify(mUsbBackend, times(1)).setPowerRole(UsbPort.POWER_ROLE_SOURCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClickDeviceAndRefresh_success_shouldClearSubtext() {
|
||||
mDetailsPowerRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getPowerRole()).thenReturn(UsbPort.POWER_ROLE_SINK);
|
||||
|
||||
SwitchPreference pref = getPreference();
|
||||
pref.performClick();
|
||||
|
||||
verify(mUsbBackend).setPowerRole(UsbPort.POWER_ROLE_SOURCE);
|
||||
assertThat(pref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching));
|
||||
mDetailsPowerRoleController.refresh(false /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_NONE, UsbPort.DATA_ROLE_NONE);
|
||||
mDetailsPowerRoleController.refresh(true /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_SOURCE, UsbPort.DATA_ROLE_DEVICE);
|
||||
assertThat(pref.getSummary()).isEqualTo("");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClickDeviceAndRefresh_failed_shouldShowFailureText() {
|
||||
mDetailsPowerRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getPowerRole()).thenReturn(UsbPort.POWER_ROLE_SINK);
|
||||
|
||||
SwitchPreference pref = getPreference();
|
||||
pref.performClick();
|
||||
|
||||
verify(mUsbBackend).setPowerRole(UsbPort.POWER_ROLE_SOURCE);
|
||||
assertThat(pref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching));
|
||||
mDetailsPowerRoleController.refresh(false /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_NONE, UsbPort.DATA_ROLE_NONE);
|
||||
mDetailsPowerRoleController.refresh(true /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_SINK, UsbPort.DATA_ROLE_DEVICE);
|
||||
assertThat(pref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching_failed));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void onClickDevice_timedOut_shouldShowFailureText() {
|
||||
mDetailsPowerRoleController.displayPreference(mScreen);
|
||||
when(mUsbBackend.getPowerRole()).thenReturn(UsbPort.POWER_ROLE_SINK);
|
||||
|
||||
SwitchPreference pref = getPreference();
|
||||
pref.performClick();
|
||||
|
||||
verify(mUsbBackend).setPowerRole(UsbPort.POWER_ROLE_SOURCE);
|
||||
ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
|
||||
verify(mHandler).postDelayed(captor.capture(), anyLong());
|
||||
assertThat(pref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching));
|
||||
mDetailsPowerRoleController.refresh(false /* connected */, UsbManager.FUNCTION_NONE,
|
||||
UsbPort.POWER_ROLE_NONE, UsbPort.DATA_ROLE_NONE);
|
||||
captor.getValue().run();
|
||||
assertThat(pref.getSummary())
|
||||
.isEqualTo(mContext.getString(R.string.usb_switching_failed));
|
||||
}
|
||||
|
||||
|
||||
private SwitchPreference getPreference() {
|
||||
return (SwitchPreference) mPreference.getPreference(0);
|
||||
}
|
||||
}
|
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.connecteddevice.usb;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.support.v14.preference.PreferenceFragment;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceManager;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.google.android.collect.Lists;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
public class UsbDetailsProfilesControllerTest {
|
||||
|
||||
private UsbDetailsProfilesController mDetailsProfilesController;
|
||||
private Context mContext;
|
||||
private Lifecycle mLifecycle;
|
||||
private PreferenceCategory mPreference;
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private PreferenceScreen mScreen;
|
||||
private List<String> mOptions;
|
||||
|
||||
@Mock
|
||||
private UsbBackend mUsbBackend;
|
||||
@Mock
|
||||
private PreferenceFragment mFragment;
|
||||
@Mock
|
||||
private Activity mActivity;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mLifecycle = new Lifecycle(() -> mLifecycle);
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
mScreen = mPreferenceManager.createPreferenceScreen(mContext);
|
||||
|
||||
when(mFragment.getActivity()).thenReturn(mActivity);
|
||||
when(mActivity.getApplicationContext()).thenReturn(mContext);
|
||||
when(mFragment.getContext()).thenReturn(mContext);
|
||||
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
when(mFragment.getPreferenceScreen()).thenReturn(mScreen);
|
||||
|
||||
mOptions = Lists.newArrayList(UsbManager.USB_FUNCTION_MTP, UsbManager.USB_FUNCTION_PTP,
|
||||
UsbManager.USB_FUNCTION_MIDI, UsbDetailsProfilesController.KEY_POWER);
|
||||
mDetailsProfilesController = new UsbDetailsProfilesController(mContext, mFragment,
|
||||
mUsbBackend, mOptions, "usb_options");
|
||||
mPreference = new PreferenceCategory(mContext);
|
||||
mPreference.setKey(mDetailsProfilesController.getPreferenceKey());
|
||||
mScreen.addPreference(mPreference);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisplayRefresh_allAllowed_shouldCreateSwitches() {
|
||||
when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
|
||||
when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
|
||||
when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
|
||||
|
||||
mDetailsProfilesController.displayPreference(mScreen);
|
||||
mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_NONE);
|
||||
List<SwitchPreference> switches = getProfileSwitches();
|
||||
|
||||
for (int i = 0; i < switches.size(); i++) {
|
||||
assertThat(switches.get(i).getKey()).isEqualTo(mOptions.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisplayRefresh_onlyMidiAllowed_shouldCreateOnlyMidiSwitch() {
|
||||
when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
|
||||
when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
|
||||
when(mUsbBackend.isModeDisallowedBySystem(UsbBackend.MODE_DATA_MIDI)).thenReturn(false);
|
||||
when(mUsbBackend.isModeDisallowedBySystem(UsbBackend.MODE_DATA_MTP)).thenReturn(true);
|
||||
when(mUsbBackend.isModeDisallowedBySystem(UsbBackend.MODE_DATA_PTP)).thenReturn(true);
|
||||
when(mUsbBackend.isModeDisallowedBySystem(UsbBackend.MODE_POWER_SOURCE)).thenReturn(true);
|
||||
|
||||
mDetailsProfilesController.displayPreference(mScreen);
|
||||
mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_NONE);
|
||||
List<SwitchPreference> switches = getProfileSwitches();
|
||||
assertThat(switches.size()).isEqualTo(1);
|
||||
assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MIDI);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisplayRefresh_mtpEnabled_shouldCheckSwitches() {
|
||||
when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
|
||||
when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
|
||||
when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
|
||||
|
||||
mDetailsProfilesController.displayPreference(mScreen);
|
||||
mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_MTP);
|
||||
List<SwitchPreference> switches = getProfileSwitches();
|
||||
|
||||
assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
|
||||
assertThat(switches.get(0).isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisplayRefresh_mtpSupplyPowerEnabled_shouldCheckSwitches() {
|
||||
when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
|
||||
when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
|
||||
when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
|
||||
|
||||
mDetailsProfilesController.displayPreference(mScreen);
|
||||
mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_MTP | UsbBackend.MODE_POWER_SOURCE);
|
||||
List<SwitchPreference> switches = getProfileSwitches();
|
||||
|
||||
assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
|
||||
assertThat(switches.get(0).isChecked()).isTrue();
|
||||
assertThat(switches.get(3).getKey()).isEqualTo(UsbDetailsProfilesController.KEY_POWER);
|
||||
assertThat(switches.get(3).isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClickMtp_noneEnabled_shouldEnableMtp() {
|
||||
when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
|
||||
when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
|
||||
when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
|
||||
|
||||
mDetailsProfilesController.displayPreference(mScreen);
|
||||
mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_NONE);
|
||||
List<SwitchPreference> switches = getProfileSwitches();
|
||||
switches.get(0).performClick();
|
||||
|
||||
assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
|
||||
verify(mUsbBackend).setMode(UsbBackend.MODE_DATA_MTP);
|
||||
assertThat(switches.get(0).isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClickMtp_supplyingPowerEnabled_shouldEnableBoth() {
|
||||
when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
|
||||
when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
|
||||
when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
|
||||
|
||||
mDetailsProfilesController.displayPreference(mScreen);
|
||||
mDetailsProfilesController.refresh(UsbBackend.MODE_POWER_SOURCE);
|
||||
when(mUsbBackend.getCurrentMode()).thenReturn(UsbBackend.MODE_POWER_SOURCE);
|
||||
List<SwitchPreference> switches = getProfileSwitches();
|
||||
switches.get(0).performClick();
|
||||
|
||||
assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
|
||||
verify(mUsbBackend).setMode(UsbBackend.MODE_DATA_MTP | UsbBackend.MODE_POWER_SOURCE);
|
||||
assertThat(switches.get(0).isChecked()).isTrue();
|
||||
assertThat(switches.get(3).getKey()).isEqualTo(UsbDetailsProfilesController.KEY_POWER);
|
||||
assertThat(switches.get(3).isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClickMtp_ptpEnabled_shouldEnableMtpOnly() {
|
||||
when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
|
||||
when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
|
||||
when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
|
||||
|
||||
mDetailsProfilesController.displayPreference(mScreen);
|
||||
mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_PTP);
|
||||
when(mUsbBackend.getCurrentMode()).thenReturn(UsbBackend.MODE_DATA_PTP);
|
||||
List<SwitchPreference> switches = getProfileSwitches();
|
||||
switches.get(0).performClick();
|
||||
|
||||
assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
|
||||
verify(mUsbBackend).setMode(UsbBackend.MODE_DATA_MTP);
|
||||
mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_MTP);
|
||||
assertThat(switches.get(0).isChecked()).isTrue();
|
||||
assertThat(switches.get(1).getKey()).isEqualTo(UsbManager.USB_FUNCTION_PTP);
|
||||
assertThat(switches.get(1).isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnClickMtp_mtpEnabled_shouldDisableMtp() {
|
||||
when(mUsbBackend.isModeSupported(anyInt())).thenReturn(true);
|
||||
when(mUsbBackend.isModeDisallowed(anyInt())).thenReturn(false);
|
||||
when(mUsbBackend.isModeDisallowedBySystem(anyInt())).thenReturn(false);
|
||||
|
||||
mDetailsProfilesController.displayPreference(mScreen);
|
||||
mDetailsProfilesController.refresh(UsbBackend.MODE_DATA_MTP);
|
||||
when(mUsbBackend.getCurrentMode()).thenReturn(UsbBackend.MODE_DATA_MTP);
|
||||
List<SwitchPreference> switches = getProfileSwitches();
|
||||
switches.get(0).performClick();
|
||||
|
||||
assertThat(switches.get(0).getKey()).isEqualTo(UsbManager.USB_FUNCTION_MTP);
|
||||
verify(mUsbBackend).setMode(UsbBackend.MODE_DATA_NONE);
|
||||
assertThat(switches.get(0).isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowUtils.class)
|
||||
public void testIsAvailable_isMonkey_shouldReturnFalse() {
|
||||
ShadowUtils.setIsUserAMonkey(true);
|
||||
assertThat(mDetailsProfilesController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
private List<SwitchPreference> getProfileSwitches() {
|
||||
List<SwitchPreference> result = new ArrayList<>();
|
||||
for (int i = 0; i < mPreference.getPreferenceCount(); i++) {
|
||||
result.add((SwitchPreference) mPreference.getPreference(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user