UsbHostManager是手机作为一个host,比如键盘、鼠标通过usb连接手机。而UsbDeviceManager是手机与电脑连接。
先看下UsbDevice的代码:就看构造函数和systemReady
public UsbService(Context context) { mContext = context; final PackageManager pm = mContext.getPackageManager(); if (pm.hasSystemFeature(PackageManager.FEATURE_USB_HOST)) { mHostManager = new UsbHostManager(context);//new UsbHostManager } if (new File("/sys/class/android_usb").exists()) { mDeviceManager = new UsbDeviceManager(context);//new UsbDeviceManager } setCurrentUser(UserHandle.USER_OWNER); final IntentFilter userFilter = new IntentFilter(); userFilter.addAction(Intent.ACTION_USER_SWITCHED); userFilter.addAction(Intent.ACTION_USER_STOPPED); mContext.registerReceiver(mUserReceiver, userFilter, null, null); }
public void systemReady() { if (mDeviceManager != null) { mDeviceManager.systemReady(); } if (mHostManager != null) { mHostManager.systemReady(); } }
今天主要介绍下UsbDeviceManager,先来看下构造函数:
public UsbDeviceManager(Context context) { Log.d(TAG,"UsbDeviceManager start , persist.sys.usb.config =" + SystemProperties.get("persist.sys.usb.config", "")); mContext = context; mContentResolver = context.getContentResolver(); mMassStorageEnable = SystemProperties.get("persist.mass_storage.enable", "true");//大容量属性 PackageManager pm = mContext.getPackageManager(); mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY); initRndisAddress();//初始化usb共享的地址,用手机序列码作为地址,序列码是存在系统属性中的 readOemUsbOverrideConfig();//读取厂家设置 mHandler = new UsbHandler(FgThread.get().getLooper());//构造UsbHandler,后面详细看 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); } }
接下来看UsbHandler这个内部类:
先看usbHandler构造函数的前半部分:
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. Log.d(TAG,"UsbHandler , persist.sys.usb.config :" + SystemProperties.get("persist.sys.usb.config")); if(SystemProperties.get("persist.sys.usb.config", "") == null || SystemProperties.get("persist.sys.usb.config", "") == "none"){//永久性属性里面没有就设置 if("false".equals(mMassStorageEnable)){ SystemProperties.set("persist.sys.usb.config", "mtp,adb"); }else{ SystemProperties.set("persist.sys.usb.config", "mtp,mass_storage,adb"); } } if("false".equals(mMassStorageEnable)){//有的话就直接将获取的属性放在mDefaultFunctions mDefaultFunctions = SystemProperties.get("persist.sys.usb.config", "mtp,adb"); }else{ mDefaultFunctions = SystemProperties.get("persist.sys.usb.config", "mtp,mass_storage,adb"); } Log.d(TAG,"mMassStorageEnable ="+ mMassStorageEnable +", mDefaultFunctions :" + mDefaultFunctions); // 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)) {//如果mDefaultFunctions与"sys.usb.config“属性不一样,就重新设置属性 Slog.w(TAG, "resetting config to persistent property: " + mDefaultFunctions); SystemProperties.set("sys.usb.config", mDefaultFunctions); }
上面理论上persist.sys.usb.config 与sys.usb.config属性一样的
因为在init.usb.rc中设置persist.sys.usb.config 属性,也会将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
继续分析usbHandler的构造函数
mCurrentFunctions = getDefaultFunctions(); String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); Log.d(TAG,"UsbHandler updateState state:" + state); mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB);//属性中如果有adb,就置位true updateState(state); Log.d(TAG," UsbHandler charging_value:" + SystemProperties.get("sys.usb.charging", "") + " ro.debuggable:" + SystemProperties.get("ro.debuggable", "")); if(SystemProperties.get("sys.usb.charging", "").equals("yes") && SystemProperties.get("ro.debuggable","").equals("1")){
下面再看看updateState函数,state从下面这个节点读取状态
private static final String STATE_PATH = "/sys/class/android_usb/android0/state"
updateState函数如下:
public void updateState(String state) { Log.d(TAG, "updateState : state = " + state ); int connected, configured; if ("DISCONNECTED".equals(state)) { connected = 0; configured = 0; SystemProperties.set("sys.lc.usb.state", "0"); } else if ("CONNECTED".equals(state)) { connected = 1; configured = 0; } else if ("CONFIGURED".equals(state)) { connected = 1; configured = 1; SystemProperties.set("sys.lc.usb.state", "1"); } else { Slog.e(TAG, "unknown state " + state); return; } removeMessages(MSG_UPDATE_STATE); Message msg = Message.obtain(this, MSG_UPDATE_STATE); msg.arg1 = connected; msg.arg2 = configured; // debounce disconnects to avoid problems bringing up USB tethering sendMessage(msg);//参数配置后发送消息
收到消息后处理
public void handleMessage(Message msg) { Log.d(TAG," handleMessage msg:" + msg + " msg.arg1:" + msg.arg1 + " msg.arg2 "+ msg.arg2); switch (msg.what) { case MSG_UPDATE_STATE: mConnected = (msg.arg1 == 1); mConfigured = (msg.arg2 == 1); updateUsbNotification(); updateAdbNotification(); if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ACCESSORY)) { updateCurrentAccessory(); } else if (!mConnected) {//usb断开连接后,属性设置成默认的 // restore defaults when USB is disconnected setEnabledFunctions(getDefaultFunctions(), false); } if (mBootCompleted) { updateUsbState();//发送广播 updateAudioSourceFunction(); } break;
继续分析
String value = SystemProperties.get("persist.service.adb.enable", ""); if (value.length() > 0) { char enable = value.charAt(0); if (enable == '1') { setAdbEnabled(true); } else if (enable == '0') { setAdbEnabled(false); } SystemProperties.set("persist.service.adb.enable", ""); }分析setAdbEnabled函数
private void setAdbEnabled(boolean enable) { if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable + " mCurrentFunctions:" + mCurrentFunctions); if (enable != mAdbEnabled) {//当mAdbEnabled改变时 mAdbEnabled = enable; // Due to the persist.sys.usb.config property trigger, changing adb state requires // persisting default function if(!mCurrentFunctions.equals(UsbManager.USB_FUNCTION_CHARGING)){ setEnabledFunctions(mDefaultFunctions, true);//先设置永久属性 // After persisting them use the lock-down aware function set setEnabledFunctions(getDefaultFunctions(), false);//再设置usb.config属性 updateAdbNotification(); } } if (mDebuggingManager != null) { mDebuggingManager.setAdbEnabled(mAdbEnabled); } }
再来看看setEnabledFunctions函数
private void setEnabledFunctions(String functions, boolean makeDefault) { if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions + " makeDefault: " + makeDefault); // Do not update persystent.sys.usb.config if the device is booted up // with OEM specific mode. if (functions != null && makeDefault && !needsOemUsbOverride()) {//设置永久属性 if (mAdbEnabled && !functions.equals(UsbManager.USB_FUNCTION_CHARGING)) { functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);//根据mAdbEnabled设置系统属性 } else { functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB); } if (!mDefaultFunctions.equals(functions)) {//当functions改变时 if (!setUsbConfig("none")) {//设置none,直接断开usb,也就是差不多每次设置不一样属性。都要先断开usb。稍后详细看看setUsbConfig这个函数 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 (waitForState(functions)) {//就是设置的属性,去读取属性是否和设置的一样 if(mCurrentFunctions.equals(UsbManager.USB_FUNCTION_CHARGING) && !mCurrentFunctions.equals(functions)){ if (DEBUG) Slog.d(TAG, " change charging functions to new functions: " + functions); SystemProperties.set("sys.usb.charging", "no"); } 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); } } }
非永久属性的,和永久属性的差不多。只是一个是设置永久属性。一个是设置usb.config这个属性
else { if (functions == null) { functions = mDefaultFunctions; } // Override with bootmode specific usb mode if needed functions = processOemUsbOverride(functions); if (mAdbEnabled && !functions.equals(UsbManager.USB_FUNCTION_CHARGING)) { functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB); } else { functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB); } if (!mCurrentFunctions.equals(functions)) { if (!setUsbConfig("none")) {//断开usb Slog.e(TAG, "Failed to disable USB"); // revert to previous configuration if we fail setUsbConfig(mCurrentFunctions); return; } if (setUsbConfig(functions)) { if(mCurrentFunctions.equals(UsbManager.USB_FUNCTION_CHARGING) && !mCurrentFunctions.equals(functions)){ if (DEBUG) Slog.d(TAG, " change charging functions to new functions: " + functions); SystemProperties.set("sys.usb.charging", "no"); } mCurrentFunctions = functions; } else { Slog.e(TAG, "Failed to switch USB config to " + functions); // revert to previous configuration if we fail setUsbConfig(mCurrentFunctions); } } }
下面我们再来看看setUsbConfig这个函数
private boolean setUsbConfig(String config) { if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")"); // set the new configuration SystemProperties.set("sys.usb.config", config); return waitForState(config); }
waitForState函数
private boolean waitForState(String state) { // wait for the transition to complete. // give up after 1 second. for (int i = 0; i < 40; i++) { // State transition is done when sys.usb.state is set to the new configuration if (state.equals(SystemProperties.get("sys.usb.state"))){//设置的属性和读取的属性相同 Log.i(TAG,"Setting SystemProperties ,i = "+i); if(state.equals("none")){ if(SystemProperties.get("sys.lc.usb.state").equals("0")){ return true; }else{ Log.i(TAG,"sys.lc.usb.state ="+SystemProperties.get("sys.lc.usb.state")); } }else{ return true; } } SystemClock.sleep(50);//不相同,睡50ms 也就是最多会睡2s } Slog.e(TAG, "waitForState(" + state + ") FAILED"); return false; }继续分析usbhandler
mContentResolver.registerContentObserver( Settings.Global.getUriFor(Settings.Global.ADB_ENABLED), false, new AdbSettingsObserver());//注册一个adb的观察者,会发送消息。 // Watch for USB configuration changes mUEventObserver.startObserving(USB_STATE_MATCH);//开启两个节点的监控。 mUEventObserver.startObserving(ACCESSORY_START_MATCH); IntentFilter filter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED); filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); mContext.registerReceiver(mBootCompletedReceiver, filter); mContext.registerReceiver( mUserSwitchedReceiver, new IntentFilter(Intent.ACTION_USER_SWITCHED)); mContext.registerReceiver( mBatteryChangedReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));AdbSettingsObserver 发送消息
private class AdbSettingsObserver extends ContentObserver { public AdbSettingsObserver() { super(null); } @Override public void onChange(boolean selfChange) { boolean enable = (Settings.Global.getInt(mContentResolver, Settings.Global.ADB_ENABLED, 0) > 0); mHandler.sendMessage(MSG_ENABLE_ADB, enable); } }消息处理,调用setAdbEnabled
case MSG_ENABLE_ADB: setAdbEnabled(msg.arg1 == 1); break;UEventObserver 分析
private final UEventObserver mUEventObserver = new UEventObserver() { @Override public void onUEvent(UEventObserver.UEvent event) { if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString()); String state = event.get("USB_STATE"); String accessory = event.get("ACCESSORY"); if (state != null) {//state对应一个节点 mHandler.updateState(state);//updateState函数前面分析过了 } else if ("START".equals(accessory)) {//accessory对应一个节点 if (DEBUG) Slog.d(TAG, "got accessory start"); startAccessoryMode(); } } }
startAccessoryMode函数
private void startAccessoryMode() { if (!mHasUsbAccessory) return; mAccessoryStrings = nativeGetAccessoryStrings(); boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE); // don't start accessory mode if our mandatory strings have not been set boolean enableAccessory = (mAccessoryStrings != null && mAccessoryStrings[UsbAccessory.MANUFACTURER_STRING] != null && mAccessoryStrings[UsbAccessory.MODEL_STRING] != null); String functions = null; if (enableAccessory && enableAudio) { functions = UsbManager.USB_FUNCTION_ACCESSORY + "," + UsbManager.USB_FUNCTION_AUDIO_SOURCE; } else if (enableAccessory) { functions = UsbManager.USB_FUNCTION_ACCESSORY; } else if (enableAudio) { functions = UsbManager.USB_FUNCTION_AUDIO_SOURCE; } if (functions != null) { mAccessoryModeRequestTime = SystemClock.elapsedRealtime(); setCurrentFunctions(functions, false);//设置属性 } }
还有就是用户调用usbmanger中的setCurrentFunction
public void setCurrentFunction(String function, boolean makeDefault) { try { mService.setCurrentFunction(function, makeDefault); } catch (RemoteException e) { Log.e(TAG, "RemoteException in setCurrentFunction", e); } }
接着调用usbservice中的setCurrentFunction函数
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中的setCurrentFunctions函数
public void setCurrentFunctions(String functions, boolean makeDefault) { String currentUsbConfig = SystemProperties.get("sys.usb.config", "none");// 先从属性里面读出来,主要看有没有adb Log.i(TAG, "begin to setCurrentFunction : sys.usb.config = " + currentUsbConfig + " , mMassStorageEnable:" + mMassStorageEnable + " , functions =" + functions +" , makeDefault =" + makeDefault); if(functions != null){ if(containsFunction(functions,UsbManager.USB_FUNCTION_ENABLE_SERIAL)){ functions = "serial"; }else if(containsFunction(functions,UsbManager.USB_FUNCTION_DISABLE_SERIAL)){ if("false".equals(mMassStorageEnable)){ functions = "mtp"; }else{ functions = "mtp,mass_storage"; } }else if(containsFunction(functions,UsbManager.USB_FUNCTION_RNDIS)){// usb共享要看,串口有没有开, if(containsFunction(currentUsbConfig,UsbManager.USB_FUNCTION_SERIAL)){ functions = "rndis,serial";//开了串口才能把这两项都设置到属性中去 } } } if(containsFunction(currentUsbConfig,UsbManager.USB_FUNCTION_ADB)){ if(functions != null)addFunction(functions,UsbManager.USB_FUNCTION_ADB); } Log.i(TAG, "setCurrentFunction finally function:" + fixFunction(functions) + " makeDefault:" + makeDefault); mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, fixFunction(functions), makeDefault); }
fixFunction的话是将一些其他的属性加入,因为设置属性每次都要设置所有的
private String fixFunction(String function) { Log.d(TAG," fixFunction: function:" + function); String ret = function; if (null == function) { return null; } if (containsFunction(function, UsbManager.USB_FUNCTION_MTP)){ if("false".equals(mMassStorageEnable)){ ret = "mtp"; } else { ret = "mtp,mass_storage"; } } else if (containsFunction(function, UsbManager.USB_FUNCTION_PTP)) { if("false".equals(mMassStorageEnable)){ ret = "ptp"; } else { ret = "ptp,mass_storage"; } } else { return ret; } if (containsFunction(function, UsbManager.USB_FUNCTION_ADB)) { addFunction(ret, UsbManager.USB_FUNCTION_ADB); } return ret; }
发送消息之后,消息处理。主要还是调用setEnabledFunctions设置属性。当属性中含有rndis和accessory经常导致不能及时获取的属性值一样。而waitforstate时会等待,所有这边就起了一个线程。
case MSG_SET_CURRENT_FUNCTIONS: final String functions = (String)msg.obj; final boolean makeDefault = (msg.arg1 == 1); Log.d(TAG, "set current funtion to " + functions); if (null != functions){ if(!functions.contains(UsbManager.USB_FUNCTION_CHARGING)){ mConnected_InChargeOnlyMode = false; }else{ mConnected_InChargeOnlyMode = true; } } if (null != functions && (functions.contains("rndis")||functions.contains("accessory"))) { new Thread() { public void run() { Log.d(TAG, "new Thread setEnabledFunctions to " + functions); setEnabledFunctions(functions, makeDefault); } }.start(); } else { setEnabledFunctions(functions, makeDefault); } break;下面大致说下各个属性。
public static final String USB_FUNCTION_ADB = "adb"; /** * Name of the RNDIS ethernet USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * {@hide} */ public static final String USB_FUNCTION_RNDIS = "rndis";//usb共享 /** * Name of the MTP USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * {@hide} */ public static final String USB_FUNCTION_MTP = "mtp"; /** * Name of the PTP USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * {@hide} */ public static final String USB_FUNCTION_PTP = "ptp"; /** * Name of the audio source USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * {@hide} */ public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source"; /** * Name of the Accessory USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * {@hide} */ public static final String USB_FUNCTION_ACCESSORY = "accessory"; /** * Name of the charging USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * {@hide} */ public static final String USB_FUNCTION_CHARGING = "charging"; /** * Name of the serial USB function. * Used in extras for the {@link #ACTION_USB_STATE} broadcast * * {@hide} */ public static final String USB_FUNCTION_SERIAL = "serial";//开启串口的
还有整个usb.config属性设置后。会触发init.usb.rc中的一些触发器。这在init的博客中分析过了。
下面我们看下整个init.usb.rc,是各个排列组合都列出来了。最后一个是设置persist.sys.usb.config永久系统属性的时候也会设置 sys.usb.config属性。
# Used to disable USB when switching states on property:sys.usb.config=none//设置属性none stop adbd write /sys/class/android_usb/android0/enable 0//写enable为0 write /sys/class/android_usb/android0/bDeviceClass 0 setprop sys.usb.state $sys.usb.config #mtp,mass_storage,adb on property:sys.usb.config=mtp,mass_storage,adb write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 181C 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 #mtp,mass_storage on property:sys.usb.config=mtp,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 181C 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 #ptp,mass_storage,adb on property:sys.usb.config=ptp,mass_storage,adb write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 181D 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 #ptp,mass_storage on property:sys.usb.config=ptp,mass_storage write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 181D 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 #rndis,adb,serial on property:sys.usb.config=rndis,adb,serial write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 181F write /sys/class/android_usb/android0/functions rndis,serial,adb write /sys/class/android_usb/android0/f_rndis/wceis 1 write /sys/class/android_usb/android0/f_serial/serial_port_num 4 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state rndis,serial,adb #rndis,serial,adb on property:sys.usb.config=rndis,serial,adb write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 181F write /sys/class/android_usb/android0/functions $sys.usb.config write /sys/class/android_usb/android0/f_rndis/wceis 1 write /sys/class/android_usb/android0/f_serial/serial_port_num 4 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state $sys.usb.config #rndis,serial on property:sys.usb.config=rndis,serial write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 181F write /sys/class/android_usb/android0/functions $sys.usb.config write /sys/class/android_usb/android0/f_rndis/wceis 1 write /sys/class/android_usb/android0/f_serial/serial_port_num 4 write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state $sys.usb.config #rndis,adb on property:sys.usb.config=rndis,adb write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 181E write /sys/class/android_usb/android0/functions $sys.usb.config write /sys/class/android_usb/android0/f_rndis/wceis 1 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state $sys.usb.config #rndis on property:sys.usb.config=rndis write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 181E write /sys/class/android_usb/android0/functions $sys.usb.config write /sys/class/android_usb/android0/f_rndis/wceis 1 write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state $sys.usb.config #mass_storage,serial,adb on property:sys.usb.config=mass_storage,serial,adb write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 181B write /sys/class/android_usb/android0/functions $sys.usb.config write /sys/class/android_usb/android0/f_serial/serial_port_num 5 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state $sys.usb.config #accessory,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 2D00 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 #accessory 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 2D01 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 #adb 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 1819 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 #mtp,adb on property:sys.usb.config=mtp,adb write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 1818 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 #mtp on property:sys.usb.config=mtp write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 1818 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 #ptp,adb on property:sys.usb.config=ptp,adb write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 1817 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 #ptp on property:sys.usb.config=ptp write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 1817 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 #serial,adb on property:sys.usb.config=serial,adb write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 1816 write /sys/class/android_usb/android0/functions $sys.usb.config write /sys/class/android_usb/android0/f_serial/serial_port_num 4 write /sys/class/android_usb/android0/enable 1 start adbd setprop sys.usb.state $sys.usb.config #serial on property:sys.usb.config=serial write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 1816 write /sys/class/android_usb/android0/functions $sys.usb.config write /sys/class/android_usb/android0/f_serial/serial_port_num 4 write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state $sys.usb.config #USB Charging Only configuration #for android_usb device should not been none,so set a default function in this mode on property:sys.usb.config=charging write /sys/class/android_usb/android0/enable 0 write /sys/class/android_usb/android0/idVendor 18D1 write /sys/class/android_usb/android0/idProduct 181C write /sys/class/android_usb/android0/functions mtp,mass_storage,adb write /sys/class/android_usb/android0/enable 1 setprop sys.usb.state $sys.usb.config setprop sys.usb.charging yes on property:sys.usb.charging=yes write /sys/devices/platform/comip-u2d/charge_mode 1 on property:sys.usb.charging=no write /sys/devices/platform/comip-u2d/charge_mode 0 # 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