USB Tethering always displays grey when USB tethering type is Linux(EEM)

1.Problem DESCRIPTION

  • USB Tethering always displays grey when USB tethering type is Linux(EEM)

  • Precondition:

    MS connects wifi

  • REPRODUCING PROCEDURES:

    1.Go to Settings-More-Tethering&mobile hotspot,select USB tethering type as Linux(EEM)

    2.Use usb cable connect MS to PC,and enable USB tethering,tethering is enable,but the item always displays grey

    3.Disconnect the MS to PC,check the Tethering&mobile hotspot,tethering is off,but the USB tethering type item displays grey

2.Analysis

控制usb tethering type这个preference是否可用的方法在文件TetherSettingsExt.java中,具体实现如下所示:

  1. publicvoid updateUsbTypeListState(boolean state){
  2. if(mUsbTetherType !=null){
  3. Log.d(TAG,"set USB Tether Type state = "+ state);
  4. mUsbTetherType.setEnabled(state);
  5. }
  6. }

在正常情况下有如下状态:

  1. 在未通过usb连接电脑时,usb tethering type这个preference为黑色(state为true),usb tethering 这个preference为灰色(state为false)。
  2. 在通过usb连接电脑时,usb tethering type这个preference为黑色(state为true),usb tethering 这个preference为黑色(state为true)。
  3. 在通过usb连接电脑时,打开usb tethering ,这时该preference为黑色(state为true),usb tethering type这个preference为灰色(state为false)。
  4. 拔出usb连接线,首先,usb tethering 这个preference和usb tethering type这个preference都为灰色(state为false),过几秒钟后usb tethering type这个preference会转为黑色(state为true)。

而现在测试的实际情况是,在拔出usb连接线后,usb tethering 这个preference和usb tethering type这个preference都为灰色(state为false)且,usb tethering type这个preference一直为灰色(state为false)。

