当前位置:   article > 正文

usb 网络共享无法选择_rk3568 usb tethering 无效

rk3568 usb tethering 无效

请转载的朋友表明出处:

http://blog.csdn.net/shift_wwx/article/details/77941434


最近碰到一个bug,设置中usb 网络共享无法选择,跟了一下code 后总结一下(版本是android 4.4)


Setting 中详细code 不做总结,主要是最后调用的地方:

(code 路径是:packages/app/Settings/****/TetherSettings.java)

  1. private void setUsbTethering(boolean enabled) {
  2. ConnectivityManager cm =
  3. (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
  4. mUsbTether.setChecked(false);
  5. if (cm.setUsbTethering(enabled) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
  6. mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
  7. return;
  8. }
  9. mUsbTether.setSummary("");
  10. }


最终调用到cm.setUsbTethering(enabled):

(code 路径是: frameworks/base/services/****/ConnectivityService.java)

  1. public int setUsbTethering(boolean enable) {
  2. enforceTetherChangePermission();
  3. if (isTetheringSupported()) {
  4. return mTethering.setUsbTethering(enable);
  5. } else {
  6. return ConnectivityManager.TETHER_ERROR_UNSUPPORTED;
  7. }
  8. }


下一步是Tethering.java:

(code 路径是 frameworks/base/services/****/Tethering.java)

  1. public int setUsbTethering(boolean enable) {
  2. if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")");
  3. UsbManager usbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
  4. synchronized (mPublicSync) {
  5. if (enable) {
  6. if (mRndisEnabled) {
  7. tetherUsb(true);
  8. } else {
  9. mUsbTetherRequested = true;
  10. usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS, false);
  11. }
  12. } else {
  13. tetherUsb(false);
  14. if (mRndisEnabled) {
  15. usbManager.setCurrentFunction(null, false);
  16. }
  17. mUsbTetherRequested = false;
  18. }
  19. }
  20. return ConnectivityManager.TETHER_ERROR_NO_ERROR;
  21. }

---->

  1. private void tetherUsb(boolean enable) {
  2. if (VDBG) Log.d(TAG, "tetherUsb " + enable);
  3. String[] ifaces = new String[0];
  4. try {
  5. ifaces = mNMService.listInterfaces();
  6. } catch (Exception e) {
  7. Log.e(TAG, "Error listing Interfaces", e);
  8. return;
  9. }
  10. final String usbSysctlKey = "sys.usb.tethering";
  11. SystemProperties.set(usbSysctlKey, "false");
  12. if (enable) {
  13. SystemProperties.set(usbSysctlKey, "true");
  14. }
  15. for (String iface : ifaces) {
  16. Log.d(TAG, "iface: " + iface);
  17. if (isUsb(iface)) {
  18. int result = (enable ? tether(iface) : untether(iface));
  19. if (result == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
  20. return;
  21. }
  22. }
  23. }
  24. Log.e(TAG, "unable start or stop USB tethering");
  25. }

看到这里,大概可以猜到无法成功选择的原因:

1、ifaces = mNMService.listInterfaces(); 出现异常,catch 中直接return

2、同样 1 这句话,可能获取的ifaces 不存在(是否存在,可以在下面的循环中加上log,贴出来的code 中已经加上log)

3、循环中 isUsb(iface) 返回为false


对于上面的三个问题,我一一做了排查,最后发现是isUsb这个函数出现的问题:

  1. private boolean isUsb(String iface) {
  2. synchronized (mPublicSync) {
  3. for (String regex : mTetherableUsbRegexs) {
  4. if (iface.matches(regex)) return true;
  5. }
  6. return false;
  7. }
  8. }
也就是iface 必须要是符合一定的规则,而变量mTetherableUsbRegexs 就是所谓的规则。


找到mTetherableUsbRegexs 定义个赋值的地方:

  1. void updateConfiguration() {
  2. String[] tetherableUsbRegexs = mContext.getResources().getStringArray(
  3. com.android.internal.R.array.config_tether_usb_regexs);
  4. String[] tetherableWifiRegexs = mContext.getResources().getStringArray(
  5. com.android.internal.R.array.config_tether_wifi_regexs);
  6. String[] tetherableBluetoothRegexs = mContext.getResources().getStringArray(
  7. com.android.internal.R.array.config_tether_bluetooth_regexs);
  8. int ifaceTypes[] = mContext.getResources().getIntArray(
  9. com.android.internal.R.array.config_tether_upstream_types);
  10. Collection<Integer> upstreamIfaceTypes = new ArrayList();
  11. IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
  12. IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
  13. try {
  14. int activeNetType = cm.getActiveNetworkInfo().getType();
  15. for (int i : ifaceTypes) {
  16. if(i == activeNetType) {
  17. upstreamIfaceTypes.add(new Integer(i));
  18. }
  19. }
  20. } catch (Exception e) {
  21. Log.d(TAG, "Exception adding default nw to upstreamIfaceTypes: " + e);
  22. }
  23. for (int i : ifaceTypes) {
  24. if(!upstreamIfaceTypes.contains(new Integer(i))) {
  25. upstreamIfaceTypes.add(new Integer(i));
  26. }
  27. }
  28. synchronized (mPublicSync) {
  29. mTetherableUsbRegexs = tetherableUsbRegexs;
  30. mTetherableWifiRegexs = tetherableWifiRegexs;
  31. mTetherableBluetoothRegexs = tetherableBluetoothRegexs;
  32. mUpstreamIfaceTypes = upstreamIfaceTypes;
  33. }
  34. // check if the upstream type list needs to be modified due to secure-settings
  35. checkDunRequired();
  36. }
最终知道变量mTetherableUsbRegexs 来源于config:

com.android.internal.R.array.config_tether_usb_regexs


最终确定的是这个config 必须要配置,android 源生是没有这样配置的,需要在overlay 中做配置,如下:

  1. <string-array translatable="false" name="config_tether_usb_regexs">
  2. <item>"usb\\d"</item>
  3. <item>"rndis\\d"</item>
  4. </string-array>

这样,只要驱动给出来的interface 是rndis0 即可,bug 就算解决了



后话:

总结的时候是在一个低版本的平台中发现的问题,所以就总结了低版本的code,我看了下 android 7.1 的版本,逻辑上做了稍微的调整,功能上设计是一样的,最终同样调用到的还是Tethering.java 中的setUsbTethering。



















声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号