FileDocCategorySizeDatePackage
UsbDeviceManager.javaAPI DocAndroid 5.1 API40643Thu Mar 12 22:22:42 GMT 2015com.android.server.usb

UsbDeviceManager

public class UsbDeviceManager extends Object
UsbDeviceManager manages USB state in device mode.

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private static final String
USB_STATE_MATCH
private static final String
ACCESSORY_START_MATCH
private static final String
FUNCTIONS_PATH
private static final String
STATE_PATH
private static final String
MASS_STORAGE_FILE_PATH
private static final String
RNDIS_ETH_ADDR_PATH
private static final String
AUDIO_SOURCE_PCM_PATH
private static final int
MSG_UPDATE_STATE
private static final int
MSG_ENABLE_ADB
private static final int
MSG_SET_CURRENT_FUNCTIONS
private static final int
MSG_SYSTEM_READY
private static final int
MSG_BOOT_COMPLETED
private static final int
MSG_USER_SWITCHED
private static final int
AUDIO_MODE_NONE
private static final int
AUDIO_MODE_SOURCE
private static final int
UPDATE_DELAY
private long
mAccessoryModeRequestTime
private static final int
ACCESSORY_REQUEST_TIMEOUT
private static final String
BOOT_MODE_PROPERTY
private UsbHandler
mHandler
private boolean
mBootCompleted
private final Object
mLock
private final android.content.Context
mContext
private final android.content.ContentResolver
mContentResolver
private UsbSettingsManager
mCurrentSettings
private android.app.NotificationManager
mNotificationManager
private final boolean
mHasUsbAccessory
private boolean
mUseUsbNotification
private boolean
mAdbEnabled
private boolean
mAudioSourceEnabled
private Map
mOemModeMap
private String[]
mAccessoryStrings
private UsbDebuggingManager
mDebuggingManager
private final android.os.UEventObserver
mUEventObserver
Constructors Summary
public UsbDeviceManager(android.content.Context context)


       
        mContext = context;
        mContentResolver = context.getContentResolver();
        PackageManager pm = mContext.getPackageManager();
        mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
        initRndisAddress();

        readOemUsbOverrideConfig();

        mHandler = new UsbHandler(FgThread.get().getLooper());

        if (nativeIsStartRequested()) {
            if (DEBUG) Slog.d(TAG, "accessory attached at boot");
            startAccessoryMode();
        }

        boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false);
        boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt"));
        if (secureAdbEnabled && !dataEncrypted) {
            mDebuggingManager = new UsbDebuggingManager(context);
        }
    
Methods Summary
private static java.lang.StringaddFunction(java.lang.String functions, java.lang.String function)

         if ("none".equals(functions)) {
             return function;
         }
        if (!containsFunction(functions, function)) {
            if (functions.length() > 0) {
                functions += ",";
            }
            functions += function;
        }
        return functions;
    
public voidallowUsbDebugging(boolean alwaysAllow, java.lang.String publicKey)

        if (mDebuggingManager != null) {
            mDebuggingManager.allowUsbDebugging(alwaysAllow, publicKey);
        }
    
public voidclearUsbDebuggingKeys()

        if (mDebuggingManager != null) {
            mDebuggingManager.clearUsbDebuggingKeys();
        } else {
            throw new RuntimeException("Cannot clear Usb Debugging keys, "
                        + "UsbDebuggingManager not enabled");
        }
    
private static booleancontainsFunction(java.lang.String functions, java.lang.String function)

        return Arrays.asList(functions.split(",")).contains(function);
    
public voiddenyUsbDebugging()

        if (mDebuggingManager != null) {
            mDebuggingManager.denyUsbDebugging();
        }
    
public voiddump(java.io.FileDescriptor fd, java.io.PrintWriter pw)

        if (mHandler != null) {
            mHandler.dump(fd, pw);
        }
        if (mDebuggingManager != null) {
            mDebuggingManager.dump(fd, pw);
        }
    
public android.hardware.usb.UsbAccessorygetCurrentAccessory()

        return mHandler.getCurrentAccessory();
    
private UsbSettingsManagergetCurrentSettings()

        synchronized (mLock) {
            return mCurrentSettings;
        }
    
private static voidinitRndisAddress()

        // configure RNDIS ethernet address based on our serial number using the same algorithm
        // we had been previously using in kernel board files
        final int ETH_ALEN = 6;
        int address[] = new int[ETH_ALEN];
        // first byte is 0x02 to signify a locally administered address
        address[0] = 0x02;

        String serial = SystemProperties.get("ro.serialno", "1234567890ABCDEF");
        int serialLength = serial.length();
        // XOR the USB serial across the remaining 5 bytes
        for (int i = 0; i < serialLength; i++) {
            address[i % (ETH_ALEN - 1) + 1] ^= (int)serial.charAt(i);
        }
        String addrString = String.format(Locale.US, "%02X:%02X:%02X:%02X:%02X:%02X",
            address[0], address[1], address[2], address[3], address[4], address[5]);
        try {
            FileUtils.stringToFile(RNDIS_ETH_ADDR_PATH, addrString);
        } catch (IOException e) {
           Slog.e(TAG, "failed to write to " + RNDIS_ETH_ADDR_PATH);
        }
    
private native java.lang.String[]nativeGetAccessoryStrings()

private native intnativeGetAudioMode()

private native booleannativeIsStartRequested()

private native android.os.ParcelFileDescriptornativeOpenAccessory()

