Loading services/java/com/android/server/connectivity/Tethering.java +172 −131 Original line number Diff line number Diff line Loading @@ -81,6 +81,9 @@ public class Tethering extends INetworkManagementEventObserver.Stub { private String[] mTetherableBluetoothRegexs; private Collection<Integer> mUpstreamIfaceTypes; // used to synchronize public access to members private Object mPublicSync; private static final Integer MOBILE_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE); private static final Integer HIPRI_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE_HIPRI); private static final Integer DUN_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE_DUN); Loading Loading @@ -135,6 +138,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub { mConnService = connService; mLooper = looper; mPublicSync = new Object(); mIfaces = new HashMap<String, TetherInterfaceSM>(); // make our own thread so we don't anr the system Loading Loading @@ -172,18 +177,25 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } void updateConfiguration() { mTetherableUsbRegexs = mContext.getResources().getStringArray( String[] tetherableUsbRegexs = mContext.getResources().getStringArray( com.android.internal.R.array.config_tether_usb_regexs); mTetherableWifiRegexs = mContext.getResources().getStringArray( String[] tetherableWifiRegexs = mContext.getResources().getStringArray( com.android.internal.R.array.config_tether_wifi_regexs); mTetherableBluetoothRegexs = mContext.getResources().getStringArray( String[] tetherableBluetoothRegexs = mContext.getResources().getStringArray( com.android.internal.R.array.config_tether_bluetooth_regexs); int ifaceTypes[] = mContext.getResources().getIntArray( com.android.internal.R.array.config_tether_upstream_types); mUpstreamIfaceTypes = new ArrayList(); Collection<Integer> upstreamIfaceTypes = new ArrayList(); for (int i : ifaceTypes) { mUpstreamIfaceTypes.add(new Integer(i)); upstreamIfaceTypes.add(new Integer(i)); } synchronized (mPublicSync) { mTetherableUsbRegexs = tetherableUsbRegexs; mTetherableWifiRegexs = tetherableWifiRegexs; mTetherableBluetoothRegexs = tetherableBluetoothRegexs; mUpstreamIfaceTypes = upstreamIfaceTypes; } // check if the upstream type list needs to be modified due to secure-settings Loading @@ -194,6 +206,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up); boolean found = false; boolean usb = false; synchronized (mPublicSync) { if (isWifi(iface)) { found = true; } else if (isUsb(iface)) { Loading @@ -204,7 +217,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } if (found == false) return; synchronized (mIfaces) { TetherInterfaceSM sm = mIfaces.get(iface); if (up) { if (sm == null) { Loading @@ -231,30 +243,37 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } private boolean isUsb(String iface) { synchronized (mPublicSync) { for (String regex : mTetherableUsbRegexs) { if (iface.matches(regex)) return true; } return false; } } public boolean isWifi(String iface) { synchronized (mPublicSync) { for (String regex : mTetherableWifiRegexs) { if (iface.matches(regex)) return true; } return false; } } public boolean isBluetooth(String iface) { synchronized (mPublicSync) { for (String regex : mTetherableBluetoothRegexs) { if (iface.matches(regex)) return true; } return false; } } public void interfaceAdded(String iface) { if (VDBG) Log.d(TAG, "interfaceAdded " + iface); boolean found = false; boolean usb = false; synchronized (mPublicSync) { if (isWifi(iface)) { found = true; } Loading @@ -270,7 +289,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { return; } synchronized (mIfaces) { TetherInterfaceSM sm = mIfaces.get(iface); if (sm != null) { if (VDBG) Log.d(TAG, "active iface (" + iface + ") reported as added, ignoring"); Loading @@ -285,7 +303,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public void interfaceRemoved(String iface) { if (VDBG) Log.d(TAG, "interfaceRemoved " + iface); synchronized (mIfaces) { synchronized (mPublicSync) { TetherInterfaceSM sm = mIfaces.get(iface); if (sm == null) { if (VDBG) { Loading @@ -303,7 +321,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public int tether(String iface) { if (DBG) Log.d(TAG, "Tethering " + iface); TetherInterfaceSM sm = null; synchronized (mIfaces) { synchronized (mPublicSync) { sm = mIfaces.get(iface); } if (sm == null) { Loading @@ -321,7 +339,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public int untether(String iface) { if (DBG) Log.d(TAG, "Untethering " + iface); TetherInterfaceSM sm = null; synchronized (mIfaces) { synchronized (mPublicSync) { sm = mIfaces.get(iface); } if (sm == null) { Loading @@ -338,16 +356,19 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public int getLastTetherError(String iface) { TetherInterfaceSM sm = null; synchronized (mIfaces) { synchronized (mPublicSync) { sm = mIfaces.get(iface); } if (sm == null) { Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface + ", ignoring"); Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface + ", ignoring"); return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; } return sm.getLastError(); } } // TODO - move all private methods used only by the state machine into the state machine // to clarify what needs synchronized protection. private void sendTetherStateChangedBroadcast() { try { if (!mConnService.isTetheringSupported()) return; Loading @@ -363,7 +384,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { boolean usbTethered = false; boolean bluetoothTethered = false; synchronized (mIfaces) { synchronized (mPublicSync) { Set ifaces = mIfaces.keySet(); for (Object iface : ifaces) { TetherInterfaceSM sm = mIfaces.get(iface); Loading Loading @@ -469,7 +490,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public void onReceive(Context content, Intent intent) { String action = intent.getAction(); if (action.equals(UsbManager.ACTION_USB_STATE)) { synchronized (Tethering.this) { synchronized (Tethering.this.mPublicSync) { boolean usbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); mRndisEnabled = intent.getBooleanExtra(UsbManager.USB_FUNCTION_RNDIS, false); // start tethering if we have a request pending Loading Loading @@ -545,6 +566,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { return true; } // TODO - return copies so people can't tamper public String[] getTetherableUsbRegexs() { return mTetherableUsbRegexs; } Loading @@ -561,7 +583,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")"); UsbManager usbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE); synchronized (this) { synchronized (mPublicSync) { if (enable) { if (mRndisEnabled) { tetherUsb(true); Loading @@ -581,18 +603,22 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } public int[] getUpstreamIfaceTypes() { int values[]; synchronized (mPublicSync) { updateConfiguration(); int values[] = new int[mUpstreamIfaceTypes.size()]; values = new int[mUpstreamIfaceTypes.size()]; Iterator<Integer> iterator = mUpstreamIfaceTypes.iterator(); for (int i=0; i < mUpstreamIfaceTypes.size(); i++) { values[i] = iterator.next(); } } return values; } public void checkDunRequired() { int secureSetting = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.TETHER_DUN_REQUIRED, 2); synchronized (mPublicSync) { // 2 = not set, 0 = DUN not required, 1 = DUN required if (secureSetting != 2) { int requiredApn = (secureSetting == 1 ? Loading Loading @@ -626,10 +652,12 @@ public class Tethering extends INetworkManagementEventObserver.Stub { mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_HIPRI; } } } // TODO review API - maybe return ArrayList<String> here and below? public String[] getTetheredIfaces() { ArrayList<String> list = new ArrayList<String>(); synchronized (mIfaces) { synchronized (mPublicSync) { Set keys = mIfaces.keySet(); for (Object key : keys) { TetherInterfaceSM sm = mIfaces.get(key); Loading @@ -647,7 +675,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public String[] getTetheredIfacePairs() { final ArrayList<String> list = Lists.newArrayList(); synchronized (mIfaces) { synchronized (mPublicSync) { for (TetherInterfaceSM sm : mIfaces.values()) { if (sm.isTethered()) { list.add(sm.mMyUpstreamIfaceName); Loading @@ -660,7 +688,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public String[] getTetherableIfaces() { ArrayList<String> list = new ArrayList<String>(); synchronized (mIfaces) { synchronized (mPublicSync) { Set keys = mIfaces.keySet(); for (Object key : keys) { TetherInterfaceSM sm = mIfaces.get(key); Loading @@ -678,7 +706,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public String[] getErroredIfaces() { ArrayList<String> list = new ArrayList<String>(); synchronized (mIfaces) { synchronized (mPublicSync) { Set keys = mIfaces.keySet(); for (Object key : keys) { TetherInterfaceSM sm = mIfaces.get(key); Loading Loading @@ -777,11 +805,14 @@ public class Tethering extends INetworkManagementEventObserver.Stub { return res; } public synchronized int getLastError() { public int getLastError() { synchronized (Tethering.this.mPublicSync) { return mLastError; } } private synchronized void setLastError(int error) { private void setLastError(int error) { synchronized (Tethering.this.mPublicSync) { mLastError = error; if (isErrored()) { Loading @@ -792,29 +823,37 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } } } } // synchronized between this getter and the following setter public synchronized boolean isAvailable() { public boolean isAvailable() { synchronized (Tethering.this.mPublicSync) { return mAvailable; } } private synchronized void setAvailable(boolean available) { private void setAvailable(boolean available) { synchronized (Tethering.this.mPublicSync) { mAvailable = available; } } // synchronized between this getter and the following setter public synchronized boolean isTethered() { public boolean isTethered() { synchronized (Tethering.this.mPublicSync) { return mTethered; } } private synchronized void setTethered(boolean tethered) { private void setTethered(boolean tethered) { synchronized (Tethering.this.mPublicSync) { mTethered = tethered; } } // synchronized between this getter and the following setter public synchronized boolean isErrored() { public boolean isErrored() { synchronized (Tethering.this.mPublicSync) { return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR); } } class InitialState extends State { @Override Loading Loading @@ -922,7 +961,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { sendTetherStateChangedBroadcast(); } void cleanupUpstream() { private void cleanupUpstream() { if (mMyUpstreamIfaceName != null) { // note that we don't care about errors here. // sometimes interfaces are gone before we get Loading Loading @@ -1237,6 +1276,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { updateConfiguration(); synchronized (mPublicSync) { if (VDBG) { Log.d(TAG, "chooseUpstreamType has upstream iface types:"); for (Integer netType : mUpstreamIfaceTypes) { Loading @@ -1254,6 +1294,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { break; } } } if (VDBG) { Log.d(TAG, "chooseUpstreamType(" + tryCell + "), preferredApn =" Loading Loading @@ -1479,6 +1520,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { return; } synchronized (mPublicSync) { pw.println("mUpstreamIfaceTypes: "); for (Integer netType : mUpstreamIfaceTypes) { pw.println(" " + netType); Loading @@ -1486,7 +1528,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { pw.println(); pw.println("Tether state:"); synchronized (mIfaces) { for (Object o : mIfaces.values()) { pw.println(" "+o.toString()); } Loading Loading
services/java/com/android/server/connectivity/Tethering.java +172 −131 Original line number Diff line number Diff line Loading @@ -81,6 +81,9 @@ public class Tethering extends INetworkManagementEventObserver.Stub { private String[] mTetherableBluetoothRegexs; private Collection<Integer> mUpstreamIfaceTypes; // used to synchronize public access to members private Object mPublicSync; private static final Integer MOBILE_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE); private static final Integer HIPRI_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE_HIPRI); private static final Integer DUN_TYPE = new Integer(ConnectivityManager.TYPE_MOBILE_DUN); Loading Loading @@ -135,6 +138,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub { mConnService = connService; mLooper = looper; mPublicSync = new Object(); mIfaces = new HashMap<String, TetherInterfaceSM>(); // make our own thread so we don't anr the system Loading Loading @@ -172,18 +177,25 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } void updateConfiguration() { mTetherableUsbRegexs = mContext.getResources().getStringArray( String[] tetherableUsbRegexs = mContext.getResources().getStringArray( com.android.internal.R.array.config_tether_usb_regexs); mTetherableWifiRegexs = mContext.getResources().getStringArray( String[] tetherableWifiRegexs = mContext.getResources().getStringArray( com.android.internal.R.array.config_tether_wifi_regexs); mTetherableBluetoothRegexs = mContext.getResources().getStringArray( String[] tetherableBluetoothRegexs = mContext.getResources().getStringArray( com.android.internal.R.array.config_tether_bluetooth_regexs); int ifaceTypes[] = mContext.getResources().getIntArray( com.android.internal.R.array.config_tether_upstream_types); mUpstreamIfaceTypes = new ArrayList(); Collection<Integer> upstreamIfaceTypes = new ArrayList(); for (int i : ifaceTypes) { mUpstreamIfaceTypes.add(new Integer(i)); upstreamIfaceTypes.add(new Integer(i)); } synchronized (mPublicSync) { mTetherableUsbRegexs = tetherableUsbRegexs; mTetherableWifiRegexs = tetherableWifiRegexs; mTetherableBluetoothRegexs = tetherableBluetoothRegexs; mUpstreamIfaceTypes = upstreamIfaceTypes; } // check if the upstream type list needs to be modified due to secure-settings Loading @@ -194,6 +206,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { if (VDBG) Log.d(TAG, "interfaceStatusChanged " + iface + ", " + up); boolean found = false; boolean usb = false; synchronized (mPublicSync) { if (isWifi(iface)) { found = true; } else if (isUsb(iface)) { Loading @@ -204,7 +217,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } if (found == false) return; synchronized (mIfaces) { TetherInterfaceSM sm = mIfaces.get(iface); if (up) { if (sm == null) { Loading @@ -231,30 +243,37 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } private boolean isUsb(String iface) { synchronized (mPublicSync) { for (String regex : mTetherableUsbRegexs) { if (iface.matches(regex)) return true; } return false; } } public boolean isWifi(String iface) { synchronized (mPublicSync) { for (String regex : mTetherableWifiRegexs) { if (iface.matches(regex)) return true; } return false; } } public boolean isBluetooth(String iface) { synchronized (mPublicSync) { for (String regex : mTetherableBluetoothRegexs) { if (iface.matches(regex)) return true; } return false; } } public void interfaceAdded(String iface) { if (VDBG) Log.d(TAG, "interfaceAdded " + iface); boolean found = false; boolean usb = false; synchronized (mPublicSync) { if (isWifi(iface)) { found = true; } Loading @@ -270,7 +289,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { return; } synchronized (mIfaces) { TetherInterfaceSM sm = mIfaces.get(iface); if (sm != null) { if (VDBG) Log.d(TAG, "active iface (" + iface + ") reported as added, ignoring"); Loading @@ -285,7 +303,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public void interfaceRemoved(String iface) { if (VDBG) Log.d(TAG, "interfaceRemoved " + iface); synchronized (mIfaces) { synchronized (mPublicSync) { TetherInterfaceSM sm = mIfaces.get(iface); if (sm == null) { if (VDBG) { Loading @@ -303,7 +321,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public int tether(String iface) { if (DBG) Log.d(TAG, "Tethering " + iface); TetherInterfaceSM sm = null; synchronized (mIfaces) { synchronized (mPublicSync) { sm = mIfaces.get(iface); } if (sm == null) { Loading @@ -321,7 +339,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public int untether(String iface) { if (DBG) Log.d(TAG, "Untethering " + iface); TetherInterfaceSM sm = null; synchronized (mIfaces) { synchronized (mPublicSync) { sm = mIfaces.get(iface); } if (sm == null) { Loading @@ -338,16 +356,19 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public int getLastTetherError(String iface) { TetherInterfaceSM sm = null; synchronized (mIfaces) { synchronized (mPublicSync) { sm = mIfaces.get(iface); } if (sm == null) { Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface + ", ignoring"); Log.e(TAG, "Tried to getLastTetherError on an unknown iface :" + iface + ", ignoring"); return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE; } return sm.getLastError(); } } // TODO - move all private methods used only by the state machine into the state machine // to clarify what needs synchronized protection. private void sendTetherStateChangedBroadcast() { try { if (!mConnService.isTetheringSupported()) return; Loading @@ -363,7 +384,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { boolean usbTethered = false; boolean bluetoothTethered = false; synchronized (mIfaces) { synchronized (mPublicSync) { Set ifaces = mIfaces.keySet(); for (Object iface : ifaces) { TetherInterfaceSM sm = mIfaces.get(iface); Loading Loading @@ -469,7 +490,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public void onReceive(Context content, Intent intent) { String action = intent.getAction(); if (action.equals(UsbManager.ACTION_USB_STATE)) { synchronized (Tethering.this) { synchronized (Tethering.this.mPublicSync) { boolean usbConnected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); mRndisEnabled = intent.getBooleanExtra(UsbManager.USB_FUNCTION_RNDIS, false); // start tethering if we have a request pending Loading Loading @@ -545,6 +566,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { return true; } // TODO - return copies so people can't tamper public String[] getTetherableUsbRegexs() { return mTetherableUsbRegexs; } Loading @@ -561,7 +583,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { if (VDBG) Log.d(TAG, "setUsbTethering(" + enable + ")"); UsbManager usbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE); synchronized (this) { synchronized (mPublicSync) { if (enable) { if (mRndisEnabled) { tetherUsb(true); Loading @@ -581,18 +603,22 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } public int[] getUpstreamIfaceTypes() { int values[]; synchronized (mPublicSync) { updateConfiguration(); int values[] = new int[mUpstreamIfaceTypes.size()]; values = new int[mUpstreamIfaceTypes.size()]; Iterator<Integer> iterator = mUpstreamIfaceTypes.iterator(); for (int i=0; i < mUpstreamIfaceTypes.size(); i++) { values[i] = iterator.next(); } } return values; } public void checkDunRequired() { int secureSetting = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.TETHER_DUN_REQUIRED, 2); synchronized (mPublicSync) { // 2 = not set, 0 = DUN not required, 1 = DUN required if (secureSetting != 2) { int requiredApn = (secureSetting == 1 ? Loading Loading @@ -626,10 +652,12 @@ public class Tethering extends INetworkManagementEventObserver.Stub { mPreferredUpstreamMobileApn = ConnectivityManager.TYPE_MOBILE_HIPRI; } } } // TODO review API - maybe return ArrayList<String> here and below? public String[] getTetheredIfaces() { ArrayList<String> list = new ArrayList<String>(); synchronized (mIfaces) { synchronized (mPublicSync) { Set keys = mIfaces.keySet(); for (Object key : keys) { TetherInterfaceSM sm = mIfaces.get(key); Loading @@ -647,7 +675,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public String[] getTetheredIfacePairs() { final ArrayList<String> list = Lists.newArrayList(); synchronized (mIfaces) { synchronized (mPublicSync) { for (TetherInterfaceSM sm : mIfaces.values()) { if (sm.isTethered()) { list.add(sm.mMyUpstreamIfaceName); Loading @@ -660,7 +688,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public String[] getTetherableIfaces() { ArrayList<String> list = new ArrayList<String>(); synchronized (mIfaces) { synchronized (mPublicSync) { Set keys = mIfaces.keySet(); for (Object key : keys) { TetherInterfaceSM sm = mIfaces.get(key); Loading @@ -678,7 +706,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { public String[] getErroredIfaces() { ArrayList<String> list = new ArrayList<String>(); synchronized (mIfaces) { synchronized (mPublicSync) { Set keys = mIfaces.keySet(); for (Object key : keys) { TetherInterfaceSM sm = mIfaces.get(key); Loading Loading @@ -777,11 +805,14 @@ public class Tethering extends INetworkManagementEventObserver.Stub { return res; } public synchronized int getLastError() { public int getLastError() { synchronized (Tethering.this.mPublicSync) { return mLastError; } } private synchronized void setLastError(int error) { private void setLastError(int error) { synchronized (Tethering.this.mPublicSync) { mLastError = error; if (isErrored()) { Loading @@ -792,29 +823,37 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } } } } // synchronized between this getter and the following setter public synchronized boolean isAvailable() { public boolean isAvailable() { synchronized (Tethering.this.mPublicSync) { return mAvailable; } } private synchronized void setAvailable(boolean available) { private void setAvailable(boolean available) { synchronized (Tethering.this.mPublicSync) { mAvailable = available; } } // synchronized between this getter and the following setter public synchronized boolean isTethered() { public boolean isTethered() { synchronized (Tethering.this.mPublicSync) { return mTethered; } } private synchronized void setTethered(boolean tethered) { private void setTethered(boolean tethered) { synchronized (Tethering.this.mPublicSync) { mTethered = tethered; } } // synchronized between this getter and the following setter public synchronized boolean isErrored() { public boolean isErrored() { synchronized (Tethering.this.mPublicSync) { return (mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR); } } class InitialState extends State { @Override Loading Loading @@ -922,7 +961,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { sendTetherStateChangedBroadcast(); } void cleanupUpstream() { private void cleanupUpstream() { if (mMyUpstreamIfaceName != null) { // note that we don't care about errors here. // sometimes interfaces are gone before we get Loading Loading @@ -1237,6 +1276,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { updateConfiguration(); synchronized (mPublicSync) { if (VDBG) { Log.d(TAG, "chooseUpstreamType has upstream iface types:"); for (Integer netType : mUpstreamIfaceTypes) { Loading @@ -1254,6 +1294,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { break; } } } if (VDBG) { Log.d(TAG, "chooseUpstreamType(" + tryCell + "), preferredApn =" Loading Loading @@ -1479,6 +1520,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub { return; } synchronized (mPublicSync) { pw.println("mUpstreamIfaceTypes: "); for (Integer netType : mUpstreamIfaceTypes) { pw.println(" " + netType); Loading @@ -1486,7 +1528,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { pw.println(); pw.println("Tether state:"); synchronized (mIfaces) { for (Object o : mIfaces.values()) { pw.println(" "+o.toString()); } Loading