UsbService.java revision 1848d31c2cbb5404be383ad44049e58e36b258ba
1/* 2 * Copyright (C) 2010 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 an 14 * limitations under the License. 15 */ 16 17package com.android.server.usb; 18 19import android.app.PendingIntent; 20import android.content.BroadcastReceiver; 21import android.content.Context; 22import android.content.Intent; 23import android.content.IntentFilter; 24import android.content.pm.PackageManager; 25import android.hardware.usb.IUsbManager; 26import android.hardware.usb.UsbAccessory; 27import android.hardware.usb.UsbDevice; 28import android.os.Bundle; 29import android.os.ParcelFileDescriptor; 30import android.os.UserHandle; 31import android.os.UserManager; 32import android.util.SparseArray; 33 34import com.android.internal.annotations.GuardedBy; 35import com.android.internal.util.IndentingPrintWriter; 36import com.android.server.SystemService; 37 38import java.io.File; 39import java.io.FileDescriptor; 40import java.io.PrintWriter; 41 42/** 43 * UsbService manages all USB related state, including both host and device support. 44 * Host related events and calls are delegated to UsbHostManager, and device related 45 * support is delegated to UsbDeviceManager. 46 */ 47public class UsbService extends IUsbManager.Stub { 48 49 public static class Lifecycle extends SystemService { 50 private UsbService mUsbService; 51 52 public Lifecycle(Context context) { 53 super(context); 54 } 55 56 @Override 57 public void onStart() { 58 mUsbService = new UsbService(getContext()); 59 publishBinderService(Context.USB_SERVICE, mUsbService); 60 } 61 62 @Override 63 public void onBootPhase(int phase) { 64 if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) { 65 mUsbService.systemReady(); 66 } 67 } 68 } 69 70 private static final String TAG = "UsbService"; 71 72 private final Context mContext; 73 74 private UsbDeviceManager mDeviceManager; 75 private UsbHostManager mHostManager; 76 77 private final Object mLock = new Object(); 78 79 /** Map from {@link UserHandle} to {@link UsbSettingsManager} */ 80 @GuardedBy("mLock") 81 private final SparseArray<UsbSettingsManager> 82 mSettingsByUser = new SparseArray<UsbSettingsManager>(); 83 84 private UsbSettingsManager getSettingsForUser(int userId) { 85 synchronized (mLock) { 86 UsbSettingsManager settings = mSettingsByUser.get(userId); 87 if (settings == null) { 88 settings = new UsbSettingsManager(mContext, new UserHandle(userId)); 89 mSettingsByUser.put(userId, settings); 90 } 91 return settings; 92 } 93 } 94 95 public UsbService(Context context) { 96 mContext = context; 97 98 final PackageManager pm = mContext.getPackageManager(); 99 if (pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) { 100 mHostManager = new UsbHostManager(context); 101 } 102 if (new File("/sys/class/android_usb").exists()) { 103 mDeviceManager = new UsbDeviceManager(context); 104 } 105 106 setCurrentUser(UserHandle.USER_OWNER); 107 108 final IntentFilter userFilter = new IntentFilter(); 109 userFilter.addAction(Intent.ACTION_USER_SWITCHED); 110 userFilter.addAction(Intent.ACTION_USER_STOPPED); 111 mContext.registerReceiver(mUserReceiver, userFilter, null, null); 112 } 113 114 private BroadcastReceiver mUserReceiver = new BroadcastReceiver() { 115 @Override 116 public void onReceive(Context context, Intent intent) { 117 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 118 final String action = intent.getAction(); 119 if (Intent.ACTION_USER_SWITCHED.equals(action)) { 120 setCurrentUser(userId); 121 } else if (Intent.ACTION_USER_STOPPED.equals(action)) { 122 synchronized (mLock) { 123 mSettingsByUser.remove(userId); 124 } 125 } 126 } 127 }; 128 129 private void setCurrentUser(int userId) { 130 final UsbSettingsManager userSettings = getSettingsForUser(userId); 131 if (mHostManager != null) { 132 mHostManager.setCurrentSettings(userSettings); 133 } 134 if (mDeviceManager != null) { 135 mDeviceManager.setCurrentSettings(userSettings); 136 } 137 } 138 139 public void systemReady() { 140 if (mDeviceManager != null) { 141 mDeviceManager.systemReady(); 142 } 143 if (mHostManager != null) { 144 mHostManager.systemReady(); 145 } 146 } 147 148 /* Returns a list of all currently attached USB devices (host mdoe) */ 149 @Override 150 public void getDeviceList(Bundle devices) { 151 if (mHostManager != null) { 152 mHostManager.getDeviceList(devices); 153 } 154 } 155 156 /* Opens the specified USB device (host mode) */ 157 @Override 158 public ParcelFileDescriptor openDevice(String deviceName) { 159 if (mHostManager != null) { 160 return mHostManager.openDevice(deviceName); 161 } else { 162 return null; 163 } 164 } 165 166 /* returns the currently attached USB accessory (device mode) */ 167 @Override 168 public UsbAccessory getCurrentAccessory() { 169 if (mDeviceManager != null) { 170 return mDeviceManager.getCurrentAccessory(); 171 } else { 172 return null; 173 } 174 } 175 176 /* opens the currently attached USB accessory (device mode) */ 177 @Override 178 public ParcelFileDescriptor openAccessory(UsbAccessory accessory) { 179 if (mDeviceManager != null) { 180 return mDeviceManager.openAccessory(accessory); 181 } else { 182 return null; 183 } 184 } 185 186 @Override 187 public void setDevicePackage(UsbDevice device, String packageName, int userId) { 188 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 189 getSettingsForUser(userId).setDevicePackage(device, packageName); 190 } 191 192 @Override 193 public void setAccessoryPackage(UsbAccessory accessory, String packageName, int userId) { 194 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 195 getSettingsForUser(userId).setAccessoryPackage(accessory, packageName); 196 } 197 198 @Override 199 public boolean hasDevicePermission(UsbDevice device) { 200 final int userId = UserHandle.getCallingUserId(); 201 return getSettingsForUser(userId).hasPermission(device); 202 } 203 204 @Override 205 public boolean hasAccessoryPermission(UsbAccessory accessory) { 206 final int userId = UserHandle.getCallingUserId(); 207 return getSettingsForUser(userId).hasPermission(accessory); 208 } 209 210 @Override 211 public void requestDevicePermission(UsbDevice device, String packageName, PendingIntent pi) { 212 final int userId = UserHandle.getCallingUserId(); 213 getSettingsForUser(userId).requestPermission(device, packageName, pi); 214 } 215 216 @Override 217 public void requestAccessoryPermission( 218 UsbAccessory accessory, String packageName, PendingIntent pi) { 219 final int userId = UserHandle.getCallingUserId(); 220 getSettingsForUser(userId).requestPermission(accessory, packageName, pi); 221 } 222 223 @Override 224 public void grantDevicePermission(UsbDevice device, int uid) { 225 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 226 final int userId = UserHandle.getUserId(uid); 227 getSettingsForUser(userId).grantDevicePermission(device, uid); 228 } 229 230 @Override 231 public void grantAccessoryPermission(UsbAccessory accessory, int uid) { 232 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 233 final int userId = UserHandle.getUserId(uid); 234 getSettingsForUser(userId).grantAccessoryPermission(accessory, uid); 235 } 236 237 @Override 238 public boolean hasDefaults(String packageName, int userId) { 239 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 240 return getSettingsForUser(userId).hasDefaults(packageName); 241 } 242 243 @Override 244 public void clearDefaults(String packageName, int userId) { 245 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 246 getSettingsForUser(userId).clearDefaults(packageName); 247 } 248 249 @Override 250 public void setCurrentFunction(String function, boolean makeDefault) { 251 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 252 253 // If attempt to change USB function while file transfer is restricted, ensure that 254 // the current function is set to "none", and return. 255 UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 256 if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) { 257 if (mDeviceManager != null) mDeviceManager.setCurrentFunctions("none", false); 258 return; 259 } 260 261 if (mDeviceManager != null) { 262 mDeviceManager.setCurrentFunctions(function, makeDefault); 263 } else { 264 throw new IllegalStateException("USB device mode not supported"); 265 } 266 } 267 268 @Override 269 public void setMassStorageBackingFile(String path) { 270 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 271 if (mDeviceManager != null) { 272 mDeviceManager.setMassStorageBackingFile(path); 273 } else { 274 throw new IllegalStateException("USB device mode not supported"); 275 } 276 } 277 278 @Override 279 public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { 280 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 281 mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey); 282 } 283 284 @Override 285 public void denyUsbDebugging() { 286 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 287 mDeviceManager.denyUsbDebugging(); 288 } 289 290 @Override 291 public void clearUsbDebuggingKeys() { 292 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 293 mDeviceManager.clearUsbDebuggingKeys(); 294 } 295 296 @Override 297 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 298 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); 299 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 300 301 pw.println("USB Manager State:"); 302 if (mDeviceManager != null) { 303 mDeviceManager.dump(fd, pw); 304 } 305 if (mHostManager != null) { 306 mHostManager.dump(fd, pw); 307 } 308 309 synchronized (mLock) { 310 for (int i = 0; i < mSettingsByUser.size(); i++) { 311 final int userId = mSettingsByUser.keyAt(i); 312 final UsbSettingsManager settings = mSettingsByUser.valueAt(i); 313 pw.increaseIndent(); 314 pw.println("Settings for user " + userId + ":"); 315 settings.dump(fd, pw); 316 pw.decreaseIndent(); 317 } 318 } 319 pw.decreaseIndent(); 320 } 321} 322