1 /* 2 * Copyright (C) 2017 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 package com.android.settings.connecteddevice.usb; 17 18 import static android.hardware.usb.UsbPortStatus.DATA_ROLE_DEVICE; 19 import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SINK; 20 import static android.hardware.usb.UsbPortStatus.POWER_ROLE_SOURCE; 21 22 import static com.android.settingslib.RestrictedLockUtilsInternal.checkIfUsbDataSignalingIsDisabled; 23 24 import android.content.Context; 25 import android.hardware.usb.UsbManager; 26 import android.os.UserHandle; 27 28 import androidx.annotation.VisibleForTesting; 29 import androidx.preference.Preference; 30 31 import com.android.settings.R; 32 import com.android.settings.connecteddevice.DevicePreferenceCallback; 33 import com.android.settings.core.SubSettingLauncher; 34 import com.android.settings.dashboard.DashboardFragment; 35 import com.android.settings.overlay.FeatureFactory; 36 import com.android.settingslib.RestrictedPreference; 37 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; 38 39 /** 40 * Controller to maintain connected usb device 41 */ 42 public class ConnectedUsbDeviceUpdater { 43 44 private static final String PREF_KEY = "connected_usb"; 45 46 private final MetricsFeatureProvider mMetricsFeatureProvider; 47 48 private DashboardFragment mFragment; 49 private UsbBackend mUsbBackend; 50 private DevicePreferenceCallback mDevicePreferenceCallback; 51 @VisibleForTesting 52 RestrictedPreference mUsbPreference; 53 @VisibleForTesting 54 UsbConnectionBroadcastReceiver mUsbReceiver; 55 56 @VisibleForTesting 57 UsbConnectionBroadcastReceiver.UsbConnectionListener mUsbConnectionListener = 58 (connected, functions, powerRole, dataRole, isUsbConfigured) -> { 59 if (connected) { 60 mUsbPreference.setSummary(getSummary(dataRole == DATA_ROLE_DEVICE 61 ? functions : UsbManager.FUNCTION_NONE, powerRole)); 62 mDevicePreferenceCallback.onDeviceAdded(mUsbPreference); 63 } else { 64 mDevicePreferenceCallback.onDeviceRemoved(mUsbPreference); 65 } 66 }; 67 ConnectedUsbDeviceUpdater(Context context, DashboardFragment fragment, DevicePreferenceCallback devicePreferenceCallback)68 public ConnectedUsbDeviceUpdater(Context context, DashboardFragment fragment, 69 DevicePreferenceCallback devicePreferenceCallback) { 70 this(context, fragment, devicePreferenceCallback, new UsbBackend(context)); 71 } 72 73 @VisibleForTesting ConnectedUsbDeviceUpdater(Context context, DashboardFragment fragment, DevicePreferenceCallback devicePreferenceCallback, UsbBackend usbBackend)74 ConnectedUsbDeviceUpdater(Context context, DashboardFragment fragment, 75 DevicePreferenceCallback devicePreferenceCallback, UsbBackend usbBackend) { 76 mFragment = fragment; 77 mDevicePreferenceCallback = devicePreferenceCallback; 78 mUsbBackend = usbBackend; 79 mUsbReceiver = new UsbConnectionBroadcastReceiver(context, 80 mUsbConnectionListener, mUsbBackend); 81 mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); 82 } 83 registerCallback()84 public void registerCallback() { 85 // This method could handle multiple register 86 mUsbReceiver.register(); 87 } 88 unregisterCallback()89 public void unregisterCallback() { 90 mUsbReceiver.unregister(); 91 } 92 initUsbPreference(Context context)93 public void initUsbPreference(Context context) { 94 mUsbPreference = new RestrictedPreference(context, null /* AttributeSet */); 95 mUsbPreference.setTitle(R.string.usb_pref); 96 mUsbPreference.setIcon(R.drawable.ic_usb); 97 mUsbPreference.setKey(PREF_KEY); 98 mUsbPreference.setDisabledByAdmin( 99 checkIfUsbDataSignalingIsDisabled(context, UserHandle.myUserId())); 100 mUsbPreference.setOnPreferenceClickListener((Preference p) -> { 101 mMetricsFeatureProvider.logClickedPreference(p, mFragment.getMetricsCategory()); 102 // New version - uses a separate screen. 103 new SubSettingLauncher(mFragment.getContext()) 104 .setDestination(UsbDetailsFragment.class.getName()) 105 .setTitleRes(R.string.usb_preference) 106 .setSourceMetricsCategory(mFragment.getMetricsCategory()) 107 .launch(); 108 return true; 109 }); 110 111 forceUpdate(); 112 } 113 forceUpdate()114 private void forceUpdate() { 115 // Register so we can get the connection state from sticky intent. 116 //TODO(b/70336520): Use an API to get data instead of sticky intent 117 mUsbReceiver.register(); 118 } 119 getSummary(long functions, int power)120 public static int getSummary(long functions, int power) { 121 switch (power) { 122 case POWER_ROLE_SINK: 123 if (functions == UsbManager.FUNCTION_MTP) { 124 return R.string.usb_summary_file_transfers; 125 } else if (functions == UsbManager.FUNCTION_RNDIS) { 126 return R.string.usb_summary_tether; 127 } else if (functions == UsbManager.FUNCTION_PTP) { 128 return R.string.usb_summary_photo_transfers; 129 } else if (functions == UsbManager.FUNCTION_MIDI) { 130 return R.string.usb_summary_MIDI; 131 } else if (functions == UsbManager.FUNCTION_UVC) { 132 return R.string.usb_summary_UVC; 133 } else { 134 return R.string.usb_summary_charging_only; 135 } 136 case POWER_ROLE_SOURCE: 137 if (functions == UsbManager.FUNCTION_MTP) { 138 return R.string.usb_summary_file_transfers_power; 139 } else if (functions == UsbManager.FUNCTION_RNDIS) { 140 return R.string.usb_summary_tether_power; 141 } else if (functions == UsbManager.FUNCTION_PTP) { 142 return R.string.usb_summary_photo_transfers_power; 143 } else if (functions == UsbManager.FUNCTION_MIDI) { 144 return R.string.usb_summary_MIDI_power; 145 } else if (functions == UsbManager.FUNCTION_UVC) { 146 return R.string.usb_summary_UVC_power; 147 } else { 148 return R.string.usb_summary_power_only; 149 } 150 default: 151 return R.string.usb_summary_charging_only; 152 } 153 } 154 } 155