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

UsbDebuggingManager

public class UsbDebuggingManager extends Object implements Runnable

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private final String
ADBD_SOCKET
private final String
ADB_DIRECTORY
private final String
ADB_KEYS_FILE
private final int
BUFFER_SIZE
private final android.content.Context
mContext
private final android.os.Handler
mHandler
private Thread
mThread
private boolean
mAdbEnabled
private String
mFingerprints
private android.net.LocalSocket
mSocket
private OutputStream
mOutputStream
Constructors Summary
public UsbDebuggingManager(android.content.Context context)


       
        mHandler = new UsbDebuggingHandler(FgThread.get().getLooper());
        mContext = context;
    
Methods Summary
public voidallowUsbDebugging(boolean alwaysAllow, java.lang.String publicKey)

        Message msg = mHandler.obtainMessage(UsbDebuggingHandler.MESSAGE_ADB_ALLOW);
        msg.arg1 = alwaysAllow ? 1 : 0;
        msg.obj = publicKey;
        mHandler.sendMessage(msg);
    
public voidclearUsbDebuggingKeys()

        mHandler.sendEmptyMessage(UsbDebuggingHandler.MESSAGE_ADB_CLEAR);
    
private voidcloseSocket()

        try {
            mOutputStream.close();
        } catch (IOException e) {
            Slog.e(TAG, "Failed closing output stream: " + e);
        }

        try {
            mSocket.close();
        } catch (IOException ex) {
            Slog.e(TAG, "Failed closing socket: " + ex);
        }
    
private android.content.IntentcreateConfirmationIntent(android.content.ComponentName componentName, java.lang.String key, java.lang.String fingerprints)

        Intent intent = new Intent();
        intent.setClassName(componentName.getPackageName(), componentName.getClassName());
        intent.putExtra("key", key);
        intent.putExtra("fingerprints", fingerprints);
        return intent;
    
private voiddeleteKeyFile()

        File keyFile = getUserKeyFile();
        if (keyFile != null) {
            keyFile.delete();
        }
    
public voiddenyUsbDebugging()

        mHandler.sendEmptyMessage(UsbDebuggingHandler.MESSAGE_ADB_DENY);
    
public voiddump(java.io.FileDescriptor fd, java.io.PrintWriter pw)

        pw.println("  USB Debugging State:");
        pw.println("    Connected to adbd: " + (mOutputStream != null));
        pw.println("    Last key received: " + mFingerprints);
        pw.println("    User keys:");
        try {
            pw.println(FileUtils.readTextFile(new File("/data/misc/adb/adb_keys"), 0, null));
        } catch (IOException e) {
            pw.println("IOException: " + e);
        }
        pw.println("    System keys:");
        try {
            pw.println(FileUtils.readTextFile(new File("/adb_keys"), 0, null));
        } catch (IOException e) {
            pw.println("IOException: " + e);
        }
    
private java.lang.StringgetFingerprints(java.lang.String key)

        String hex = "0123456789ABCDEF";
        StringBuilder sb = new StringBuilder();
        MessageDigest digester;

        if (key == null) {
            return "";
        }

        try {
            digester = MessageDigest.getInstance("MD5");
        } catch (Exception ex) {
            Slog.e(TAG, "Error getting digester", ex);
            return "";
        }

        byte[] base64_data = key.split("\\s+")[0].getBytes();
        byte[] digest;
        try {
            digest = digester.digest(Base64.decode(base64_data, Base64.DEFAULT));
        } catch (IllegalArgumentException e) {
            Slog.e(TAG, "error doing base64 decoding", e);
            return "";
        }
        for (int i = 0; i < digest.length; i++) {
            sb.append(hex.charAt((digest[i] >> 4) & 0xf));
            sb.append(hex.charAt(digest[i] & 0xf));
            if (i < digest.length - 1)
                sb.append(":");
        }
        return sb.toString();
    
private java.io.FilegetUserKeyFile()

        File dataDir = Environment.getDataDirectory();
        File adbDir = new File(dataDir, ADB_DIRECTORY);

        if (!adbDir.exists()) {
            Slog.e(TAG, "ADB data directory does not exist");
            return null;
        }

        return new File(adbDir, ADB_KEYS_FILE);
    
