UsbSettingsManager.java revision bee04d08b555b030c6e6cf31b10124862411eeb1
1/* 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 */ 16 17package com.android.server.usb; 18 19import android.annotation.NonNull; 20import android.annotation.UserIdInt; 21import android.content.Context; 22import android.content.Intent; 23import android.content.pm.UserInfo; 24import android.hardware.usb.UsbAccessory; 25import android.hardware.usb.UsbDevice; 26import android.hardware.usb.UsbManager; 27import android.os.UserHandle; 28import android.os.UserManager; 29import android.util.Slog; 30import android.util.SparseArray; 31 32import com.android.internal.annotations.GuardedBy; 33import com.android.internal.util.IndentingPrintWriter; 34 35/** 36 * Maintains all {@link UsbUserSettingsManager} for all users. 37 */ 38class UsbSettingsManager { 39 private static final String LOG_TAG = UsbSettingsManager.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 UsbUserSettingsManager} for the user */ 46 @GuardedBy("mSettingsByUser") 47 private final SparseArray<UsbUserSettingsManager> mSettingsByUser = new SparseArray<>(); 48 49 /** 50 * Map from the parent profile's user id to {@link UsbProfileGroupSettingsManager} for the 51 * group. 52 */ 53 @GuardedBy("mSettingsByProfileGroup") 54 private final SparseArray<UsbProfileGroupSettingsManager> mSettingsByProfileGroup 55 = new SparseArray<>(); 56 private UserManager mUserManager; 57 58 public UsbSettingsManager(@NonNull Context context) { 59 mContext = context; 60 mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); 61 } 62 63 /** 64 * Get the {@link UsbUserSettingsManager} for a user. 65 * 66 * @param userId The id of the user 67 * 68 * @return The settings for the user 69 */ 70 @NonNull UsbUserSettingsManager getSettingsForUser(@UserIdInt int userId) { 71 synchronized (mSettingsByUser) { 72 UsbUserSettingsManager settings = mSettingsByUser.get(userId); 73 if (settings == null) { 74 settings = new UsbUserSettingsManager(mContext, new UserHandle(userId)); 75 mSettingsByUser.put(userId, settings); 76 } 77 return settings; 78 } 79 } 80 81 /** 82 * Get the {@link UsbProfileGroupSettingsManager} for a user. 83 * 84 * @param user Any user of the profile group 85 * 86 * @return The settings for the profile group 87 */ 88 @NonNull UsbProfileGroupSettingsManager getSettingsForProfileGroup(@NonNull UserHandle user) { 89 UserHandle parentUser; 90 91 UserInfo parentUserInfo = mUserManager.getProfileParent(user.getIdentifier()); 92 if (parentUserInfo != null) { 93 parentUser = parentUserInfo.getUserHandle(); 94 } else { 95 parentUser = user; 96 } 97 98 synchronized (mSettingsByProfileGroup) { 99 UsbProfileGroupSettingsManager settings = mSettingsByProfileGroup.get( 100 parentUser.getIdentifier()); 101 if (settings == null) { 102 settings = new UsbProfileGroupSettingsManager(mContext, parentUser, this); 103 mSettingsByProfileGroup.put(parentUser.getIdentifier(), settings); 104 } 105 return settings; 106 } 107 } 108 109 /** 110 * Remove the settings for a user. 111 * 112 * @param userToRemove The user to remove 113 */ 114 void remove(@NonNull UserHandle userToRemove) { 115 synchronized (mSettingsByUser) { 116 mSettingsByUser.remove(userToRemove.getIdentifier()); 117 } 118 119 synchronized (mSettingsByProfileGroup) { 120 if (mSettingsByProfileGroup.indexOfKey(userToRemove.getIdentifier()) >= 0) { 121 // The user to remove is the parent user of the group. The parent is the last user 122 // that gets removed. All state will be removed with the user 123 mSettingsByProfileGroup.remove(userToRemove.getIdentifier()); 124 } else { 125 // We cannot find the parent user of the user that is removed, hence try to remove 126 // it from all profile groups. 127 int numProfileGroups = mSettingsByProfileGroup.size(); 128 for (int i = 0; i < numProfileGroups; i++) { 129 mSettingsByProfileGroup.valueAt(i).removeAllDefaultsForUser(userToRemove); 130 } 131 } 132 } 133 } 134 135 /** 136 * Dump all settings of all users. 137 * 138 * @param pw The writer to dump to 139 */ 140 void dump(@NonNull IndentingPrintWriter pw) { 141 synchronized (mSettingsByUser) { 142 int numUsers = mSettingsByUser.size(); 143 for (int i = 0; i < numUsers; i++) { 144 final int userId = mSettingsByUser.keyAt(i); 145 final UsbUserSettingsManager settings = mSettingsByUser.valueAt(i); 146 pw.println("Settings for user " + userId + ":"); 147 pw.increaseIndent(); 148 try { 149 settings.dump(pw); 150 } finally { 151 pw.decreaseIndent(); 152 } 153 } 154 } 155 156 synchronized (mSettingsByProfileGroup) { 157 int numProfileGroups = mSettingsByProfileGroup.size(); 158 for (int i = 0; i < numProfileGroups; i++) { 159 final int parentUserId = mSettingsByProfileGroup.keyAt(i); 160 final UsbProfileGroupSettingsManager settings = mSettingsByProfileGroup.valueAt(i); 161 pw.println("Settings for profile group " + parentUserId + ":"); 162 pw.increaseIndent(); 163 try { 164 settings.dump(pw); 165 } finally { 166 pw.decreaseIndent(); 167 } 168 } 169 } 170 } 171 172 /** 173 * Remove temporary access permission and broadcast that a device was removed. 174 * 175 * @param device The device that is removed 176 */ 177 void usbDeviceRemoved(@NonNull UsbDevice device) { 178 synchronized (mSettingsByUser) { 179 for (int i = 0; i < mSettingsByUser.size(); i++) { 180 // clear temporary permissions for the device 181 mSettingsByUser.valueAt(i).removeDevicePermissions(device); 182 } 183 } 184 185 Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_DETACHED); 186 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 187 intent.putExtra(UsbManager.EXTRA_DEVICE, device); 188 189 if (DEBUG) { 190 Slog.d(LOG_TAG, "usbDeviceRemoved, sending " + intent); 191 } 192 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 193 } 194 195 /** 196 * Remove temporary access permission and broadcast that a accessory was removed. 197 * 198 * @param accessory The accessory that is removed 199 */ 200 void usbAccessoryRemoved(@NonNull UsbAccessory accessory) { 201 synchronized (mSettingsByUser) { 202 for (int i = 0; i < mSettingsByUser.size(); i++) { 203 // clear temporary permissions for the accessory 204 mSettingsByUser.valueAt(i).removeAccessoryPermissions(accessory); 205 } 206 } 207 208 Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_DETACHED); 209 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 210 intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory); 211 mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 212 } 213} 214