Files
packages_apps_Settings/src/com/android/settings/deviceinfo/simstatus/SimEidPreferenceController.kt
SongFerngWang c6eba747db [Sim UI enhancement] remove the "Tap to show info"
Bug: 318310357
Bug: 298898436
Bug: 298891941

Test: atest PhoneNumberPreferenceControllerTest
atest ImeiInfoPreferenceControllerTest
atest SimEidPreferenceControllerTest

Change-Id: Iadd82173b55b8f66409c1ff056dd4c323d6dcc35
2024-01-31 11:14:38 +00:00

169 lines
6.0 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.deviceinfo.simstatus
import android.content.Context
import android.graphics.Bitmap
import android.util.Log
import android.view.WindowManager
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.preference.Preference
import androidx.preference.PreferenceScreen
import com.android.settings.R
import com.android.settings.core.BasePreferenceController
import com.android.settings.deviceinfo.PhoneNumberUtil
import com.android.settings.network.SubscriptionUtil
import com.android.settingslib.CustomDialogPreferenceCompat
import com.android.settingslib.Utils
import com.android.settingslib.qrcode.QrCodeGenerator
import com.android.settingslib.spaprivileged.framework.common.userManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
* This is to show a preference regarding EID of SIM card.
*
* @param preferenceKey is the key for Preference
*/
class SimEidPreferenceController(context: Context, preferenceKey: String) :
BasePreferenceController(context, preferenceKey) {
private var slotSimStatus: SlotSimStatus? = null
private var eidStatus: EidStatus? = null
private lateinit var preference: CustomDialogPreferenceCompat
private var coroutineScope: CoroutineScope? = null
private lateinit var eid: String
fun init(slotSimStatus: SlotSimStatus?, eidStatus: EidStatus?) {
this.slotSimStatus = slotSimStatus
this.eidStatus = eidStatus
}
/**
* Returns available here, if SIM hardware is visible.
*
* Also check [getIsAvailableAndUpdateEid] for other availability check which retrieved
* asynchronously later.
*/
override fun getAvailabilityStatus() =
if (SubscriptionUtil.isSimHardwareVisible(mContext)) AVAILABLE else UNSUPPORTED_ON_DEVICE
override fun displayPreference(screen: PreferenceScreen) {
super.displayPreference(screen)
preference = screen.findPreference(preferenceKey)!!
}
override fun onViewCreated(viewLifecycleOwner: LifecycleOwner) {
coroutineScope = viewLifecycleOwner.lifecycleScope
coroutineScope?.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
update()
}
}
}
private suspend fun update() {
val isAvailable = withContext(Dispatchers.Default) {
getIsAvailableAndUpdateEid()
}
preference.isVisible = isAvailable
if (isAvailable) {
val title = withContext(Dispatchers.Default) {
getTitle()
}
preference.title = title
preference.dialogTitle = title
preference.summary = eid
updateDialog()
}
}
private fun getIsAvailableAndUpdateEid(): Boolean {
if (!mContext.userManager.isAdminUser || Utils.isWifiOnly(mContext)) return false
eid = eidStatus?.eid ?: ""
return eid.isNotEmpty()
}
/** Constructs title string. */
private fun getTitle(): String {
val slotSize = slotSimStatus?.size() ?: 0
if (slotSize <= 1) {
return mContext.getString(R.string.status_eid)
}
// Only append slot index to title when more than 1 is available
for (idxSlot in 0 until slotSize) {
val subInfo = slotSimStatus?.getSubscriptionInfo(idxSlot)
if (subInfo != null && subInfo.isEmbedded) {
return mContext.getString(R.string.eid_multi_sim, idxSlot + 1)
}
}
return mContext.getString(R.string.status_eid)
}
private suspend fun updateDialog() {
val dialog = preference.dialog ?: return
dialog.window?.setFlags(
WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE
)
dialog.setCanceledOnTouchOutside(false)
val textView = dialog.requireViewById<TextView>(R.id.esim_id_value)
textView.text = PhoneNumberUtil.expandByTts(eid)
val qrCodeView = dialog.requireViewById<ImageView>(R.id.esim_id_qrcode)
qrCodeView.setImageBitmap(getEidQrCode(eid))
}
override fun handlePreferenceTreeClick(preference: Preference): Boolean {
if (preference.key != preferenceKey) return false
this.preference.setOnShowListener {
coroutineScope?.launch { updateDialog() }
}
return true
}
override fun updateNonIndexableKeys(keys: MutableList<String>) {
if (!isAvailable() || !getIsAvailableAndUpdateEid()) {
keys += preferenceKey
}
}
companion object {
private const val TAG = "SimEidPreferenceController"
private const val QR_CODE_SIZE = 600
/**
* Gets the QR code for EID
* @param eid is the EID string
* @return a Bitmap of QR code
*/
private suspend fun getEidQrCode(eid: String): Bitmap? = withContext(Dispatchers.Default) {
try {
QrCodeGenerator.encodeQrCode(contents = eid, size = QR_CODE_SIZE)
} catch (exception: Exception) {
Log.w(TAG, "Error when creating QR code width $QR_CODE_SIZE", exception)
null
}
}
}
}