1 /* 2 * Copyright (C) 2017 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.deviceinfo.imei; 18 19 import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA; 20 21 import android.content.Context; 22 import android.os.UserManager; 23 import android.telephony.SubscriptionInfo; 24 import android.telephony.SubscriptionManager; 25 import android.telephony.TelephonyManager; 26 import android.util.Log; 27 28 import androidx.annotation.VisibleForTesting; 29 import androidx.fragment.app.Fragment; 30 import androidx.preference.Preference; 31 import androidx.preference.PreferenceCategory; 32 import androidx.preference.PreferenceScreen; 33 34 import com.android.settings.R; 35 import com.android.settings.core.BasePreferenceController; 36 import com.android.settings.deviceinfo.simstatus.SlotSimStatus; 37 import com.android.settings.network.SubscriptionUtil; 38 import com.android.settingslib.Utils; 39 40 /** 41 * Controller that manages preference for single and multi sim devices. 42 */ 43 public class ImeiInfoPreferenceController extends BasePreferenceController { 44 45 private static final String TAG = "ImeiInfoPreferenceController"; 46 47 private static final String KEY_PREFERENCE_CATEGORY = "device_detail_category"; 48 public static final String DEFAULT_KEY = "imei_info"; 49 50 private TelephonyManager mTelephonyManager; 51 private Fragment mFragment; 52 private SlotSimStatus mSlotSimStatus; 53 ImeiInfoPreferenceController(Context context, String key)54 public ImeiInfoPreferenceController(Context context, String key) { 55 super(context, key); 56 } 57 init(Fragment fragment, SlotSimStatus slotSimStatus)58 public void init(Fragment fragment, SlotSimStatus slotSimStatus) { 59 mFragment = fragment; 60 mSlotSimStatus = slotSimStatus; 61 } 62 isMultiSim()63 private boolean isMultiSim() { 64 return (mSlotSimStatus != null) && (mSlotSimStatus.size() > 1); 65 } 66 keyToSlotIndex(String key)67 private int keyToSlotIndex(String key) { 68 int simSlot = SubscriptionManager.INVALID_SIM_SLOT_INDEX; 69 try { 70 simSlot = Integer.valueOf(key.replace(DEFAULT_KEY, "")) - 1; 71 } catch (Exception exception) { 72 Log.i(TAG, "Invalid key : " + key); 73 } 74 return simSlot; 75 } 76 getSubscriptionInfo(int simSlot)77 private SubscriptionInfo getSubscriptionInfo(int simSlot) { 78 return (mSlotSimStatus == null) ? null : mSlotSimStatus.getSubscriptionInfo(simSlot); 79 } 80 81 @Override displayPreference(PreferenceScreen screen)82 public void displayPreference(PreferenceScreen screen) { 83 super.displayPreference(screen); 84 if ((!SubscriptionUtil.isSimHardwareVisible(mContext)) || (mSlotSimStatus == null)) { 85 return; 86 } 87 mTelephonyManager = mContext.getSystemService(TelephonyManager.class); 88 Preference preference = screen.findPreference(DEFAULT_KEY); 89 if (!isAvailable() || preference == null || !preference.isVisible()) { 90 return; 91 } 92 PreferenceCategory category = screen.findPreference(KEY_PREFERENCE_CATEGORY); 93 94 int imeiPreferenceOrder = preference.getOrder(); 95 screen.removePreference(preference); 96 preference.setVisible(false); 97 98 // Add additional preferences for each imei slot in the device 99 for (int simSlotNumber = 0; simSlotNumber < mSlotSimStatus.size(); simSlotNumber++) { 100 Preference multiImeiPreference = createNewPreference(screen.getContext()); 101 multiImeiPreference.setOrder(imeiPreferenceOrder + 1 + simSlotNumber); 102 multiImeiPreference.setKey(DEFAULT_KEY + (1 + simSlotNumber)); 103 multiImeiPreference.setEnabled(true); 104 multiImeiPreference.setCopyingEnabled(true); 105 106 category.addPreference(multiImeiPreference); 107 } 108 } 109 110 @Override updateState(Preference preference)111 public void updateState(Preference preference) { 112 updatePreference(preference, keyToSlotIndex(preference.getKey())); 113 } 114 getSummary(int simSlot)115 private CharSequence getSummary(int simSlot) { 116 final int phoneType = getPhoneType(simSlot); 117 return phoneType == PHONE_TYPE_CDMA ? mTelephonyManager.getMeid(simSlot) 118 : mTelephonyManager.getImei(simSlot); 119 } 120 121 @Override handlePreferenceTreeClick(Preference preference)122 public boolean handlePreferenceTreeClick(Preference preference) { 123 final int simSlot = keyToSlotIndex(preference.getKey()); 124 if (simSlot < 0) { 125 return false; 126 } 127 128 ImeiInfoDialogFragment.show(mFragment, simSlot, preference.getTitle().toString()); 129 preference.setSummary(getSummary(simSlot)); 130 return true; 131 } 132 133 @Override getAvailabilityStatus()134 public int getAvailabilityStatus() { 135 boolean isAvailable = SubscriptionUtil.isSimHardwareVisible(mContext) && 136 mContext.getSystemService(UserManager.class).isAdminUser() && 137 !Utils.isWifiOnly(mContext); 138 return isAvailable ? AVAILABLE : UNSUPPORTED_ON_DEVICE; 139 } 140 141 @Override useDynamicSliceSummary()142 public boolean useDynamicSliceSummary() { 143 return true; 144 } 145 146 @VisibleForTesting updatePreference(Preference preference, int simSlot)147 protected void updatePreference(Preference preference, int simSlot) { 148 if (simSlot < 0) { 149 preference.setVisible(false); 150 return; 151 } 152 preference.setTitle(getTitle(simSlot)); 153 preference.setSummary(getSummary(simSlot)); 154 } 155 getTitleForGsmPhone(int simSlot, boolean isPrimaryImei)156 private CharSequence getTitleForGsmPhone(int simSlot, boolean isPrimaryImei) { 157 int titleId = isPrimaryImei ? R.string.imei_multi_sim_primary : R.string.imei_multi_sim; 158 return isMultiSim() ? mContext.getString(titleId, simSlot + 1) 159 : mContext.getString(R.string.status_imei); 160 } 161 getTitleForCdmaPhone(int simSlot, boolean isPrimaryImei)162 private CharSequence getTitleForCdmaPhone(int simSlot, boolean isPrimaryImei) { 163 int titleId = isPrimaryImei ? R.string.meid_multi_sim_primary : R.string.meid_multi_sim; 164 return isMultiSim() ? mContext.getString(titleId, simSlot + 1) 165 : mContext.getString(R.string.status_meid_number); 166 } 167 isPrimaryImei(int simSlot)168 protected boolean isPrimaryImei(int simSlot) { 169 CharSequence imei = getSummary(simSlot); 170 if (imei == null) { 171 return false; 172 } 173 String primaryImei = null; 174 try { 175 primaryImei = mTelephonyManager.getPrimaryImei(); 176 } catch (Exception exception) { 177 Log.i(TAG, "PrimaryImei not available. " + exception); 178 } 179 return (primaryImei != null) && primaryImei.equals(imei.toString()); 180 } 181 getTitle(int simSlot)182 private CharSequence getTitle(int simSlot) { 183 boolean isPrimaryImei = isMultiSim() && isPrimaryImei(simSlot); 184 final int phoneType = getPhoneType(simSlot); 185 return phoneType == PHONE_TYPE_CDMA ? getTitleForCdmaPhone(simSlot, isPrimaryImei) 186 : getTitleForGsmPhone(simSlot, isPrimaryImei); 187 } 188 getPhoneType(int slotIndex)189 public int getPhoneType(int slotIndex) { 190 SubscriptionInfo subInfo = getSubscriptionInfo(slotIndex); 191 return mTelephonyManager.getCurrentPhoneType(subInfo != null ? subInfo.getSubscriptionId() 192 : SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); 193 } 194 195 @VisibleForTesting createNewPreference(Context context)196 Preference createNewPreference(Context context) { 197 return new Preference(context); 198 } 199 } 200