private booleanneedsOemUsbOverride()

        if (mOemModeMap == null) return false;

        String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");
        return (mOemModeMap.get(bootMode) != null) ? true : false;
    
public android.os.ParcelFileDescriptoropenAccessory(android.hardware.usb.UsbAccessory accessory)

        UsbAccessory currentAccessory = mHandler.getCurrentAccessory();
        if (currentAccessory == null) {
            throw new IllegalArgumentException("no accessory attached");
        }
        if (!currentAccessory.equals(accessory)) {
            String error = accessory.toString()
                    + " does not match current accessory "
                    + currentAccessory;
            throw new IllegalArgumentException(error);
        }
        getCurrentSettings().checkPermission(accessory);
        return nativeOpenAccessory();
    
private java.lang.StringprocessOemUsbOverride(java.lang.String usbFunctions)

        if ((usbFunctions == null) || (mOemModeMap == null)) return usbFunctions;

        String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");

        List<Pair<String, String>> overrides = mOemModeMap.get(bootMode);
        if (overrides != null) {
            for (Pair<String, String> pair: overrides) {
                if (pair.first.equals(usbFunctions)) {
                    Slog.d(TAG, "OEM USB override: " + pair.first + " ==> " + pair.second);
                    return pair.second;
                }
            }
        }
        // return passed in functions as is.
        return usbFunctions;
    
private voidreadOemUsbOverrideConfig()

        String[] configList = mContext.getResources().getStringArray(
            com.android.internal.R.array.config_oemUsbModeOverride);

        if (configList != null) {
            for (String config: configList) {
                String[] items = config.split(":");
                if (items.length == 3) {
                    if (mOemModeMap == null) {
                        mOemModeMap = new HashMap<String, List<Pair<String, String>>>();
                    }
                    List<Pair<String, String>> overrideList = mOemModeMap.get(items[0]);
                    if (overrideList == null) {
                        overrideList = new LinkedList<Pair<String, String>>();
                        mOemModeMap.put(items[0], overrideList);
                    }
                    overrideList.add(new Pair<String, String>(items[1], items[2]));
                }
            }
        }
    
private static java.lang.StringremoveFunction(java.lang.String functions, java.lang.String function)

        String[] split = functions.split(",");
        for (int i = 0; i < split.length; i++) {
            if (function.equals(split[i])) {
                split[i] = null;
            }
        }
        if (split.length == 1 && split[0] == null) {
            return "none";
        }
        StringBuilder builder = new StringBuilder();
         for (int i = 0; i < split.length; i++) {
            String s = split[i];
            if (s != null) {
                if (builder.length() > 0) {
                    builder.append(",");
                }
                builder.append(s);
            }
        }
        return builder.toString();
    
public voidsetCurrentFunctions(java.lang.String functions, boolean makeDefault)

        if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ") default: " + makeDefault);
        mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, makeDefault);
    
public voidsetCurrentSettings(UsbSettingsManager settings)

        synchronized (mLock) {
            mCurrentSettings = settings;
        }
    
public voidsetMassStorageBackingFile(java.lang.String path)

        if (path == null) path = "";
        try {
            FileUtils.stringToFile(MASS_STORAGE_FILE_PATH, path);
        } catch (IOException e) {
           Slog.e(TAG, "failed to write to " + MASS_STORAGE_FILE_PATH);
        }
    
private voidstartAccessoryMode()

        if (!mHasUsbAccessory) return;

        mAccessoryStrings = nativeGetAccessoryStrings();
        boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE);
        // don't start accessory mode if our mandatory strings have not been set
        boolean enableAccessory = (mAccessoryStrings != null &&
                        mAccessoryStrings[UsbAccessory.MANUFACTURER_STRING] != null &&
                        mAccessoryStrings[UsbAccessory.MODEL_STRING] != null);
        String functions = null;

        if (enableAccessory && enableAudio) {
            functions = UsbManager.USB_FUNCTION_ACCESSORY + ","
                    + UsbManager.USB_FUNCTION_AUDIO_SOURCE;
        } else if (enableAccessory) {
            functions = UsbManager.USB_FUNCTION_ACCESSORY;
        } else if (enableAudio) {
            functions = UsbManager.USB_FUNCTION_AUDIO_SOURCE;
        }

        if (functions != null) {
            mAccessoryModeRequestTime = SystemClock.elapsedRealtime();
            setCurrentFunctions(functions, false);
        }
    
public voidsystemReady()

        if (DEBUG) Slog.d(TAG, "systemReady");

        mNotificationManager = (NotificationManager)
                mContext.getSystemService(Context.NOTIFICATION_SERVICE);

        // We do not show the USB notification if the primary volume supports mass storage.
        // The legacy mass storage UI will be used instead.
        boolean massStorageSupported = false;
        final StorageManager storageManager = StorageManager.from(mContext);
        final StorageVolume primary = storageManager.getPrimaryVolume();
        massStorageSupported = primary != null && primary.allowMassStorage();
        mUseUsbNotification = !massStorageSupported;

        // make sure the ADB_ENABLED setting value matches the current state
        try {
            Settings.Global.putInt(mContentResolver,
                    Settings.Global.ADB_ENABLED, mAdbEnabled ? 1 : 0);
        } catch (SecurityException e) {
            // If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't be changed.
            Slog.d(TAG, "ADB_ENABLED is restricted.");
        }
        mHandler.sendEmptyMessage(MSG_SYSTEM_READY);