blob: 9f0a042f040b838e14a2c9c1cf8ed7e593740b3f [file] [log] [blame]
Jim Miller109f1fd2012-09-19 20:44:16 -07001/*
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
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
Jim Millerf9cb7ba2012-09-17 22:31:56 -070018
19import android.content.Context;
20import android.text.TextUtils;
21import android.util.AttributeSet;
22import android.widget.TextView;
23
Jim Millerf9cb7ba2012-09-17 22:31:56 -070024import com.android.internal.telephony.IccCardConstants;
25import com.android.internal.telephony.IccCardConstants.State;
26import com.android.internal.widget.LockPatternUtils;
27
28public class CarrierText extends TextView {
Jim Millere9be1402012-11-01 16:14:20 -070029 private static CharSequence mSeparator;
30
Jim Millerf9cb7ba2012-09-17 22:31:56 -070031 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 */
Jim Miller109f1fd2012-09-19 20:44:16 -070054 private static enum StatusMode {
Jim Millerf9cb7ba2012-09-17 22:31:56 -070055 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
Jim Miller109f1fd2012-09-19 20:44:16 -070061 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.
Jim Millerf9cb7ba2012-09-17 22:31:56 -070063 }
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) {
Jim Miller109f1fd2012-09-19 20:44:16 -070075 CharSequence text = getCarrierTextForSimState(simState, plmn, spn);
76 if (KeyguardViewManager.USE_UPPER_CASE) {
77 setText(text != null ? text.toString().toUpperCase() : null);
78 } else {
79 setText(text);
80 }
Jim Millerf9cb7ba2012-09-17 22:31:56 -070081 }
82
83 @Override
84 protected void onFinishInflate() {
85 super.onFinishInflate();
Jim Millere9be1402012-11-01 16:14:20 -070086 mSeparator = getResources().getString(R.string.kg_text_message_separator);
Jim Millerf9cb7ba2012-09-17 22:31:56 -070087 setSelected(true); // Allow marquee to work.
88 }
89
Jim Miller0928e012012-11-06 18:43:22 -080090 @Override
91 protected void onAttachedToWindow() {
92 super.onAttachedToWindow();
93 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mCallback);
94 }
95
96 @Override
97 protected void onDetachedFromWindow() {
98 super.onDetachedFromWindow();
99 KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback);
100 }
101
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700102 /**
103 * Top-level function for creating carrier text. Makes text based on simState, PLMN
104 * and SPN as well as device capabilities, such as being emergency call capable.
105 *
106 * @param simState
107 * @param plmn
108 * @param spn
109 * @return
110 */
111 private CharSequence getCarrierTextForSimState(IccCardConstants.State simState,
112 CharSequence plmn, CharSequence spn) {
113 CharSequence carrierText = null;
114 StatusMode status = getStatusForIccState(simState);
115 switch (status) {
116 case Normal:
117 carrierText = concatenate(plmn, spn);
118 break;
119
Jim Miller109f1fd2012-09-19 20:44:16 -0700120 case SimNotReady:
121 carrierText = null; // nothing to display yet.
122 break;
123
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700124 case NetworkLocked:
125 carrierText = makeCarrierStringOnEmergencyCapable(
Jim Miller5ecd8112013-01-09 18:50:26 -0800126 mContext.getText(R.string.keyguard_network_locked_message), plmn);
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700127 break;
128
129 case SimMissing:
130 // Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
131 // This depends on mPlmn containing the text "Emergency calls only" when the radio
132 // has some connectivity. Otherwise, it should be null or empty and just show
133 // "No SIM card"
134 carrierText = makeCarrierStringOnEmergencyCapable(
Jim Miller5ecd8112013-01-09 18:50:26 -0800135 getContext().getText(R.string.keyguard_missing_sim_message_short),
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700136 plmn);
137 break;
138
139 case SimPermDisabled:
140 carrierText = getContext().getText(
Jim Miller5ecd8112013-01-09 18:50:26 -0800141 R.string.keyguard_permanent_disabled_sim_message_short);
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700142 break;
143
144 case SimMissingLocked:
145 carrierText = makeCarrierStringOnEmergencyCapable(
Jim Miller5ecd8112013-01-09 18:50:26 -0800146 getContext().getText(R.string.keyguard_missing_sim_message_short),
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700147 plmn);
148 break;
149
150 case SimLocked:
151 carrierText = makeCarrierStringOnEmergencyCapable(
Jim Miller5ecd8112013-01-09 18:50:26 -0800152 getContext().getText(R.string.keyguard_sim_locked_message),
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700153 plmn);
154 break;
155
156 case SimPukLocked:
157 carrierText = makeCarrierStringOnEmergencyCapable(
Jim Miller5ecd8112013-01-09 18:50:26 -0800158 getContext().getText(R.string.keyguard_sim_puk_locked_message),
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700159 plmn);
160 break;
161 }
162
163 return carrierText;
164 }
165
166 /*
167 * Add emergencyCallMessage to carrier string only if phone supports emergency calls.
168 */
169 private CharSequence makeCarrierStringOnEmergencyCapable(
170 CharSequence simMessage, CharSequence emergencyCallMessage) {
171 if (mLockPatternUtils.isEmergencyCallCapable()) {
172 return concatenate(simMessage, emergencyCallMessage);
173 }
174 return simMessage;
175 }
176
177 /**
178 * Determine the current status of the lock screen given the SIM state and other stuff.
179 */
180 private StatusMode getStatusForIccState(IccCardConstants.State simState) {
181 // Since reading the SIM may take a while, we assume it is present until told otherwise.
182 if (simState == null) {
183 return StatusMode.Normal;
184 }
185
186 final boolean missingAndNotProvisioned =
187 !KeyguardUpdateMonitor.getInstance(mContext).isDeviceProvisioned()
188 && (simState == IccCardConstants.State.ABSENT ||
189 simState == IccCardConstants.State.PERM_DISABLED);
190
191 // Assume we're NETWORK_LOCKED if not provisioned
192 simState = missingAndNotProvisioned ? IccCardConstants.State.NETWORK_LOCKED : simState;
193 switch (simState) {
194 case ABSENT:
195 return StatusMode.SimMissing;
196 case NETWORK_LOCKED:
197 return StatusMode.SimMissingLocked;
198 case NOT_READY:
Jim Miller109f1fd2012-09-19 20:44:16 -0700199 return StatusMode.SimNotReady;
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700200 case PIN_REQUIRED:
201 return StatusMode.SimLocked;
202 case PUK_REQUIRED:
203 return StatusMode.SimPukLocked;
204 case READY:
205 return StatusMode.Normal;
206 case PERM_DISABLED:
207 return StatusMode.SimPermDisabled;
208 case UNKNOWN:
209 return StatusMode.SimMissing;
210 }
211 return StatusMode.SimMissing;
212 }
213
214 private static CharSequence concatenate(CharSequence plmn, CharSequence spn) {
215 final boolean plmnValid = !TextUtils.isEmpty(plmn);
216 final boolean spnValid = !TextUtils.isEmpty(spn);
217 if (plmnValid && spnValid) {
Jim Millere9be1402012-11-01 16:14:20 -0700218 return new StringBuilder().append(plmn).append(mSeparator).append(spn).toString();
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700219 } else if (plmnValid) {
220 return plmn;
221 } else if (spnValid) {
222 return spn;
223 } else {
224 return "";
225 }
226 }
227
228 private CharSequence getCarrierHelpTextForSimState(IccCardConstants.State simState,
229 String plmn, String spn) {
230 int carrierHelpTextId = 0;
231 StatusMode status = getStatusForIccState(simState);
232 switch (status) {
233 case NetworkLocked:
Jim Miller5ecd8112013-01-09 18:50:26 -0800234 carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled;
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700235 break;
236
237 case SimMissing:
Jim Miller5ecd8112013-01-09 18:50:26 -0800238 carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long;
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700239 break;
240
241 case SimPermDisabled:
Jim Miller5ecd8112013-01-09 18:50:26 -0800242 carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions;
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700243 break;
244
245 case SimMissingLocked:
Jim Miller5ecd8112013-01-09 18:50:26 -0800246 carrierHelpTextId = R.string.keyguard_missing_sim_instructions;
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700247 break;
248
249 case Normal:
250 case SimLocked:
251 case SimPukLocked:
252 break;
253 }
254
255 return mContext.getText(carrierHelpTextId);
256 }
257}