文章出处:http://blog.csdn.net/shift_wwx

请转载的朋友标明出处~~


最近,在新搭建的系统上用adb,发现adb shell不能用。

出现offline 和 authorized的现象:


借这个机会,我这里总结一下出现这种现象,可能存在的原因:

1. 客户端是否有adb

PC端是否存在adb,这个我们很容易检查出来的,在命令行输入adb,就会提示一些adb相关的命令,如果没有,那。。。我不想说什么了

2. server端是否有adb

android系统一般都会有adb的,同样的方式,在终端输入adb,是否有相关命令出现

3. server端adbd是否打开了

adbd是中间的最关键的东西,这就是传说中adb的守护进程,这个service都没有打开,那完全没得玩,stop adbd,start adbd,然后重新连接试试看

4. 确定一下两边adb的版本是否相同

用adb version命令试试看,如果不一样,更新一下sdk吧

5. 如果是通过网络连接

service.adb.tcp.port是否设置了,一般设置为5555

6. 平台上将USB debugging打开

平台上有个“设置”的应用,点击打开,然后在最下面位置的development选项中

7. 需要检查一下adb相关的prop

ro.debuggable=1

persist.service.adb.enable=1

persist.sys.usb.config=adb

ro.adb.secure=1


在android 4.0 之后,因为adb 的控制,统一使用了persist.sys.usb.config 来控制,于是对应的设置点也改到了

frameworks/base/service/...../usb/UsbDeviceManager.java 中,您也可以看到类似的代码如:

 public UsbHandler(Looper looper) {
            super(looper);
            try {
                // persist.sys.usb.config should never be unset.  But if it is, set it to "adb"
                // so we have a chance of debugging what happened.
                mDefaultFunctions = SystemProperties.get("persist.sys.usb.config", "adb");

                // Check if USB mode needs to be overridden depending on OEM specific bootmode.
                mDefaultFunctions = processOemUsbOverride(mDefaultFunctions);

                // sanity check the sys.usb.config system property
                // this may be necessary if we crashed while switching USB configurations
                String config = SystemProperties.get("sys.usb.config", "none");
                if (!config.equals(mDefaultFunctions)) {
                    Slog.w(TAG, "resetting config to persistent property: " + mDefaultFunctions);
                    SystemProperties.set("sys.usb.config", mDefaultFunctions);
                }

                mCurrentFunctions = mDefaultFunctions;
                if(new File(STATE_PATH).exists()){
                    String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
                    updateState(state);
                }
                mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB);

mAdbEnabled就是最终的关键变量。

而prop persist.sys.usb.config是在alps/build/tools/post_process_props.py中配置的。如下:

  if prop.get("ro.debuggable") == "1":
    val = prop.get("persist.sys.usb.config")
    if val == "":
      val = "adb"
    else:
      val = val + ",adb"

而prop ro.debuggable是在build/core/main.mk中配置的。如下:

ifeq (true,$(strip $(enable_target_debugging)))
  # Target is more debuggable and adbd is on by default
  ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=1
  # Include the debugging/testing OTA keys in this build.
  INCLUDE_TEST_OTA_KEYS := true
else # !enable_target_debugging
  # Target is less debuggable and adbd is off by default
  ADDITIONAL_DEFAULT_PROPERTIES += ro.debuggable=0
endif # !enable_target_debugging

接下来分析一下ro.adb.secure=1,会影响到网络adb的connect关键因素,在UsbDeviceManager.java的构造函数中:

    public UsbDeviceManager(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);
        }
    }
值为1的时候会创建对象mDebuggingManager,而这个对象实际上是控制adb应用的关键!

        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;

收到adb_enable的时候,会新建一个thread,并start了thread。

    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);
            }
        }
    }

而这个thread的目的是listenToSocket:

    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();
        }
    }

这样就可以监听adb了。

ro.adb.secure是必定要设置的,而且cts也是会去检查这一项的,当然,cts是需要adb连接的,没这个prop,是没的玩!


如果正常的话,会出现:


ok的话,offline或者authorized就会变成device了。


其他的adb应用可以看一下《adb命令大全





更多推荐