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 17 package com.android.server.usb; 18 19 import android.annotation.NonNull; 20 import android.annotation.UserIdInt; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.pm.UserInfo; 24 import android.hardware.usb.UsbAccessory; 25 import android.hardware.usb.UsbDevice; 26 import android.hardware.usb.UsbManager; 27 import android.os.UserHandle; 28 import android.os.UserManager; 29 import android.service.usb.UsbSettingsManagerProto; 30 import android.util.Slog; 31 import android.util.SparseArray; 32 33 import com.android.internal.annotations.GuardedBy; 34 import com.android.internal.util.dump.DualDumpOutputStream; 35 36 import java.util.List; 37 38 class UsbPermissionManager { 39 private static final String LOG_TAG = UsbPermissionManager.class.getSimpleName(); 40 private static final boolean DEBUG = false; 41 42 /** Context to be used by this module */ 43 private final @NonNull Context mContext; 44 45 /** Map from user id to {@link UsbUserPermissionManager} for the user */ 46 @GuardedBy("mPermissionsByUser") 47 private final SparseArray<UsbUserPermissionManager> mPermissionsByUser = new SparseArray<>(); 48 49 final UsbService mUsbService; 50 UsbPermissionManager(@onNull Context context, @NonNull UsbService usbService)51 UsbPermissionManager(@NonNull Context context, 52 @NonNull UsbService usbService) { 53 mContext = context; 54 mUsbService = usbService; 55 } 56 getPermissionsForUser(@serIdInt int userId)57 @NonNull UsbUserPermissionManager getPermissionsForUser(@UserIdInt int userId) { 58 synchronized (mPermissionsByUser) { 59 UsbUserPermissionManager permissions = mPermissionsByUser.get(userId); 60 if (permissions == null) { 61 permissions = new UsbUserPermissionManager(mContext.createContextAsUser( 62 UserHandle.of(userId), 0), mUsbService.getSettingsForUser(userId)); 63 mPermissionsByUser.put(userId, permissions); 64 } 65 return permissions; 66 } 67 } 68 getPermissionsForUser(@onNull UserHandle user)69 @NonNull UsbUserPermissionManager getPermissionsForUser(@NonNull UserHandle user) { 70 return getPermissionsForUser(user.getIdentifier()); 71 } 72 remove(@onNull UserHandle userToRemove)73 void remove(@NonNull UserHandle userToRemove) { 74 synchronized (mPermissionsByUser) { 75 mPermissionsByUser.remove(userToRemove.getIdentifier()); 76 } 77 } 78 79 /** 80 * Remove temporary access permission and broadcast that a device was removed. 81 * 82 * @param device The device that is removed 83 */ usbDeviceRemoved(@onNull UsbDevice device)84 void usbDeviceRemoved(@NonNull UsbDevice device) { 85 synchronized (mPermissionsByUser) { 86 for (int i = 0; i < mPermissionsByUser.size(); i++) { 87 // clear temporary permissions for the device 88 mPermissionsByUser.valueAt(i).removeDevicePermissions(device); 89 } 90 } 91 92 Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_DETACHED); 93 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 94 intent.putExtra(UsbManager.EXTRA_DEVICE, device); 95 96 if (DEBUG) { 97 Slog.d(LOG_TAG, "usbDeviceRemoved, sending " + intent); 98 } 99 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 100 } 101 102 /** 103 * Remove temporary access permission and broadcast that a accessory was removed. 104 * 105 * @param accessory The accessory that is removed 106 */ usbAccessoryRemoved(@onNull UsbAccessory accessory)107 void usbAccessoryRemoved(@NonNull UsbAccessory accessory) { 108 synchronized (mPermissionsByUser) { 109 for (int i = 0; i < mPermissionsByUser.size(); i++) { 110 // clear temporary permissions for the accessory 111 mPermissionsByUser.valueAt(i).removeAccessoryPermissions(accessory); 112 } 113 } 114 115 Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_DETACHED); 116 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 117 intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory); 118 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 119 } 120 dump(@onNull DualDumpOutputStream dump, String idName, long id)121 void dump(@NonNull DualDumpOutputStream dump, String idName, long id) { 122 long token = dump.start(idName, id); 123 UserManager userManager = mContext.getSystemService(UserManager.class); 124 synchronized (mPermissionsByUser) { 125 List<UserInfo> users = userManager.getUsers(); 126 int numUsers = users.size(); 127 for (int i = 0; i < numUsers; i++) { 128 getPermissionsForUser(users.get(i).id).dump(dump, "user_permissions", 129 UsbSettingsManagerProto.USER_SETTINGS); 130 } 131 } 132 dump.end(token); 133 } 134 135 } 136