• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2024 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
18 
19 import android.net.ConnectivityManager
20 import android.net.ConnectivityManager.CALLBACK_AVAILABLE
21 import android.net.ConnectivityManager.CALLBACK_CAP_CHANGED
22 import android.net.ConnectivityManager.CALLBACK_IP_CHANGED
23 import android.os.Build
24 import androidx.test.filters.SmallTest
25 import com.android.testutils.DevSdkIgnoreRule
26 import com.android.testutils.DevSdkIgnoreRunner
27 import java.lang.reflect.Modifier
28 import kotlin.test.assertEquals
29 import kotlin.test.assertFalse
30 import kotlin.test.assertTrue
31 import org.junit.Test
32 import org.junit.runner.RunWith
33 
34 private const val TEST_NETID_1 = 123
35 
36 // Maximum 16 bits unsigned value
37 private const val TEST_NETID_2 = 0xffff
38 
39 @RunWith(DevSdkIgnoreRunner::class)
40 @SmallTest
41 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
42 class CallbackQueueTest {
43     @Test
44     fun testAddCallback() {
45         val cbs = listOf(
46             TEST_NETID_1 to CALLBACK_AVAILABLE,
47             TEST_NETID_2 to CALLBACK_AVAILABLE,
48             TEST_NETID_1 to CALLBACK_CAP_CHANGED,
49             TEST_NETID_1 to CALLBACK_CAP_CHANGED
50         )
51         val queue = CallbackQueue(intArrayOf()).apply {
52             cbs.forEach { addCallback(it.first, it.second) }
53         }
54 
55         assertQueueEquals(cbs, queue)
56     }
57 
58     @Test
59     fun testHasCallback() {
60         val queue = CallbackQueue(intArrayOf()).apply {
61             addCallback(TEST_NETID_1, CALLBACK_AVAILABLE)
62             addCallback(TEST_NETID_2, CALLBACK_AVAILABLE)
63             addCallback(TEST_NETID_1, CALLBACK_CAP_CHANGED)
64             addCallback(TEST_NETID_1, CALLBACK_CAP_CHANGED)
65         }
66 
67         assertTrue(queue.hasCallback(TEST_NETID_1, CALLBACK_AVAILABLE))
68         assertTrue(queue.hasCallback(TEST_NETID_2, CALLBACK_AVAILABLE))
69         assertTrue(queue.hasCallback(TEST_NETID_1, CALLBACK_CAP_CHANGED))
70 
71         assertFalse(queue.hasCallback(TEST_NETID_2, CALLBACK_CAP_CHANGED))
72         assertFalse(queue.hasCallback(1234, CALLBACK_AVAILABLE))
73         assertFalse(queue.hasCallback(TEST_NETID_1, 5678))
74         assertFalse(queue.hasCallback(1234, 5678))
75     }
76 
77     @Test
78     fun testRemoveCallbacks() {
79         val queue = CallbackQueue(intArrayOf()).apply {
80             assertFalse(removeCallbacks(TEST_NETID_1, CALLBACK_AVAILABLE))
81             addCallback(TEST_NETID_1, CALLBACK_AVAILABLE)
82             addCallback(TEST_NETID_1, CALLBACK_CAP_CHANGED)
83             addCallback(TEST_NETID_2, CALLBACK_AVAILABLE)
84             addCallback(TEST_NETID_1, CALLBACK_AVAILABLE)
85             assertTrue(removeCallbacks(TEST_NETID_1, CALLBACK_AVAILABLE))
86         }
87         assertQueueEquals(listOf(
88             TEST_NETID_1 to CALLBACK_CAP_CHANGED,
89             TEST_NETID_2 to CALLBACK_AVAILABLE
90         ), queue)
91     }
92 
93     @Test
94     fun testRemoveCallbacksForNetId() {
95         val queue = CallbackQueue(intArrayOf()).apply {
96             assertFalse(removeCallbacksForNetId(TEST_NETID_2))
97             addCallback(TEST_NETID_2, CALLBACK_AVAILABLE)
98             assertFalse(removeCallbacksForNetId(TEST_NETID_1))
99             addCallback(TEST_NETID_1, CALLBACK_AVAILABLE)
100             addCallback(TEST_NETID_1, CALLBACK_CAP_CHANGED)
101             addCallback(TEST_NETID_2, CALLBACK_CAP_CHANGED)
102             addCallback(TEST_NETID_1, CALLBACK_AVAILABLE)
103             addCallback(TEST_NETID_2, CALLBACK_IP_CHANGED)
104             assertTrue(removeCallbacksForNetId(TEST_NETID_2))
105         }
106         assertQueueEquals(listOf(
107             TEST_NETID_1 to CALLBACK_AVAILABLE,
108             TEST_NETID_1 to CALLBACK_CAP_CHANGED,
109             TEST_NETID_1 to CALLBACK_AVAILABLE,
110         ), queue)
111     }
112 
113     @Test
114     fun testConstructorFromExistingArray() {
115         val queue1 = CallbackQueue(intArrayOf()).apply {
116             addCallback(TEST_NETID_1, CALLBACK_AVAILABLE)
117             addCallback(TEST_NETID_2, CALLBACK_AVAILABLE)
118         }
119         val queue2 = CallbackQueue(queue1.minimizedBackingArray)
120         assertQueueEquals(listOf(
121             TEST_NETID_1 to CALLBACK_AVAILABLE,
122             TEST_NETID_2 to CALLBACK_AVAILABLE
123         ), queue2)
124     }
125 
126     @Test
127     fun testToString() {
128         assertEquals("[]", CallbackQueue(intArrayOf()).toString())
129         assertEquals(
130             "[CALLBACK_AVAILABLE($TEST_NETID_1)]",
131             CallbackQueue(intArrayOf()).apply {
132                 addCallback(TEST_NETID_1, CALLBACK_AVAILABLE)
133             }.toString()
134         )
135         assertEquals(
136             "[CALLBACK_AVAILABLE($TEST_NETID_1),CALLBACK_CAP_CHANGED($TEST_NETID_2)]",
137             CallbackQueue(intArrayOf()).apply {
138                 addCallback(TEST_NETID_1, CALLBACK_AVAILABLE)
139                 addCallback(TEST_NETID_2, CALLBACK_CAP_CHANGED)
140             }.toString()
141         )
142     }
143 
144     @Test
145     fun testMaxNetId() {
146         // CallbackQueue assumes netIds are at most 16 bits
147         assertTrue(NetIdManager.MAX_NET_ID <= 0xffff)
148     }
149 
150     @Test
151     fun testMaxCallbackId() {
152         // CallbackQueue assumes callback IDs are at most 16 bits.
153         val constants = ConnectivityManager::class.java.declaredFields.filter {
154             Modifier.isStatic(it.modifiers) && Modifier.isFinal(it.modifiers) &&
155                     it.name.startsWith("CALLBACK_")
156         }
157         constants.forEach {
158             it.isAccessible = true
159             assertTrue(it.get(null) as Int <= 0xffff)
160         }
161     }
162 }
163 
assertQueueEqualsnull164 private fun assertQueueEquals(expected: List<Pair<Int, Int>>, actual: CallbackQueue) {
165     assertEquals(
166         expected.size,
167         actual.length(),
168         "Size mismatch between expected: $expected and actual: $actual"
169     )
170 
171     var nextIndex = 0
172     actual.forEach { netId, cbId ->
173         val (expNetId, expCbId) = expected[nextIndex]
174         val msg = "$actual does not match $expected at index $nextIndex"
175         assertEquals(expNetId, netId, msg)
176         assertEquals(expCbId, cbId, msg)
177         nextIndex++
178     }
179     // Ensure forEach iterations and size are consistent
180     assertEquals(expected.size, nextIndex)
181 }
182