• 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 android.content.BroadcastReceiver;
19 import android.content.Context;
20 import android.content.Intent;
21 import android.content.IntentFilter;
22 import android.hardware.usb.UsbManager;
23 import android.hardware.usb.UsbPortStatus;
24 
25 import com.android.settingslib.core.lifecycle.LifecycleObserver;
26 import com.android.settingslib.core.lifecycle.events.OnPause;
27 import com.android.settingslib.core.lifecycle.events.OnResume;
28 
29 /**
30  * Receiver to receive usb update and use {@link UsbConnectionListener} to invoke callback
31  */
32 public class UsbConnectionBroadcastReceiver extends BroadcastReceiver implements LifecycleObserver,
33         OnResume, OnPause {
34     private Context mContext;
35     private UsbConnectionListener mUsbConnectionListener;
36     private boolean mListeningToUsbEvents;
37     private UsbBackend mUsbBackend;
38 
39     private boolean mConnected;
40     private long mFunctions;
41     private int mDataRole;
42     private int mPowerRole;
43 
UsbConnectionBroadcastReceiver(Context context, UsbConnectionListener usbConnectionListener, UsbBackend backend)44     public UsbConnectionBroadcastReceiver(Context context,
45             UsbConnectionListener usbConnectionListener, UsbBackend backend) {
46         mContext = context;
47         mUsbConnectionListener = usbConnectionListener;
48         mUsbBackend = backend;
49 
50         mFunctions = UsbManager.FUNCTION_NONE;
51         mDataRole = UsbPortStatus.DATA_ROLE_NONE;
52         mPowerRole = UsbPortStatus.POWER_ROLE_NONE;
53     }
54 
55     @Override
onReceive(Context context, Intent intent)56     public void onReceive(Context context, Intent intent) {
57         if (UsbManager.ACTION_USB_STATE.equals(intent.getAction())) {
58             mConnected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED)
59                     || intent.getExtras().getBoolean(UsbManager.USB_HOST_CONNECTED);
60             long functions = UsbManager.FUNCTION_NONE;
61             if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MTP)
62                     && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) {
63                 functions |= UsbManager.FUNCTION_MTP;
64             }
65             if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_PTP)
66                     && intent.getExtras().getBoolean(UsbManager.USB_DATA_UNLOCKED, false)) {
67                 functions |= UsbManager.FUNCTION_PTP;
68             }
69             if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_MIDI)) {
70                 functions |= UsbManager.FUNCTION_MIDI;
71             }
72             if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_RNDIS)) {
73                 functions |= UsbManager.FUNCTION_RNDIS;
74             }
75             if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_ACCESSORY)) {
76                 functions |= UsbManager.FUNCTION_ACCESSORY;
77             }
78             if (intent.getExtras().getBoolean(UsbManager.USB_FUNCTION_NCM)) {
79                 functions |= UsbManager.FUNCTION_NCM;
80             }
81             mFunctions = functions;
82             mDataRole = mUsbBackend.getDataRole();
83             mPowerRole = mUsbBackend.getPowerRole();
84         } else if (UsbManager.ACTION_USB_PORT_CHANGED.equals(intent.getAction())) {
85             UsbPortStatus portStatus = intent.getExtras()
86                     .getParcelable(UsbManager.EXTRA_PORT_STATUS);
87             if (portStatus != null) {
88                 mDataRole = portStatus.getCurrentDataRole();
89                 mPowerRole = portStatus.getCurrentPowerRole();
90             }
91         }
92         if (mUsbConnectionListener != null) {
93             mUsbConnectionListener.onUsbConnectionChanged(mConnected, mFunctions, mPowerRole,
94                     mDataRole);
95         }
96     }
97 
register()98     public void register() {
99         if (!mListeningToUsbEvents) {
100             mConnected = false;
101             final IntentFilter intentFilter = new IntentFilter();
102             intentFilter.addAction(UsbManager.ACTION_USB_STATE);
103             intentFilter.addAction(UsbManager.ACTION_USB_PORT_CHANGED);
104             final Intent intent = mContext.registerReceiver(this, intentFilter);
105             // TODO b/77240599 use an api instead of sticky intent
106             if (intent != null) {
107                 onReceive(mContext, intent);
108             }
109             mListeningToUsbEvents = true;
110         }
111     }
112 
unregister()113     public void unregister() {
114         if (mListeningToUsbEvents) {
115             mContext.unregisterReceiver(this);
116             mListeningToUsbEvents = false;
117         }
118     }
119 
isConnected()120     public boolean isConnected() {
121         return mConnected;
122     }
123 
124     @Override
onResume()125     public void onResume() {
126         register();
127     }
128 
129     @Override
onPause()130     public void onPause() {
131         unregister();
132     }
133 
134     /**
135      * Interface definition for a callback to be invoked when usb connection is changed.
136      */
137     interface UsbConnectionListener {
onUsbConnectionChanged(boolean connected, long functions, int powerRole, int dataRole)138         void onUsbConnectionChanged(boolean connected, long functions, int powerRole, int dataRole);
139     }
140 }
141