1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.connecteddevice.usb; 18 19 import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE; 20 import static android.hardware.usb.UsbPortStatus.DATA_ROLE_HOST; 21 import static android.hardware.usb.UsbPortStatus.DATA_ROLE_NONE; 22 23 import android.content.Context; 24 25 import androidx.preference.PreferenceCategory; 26 import androidx.preference.PreferenceScreen; 27 28 import com.android.settings.R; 29 import com.android.settings.Utils; 30 import com.android.settingslib.widget.SelectorWithWidgetPreference; 31 32 /** 33 * This class controls the radio buttons for switching between 34 * USB device and host mode. 35 */ 36 public class UsbDetailsDataRoleController extends UsbDetailsController 37 implements SelectorWithWidgetPreference.OnClickListener { 38 39 private PreferenceCategory mPreferenceCategory; 40 private SelectorWithWidgetPreference mDevicePref; 41 private SelectorWithWidgetPreference mHostPref; 42 43 private SelectorWithWidgetPreference mNextRolePref; 44 45 private final Runnable mFailureCallback = () -> { 46 if (mNextRolePref != null) { 47 mNextRolePref.setSummary(R.string.usb_switching_failed); 48 mNextRolePref = null; 49 } 50 }; 51 UsbDetailsDataRoleController(Context context, UsbDetailsFragment fragment, UsbBackend backend)52 public UsbDetailsDataRoleController(Context context, UsbDetailsFragment fragment, 53 UsbBackend backend) { 54 super(context, fragment, backend); 55 } 56 57 @Override displayPreference(PreferenceScreen screen)58 public void displayPreference(PreferenceScreen screen) { 59 super.displayPreference(screen); 60 mPreferenceCategory = screen.findPreference(getPreferenceKey()); 61 mHostPref = makeRadioPreference(UsbBackend.dataRoleToString(DATA_ROLE_HOST), 62 R.string.usb_control_host); 63 mDevicePref = makeRadioPreference(UsbBackend.dataRoleToString(DATA_ROLE_DEVICE), 64 R.string.usb_control_device); 65 } 66 67 @Override refresh(boolean connected, long functions, int powerRole, int dataRole)68 protected void refresh(boolean connected, long functions, int powerRole, int dataRole) { 69 if (dataRole == DATA_ROLE_DEVICE) { 70 mDevicePref.setChecked(true); 71 mHostPref.setChecked(false); 72 mPreferenceCategory.setEnabled(true); 73 } else if (dataRole == DATA_ROLE_HOST) { 74 mDevicePref.setChecked(false); 75 mHostPref.setChecked(true); 76 mPreferenceCategory.setEnabled(true); 77 } else if (!connected || dataRole == DATA_ROLE_NONE) { 78 mPreferenceCategory.setEnabled(false); 79 if (mNextRolePref == null) { 80 // Disconnected with no operation pending, so clear subtexts 81 mHostPref.setSummary(""); 82 mDevicePref.setSummary(""); 83 } 84 } 85 86 if (mNextRolePref != null && dataRole != DATA_ROLE_NONE) { 87 if (UsbBackend.dataRoleFromString(mNextRolePref.getKey()) == dataRole) { 88 // Clear switching text if switch succeeded 89 mNextRolePref.setSummary(""); 90 } else { 91 // Set failure text if switch failed 92 mNextRolePref.setSummary(R.string.usb_switching_failed); 93 } 94 mNextRolePref = null; 95 mHandler.removeCallbacks(mFailureCallback); 96 } 97 } 98 99 @Override onRadioButtonClicked(SelectorWithWidgetPreference preference)100 public void onRadioButtonClicked(SelectorWithWidgetPreference preference) { 101 requireAuthAndExecute(() -> { 102 int role = UsbBackend.dataRoleFromString(preference.getKey()); 103 if (role != mUsbBackend.getDataRole() && mNextRolePref == null 104 && !Utils.isMonkeyRunning()) { 105 mUsbBackend.setDataRole(role); 106 mNextRolePref = preference; 107 preference.setSummary(R.string.usb_switching); 108 109 mHandler.postDelayed(mFailureCallback, 110 mUsbBackend.areAllRolesSupported() ? UsbBackend.PD_ROLE_SWAP_TIMEOUT_MS 111 : UsbBackend.NONPD_ROLE_SWAP_TIMEOUT_MS); 112 } 113 }); 114 } 115 116 @Override isAvailable()117 public boolean isAvailable() { 118 return !Utils.isMonkeyRunning(); 119 } 120 121 @Override getPreferenceKey()122 public String getPreferenceKey() { 123 return "usb_details_data_role"; 124 } 125 makeRadioPreference(String key, int titleId)126 private SelectorWithWidgetPreference makeRadioPreference(String key, int titleId) { 127 SelectorWithWidgetPreference pref = new SelectorWithWidgetPreference( 128 mPreferenceCategory.getContext()); 129 pref.setKey(key); 130 pref.setTitle(titleId); 131 pref.setOnClickListener(this); 132 mPreferenceCategory.addPreference(pref); 133 return pref; 134 } 135 } 136