CarrierText.java revision e38c8e28ba50d5fe7f4f2bc5fe68a9f10bafe0f0
1/* 2 * Copyright (C) 2012 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 17package com.android.keyguard; 18 19import android.content.Context; 20import android.text.TextUtils; 21import android.util.AttributeSet; 22import android.widget.TextView; 23 24import com.android.internal.telephony.IccCardConstants; 25import com.android.internal.telephony.IccCardConstants.State; 26import com.android.internal.widget.LockPatternUtils; 27 28public class CarrierText extends TextView { 29 private static CharSequence mSeparator; 30 31 private LockPatternUtils mLockPatternUtils; 32 33 private KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() { 34 private CharSequence mPlmn; 35 private CharSequence mSpn; 36 private State mSimState; 37 38 @Override 39 public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { 40 mPlmn = plmn; 41 mSpn = spn; 42 updateCarrierText(mSimState, mPlmn, mSpn); 43 } 44 45 @Override 46 public void onSimStateChanged(IccCardConstants.State simState) { 47 mSimState = simState; 48 updateCarrierText(mSimState, mPlmn, mSpn); 49 } 50 }; 51 /** 52 * The status of this lock screen. Primarily used for widgets on LockScreen. 53 */ 54 private static enum StatusMode { 55 Normal, // Normal case (sim card present, it's not locked) 56 NetworkLocked, // SIM card is 'network locked'. 57 SimMissing, // SIM card is missing. 58 SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access 59 SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times 60 SimLocked, // SIM card is currently locked 61 SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure 62 SimNotReady; // SIM is not ready yet. May never be on devices w/o a SIM. 63 } 64 65 public CarrierText(Context context) { 66 this(context, null); 67 } 68 69 public CarrierText(Context context, AttributeSet attrs) { 70 super(context, attrs); 71 mLockPatternUtils = new LockPatternUtils(mContext); 72 } 73 74 protected void updateCarrierText(State simState, CharSequence plmn, CharSequence spn) { 75 setText(getCarrierTextForSimState(simState, plmn, spn)); 76 } 77 78 @Override 79 protected void onFinishInflate() { 80 super.onFinishInflate(); 81 mSeparator = getResources().getString(R.string.kg_text_message_separator); 82 setSelected(true); // Allow marquee to work. 83 } 84 85 @Override 86 protected void onAttachedToWindow() { 87 super.onAttachedToWindow(); 88 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mCallback); 89 } 90 91 @Override 92 protected void onDetachedFromWindow() { 93 super.onDetachedFromWindow(); 94 KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback); 95 } 96 97 /** 98 * Top-level function for creating carrier text. Makes text based on simState, PLMN 99 * and SPN as well as device capabilities, such as being emergency call capable. 100 * 101 * @param simState 102 * @param plmn 103 * @param spn 104 * @return 105 */ 106 private CharSequence getCarrierTextForSimState(IccCardConstants.State simState, 107 CharSequence plmn, CharSequence spn) { 108 CharSequence carrierText = null; 109 StatusMode status = getStatusForIccState(simState); 110 switch (status) { 111 case Normal: 112 carrierText = concatenate(plmn, spn); 113 break; 114 115 case SimNotReady: 116 carrierText = null; // nothing to display yet. 117 break; 118 119 case NetworkLocked: 120 carrierText = makeCarrierStringOnEmergencyCapable( 121 mContext.getText(R.string.keyguard_network_locked_message), plmn); 122 break; 123 124 case SimMissing: 125 // Shows "No SIM card | Emergency calls only" on devices that are voice-capable. 126 // This depends on mPlmn containing the text "Emergency calls only" when the radio 127 // has some connectivity. Otherwise, it should be null or empty and just show 128 // "No SIM card" 129 carrierText = makeCarrierStringOnEmergencyCapable( 130 getContext().getText(R.string.keyguard_missing_sim_message_short), 131 plmn); 132 break; 133 134 case SimPermDisabled: 135 carrierText = getContext().getText( 136 R.string.keyguard_permanent_disabled_sim_message_short); 137 break; 138 139 case SimMissingLocked: 140 carrierText = makeCarrierStringOnEmergencyCapable( 141 getContext().getText(R.string.keyguard_missing_sim_message_short), 142 plmn); 143 break; 144 145 case SimLocked: 146 carrierText = makeCarrierStringOnEmergencyCapable( 147 getContext().getText(R.string.keyguard_sim_locked_message), 148 plmn); 149 break; 150 151 case SimPukLocked: 152 carrierText = makeCarrierStringOnEmergencyCapable( 153 getContext().getText(R.string.keyguard_sim_puk_locked_message), 154 plmn); 155 break; 156 } 157 158 return carrierText; 159 } 160 161 /* 162 * Add emergencyCallMessage to carrier string only if phone supports emergency calls. 163 */ 164 private CharSequence makeCarrierStringOnEmergencyCapable( 165 CharSequence simMessage, CharSequence emergencyCallMessage) { 166 if (mLockPatternUtils.isEmergencyCallCapable()) { 167 return concatenate(simMessage, emergencyCallMessage); 168 } 169 return simMessage; 170 } 171 172 /** 173 * Determine the current status of the lock screen given the SIM state and other stuff. 174 */ 175 private StatusMode getStatusForIccState(IccCardConstants.State simState) { 176 // Since reading the SIM may take a while, we assume it is present until told otherwise. 177 if (simState == null) { 178 return StatusMode.Normal; 179 } 180 181 final boolean missingAndNotProvisioned = 182 !KeyguardUpdateMonitor.getInstance(mContext).isDeviceProvisioned() 183 && (simState == IccCardConstants.State.ABSENT || 184 simState == IccCardConstants.State.PERM_DISABLED); 185 186 // Assume we're NETWORK_LOCKED if not provisioned 187 simState = missingAndNotProvisioned ? IccCardConstants.State.NETWORK_LOCKED : simState; 188 switch (simState) { 189 case ABSENT: 190 return StatusMode.SimMissing; 191 case NETWORK_LOCKED: 192 return StatusMode.SimMissingLocked; 193 case NOT_READY: 194 return StatusMode.SimNotReady; 195 case PIN_REQUIRED: 196 return StatusMode.SimLocked; 197 case PUK_REQUIRED: 198 return StatusMode.SimPukLocked; 199 case READY: 200 return StatusMode.Normal; 201 case PERM_DISABLED: 202 return StatusMode.SimPermDisabled; 203 case UNKNOWN: 204 return StatusMode.SimMissing; 205 } 206 return StatusMode.SimMissing; 207 } 208 209 private static CharSequence concatenate(CharSequence plmn, CharSequence spn) { 210 final boolean plmnValid = !TextUtils.isEmpty(plmn); 211 final boolean spnValid = !TextUtils.isEmpty(spn); 212 if (plmnValid && spnValid) { 213 return new StringBuilder().append(plmn).append(mSeparator).append(spn).toString(); 214 } else if (plmnValid) { 215 return plmn; 216 } else if (spnValid) { 217 return spn; 218 } else { 219 return ""; 220 } 221 } 222 223 private CharSequence getCarrierHelpTextForSimState(IccCardConstants.State simState, 224 String plmn, String spn) { 225 int carrierHelpTextId = 0; 226 StatusMode status = getStatusForIccState(simState); 227 switch (status) { 228 case NetworkLocked: 229 carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled; 230 break; 231 232 case SimMissing: 233 carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long; 234 break; 235 236 case SimPermDisabled: 237 carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions; 238 break; 239 240 case SimMissingLocked: 241 carrierHelpTextId = R.string.keyguard_missing_sim_instructions; 242 break; 243 244 case Normal: 245 case SimLocked: 246 case SimPukLocked: 247 break; 248 } 249 250 return mContext.getText(carrierHelpTextId); 251 } 252} 253