Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 454d7616 authored by Winson Chiu's avatar Winson Chiu Committed by Automerger Merge Worker
Browse files

Merge "Test scheduleWriteSettings inside DomainVerificationService" into sc-dev am: 081b3e43

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13438572

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I6bb9f2a3af3eece943175b85e99488f7e438e979
parents 968ba926 081b3e43
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -542,8 +542,6 @@ public class DomainVerificationService extends SystemService
                userState.removeHosts(domains);
            }
        }

        mConnection.scheduleWriteSettings();
    }

    @Nullable
@@ -849,6 +847,7 @@ public class DomainVerificationService extends SystemService
    public void setLegacyUserState(@NonNull String packageName, @UserIdInt int userId, int state) {
        mEnforcer.callerIsLegacyUserSelector(mConnection.getCallingUid());
        mLegacySettings.add(packageName, userId, state);
        mConnection.scheduleWriteSettings();
    }

    @Override
@@ -1067,6 +1066,8 @@ public class DomainVerificationService extends SystemService
                }
            }
        }

        mConnection.scheduleWriteSettings();
    }

    /**
@@ -1124,6 +1125,8 @@ public class DomainVerificationService extends SystemService
                }
            }
        }

        mConnection.scheduleWriteSettings();
    }

    @Override
+271 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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.pm.test.verify.domain

import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.PackageUserState
import android.content.pm.verify.domain.DomainVerificationManager
import android.content.pm.parsing.component.ParsedActivity
import android.content.pm.parsing.component.ParsedIntentInfo
import android.os.Build
import android.os.Process
import android.util.ArraySet
import android.util.SparseArray
import com.android.server.pm.PackageSetting
import com.android.server.pm.verify.domain.DomainVerificationManagerInternal
import com.android.server.pm.verify.domain.DomainVerificationService
import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy
import com.android.server.pm.parsing.pkg.AndroidPackage
import com.android.server.testutils.mockThrowOnUnmocked
import com.android.server.testutils.spyThrowOnUnmocked
import com.android.server.testutils.whenever
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.mockito.Mockito
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.anyLong
import org.mockito.Mockito.any
import org.mockito.Mockito.anyString
import org.mockito.Mockito.eq
import org.mockito.Mockito.verify
import java.io.File
import java.util.UUID

@RunWith(Parameterized::class)
class DomainVerificationSettingsMutationTest {

    companion object {
        private const val TEST_PKG = "com.test"

        // Pretend to be the system. This class doesn't verify any enforcement behavior.
        private const val TEST_UID = Process.SYSTEM_UID
        private const val TEST_USER_ID = 10
        private val TEST_UUID = UUID.fromString("5168e42e-327e-432b-b562-cfb553518a70")

        @JvmStatic
        @Parameterized.Parameters(name = "{0}")
        fun parameters(): Array<Any> {
            val context: Context = mockThrowOnUnmocked {
                whenever(
                    enforcePermission(
                        eq(android.Manifest.permission.DOMAIN_VERIFICATION_AGENT),
                        anyInt(), anyInt(), anyString()
                    )
                )
                whenever(
                    enforcePermission(
                        eq(android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION),
                        anyInt(), anyInt(), anyString()
                    )
                )
                whenever(
                    enforcePermission(
                        eq(android.Manifest.permission.INTERACT_ACROSS_USERS),
                        anyInt(), anyInt(), anyString()
                    )
                )
                whenever(
                    enforcePermission(
                        eq(android.Manifest.permission.SET_PREFERRED_APPLICATIONS),
                        anyInt(), anyInt(), anyString()
                    )
                )
            }
            val proxy: DomainVerificationProxy = mockThrowOnUnmocked {
                whenever(isCallerVerifier(anyInt())) { true }
                whenever(sendBroadcastForPackages(any()))
            }

            val makeService: (DomainVerificationManagerInternal.Connection) -> DomainVerificationService =
                { connection ->
                    DomainVerificationService(
                        context,
                        mockThrowOnUnmocked { whenever(linkedApps) { ArraySet<String>() } },
                        mockThrowOnUnmocked {
                            whenever(isChangeEnabled(anyLong(),any())) { true }
                        }).apply {
                        setConnection(connection)
                    }
                }

            fun service(name: String, block: DomainVerificationService.() -> Unit) =
                Params(makeService, name) { service ->
                    service.proxy = proxy
                    service.addPackage(mockPkgSetting())
                    service.block()
                }

            return arrayOf(
                service("clearPackage") {
                    clearPackage(TEST_PKG)
                },
                service("clearUser") {
                    clearUser(TEST_USER_ID)
                },
                service("clearState") {
                    clearDomainVerificationState(listOf(TEST_PKG))
                },
                service("clearUserSelections") {
                    clearUserSelections(listOf(TEST_PKG), TEST_USER_ID)
                },
                service("setStatus") {
                    setDomainVerificationStatus(
                        TEST_UUID,
                        setOf("example.com"),
                        DomainVerificationManager.STATE_SUCCESS
                    )
                },
                service("setStatusInternalPackageName") {
                    setDomainVerificationStatusInternal(
                        TEST_PKG,
                        DomainVerificationManager.STATE_SUCCESS,
                        ArraySet(setOf("example.com"))
                    )
                },
                service("setStatusInternalUid") {
                    setDomainVerificationStatusInternal(
                        TEST_UID,
                        TEST_UUID,
                        setOf("example.com"),
                        DomainVerificationManager.STATE_SUCCESS
                    )
                },
                service("setLinkHandlingAllowed") {
                    setDomainVerificationLinkHandlingAllowed(TEST_PKG, true)
                },
                service("setLinkHandlingAllowedUserId") {
                    setDomainVerificationLinkHandlingAllowed(TEST_PKG, true, TEST_USER_ID)
                },
                service("setLinkHandlingAllowedInternal") {
                    setDomainVerificationLinkHandlingAllowedInternal(TEST_PKG, true, TEST_USER_ID)
                },
                service("setUserSelection") {
                    setDomainVerificationUserSelection(TEST_UUID, setOf("example.com"), true)
                },
                service("setUserSelectionUserId") {
                    setDomainVerificationUserSelection(
                        TEST_UUID,
                        setOf("example.com"),
                        true,
                        TEST_USER_ID
                    )
                },
                service("setUserSelectionInternal") {
                    setDomainVerificationUserSelectionInternal(
                        TEST_USER_ID,
                        TEST_PKG,
                        true,
                        ArraySet(setOf("example.com")),
                    )
                },
                service("setLegacyUserState") {
                    setLegacyUserState(
                        TEST_PKG,
                        TEST_USER_ID,
                        PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER
                    )
                },
            )
        }

        data class Params(
            val construct: (
                DomainVerificationManagerInternal.Connection
            ) -> DomainVerificationService,
            val name: String,
            val method: (DomainVerificationService) -> Unit
        ) {
            override fun toString() = name
        }


        fun mockPkg() = mockThrowOnUnmocked<AndroidPackage> {
            whenever(packageName) { TEST_PKG }
            whenever(targetSdkVersion) { Build.VERSION_CODES.S }
            whenever(activities) {
                listOf(
                    ParsedActivity().apply {
                        addIntent(
                            ParsedIntentInfo().apply {
                                autoVerify = true
                                addAction(Intent.ACTION_VIEW)
                                addCategory(Intent.CATEGORY_BROWSABLE)
                                addCategory(Intent.CATEGORY_DEFAULT)
                                addDataScheme("https")
                                addDataAuthority("example.com", null)
                            }
                        )
                    }
                )
            }
        }

        // TODO: PackageSetting field encapsulation to move to whenever(name)
        fun mockPkgSetting() = spyThrowOnUnmocked(
            PackageSetting(
                TEST_PKG,
                TEST_PKG,
                File("/test"),
                null,
                null,
                null,
                null,
                1,
                0,
                0,
                0,
                null,
                null,
                null,
                TEST_UUID
            )
        ) {
            whenever(getPkg()) { mockPkg() }
            whenever(domainSetId) { TEST_UUID }
            whenever(userState) {
                SparseArray<PackageUserState>().apply {
                    this[0] = PackageUserState()
                }
            }
        }
    }

    @Parameterized.Parameter(0)
    lateinit var params: Params

    @Test
    fun writeScheduled() {
        val connection = mockConnection()
        val service = params.construct(connection)
        params.method(service)

        verify(connection).scheduleWriteSettings()
    }

    private fun mockConnection(): DomainVerificationManagerInternal.Connection =
        mockThrowOnUnmocked {
            whenever(callingUid) { TEST_UID }
            whenever(callingUserId) { TEST_USER_ID }
            whenever(getPackageSettingLocked(TEST_PKG)) { mockPkgSetting() }
            whenever(getPackageLocked(TEST_PKG)) { mockPkg() }
            whenever(schedule(anyInt(), any()))
            whenever(scheduleWriteSettings())
        }
}