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