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