From f4b6e34fc093d0e493bc97e91b71d753720f7114 Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Tue, 25 Apr 2017 19:19:59 +0900 Subject: [PATCH] Support registration of offload control callbacks. Test: as follows - built - flashed - booted - runtest frameworks-net passes Bug: 29337859 Bug: 32163131 Bug: 34361337 Change-Id: I054cdf6a277c77e4cbf5c81145446a9be1c5fe39 --- .../server/connectivity/Tethering.java | 18 +++- .../tethering/OffloadController.java | 22 +++- .../tethering/OffloadHardwareInterface.java | 102 ++++++++++++++---- .../tethering/TetheringDependencies.java | 7 +- .../server/connectivity/TetheringTest.java | 5 +- 5 files changed, 122 insertions(+), 32 deletions(-) diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index ee89d57ac68ea..f212c808fca1e 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.util.SharedLog; 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 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering 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 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering TetherMasterSM(String name, Looper looper) { super(name, looper); - //Add states mInitialState = new InitialState(); mTetherModeAliveState = new TetherModeAliveState(); mSetIpForwardingEnabledErrorState = new SetIpForwardingEnabledErrorState(); @@ -1397,10 +1399,11 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering 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 @@ public class Tethering extends BaseNetworkObserver implements IControlsTethering 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 ec7ab5bd5f1a6..12899d803ca43 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 @@ public class OffloadController { 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 87fc491b0bddd..0429ab3dca923 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 @@ public class OffloadHardwareInterface { 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 be2cf080b3303..b8174b6c8d2bc 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 @@ package com.android.server.connectivity.tethering; * @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 bc89c0f4f71f1..d5a0b864583a8 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.INetworkPolicyManager; 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 @@ public class TetheringTest { }; 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);