private voidlistenToSocket()

        try {
            byte[] buffer = new byte[BUFFER_SIZE];
            LocalSocketAddress address = new LocalSocketAddress(ADBD_SOCKET,
                                         LocalSocketAddress.Namespace.RESERVED);
            InputStream inputStream = null;

            mSocket = new LocalSocket();
            mSocket.connect(address);

            mOutputStream = mSocket.getOutputStream();
            inputStream = mSocket.getInputStream();

            while (true) {
                int count = inputStream.read(buffer);
                if (count < 0) {
                    break;
                }

                if (buffer[0] == 'P" && buffer[1] == 'K") {
                    String key = new String(Arrays.copyOfRange(buffer, 2, count));
                    Slog.d(TAG, "Received public key: " + key);
                    Message msg = mHandler.obtainMessage(UsbDebuggingHandler.MESSAGE_ADB_CONFIRM);
                    msg.obj = key;
                    mHandler.sendMessage(msg);
                }
                else {
                    Slog.e(TAG, "Wrong message: " + (new String(Arrays.copyOfRange(buffer, 0, 2))));
                    break;
                }
            }
        } finally {
            closeSocket();
        }
    
public voidrun()

        while (mAdbEnabled) {
            try {
                listenToSocket();
            } catch (Exception e) {
                /* Don't loop too fast if adbd dies, before init restarts it */
                SystemClock.sleep(1000);
            }
        }
    
private voidsendResponse(java.lang.String msg)

        if (mOutputStream != null) {
            try {
                mOutputStream.write(msg.getBytes());
            }
            catch (IOException ex) {
                Slog.e(TAG, "Failed to write response:", ex);
            }
        }
    
public voidsetAdbEnabled(boolean enabled)

        mHandler.sendEmptyMessage(enabled ? UsbDebuggingHandler.MESSAGE_ADB_ENABLED
                                          : UsbDebuggingHandler.MESSAGE_ADB_DISABLED);
    
private voidstartConfirmation(java.lang.String key, java.lang.String fingerprints)

        String nameString = Resources.getSystem().getString(
                com.android.internal.R.string.config_customAdbPublicKeyConfirmationComponent);
        ComponentName componentName = ComponentName.unflattenFromString(nameString);
        if (startConfirmationActivity(componentName, key, fingerprints)
                || startConfirmationService(componentName, key, fingerprints)) {
            return;
        }
        Slog.e(TAG, "unable to start customAdbPublicKeyConfirmationComponent "
                + nameString + " as an Activity or a Service");
    
private booleanstartConfirmationActivity(android.content.ComponentName componentName, java.lang.String key, java.lang.String fingerprints)

returns
true if the componentName led to an Activity that was started.

        PackageManager packageManager = mContext.getPackageManager();
        Intent intent = createConfirmationIntent(componentName, key, fingerprints);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
            try {
                mContext.startActivity(intent);
                return true;
            } catch (ActivityNotFoundException e) {
                Slog.e(TAG, "unable to start adb whitelist activity: " + componentName, e);
            }
        }
        return false;
    
private booleanstartConfirmationService(android.content.ComponentName componentName, java.lang.String key, java.lang.String fingerprints)

returns
true if the componentName led to a Service that was started.

        Intent intent = createConfirmationIntent(componentName, key, fingerprints);
        try {
            if (mContext.startService(intent) != null) {
                return true;
            }
        } catch (SecurityException e) {
            Slog.e(TAG, "unable to start adb whitelist service: " + componentName, e);
        }
        return false;
    
private voidwriteKey(java.lang.String key)

        try {
            File keyFile = getUserKeyFile();

            if (keyFile == null) {
                return;
            }

            if (!keyFile.exists()) {
                keyFile.createNewFile();
                FileUtils.setPermissions(keyFile.toString(),
                    FileUtils.S_IRUSR | FileUtils.S_IWUSR |
                    FileUtils.S_IRGRP, -1, -1);
            }

            FileOutputStream fo = new FileOutputStream(keyFile, true);
            fo.write(key.getBytes());
            fo.write('\n");
            fo.close();
        }
        catch (IOException ex) {
            Slog.e(TAG, "Error writing key:" + ex);
        }