然后找到监控usb连接状态监听,其代码具体如下所示:

  1. privateclassTetherChangeReceiverextendsBroadcastReceiver{
  2. @Override
  3. publicvoid onReceive(Context content,Intent intent){
  4. String action = intent.getAction();
  5. /// M:
  6. Log.d(TAG,"TetherChangeReceiver - onReceive, action is "+ action);
  7. if(action.equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)){
  8. // TODO - this should understand the interface types
  9. ArrayList<String> available = intent.getStringArrayListExtra(
  10. ConnectivityManager.EXTRA_AVAILABLE_TETHER);
  11. ArrayList<String> active = intent.getStringArrayListExtra(
  12. ConnectivityManager.EXTRA_ACTIVE_TETHER);
  13. ArrayList<String> errored = intent.getStringArrayListExtra(
  14. ConnectivityManager.EXTRA_ERRORED_TETHER);
  15. /** M: for bug solving, ALPS00331223 */
  16. mUsbUnTetherDone = intent.getBooleanExtra("UnTetherDone",false);
  17. mUsbTetherDone = intent.getBooleanExtra("TetherDone",false);
  18. mUsbTetherFail = intent.getBooleanExtra("TetherFail",false);
  19. /// M: print log
  20. Log.d(TAG,"mUsbUnTetherDone? :"+ mUsbUnTetherDone +" , mUsbTetherDonel? :"+
  21. mUsbTetherDone +" , tether fail? :"+ mUsbTetherFail);
  22. updateState(available.toArray(newString[available.size()]),
  23. active.toArray(newString[active.size()]),
  24. errored.toArray(newString[errored.size()]));
  25. if(mWifiManager.getWifiApState()==WifiManager.WIFI_AP_STATE_DISABLED
  26. && mRestartWifiApAfterConfigChange){
  27. mRestartWifiApAfterConfigChange =false;
  28. Log.d(TAG,"Restarting WifiAp due to prior config change.");
  29. startTethering(TETHERING_WIFI);
  30. }
  31. }elseif(action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)){
  32. int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE,0);
  33. if(state ==WifiManager.WIFI_AP_STATE_DISABLED
  34. && mRestartWifiApAfterConfigChange){
  35. mRestartWifiApAfterConfigChange =false;
  36. Log.d(TAG,"Restarting WifiAp due to prior config change.");
  37. startTethering(TETHERING_WIFI);
  38. }
  39. }elseif(action.equals(Intent.ACTION_MEDIA_SHARED)){
  40. mMassStorageActive =true;
  41. updateState();
  42. }elseif(action.equals(Intent.ACTION_MEDIA_UNSHARED)){
  43. mMassStorageActive =false;
  44. updateState();
  45. /*此处就是 usb状态的监听部分*/
  46. }elseif(action.equals(UsbManager.ACTION_USB_STATE)){
  47. /*应该是活动usb连接状态,默认为false*/
  48. mUsbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED,false);
  49. /// M: @{
  50. mUsbConfigured = intent.getBooleanExtra(UsbManager.USB_CONFIGURED,false);
  51. mUsbHwDisconnected = intent.getBooleanExtra("USB_HW_DISCONNECTED",false);
  52. mIsPcKnowMe = intent.getBooleanExtra("USB_IS_PC_KNOW_ME",true);
  53. /* 最后拔出usb时的log如下:
  54. TetheringSettings: TetherChangeReceiver - ACTION_USB_STATE mUsbConnected: false, mUsbConfigured: false, mUsbHwDisconnected: true
  55. */
  56. Log.d(TAG,"TetherChangeReceiver - ACTION_USB_STATE mUsbConnected: "
  57. + mUsbConnected +
  58. ", mUsbConfigured: "+ mUsbConfigured +", mUsbHwDisconnected: "
  59. + mUsbHwDisconnected);
  60. /// @}
  61. /*重点是updateState()方法来设置这2个perference 的enabled状态*/
  62. updateState();
  63. }elseif(action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)){
  64. if(mBluetoothEnableForTether){
  65. switch(intent
  66. .getIntExtra(BluetoothAdapter.EXTRA_STATE,BluetoothAdapter.ERROR)){
  67. caseBluetoothAdapter.STATE_ON:
  68. startTethering(TETHERING_BLUETOOTH);
  69. mBluetoothEnableForTether =false;
  70. /// M: @{
  71. BluetoothDun bluetoothDun = mTetherSettingsExt.BluetoothDunGetProxy();
  72. if(bluetoothDun !=null){
  73. bluetoothDun.setBluetoothTethering(true);
  74. mBluetoothEnableForTether =false;
  75. }
  76. /// @}
  77. break;
  78. caseBluetoothAdapter.STATE_OFF:
  79. caseBluetoothAdapter.ERROR:
  80. mBluetoothEnableForTether =false;
  81. break;
  82. default:
  83. // ignore transition states
  84. }
  85. }
  86. updateState();
  87. }
  88. /// M: add
  89. onReceiveExt(action, intent);
  90. }
  91. }

在这个监听中,通过ACTION_USB_STATE这个action来监听usb状态的改变,从它的定义可以知道:

  1. publicstaticfinalString ACTION_USB_STATE =
  2. "android.hardware.usb.action.USB_STATE";
  3. /**
  4. * Broadcast Action: A broadcast for USB port changes.
  5. *
  6. * This intent is sent when a USB port is added, removed, or changes state.
  7. * <ul>
  8. * <li> {@link #EXTRA_PORT} containing the {@link android.hardware.usb.UsbPort}
  9. * for the port.
  10. * <li> {@link #EXTRA_PORT_STATUS} containing the {@link android.hardware.usb.UsbPortStatus}
  11. * for the port, or null if the port has been removed
  12. * </ul>
  13. *
  14. * @hide
  15. */

然后看看 updateState()方法,具体实现如下:

  1. privatevoid updateState(){
  2. /* */
  3. String[] available = mCm.getTetherableIfaces();
  4. String[] tethered = mCm.getTetheredIfaces();
  5. String[] errored = mCm.getTetheringErroredIfaces();
  6. updateState(available, tethered, errored);
  7. }
  8. privatevoid updateState(String[] available,String[] tethered,
  9. String[] errored){
  10. /// M: need put firstly @{
  11. if(updateStateExt(available, tethered, errored)){
  12. return;
  13. }
  14. // @}
  15. updateUsbState(available, tethered, errored);
  16. updateBluetoothState(available, tethered, errored);
  17. /// M: resolve JE
  18. if(!Utils.isMonkeyRunning()){
  19. mTetherSettingsExt.updateIpv6Preference(mUsbTether, mBluetoothTether, mWifiManager);
  20. }
  21. // @}
  22. }

