• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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