Fork the NfcTagAppsSettings page to SPA

The page is located at "Apps > Special app access > Nfc launch"

Bug: 267404181
Test: make RunSettingsRoboTests ROBOTEST_FILTER=NfcTagAppsPreferenceControllerTest
Change-Id: I9fb4a68634f0b6f20d5f87601c1175ced33daad5
This commit is contained in:
George
2023-03-07 22:33:58 +08:00
committed by George Chang
parent d71accda55
commit 750cd809fe
5 changed files with 164 additions and 0 deletions

View File

@@ -35,6 +35,7 @@ import com.android.settings.spa.app.specialaccess.DisplayOverOtherAppsAppListPro
import com.android.settings.spa.app.specialaccess.InstallUnknownAppsListProvider
import com.android.settings.spa.app.specialaccess.MediaManagementAppsAppListProvider
import com.android.settings.spa.app.specialaccess.ModifySystemSettingsAppListProvider
import com.android.settings.spa.app.specialaccess.NfcTagAppsSettingsProvider
import com.android.settings.spa.app.specialaccess.PictureInPictureListProvider
import com.android.settings.spa.app.specialaccess.WifiControlAppListProvider
import com.android.settings.wifi.ChangeWifiStateDetails
@@ -62,6 +63,8 @@ object SettingsActivityUtil {
MediaManagementAppsAppListProvider.getAppInfoRoutePrefix(),
ChangeWifiStateDetails::class.qualifiedName to
WifiControlAppListProvider.getAppInfoRoutePrefix(),
NfcTagAppsSettingsProvider::class.qualifiedName to
NfcTagAppsSettingsProvider.getAppInfoRoutePrefix(),
)
@JvmStatic

View File

@@ -63,6 +63,7 @@ import com.android.settings.spa.app.specialaccess.DisplayOverOtherAppsAppListPro
import com.android.settings.spa.app.specialaccess.InstallUnknownAppsListProvider
import com.android.settings.spa.app.specialaccess.MediaManagementAppsAppListProvider
import com.android.settings.spa.app.specialaccess.ModifySystemSettingsAppListProvider
import com.android.settings.spa.app.specialaccess.NfcTagAppsSettingsProvider
import com.android.settings.spa.app.specialaccess.WifiControlAppListProvider
import com.android.settings.spa.notification.AppListNotificationsPageProvider
import com.android.settings.spa.system.AppLanguagesPageProvider
@@ -112,6 +113,7 @@ object ManageApplicationsUtil {
LIST_TYPE_NOTIFICATION -> AppListNotificationsPageProvider.name
LIST_TYPE_APPS_LOCALE -> AppLanguagesPageProvider.name
LIST_TYPE_MAIN -> AllAppListPageProvider.name
LIST_TYPE_NFC_TAG_APPS -> NfcTagAppsSettingsProvider.getAppListRoute()
else -> null
}
}

View File

@@ -29,6 +29,7 @@ import com.android.settings.spa.app.specialaccess.DisplayOverOtherAppsAppListPro
import com.android.settings.spa.app.specialaccess.InstallUnknownAppsListProvider
import com.android.settings.spa.app.specialaccess.MediaManagementAppsAppListProvider
import com.android.settings.spa.app.specialaccess.ModifySystemSettingsAppListProvider
import com.android.settings.spa.app.specialaccess.NfcTagAppsSettingsProvider
import com.android.settings.spa.app.specialaccess.PictureInPictureListProvider
import com.android.settings.spa.app.specialaccess.SpecialAppAccessPageProvider
import com.android.settings.spa.app.specialaccess.WifiControlAppListProvider
@@ -61,6 +62,7 @@ open class SettingsSpaEnvironment(context: Context) : SpaEnvironment(context) {
InstallUnknownAppsListProvider,
AlarmsAndRemindersAppListProvider,
WifiControlAppListProvider,
NfcTagAppsSettingsProvider,
)
}

View File

