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