1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.server.net.integrationtests 18 19 import android.app.Service 20 import android.content.Context 21 import android.content.Intent 22 import android.net.INetworkMonitorCallbacks 23 import android.net.Network 24 import android.net.metrics.IpConnectivityLog 25 import android.os.IBinder 26 import com.android.net.module.util.SharedLog 27 import com.android.networkstack.netlink.TcpSocketTracker 28 import com.android.server.NetworkStackService 29 import com.android.server.NetworkStackService.NetworkMonitorConnector 30 import com.android.server.NetworkStackService.NetworkStackConnector 31 import com.android.server.connectivity.NetworkMonitor 32 import com.android.server.net.integrationtests.NetworkStackInstrumentationService.InstrumentationConnector 33 import java.io.ByteArrayInputStream 34 import java.net.HttpURLConnection 35 import java.net.URL 36 import java.nio.charset.StandardCharsets 37 import java.util.concurrent.ExecutorService 38 import org.mockito.Mockito.doReturn 39 import org.mockito.Mockito.mock 40 import org.mockito.Mockito.spy 41 42 private const val TEST_NETID = 42 43 44 /** 45 * Android service that can return an [android.net.INetworkStackConnector] which can be instrumented 46 * through [NetworkStackInstrumentationService]. 47 * Useful in tests to create test instrumented NetworkStack components that can receive 48 * instrumentation commands through [NetworkStackInstrumentationService]. 49 */ 50 class TestNetworkStackService : Service() { onBindnull51 override fun onBind(intent: Intent): IBinder = TestNetworkStackConnector(makeTestContext()) 52 53 private fun makeTestContext() = spy(applicationContext).also { 54 doReturn(mock(IBinder::class.java)).`when`(it).getSystemService(Context.NETD_SERVICE) 55 } 56 57 private class TestPermissionChecker : NetworkStackService.PermissionChecker() { enforceNetworkStackCallingPermissionnull58 override fun enforceNetworkStackCallingPermission() = Unit 59 } 60 61 private class NetworkMonitorDeps(private val privateDnsBypassNetwork: Network) : 62 NetworkMonitor.Dependencies() { 63 override fun getPrivateDnsBypassNetwork(network: Network?) = privateDnsBypassNetwork 64 override fun onThreadCreated(thread: Thread) = 65 InstrumentationConnector.onNetworkMonitorThreadCreated(thread) 66 override fun onExecutorServiceCreated(ecs: ExecutorService) = 67 InstrumentationConnector.onNetworkMonitorExecutorServiceCreated(ecs) 68 } 69 70 /** 71 * Mock [HttpURLConnection] to simulate reply from a server. 72 */ 73 private class MockConnection( 74 url: URL, 75 private val response: HttpResponse 76 ) : HttpURLConnection(url) { 77 private val responseBytes = checkNotNull(response.content) 78 .toByteArray(StandardCharsets.UTF_8) getResponseCodenull79 override fun getResponseCode() = response.responseCode 80 override fun getContentLengthLong() = responseBytes.size.toLong() 81 override fun getHeaderField(field: String): String? { 82 return when (field) { 83 "location" -> response.redirectUrl 84 else -> null 85 } 86 } getInputStreamnull87 override fun getInputStream() = ByteArrayInputStream(responseBytes) 88 override fun connect() = Unit 89 override fun disconnect() = Unit 90 override fun usingProxy() = false 91 } 92 93 private inner class TestNetworkStackConnector(context: Context) : NetworkStackConnector( 94 context, TestPermissionChecker(), NetworkStackService.Dependencies()) { 95 96 private val network = Network(TEST_NETID) 97 private val privateDnsBypassNetwork = TestNetwork(TEST_NETID) 98 99 private inner class TestNetwork(netId: Int) : Network(netId) { 100 override fun openConnection(url: URL) = MockConnection( 101 url, InstrumentationConnector.processRequest(url)) 102 } 103 104 override fun makeNetworkMonitor( 105 network: Network, 106 name: String?, 107 cb: INetworkMonitorCallbacks 108 ) { 109 val nm = NetworkMonitor(this@TestNetworkStackService, cb, 110 this.network, 111 mock(IpConnectivityLog::class.java), mock(SharedLog::class.java), 112 mock(NetworkStackService.NetworkStackServiceManager::class.java), 113 NetworkMonitorDeps(privateDnsBypassNetwork), 114 mock(TcpSocketTracker::class.java)) 115 cb.onNetworkMonitorCreated(NetworkMonitorConnector(nm, TestPermissionChecker())) 116 } 117 } 118 } 119