在updateState方法中首先执行updateStateExt方法,该方法放回固定值false。??有什么用呢

  1. privateboolean updateStateExt(String[] available,String[] tethered,
  2. String[] errored){
  3. /*
  4. TetheringSettings: =======> updateState - mUsbConnected: false, mUsbConfigured: false, mUsbHwDisconnected: true, checked: true, mUsbUnTetherDone: true, mUsbTetherDone: false, tetherfail: false, mIsPcKnowMe: true
  5. */
  6. Log.d(TAG,"=======> updateState - mUsbConnected: "+ mUsbConnected +
  7. ", mUsbConfigured: "+ mUsbConfigured +", mUsbHwDisconnected: "+
  8. mUsbHwDisconnected +", checked: "+ mUsbTether.isChecked()+
  9. ", mUsbUnTetherDone: "+ mUsbUnTetherDone +", mUsbTetherDone: "+
  10. mUsbTetherDone +", tetherfail: "+ mUsbTetherFail +
  11. ", mIsPcKnowMe: "+ mIsPcKnowMe);
  12. /** M: for bug solving, ALPS00331223 */
  13. // turn on tethering case
  14. if(mUsbTether.isChecked()){
  15. /*
  16. 进入if逻辑
  17. */
  18. if(mUsbConnected && mUsbConfigured &&!mUsbHwDisconnected){
  19. if(mUsbTetherFail || mUsbTetherDone ||!mIsPcKnowMe){
  20. mUsbTetherCheckEnable =true;
  21. }
  22. }else{
  23. /* 将属性mUsbTetherCheckEnable置为false。???什么用?
  24. */
  25. mUsbTetherCheckEnable =false;
  26. }
  27. }else{// turn off tethering case or first launch case
  28. if(mUsbConnected &&!mUsbHwDisconnected){
  29. if(mUsbUnTetherDone || mUsbTetherFail){
  30. mUsbTetherCheckEnable =true;
  31. }
  32. }else{
  33. mUsbTetherCheckEnable =false;
  34. }
  35. }
  36. returnfalse;
  37. }

