1 /* 2 * Copyright (C) 2019 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 android.car.usb.handler; 17 18 import android.app.Notification; 19 import android.app.NotificationChannel; 20 import android.app.NotificationManager; 21 import android.app.Service; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.hardware.usb.UsbDevice; 25 import android.hardware.usb.UsbManager; 26 import android.os.Binder; 27 import android.os.UserHandle; 28 import android.util.Log; 29 30 import java.util.ArrayList; 31 32 /** 33 * Starts the {@link UsbHostManagementActivity} for each connected usb device when {@link 34 * #onStartCommand(Intent, int, int)} is called. This is meant to allow this activity to start for 35 * connected devices on start up, without holding up processing of the LOCKED_BOOT_COMPLETED intent. 36 */ 37 public class BootUsbService extends Service { 38 private static final String TAG = BootUsbService.class.getSimpleName(); 39 private static final int NOTIFICATION_ID = 1; 40 41 static final String USB_DEVICE_LIST_KEY = "usb_device_list"; 42 43 private ArrayList<UsbDevice> mDeviceList; 44 45 @Override onBind(Intent intent)46 public Binder onBind(Intent intent) { 47 return null; 48 } 49 50 @Override onCreate()51 public void onCreate() { 52 String notificationIdString = 53 getResources().getString(R.string.usb_boot_service_notification); 54 NotificationManager notificationManager = getSystemService(NotificationManager.class); 55 NotificationChannel notificationChannel = 56 new NotificationChannel( 57 notificationIdString, 58 "Car Usb Handler enumeration", 59 NotificationManager.IMPORTANCE_NONE); 60 notificationManager.createNotificationChannel(notificationChannel); 61 Notification notification = 62 new Notification.Builder( 63 this, notificationIdString).setSmallIcon(R.drawable.ic_launcher).build(); 64 // CarUsbHandler runs in the background, so startForeground must be explicitly called. 65 startForeground(NOTIFICATION_ID, notification); 66 } 67 68 @Override onStartCommand(Intent intent, int flags, int startId)69 public int onStartCommand(Intent intent, int flags, int startId) { 70 mDeviceList = intent.getParcelableArrayListExtra(USB_DEVICE_LIST_KEY); 71 processDevices(); 72 return START_NOT_STICKY; 73 } 74 processDevices()75 private void processDevices() { 76 for (UsbDevice device : mDeviceList) { 77 Log.d(TAG, "Processing device: " + device.getProductName()); 78 handle(this, device); 79 } 80 stopSelf(); 81 } 82 handle(Context context, UsbDevice device)83 private void handle(Context context, UsbDevice device) { 84 Intent manageDevice = new Intent(context, UsbHostManagementActivity.class); 85 manageDevice.setAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); 86 manageDevice.putExtra(UsbManager.EXTRA_DEVICE, device); 87 manageDevice.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); 88 context.startActivityAsUser(manageDevice, UserHandle.CURRENT); 89 } 90 } 91