Merge "FRP bypass defense in the Settings App for SPA" into udc-dev

This commit is contained in:
Chaohui Wang
2023-05-05 07:57:39 +00:00
committed by Android (Google) Code Review
2 changed files with 67 additions and 9 deletions

View File

@@ -22,14 +22,34 @@ import android.content.Intent
import android.os.RemoteException import android.os.RemoteException
import android.os.UserHandle import android.os.UserHandle
import android.util.Log import android.util.Log
import androidx.annotation.VisibleForTesting
import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider
import com.android.settingslib.spa.framework.BrowseActivity import com.android.settingslib.spa.framework.BrowseActivity
import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.util.SESSION_BROWSE import com.android.settingslib.spa.framework.util.SESSION_BROWSE
import com.android.settingslib.spa.framework.util.SESSION_EXTERNAL import com.android.settingslib.spa.framework.util.SESSION_EXTERNAL
import com.android.settingslib.spa.framework.util.appendSpaParams import com.android.settingslib.spa.framework.util.appendSpaParams
import com.google.android.setupcompat.util.WizardManagerHelper
class SpaActivity : BrowseActivity() { class SpaActivity : BrowseActivity() {
override fun isPageEnabled(page: SettingsPage) =
super.isPageEnabled(page) && !isSuwAndPageBlocked(page.sppName)
companion object { companion object {
private const val TAG = "SpaActivity" private const val TAG = "SpaActivity"
/** The pages that blocked from SUW. */
private val SuwBlockedPages = setOf(AppInfoSettingsProvider.name)
@VisibleForTesting
fun Context.isSuwAndPageBlocked(name: String): Boolean =
if (name in SuwBlockedPages && !WizardManagerHelper.isDeviceProvisioned(this)) {
Log.w(TAG, "$name blocked before SUW completed.");
true
} else {
false
}
@JvmStatic @JvmStatic
fun Context.startSpaActivity(destination: String) { fun Context.startSpaActivity(destination: String) {
val intent = Intent(this, SpaActivity::class.java) val intent = Intent(this, SpaActivity::class.java)

View File

@@ -21,33 +21,71 @@ import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.UserHandle import android.os.UserHandle
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.dx.mockito.inline.extended.ExtendedMockito
import com.android.settings.spa.SpaActivity.Companion.isSuwAndPageBlocked
import com.android.settings.spa.SpaActivity.Companion.startSpaActivity import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
import com.android.settings.spa.SpaActivity.Companion.startSpaActivityForApp import com.android.settings.spa.SpaActivity.Companion.startSpaActivityForApp
import com.android.settings.spa.app.AllAppListPageProvider
import com.android.settings.spa.app.appinfo.AppInfoSettingsProvider
import com.android.settingslib.spa.framework.util.KEY_DESTINATION import com.android.settingslib.spa.framework.util.KEY_DESTINATION
import com.google.android.setupcompat.util.WizardManagerHelper
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before import org.junit.Before
import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Answers
import org.mockito.ArgumentCaptor import org.mockito.ArgumentCaptor
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito.verify import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` import org.mockito.MockitoSession
import org.mockito.junit.MockitoJUnit import org.mockito.quality.Strictness
import org.mockito.junit.MockitoRule import org.mockito.Mockito.`when` as whenever
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class SpaActivityTest { class SpaActivityTest {
@get:Rule private lateinit var mockSession: MockitoSession
val mockito: MockitoRule = MockitoJUnit.rule()
@Mock(answer = Answers.RETURNS_DEEP_STUBS) @Mock
private lateinit var context: Context private lateinit var context: Context
@Before @Before
fun setUp() { fun setUp() {
`when`(context.applicationContext.packageName).thenReturn("com.android.settings") mockSession = ExtendedMockito.mockitoSession()
.initMocks(this)
.mockStatic(WizardManagerHelper::class.java)
.strictness(Strictness.LENIENT)
.startMocking()
whenever(context.applicationContext).thenReturn(context)
}
@After
fun tearDown() {
mockSession.finishMocking()
}
@Test
fun isSuwAndPageBlocked_regularPage_notBlocked() {
val isBlocked = context.isSuwAndPageBlocked(AllAppListPageProvider.name)
assertThat(isBlocked).isFalse()
}
@Test
fun isSuwAndPageBlocked_blocklistedPageInSuw_blocked() {
whenever(WizardManagerHelper.isDeviceProvisioned(context)).thenReturn(false)
val isBlocked = context.isSuwAndPageBlocked(AppInfoSettingsProvider.name)
assertThat(isBlocked).isTrue()
}
@Test
fun isSuwAndPageBlocked_blocklistedPageNotInSuw_notBlocked() {
whenever(WizardManagerHelper.isDeviceProvisioned(context)).thenReturn(true)
val isBlocked = context.isSuwAndPageBlocked(AppInfoSettingsProvider.name)
assertThat(isBlocked).isFalse()
} }
@Test @Test