@@ -0,0 +1,127 @@
/*
* 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.settings.spa.app.specialaccess
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager.GET_ACTIVITIES
import android.content.pm.PackageManager.PackageInfoFlags
import android.nfc.NfcAdapter
import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.livedata.observeAsState
import com.android.settings.R
import com.android.settingslib.spaprivileged.model.app.AppRecord
import com.android.settingslib.spaprivileged.model.app.userId
import com.android.settingslib.spaprivileged.template.app.TogglePermissionAppListModel
import com.android.settingslib.spaprivileged.template.app.TogglePermissionAppListProvider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
object NfcTagAppsSettingsProvider : TogglePermissionAppListProvider {
override val permissionType = "NfcTagAppsSettings"
override fun createModel(context: Context) = NfcTagAppsSettingsListModel(context)
}
data class NfcTagAppsSettingsRecord(
override val app: ApplicationInfo,
val controller: NfcTagAppsSettingsController,
val isSupported: Boolean,
) : AppRecord
class NfcTagAppsSettingsListModel(private val context: Context) :
TogglePermissionAppListModel<NfcTagAppsSettingsRecord> {
override val pageTitleResId = R.string.change_nfc_tag_apps_title
override val switchTitleResId = R.string.change_nfc_tag_apps_detail_switch
override val footerResId = R.string.change_nfc_tag_apps_detail_summary
private val packageManager = context.packageManager
override fun transform(
userIdFlow: Flow<Int>,
appListFlow: Flow<List<ApplicationInfo>>
): Flow<List<NfcTagAppsSettingsRecord>> =
userIdFlow.combine(appListFlow) { userId, appList ->
// The appListFlow always refreshed on resume, need to update nfcTagAppsSettingsPackages
// here to handle status change.
val nfcTagAppsSettingsPackages = getNfcTagAppsSettingsPackages(userId)
appList.map { app ->
createNfcTagAppsSettingsRecord(
app = app,
isAllowed = nfcTagAppsSettingsPackages[app.packageName],
)
}
}
private fun getNfcTagAppsSettingsPackages(userId: Int): Map<String, Boolean> {
NfcAdapter.getDefaultAdapter(context)?.let { nfcAdapter ->
if (nfcAdapter.isTagIntentAppPreferenceSupported) {
return nfcAdapter.getTagIntentAppPreferenceForUser(userId)
}
}
return emptyMap()
}
override fun transformItem(app: ApplicationInfo) =
createNfcTagAppsSettingsRecord(
app = app,
isAllowed = getNfcTagAppsSettingsPackages(app.userId)[app.packageName],
)
private fun createNfcTagAppsSettingsRecord(
app: ApplicationInfo,
isAllowed: Boolean?,
) =
NfcTagAppsSettingsRecord(
app = app,
isSupported = isAllowed != null,
controller = NfcTagAppsSettingsController(isAllowed == true),
)
override fun filter(
userIdFlow: Flow<Int>,
recordListFlow: Flow<List<NfcTagAppsSettingsRecord>>
) = recordListFlow.map { recordList -> recordList.filter { it.isSupported } }
@Composable
override fun isAllowed(record: NfcTagAppsSettingsRecord) =
record.controller.isAllowed.observeAsState()
override fun isChangeable(record: NfcTagAppsSettingsRecord) = true
override fun setAllowed(record: NfcTagAppsSettingsRecord, newAllowed: Boolean) {
NfcAdapter.getDefaultAdapter(context)?.let {
if (
it.setTagIntentAppPreferenceForUser(
record.app.userId,
record.app.packageName,
newAllowed
) == NfcAdapter.TAG_INTENT_APP_PREF_RESULT_SUCCESS
) {
record.controller.setAllowed(newAllowed)
} else {
Log.e(TAG, "Error updating TagIntentAppPreference")
}
}
}
private companion object {
const val TAG = "NfcTagAppsSettingsListModel"
val GET_ACTIVITIES_FLAGS = PackageInfoFlags.of(GET_ACTIVITIES.toLong())
}
}

View File

@@ -0,0 +1,30 @@
/*
* 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.settings.spa.app.specialaccess
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
class NfcTagAppsSettingsController(initialStatus: Boolean) {
val isAllowed: LiveData<Boolean>
get() = _allowed
fun setAllowed(newAllowed: Boolean) {
_allowed.postValue(newAllowed)
}
private val _allowed = MutableLiveData<Boolean>(initialStatus)
}