Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62ea8f72 authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN
Browse files

Use NetworkStack.getService in NetworkStackClient

This avoids returning IBinder in Context.getSystemService, having a
dedicated getter for the NetworkStack AIDL interface instead.

Test: atest FrameworksNetTests NetworkStackTests
Bug: 151243982
Change-Id: Ibeaeff5890631e14581a084863d9aeb3178c5d5c
parent aa561db2
Loading
Loading
Loading
Loading
+8 −11
Original line number Original line Diff line number Diff line
@@ -16,12 +16,12 @@


package android.net.networkstack;
package android.net.networkstack;


import static android.content.Context.NETWORK_STACK_SERVICE;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION.SDK_INT;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.content.Context;
import android.content.Context;
import android.net.INetworkStackConnector;
import android.net.INetworkStackConnector;
import android.net.NetworkStack;
import android.os.Build;
import android.os.Build;
import android.os.IBinder;
import android.os.IBinder;
import android.util.Log;
import android.util.Log;
@@ -47,14 +47,14 @@ public class ModuleNetworkStackClient extends NetworkStackClientBase {
        // TODO(b/149676685): change this check to "< R" once R is defined
        // TODO(b/149676685): change this check to "< R" once R is defined
        if (SDK_INT < Build.VERSION_CODES.Q
        if (SDK_INT < Build.VERSION_CODES.Q
                || (SDK_INT == Build.VERSION_CODES.Q && "REL".equals(Build.VERSION.CODENAME))) {
                || (SDK_INT == Build.VERSION_CODES.Q && "REL".equals(Build.VERSION.CODENAME))) {
            // NETWORK_STACK_SERVICE is not available through getSystemService before R
            // The NetworkStack connector is not available through NetworkStack before R
            throw new UnsupportedOperationException(
            throw new UnsupportedOperationException(
                    "ModuleNetworkStackClient is not supported on API " + SDK_INT);
                    "ModuleNetworkStackClient is not supported on API " + SDK_INT);
        }
        }


        if (sInstance == null) {
        if (sInstance == null) {
            sInstance = new ModuleNetworkStackClient();
            sInstance = new ModuleNetworkStackClient();
            sInstance.startPolling(packageContext);
            sInstance.startPolling();
        }
        }
        return sInstance;
        return sInstance;
    }
    }
