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