然后具体控制usb tethering type这个preference是否可用的逻辑在updateUsbState方法中,其代码如下:

  1. privatevoid updateUsbState(String[] available,String[] tethered,
  2. String[] errored){
  3. /*控制usb tethering这个perfernece是否可用*/
  4. boolean usbAvailable = mUsbConnected &&!mMassStorageActive;
  5. int usbError =ConnectivityManager.TETHER_ERROR_NO_ERROR;
  6. /**/
  7. for(String s : available){
  8. for(String regex : mUsbRegexs){
  9. if(s.matches(regex)){
  10. if(usbError ==ConnectivityManager.TETHER_ERROR_NO_ERROR){
  11. usbError = mCm.getLastTetherError(s);
  12. }
  13. }
  14. }
  15. }
  16. boolean usbTethered =false;
  17. for(String s : tethered){
  18. for(String regex : mUsbRegexs){
  19. if(s.matches(regex)) usbTethered =true;
  20. }
  21. }
  22. boolean usbErrored =false;
  23. for(String s: errored){
  24. for(String regex : mUsbRegexs){
  25. if(s.matches(regex)) usbErrored =true;
  26. }
  27. }
  28. // M: add for IPV4/IPV6 , must return the usbError
  29. usbError = mTetherSettingsExt.getUSBErrorCode(available, tethered,
  30. mUsbRegexs);
  31. /* log如下:
  32. TetheringSettings: updateUsbState - usbTethered : false usbErrored: false usbAvailable: false
  33. */
  34. Log.d(TAG,"updateUsbState - usbTethered : "+ usbTethered +" usbErrored: "+
  35. usbErrored +" usbAvailable: "+ usbAvailable);
  36. /*从log看 usbTethered : false 不走该逻辑*/
  37. if(usbTethered){
  38. /** M: Google original code removed to adapt to our feature
  39. mUsbTether.setSummary(R.string.usb_tethering_active_subtext);
  40. */
  41. Log.d(TAG,"updateUsbState: usbTethered ! mUsbTether checkbox setEnabled & checked ");
  42. mUsbTether.setEnabled(!mDataSaverEnabled);
  43. mUsbTether.setChecked(true);
  44. /// M: set usb tethering to false @{
  45. finalString summary = getString(R.string.usb_tethering_active_subtext);
  46. mTetherSettingsExt.updateUSBPrfSummary(mUsbTether, summary, usbTethered, usbAvailable);
  47. mUsbTethering =false;
  48. mTetherSettingsExt.updateUsbTypeListState(false);
  49. Log.d(TAG,"updateUsbState - usbTethered - mUsbTetherCheckEnable: "
  50. + mUsbTetherCheckEnable);
  51. /// @}
  52. /*从log看usbAvailable: false 也不走该逻辑*/
  53. }elseif(usbAvailable){
  54. if(usbError ==ConnectivityManager.TETHER_ERROR_NO_ERROR){
  55. mUsbTether.setSummary(R.string.usb_tethering_available_subtext);
  56. }else{
  57. mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
  58. }
  59. mTetherSettingsExt.updateUSBPrfSummary(mUsbTether,null, usbTethered, usbAvailable);
  60. if(mUsbTetherCheckEnable){
  61. Log.d(TAG,"updateUsbState - mUsbTetherCheckEnable, "+
  62. "mUsbTether checkbox setEnabled, and set unchecked ");
  63. mUsbTether.setEnabled(!mDataSaverEnabled);
  64. mUsbTether.setChecked(false);
  65. /// M:
  66. mUsbTethering =false;
  67. mTetherSettingsExt.updateUsbTypeListState(true);
  68. }
  69. Log.d(TAG,"updateUsbState - usbAvailable - mUsbConfigured: "+ mUsbConfigured +
  70. " mUsbTethering: "+ mUsbTethering +
  71. " mUsbTetherCheckEnable: "+ mUsbTetherCheckEnable);
  72. /*usbErrored: false 不进入该逻辑
  73. */
  74. }elseif(usbErrored){
  75. mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
  76. mUsbTether.setEnabled(false);
  77. mUsbTether.setChecked(false);
  78. /// M: set usb tethering to false
  79. mUsbTethering =false;
  80. /**/
  81. }elseif(mMassStorageActive){
  82. mUsbTether.setSummary(R.string.usb_tethering_storage_active_subtext);
  83. mUsbTether.setEnabled(false);
  84. mUsbTether.setChecked(false);
  85. /// M: set usb tethering to false
  86. mUsbTethering =false;
  87. }else{
  88. if(mUsbHwDisconnected ||(!mUsbHwDisconnected &&!mUsbConnected &&!mUsbConfigured)){
  89. /*在打开usb tethering时强制拔出usb,并想要在此时设置usb tethering type为可操作(黑色state为true)
  90. */
  91. mUsbTether.setSummary(R.string.usb_tethering_unavailable_subtext);
  92. mUsbTether.setEnabled(false);
  93. mUsbTether.setChecked(false);
  94. mUsbTethering =false;
  95. }else{
  96. /*
  97. 用来更新usb state状态,如在连接usb时打开或者关闭usb tethering
  98. */
  99. /// M: update usb state @{
  100. Log.d(TAG,"updateUsbState - else, "+
  101. "mUsbTether checkbox setEnabled, and set unchecked ");
  102. mUsbTether.setSummary(R.string.usb_tethering_available_subtext);
  103. mUsbTether.setEnabled(true);
  104. mUsbTether.setChecked(false);
  105. mUsbTethering =false;
  106. mTetherSettingsExt.updateUsbTypeListState(true);
  107. /// @}
  108. }
  109. /*log如下:
  110. TetheringSettings: updateUsbState- usbAvailable- mUsbHwDisconnected:true
  111. */
  112. Log.d(TAG,"updateUsbState- usbAvailable- mUsbHwDisconnected:"+ mUsbHwDisconnected);
  113. }
  114. }

从如下的log,可以看出在进入updateUsbState方法后的运行流程。

  1. 06-0610:33:13.99011456135613 D TetheringSettings:=======> updateState - mUsbConnected:false, mUsbConfigured:false, mUsbHwDisconnected:true,checked:true, mUsbUnTetherDone:true, mUsbTetherDone:false, tetherfail:false, mIsPcKnowMe:true
  2. 06-0610:33:13.99017956135613 D TetheringSettings: updateUsbState - usbTethered :false usbErrored:false usbAvailable:false
  3. 06-0610:33:13.99137056135613 D TetheringSettings: updateUsbState- usbAvailable- mUsbHwDisconnected:true

