Make Tethering.TetherInterfaceSM more self contained

Remove references from the class into the containing class:
  - Move functionality to bring up a USB interface into the class itself.
  - Extract an interface to wrap methods where TetherInterfaceSM was
    calling into other private classes of Tethering
  - Inject necessary dependendencies into TetherInterfaceSM instances.

Bug: 28833951
Test: Compiles.

Change-Id: Ic96947417cf8734072d027b0f1cba8a1a1be7a74
This commit is contained in:
Christopher Wiley
2016-05-18 13:45:20 -07:00
parent a255e7834a
commit 9a509ca728
2 changed files with 110 additions and 67 deletions

View File

@@ -70,6 +70,7 @@ import com.android.internal.util.Protocol;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.server.IoThread;
import com.android.server.connectivity.tethering.IControlsTethering;
import com.android.server.net.BaseNetworkObserver;
import java.io.FileDescriptor;
@@ -92,7 +93,7 @@ import java.util.concurrent.atomic.AtomicInteger;
*
* TODO - look for parent classes and code sharing
*/
public class Tethering extends BaseNetworkObserver {
public class Tethering extends BaseNetworkObserver implements IControlsTethering {
private final Context mContext;
private final static String TAG = "Tethering";
@@ -264,7 +265,8 @@ public class Tethering extends BaseNetworkObserver {
TetherInterfaceSM sm = mIfaces.get(iface);
if (up) {
if (sm == null) {
sm = new TetherInterfaceSM(iface, mLooper, usb, mPublicSync);
sm = new TetherInterfaceSM(iface, mLooper, usb, mPublicSync,
mNMService, mStatsService, this);
mIfaces.put(iface, sm);
sm.start();
}
@@ -339,7 +341,8 @@ public class Tethering extends BaseNetworkObserver {
if (VDBG) Log.d(TAG, "active iface (" + iface + ") reported as added, ignoring");
return;
}
sm = new TetherInterfaceSM(iface, mLooper, usb, mPublicSync);
sm = new TetherInterfaceSM(iface, mLooper, usb, mPublicSync,
mNMService, mStatsService, this);
mIfaces.put(iface, sm);
sm.start();
}
@@ -632,7 +635,8 @@ public class Tethering extends BaseNetworkObserver {
// TODO - move all private methods used only by the state machine into the state machine
// to clarify what needs synchronized protection.
private void sendTetherStateChangedBroadcast() {
@Override
public void sendTetherStateChangedBroadcast() {
if (!getConnectivityManager().isTetheringSupported()) return;
ArrayList<String> availableList = new ArrayList<String>();
@@ -809,44 +813,6 @@ public class Tethering extends BaseNetworkObserver {
Log.e(TAG, "unable start or stop USB tethering");
}
// configured when we start tethering and unconfig'd on error or conclusion
private boolean configureUsbIface(boolean enabled) {
if (VDBG) Log.d(TAG, "configureUsbIface(" + enabled + ")");
// toggle the USB interfaces
String[] ifaces = new String[0];
try {
ifaces = mNMService.listInterfaces();
} catch (Exception e) {
Log.e(TAG, "Error listing Interfaces", e);
return false;
}
for (String iface : ifaces) {
if (isUsb(iface)) {
InterfaceConfiguration ifcg = null;
try {
ifcg = mNMService.getInterfaceConfig(iface);
if (ifcg != null) {
InetAddress addr = NetworkUtils.numericToInetAddress(USB_NEAR_IFACE_ADDR);
ifcg.setLinkAddress(new LinkAddress(addr, USB_PREFIX_LENGTH));
if (enabled) {
ifcg.setInterfaceUp();
} else {
ifcg.setInterfaceDown();
}
ifcg.clearFlag("running");
mNMService.setInterfaceConfig(iface, ifcg);
}
} catch (Exception e) {
Log.e(TAG, "Error configuring interface " + iface, e);
return false;
}
}
}
return true;
}
// TODO - return copies so people can't tamper
public String[] getTetherableUsbRegexs() {
return mTetherableUsbRegexs;
@@ -1014,7 +980,12 @@ public class Tethering extends BaseNetworkObserver {
}
}
class TetherInterfaceSM extends StateMachine {
/**
* @hide
*
* Tracks the eligibility of a given network interface for tethering.
*/
public static class TetherInterfaceSM extends StateMachine {
private static final int BASE_IFACE = Protocol.BASE_TETHERING + 100;
// notification from the master SM that it's not in tether mode
static final int CMD_TETHER_MODE_DEAD = BASE_IFACE + 1;
@@ -1046,6 +1017,10 @@ public class Tethering extends BaseNetworkObserver {
private final State mTetheredState;
private final State mUnavailableState;
private final INetworkManagementService mNMService;
private final INetworkStatsService mStatsService;
private final IControlsTethering mTetherController;
private final boolean mUsb;
private final String mIfaceName;
@@ -1055,12 +1030,17 @@ public class Tethering extends BaseNetworkObserver {
private int mLastError;
private String mMyUpstreamIfaceName; // may change over time
TetherInterfaceSM(String name, Looper looper, boolean usb, Object mutex) {
super(name, looper);
mIfaceName = name;
TetherInterfaceSM(String ifaceName, Looper looper, boolean usb, Object mutex,
INetworkManagementService nMService, INetworkStatsService statsService,
IControlsTethering tetherController) {
super(ifaceName, looper);
mNMService = nMService;
mStatsService = statsService;
mTetherController = tetherController;
mIfaceName = ifaceName;
mUsb = usb;
setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR);
mMutex = mutex;
setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR);
mInitialState = new InitialState();
addState(mInitialState);
@@ -1103,7 +1083,7 @@ public class Tethering extends BaseNetworkObserver {
if (mUsb) {
// note everything's been unwound by this point so nothing to do on
// further error..
Tethering.this.configureUsbIface(false);
configureUsbIface(false, mIfaceName);
}
}
}
@@ -1139,12 +1119,45 @@ public class Tethering extends BaseNetworkObserver {
}
}
// configured when we start tethering and unconfig'd on error or conclusion
private boolean configureUsbIface(boolean enabled, String iface) {
if (VDBG) Log.d(TAG, "configureUsbIface(" + enabled + ")");
InterfaceConfiguration ifcg = null;
try {
ifcg = mNMService.getInterfaceConfig(iface);
if (ifcg != null) {
InetAddress addr = NetworkUtils.numericToInetAddress(USB_NEAR_IFACE_ADDR);
ifcg.setLinkAddress(new LinkAddress(addr, USB_PREFIX_LENGTH));
if (enabled) {
ifcg.setInterfaceUp();
} else {
ifcg.setInterfaceDown();
}
ifcg.clearFlag("running");
mNMService.setInterfaceConfig(iface, ifcg);
}
} catch (Exception e) {
Log.e(TAG, "Error configuring interface " + iface, e);
return false;
}
return true;
}
private void maybeLogMessage(State state, int what) {
if (DBG) {
Log.d(TAG, state.getName() + " got " +
sMagicDecoderRing.get(what, Integer.toString(what)));
}
}
class InitialState extends State {
@Override
public void enter() {
setAvailable(true);
setTethered(false);
sendTetherStateChangedBroadcast();
mTetherController.sendTetherStateChangedBroadcast();
}
@Override
@@ -1154,8 +1167,7 @@ public class Tethering extends BaseNetworkObserver {
switch (message.what) {
case CMD_TETHER_REQUESTED:
setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR);
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_REQUESTED,
TetherInterfaceSM.this);
mTetherController.notifyInterfaceTetheringReadiness(true, TetherInterfaceSM.this);
transitionTo(mStartingState);
break;
case CMD_INTERFACE_DOWN:
@@ -1174,16 +1186,15 @@ public class Tethering extends BaseNetworkObserver {
public void enter() {
setAvailable(false);
if (mUsb) {
if (!Tethering.this.configureUsbIface(true)) {
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED,
TetherInterfaceSM.this);
if (!configureUsbIface(true, mIfaceName)) {
mTetherController.notifyInterfaceTetheringReadiness(false, TetherInterfaceSM.this);
setLastError(ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR);
transitionTo(mInitialState);
return;
}
}
sendTetherStateChangedBroadcast();
mTetherController.sendTetherStateChangedBroadcast();
// Skipping StartingState
transitionTo(mTetheredState);
@@ -1195,10 +1206,9 @@ public class Tethering extends BaseNetworkObserver {
switch (message.what) {
// maybe a parent class?
case CMD_TETHER_UNREQUESTED:
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED,
TetherInterfaceSM.this);
mTetherController.notifyInterfaceTetheringReadiness(false, TetherInterfaceSM.this);
if (mUsb) {
if (!Tethering.this.configureUsbIface(false)) {
if (!configureUsbIface(false, mIfaceName)) {
setLastErrorAndTransitionToInitialState(
ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR);
break;
@@ -1216,8 +1226,7 @@ public class Tethering extends BaseNetworkObserver {
ConnectivityManager.TETHER_ERROR_MASTER_ERROR);
break;
case CMD_INTERFACE_DOWN:
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED,
TetherInterfaceSM.this);
mTetherController.notifyInterfaceTetheringReadiness(false, TetherInterfaceSM.this);
transitionTo(mUnavailableState);
break;
default:
@@ -1247,7 +1256,7 @@ public class Tethering extends BaseNetworkObserver {
if (DBG) Log.d(TAG, "Tethered " + mIfaceName);
setAvailable(false);
setTethered(true);
sendTetherStateChangedBroadcast();
mTetherController.sendTetherStateChangedBroadcast();
}
private void cleanupUpstream() {
@@ -1294,11 +1303,10 @@ public class Tethering extends BaseNetworkObserver {
ConnectivityManager.TETHER_ERROR_UNTETHER_IFACE_ERROR);
break;
}
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED,
TetherInterfaceSM.this);
mTetherController.notifyInterfaceTetheringReadiness(false, TetherInterfaceSM.this);
if (message.what == CMD_TETHER_UNREQUESTED) {
if (mUsb) {
if (!Tethering.this.configureUsbIface(false)) {
if (!configureUsbIface(false, mIfaceName)) {
setLastError(
ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR);
}
@@ -1362,9 +1370,9 @@ public class Tethering extends BaseNetworkObserver {
break;
}
if (DBG) Log.d(TAG, "Tether lost upstream connection " + mIfaceName);
sendTetherStateChangedBroadcast();
mTetherController.sendTetherStateChangedBroadcast();
if (mUsb) {
if (!Tethering.this.configureUsbIface(false)) {
if (!configureUsbIface(false, mIfaceName)) {
setLastError(ConnectivityManager.TETHER_ERROR_IFACE_CFG_ERROR);
}
}
@@ -1384,7 +1392,7 @@ public class Tethering extends BaseNetworkObserver {
setAvailable(false);
setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR);
setTethered(false);
sendTetherStateChangedBroadcast();
mTetherController.sendTetherStateChangedBroadcast();
}
@Override
public boolean processMessage(Message message) {
@@ -2104,4 +2112,10 @@ public class Tethering extends BaseNetworkObserver {
}
pw.decreaseIndent();
}
@Override
public void notifyInterfaceTetheringReadiness(boolean isReady, TetherInterfaceSM who) {
mTetherMasterSM.sendMessage((isReady) ? TetherMasterSM.CMD_TETHER_MODE_REQUESTED
: TetherMasterSM.CMD_TETHER_MODE_UNREQUESTED, who);
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.connectivity.tethering;
import com.android.server.connectivity.Tethering;
/**
* @hide
*
* Interface with methods necessary to notify that a given interface is ready for tethering.
*/
public interface IControlsTethering {
void sendTetherStateChangedBroadcast();
void notifyInterfaceTetheringReadiness(boolean isReady, Tethering.TetherInterfaceSM who);
}