USB模式设置流程

1.setting中改变USB状态

    在setting中关于改变USB状态的有两个重要的类:UsbSettings和UsbSettingsExts。UsbSettings实际上是一个PreferenceFragment,它负责展示界面;UsbSettingsExts负责保存USB状态的。

UsbSettings.java

 @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {

        // Don't allow any changes to take effect as the USB host will be disconnected, killing
        // the monkeys
        if (Utils.isMonkeyRunning()) {
            return true;
        }
        // If this user is disallowed from using USB, don't handle their attempts to change the
        // setting.
        UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
        if (um.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) {
            return true;
        }

        String function = mUsbExts.getFunction(preference);
        boolean makeDefault = mUsbExts.isMakeDefault(preference);
        mUsbManager.setCurrentFunction(function, makeDefault);//改变USB状态
        updateToggles(function);

        mUsbExts.setNeedUpdate(false);
        return true;
    }

UsbSettingsExts.java

    public String getFunction(Preference preference) {
        String function = FUNCTION_NONE;
        if (preference == mMtp && mMtp.isChecked()) {
            function = UsbManager.USB_FUNCTION_MTP;
        } else if (preference == mPtp && mPtp.isChecked()) {
            function = UsbManager.USB_FUNCTION_PTP;
        } else if (preference == mUms && mUms.isChecked()) {
            function = UsbManager.USB_FUNCTION_MASS_STORAGE;
        } else if (preference == mCharge && mCharge.isChecked()) {
            function = UsbManager.USB_FUNCTION_CHARGING_ONLY;
        } else if (preference == mBicr && mBicr.isChecked()) {
            function = UsbManager.USB_FUNCTION_BICR;
        }
        return function;
    }

下面来看下USB的管理类UsbManager.java

    public void setCurrentFunction(String function, boolean makeDefault) {
        try {
            mService.setCurrentFunction(function, makeDefault);//调用usbservice,改变USB状态
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException in setCurrentFunction", e);
        }
    }

UsbService.java

    @Override
    public void setCurrentFunction(String function, boolean makeDefault) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);

        // If attempt to change USB function while file transfer is restricted, ensure that
        // the current function is set to "none", and return.
        UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
        if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) {
            if (mDeviceManager != null) mDeviceManager.setCurrentFunctions("none", false);
            return;
        }

        if (mDeviceManager != null) {
            mDeviceManager.setCurrentFunctions(function, makeDefault);
        } else {
            throw new IllegalStateException("USB device mode not supported");
        }
    }

UsbDeviceManager.java

    public void setCurrentFunctions(String functions, boolean makeDefault) {
        if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ") default: " + makeDefault);
        mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, makeDefault);
    }
