Move dumpsys to handler thread

I0afdda023208c3f8620cb5b89add66448af596d7 added some assertions
to ensure NetworkAgentInfo can only be accessed from the handler
thread. This is good to eliminate any potential concurrent
accessing problem. Howver, dumpsys runs on binder thread, this
change breaks dumpsys functionality.

Thus, this change:
  1. Copy Handler#runWithScissors() and related class
     locally since they are @hide methods.
  2. Run doDump on the handler thread and waits for return.

Test: adb shell dumpsys connectivity
Test: atest FrameworksNetTests:android.net.connectivity.com.android.server.HandlerUtilsTest
Fix: 303348620
Change-Id: Ic3a22f5d370bbf8c18b1972e86d695b6ad61bd0d
This commit is contained in:
Junyu Lai
2023-10-12 17:01:03 +08:00
parent 1eeeb15f2e
commit f8dba342f1
3 changed files with 209 additions and 3 deletions

View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server
import android.os.HandlerThread
import com.android.server.connectivity.HandlerUtils
import com.android.testutils.DevSdkIgnoreRunner
import kotlin.test.assertEquals
import kotlin.test.assertTrue
import org.junit.After
import org.junit.Test
import org.junit.runner.RunWith
const val THREAD_BLOCK_TIMEOUT_MS = 1000L
const val TEST_REPEAT_COUNT = 100
@RunWith(DevSdkIgnoreRunner::class)
class HandlerUtilsTest {
val handlerThread = HandlerThread("HandlerUtilsTestHandlerThread").also {
it.start()
}
val handler = handlerThread.threadHandler
@Test
fun testRunWithScissors() {
// Repeat the test a fair amount of times to ensure that it does not pass by chance.
repeat(TEST_REPEAT_COUNT) {
var result = false
HandlerUtils.runWithScissors(handler, {
assertEquals(Thread.currentThread(), handlerThread)
result = true
}, THREAD_BLOCK_TIMEOUT_MS)
// Assert that the result is modified on the handler thread, but can also be seen from
// the current thread. The assertion should pass if the runWithScissors provides
// the guarantee where the assignment happens-before the assertion.
assertTrue(result)
}
}
@After
fun tearDown() {
handlerThread.quitSafely()
handlerThread.join()
}
}