From 692727b84e47cf0240a26a931c9f5cf6dbaa5fae Mon Sep 17 00:00:00 2001 From: Chiachang Wang Date: Mon, 19 Feb 2024 07:12:27 +0000 Subject: [PATCH 1/2] Add permission control methods override Bug: 325984919 Test: atest FrameworksNetTests Change-Id: Ib57a4a936538295a6df10ae7e334bc969ea455d1 --- .../server/connectivityservice/base/CSTest.kt | 61 +++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt index e40143471b..ea9ba7523b 100644 --- a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt +++ b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt @@ -47,8 +47,10 @@ import android.os.BatteryStatsManager import android.os.Bundle import android.os.Handler import android.os.HandlerThread +import android.os.Process import android.os.UserHandle import android.os.UserManager +import android.permission.PermissionManager.PermissionResult import android.telephony.TelephonyManager import android.testing.TestableContext import android.util.ArraySet @@ -300,13 +302,64 @@ open class CSTest { val pacProxyManager = mock() val networkPolicyManager = mock() + // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant + // For permissions granted across the board, the key is only the permission name. + // For permissions only granted to a combination of uid/pid, the key + // is ",,". PID+UID permissions have priority over generic ones. + private val mMockedPermissions: HashMap = HashMap() override fun getPackageManager() = this@CSTest.packageManager override fun getContentResolver() = this@CSTest.contentResolver - // TODO : buff up the capabilities of this permission scheme to allow checking for - // permission rejections - override fun checkPermission(permission: String, pid: Int, uid: Int) = PERMISSION_GRANTED - override fun checkCallingOrSelfPermission(permission: String) = PERMISSION_GRANTED + // If the permission result does not set in the mMockedPermissions, it will be + // considered as PERMISSION_GRANTED as existing design to prevent breaking other tests. + override fun checkPermission(permission: String, pid: Int, uid: Int) = + checkMockedPermission(permission, pid, uid, PERMISSION_GRANTED) + + override fun enforceCallingOrSelfPermission(permission: String, message: String?) { + // If the permission result does not set in the mMockedPermissions, it will be + // considered as PERMISSION_GRANTED as existing design to prevent breaking other tests. + val granted = checkMockedPermission(permission, Process.myPid(), Process.myUid(), + PERMISSION_GRANTED) + if (!granted.equals(PERMISSION_GRANTED)) { + throw SecurityException("[Test] permission denied: " + permission) + } + } + + // If the permission result does not set in the mMockedPermissions, it will be + // considered as PERMISSION_GRANTED as existing design to prevent breaking other tests. + override fun checkCallingOrSelfPermission(permission: String) = + checkMockedPermission(permission, Process.myPid(), Process.myUid(), PERMISSION_GRANTED) + + private fun checkMockedPermission(permission: String, pid: Int, uid: Int, default: Int): + Int { + val processSpecificKey = "$permission,$pid,$uid" + return mMockedPermissions[processSpecificKey] + ?: mMockedPermissions[permission] ?: default + } + + /** + * Mock checks for the specified permission, and have them behave as per `granted` or + * `denied`. + * + * This will apply to all calls no matter what the checked UID and PID are. + * + * @param granted One of {@link PackageManager#PermissionResult}. + */ + fun setPermission(permission: String, @PermissionResult granted: Int) { + mMockedPermissions.put(permission, granted) + } + + /** + * Mock checks for the specified permission, and have them behave as per `granted` or + * `denied`. + * + * This will only apply to the passed UID and PID. + * + * @param granted One of {@link PackageManager#PermissionResult}. + */ + fun setPermission(permission: String, pid: Int, uid: Int, @PermissionResult granted: Int) { + mMockedPermissions.put("$permission,$pid,$uid", granted) + } // Necessary for MultinetworkPolicyTracker, which tries to register a receiver for // all users. The test can't do that since it doesn't hold INTERACT_ACROSS_USERS. From 6b95876228ff28d8a8c7623cd157a6368ff7f48e Mon Sep 17 00:00:00 2001 From: Chiachang Wang Date: Mon, 19 Feb 2024 09:23:29 +0000 Subject: [PATCH 2/2] Add start activity method override method Add helper methods to support verifying startActivityAsUser(). Test: atest FrameworksNetTests Bug: 325984919 Change-Id: Id512ba6b1181974dde799ece64b263ce7a2f88f7 --- .../server/connectivityservice/base/CSTest.kt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt index ea9ba7523b..595ca47a3a 100644 --- a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt +++ b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt @@ -73,8 +73,11 @@ import com.android.server.connectivity.SatelliteAccessController import com.android.testutils.visibleOnHandlerThread import com.android.testutils.waitForIdle import java.util.concurrent.Executors +import java.util.concurrent.LinkedBlockingQueue +import java.util.concurrent.TimeUnit import java.util.function.Consumer import java.util.function.BiConsumer +import kotlin.test.assertNotNull import kotlin.test.assertNull import kotlin.test.fail import org.junit.After @@ -84,7 +87,7 @@ import org.mockito.Mockito.doAnswer import org.mockito.Mockito.doReturn import org.mockito.Mockito.mock -internal const val HANDLER_TIMEOUT_MS = 2_000 +internal const val HANDLER_TIMEOUT_MS = 2_000L internal const val BROADCAST_TIMEOUT_MS = 3_000L internal const val TEST_PACKAGE_NAME = "com.android.test.package" internal const val WIFI_WOL_IFNAME = "test_wlan_wol" @@ -307,6 +310,7 @@ open class CSTest { // For permissions only granted to a combination of uid/pid, the key // is ",,". PID+UID permissions have priority over generic ones. private val mMockedPermissions: HashMap = HashMap() + private val mStartedActivities = LinkedBlockingQueue() override fun getPackageManager() = this@CSTest.packageManager override fun getContentResolver() = this@CSTest.contentResolver @@ -417,6 +421,16 @@ open class CSTest { ) { orderedBroadcastAsUserHistory.add(intent) } + + override fun startActivityAsUser(intent: Intent, handle: UserHandle) { + mStartedActivities.put(intent) + } + + fun expectStartActivityIntent(timeoutMs: Long = HANDLER_TIMEOUT_MS): Intent { + val intent = mStartedActivities.poll(timeoutMs, TimeUnit.MILLISECONDS) + assertNotNull(intent, "Did not receive sign-in intent after " + timeoutMs + "ms") + return intent + } } // Utility methods for subclasses to use