case MSG_SET_CURRENT_FUNCTIONS:
                    String functions = (String)msg.obj;
                    boolean makeDefault = (msg.arg1 == 1);

                    mSettingUsbCharging = false;
                    mSettingUsbBicr = false;

                    /* In BICR evo, it's hard to confirm that the current disconnect is caused by switching usb function or unplugging usb cable*/
                    /* So add a flag to know it*/
                    mIsUserSwitch = true;

                    if (functions != null && functions.equals(UsbManager.USB_FUNCTION_CHARGING_ONLY)) {
                        mSettingUsbCharging = true;
                        mCurrentFunctions = removeFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_MTP);
                        mCurrentFunctions = removeFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_PTP);
                        updateUsbState();
                        Slog.d(TAG, "handleMessage - MSG_SET_CURRENT_FUNCTION - CHARGING_ONLY - makeDefault: " + makeDefault);
                    } else if (functions != null && functions.equals(UsbManager.USB_FUNCTION_BICR)) {
                        mSettingUsbBicr = true;
                        Slog.d(TAG, "handleMessage - MSG_SET_CURRENT_FUNCTION - BICR - makeDefault: " + makeDefault);
                    } else if (functions == null && mDefaultFunctions.equals(UsbManager.USB_FUNCTION_CHARGING_ONLY)) {
                        functions = mDefaultFunctions;
                        mSettingUsbCharging = true;
                        makeDefault = true;
                        updateUsbState();
                        Slog.d(TAG, "handleMessage - MSG_SET_CURRENT_FUNCTION - [Tethering Off] USB_FUNCTION_CHARGING_ONLY - makeDefault: " + makeDefault);
                    }

                    setEnabledFunctions(functions, makeDefault);

                    mIsUserSwitch = false;
                    //ALPS00428998
                    if(mMtpAskDisconnect) mMtpAskDisconnect = false;
                    //ALPS00428998

                    Slog.d(TAG, "handleMessage - MSG_SET_CURRENT_FUNCTION - functions: " + functions);
                    break;
 private void setEnabledFunctions(String functions, boolean makeDefault) {
            if (DEBUG) {
                Slog.d(TAG, "setEnabledFunctions - functions: " + functions);
                Slog.d(TAG, "setEnabledFunctions - mDefaultFunctions: " + mDefaultFunctions);
                Slog.d(TAG, "setEnabledFunctions - mCurrentFunctions: " + mCurrentFunctions);
                Slog.d(TAG, "setEnabledFunctions - mSettingFunction: " + mSettingFunction);
            }

            if (mCurrentFunctions.equals(UsbManager.USB_FUNCTION_CHARGING_ONLY)) {
                Slog.d(TAG, "setEnabledFunctions - [Disable USB Charging]");
                SystemProperties.set("sys.usb.charging","no");
            }

            if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_BICR)) {
                if (mIsUsbBicrEvo) {
                    Slog.w(TAG, "====mIsPcKnowMe:" + mIsPcKnowMe + ", mIsBicrSet:" + mIsBicrSet + ", mHwDisconnected:" + mHwDisconnected);
                    if (mIsBicrSet && mHwDisconnected) {
                        Slog.d(TAG, "Do not set sys.usb.bicr=no again!!!");
                    } else {
                        Slog.d(TAG, "setEnabledFunctions1 - [Disable USB BICR]");
                        SystemProperties.set("sys.usb.bicr","no");//设置为光驱
                    }
                } else {
                    Slog.d(TAG, "setEnabledFunctions2 - [Disable USB BICR]");
                    SystemProperties.set("sys.usb.bicr","no");
                }
            }

            if (mIsUsbBicrEvo && functions != null) {
                if( containsFunction(functions, UsbManager.USB_FUNCTION_RNDIS) || containsFunction(functions, UsbManager.USB_FUNCTION_EEM) ) {
                    mDefaultFunctions = mSettingFunction;
                }
            }
            // Do not update persystent.sys.usb.config if the device is booted up
            // with OEM specific mode.
            if (functions != null && makeDefault && !needsOemUsbOverride() && !mIsUsbBicrEvo) {
                if(bEvdoDtViaSupport == true) {
                    //VIA-START VIA USB
                    if(Settings.Secure.getInt(mContentResolver,
                        Settings.Secure.ADB_ENABLED, 0) > 0){
                        mAdbEnabled = true;
                        updateAdbNotification();
                    }
                    //VIA-END VIA USB
                }

                mSettingFunction = functions;
                if (mAdbEnabled && !mSettingUsbCharging) {
                    functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);
                } else {
                    functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
                }

                String acm_idx = SystemProperties.get("sys.usb.acm_idx", "");
                Slog.d(TAG, "sys.usb.acm_idx=" + acm_idx + ",mAcmPortIdx=" + mAcmPortIdx);
                if ((mAcmEnabled || ((acm_idx!=null) && !acm_idx.isEmpty()) ||
                                  ((mAcmPortIdx!=null) && !mAcmPortIdx.isEmpty())) &&
                                  !mSettingUsbCharging && !mSettingUsbBicr) {
                    int port_num = 0;
                    String port_str = "";
                    if(!acm_idx.isEmpty()) {
                        port_num = validPortNum(acm_idx);
                        if(port_num > 0 ) {
                            port_str = acm_idx;
                            mAcmPortIdx = acm_idx;
                        }
                    } else if(!mAcmPortIdx.isEmpty()) {
                        port_num = validPortNum(mAcmPortIdx);
                        if(port_num > 0 )
                            port_str = mAcmPortIdx;
                    }

                    Slog.d(TAG, "port_num=" + port_num);
                    if (port_num > 0) {
                        Slog.d(TAG, "Write port_str=" + port_str);
                        writeFile(ACM_PORT_INDEX_PATH, port_str);
                    }

                    /*Add ACM or Dual ACM at the tail. Even with ADB.*/
                    functions = removeFunction(functions, UsbManager.USB_FUNCTION_ACM);
                    functions = removeFunction(functions, UsbManager.USB_FUNCTION_DUAL_ACM);

                    String tmp = ( (port_num == 2) ? UsbManager.USB_FUNCTION_DUAL_ACM : UsbManager.USB_FUNCTION_ACM);
                    functions = addFunction(functions, tmp);

                    //Slog.d(TAG, "set persist.sys.port_index=" + port_str);
                    /*Keep the port info. We need it when reboot.*/
                    //SystemProperties.set("persist.sys.port_index", port_str);

                } else {
                    functions = removeFunction(functions, UsbManager.USB_FUNCTION_ACM);
                    functions = removeFunction(functions, UsbManager.USB_FUNCTION_DUAL_ACM);

                    SystemProperties.set("persist.sys.port_index", "");
                }
                Slog.d(TAG, "setEnabledFunctions - functions: " + functions);
                if (!mDefaultFunctions.equals(functions) || containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_BICR) || containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_RNDIS)) {
                    if (!setUsbConfig("none")) {
                        Slog.e(TAG, "Failed to disable USB");
                        // revert to previous configuration if we fail
                        setUsbConfig(mCurrentFunctions);
                        return;
                    }
                    // setting this property will also change the current USB state
                    // via a property trigger
                    SystemProperties.set("persist.sys.usb.config", functions);

                    if (mSettingFunction.equals(UsbManager.USB_FUNCTION_CHARGING_ONLY)) {
                        if (mAdbEnabled) {
                            SystemProperties.set("persist.service.adb.enable", "1");
                        } else {
                            SystemProperties.set("persist.service.adb.enable", "0");
                        }
                    } else {
                        SystemProperties.set("persist.service.adb.enable", "");
                    }

                    if (waitForState(functions)) {
                        mCurrentFunctions = functions;
                        mDefaultFunctions = functions;
                    } else {
                        Slog.e(TAG, "Failed to switch persistent USB config to " + functions);
                        // revert to previous configuration if we fail
                        SystemProperties.set("persist.sys.usb.config", mDefaultFunctions);
                    }
                } else {
                    //VIA-START VIA USB
                    if(bEvdoDtViaSupport == true) {
                        if(mDefaultFunctions.equals(functions) &&
                        (mCurrentFunctions.contains(UsbManager.USB_FUNCTION_VIA_CDROM)
                        ||mCurrentFunctions.contains(Bypass.USB_FUNCTION_BYPASS))){
                            Slog.i(TAG, "reset DefaultFunctions!");
                            if (!setUsbConfig("none")) {
                                Slog.e(TAG, "Failed to disable USB");
                                // revert to previous configuration if we fail
                                setUsbConfig(mCurrentFunctions);
                                return;
                            }
                            if (setUsbConfig(functions)) {
                                mCurrentFunctions = functions;
                            } else {
                                Slog.e(TAG, "Failed to switch USB config to " + functions);
                                // revert to previous configuration if we fail
                                setUsbConfig(mCurrentFunctions);
                            }
                        }
                    }
                    //VIA-END VIA USB
                }
            } else {
                if (functions == null) {
                    functions = mDefaultFunctions;
                    if(bEvdoDtViaSupport == true){
                        mUsbSetBypassWithTether=false ;
                    }
                }
                //VIA-START VIA USB
                if(bEvdoDtViaSupport == true) {
                    //adb can't be open with bypass and via cdrom
                    if(Settings.Secure.getInt(mContentResolver,
                        Settings.Secure.ADB_ENABLED, 0) > 0){
                        mAdbEnabled = true;
                        updateAdbNotification();
                    }
                }
                //VIA-END VIA USB
                // Override with bootmode specific usb mode if needed
                functions = processOemUsbOverride(functions);
                mSettingFunction = functions;

                if(bEvdoDtViaSupport == true){
                    if ((containsFunction(functions, UsbManager.USB_FUNCTION_RNDIS) || containsFunction(functions, UsbManager.USB_FUNCTION_EEM)) && mUsbSetBypassWithTether){					
                        functions = addFunction(functions, Bypass.USB_FUNCTION_BYPASS);
                        Slog.d(TAG, "add the bypass functions to tethering : " + functions);
                    }
                }

                if (mIsUsbBicrEvo && !mIsPcKnowMe && !mSettingUsbCharging) {
                    functions = UsbManager.USB_FUNCTION_BICR;
                    mSettingFunction = functions;
                }

                if (mAdbEnabled && !mSettingUsbCharging) {
                    functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);
                } else {
                    functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
                }

                String acm_idx = SystemProperties.get("sys.usb.acm_idx", "");
                Slog.d(TAG, "sys.usb.acm_idx=" + acm_idx);
                if ((mAcmEnabled || ((acm_idx!=null) && !acm_idx.isEmpty()) ||
                                  ((mAcmPortIdx!=null) && !mAcmPortIdx.isEmpty())) &&
                                  !mSettingUsbCharging && !mSettingUsbBicr) {
                    int port_num = 0;
                    String port_str = "";
                    if(!acm_idx.isEmpty()) {
                        port_num = validPortNum(acm_idx);
                        if(port_num > 0 ) {
                            port_str = acm_idx;
                            mAcmPortIdx = acm_idx;
                        }

                    } else if(!mAcmPortIdx.isEmpty()) {
                        port_num = validPortNum(mAcmPortIdx);
                        if(port_num > 0 )
                            port_str = mAcmPortIdx;
                    }

                    Slog.d(TAG, "port_num=" + port_num);
                    if (port_num > 0) {
                        Slog.d(TAG, "Write port_str=" + port_str);
                        writeFile(ACM_PORT_INDEX_PATH, port_str);
                    }

                    /*Add ACM or Dual ACM at the tail. Even with ADB.*/
                    functions = removeFunction(functions, UsbManager.USB_FUNCTION_ACM);
                    functions = removeFunction(functions, UsbManager.USB_FUNCTION_DUAL_ACM);

                    String tmp = ( (port_num == 2) ? UsbManager.USB_FUNCTION_DUAL_ACM : UsbManager.USB_FUNCTION_ACM);
                    functions = addFunction(functions, tmp);
                } else {
                    functions = removeFunction(functions, UsbManager.USB_FUNCTION_ACM);
                    functions = removeFunction(functions, UsbManager.USB_FUNCTION_DUAL_ACM);
                }

                Slog.d(TAG, "else setEnabledFunctions, functions: " + functions + ", mCurrentFunctions: " + mCurrentFunctions);
                if (!mCurrentFunctions.equals(functions) || containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_BICR) || (mIsUsbBicrEvo && !mIsPcKnowMe) || mMtpAskDisconnect) {
                    if (mIsUsbBicrEvo) {
                        Slog.w(TAG, "====mIsPcKnowMe:" + mIsPcKnowMe + ", mIsBicrSet:" + mIsBicrSet + ", mHwDisconnected:" + mHwDisconnected);
                        if (mIsBicrSet && !mIsPcKnowMe && mHwDisconnected && mCurrentFunctions.equals(functions) && containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_BICR)) {
                            Slog.e(TAG, "Do not do setUsbConfig() again!!!");
                            return;
                        } else {
                            mIsBicrSet = true;
                        }
                    }
                    if (!setUsbConfig("none")) {
                        Slog.e(TAG, "Failed to disable USB");
                        // revert to previous configuration if we fail
                        setUsbConfig(mCurrentFunctions);
                        return;
                    }
                    if (setUsbConfig(functions)) {
                        mCurrentFunctions = functions;
                    } else {
                        Slog.e(TAG, "Failed to switch USB config to " + functions);
                        // revert to previous configuration if we fail
                        setUsbConfig(mCurrentFunctions);
                    }
                }
            }
			
			/* reset this value after trigger setconfig, i.e. one time JOB */	
			if(bEvdoDtViaSupport == true){
				mUsbSetBypassWithTether=false ;
			}
        }

