UsbService.java revision fcf10f7c12cb3107bdfedce6f76a8c866d154f3c
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 private final UsbAlsaManager mAlsaManager; 77 78 private final Object mLock = new Object(); 79 80 /** Map from {@link UserHandle} to {@link UsbSettingsManager} */ 81 @GuardedBy("mLock") 82 private final SparseArray<UsbSettingsManager> 83 mSettingsByUser = new SparseArray<UsbSettingsManager>(); 84 85 private UsbSettingsManager getSettingsForUser(int userId) { 86 synchronized (mLock) { 87 UsbSettingsManager settings = mSettingsByUser.get(userId); 88 if (settings == null) { 89 settings = new UsbSettingsManager(mContext, new UserHandle(userId)); 90 mSettingsByUser.put(userId, settings); 91 } 92 return settings; 93 } 94 } 95 96 public UsbService(Context context) { 97 mContext = context; 98 99 mAlsaManager = new UsbAlsaManager(context); 100 101 final PackageManager pm = mContext.getPackageManager(); 102 if (pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) { 103 mHostManager = new UsbHostManager(context, mAlsaManager); 104 } 105 if (new File("/sys/class/android_usb").exists()) { 106 mDeviceManager = new UsbDeviceManager(context, mAlsaManager); 107 } 108 109 setCurrentUser(UserHandle.USER_OWNER); 110 111 final IntentFilter userFilter = new IntentFilter(); 112 userFilter.addAction(Intent.ACTION_USER_SWITCHED); 113 userFilter.addAction(Intent.ACTION_USER_STOPPED); 114 mContext.registerReceiver(mUserReceiver, userFilter, null, null); 115 } 116 117 private BroadcastReceiver mUserReceiver = new BroadcastReceiver() { 118 @Override 119 public void onReceive(Context context, Intent intent) { 120 final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); 121 final String action = intent.getAction(); 122 if (Intent.ACTION_USER_SWITCHED.equals(action)) { 123 setCurrentUser(userId); 124 } else if (Intent.ACTION_USER_STOPPED.equals(action)) { 125 synchronized (mLock) { 126 mSettingsByUser.remove(userId); 127 } 128 } 129 } 130 }; 131 132 private void setCurrentUser(int userId) { 133 final UsbSettingsManager userSettings = getSettingsForUser(userId); 134 if (mHostManager != null) { 135 mHostManager.setCurrentSettings(userSettings); 136 } 137 if (mDeviceManager != null) { 138 mDeviceManager.setCurrentSettings(userSettings); 139 } 140 } 141 142 public void systemReady() { 143 mAlsaManager.systemReady(); 144 145 if (mDeviceManager != null) { 146 mDeviceManager.systemReady(); 147 } 148 if (mHostManager != null) { 149 mHostManager.systemReady(); 150 } 151 } 152 153 /* Returns a list of all currently attached USB devices (host mdoe) */ 154 @Override 155 public void getDeviceList(Bundle devices) { 156 if (mHostManager != null) { 157 mHostManager.getDeviceList(devices); 158 } 159 } 160 161 /* Opens the specified USB device (host mode) */ 162 @Override 163 public ParcelFileDescriptor openDevice(String deviceName) { 164 if (mHostManager != null) { 165 return mHostManager.openDevice(deviceName); 166 } else { 167 return null; 168 } 169 } 170 171 /* returns the currently attached USB accessory (device mode) */ 172 @Override 173 public UsbAccessory getCurrentAccessory() { 174 if (mDeviceManager != null) { 175 return mDeviceManager.getCurrentAccessory(); 176 } else { 177 return null; 178 } 179 } 180 181 /* opens the currently attached USB accessory (device mode) */ 182 @Override 183 public ParcelFileDescriptor openAccessory(UsbAccessory accessory) { 184 if (mDeviceManager != null) { 185 return mDeviceManager.openAccessory(accessory); 186 } else { 187 return null; 188 } 189 } 190 191 @Override 192 public void setDevicePackage(UsbDevice device, String packageName, int userId) { 193 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 194 getSettingsForUser(userId).setDevicePackage(device, packageName); 195 } 196 197 @Override 198 public void setAccessoryPackage(UsbAccessory accessory, String packageName, int userId) { 199 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 200 getSettingsForUser(userId).setAccessoryPackage(accessory, packageName); 201 } 202 203 @Override 204 public boolean hasDevicePermission(UsbDevice device) { 205 final int userId = UserHandle.getCallingUserId(); 206 return getSettingsForUser(userId).hasPermission(device); 207 } 208 209 @Override 210 public boolean hasAccessoryPermission(UsbAccessory accessory) { 211 final int userId = UserHandle.getCallingUserId(); 212 return getSettingsForUser(userId).hasPermission(accessory); 213 } 214 215 @Override 216 public void requestDevicePermission(UsbDevice device, String packageName, PendingIntent pi) { 217 final int userId = UserHandle.getCallingUserId(); 218 getSettingsForUser(userId).requestPermission(device, packageName, pi); 219 } 220 221 @Override 222 public void requestAccessoryPermission( 223 UsbAccessory accessory, String packageName, PendingIntent pi) { 224 final int userId = UserHandle.getCallingUserId(); 225 getSettingsForUser(userId).requestPermission(accessory, packageName, pi); 226 } 227 228 @Override 229 public void grantDevicePermission(UsbDevice device, int uid) { 230 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 231 final int userId = UserHandle.getUserId(uid); 232 getSettingsForUser(userId).grantDevicePermission(device, uid); 233 } 234 235 @Override 236 public void grantAccessoryPermission(UsbAccessory accessory, int uid) { 237 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 238 final int userId = UserHandle.getUserId(uid); 239 getSettingsForUser(userId).grantAccessoryPermission(accessory, uid); 240 } 241 242 @Override 243 public boolean hasDefaults(String packageName, int userId) { 244 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 245 return getSettingsForUser(userId).hasDefaults(packageName); 246 } 247 248 @Override 249 public void clearDefaults(String packageName, int userId) { 250 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 251 getSettingsForUser(userId).clearDefaults(packageName); 252 } 253 254 @Override 255 public void setCurrentFunction(String function) { 256 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 257 258 // If attempt to change USB function while file transfer is restricted, ensure that 259 // the current function is set to "none", and return. 260 UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE); 261 if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) { 262 if (mDeviceManager != null) mDeviceManager.setCurrentFunctions("none"); 263 return; 264 } 265 266 if (mDeviceManager != null) { 267 mDeviceManager.setCurrentFunctions(function); 268 } else { 269 throw new IllegalStateException("USB device mode not supported"); 270 } 271 } 272 273 @Override 274 public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { 275 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 276 mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey); 277 } 278 279 @Override 280 public void denyUsbDebugging() { 281 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 282 mDeviceManager.denyUsbDebugging(); 283 } 284 285 @Override 286 public void clearUsbDebuggingKeys() { 287 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null); 288 mDeviceManager.clearUsbDebuggingKeys(); 289 } 290 291 @Override 292 public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 293 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); 294 final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); 295 296 pw.println("USB Manager State:"); 297 if (mDeviceManager != null) { 298 mDeviceManager.dump(fd, pw); 299 } 300 if (mHostManager != null) { 301 mHostManager.dump(fd, pw); 302 } 303 mAlsaManager.dump(fd, pw); 304 305 synchronized (mLock) { 306 for (int i = 0; i < mSettingsByUser.size(); i++) { 307 final int userId = mSettingsByUser.keyAt(i); 308 final UsbSettingsManager settings = mSettingsByUser.valueAt(i); 309 pw.increaseIndent(); 310 pw.println("Settings for user " + userId + ":"); 311 settings.dump(fd, pw); 312 pw.decreaseIndent(); 313 } 314 } 315 pw.decreaseIndent(); 316 } 317} 318