Merge "Support registration of offload control callbacks."
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index ee89d57..f212c80 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -52,6 +52,7 @@
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Handler;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
@@ -195,8 +196,10 @@
mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper);
mTetherMasterSM.start();
- mOffloadController = new OffloadController(mTetherMasterSM.getHandler(),
- deps.getOffloadHardwareInterface(), mLog);
+ final Handler smHandler = mTetherMasterSM.getHandler();
+ mOffloadController = new OffloadController(smHandler,
+ deps.getOffloadHardwareInterface(smHandler, mLog),
+ mLog);
mUpstreamNetworkMonitor = new UpstreamNetworkMonitor(
mContext, mTetherMasterSM, TetherMasterSM.EVENT_UPSTREAM_CALLBACK, mLog);
mForwardedDownstreams = new HashSet<>();
@@ -1083,7 +1086,6 @@
TetherMasterSM(String name, Looper looper) {
super(name, looper);
- //Add states
mInitialState = new InitialState();
mTetherModeAliveState = new TetherModeAliveState();
mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState();
@@ -1397,10 +1399,11 @@
mSimChange.startListening();
mUpstreamNetworkMonitor.start();
- mOffloadController.start();
+ // TODO: De-duplicate with updateUpstreamWanted() below.
if (upstreamWanted()) {
mUpstreamWanted = true;
+ mOffloadController.start();
chooseUpstreamType(true);
mTryCell = false;
}
@@ -1419,6 +1422,13 @@
private boolean updateUpstreamWanted() {
final boolean previousUpstreamWanted = mUpstreamWanted;
mUpstreamWanted = upstreamWanted();
+ if (mUpstreamWanted != previousUpstreamWanted) {
+ if (mUpstreamWanted) {
+ mOffloadController.start();
+ } else {
+ mOffloadController.stop();
+ }
+ }
return previousUpstreamWanted;
}
diff --git a/services/core/java/com/android/server/connectivity/tethering/OffloadController.java b/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
index ec7ab5b..12899d8 100644
--- a/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
+++ b/services/core/java/com/android/server/connectivity/tethering/OffloadController.java
@@ -49,12 +49,30 @@
mConfigInitialized = mHwInterface.initOffloadConfig();
if (!mConfigInitialized) {
mLog.i("tethering offload config not supported");
+ stop();
return;
}
}
- // TODO: Create and register ITetheringOffloadCallback.
- mControlInitialized = mHwInterface.initOffloadControl();
+ mControlInitialized = mHwInterface.initOffloadControl(
+ new OffloadHardwareInterface.ControlCallback() {
+ @Override
+ public void onOffloadEvent(int event) {
+ mLog.log("got offload event: " + event);
+ }
+
+ @Override
+ public void onNatTimeoutUpdate(int proto,
+ String srcAddr, int srcPort,
+ String dstAddr, int dstPort) {
+ mLog.log(String.format("NAT timeout update: %s (%s,%s) -> (%s,%s)",
+ proto, srcAddr, srcPort, dstAddr, dstPort));
+ }
+ });
+ if (!mControlInitialized) {
+ mLog.i("tethering offload control not supported");
+ stop();
+ }
}
public void stop() {
diff --git a/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java b/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
index 87fc491..0429ab3 100644
--- a/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
+++ b/services/core/java/com/android/server/connectivity/tethering/OffloadHardwareInterface.java
@@ -17,9 +17,11 @@
package com.android.server.connectivity.tethering;
import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
-import android.hardware.tetheroffload.control.V1_0.IOffloadControl.stopOffloadCallback;
+import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;
+import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
+import android.os.Handler;
import android.os.RemoteException;
-import android.util.Log;
+import android.net.util.SharedLog;
/**
@@ -32,46 +34,102 @@
private static native boolean configOffload();
+ private final Handler mHandler;
+ private final SharedLog mLog;
private IOffloadControl mOffloadControl;
+ private TetheringOffloadCallback mTetheringOffloadCallback;
+ private ControlCallback mControlCallback;
- public OffloadHardwareInterface() {}
+ public static class ControlCallback {
+ public void onOffloadEvent(int event) {}
+
+ public void onNatTimeoutUpdate(int proto,
+ String srcAddr, int srcPort,
+ String dstAddr, int dstPort) {}
+ }
+
+ public OffloadHardwareInterface(Handler h, SharedLog log) {
+ mHandler = h;
+ mLog = log.forSubComponent(TAG);
+ }
public boolean initOffloadConfig() {
return configOffload();
}
- // TODO: Extend this to take a TetheringControlCallback for registration.
- public boolean initOffloadControl() {
+ public boolean initOffloadControl(ControlCallback controlCb) {
+ mControlCallback = controlCb;
+
if (mOffloadControl == null) {
try {
mOffloadControl = IOffloadControl.getService();
} catch (RemoteException e) {
- Log.d(TAG, "tethering offload control not supported: " + e);
+ mLog.e("tethering offload control not supported: " + e);
return false;
}
}
- // TODO: call mOffloadControl.initOffload(...callback...);
+ mTetheringOffloadCallback = new TetheringOffloadCallback(mHandler, mControlCallback);
+ final CbResults results = new CbResults();
+ try {
+ mOffloadControl.initOffload(
+ mTetheringOffloadCallback,
+ (boolean success, String errMsg) -> {
+ results.success = success;
+ results.errMsg = errMsg;
+ });
+ } catch (RemoteException e) {
+ mLog.e("failed to initOffload: " + e);
+ return false;
+ }
- return true;
+ if (!results.success) mLog.e("initOffload failed: " + results.errMsg);
+ return results.success;
}
public void stopOffloadControl() {
- if (mOffloadControl == null) return;
-
- try {
- final stopOffloadCallback cb = new stopOffloadCallback() {
- @Override
- public void onValues(boolean success, String errMsg) {
- if (success) return;
-
- Log.e(TAG, "stopOffload failed: " + errMsg);
- }
- };
- mOffloadControl.stopOffload(cb);
- } catch (RemoteException e) {
- Log.d(TAG, "failed to stopOffload: " + e);
+ if (mOffloadControl != null) {
+ try {
+ mOffloadControl.stopOffload(
+ (boolean success, String errMsg) -> {
+ if (!success) mLog.e("stopOffload failed: " + errMsg);
+ });
+ } catch (RemoteException e) {
+ mLog.e("failed to stopOffload: " + e);
+ }
}
mOffloadControl = null;
+ mTetheringOffloadCallback = null;
+ mControlCallback = null;
+ }
+
+ private static class TetheringOffloadCallback extends ITetheringOffloadCallback.Stub {
+ public final Handler handler;
+ public final ControlCallback controlCb;
+
+ public TetheringOffloadCallback(Handler h, ControlCallback cb) {
+ handler = h;
+ controlCb = cb;
+ }
+
+ @Override
+ public void onEvent(int event) {
+ handler.post(() -> { controlCb.onOffloadEvent(event); });
+ }
+
+ @Override
+ public void updateTimeout(NatTimeoutUpdate params) {
+ handler.post(() -> {
+ controlCb.onNatTimeoutUpdate(
+ params.proto,
+ params.src.addr, params.src.port,
+ params.dst.addr, params.dst.port);
+ });
+ }
+ }
+
+ private static class CbResults {
+ boolean success;
+ String errMsg;
}
}
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
index be2cf08..b8174b6 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java
@@ -16,6 +16,9 @@
package com.android.server.connectivity.tethering;
+import android.os.Handler;
+import android.net.util.SharedLog;
+
/**
* Capture tethering dependencies, for injection.
@@ -23,7 +26,7 @@
* @hide
*/
public class TetheringDependencies {
- public OffloadHardwareInterface getOffloadHardwareInterface() {
- return new OffloadHardwareInterface();
+ public OffloadHardwareInterface getOffloadHardwareInterface(Handler h, SharedLog log) {
+ return new OffloadHardwareInterface(h, log);
}
}
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index bc89c0f..d5a0b86 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -43,6 +43,7 @@
import android.net.INetworkStatsService;
import android.net.InterfaceConfiguration;
import android.net.NetworkRequest;
+import android.net.util.SharedLog;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Handler;
@@ -142,8 +143,8 @@
};
mServiceContext.registerReceiver(mBroadcastReceiver,
new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
- when(mTetheringDependencies.getOffloadHardwareInterface())
- .thenReturn(mOffloadHardwareInterface);
+ when(mTetheringDependencies.getOffloadHardwareInterface(
+ any(Handler.class), any(SharedLog.class))).thenReturn(mOffloadHardwareInterface);
mTethering = new Tethering(mServiceContext, mNMService, mStatsService, mPolicyManager,
mLooper.getLooper(), mSystemProperties,
mTetheringDependencies);