Android MTP之服务端UsbService启动

UsbService是USB功能的服务端,它是在system_server进程中启动的.MTP属于USB的一个功能,UsbService自然也是MTP的服务端.

本文是基于Android 10源码分析的.

// frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer {
    private static final String USB_SERVICE_CLASS =
            "com.android.server.usb.UsbService$Lifecycle";

    private void startOtherServices() {
        if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_USB_HOST)
                || mPackageManager.hasSystemFeature(
                        PackageManager.FEATURE_USB_ACCESSORY)) {
            mSystemServiceManager.startService(USB_SERVICE_CLASS);
            traceEnd();
        }
    }
}

UsbService就是在UsbService$LifecycleonStart()方法中创建的

// frameworks/base/services/usb/java/com/android/server/usb/UsbService.java

public class UsbService extends IUsbManager.Stub {

    public static class Lifecycle extends SystemService {
        @Override
        public void onStart() {
            // 创建服务
            mUsbService = new UsbService(getContext());
            // 注册到ServiceManager中,以便其他进程可以访问
            publishBinderService(Context.USB_SERVICE, mUsbService);
        }
    }
}

在创建UsbService这个服务后,就会立即把它注册到ServiceManager中.

// frameworks/base/services/usb/java/com/android/server/usb/UsbService.java

public UsbService(Context context) {
    //...

    if (new File("/sys/class/android_usb").exists()) {
        mDeviceManager = new UsbDeviceManager(context, mAlsaManager, mSettingsManager);
    }

    // ...
}

在MTP模式下,Android设备是作为Device端,因此只需要关心UsbDeviceManager

// frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java

public UsbDeviceManager(Context context, UsbAlsaManager alsaManager,
        UsbSettingsManager settingsManager) {

    // 1. 根据设备是否支持hal层,来决定使用哪个Handler
    if (halNotPresent) {
        mHandler = new UsbHandlerLegacy(FgThread.get().getLooper(), mContext, this,
                    alsaManager, settingsManager);
    } else {
        mHandler = new UsbHandlerHal(FgThread.get().getLooper(), mContext, this,
                    alsaManager, settingsManager);
    }


    // 注册各种广播
    // ...

    // 2. 监听USB状态
    mUEventObserver = new UsbUEventObserver();
    mUEventObserver.startObserving(USB_STATE_MATCH);
    mUEventObserver.startObserving(USB_STATE_MATCH_SEC);
    mUEventObserver.startObserving(ACCESSORY_START_MATCH);
}

UsbDeviceManager在创建的时候做了两件事

  1. 创建一个UsbHandler类型的对象,之后所有的事情都交给了它来做.
  2. 监听usb状态改变,从而更新上层信息.

由于我的项目不支持hal层,因此UsbDeviceManager这里就是创建了UsbHandlerLegacy对象.

// frameworks/base/services/usb/java/com/android/server/usb/UsbDeviceManager.java

UsbHandlerLegacy(Looper looper, Context context, UsbDeviceManager deviceManager,
        UsbAlsaManager alsaManager, UsbSettingsManager settingsManager) {
    super(looper, context, deviceManager, alsaManager, settingsManager);
    try {
        // ...

        // 从节点中读取当前usb状态,立即更新一次状态
        String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
        updateState(state);
    } catch (Exception e) {
        Slog.e(TAG, "Error initializing UsbHandler", e);
    }
}

UsbHandlerLegacy创建的时候最主要的事情就是更新一次usb状态,其实就是向自己(也就是Handler)发送一个MSG_UPDATE_STATE消息.

public void handleMessage(Message msg) {
    switch (msg.what) {
        case MSG_UPDATE_STATE:
            mConnected = (msg.arg1 == 1);
            mConfigured = (msg.arg2 == 1);

            // 1.如果usb已经连接,更新通知
            updateUsbNotification(false);
            updateAdbNotification(false);

            // 2. 如果usb状态改变,就发送广播
            if (mBootCompleted) {
                updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions));
            }

            if (mBootCompleted) {
                // 3. usb断开连接,恢复默认
                if (!mConnected && !hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT)
                        && !hasMessages(MSG_FUNCTION_SWITCH_TIMEOUT)) {
                    if (!mScreenLocked
                            && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) {
                        setScreenUnlockedFunctions();
                    } else {
                        setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
                    }
                }
                // 这里是更新usb midi功能
                updateUsbFunctions();
                } else {
                    mPendingBootBroadcast = true;
                }
            break;
    }
}

更新usb状态的操作,对于mtp来说,主要包括三件事

  1. 如果usb已经连接,会更新两个通知,一个是关于usb,一个是关于adb.这就是userdebug版本连上pc后,会出现两个烦人的通知.
  2. 如果usb状态改变,例如从充电模式成功切换到mtp模式,就会发送一个usb状态改变的广播.

你可能感兴趣的:(Android,MTP)