blob: 88558cd420bff807d70d80d9d976d0c9fc0399fa [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;
Victoria Lease1d80e972013-11-01 16:34:03 -070020import android.text.method.SingleLineTransformationMethod;
Jim Millerf9cb7ba2012-09-17 22:31:56 -070021import android.text.TextUtils;
22import android.util.AttributeSet;
Victoria Lease1d80e972013-11-01 16:34:03 -070023import android.view.View;
Jim Millerf9cb7ba2012-09-17 22:31:56 -070024import android.widget.TextView;
25
Jim Millerf9cb7ba2012-09-17 22:31:56 -070026import com.android.internal.telephony.IccCardConstants;
27import com.android.internal.telephony.IccCardConstants.State;
28import com.android.internal.widget.LockPatternUtils;
29
Victoria Lease1d80e972013-11-01 16:34:03 -070030import java.util.Locale;
31
Jim Millerf9cb7ba2012-09-17 22:31:56 -070032public class CarrierText extends TextView {
Jim Millere9be1402012-11-01 16:14:20 -070033 private static CharSequence mSeparator;
34
Jim Millerf9cb7ba2012-09-17 22:31:56 -070035 private LockPatternUtils mLockPatternUtils;
36
37 private KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
38 private CharSequence mPlmn;
39 private CharSequence mSpn;
40 private State mSimState;
41
42 @Override
43 public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
44 mPlmn = plmn;
45 mSpn = spn;
46 updateCarrierText(mSimState, mPlmn, mSpn);
47 }
48
49 @Override
50 public void onSimStateChanged(IccCardConstants.State simState) {
51 mSimState = simState;
52 updateCarrierText(mSimState, mPlmn, mSpn);
53 }
Jim Miller20daffd2013-10-07 14:59:53 -070054
55 public void onScreenTurnedOff(int why) {
56 setSelected(false);
57 };
58
59 public void onScreenTurnedOn() {
60 setSelected(true);
61 };
Jim Millerf9cb7ba2012-09-17 22:31:56 -070062 };
63 /**
64 * The status of this lock screen. Primarily used for widgets on LockScreen.
65 */
Jim Miller109f1fd2012-09-19 20:44:16 -070066 private static enum StatusMode {
Jim Millerf9cb7ba2012-09-17 22:31:56 -070067 Normal, // Normal case (sim card present, it's not locked)
68 NetworkLocked, // SIM card is 'network locked'.
69 SimMissing, // SIM card is missing.
70 SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access
71 SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times
72 SimLocked, // SIM card is currently locked
Jim Miller109f1fd2012-09-19 20:44:16 -070073 SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure
74 SimNotReady; // SIM is not ready yet. May never be on devices w/o a SIM.
Jim Millerf9cb7ba2012-09-17 22:31:56 -070075 }
76
77 public CarrierText(Context context) {
78 this(context, null);
79 }
80
81 public CarrierText(Context context, AttributeSet attrs) {
82 super(context, attrs);
83 mLockPatternUtils = new LockPatternUtils(mContext);
Victoria Lease1d80e972013-11-01 16:34:03 -070084 boolean useAllCaps = mContext.getResources().getBoolean(R.bool.kg_use_all_caps);
85 setTransformationMethod(new CarrierTextTransformationMethod(mContext, useAllCaps));
Jim Millerf9cb7ba2012-09-17 22:31:56 -070086 }
87
88 protected void updateCarrierText(State simState, CharSequence plmn, CharSequence spn) {
Jim Millere38c8e22013-09-24 15:54:04 -070089 setText(getCarrierTextForSimState(simState, plmn, spn));
Jim Millerf9cb7ba2012-09-17 22:31:56 -070090 }
91
92 @Override
93 protected void onFinishInflate() {
94 super.onFinishInflate();
Jim Millere9be1402012-11-01 16:14:20 -070095 mSeparator = getResources().getString(R.string.kg_text_message_separator);
Jim Miller20daffd2013-10-07 14:59:53 -070096 final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
97 setSelected(screenOn); // Allow marquee to work.
Jim Millerf9cb7ba2012-09-17 22:31:56 -070098 }
99
Jim Miller0928e012012-11-06 18:43:22 -0800100 @Override
101 protected void onAttachedToWindow() {
102 super.onAttachedToWindow();
103 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mCallback);
104 }
105
106 @Override
107 protected void onDetachedFromWindow() {
108 super.onDetachedFromWindow();
109 KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mCallback);
110 }
111
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700112 /**
113 * Top-level function for creating carrier text. Makes text based on simState, PLMN
114 * and SPN as well as device capabilities, such as being emergency call capable.
115 *
116 * @param simState
117 * @param plmn
118 * @param spn
119 * @return
120 */
121 private CharSequence getCarrierTextForSimState(IccCardConstants.State simState,
122 CharSequence plmn, CharSequence spn) {
123 CharSequence carrierText = null;
124 StatusMode status = getStatusForIccState(simState);
125 switch (status) {
126 case Normal:
127 carrierText = concatenate(plmn, spn);
128 break;
129
Jim Miller109f1fd2012-09-19 20:44:16 -0700130 case SimNotReady:
131 carrierText = null; // nothing to display yet.
132 break;
133
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700134 case NetworkLocked:
135 carrierText = makeCarrierStringOnEmergencyCapable(
Jim Miller5ecd8112013-01-09 18:50:26 -0800136 mContext.getText(R.string.keyguard_network_locked_message), plmn);
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700137 break;
138
139 case SimMissing:
140 // Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
141 // This depends on mPlmn containing the text "Emergency calls only" when the radio
142 // has some connectivity. Otherwise, it should be null or empty and just show
143 // "No SIM card"
144 carrierText = makeCarrierStringOnEmergencyCapable(
Jim Miller5ecd8112013-01-09 18:50:26 -0800145 getContext().getText(R.string.keyguard_missing_sim_message_short),
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700146 plmn);
147 break;
148
149 case SimPermDisabled:
150 carrierText = getContext().getText(
Jim Miller5ecd8112013-01-09 18:50:26 -0800151 R.string.keyguard_permanent_disabled_sim_message_short);
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700152 break;
153
154 case SimMissingLocked:
155 carrierText = makeCarrierStringOnEmergencyCapable(
Jim Miller5ecd8112013-01-09 18:50:26 -0800156 getContext().getText(R.string.keyguard_missing_sim_message_short),
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700157 plmn);
158 break;
159
160 case SimLocked:
161 carrierText = makeCarrierStringOnEmergencyCapable(
Jim Miller5ecd8112013-01-09 18:50:26 -0800162 getContext().getText(R.string.keyguard_sim_locked_message),
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700163 plmn);
164 break;
165
166 case SimPukLocked:
167 carrierText = makeCarrierStringOnEmergencyCapable(
Jim Miller5ecd8112013-01-09 18:50:26 -0800168 getContext().getText(R.string.keyguard_sim_puk_locked_message),
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700169 plmn);
170 break;
171 }
172
173 return carrierText;
174 }
175
176 /*
177 * Add emergencyCallMessage to carrier string only if phone supports emergency calls.
178 */
179 private CharSequence makeCarrierStringOnEmergencyCapable(
180 CharSequence simMessage, CharSequence emergencyCallMessage) {
181 if (mLockPatternUtils.isEmergencyCallCapable()) {
182 return concatenate(simMessage, emergencyCallMessage);
183 }
184 return simMessage;
185 }
186
187 /**
188 * Determine the current status of the lock screen given the SIM state and other stuff.
189 */
190 private StatusMode getStatusForIccState(IccCardConstants.State simState) {
191 // Since reading the SIM may take a while, we assume it is present until told otherwise.
192 if (simState == null) {
193 return StatusMode.Normal;
194 }
195
196 final boolean missingAndNotProvisioned =
197 !KeyguardUpdateMonitor.getInstance(mContext).isDeviceProvisioned()
198 && (simState == IccCardConstants.State.ABSENT ||
199 simState == IccCardConstants.State.PERM_DISABLED);
200
201 // Assume we're NETWORK_LOCKED if not provisioned
202 simState = missingAndNotProvisioned ? IccCardConstants.State.NETWORK_LOCKED : simState;
203 switch (simState) {
204 case ABSENT:
205 return StatusMode.SimMissing;
206 case NETWORK_LOCKED:
207 return StatusMode.SimMissingLocked;
208 case NOT_READY:
Jim Miller109f1fd2012-09-19 20:44:16 -0700209 return StatusMode.SimNotReady;
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700210 case PIN_REQUIRED:
211 return StatusMode.SimLocked;
212 case PUK_REQUIRED:
213 return StatusMode.SimPukLocked;
214 case READY:
215 return StatusMode.Normal;
216 case PERM_DISABLED:
217 return StatusMode.SimPermDisabled;
218 case UNKNOWN:
219 return StatusMode.SimMissing;
220 }
221 return StatusMode.SimMissing;
222 }
223
224 private static CharSequence concatenate(CharSequence plmn, CharSequence spn) {
225 final boolean plmnValid = !TextUtils.isEmpty(plmn);
226 final boolean spnValid = !TextUtils.isEmpty(spn);
227 if (plmnValid && spnValid) {
Jim Millere9be1402012-11-01 16:14:20 -0700228 return new StringBuilder().append(plmn).append(mSeparator).append(spn).toString();
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700229 } else if (plmnValid) {
230 return plmn;
231 } else if (spnValid) {
232 return spn;
233 } else {
234 return "";
235 }
236 }
237
238 private CharSequence getCarrierHelpTextForSimState(IccCardConstants.State simState,
239 String plmn, String spn) {
240 int carrierHelpTextId = 0;
241 StatusMode status = getStatusForIccState(simState);
242 switch (status) {
243 case NetworkLocked:
Jim Miller5ecd8112013-01-09 18:50:26 -0800244 carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled;
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700245 break;
246
247 case SimMissing:
Jim Miller5ecd8112013-01-09 18:50:26 -0800248 carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long;
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700249 break;
250
251 case SimPermDisabled:
Jim Miller5ecd8112013-01-09 18:50:26 -0800252 carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions;
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700253 break;
254
255 case SimMissingLocked:
Jim Miller5ecd8112013-01-09 18:50:26 -0800256 carrierHelpTextId = R.string.keyguard_missing_sim_instructions;
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700257 break;
258
259 case Normal:
260 case SimLocked:
261 case SimPukLocked:
262 break;
263 }
264
265 return mContext.getText(carrierHelpTextId);
266 }
Victoria Lease1d80e972013-11-01 16:34:03 -0700267
268 private class CarrierTextTransformationMethod extends SingleLineTransformationMethod {
269 private final Locale mLocale;
270 private final boolean mAllCaps;
271
272 public CarrierTextTransformationMethod(Context context, boolean allCaps) {
273 mLocale = context.getResources().getConfiguration().locale;
274 mAllCaps = allCaps;
275 }
276
277 @Override
278 public CharSequence getTransformation(CharSequence source, View view) {
279 source = super.getTransformation(source, view);
280
281 if (mAllCaps && source != null) {
282 source = source.toString().toUpperCase(mLocale);
283 }
284
285 return source;
286 }
287 }
Jim Millerf9cb7ba2012-09-17 22:31:56 -0700288}