usb tethering这个preference对应的点击监听器代码实现如下:

  1. publicboolean onPreferenceTreeClick(Preference preference){
  2. if(preference == mUsbTether){
  3. if(!mUsbTethering){
  4. /// M: update usb tethering @{
  5. boolean newState = mUsbTether.isChecked();if((getResources().getBoolean(R.bool.def_usb_tethering_on_restraint_data_connect))){
  6. WifiManager wifiManager =(WifiManager)getSystemService(Context.WIFI_SERVICE);
  7. android.net.wifi.WifiInfo wifiInfo = wifiManager.getConnectionInfo();
  8. if(mUsbTether.isChecked()){
  9. if(!isNetworkConnected()&&!(wifiManager.isWifiEnabled()&&(null!= wifiInfo)&&(wifiInfo.getNetworkId()!=-1))){
  10. initNetworkConnectDialog();
  11. mUsbTether.setChecked(false);
  12. returnfalse;
  13. }
  14. }
  15. }
  16. /*此处就是将usb tethering这个preference置为灰色的逻辑*/
  17. mUsbTether.setEnabled(false);
  18. /*此处就是将usb tethering type这个preference置为灰色的逻辑*/
  19. mTetherSettingsExt.updateUsbTypeListState(false);
  20. mUsbTethering =true;
  21. mUsbTetherCheckEnable =false;
  22. if(newState){
  23. mUsbTetherDone =false;
  24. }else{
  25. mUsbUnTetherDone =false;
  26. }
  27. mUsbTetherFail =false;
  28. Log.d(TAG,"onPreferenceTreeClick - setusbTethering("+ newState +
  29. ") mUsbTethering: "+ mUsbTethering);
  30. /// @}
  31. if(mUsbTether.isChecked()){
  32. showDatasetDialog();
  33. startTethering(TETHERING_USB);
  34. }else{
  35. mCm.stopTethering(TETHERING_USB);
  36. }
  37. }else{
  38. returntrue;
  39. }
  40. }elseif(preference == mBluetoothTether){
  41. if(mBluetoothTether.isChecked()){
  42. startTethering(TETHERING_BLUETOOTH);
  43. }else{
  44. mCm.stopTethering(TETHERING_BLUETOOTH);
  45. /// M: set bluetooth tethering to false
  46. mTetherSettingsExt.updateBtDunTether(false);
  47. // No ACTION_TETHER_STATE_CHANGED is fired or bluetooth unless a device is
  48. // connected. Need to update state manually.
  49. updateState();
  50. }
  51. if(!Utils.isMonkeyRunning()){
  52. mTetherSettingsExt.updateIpv6Preference(mUsbTether, mBluetoothTether, mWifiManager);
  53. }
  54. }elseif(preference == mCreateNetwork){
  55. showDialog(DIALOG_AP_SETTINGS);
  56. }
  57. returnsuper.onPreferenceTreeClick(preference);
  58. }

从上面代码可以看出,就是在点击usb tethering这个item时将usb tethering和usb tethering type preference变为灰色的,然后会通过发送广播重新将它自己变为黑色而并没有对usb tethering type这个preference对象进行操作,所以usb tethering type还是灰色,如果需要将它变成黑色,就需要添加新逻辑来操作。

