1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.settings.deviceinfo.simstatus 17 18 import android.content.Context 19 import android.graphics.Bitmap 20 import android.util.Log 21 import android.view.WindowManager 22 import android.widget.ImageView 23 import android.widget.TextView 24 import androidx.preference.Preference 25 import androidx.preference.PreferenceScreen 26 import com.android.settings.R 27 import com.android.settings.core.BasePreferenceController 28 import com.android.settings.deviceinfo.PhoneNumberUtil 29 import com.android.settings.network.SubscriptionUtil 30 import com.android.settings.network.telephony.TelephonyPreferenceDialog 31 import com.android.settingslib.Utils 32 import com.android.settingslib.qrcode.QrCodeGenerator 33 import com.android.settingslib.spaprivileged.framework.common.userManager 34 35 /** 36 * This is to show a preference regarding EID of SIM card. 37 * 38 * @param preferenceKey is the key for Preference 39 */ 40 class SimEidPreferenceController(context: Context, preferenceKey: String) : 41 BasePreferenceController(context, preferenceKey) { 42 private var slotSimStatus: SlotSimStatus? = null 43 private var eidStatus: EidStatus? = null 44 private lateinit var preference: TelephonyPreferenceDialog 45 private lateinit var eid: String 46 initnull47 fun init(slotSimStatus: SlotSimStatus?, eidStatus: EidStatus?) { 48 this.slotSimStatus = slotSimStatus 49 this.eidStatus = eidStatus 50 } 51 getAvailabilityStatusnull52 override fun getAvailabilityStatus(): Int { 53 if (!SubscriptionUtil.isSimHardwareVisible(mContext)) return UNSUPPORTED_ON_DEVICE 54 eid = eidStatus?.eid ?: "" 55 val isAvailable = mContext.userManager.isAdminUser && 56 !Utils.isWifiOnly(mContext) && 57 eid.isNotEmpty() 58 return if (isAvailable) AVAILABLE else CONDITIONALLY_UNAVAILABLE 59 } 60 displayPreferencenull61 override fun displayPreference(screen: PreferenceScreen) { 62 super.displayPreference(screen) 63 preference = screen.findPreference(preferenceKey)!! 64 val title = getTitle() 65 preference.title = title 66 preference.dialogTitle = title 67 } 68 69 /** Constructs title string. */ getTitlenull70 private fun getTitle(): String { 71 val slotSize = slotSimStatus?.size() ?: 0 72 if (slotSize <= 1) { 73 return mContext.getString(R.string.status_eid) 74 } 75 // Only append slot index to title when more than 1 is available 76 for (idxSlot in 0 until slotSize) { 77 val subInfo = slotSimStatus?.getSubscriptionInfo(idxSlot) 78 if (subInfo != null && subInfo.isEmbedded) { 79 return mContext.getString(R.string.eid_multi_sim, idxSlot + 1) 80 } 81 } 82 return mContext.getString(R.string.status_eid) 83 } 84 updateStatenull85 override fun updateState(preference: Preference?) { 86 super.updateState(preference) 87 88 updateDialog() 89 } 90 updateDialognull91 private fun updateDialog() { 92 val dialog = preference.dialog ?: return 93 dialog.window?.setFlags( 94 WindowManager.LayoutParams.FLAG_SECURE, 95 WindowManager.LayoutParams.FLAG_SECURE 96 ) 97 dialog.setCanceledOnTouchOutside(false) 98 val textView = dialog.findViewById<TextView>(R.id.esim_id_value) 99 textView.text = PhoneNumberUtil.expandByTts(eid) 100 101 val qrCodeView = dialog.findViewById<ImageView>(R.id.esim_id_qrcode) 102 qrCodeView.setImageBitmap(getEidQrCode(eid)) 103 104 // After "Tap to show", eid is displayed on preference. 105 preference.summary = textView.text 106 } 107 handlePreferenceTreeClicknull108 override fun handlePreferenceTreeClick(preference: Preference): Boolean { 109 if (preference.key == preferenceKey) { 110 this.preference.setOnShowListener { updateDialog() } 111 return true 112 } 113 return super.handlePreferenceTreeClick(preference) 114 } 115 116 companion object { 117 private const val TAG = "SimEidPreferenceController" 118 private const val QR_CODE_SIZE = 600 119 120 /** 121 * Gets the QR code for EID 122 * @param eid is the EID string 123 * @return a Bitmap of QR code 124 */ getEidQrCodenull125 private fun getEidQrCode(eid: String): Bitmap? = try { 126 QrCodeGenerator.encodeQrCode(eid, QR_CODE_SIZE) 127 } catch (exception: Exception) { 128 Log.w(TAG, "Error when creating QR code width $QR_CODE_SIZE", exception) 129 null 130 } 131 } 132 } 133