下面我们来看下init.usb.rc

on property:sys.usb.config=none
    stop adbd
    write /sys/class/android_usb/android0/enable 0
    write /sys/class/android_usb/android0/bDeviceClass 0
    setprop sys.usb.state ${sys.usb.config}

# adb only USB configuration
# This is the fallback configuration if the
# USB manager fails to set a standard configuration
on property:sys.usb.config=adb
    write /sys/class/android_usb/android0/enable 0
    write /sys/class/android_usb/android0/idVendor 18d1
    write /sys/class/android_usb/android0/idProduct 4EE7
    write /sys/class/android_usb/android0/functions ${sys.usb.config}
    write /sys/class/android_usb/android0/enable 1
    start adbd
    setprop sys.usb.state ${sys.usb.config}

# USB accessory configuration
on property:sys.usb.config=accessory
    write /sys/class/android_usb/android0/enable 0
    write /sys/class/android_usb/android0/idVendor 18d1
    write /sys/class/android_usb/android0/idProduct 2d00
    write /sys/class/android_usb/android0/functions ${sys.usb.config}
    write /sys/class/android_usb/android0/enable 1
    setprop sys.usb.state ${sys.usb.config}

# USB accessory configuration, with adb
on property:sys.usb.config=accessory,adb
    write /sys/class/android_usb/android0/enable 0
    write /sys/class/android_usb/android0/idVendor 18d1
    write /sys/class/android_usb/android0/idProduct 2d01
    write /sys/class/android_usb/android0/functions ${sys.usb.config}
    write /sys/class/android_usb/android0/enable 1
    start adbd
    setprop sys.usb.state ${sys.usb.config}

