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 if (!SubscriptionUtil.isSimHardwareVisible(mContext) || Utils.isWifiOnly(mContext)) { 136 return UNSUPPORTED_ON_DEVICE; 137 } 138 if (!mContext.getSystemService(UserManager.class).isAdminUser()) { 139 return DISABLED_FOR_USER; 140 } 141 return AVAILABLE; 142 } 143 144 @Override useDynamicSliceSummary()145 public boolean useDynamicSliceSummary() { 146 return true; 147 } 148 149 @VisibleForTesting updatePreference(Preference preference, int simSlot)150 protected void updatePreference(Preference preference, int simSlot) { 151 if (simSlot < 0) { 152 preference.setVisible(false); 153 return; 154 } 155 preference.setTitle(getTitle(simSlot)); 156 preference.setSummary(getSummary(simSlot)); 157 } 158 getTitleForGsmPhone(int simSlot, boolean isPrimaryImei)159 private CharSequence getTitleForGsmPhone(int simSlot, boolean isPrimaryImei) { 160 int titleId = isPrimaryImei ? R.string.imei_multi_sim_primary : R.string.imei_multi_sim; 161 return isMultiSim() ? mContext.getString(titleId, simSlot + 1) 162 : mContext.getString(R.string.status_imei); 163 } 164 getTitleForCdmaPhone(int simSlot, boolean isPrimaryImei)165 private CharSequence getTitleForCdmaPhone(int simSlot, boolean isPrimaryImei) { 166 int titleId = isPrimaryImei ? R.string.meid_multi_sim_primary : R.string.meid_multi_sim; 167 return isMultiSim() ? mContext.getString(titleId, simSlot + 1) 168 : mContext.getString(R.string.status_meid_number); 169 } 170 isPrimaryImei(int simSlot)171 protected boolean isPrimaryImei(int simSlot) { 172 CharSequence imei = getSummary(simSlot); 173 if (imei == null) { 174 return false; 175 } 176 String primaryImei = null; 177 try { 178 primaryImei = mTelephonyManager.getPrimaryImei(); 179 } catch (Exception exception) { 180 Log.i(TAG, "PrimaryImei not available. " + exception); 181 } 182 return (primaryImei != null) && primaryImei.equals(imei.toString()); 183 } 184 getTitle(int simSlot)185 private CharSequence getTitle(int simSlot) { 186 boolean isPrimaryImei = isMultiSim() && isPrimaryImei(simSlot); 187 final int phoneType = getPhoneType(simSlot); 188 return phoneType == PHONE_TYPE_CDMA ? getTitleForCdmaPhone(simSlot, isPrimaryImei) 189 : getTitleForGsmPhone(simSlot, isPrimaryImei); 190 } 191 getPhoneType(int slotIndex)192 public int getPhoneType(int slotIndex) { 193 SubscriptionInfo subInfo = getSubscriptionInfo(slotIndex); 194 return mTelephonyManager.getCurrentPhoneType(subInfo != null ? subInfo.getSubscriptionId() 195 : SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); 196 } 197 198 @VisibleForTesting createNewPreference(Context context)199 Preference createNewPreference(Context context) { 200 return new Preference(context); 201 } 202 } 203