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.net.util.SharedLog 26 import android.os.IBinder 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 org.mockito.Mockito.doReturn 34 import org.mockito.Mockito.mock 35 import org.mockito.Mockito.spy 36 import java.io.ByteArrayInputStream 37 import java.net.HttpURLConnection 38 import java.net.URL 39 import java.nio.charset.StandardCharsets 40 41 private const val TEST_NETID = 42 42 43 /** 44 * Android service that can return an [android.net.INetworkStackConnector] which can be instrumented 45 * through [NetworkStackInstrumentationService]. 46 * Useful in tests to create test instrumented NetworkStack components that can receive 47 * instrumentation commands through [NetworkStackInstrumentationService]. 48 */ 49 class TestNetworkStackService : Service() { onBindnull50 override fun onBind(intent: Intent): IBinder = TestNetworkStackConnector(makeTestContext()) 51 52 private fun makeTestContext() = spy(applicationContext).also { 53 doReturn(mock(IBinder::class.java)).`when`(it).getSystemService(Context.NETD_SERVICE) 54 } 55 56 private class TestPermissionChecker : NetworkStackService.PermissionChecker() { enforceNetworkStackCallingPermissionnull57 override fun enforceNetworkStackCallingPermission() = Unit 58 } 59 60 private class NetworkMonitorDeps(private val privateDnsBypassNetwork: Network) : 61 NetworkMonitor.Dependencies() { 62 override fun getPrivateDnsBypassNetwork(network: Network?) = privateDnsBypassNetwork 63 } 64 65 /** 66 * Mock [HttpURLConnection] to simulate reply from a server. 67 */ 68 private class MockConnection( 69 url: URL, 70 private val response: HttpResponse 71 ) : HttpURLConnection(url) { 72 private val responseBytes = response.content.toByteArray(StandardCharsets.UTF_8) getResponseCodenull73 override fun getResponseCode() = response.responseCode 74 override fun getContentLengthLong() = responseBytes.size.toLong() 75 override fun getHeaderField(field: String): String? { 76 return when (field) { 77 "location" -> response.redirectUrl 78 else -> null 79 } 80 } getInputStreamnull81 override fun getInputStream() = ByteArrayInputStream(responseBytes) 82 override fun connect() = Unit 83 override fun disconnect() = Unit 84 override fun usingProxy() = false 85 } 86 87 private inner class TestNetworkStackConnector(context: Context) : NetworkStackConnector( 88 context, TestPermissionChecker(), NetworkStackService.Dependencies()) { 89 90 private val network = Network(TEST_NETID) 91 private val privateDnsBypassNetwork = TestNetwork(TEST_NETID) 92 93 private inner class TestNetwork(netId: Int) : Network(netId) { 94 override fun openConnection(url: URL) = MockConnection( 95 url, InstrumentationConnector.processRequest(url)) 96 } 97 98 override fun makeNetworkMonitor( 99 network: Network, 100 name: String?, 101 cb: INetworkMonitorCallbacks 102 ) { 103 val nm = NetworkMonitor(this@TestNetworkStackService, cb, 104 this.network, 105 mock(IpConnectivityLog::class.java), mock(SharedLog::class.java), 106 mock(NetworkStackService.NetworkStackServiceManager::class.java), 107 NetworkMonitorDeps(privateDnsBypassNetwork), 108 mock(TcpSocketTracker::class.java)) 109 cb.onNetworkMonitorCreated(NetworkMonitorConnector(nm, TestPermissionChecker())) 110 } 111 } 112 } 113