14e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby/* 24e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * Copyright (C) 2012 The Android Open Source Project 34e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * 44e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * Licensed under the Apache License, Version 2.0 (the "License"); 54e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * you may not use this file except in compliance with the License. 64e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * You may obtain a copy of the License at 74e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * 84e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * http://www.apache.org/licenses/LICENSE-2.0 94e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * 104e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * Unless required by applicable law or agreed to in writing, software 114e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * distributed under the License is distributed on an "AS IS" BASIS, 124e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * See the License for the specific language governing permissions an 144e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby * limitations under the License. 154e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby */ 164e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 174e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobypackage com.android.server.usb; 184e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 19ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chenimport android.app.ActivityManager; 204e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport android.content.ActivityNotFoundException; 21f10d0399bf5f519dff414a9d195a0eaacb37f9b7Aaron Whyteimport android.content.ComponentName; 224e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport android.content.Context; 234e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport android.content.Intent; 24d1931ffc075f73d043616b7446f14a653609782eAaron Whyteimport android.content.pm.PackageManager; 2505d58afddb1bbfa893354c1cb331bd69c9d2cb6fXiaohui Chenimport android.content.pm.UserInfo; 26f10d0399bf5f519dff414a9d195a0eaacb37f9b7Aaron Whyteimport android.content.res.Resources; 274e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport android.net.LocalSocket; 284e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport android.net.LocalSocketAddress; 294e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport android.os.Environment; 304e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport android.os.FileUtils; 31ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chenimport android.os.Handler; 324e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport android.os.Looper; 334e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport android.os.Message; 344e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport android.os.SystemClock; 35b43d3cff67b831db3b7e9fb834de66e4f9d2bc16Craig Mautnerimport android.os.SystemProperties; 36b43d3cff67b831db3b7e9fb834de66e4f9d2bc16Craig Mautnerimport android.os.UserHandle; 37ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chenimport android.os.UserManager; 384e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport android.util.Base64; 39ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chenimport android.util.Slog; 40f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani 41ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chenimport com.android.internal.R; 422dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brownimport com.android.internal.util.IndentingPrintWriter; 438d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackbornimport com.android.server.FgThread; 444e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 454e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport java.io.File; 464e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport java.io.FileDescriptor; 474e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport java.io.FileOutputStream; 484e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport java.io.IOException; 494e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport java.io.InputStream; 504e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport java.io.OutputStream; 514e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport java.io.PrintWriter; 524e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport java.security.MessageDigest; 534e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Gobyimport java.util.Arrays; 544e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 55f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasanipublic class UsbDebuggingManager { 564e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private static final String TAG = "UsbDebuggingManager"; 574e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private static final boolean DEBUG = false; 584e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 594e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private final String ADBD_SOCKET = "adbd"; 604e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private final String ADB_DIRECTORY = "misc/adb"; 614e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private final String ADB_KEYS_FILE = "adb_keys"; 624e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private final int BUFFER_SIZE = 4096; 634e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 644e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private final Context mContext; 654e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private final Handler mHandler; 66f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani private UsbDebuggingThread mThread; 674e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private boolean mAdbEnabled = false; 684e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private String mFingerprints; 694e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 704e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby public UsbDebuggingManager(Context context) { 718d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mHandler = new UsbDebuggingHandler(FgThread.get().getLooper()); 724e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mContext = context; 734e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 744e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 75f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani class UsbDebuggingThread extends Thread { 76f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani private boolean mStopped; 77f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani private LocalSocket mSocket; 78f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani private OutputStream mOutputStream; 79f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani private InputStream mInputStream; 804e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 81f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani UsbDebuggingThread() { 82f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani super(TAG); 83f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 844e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 85f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani @Override 86f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani public void run() { 87f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (DEBUG) Slog.d(TAG, "Entering thread"); 884e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby while (true) { 89f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani synchronized (this) { 90f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (mStopped) { 91f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (DEBUG) Slog.d(TAG, "Exiting thread"); 92f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani return; 93f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 94f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani try { 95f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani openSocketLocked(); 96f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } catch (Exception e) { 97f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani /* Don't loop too fast if adbd dies, before init restarts it */ 98f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani SystemClock.sleep(1000); 99f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 1004e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 101f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani try { 102f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani listenToSocket(); 103f4a8df4c7ee8d6a402e26339514cd73aba613105Amith Yamasani } catch (Exception e) { 104f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani /* Don't loop too fast if adbd dies, before init restarts it */ 105f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani SystemClock.sleep(1000); 1064e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 1074e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 1084e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 1094e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 110f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani private void openSocketLocked() throws IOException { 1114e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby try { 112f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani LocalSocketAddress address = new LocalSocketAddress(ADBD_SOCKET, 113f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani LocalSocketAddress.Namespace.RESERVED); 114f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mInputStream = null; 115f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani 116f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (DEBUG) Slog.d(TAG, "Creating socket"); 117f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mSocket = new LocalSocket(); 118f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mSocket.connect(address); 119f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani 120f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mOutputStream = mSocket.getOutputStream(); 121f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mInputStream = mSocket.getInputStream(); 122f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } catch (IOException ioe) { 123f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani closeSocketLocked(); 124f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani throw ioe; 1254e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 1264e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 1274e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 128f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani private void listenToSocket() throws IOException { 129f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani try { 130f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani byte[] buffer = new byte[BUFFER_SIZE]; 131f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani while (true) { 132f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani int count = mInputStream.read(buffer); 133f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (count < 0) { 134f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani break; 135f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 1364e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 137f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (buffer[0] == 'P' && buffer[1] == 'K') { 138f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani String key = new String(Arrays.copyOfRange(buffer, 2, count)); 139f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani Slog.d(TAG, "Received public key: " + key); 140f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani Message msg = mHandler.obtainMessage(UsbDebuggingHandler.MESSAGE_ADB_CONFIRM); 141f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani msg.obj = key; 142f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mHandler.sendMessage(msg); 143f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } else { 144f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani Slog.e(TAG, "Wrong message: " 145f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani + (new String(Arrays.copyOfRange(buffer, 0, 2)))); 146f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani break; 147f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 148f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 149f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } finally { 150f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani synchronized (this) { 151f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani closeSocketLocked(); 152f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 153f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 1544e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 1554e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 156f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani private void closeSocketLocked() { 157f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (DEBUG) Slog.d(TAG, "Closing socket"); 158f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani try { 159f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (mOutputStream != null) { 160f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mOutputStream.close(); 161f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mOutputStream = null; 162f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 163f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } catch (IOException e) { 164f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani Slog.e(TAG, "Failed closing output stream: " + e); 165f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 166f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani 1674e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby try { 168f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (mSocket != null) { 169f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mSocket.close(); 170f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mSocket = null; 171f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 172f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } catch (IOException ex) { 173f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani Slog.e(TAG, "Failed closing socket: " + ex); 1744e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 175f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 176f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani 177f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani /** Call to stop listening on the socket and exit the thread. */ 178f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani void stopListening() { 179f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani synchronized (this) { 180f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mStopped = true; 181f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani closeSocketLocked(); 182f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 183f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 184f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani 185f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani void sendResponse(String msg) { 186f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani synchronized (this) { 187f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (!mStopped && mOutputStream != null) { 188f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani try { 189f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mOutputStream.write(msg.getBytes()); 190f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 191f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani catch (IOException ex) { 192f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani Slog.e(TAG, "Failed to write response:", ex); 193f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 194f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 1954e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 1964e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 1974e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 1984e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 1994e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby class UsbDebuggingHandler extends Handler { 2004e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private static final int MESSAGE_ADB_ENABLED = 1; 2014e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private static final int MESSAGE_ADB_DISABLED = 2; 2024e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private static final int MESSAGE_ADB_ALLOW = 3; 2034e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private static final int MESSAGE_ADB_DENY = 4; 2044e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private static final int MESSAGE_ADB_CONFIRM = 5; 205cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby private static final int MESSAGE_ADB_CLEAR = 6; 2064e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 2074e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby public UsbDebuggingHandler(Looper looper) { 2084e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby super(looper); 2094e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 2104e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 2114e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby public void handleMessage(Message msg) { 2124e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby switch (msg.what) { 2134e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby case MESSAGE_ADB_ENABLED: 2144e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (mAdbEnabled) 2154e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby break; 2164e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 2174e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mAdbEnabled = true; 2184e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 219f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mThread = new UsbDebuggingThread(); 2204e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mThread.start(); 2214e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 2224e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby break; 2234e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 2244e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby case MESSAGE_ADB_DISABLED: 2254e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (!mAdbEnabled) 2264e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby break; 2274e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 2284e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mAdbEnabled = false; 2294e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 230f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (mThread != null) { 231f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mThread.stopListening(); 232f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mThread = null; 2334e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 2344e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 23537ce5c5d5e8216f02230aeb89b147c0395e18329Benoit Goby break; 2364e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 2374e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby case MESSAGE_ADB_ALLOW: { 2384e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby String key = (String)msg.obj; 2394e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby String fingerprints = getFingerprints(key); 2404e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 2414e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (!fingerprints.equals(mFingerprints)) { 2424e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby Slog.e(TAG, "Fingerprints do not match. Got " 2434e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby + fingerprints + ", expected " + mFingerprints); 2444e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby break; 2454e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 2464e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 2474e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (msg.arg1 == 1) { 2484e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby writeKey(key); 2494e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 2504e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 251f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (mThread != null) { 252f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mThread.sendResponse("OK"); 253f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 2544e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby break; 2554e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 2564e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 2574e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby case MESSAGE_ADB_DENY: 258f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (mThread != null) { 259f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mThread.sendResponse("NO"); 260f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 2614e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby break; 2624e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 2634e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby case MESSAGE_ADB_CONFIRM: { 264b43d3cff67b831db3b7e9fb834de66e4f9d2bc16Craig Mautner if ("trigger_restart_min_framework".equals( 265b43d3cff67b831db3b7e9fb834de66e4f9d2bc16Craig Mautner SystemProperties.get("vold.decrypt"))) { 266b43d3cff67b831db3b7e9fb834de66e4f9d2bc16Craig Mautner Slog.d(TAG, "Deferring adb confirmation until after vold decrypt"); 267f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (mThread != null) { 268f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mThread.sendResponse("NO"); 269f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 270b43d3cff67b831db3b7e9fb834de66e4f9d2bc16Craig Mautner break; 271b43d3cff67b831db3b7e9fb834de66e4f9d2bc16Craig Mautner } 2724e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby String key = (String)msg.obj; 273451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich String fingerprints = getFingerprints(key); 274451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich if ("".equals(fingerprints)) { 275f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani if (mThread != null) { 276f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani mThread.sendResponse("NO"); 277f6197e8fa25d7a411a08ca01f9af8f6278ef97d6Amith Yamasani } 278451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich break; 279451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich } 280451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich mFingerprints = fingerprints; 281d1931ffc075f73d043616b7446f14a653609782eAaron Whyte startConfirmation(key, mFingerprints); 2824e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby break; 2834e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 284cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby 285cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby case MESSAGE_ADB_CLEAR: 286cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby deleteKeyFile(); 287cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby break; 2884e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 2894e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 2904e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 2914e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 2924e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby private String getFingerprints(String key) { 2934e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby String hex = "0123456789ABCDEF"; 2944e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby StringBuilder sb = new StringBuilder(); 2954e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby MessageDigest digester; 2964e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 297451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich if (key == null) { 298451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich return ""; 299451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich } 300451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich 3014e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby try { 3024e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby digester = MessageDigest.getInstance("MD5"); 3034e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } catch (Exception ex) { 304451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich Slog.e(TAG, "Error getting digester", ex); 3054e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby return ""; 3064e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 3074e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 3084e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby byte[] base64_data = key.split("\\s+")[0].getBytes(); 309451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich byte[] digest; 310451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich try { 311451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich digest = digester.digest(Base64.decode(base64_data, Base64.DEFAULT)); 312451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich } catch (IllegalArgumentException e) { 313451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich Slog.e(TAG, "error doing base64 decoding", e); 314451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich return ""; 315451a6f8f9a5e629a94b3cb75eb2d8576caea5471Nick Kralevich } 3164e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby for (int i = 0; i < digest.length; i++) { 3174e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby sb.append(hex.charAt((digest[i] >> 4) & 0xf)); 3184e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby sb.append(hex.charAt(digest[i] & 0xf)); 3194e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (i < digest.length - 1) 3204e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby sb.append(":"); 3214e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 3224e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby return sb.toString(); 3234e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 3244e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 325d1931ffc075f73d043616b7446f14a653609782eAaron Whyte private void startConfirmation(String key, String fingerprints) { 326ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen int currentUserId = ActivityManager.getCurrentUser(); 32705d58afddb1bbfa893354c1cb331bd69c9d2cb6fXiaohui Chen UserInfo userInfo = UserManager.get(mContext).getUserInfo(currentUserId); 328ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen String componentString; 32905d58afddb1bbfa893354c1cb331bd69c9d2cb6fXiaohui Chen if (userInfo.isAdmin()) { 330ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen componentString = Resources.getSystem().getString( 331ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen com.android.internal.R.string.config_customAdbPublicKeyConfirmationComponent); 332ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen } else { 33305d58afddb1bbfa893354c1cb331bd69c9d2cb6fXiaohui Chen // If the current foreground user is not the admin user we send a different 334ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen // notification specific to secondary users. 335ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen componentString = Resources.getSystem().getString( 336ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen R.string.config_customAdbPublicKeyConfirmationSecondaryUserComponent); 337ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen } 338ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen ComponentName componentName = ComponentName.unflattenFromString(componentString); 33905d58afddb1bbfa893354c1cb331bd69c9d2cb6fXiaohui Chen if (startConfirmationActivity(componentName, userInfo.getUserHandle(), key, fingerprints) 34005d58afddb1bbfa893354c1cb331bd69c9d2cb6fXiaohui Chen || startConfirmationService(componentName, userInfo.getUserHandle(), 34105d58afddb1bbfa893354c1cb331bd69c9d2cb6fXiaohui Chen key, fingerprints)) { 342d1931ffc075f73d043616b7446f14a653609782eAaron Whyte return; 343d1931ffc075f73d043616b7446f14a653609782eAaron Whyte } 344ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen Slog.e(TAG, "unable to start customAdbPublicKeyConfirmation[SecondaryUser]Component " 345ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen + componentString + " as an Activity or a Service"); 346d1931ffc075f73d043616b7446f14a653609782eAaron Whyte } 347f10d0399bf5f519dff414a9d195a0eaacb37f9b7Aaron Whyte 348d1931ffc075f73d043616b7446f14a653609782eAaron Whyte /** 349d1931ffc075f73d043616b7446f14a653609782eAaron Whyte * @returns true if the componentName led to an Activity that was started. 350d1931ffc075f73d043616b7446f14a653609782eAaron Whyte */ 351ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen private boolean startConfirmationActivity(ComponentName componentName, UserHandle userHandle, 352ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen String key, String fingerprints) { 353d1931ffc075f73d043616b7446f14a653609782eAaron Whyte PackageManager packageManager = mContext.getPackageManager(); 354d1931ffc075f73d043616b7446f14a653609782eAaron Whyte Intent intent = createConfirmationIntent(componentName, key, fingerprints); 355f10d0399bf5f519dff414a9d195a0eaacb37f9b7Aaron Whyte intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 356d1931ffc075f73d043616b7446f14a653609782eAaron Whyte if (packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) { 357d1931ffc075f73d043616b7446f14a653609782eAaron Whyte try { 358ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen mContext.startActivityAsUser(intent, userHandle); 359d1931ffc075f73d043616b7446f14a653609782eAaron Whyte return true; 360d1931ffc075f73d043616b7446f14a653609782eAaron Whyte } catch (ActivityNotFoundException e) { 361d1931ffc075f73d043616b7446f14a653609782eAaron Whyte Slog.e(TAG, "unable to start adb whitelist activity: " + componentName, e); 362d1931ffc075f73d043616b7446f14a653609782eAaron Whyte } 363d1931ffc075f73d043616b7446f14a653609782eAaron Whyte } 364d1931ffc075f73d043616b7446f14a653609782eAaron Whyte return false; 365d1931ffc075f73d043616b7446f14a653609782eAaron Whyte } 366d1931ffc075f73d043616b7446f14a653609782eAaron Whyte 367d1931ffc075f73d043616b7446f14a653609782eAaron Whyte /** 368d1931ffc075f73d043616b7446f14a653609782eAaron Whyte * @returns true if the componentName led to a Service that was started. 369d1931ffc075f73d043616b7446f14a653609782eAaron Whyte */ 370ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen private boolean startConfirmationService(ComponentName componentName, UserHandle userHandle, 371ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen String key, String fingerprints) { 372d1931ffc075f73d043616b7446f14a653609782eAaron Whyte Intent intent = createConfirmationIntent(componentName, key, fingerprints); 3734e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby try { 374ffcfe3411ff6ccaa35c2873151e31c879506daddXiaohui Chen if (mContext.startServiceAsUser(intent, userHandle) != null) { 375d1931ffc075f73d043616b7446f14a653609782eAaron Whyte return true; 376d1931ffc075f73d043616b7446f14a653609782eAaron Whyte } 377d1931ffc075f73d043616b7446f14a653609782eAaron Whyte } catch (SecurityException e) { 378d1931ffc075f73d043616b7446f14a653609782eAaron Whyte Slog.e(TAG, "unable to start adb whitelist service: " + componentName, e); 3794e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 380d1931ffc075f73d043616b7446f14a653609782eAaron Whyte return false; 381d1931ffc075f73d043616b7446f14a653609782eAaron Whyte } 382d1931ffc075f73d043616b7446f14a653609782eAaron Whyte 383d1931ffc075f73d043616b7446f14a653609782eAaron Whyte private Intent createConfirmationIntent(ComponentName componentName, String key, 384d1931ffc075f73d043616b7446f14a653609782eAaron Whyte String fingerprints) { 385d1931ffc075f73d043616b7446f14a653609782eAaron Whyte Intent intent = new Intent(); 386d1931ffc075f73d043616b7446f14a653609782eAaron Whyte intent.setClassName(componentName.getPackageName(), componentName.getClassName()); 387d1931ffc075f73d043616b7446f14a653609782eAaron Whyte intent.putExtra("key", key); 388d1931ffc075f73d043616b7446f14a653609782eAaron Whyte intent.putExtra("fingerprints", fingerprints); 389d1931ffc075f73d043616b7446f14a653609782eAaron Whyte return intent; 3904e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 3914e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 392cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby private File getUserKeyFile() { 3934e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby File dataDir = Environment.getDataDirectory(); 3944e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby File adbDir = new File(dataDir, ADB_DIRECTORY); 3954e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 3964e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (!adbDir.exists()) { 3974e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby Slog.e(TAG, "ADB data directory does not exist"); 398cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby return null; 3994e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 4004e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 401cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby return new File(adbDir, ADB_KEYS_FILE); 402cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby } 403cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby 404cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby private void writeKey(String key) { 4054e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby try { 406cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby File keyFile = getUserKeyFile(); 407cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby 408cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby if (keyFile == null) { 409cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby return; 410cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby } 4114e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 4124e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby if (!keyFile.exists()) { 4134e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby keyFile.createNewFile(); 4144e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby FileUtils.setPermissions(keyFile.toString(), 4154e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby FileUtils.S_IRUSR | FileUtils.S_IWUSR | 4164e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby FileUtils.S_IRGRP, -1, -1); 4174e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 4184e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 4194e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby FileOutputStream fo = new FileOutputStream(keyFile, true); 4204e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby fo.write(key.getBytes()); 4214e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby fo.write('\n'); 4224e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby fo.close(); 4234e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 4244e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby catch (IOException ex) { 4254e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby Slog.e(TAG, "Error writing key:" + ex); 4264e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 4274e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 4284e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 429cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby private void deleteKeyFile() { 430cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby File keyFile = getUserKeyFile(); 431cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby if (keyFile != null) { 432cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby keyFile.delete(); 433cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby } 434cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby } 4354e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 4364e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby public void setAdbEnabled(boolean enabled) { 4374e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mHandler.sendEmptyMessage(enabled ? UsbDebuggingHandler.MESSAGE_ADB_ENABLED 4384e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby : UsbDebuggingHandler.MESSAGE_ADB_DISABLED); 4394e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 4404e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 4414e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby public void allowUsbDebugging(boolean alwaysAllow, String publicKey) { 4424e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby Message msg = mHandler.obtainMessage(UsbDebuggingHandler.MESSAGE_ADB_ALLOW); 4434e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby msg.arg1 = alwaysAllow ? 1 : 0; 4444e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby msg.obj = publicKey; 4454e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mHandler.sendMessage(msg); 4464e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 4474e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 4484e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby public void denyUsbDebugging() { 4494e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby mHandler.sendEmptyMessage(UsbDebuggingHandler.MESSAGE_ADB_DENY); 4504e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 4514e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 452cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby public void clearUsbDebuggingKeys() { 453cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby mHandler.sendEmptyMessage(UsbDebuggingHandler.MESSAGE_ADB_CLEAR); 454cd7a17c645761ac0b64c75346b159dd30cbcb01cBenoit Goby } 4554e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby 4562dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown public void dump(IndentingPrintWriter pw) { 4572dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown pw.println("USB Debugging State:"); 4582dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown pw.println(" Connected to adbd: " + (mThread != null)); 4592dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown pw.println(" Last key received: " + mFingerprints); 4602dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown pw.println(" User keys:"); 4614e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby try { 4624e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby pw.println(FileUtils.readTextFile(new File("/data/misc/adb/adb_keys"), 0, null)); 4634e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } catch (IOException e) { 4644e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby pw.println("IOException: " + e); 4654e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 4662dbccc1926ea2d3e27c5cfd2d61d2b3d5ed787c0Jeff Brown pw.println(" System keys:"); 4674e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby try { 4684e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby pw.println(FileUtils.readTextFile(new File("/adb_keys"), 0, null)); 4694e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } catch (IOException e) { 4704e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby pw.println("IOException: " + e); 4714e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 4724e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby } 4734e68bd420b6cfdbeadb5e69aa6448665b2da762bBenoit Goby} 474