Android 4.2.2 引入了USB安全调试方面的内容,当启用安全调试的时候,只有被用户认证过的主机才可以通过Android SDK自带的ADB工具经由USB连接来访问设备的内部构件。
下面以android-4.3_r3.1源码分析其实现:
首先打 usb调试界面在systemui中的UsbDebuggingActivity.java实现:


View Codepublic class UsbDebuggingActivity extends AlertActivityimplements DialogInterface.OnClickListener {private static final String TAG = "UsbDebuggingActivity";private CheckBox mAlwaysAllow;private UsbDisconnectedReceiver mDisconnectedReceiver;private String mKey;@Overridepublic void onCreate(Bundle icicle) {super.onCreate(icicle);if (SystemProperties.getInt("service.adb.tcp.port", 0) == 0) {mDisconnectedReceiver = new UsbDisconnectedReceiver(this);}Intent intent = getIntent();String fingerprints = intent.getStringExtra("fingerprints");mKey = intent.getStringExtra("key");if (fingerprints == null || mKey == null) {finish();return;}final AlertController.AlertParams ap = mAlertParams;ap.mTitle = getString(R.string.usb_debugging_title);ap.mIconId = com.android.internal.R.drawable.ic_dialog_usb;ap.mMessage = getString(R.string.usb_debugging_message, fingerprints);ap.mPositiveButtonText = getString(android.R.string.ok);ap.mNegativeButtonText = getString(android.R.string.cancel);ap.mPositiveButtonListener = this;ap.mNegativeButtonListener = this;// add "always allow" checkboxLayoutInflater inflater = LayoutInflater.from(ap.mContext);View checkbox = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);mAlwaysAllow = (CheckBox)checkbox.findViewById(com.android.internal.R.id.alwaysUse);mAlwaysAllow.setText(getString(R.string.usb_debugging_always));ap.mView = checkbox;setupAlert();}private class UsbDisconnectedReceiver extends BroadcastReceiver {private final Activity mActivity;public UsbDisconnectedReceiver(Activity activity) {mActivity = activity;}@Overridepublic void onReceive(Context content, Intent intent) {String action = intent.getAction();if (!UsbManager.ACTION_USB_STATE.equals(action)) {return;}boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);if (!connected) {mActivity.finish();}}}@Overridepublic void onStart() {super.onStart();IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE);registerReceiver(mDisconnectedReceiver, filter);}@Overrideprotected void onStop() {if (mDisconnectedReceiver != null) {unregisterReceiver(mDisconnectedReceiver);}super.onStop();}@Overridepublic void onClick(DialogInterface dialog, int which) {boolean allow = (which == AlertDialog.BUTTON_POSITIVE);boolean alwaysAllow = allow && mAlwaysAllow.isChecked();try {IBinder b = ServiceManager.getService(USB_SERVICE);IUsbManager service = IUsbManager.Stub.asInterface(b);if (allow) {service.allowUsbDebugging(alwaysAllow, mKey);} else {service.denyUsbDebugging();}} catch (Exception e) {Log.e(TAG, "Unable to notify Usb service", e);}finish();} }
其主要功能实现于UsbDebuggingManager.java中:


View Codepublic class UsbDebuggingManager implements Runnable {private static final String TAG = "UsbDebuggingManager";private static final boolean DEBUG = false;private final String ADBD_SOCKET = "adbd";private final String ADB_DIRECTORY = "misc/adb";private final String ADB_KEYS_FILE = "adb_keys";private final int BUFFER_SIZE = 4096; ... class UsbDebuggingHandler extends Handler {private static final int MESSAGE_ADB_ENABLED = 1;private static final int MESSAGE_ADB_DISABLED = 2;private static final int MESSAGE_ADB_ALLOW = 3;private static final int MESSAGE_ADB_DENY = 4;private static final int MESSAGE_ADB_CONFIRM = 5;private static final int MESSAGE_ADB_CLEAR = 6;public UsbDebuggingHandler(Looper looper) {super(looper);}public void handleMessage(Message msg) {switch (msg.what) {case MESSAGE_ADB_ENABLED:if (mAdbEnabled)break;mAdbEnabled = true;mThread = new Thread(UsbDebuggingManager.this);mThread.start();break;case MESSAGE_ADB_DISABLED:if (!mAdbEnabled)break;mAdbEnabled = false;closeSocket();try {mThread.join();} catch (Exception ex) {}mThread = null;mOutputStream = null;mSocket = null;break;case MESSAGE_ADB_ALLOW: {String key = (String)msg.obj;String fingerprints = getFingerprints(key);if (!fingerprints.equals(mFingerprints)) {Slog.e(TAG, "Fingerprints do not match. Got "+ fingerprints + ", expected " + mFingerprints);break;}if (msg.arg1 == 1) {writeKey(key);}sendResponse("OK");break;}case MESSAGE_ADB_DENY:sendResponse("NO");break;case MESSAGE_ADB_CONFIRM: {String key = (String)msg.obj;mFingerprints = getFingerprints(key);showConfirmationDialog(key, mFingerprints);break;}case MESSAGE_ADB_CLEAR:deleteKeyFile();break;}}}private String getFingerprints(String key) {String hex = "0123456789ABCDEF";StringBuilder sb = new StringBuilder();MessageDigest digester;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 = digester.digest(Base64.decode(base64_data, Base64.DEFAULT));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 void showConfirmationDialog(String key, String fingerprints) {Intent dialogIntent = new Intent();dialogIntent.setClassName("com.android.systemui","com.android.systemui.usb.UsbDebuggingActivity");dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);dialogIntent.putExtra("key", key);dialogIntent.putExtra("fingerprints", fingerprints);try {mContext.startActivity(dialogIntent);} catch (ActivityNotFoundException e) {Slog.e(TAG, "unable to start UsbDebuggingActivity");}}private File getUserKeyFile() {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 void writeKey(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);}}private void deleteKeyFile() {File keyFile = getUserKeyFile();if (keyFile != null) {keyFile.delete();}}
可见,若要删除特定连接Android设备的电脑只能删除Android设备中的文件:/data/misc/adb/adb_keys,或将Android设备强制刷机。