1 /* 2 * Copyright (C) 2021 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 17 package com.android.settings.network; 18 19 import android.content.Context; 20 import android.telephony.SubscriptionManager; 21 import android.util.Log; 22 23 import com.android.settings.network.SubscriptionUtil; 24 import com.android.settings.network.helper.SelectableSubscriptions; 25 import com.android.settings.network.helper.SubscriptionAnnotation; 26 import com.android.settings.network.helper.SubscriptionGrouping; 27 import com.android.settings.network.telephony.MobileNetworkUtils; 28 import com.android.settingslib.utils.ThreadUtils; 29 30 import java.util.List; 31 import java.util.Map; 32 import java.util.concurrent.Future; 33 import java.util.function.Consumer; 34 import java.util.stream.Collectors; 35 36 /** 37 * This one keeps the information required by MobileNetworkSummaryController. 38 */ 39 public class MobileNetworkSummaryStatus { 40 private static final String LOG_TAG = "MobileNetworkSummaryStatus"; 41 42 private Future<Map<Integer, CharSequence>> mUniqueNameMapping; 43 private Map<Integer, CharSequence> mUniqueNameMappingCache; 44 45 private Future<Boolean> mIsEuiccConfiguable; 46 private Boolean mIsEuiccConfiguableCache; 47 48 private Future<Boolean> mIsPsimDisableSupported; 49 private Boolean mIsPsimDisableSupportedCache; 50 51 private List<SubscriptionAnnotation> mSubscriptionList; 52 53 private boolean mDisableReEntranceUpdate; 54 55 // Constructor MobileNetworkSummaryStatus()56 public MobileNetworkSummaryStatus() {} 57 58 /** 59 * Update the status 60 * @param context 61 * @param andThen Consumer which always performed by the end of #update() 62 * and avoid from repeated queries. 63 */ update(Context context, Consumer<MobileNetworkSummaryStatus> andThen)64 public void update(Context context, Consumer<MobileNetworkSummaryStatus> andThen) { 65 if (mDisableReEntranceUpdate) { 66 Log.d(LOG_TAG, "network summary query ignored"); 67 if (andThen != null) { 68 andThen.accept(this); 69 } 70 return; 71 } 72 mDisableReEntranceUpdate = true; 73 Log.d(LOG_TAG, "network summary query"); 74 75 // Query Euicc in background 76 mIsEuiccConfiguable = (Future<Boolean>) 77 ThreadUtils.postOnBackgroundThread(() -> isEuiccConfiguable(context)); 78 79 // Query display name in background 80 mUniqueNameMapping = (Future<Map<Integer, CharSequence>>) 81 ThreadUtils.postOnBackgroundThread(() -> getUniqueNameForDisplay(context)); 82 83 // Query support status of pSIM disable feature 84 mIsPsimDisableSupported = (Future<Boolean>) ThreadUtils.postOnBackgroundThread(() 85 -> isPhysicalSimDisableSupported(context)); 86 87 // Query subscription 88 mSubscriptionList = getSubscriptions(context); 89 90 if (andThen != null) { 91 andThen.accept(this); 92 } 93 mDisableReEntranceUpdate = false; 94 } 95 96 /** 97 * Get the subscription information 98 * @return a list of SubscriptionAnnotation 99 */ getSubscriptionList()100 public List<SubscriptionAnnotation> getSubscriptionList() { 101 return mSubscriptionList; 102 } 103 104 /** 105 * Get unique display name for a specific subscription 106 * @param subscriptionId subscription ID 107 * @return display name for that subscription 108 */ getDisplayName(int subscriptionId)109 public CharSequence getDisplayName(int subscriptionId) { 110 if (mUniqueNameMapping != null) { 111 try { 112 mUniqueNameMappingCache = mUniqueNameMapping.get(); 113 } catch (Exception exception) { 114 Log.w(LOG_TAG, "Fail to get display names", exception); 115 } 116 mUniqueNameMapping = null; 117 } 118 if (mUniqueNameMappingCache == null) { 119 return null; 120 } 121 return mUniqueNameMappingCache.get(subscriptionId); 122 } 123 124 // Check if Euicc is currently available isEuiccConfigSupport()125 public boolean isEuiccConfigSupport() { 126 if (mIsEuiccConfiguable != null) { 127 try { 128 mIsEuiccConfiguableCache = mIsEuiccConfiguable.get(); 129 } catch (Exception exception) { 130 Log.w(LOG_TAG, "Fail to get euicc config status", exception); 131 } 132 mIsEuiccConfiguable = null; 133 } 134 return (mIsEuiccConfiguableCache == null) ? 135 false : mIsEuiccConfiguableCache.booleanValue(); 136 } 137 138 // Check if disable physical SIM is supported isPhysicalSimDisableSupport()139 public boolean isPhysicalSimDisableSupport() { 140 if (mIsPsimDisableSupported != null) { 141 try { 142 mIsPsimDisableSupportedCache = mIsPsimDisableSupported.get(); 143 } catch (Exception exception) { 144 Log.w(LOG_TAG, "Fail to get pSIM disable support", exception); 145 } 146 mIsPsimDisableSupported = null; 147 } 148 return (mIsPsimDisableSupportedCache == null) ? 149 false : mIsPsimDisableSupportedCache.booleanValue(); 150 } 151 getSubscriptions(Context context)152 private List<SubscriptionAnnotation> getSubscriptions(Context context) { 153 return (new SelectableSubscriptions(context, true)) 154 155 // To maintain the consistency with SubscriptionUtil#getAvailableSubscriptions(). 156 .addFinisher(new SubscriptionGrouping()) 157 158 .call() 159 .stream() 160 .filter(SubscriptionAnnotation::isDisplayAllowed) 161 .collect(Collectors.toList()); 162 } 163 getUniqueNameForDisplay(Context context)164 private Map<Integer, CharSequence> getUniqueNameForDisplay(Context context) { 165 return SubscriptionUtil.getUniqueSubscriptionDisplayNames(context); 166 } 167 isPhysicalSimDisableSupported(Context context)168 private boolean isPhysicalSimDisableSupported(Context context) { 169 SubscriptionManager subMgr = context.getSystemService(SubscriptionManager.class); 170 return SubscriptionUtil.showToggleForPhysicalSim(subMgr); 171 } 172 isEuiccConfiguable(Context context)173 private boolean isEuiccConfiguable(Context context) { 174 return MobileNetworkUtils.showEuiccSettingsDetecting(context); 175 } 176 } 177