Merge "Fix crash and duplicated ethernet tethering request" into rvc-dev am: 02ee003aa5

Change-Id: I9b3630bde9a8409811f68a36392677b3c93814d8
This commit is contained in:
Automerger Merge Worker
2020-03-09 08:21:05 +00:00
5 changed files with 42 additions and 15 deletions

View File

@@ -6128,7 +6128,7 @@ package android.net {
} }
public class EthernetManager { public class EthernetManager {
method @NonNull public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull android.net.EthernetManager.TetheredInterfaceCallback); method @NonNull public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.TetheredInterfaceCallback);
} }
public static interface EthernetManager.TetheredInterfaceCallback { public static interface EthernetManager.TetheredInterfaceCallback {

View File

@@ -1727,7 +1727,7 @@ package android.net {
} }
public class EthernetManager { public class EthernetManager {
method @NonNull public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull android.net.EthernetManager.TetheredInterfaceCallback); method @NonNull public android.net.EthernetManager.TetheredInterfaceRequest requestTetheredInterface(@NonNull java.util.concurrent.Executor, @NonNull android.net.EthernetManager.TetheredInterfaceCallback);
} }
public static interface EthernetManager.TetheredInterfaceCallback { public static interface EthernetManager.TetheredInterfaceCallback {

View File

@@ -28,6 +28,7 @@ import android.os.RemoteException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.Executor;
/** /**
* A class representing the IP configuration of the Ethernet network. * A class representing the IP configuration of the Ethernet network.
@@ -248,18 +249,19 @@ public class EthernetManager {
* @param callback A callback to be called once the request has been fulfilled. * @param callback A callback to be called once the request has been fulfilled.
*/ */
@NonNull @NonNull
public TetheredInterfaceRequest requestTetheredInterface( public TetheredInterfaceRequest requestTetheredInterface(@NonNull final Executor executor,
@NonNull TetheredInterfaceCallback callback) { @NonNull final TetheredInterfaceCallback callback) {
Objects.requireNonNull(callback, "Callback must be non-null"); Objects.requireNonNull(callback, "Callback must be non-null");
Objects.requireNonNull(executor, "Executor must be non-null");
final ITetheredInterfaceCallback cbInternal = new ITetheredInterfaceCallback.Stub() { final ITetheredInterfaceCallback cbInternal = new ITetheredInterfaceCallback.Stub() {
@Override @Override
public void onAvailable(String iface) { public void onAvailable(String iface) {
callback.onAvailable(iface); executor.execute(() -> callback.onAvailable(iface));
} }
@Override @Override
public void onUnavailable() { public void onUnavailable() {
callback.onUnavailable(); executor.execute(() -> callback.onUnavailable());
} }
}; };

View File

@@ -220,6 +220,7 @@ public class Tethering {
private final UserRestrictionActionListener mTetheringRestriction; private final UserRestrictionActionListener mTetheringRestriction;
private final ActiveDataSubIdListener mActiveDataSubIdListener; private final ActiveDataSubIdListener mActiveDataSubIdListener;
private final ConnectedClientsTracker mConnectedClientsTracker; private final ConnectedClientsTracker mConnectedClientsTracker;
private final TetheringThreadExecutor mExecutor;
private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID;
// All the usage of mTetheringEventCallback should run in the same thread. // All the usage of mTetheringEventCallback should run in the same thread.
private ITetheringEventCallback mTetheringEventCallback = null; private ITetheringEventCallback mTetheringEventCallback = null;
@@ -296,8 +297,8 @@ public class Tethering {
final UserManager userManager = (UserManager) mContext.getSystemService( final UserManager userManager = (UserManager) mContext.getSystemService(
Context.USER_SERVICE); Context.USER_SERVICE);
mTetheringRestriction = new UserRestrictionActionListener(userManager, this); mTetheringRestriction = new UserRestrictionActionListener(userManager, this);
final TetheringThreadExecutor executor = new TetheringThreadExecutor(mHandler); mExecutor = new TetheringThreadExecutor(mHandler);
mActiveDataSubIdListener = new ActiveDataSubIdListener(executor); mActiveDataSubIdListener = new ActiveDataSubIdListener(mExecutor);
// Load tethering configuration. // Load tethering configuration.
updateConfiguration(); updateConfiguration();
@@ -315,9 +316,7 @@ public class Tethering {
final WifiManager wifiManager = getWifiManager(); final WifiManager wifiManager = getWifiManager();
if (wifiManager != null) { if (wifiManager != null) {
wifiManager.registerSoftApCallback( wifiManager.registerSoftApCallback(mExecutor, new TetheringSoftApCallback());
mHandler::post /* executor */,
new TetheringSoftApCallback());
} }
} }
@@ -606,14 +605,17 @@ public class Tethering {
Context.ETHERNET_SERVICE); Context.ETHERNET_SERVICE);
synchronized (mPublicSync) { synchronized (mPublicSync) {
if (enable) { if (enable) {
if (mEthernetCallback != null) return TETHER_ERROR_NO_ERROR;
mEthernetCallback = new EthernetCallback(); mEthernetCallback = new EthernetCallback();
mEthernetIfaceRequest = em.requestTetheredInterface(mEthernetCallback); mEthernetIfaceRequest = em.requestTetheredInterface(mExecutor, mEthernetCallback);
} else { } else {
if (mConfiguredEthernetIface != null) { stopEthernetTetheringLocked();
stopEthernetTetheringLocked(); if (mEthernetCallback != null) {
mEthernetIfaceRequest.release(); mEthernetIfaceRequest.release();
mEthernetCallback = null;
mEthernetIfaceRequest = null;
} }
mEthernetCallback = null;
} }
} }
return TETHER_ERROR_NO_ERROR; return TETHER_ERROR_NO_ERROR;

View File

@@ -28,6 +28,7 @@ import static android.net.TetheringManager.ACTION_TETHER_STATE_CHANGED;
import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY; import static android.net.TetheringManager.EXTRA_ACTIVE_LOCAL_ONLY;
import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER; import static android.net.TetheringManager.EXTRA_ACTIVE_TETHER;
import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER; import static android.net.TetheringManager.EXTRA_AVAILABLE_TETHER;
import static android.net.TetheringManager.TETHERING_ETHERNET;
import static android.net.TetheringManager.TETHERING_NCM; import static android.net.TetheringManager.TETHERING_NCM;
import static android.net.TetheringManager.TETHERING_USB; import static android.net.TetheringManager.TETHERING_USB;
import static android.net.TetheringManager.TETHERING_WIFI; import static android.net.TetheringManager.TETHERING_WIFI;
@@ -75,6 +76,8 @@ import android.content.pm.ApplicationInfo;
import android.content.res.Resources; import android.content.res.Resources;
import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.EthernetManager;
import android.net.EthernetManager.TetheredInterfaceRequest;
import android.net.INetd; import android.net.INetd;
import android.net.ITetheringEventCallback; import android.net.ITetheringEventCallback;
import android.net.InetAddresses; import android.net.InetAddresses;
@@ -180,6 +183,7 @@ public class TetheringTest {
@Mock private UserManager mUserManager; @Mock private UserManager mUserManager;
@Mock private NetworkRequest mNetworkRequest; @Mock private NetworkRequest mNetworkRequest;
@Mock private ConnectivityManager mCm; @Mock private ConnectivityManager mCm;
@Mock private EthernetManager mEm;
private final MockIpServerDependencies mIpServerDependencies = private final MockIpServerDependencies mIpServerDependencies =
spy(new MockIpServerDependencies()); spy(new MockIpServerDependencies());
@@ -232,6 +236,7 @@ public class TetheringTest {
if (Context.USER_SERVICE.equals(name)) return mUserManager; if (Context.USER_SERVICE.equals(name)) return mUserManager;
if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager; if (Context.NETWORK_STATS_SERVICE.equals(name)) return mStatsManager;
if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm; if (Context.CONNECTIVITY_SERVICE.equals(name)) return mCm;
if (Context.ETHERNET_SERVICE.equals(name)) return mEm;
return super.getSystemService(name); return super.getSystemService(name);
} }
@@ -1316,6 +1321,24 @@ public class TetheringTest {
assertEquals(fakeSubId, newConfig.activeDataSubId); assertEquals(fakeSubId, newConfig.activeDataSubId);
} }
@Test
public void testNoDuplicatedEthernetRequest() throws Exception {
final TetheredInterfaceRequest mockRequest = mock(TetheredInterfaceRequest.class);
when(mEm.requestTetheredInterface(any(), any())).thenReturn(mockRequest);
mTethering.startTethering(createTetheringRquestParcel(TETHERING_ETHERNET), null);
mLooper.dispatchAll();
verify(mEm, times(1)).requestTetheredInterface(any(), any());
mTethering.startTethering(createTetheringRquestParcel(TETHERING_ETHERNET), null);
mLooper.dispatchAll();
verifyNoMoreInteractions(mEm);
mTethering.stopTethering(TETHERING_ETHERNET);
mLooper.dispatchAll();
verify(mockRequest, times(1)).release();
mTethering.stopTethering(TETHERING_ETHERNET);
mLooper.dispatchAll();
verifyNoMoreInteractions(mEm);
}
private void workingWifiP2pGroupOwner( private void workingWifiP2pGroupOwner(
boolean emulateInterfaceStatusChanged) throws Exception { boolean emulateInterfaceStatusChanged) throws Exception {
if (emulateInterfaceStatusChanged) { if (emulateInterfaceStatusChanged) {