80,356
社区成员
发帖
与我相关
我的任务
分享
frameworks\base\packages\SystemUI\src\com\android\systemui\usb\UsbDebuggingActivity
import com.android.internal.app.AlertActivity;
import com.android.internal.app.AlertController;
import com.android.systemui.R;
public class UsbDebuggingActivity extends AlertActivity
implements DialogInterface.OnClickListener {
private static final String TAG = "UsbDebuggingActivity";
private CheckBox mAlwaysAllow;
private UsbDisconnectedReceiver mDisconnectedReceiver;
private String mKey;
@Override
public 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" checkbox
LayoutInflater 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;
}
@Override
public 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();
}
}
}
@Override
public void onStart() {
super.onStart();
IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE);
registerReceiver(mDisconnectedReceiver, filter);
}
@Override
protected void onStop() {
if (mDisconnectedReceiver != null) {
unregisterReceiver(mDisconnectedReceiver);
}
super.onStop();
}
@Override
public 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();
}
}
\frameworks\base\services\java\com\android\server\usb\UsbDebuggingManager
\
public 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;
private final Context mContext;
private final Handler mHandler;
private Thread mThread;
private boolean mAdbEnabled = false;
private String mFingerprints;
private LocalSocket mSocket = null;
private OutputStream mOutputStream = null;
public UsbDebuggingManager(Context context) {
mHandler = new UsbDebuggingHandler(FgThread.get().getLooper());
mContext = context;
}
private void listenToSocket() throws IOException {
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) {
Slog.e(TAG, "got " + count + " reading");
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;
}
}
} catch (IOException ex) {
Slog.e(TAG, "Communication error: ", ex);
throw ex;
} finally {
closeSocket();
}
}
@Override
public void run() {
while (mAdbEnabled) {
try {
listenToSocket();
} catch (Exception e) {
/* Don't loop too fast if adbd dies, before init restarts it */
SystemClock.sleep(1000);
}
}
}
private void closeSocket() {
try {
if(mOutputStream!=null){
mOutputStream.close();
}
} catch (IOException e) {
Slog.e(TAG, "Failed closing output stream: " + e);
}
try {
if(mSocket!=null){
mSocket.close();
}
} catch (IOException ex) {
Slog.e(TAG, "Failed closing socket: " + ex);
}
}
private void sendResponse(String msg) {
if (mOutputStream != null) {
try {
mOutputStream.write(msg.getBytes());
}
catch (IOException ex) {
Slog.e(TAG, "Failed to write response:", ex);
}
}
}
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, TAG);
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);//---------------UsbDebuggingHandler.handleMessage:215
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);//-----------------------------showConfirmationDialog
} 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();
}
}
public void setAdbEnabled(boolean enabled) {
mHandler.sendEmptyMessage(enabled ? UsbDebuggingHandler.MESSAGE_ADB_ENABLED
: UsbDebuggingHandler.MESSAGE_ADB_DISABLED);
}
public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
Message msg = mHandler.obtainMessage(UsbDebuggingHandler.MESSAGE_ADB_ALLOW);
msg.arg1 = alwaysAllow ? 1 : 0;
msg.obj = publicKey;
mHandler.sendMessage(msg);
}
public void denyUsbDebugging() {
mHandler.sendEmptyMessage(UsbDebuggingHandler.MESSAGE_ADB_DENY);
}
public void clearUsbDebuggingKeys() {
mHandler.sendEmptyMessage(UsbDebuggingHandler.MESSAGE_ADB_CLEAR);
}
public void dump(FileDescriptor fd, 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);
}
}
}