1 /* <lambda>null2 * Copyright 2023 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.contacts.sdn 17 18 import android.Manifest.permission 19 import android.annotation.SuppressLint 20 import android.content.Context 21 import android.content.pm.PackageManager 22 import android.telephony.CarrierConfigManager 23 import android.telephony.SubscriptionManager 24 import android.util.Log 25 import com.android.contacts.model.SimCard 26 import com.android.contacts.util.PermissionsUtil 27 import com.android.contacts.util.PhoneNumberHelper 28 29 /** Repository to fetch Sdn data from [CarrierConfigManager]. */ 30 class SdnRepository constructor(private val context: Context) { 31 32 fun isSdnPresent(): Boolean { 33 if ( 34 !hasTelephony() || 35 !PermissionsUtil.hasPermission(context, permission.READ_PHONE_STATE) || 36 !PermissionsUtil.hasPermission(context, permission.READ_PHONE_NUMBERS) || 37 !PermissionsUtil.hasPermission(context, permission.READ_CALL_LOG) 38 ) { 39 return false 40 } 41 42 val simCardList = getSimCardInformation() 43 44 for (simCard in simCardList) { 45 if (fetchSdnFromCarrierConfig(simCard).isNotEmpty()) { 46 Log.i(TAG, "Found SDN list from CarrierConfig") 47 return true 48 } 49 } 50 return false 51 } 52 53 fun fetchSdn(): List<Sdn> { 54 val simCardList = getSimCardInformation() 55 56 return simCardList 57 .flatMap { fetchSdnFromCarrierConfig(it) } 58 .distinct() 59 .sortedBy { it.serviceName } 60 } 61 62 // Permission check isn't recognized by the linter. 63 @SuppressLint("MissingPermission") 64 fun getSimCardInformation(): List<SimCard> { 65 val subscriptionManager = context.getSystemService(SubscriptionManager::class.java) 66 return subscriptionManager?.activeSubscriptionInfoList?.filterNotNull()?.mapNotNull { 67 if (it.subscriptionId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 68 null 69 } else { 70 SimCard.create(it) 71 } 72 } 73 ?: emptyList() 74 } 75 76 @Suppress("Deprecation", "MissingPermission") 77 private fun fetchSdnFromCarrierConfig(simCard: SimCard): List<Sdn> { 78 val carrierConfigManager = context.getSystemService(CarrierConfigManager::class.java) 79 val carrierConfig = 80 carrierConfigManager?.getConfigForSubId(simCard.subscriptionId) ?: return emptyList() 81 val nameList: List<String> = 82 carrierConfig 83 .getStringArray(CarrierConfigManager.KEY_CARRIER_SERVICE_NAME_STRING_ARRAY) 84 ?.map { it?.trim() ?: "" } 85 ?: return emptyList() 86 val numberList: List<String> = 87 carrierConfig 88 .getStringArray(CarrierConfigManager.KEY_CARRIER_SERVICE_NUMBER_STRING_ARRAY) 89 ?.map { it?.trim() ?: "" } 90 ?: return emptyList() 91 if (nameList.isEmpty() || nameList.size != numberList.size) return emptyList() 92 93 val sdnList = mutableListOf<Sdn>() 94 nameList.zip(numberList).forEach { (sdnServiceName, sdnNumber) -> 95 if (sdnServiceName.isNotBlank() && PhoneNumberHelper.isDialablePhoneNumber(sdnNumber)) { 96 sdnList.add(Sdn(sdnServiceName, sdnNumber)) 97 } 98 } 99 return sdnList 100 } 101 102 private fun hasTelephony(): Boolean { 103 return context.packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) 104 } 105 106 companion object { 107 private val TAG = SdnRepository::class.java.simpleName 108 } 109 } 110 111 /** Hold the Service dialing number information to be displayed in SdnActivity. */ 112 data class Sdn( 113 val serviceName: String, 114 val serviceNumber: String, 115 ) { 116 117 /** Generate lookup key that will help identify SDN when Opening QuickContact. */ lookupKeynull118 fun lookupKey(): String { 119 return "non-sim-sdn-" + hashCode() 120 } 121 } 122