# audio accessory configuration
on property:sys.usb.config=audio_source
    write /sys/class/android_usb/android0/enable 0
    write /sys/class/android_usb/android0/idVendor 18d1
    write /sys/class/android_usb/android0/idProduct 2d02
    write /sys/class/android_usb/android0/functions ${sys.usb.config}
    write /sys/class/android_usb/android0/enable 1
    setprop sys.usb.state ${sys.usb.config}

# audio accessory configuration, with adb
on property:sys.usb.config=audio_source,adb
    write /sys/class/android_usb/android0/enable 0
    write /sys/class/android_usb/android0/idVendor 18d1
    write /sys/class/android_usb/android0/idProduct 2d03
    write /sys/class/android_usb/android0/functions ${sys.usb.config}
    write /sys/class/android_usb/android0/enable 1
    start adbd
    setprop sys.usb.state ${sys.usb.config}

# USB and audio accessory configuration
on property:sys.usb.config=accessory,audio_source
    write /sys/class/android_usb/android0/enable 0
    write /sys/class/android_usb/android0/idVendor 18d1
    write /sys/class/android_usb/android0/idProduct 2d04
    write /sys/class/android_usb/android0/functions ${sys.usb.config}
    write /sys/class/android_usb/android0/enable 1
    setprop sys.usb.state ${sys.usb.config}

# USB and audio accessory configuration, with adb
on property:sys.usb.config=accessory,audio_source,adb
    write /sys/class/android_usb/android0/enable 0
    write /sys/class/android_usb/android0/idVendor 18d1
    write /sys/class/android_usb/android0/idProduct 2d05
    write /sys/class/android_usb/android0/functions ${sys.usb.config}
    write /sys/class/android_usb/android0/enable 1
    start adbd
    setprop sys.usb.state ${sys.usb.config}

# Used to set USB configuration at boot and to switch the configuration
# when changing the default configuration
on property:persist.sys.usb.config=*
    setprop sys.usb.config ${persist.sys.usb.config}

从上面可以看出,设置persist.sys.usb.config后sys.usb,config跟着改变,然后向节点写入数据改变状态




你可能感兴趣的:(USB模式设置流程)