blob: d571d5d7b9028c148ab0c9a92fa0d85bcc33e8c4 [file] [log] [blame]
Kevin Crossand4285492016-11-28 18:40:43 -08001/*
2 * Copyright (C) 2016 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 */
16package android.car.usb.handler;
17
tadvana63f42f42019-03-26 17:25:21 -070018import static android.content.Intent.ACTION_USER_UNLOCKED;
19
Kevin Crossand4285492016-11-28 18:40:43 -080020import android.annotation.Nullable;
21import android.app.Activity;
tadvana63f42f42019-03-26 17:25:21 -070022import android.content.BroadcastReceiver;
Kevin Crossand4285492016-11-28 18:40:43 -080023import android.content.ComponentName;
24import android.content.Context;
25import android.content.Intent;
tadvana63f42f42019-03-26 17:25:21 -070026import android.content.IntentFilter;
Kevin Crossand4285492016-11-28 18:40:43 -080027import android.content.pm.ApplicationInfo;
28import android.content.pm.PackageManager;
29import android.content.pm.PackageManager.NameNotFoundException;
30import android.hardware.usb.UsbDevice;
31import android.hardware.usb.UsbManager;
32import android.os.Bundle;
tadvana63f42f42019-03-26 17:25:21 -070033import android.os.UserHandle;
34import android.os.UserManager;
Kevin Crossand4285492016-11-28 18:40:43 -080035import android.util.Log;
36import android.view.View;
37import android.view.ViewGroup;
38import android.widget.AdapterView;
39import android.widget.ArrayAdapter;
40import android.widget.ImageView;
41import android.widget.LinearLayout;
42import android.widget.ListView;
43import android.widget.TextView;
44import java.util.List;
45
46/**
47 * Activity to handle USB device attached.
48 * <p>
49 * When user plugs in USB device: a) Device was used before and user selected handler for it. In
50 * this case handler will be launched. b) Device has not handler assigned. In this case supported
51 * handlers will be captured, and user will be presented with choice to assign default handler.
52 * After that handler will be launched.
53 */
54public class UsbHostManagementActivity extends Activity
55 implements UsbHostController.UsbHostControllerCallbacks {
56 private static final String TAG = UsbHostManagementActivity.class.getSimpleName();
57
58 private HandlersAdapter mListAdapter;
59 private ListView mHandlersList;
60 private LinearLayout mProgressInfo;
61 private UsbHostController mController;
62 private PackageManager mPackageManager;
63
tadvana63f42f42019-03-26 17:25:21 -070064 private final ResolveBroadcastReceiver mResolveBroadcastReceiver
65 = new ResolveBroadcastReceiver();
66 private boolean mReceiverRegistered = false;
67
68 private void unregisterResolveBroadcastReceiver() {
69 if (mReceiverRegistered) {
70 unregisterReceiver(mResolveBroadcastReceiver);
71 mReceiverRegistered = false;
72 }
73 }
74
75 private void processDevice() {
76 UsbDevice connectedDevice = getDevice();
77
78 if (connectedDevice != null) {
79 mController.processDevice(connectedDevice);
80 } else {
81 unregisterResolveBroadcastReceiver();
82 finish();
83 }
84 }
85
86 private class ResolveBroadcastReceiver extends BroadcastReceiver {
87 public void onReceive(Context context, Intent intent) {
88 // We could have been unregistered after receiving the intent but before processing it,
89 // so make sure we are still registered.
90 if (mReceiverRegistered) {
91 processDevice();
92 unregisterResolveBroadcastReceiver();
93 }
94 }
95 }
96
Kevin Crossand4285492016-11-28 18:40:43 -080097 private final AdapterView.OnItemClickListener mHandlerClickListener =
98 new AdapterView.OnItemClickListener() {
99 @Override
100 public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
101 UsbDeviceSettings settings = (UsbDeviceSettings) parent.getItemAtPosition(position);
102 settings.setDefaultHandler(true);
103 mController.applyDeviceSettings(settings);
104 }
105 };
106
107 @Override
108 public void onCreate(Bundle savedInstanceState) {
109 super.onCreate(savedInstanceState);
110 setContentView(R.layout.usb_host);
111 mHandlersList = (ListView) findViewById(R.id.usb_handlers_list);
112 mProgressInfo = (LinearLayout) findViewById(R.id.usb_handlers_progress);
113 mListAdapter = new HandlersAdapter(this);
114 mHandlersList.setAdapter(mListAdapter);
115 mHandlersList.setOnItemClickListener(mHandlerClickListener);
116 mController = new UsbHostController(this, this);
117 mPackageManager = getPackageManager();
118 }
119
120 @Override
121 public void onDestroy() {
122 super.onDestroy();
123 mController.release();
124 }
125
126 @Override
tadvana63f42f42019-03-26 17:25:21 -0700127 public void onPause() {
128 super.onPause();
129 unregisterResolveBroadcastReceiver();
130 }
131
132 @Override
Kevin Crossand4285492016-11-28 18:40:43 -0800133 public void onResume() {
134 super.onResume();
tadvana63f42f42019-03-26 17:25:21 -0700135
136 UserManager userManager = getSystemService(UserManager.class);
137 if (userManager.isUserUnlocked() || getUserId() == UserHandle.USER_SYSTEM) {
138 processDevice();
Kevin Crossand4285492016-11-28 18:40:43 -0800139 } else {
tadvana63f42f42019-03-26 17:25:21 -0700140 mReceiverRegistered = true;
141 registerReceiver(mResolveBroadcastReceiver, new IntentFilter(ACTION_USER_UNLOCKED));
142 // in case the car was unlocked while the receiver was being registered
143 if (userManager.isUserUnlocked()) {
144 mResolveBroadcastReceiver.onReceive(this, new Intent(ACTION_USER_UNLOCKED));
145 }
Kevin Crossand4285492016-11-28 18:40:43 -0800146 }
147 }
148
149 @Override
150 public void shutdown() {
151 runOnUiThread(new Runnable() {
152 @Override
153 public void run() {
154 finish();
155 }
156 });
157 }
158
159 @Override
160 public void processingStateChanged(final boolean processing) {
161 runOnUiThread(new Runnable() {
162 @Override
163 public void run() {
164 mProgressInfo.setVisibility(processing ? View.VISIBLE : View.GONE);
165 }
166 });
167 }
168
169 @Override
170 public void titleChanged(final String title) {
171 runOnUiThread(new Runnable() {
172 @Override
173 public void run() {
174 setTitle(title);
175 }
176 });
177 }
178
179 @Override
180 public void optionsUpdated(final List<UsbDeviceSettings> options) {
181 runOnUiThread(new Runnable() {
182 @Override
183 public void run() {
184 mListAdapter.clear();
185 mListAdapter.addAll(options);
186 }
187 });
188 }
189
190
191 @Override
192 public void onNewIntent(Intent intent) {
193 super.onNewIntent(intent);
194 setIntent(intent);
195 }
196
197 @Nullable
198 private UsbDevice getDevice() {
199 if (!UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(getIntent().getAction())) {
200 return null;
201 }
202 return (UsbDevice) getIntent().getParcelableExtra(UsbManager.EXTRA_DEVICE);
203 }
204
205 private class HandlersAdapter extends ArrayAdapter<UsbDeviceSettings> {
206 class HandlerHolder {
207 public TextView mAppName;
208 public ImageView mAppIcon;
209 }
210
211 HandlersAdapter(Context context) {
212 super(context, R.layout.usb_handler_row);
213 }
214
215 @Override
216 public View getView(int position, View convertView, ViewGroup parent) {
217 View rowView = convertView;
218 if (rowView == null) {
219 rowView = getLayoutInflater().inflate(R.layout.usb_handler_row, null);
220 HandlerHolder holder = new HandlerHolder();
221 holder.mAppName = (TextView) rowView.findViewById(R.id.usb_handler_title);
222 holder.mAppIcon = (ImageView) rowView.findViewById(R.id.usb_handler_icon);
223 rowView.setTag(holder);
224 }
225
226 HandlerHolder holder = (HandlerHolder) rowView.getTag();
227 ComponentName handler = getItem(position).getHandler();
228
229 try {
230 ApplicationInfo appInfo =
231 mPackageManager.getApplicationInfo(handler.getPackageName(), 0);
232 holder.mAppName.setText(appInfo.loadLabel(mPackageManager));
233 holder.mAppIcon.setImageDrawable(appInfo.loadIcon(mPackageManager));
234 } catch (NameNotFoundException e) {
235 Log.e(TAG, "Handling package not found: " + handler.getPackageName());
236 holder.mAppName.setText(handler.flattenToShortString());
237 holder.mAppIcon.setImageResource(android.R.color.transparent);
238 }
239 return rowView;
240 }
241 }
242}