而通过关闭usb tethering开关的逻辑来enable usb tethering type对象,主要是走的updateUsbState方法的如下部分:

  1. }elseif(usbAvailable){
  2. if(usbError ==ConnectivityManager.TETHER_ERROR_NO_ERROR){
  3. mUsbTether.setSummary(R.string.usb_tethering_available_subtext);
  4. }else{
  5. mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
  6. }
  7. mTetherSettingsExt.updateUSBPrfSummary(mUsbTether,null, usbTethered, usbAvailable);
  8. if(mUsbTetherCheckEnable){
  9. Log.d(TAG,"updateUsbState - mUsbTetherCheckEnable, "+
  10. "mUsbTether checkbox setEnabled, and set unchecked ");
  11. mUsbTether.setEnabled(!mDataSaverEnabled);
  12. mUsbTether.setChecked(false);
  13. /// M:
  14. mUsbTethering =false;
  15. /*将usb tethering type对象enable*/
  16. mTetherSettingsExt.updateUsbTypeListState(true);
  17. }
  18. Log.d(TAG,"updateUsbState - usbAvailable - mUsbConfigured: "+ mUsbConfigured +
  19. " mUsbTethering: "+ mUsbTethering +
  20. " mUsbTetherCheckEnable: "+ mUsbTetherCheckEnable);
  21. }elseif(usbErrored){

3.soluution

根据上面的分析,在文件TetherSettings.java中的updateUsbState方法里调用该usb tethering type item对象的updateUsbTypeListState方法,具体修改如下所示:

  1. /// M: set usb tethering to false
  2. mUsbTethering =false;
  3. }else{
  4. Log.d(TAG,"mUsbHwDisconnected: "+ mUsbHwDisconnected +
  5. " mUsbHwDisconnected: "+ mUsbHwDisconnected +
  6. " mUsbConnected: "+ mUsbConnected+
  7. " mUsbConfigured: "+mUsbConfigured);
  8. if(mUsbHwDisconnected ||(!mUsbHwDisconnected &&!mUsbConnected &&!mUsbConfigured)){
  9. mUsbTether.setSummary(R.string.usb_tethering_unavailable_subtext);
  10. mUsbTether.setEnabled(false);
  11. mUsbTether.setChecked(false);
  12. /*add for enable the object of the usb Tether type when disconnect the MS to PC*/
  13. mTetherSettingsExt.updateUsbTypeListState(true);
  14. /*add for enable the object of the usb Tether type when disconnect the MS to PC */
  15. mUsbTethering =false;
  16. }else{
  17. /// M: update usb state @{
  18. Log.d(TAG,"updateUsbState - else, "+
  19. "mUsbTether checkbox setEnabled, and set unchecked ");
  20. mUsbTether.setSummary(R.string.usb_tethering_available_subtext);
  21. mUsbTether.setEnabled(true);
  22. mUsbTether.setChecked(false);
  23. mUsbTethering =false;
  24. mTetherSettingsExt.updateUsbTypeListState(true);
  25. /// @}
  26. }
  27. Log.d(TAG,"updateUsbState- usbAvailable- mUsbHwDisconnected:"+ mUsbHwDisconnected);
  28. }
  29. }

4.summary

这个问题主要是需要找到该preference相关的监听,看时在什么地方有调用。对应第一个问题的描述,因为测试后一直没有复现,所以没有进行修改。而第二个问题成功复现,看代码应该是平台就这样设计的。其实在打开usb tethering时强制拔出usb情况,该usb tethering type一直是灰色对整个功能的影响不是很大,因为在下次插入usb时,通过usb状态广播,是会将该item置为enable的。但是也发现,在对手机旋转操作后,会调用onstarte方法来重新初始化当前界面,usb tethering type这个preference会被变为可用(黑色),所以这也算一个小bug吧。因为整个行为都是由是否插入usb状态来决定该preference是否enable,具体修改是在广播接收器中,对usb状态监听的逻辑中加入mTetherSettingsExt.updateUsbTypeListState(true);,即在拔出usb时,将usb tethering type这个preferenc对象setEnabled置为true。