@@ -64,10 +64,10 @@ public class ModuleNetworkStackClient extends NetworkStackClientBase {
        sInstance = null;
        sInstance = null;
    }
    }


    private void startPolling(Context context) {
    private void startPolling() {
        // If the service is already registered (as it will be most of the time), do not poll and
        // If the service is already registered (as it will be most of the time), do not poll and
        // fulfill requests immediately.
        // fulfill requests immediately.
        final IBinder nss = (IBinder) context.getSystemService(NETWORK_STACK_SERVICE);
        final IBinder nss = NetworkStack.getService();
        if (nss != null) {
        if (nss != null) {
            // Calling onNetworkStackConnected here means that pending oneway Binder calls to the
            // Calling onNetworkStackConnected here means that pending oneway Binder calls to the
            // NetworkStack get sent from the current thread and not a worker thread; this is fine
            // NetworkStack get sent from the current thread and not a worker thread; this is fine
@@ -75,21 +75,18 @@ public class ModuleNetworkStackClient extends NetworkStackClientBase {
            onNetworkStackConnected(INetworkStackConnector.Stub.asInterface(nss));
            onNetworkStackConnected(INetworkStackConnector.Stub.asInterface(nss));
            return;
            return;
        }
        }
        new Thread(new PollingRunner(context)).start();
        new Thread(new PollingRunner()).start();
    }
    }


    private class PollingRunner implements Runnable {
    private class PollingRunner implements Runnable {
        private final Context mContext;


        private PollingRunner(Context context) {
        private PollingRunner() {}
            mContext = context;
        }


        @Override
        @Override
        public void run() {
        public void run() {
            // Block until the NetworkStack connector is registered in ServiceManager.
            // Block until the NetworkStack connector is registered in ServiceManager.
            IBinder nss;
            IBinder nss;
            while ((nss = (IBinder) mContext.getSystemService(NETWORK_STACK_SERVICE)) == null) {
            while ((nss = NetworkStack.getService()) == null) {
                try {
                try {
                    Thread.sleep(200);
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                } catch (InterruptedException e) {
+13 −6
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import android.net.IIpMemoryStoreCallbacks
import android.net.INetworkMonitorCallbacks
import android.net.INetworkMonitorCallbacks
import android.net.INetworkStackConnector
import android.net.INetworkStackConnector
import android.net.Network
import android.net.Network
import android.net.NetworkStack
import android.net.dhcp.DhcpServingParamsParcel
import android.net.dhcp.DhcpServingParamsParcel
import android.net.dhcp.IDhcpServerCallbacks
import android.net.dhcp.IDhcpServerCallbacks
import android.net.ip.IIpClientCallbacks
import android.net.ip.IIpClientCallbacks
@@ -28,6 +29,8 @@ import android.os.Build
import android.os.IBinder
import android.os.IBinder
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.networkstack.apishim.ShimUtils
import com.android.networkstack.apishim.ShimUtils
import org.junit.After
import org.junit.After
import org.junit.Assume.assumeTrue
import org.junit.Assume.assumeTrue
@@ -36,11 +39,11 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.any
import org.mockito.Mock
import org.mockito.Mock
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.never
import org.mockito.Mockito.never
import org.mockito.Mockito.timeout
import org.mockito.Mockito.timeout
import org.mockito.Mockito.verify
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import org.mockito.MockitoAnnotations
import org.mockito.MockitoSession


@RunWith(AndroidJUnit4::class)
@RunWith(AndroidJUnit4::class)
@SmallTest
@SmallTest
@@ -49,6 +52,8 @@ class ModuleNetworkStackClientTest {
    private val TEST_NETWORK = Network(43)
    private val TEST_NETWORK = Network(43)
    private val TEST_TIMEOUT_MS = 500L
    private val TEST_TIMEOUT_MS = 500L


    private var mSession: MockitoSession? = null

    @Mock
    @Mock
    private lateinit var mContext: Context
    private lateinit var mContext: Context
    @Mock
    @Mock
@@ -68,6 +73,7 @@ class ModuleNetworkStackClientTest {
    fun setUp() {
    fun setUp() {
        // ModuleNetworkStackClient is only available after Q
        // ModuleNetworkStackClient is only available after Q
        assumeTrue(ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q))
        assumeTrue(ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q))
        mSession = mockitoSession().spyStatic(NetworkStack::class.java).startMocking()
        MockitoAnnotations.initMocks(this)
        MockitoAnnotations.initMocks(this)
        doReturn(mConnector).`when`(mConnectorBinder).queryLocalInterface(
        doReturn(mConnector).`when`(mConnectorBinder).queryLocalInterface(
                INetworkStackConnector::class.qualifiedName!!)
                INetworkStackConnector::class.qualifiedName!!)
@@ -75,12 +81,13 @@ class ModuleNetworkStackClientTest {


    @After
    @After
    fun tearDown() {
    fun tearDown() {
        mSession?.finishMocking()
        ModuleNetworkStackClient.resetInstanceForTest()
        ModuleNetworkStackClient.resetInstanceForTest()
    }
    }


    @Test
    @Test
    fun testIpClientServiceAvailableImmediately() {
    fun testIpClientServiceAvailableImmediately() {
        doReturn(mConnectorBinder).`when`(mContext).getSystemService(Context.NETWORK_STACK_SERVICE)
        doReturn(mConnectorBinder).`when` { NetworkStack.getService() }
        ModuleNetworkStackClient.getInstance(mContext).makeIpClient(TEST_IFNAME, mIpClientCb)
        ModuleNetworkStackClient.getInstance(mContext).makeIpClient(TEST_IFNAME, mIpClientCb)
        verify(mConnector).makeIpClient(TEST_IFNAME, mIpClientCb)
        verify(mConnector).makeIpClient(TEST_IFNAME, mIpClientCb)
    }
    }
@@ -91,14 +98,14 @@ class ModuleNetworkStackClientTest {


        Thread.sleep(TEST_TIMEOUT_MS)
        Thread.sleep(TEST_TIMEOUT_MS)
        verify(mConnector, never()).makeIpClient(any(), any())
        verify(mConnector, never()).makeIpClient(any(), any())
        doReturn(mConnectorBinder).`when`(mContext).getSystemService(Context.NETWORK_STACK_SERVICE)
        doReturn(mConnectorBinder).`when` { NetworkStack.getService() }
        // Use a longer timeout as polling can cause larger delays
        // Use a longer timeout as polling can cause larger delays
        verify(mConnector, timeout(TEST_TIMEOUT_MS * 4)).makeIpClient(TEST_IFNAME, mIpClientCb)
        verify(mConnector, timeout(TEST_TIMEOUT_MS * 4)).makeIpClient(TEST_IFNAME, mIpClientCb)
    }
    }


    @Test
    @Test
    fun testDhcpServerAvailableImmediately() {
    fun testDhcpServerAvailableImmediately() {
        doReturn(mConnectorBinder).`when`(mContext).getSystemService(Context.NETWORK_STACK_SERVICE)
        doReturn(mConnectorBinder).`when` { NetworkStack.getService() }
        val testParams = DhcpServingParamsParcel()
        val testParams = DhcpServingParamsParcel()
        ModuleNetworkStackClient.getInstance(mContext).makeDhcpServer(TEST_IFNAME, testParams,
        ModuleNetworkStackClient.getInstance(mContext).makeDhcpServer(TEST_IFNAME, testParams,
                mDhcpServerCb)
                mDhcpServerCb)
@@ -107,7 +114,7 @@ class ModuleNetworkStackClientTest {


    @Test
    @Test
    fun testNetworkMonitorAvailableImmediately() {
    fun testNetworkMonitorAvailableImmediately() {
        doReturn(mConnectorBinder).`when`(mContext).getSystemService(Context.NETWORK_STACK_SERVICE)
        doReturn(mConnectorBinder).`when` { NetworkStack.getService() }
        val testName = "NetworkMonitorName"
        val testName = "NetworkMonitorName"
        ModuleNetworkStackClient.getInstance(mContext).makeNetworkMonitor(TEST_NETWORK, testName,
        ModuleNetworkStackClient.getInstance(mContext).makeNetworkMonitor(TEST_NETWORK, testName,
                mNetworkMonitorCb)
                mNetworkMonitorCb)
@@ -116,7 +123,7 @@ class ModuleNetworkStackClientTest {


    @Test
    @Test
    fun testIpMemoryStoreAvailableImmediately() {
    fun testIpMemoryStoreAvailableImmediately() {
        doReturn(mConnectorBinder).`when`(mContext).getSystemService(Context.NETWORK_STACK_SERVICE)
        doReturn(mConnectorBinder).`when` { NetworkStack.getService() }
        ModuleNetworkStackClient.getInstance(mContext).fetchIpMemoryStore(mIpMemoryStoreCb)
        ModuleNetworkStackClient.getInstance(mContext).fetchIpMemoryStore(mIpMemoryStoreCb)
        verify(mConnector).fetchIpMemoryStore(mIpMemoryStoreCb)
        verify(mConnector).fetchIpMemoryStore(mIpMemoryStoreCb)
    }
    }