Merge "Update USB settings screen" into pi-dev
am: d85ef28585
Change-Id: I2eeb0b2e585fd958be20f5831bee4257b1838c92
This commit is contained in:
@@ -8135,7 +8135,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. -->
|
||||
@@ -8143,11 +8143,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. -->
|
||||
@@ -8180,17 +8176,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,20 +73,20 @@ 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();
|
||||
@@ -113,4 +133,4 @@ public class UsbConnectionBroadcastReceiverTest {
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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