Merge "Fix crash and duplicated ethernet tethering request"
This commit is contained in:
@@ -4456,7 +4456,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 {
|
||||||
|
|||||||
@@ -1440,7 +1440,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 {
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user