Files
app_Settings/src/com/android/settings/spa/SpaActivity.kt
Chaohui Wang 80462c370b FRP bypass defense in the Settings App for SPA
Over the last few years, there have been a number of
Factory Reset Protection bypass bugs in the SUW flow.
It's unlikely to defense all points from individual apps.

Therefore, we decide to block some critical pages when
user doesn't complete the SUW flow.

Fix: 280154358
Test: Unit test
Change-Id: I06e73386711d5ad13c89d033cf0fe3164781c0ef
2023-05-03 10:53:27 +08:00

83 lines
3.1 KiB
Kotlin

/*
* Copyright (C) 2022 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.settings.spa
import android.app.ActivityManager
import android.content.Context
import android.content.Intent
import android.os.RemoteException
import android.os.UserHandle
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.common.SettingsPage
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.appendSpaParams
import com.google.android.setupcompat.util.WizardManagerHelper
class SpaActivity : BrowseActivity() {
override fun isPageEnabled(page: SettingsPage) =
super.isPageEnabled(page) && !isSuwAndPageBlocked(page.sppName)
companion object {
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
fun Context.startSpaActivity(destination: String) {
val intent = Intent(this, SpaActivity::class.java)
.appendSpaParams(destination = destination)
if (isLaunchedFromInternal()) {
intent.appendSpaParams(sessionName = SESSION_BROWSE)
} else {
intent.appendSpaParams(sessionName = SESSION_EXTERNAL)
}
startActivity(intent)
}
@JvmStatic
fun Context.startSpaActivityForApp(destinationPrefix: String, intent: Intent): Boolean {
val packageName = intent.data?.schemeSpecificPart ?: return false
startSpaActivity("$destinationPrefix/$packageName/${UserHandle.myUserId()}")
return true
}
fun Context.isLaunchedFromInternal(): Boolean {
var pkg: String? = null
try {
pkg = ActivityManager.getService().getLaunchedFromPackage(getActivityToken())
} catch (e: RemoteException) {
Log.v(TAG, "Could not talk to activity manager.", e)
}
return applicationContext.packageName == pkg
}
}
}