USB Tethering always displays grey when USB tethering type is Linux(EEM)的更多相关文章

  1. 你的USB设备还安全吗?USB的安全性已从根本上被打破!

    前言: USB设备使用方便,但也可能被用来携带恶意软件.病毒,感染计算机系统.通过禁用自动播放功能.杀毒软件查杀.不定期的对设备进行格式化等操作可以确保它是干净的.但它存在的安全问题要比我们想象的更深 ...

  2. Android USB Connections Explained: MTP, PTP, and USB Mass Storage

    Android USB Connections Explained: MTP, PTP, and USB Mass Storage Older Android devices support USB ...

  3. Linux usb子系统(二):USB设备驱动usb-skeleton.c

    usb驱动分为通过usbfs操作设备的用户空间驱动,内核空间的内核驱动.两者不能同时进行,否则容易引发对共享资源访问的问题,死锁!使用了内核驱动,就不能在usbfs里驱动该设备. 下面转载的一篇分析u ...

  4. USB系列之二:读取USB设备的描述符

    在前面的文章中,我们已经给出了USB协议的链接地址,从这篇文章起,我们会涉及到许多USB 1.1的内容,我们的指导思想是先从熟悉USB 1.1协议入手,先使用现成的HCD和USBD,直接面对客户端驱动 ...

  5. Linux usb子系统(一) _写一个usb鼠标驱动

    USB总线是一种典型的热插拔的总线标准,由于其优异的性能几乎成为了当下大小设备中的标配. USB的驱动可以分为3类:SoC的USB控制器的驱动,主机端USB设备的驱动,设备上的USB Gadget驱动 ...

  6. C型USB能阻止危险充电器通过USB传播恶意软件

    C型USB能阻止危险充电器通过USB传播恶意软件 C型USB设备(USB Type-C)的新型身份验证协议可以保护用户免受潜在的充电器损坏的风险,这种新型的USB还能减少被恶意软件的风险.基于密码的认 ...

  7. android的USB MTP && USB CDC/USBnet(ECM, NCM, ACM) && USB gardget

    MTP的全称是Media Transfer Protocol(媒体传输协议),它是微软公司提出的一套媒体文件传输协议.早在智能手机普及前,数码相机和MP3播放器等都使用了MTP的前身PTP(Pictu ...

  8. Linux USB 驱动开发(一)—— USB设备基础概念【转】

    本文转载自:http://blog.csdn.net/zqixiao_09/article/details/50984074 在终端用户看来,USB设备为主机提供了多种多样的附加功能,如文件传输,声音 ...

  9. HarmonyOS USB DDK助你轻松实现USB驱动开发

    HDF(Hardware Driver Foundation)驱动框架是HarmonyOS硬件生态开放的基础,为开发者提供了驱动加载.驱动服务管理和驱动消息机制等驱动能力,让开发者能精准且高效地开发驱 ...

随机推荐

  1. 如何优雅的在scrapy中使用selenium —— 在scrapy中实现浏览器池

    1 使用 scrapy 做采集实在是爽,但是遇到网站反爬措施做的比较好的就让人头大了.除了硬着头皮上以外,还可以使用爬虫利器 selenium,selenium 因其良好的模拟能力成为爬虫爱(cai) ...

  2. [BUUCTF]PWN15——[BJDCTF 2nd]one_gadget

    [BUUCTF]PWN15--[BJDCTF 2nd]one_gadget 附件 步骤: 例行检查,64位,保护全开 nc试运行一下程序,看看情况,它一开始给了我们一个地址,然后让我们输入one ga ...

  3. Python学习问题汇总

    个人Python学习过程中遇到问题汇总,不断更新. 一.读取文件是报FileNotFoundError: 前期了解:python是在当前执行文件所在的目录中查找文件. 解决方法: 1.查看输入文件名是 ...

  4. Kubernetes 集群无损升级实践 转至元数据结尾

    一.背景 活跃的社区和广大的用户群,使 Kubernetes 仍然保持3个月一个版本的高频发布节奏.高频的版本发布带来了更多的新功能落地和 bug 及时修复,但是线上环境业务长期运行,任何变更出错都可 ...

  5. CF508A Pasha and Pixels 题解

    Content 有一个 \(n\times m\) 的矩阵,一开始全部格子被染成白色. 接下来有 \(k\) 个操作,每一个操作表示把一个格子染成黑色.问第一次出现 \(2\times 2\) 的全部 ...

  6. CF761A Dasha and Stairs 题解

    Content 给定两个数 \(n,m\),试问是否有区间里面有 \(n\) 个奇数和 \(m\) 个偶数. 数据范围:\(0\leqslant n,m\leqslant 100\). Solutio ...

  7. CF934A A Compatible Pair 题解

    Content 有两个数列 \(A\) 和 \(B\),\(A\) 数列里面有 \(n\) 个元素,\(B\) 数列里面有 \(m\) 个元素,现在请从 \(A\) 数列中删除一个数,使得 \(A\) ...

  8. 【超详细】安全测试===sqlmap使用心得(零)

    零.前言 这篇文章是学习Sqlmap的用法时做的笔记,记录了Sqlmap的常见.基础用法. 一.Sqlmap是什么 Sqlmap是开源的自动化SQL注入工具,由Python写成,具有如下特点: 完全支 ...

  9. fedora之自动寻找命令并提示安装PackageKit-command-not-found

    fedora 1.比如,我要用clang 命令编译代码,但是没有该指令.比如: clang main.cxx -o main 2.那么,输入未知命令,希望fedora会自动寻找相对应的包,再并提示安装 ...

  10. 【LeetCode】1464. 数组中两元素的最大乘积 Maximum Product of Two Elements in an Array (Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力 找最大次大 日期 题目地址:https://le ...