1 /*
2  * Copyright (C) 2020 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 android.net.networkstack
18 
19 import android.content.ComponentName
20 import android.content.Context
21 import android.content.Intent
22 import android.content.ServiceConnection
23 import android.content.pm.PackageManager.MATCH_SYSTEM_ONLY
24 import android.net.INetworkStackConnector
25 import android.os.IBinder
26 import androidx.test.platform.app.InstrumentationRegistry
27 import kotlin.test.fail
28 
29 /**
30  * A [NetworkStackClientBase] that binds to [com.android.server.TestNetworkStackService]
31  */
32 class TestNetworkStackServiceClient private constructor() : NetworkStackClientBase() {
33     companion object {
34         private val context by lazy { InstrumentationRegistry.getInstrumentation().context }
35         private val networkStackVersion by lazy {
36             val component = getNetworkStackComponent()
37             val info = context.packageManager.getPackageInfo(component.packageName, 0 /* flags */)
38             info.longVersionCode
39         }
40 
41         /**
42          * Create a [TestNetworkStackServiceClient] and connect it to the NetworkStack.
43          */
44         @JvmStatic
45         fun connect(): TestNetworkStackServiceClient {
46             return TestNetworkStackServiceClient().apply { init() }
47         }
48 
49         @JvmStatic
50         fun isSupported(): Boolean {
51             // TestNetworkStackService was introduced in NetworkStack version 301100000.
52             // It is also available at HEAD in development branches, where the version code is
53             // 300000000.
54             return networkStackVersion == 300000000L || networkStackVersion >= 301100000L
55         }
56 
57         private fun getNetworkStackComponent(): ComponentName {
58             val connectorIntent = Intent(INetworkStackConnector::class.java.name)
59             return connectorIntent.resolveSystemService(context.packageManager, MATCH_SYSTEM_ONLY)
60                     ?: fail("TestNetworkStackService not found")
61         }
62     }
63 
64     private val serviceConnection = object : ServiceConnection {
65         override fun onServiceConnected(name: ComponentName, service: IBinder) {
66             onNetworkStackConnected(INetworkStackConnector.Stub.asInterface(service))
67         }
68 
69         override fun onServiceDisconnected(name: ComponentName) = Unit
70     }
71 
72     private fun init() {
73         val bindIntent = Intent(INetworkStackConnector::class.java.name + ".Test")
74         bindIntent.component = getNetworkStackComponent()
75         context.bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE)
76     }
77 
78     fun disconnect() {
79         InstrumentationRegistry.getInstrumentation().context.unbindService(serviceConnection)
80     }
81 }