1109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller/*
2109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller * Copyright (C) 2012 The Android Open Source Project
3109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller *
4109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller * Licensed under the Apache License, Version 2.0 (the "License");
5109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller * you may not use this file except in compliance with the License.
6109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller * You may obtain a copy of the License at
7109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller *
8109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller *      http://www.apache.org/licenses/LICENSE-2.0
9109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller *
10109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller * Unless required by applicable law or agreed to in writing, software
11109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller * distributed under the License is distributed on an "AS IS" BASIS,
12109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller * See the License for the specific language governing permissions and
14109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller * limitations under the License.
15109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller */
16109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller
175ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Millerpackage com.android.keyguard;
18f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
199ff69bd8f115e70a16c72c798449908536a173eaJason Monkimport java.util.List;
209ff69bd8f115e70a16c72c798449908536a173eaJason Monkimport java.util.Locale;
21b8726b7002aa39c7a01245212d35ac9296c58a1aSanket Padaweimport java.util.Objects;
229ff69bd8f115e70a16c72c798449908536a173eaJason Monk
23f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Millerimport android.content.Context;
24de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monkimport android.content.Intent;
25de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monkimport android.content.IntentFilter;
2625807936e8e4ca2c811bb4121725e1dd87e18efdJorim Jaggiimport android.content.res.TypedArray;
2783bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monkimport android.net.ConnectivityManager;
2847051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohenimport android.net.wifi.WifiManager;
2947051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohenimport android.telephony.ServiceState;
309ff69bd8f115e70a16c72c798449908536a173eaJason Monkimport android.telephony.SubscriptionInfo;
31f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Millerimport android.text.TextUtils;
329ff69bd8f115e70a16c72c798449908536a173eaJason Monkimport android.text.method.SingleLineTransformationMethod;
33f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Millerimport android.util.AttributeSet;
349ff69bd8f115e70a16c72c798449908536a173eaJason Monkimport android.util.Log;
351d80e977da89a660aff006e93470749b359c2393Victoria Leaseimport android.view.View;
36f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Millerimport android.widget.TextView;
37f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
38f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Millerimport com.android.internal.telephony.IccCardConstants;
39f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Millerimport com.android.internal.telephony.IccCardConstants.State;
40de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monkimport com.android.internal.telephony.TelephonyIntents;
41726fb28248a2d0d13123ec808a1e28c813aa7fb5Jason Monkimport com.android.settingslib.WirelessUtils;
42f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
43f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Millerpublic class CarrierText extends TextView {
449ff69bd8f115e70a16c72c798449908536a173eaJason Monk    private static final boolean DEBUG = KeyguardConstants.DEBUG;
459ff69bd8f115e70a16c72c798449908536a173eaJason Monk    private static final String TAG = "CarrierText";
469ff69bd8f115e70a16c72c798449908536a173eaJason Monk
47e9be14077161b9c5dcaa521e9ce4d3e017c11ac6Jim Miller    private static CharSequence mSeparator;
48e9be14077161b9c5dcaa521e9ce4d3e017c11ac6Jim Miller
49c2e01683b34029729262e2fb346ceea4bfe4b4b6Adrian Roos    private final boolean mIsEmergencyCallCapable;
50c2e01683b34029729262e2fb346ceea4bfe4b4b6Adrian Roos
519ff69bd8f115e70a16c72c798449908536a173eaJason Monk    private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
52f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
5347051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen    private WifiManager mWifiManager;
5447051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen
55f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    private KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
56f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        @Override
579ff69bd8f115e70a16c72c798449908536a173eaJason Monk        public void onRefreshCarrierInfo() {
589ff69bd8f115e70a16c72c798449908536a173eaJason Monk            updateCarrierText();
59f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        }
6020daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller
610d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        public void onFinishedGoingToSleep(int why) {
6220daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller            setSelected(false);
6320daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller        };
6420daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller
650d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        public void onStartedWakingUp() {
6620daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller            setSelected(true);
6720daffd91e4a53054f8c4d7a66c2a68100abee03Jim Miller        };
68f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    };
69f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    /**
70f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller     * The status of this lock screen. Primarily used for widgets on LockScreen.
71f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller     */
72109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller    private static enum StatusMode {
73f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        Normal, // Normal case (sim card present, it's not locked)
74f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        NetworkLocked, // SIM card is 'network locked'.
75f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        SimMissing, // SIM card is missing.
76f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access
77f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times
78f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        SimLocked, // SIM card is currently locked
79109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller        SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure
80109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller        SimNotReady; // SIM is not ready yet. May never be on devices w/o a SIM.
81f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    }
82f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
83f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    public CarrierText(Context context) {
84f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        this(context, null);
85f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    }
86f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
87f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    public CarrierText(Context context, AttributeSet attrs) {
88f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        super(context, attrs);
89c2e01683b34029729262e2fb346ceea4bfe4b4b6Adrian Roos        mIsEmergencyCallCapable = context.getResources().getBoolean(
90c2e01683b34029729262e2fb346ceea4bfe4b4b6Adrian Roos                com.android.internal.R.bool.config_voice_capable);
9125807936e8e4ca2c811bb4121725e1dd87e18efdJorim Jaggi        boolean useAllCaps;
9225807936e8e4ca2c811bb4121725e1dd87e18efdJorim Jaggi        TypedArray a = context.getTheme().obtainStyledAttributes(
9325807936e8e4ca2c811bb4121725e1dd87e18efdJorim Jaggi                attrs, R.styleable.CarrierText, 0, 0);
9425807936e8e4ca2c811bb4121725e1dd87e18efdJorim Jaggi        try {
9525807936e8e4ca2c811bb4121725e1dd87e18efdJorim Jaggi            useAllCaps = a.getBoolean(R.styleable.CarrierText_allCaps, false);
9625807936e8e4ca2c811bb4121725e1dd87e18efdJorim Jaggi        } finally {
9725807936e8e4ca2c811bb4121725e1dd87e18efdJorim Jaggi            a.recycle();
9825807936e8e4ca2c811bb4121725e1dd87e18efdJorim Jaggi        }
991d80e977da89a660aff006e93470749b359c2393Victoria Lease        setTransformationMethod(new CarrierTextTransformationMethod(mContext, useAllCaps));
10047051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen
10147051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
102f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    }
103f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
1049ff69bd8f115e70a16c72c798449908536a173eaJason Monk    protected void updateCarrierText() {
1059ff69bd8f115e70a16c72c798449908536a173eaJason Monk        boolean allSimsMissing = true;
10647051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        boolean anySimReadyAndInService = false;
1079ff69bd8f115e70a16c72c798449908536a173eaJason Monk        CharSequence displayText = null;
1089ff69bd8f115e70a16c72c798449908536a173eaJason Monk
1099ff69bd8f115e70a16c72c798449908536a173eaJason Monk        List<SubscriptionInfo> subs = mKeyguardUpdateMonitor.getSubscriptionInfo(false);
1109ff69bd8f115e70a16c72c798449908536a173eaJason Monk        final int N = subs.size();
1119ff69bd8f115e70a16c72c798449908536a173eaJason Monk        if (DEBUG) Log.d(TAG, "updateCarrierText(): " + N);
1129ff69bd8f115e70a16c72c798449908536a173eaJason Monk        for (int i = 0; i < N; i++) {
11347051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            int subId = subs.get(i).getSubscriptionId();
11447051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            State simState = mKeyguardUpdateMonitor.getSimState(subId);
1159ff69bd8f115e70a16c72c798449908536a173eaJason Monk            CharSequence carrierName = subs.get(i).getCarrierName();
1169ff69bd8f115e70a16c72c798449908536a173eaJason Monk            CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName);
11747051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            if (DEBUG) {
11847051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName);
11947051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            }
1209ff69bd8f115e70a16c72c798449908536a173eaJason Monk            if (carrierTextForSimState != null) {
1219ff69bd8f115e70a16c72c798449908536a173eaJason Monk                allSimsMissing = false;
1229ff69bd8f115e70a16c72c798449908536a173eaJason Monk                displayText = concatenate(displayText, carrierTextForSimState);
1239ff69bd8f115e70a16c72c798449908536a173eaJason Monk            }
12447051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            if (simState == IccCardConstants.State.READY) {
12547051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId);
12647051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                if (ss != null && ss.getDataRegState() == ServiceState.STATE_IN_SERVICE) {
12747051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                    // hack for WFC (IWLAN) not turning off immediately once
12847051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                    // Wi-Fi is disassociated or disabled
12947051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                    if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
13047051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                            || (mWifiManager.isWifiEnabled()
13147051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                                    && mWifiManager.getConnectionInfo() != null
13247051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                                    && mWifiManager.getConnectionInfo().getBSSID() != null)) {
13347051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                        if (DEBUG) {
13447051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                            Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + ss);
13547051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                        }
13647051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                        anySimReadyAndInService = true;
13747051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                    }
13847051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen                }
13947051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen            }
1409ff69bd8f115e70a16c72c798449908536a173eaJason Monk        }
1419ff69bd8f115e70a16c72c798449908536a173eaJason Monk        if (allSimsMissing) {
1429ff69bd8f115e70a16c72c798449908536a173eaJason Monk            if (N != 0) {
1439ff69bd8f115e70a16c72c798449908536a173eaJason Monk                // Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
1449ff69bd8f115e70a16c72c798449908536a173eaJason Monk                // This depends on mPlmn containing the text "Emergency calls only" when the radio
1459ff69bd8f115e70a16c72c798449908536a173eaJason Monk                // has some connectivity. Otherwise, it should be null or empty and just show
1469ff69bd8f115e70a16c72c798449908536a173eaJason Monk                // "No SIM card"
1479ff69bd8f115e70a16c72c798449908536a173eaJason Monk                // Grab the first subscripton, because they all should contain the emergency text,
1489ff69bd8f115e70a16c72c798449908536a173eaJason Monk                // described above.
1499ff69bd8f115e70a16c72c798449908536a173eaJason Monk                displayText =  makeCarrierStringOnEmergencyCapable(
1509ff69bd8f115e70a16c72c798449908536a173eaJason Monk                        getContext().getText(R.string.keyguard_missing_sim_message_short),
1519ff69bd8f115e70a16c72c798449908536a173eaJason Monk                        subs.get(0).getCarrierName());
1529ff69bd8f115e70a16c72c798449908536a173eaJason Monk            } else {
1539ff69bd8f115e70a16c72c798449908536a173eaJason Monk                // We don't have a SubscriptionInfo to get the emergency calls only from.
154de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                // Grab it from the old sticky broadcast if possible instead. We can use it
155de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                // here because no subscriptions are active, so we don't have
156de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                // to worry about MSIM clashing.
157de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                CharSequence text =
158de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                        getContext().getText(com.android.internal.R.string.emergency_calls_only);
159de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                Intent i = getContext().registerReceiver(null,
160de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                        new IntentFilter(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION));
161de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                if (i != null) {
162de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                    String spn = "";
163de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                    String plmn = "";
164de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                    if (i.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false)) {
165de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                        spn = i.getStringExtra(TelephonyIntents.EXTRA_SPN);
166de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                    }
167de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                    if (i.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false)) {
168de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                        plmn = i.getStringExtra(TelephonyIntents.EXTRA_PLMN);
169de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                    }
170de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                    if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn);
171b8726b7002aa39c7a01245212d35ac9296c58a1aSanket Padawe                    if (Objects.equals(plmn, spn)) {
172b8726b7002aa39c7a01245212d35ac9296c58a1aSanket Padawe                        text = plmn;
173b8726b7002aa39c7a01245212d35ac9296c58a1aSanket Padawe                    } else {
174b8726b7002aa39c7a01245212d35ac9296c58a1aSanket Padawe                        text = concatenate(plmn, spn);
175b8726b7002aa39c7a01245212d35ac9296c58a1aSanket Padawe                    }
176de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                }
1779ff69bd8f115e70a16c72c798449908536a173eaJason Monk                displayText =  makeCarrierStringOnEmergencyCapable(
178de3260b5bf0a1a2b3b23d4634400e1ea56f10ee4Jason Monk                        getContext().getText(R.string.keyguard_missing_sim_message_short), text);
1799ff69bd8f115e70a16c72c798449908536a173eaJason Monk            }
1809ff69bd8f115e70a16c72c798449908536a173eaJason Monk        }
18147051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen
18247051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        // APM (airplane mode) != no carrier state. There are carrier services
18347051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        // (e.g. WFC = Wi-Fi calling) which may operate in APM.
18447051d8e6dfcede55fa926c38bc06a6314fe6e4fEtan Cohen        if (!anySimReadyAndInService && WirelessUtils.isAirplaneModeOn(mContext)) {
185726fb28248a2d0d13123ec808a1e28c813aa7fb5Jason Monk            displayText = getContext().getString(R.string.airplane_mode);
186726fb28248a2d0d13123ec808a1e28c813aa7fb5Jason Monk        }
1879ff69bd8f115e70a16c72c798449908536a173eaJason Monk        setText(displayText);
188f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    }
189f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
190f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    @Override
191f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    protected void onFinishInflate() {
192f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        super.onFinishInflate();
1939ff69bd8f115e70a16c72c798449908536a173eaJason Monk        mSeparator = getResources().getString(
1949ff69bd8f115e70a16c72c798449908536a173eaJason Monk                com.android.internal.R.string.kg_text_message_separator);
1950d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
1960d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        setSelected(shouldMarquee); // Allow marquee to work.
197f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    }
198f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
1990928e019ce1a0e343df948520f32ac638379d8eeJim Miller    @Override
2000928e019ce1a0e343df948520f32ac638379d8eeJim Miller    protected void onAttachedToWindow() {
2010928e019ce1a0e343df948520f32ac638379d8eeJim Miller        super.onAttachedToWindow();
20283bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monk        if (ConnectivityManager.from(mContext).isNetworkSupported(
20383bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monk                ConnectivityManager.TYPE_MOBILE)) {
20483bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monk            mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
20583bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monk            mKeyguardUpdateMonitor.registerCallback(mCallback);
20683bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monk        } else {
20783bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monk            // Don't listen and clear out the text when the device isn't a phone.
20883bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monk            mKeyguardUpdateMonitor = null;
20983bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monk            setText("");
21083bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monk        }
2110928e019ce1a0e343df948520f32ac638379d8eeJim Miller    }
2120928e019ce1a0e343df948520f32ac638379d8eeJim Miller
2130928e019ce1a0e343df948520f32ac638379d8eeJim Miller    @Override
2140928e019ce1a0e343df948520f32ac638379d8eeJim Miller    protected void onDetachedFromWindow() {
2150928e019ce1a0e343df948520f32ac638379d8eeJim Miller        super.onDetachedFromWindow();
21683bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monk        if (mKeyguardUpdateMonitor != null) {
21783bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monk            mKeyguardUpdateMonitor.removeCallback(mCallback);
21883bc2aafd7563dd12673bbafe6226d4db0c89bebJason Monk        }
2190928e019ce1a0e343df948520f32ac638379d8eeJim Miller    }
2200928e019ce1a0e343df948520f32ac638379d8eeJim Miller
221f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    /**
222f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller     * Top-level function for creating carrier text. Makes text based on simState, PLMN
223f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller     * and SPN as well as device capabilities, such as being emergency call capable.
224f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller     *
225f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller     * @param simState
2269ff69bd8f115e70a16c72c798449908536a173eaJason Monk     * @param text
227f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller     * @param spn
2289ff69bd8f115e70a16c72c798449908536a173eaJason Monk     * @return Carrier text if not in missing state, null otherwise.
229f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller     */
230f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    private CharSequence getCarrierTextForSimState(IccCardConstants.State simState,
2319ff69bd8f115e70a16c72c798449908536a173eaJason Monk            CharSequence text) {
232f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        CharSequence carrierText = null;
233f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        StatusMode status = getStatusForIccState(simState);
234f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        switch (status) {
235f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case Normal:
2369ff69bd8f115e70a16c72c798449908536a173eaJason Monk                carrierText = text;
237f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                break;
238f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
239109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller            case SimNotReady:
2409ff69bd8f115e70a16c72c798449908536a173eaJason Monk                // Null is reserved for denoting missing, in this case we have nothing to display.
2419ff69bd8f115e70a16c72c798449908536a173eaJason Monk                carrierText = ""; // nothing to display yet.
242109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller                break;
243109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller
244f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case NetworkLocked:
245f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                carrierText = makeCarrierStringOnEmergencyCapable(
2469ff69bd8f115e70a16c72c798449908536a173eaJason Monk                        mContext.getText(R.string.keyguard_network_locked_message), text);
247f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                break;
248f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
249f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case SimMissing:
2509ff69bd8f115e70a16c72c798449908536a173eaJason Monk                carrierText = null;
251f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                break;
252f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
253f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case SimPermDisabled:
254f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                carrierText = getContext().getText(
2555ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller                        R.string.keyguard_permanent_disabled_sim_message_short);
256f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                break;
257f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
258f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case SimMissingLocked:
2599ff69bd8f115e70a16c72c798449908536a173eaJason Monk                carrierText = null;
260f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                break;
261f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
262f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case SimLocked:
263f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                carrierText = makeCarrierStringOnEmergencyCapable(
2645ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller                        getContext().getText(R.string.keyguard_sim_locked_message),
2659ff69bd8f115e70a16c72c798449908536a173eaJason Monk                        text);
266f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                break;
267f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
268f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case SimPukLocked:
269f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                carrierText = makeCarrierStringOnEmergencyCapable(
2705ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller                        getContext().getText(R.string.keyguard_sim_puk_locked_message),
2719ff69bd8f115e70a16c72c798449908536a173eaJason Monk                        text);
272f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                break;
273f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        }
274f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
275f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        return carrierText;
276f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    }
277f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
278f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    /*
279f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller     * Add emergencyCallMessage to carrier string only if phone supports emergency calls.
280f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller     */
281f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    private CharSequence makeCarrierStringOnEmergencyCapable(
282f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            CharSequence simMessage, CharSequence emergencyCallMessage) {
283c2e01683b34029729262e2fb346ceea4bfe4b4b6Adrian Roos        if (mIsEmergencyCallCapable) {
284f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            return concatenate(simMessage, emergencyCallMessage);
285f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        }
286f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        return simMessage;
287f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    }
288f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
289f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    /**
290f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller     * Determine the current status of the lock screen given the SIM state and other stuff.
291f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller     */
292f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    private StatusMode getStatusForIccState(IccCardConstants.State simState) {
293f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        // Since reading the SIM may take a while, we assume it is present until told otherwise.
294f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        if (simState == null) {
295f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            return StatusMode.Normal;
296f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        }
297f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
298f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        final boolean missingAndNotProvisioned =
299f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                !KeyguardUpdateMonitor.getInstance(mContext).isDeviceProvisioned()
300f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                && (simState == IccCardConstants.State.ABSENT ||
301f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                        simState == IccCardConstants.State.PERM_DISABLED);
302f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
303f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        // Assume we're NETWORK_LOCKED if not provisioned
304f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        simState = missingAndNotProvisioned ? IccCardConstants.State.NETWORK_LOCKED : simState;
305f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        switch (simState) {
306f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case ABSENT:
307f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                return StatusMode.SimMissing;
308f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case NETWORK_LOCKED:
309f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                return StatusMode.SimMissingLocked;
310f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case NOT_READY:
311109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller                return StatusMode.SimNotReady;
312f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case PIN_REQUIRED:
313f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                return StatusMode.SimLocked;
314f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case PUK_REQUIRED:
315f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                return StatusMode.SimPukLocked;
316f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case READY:
317f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                return StatusMode.Normal;
318f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case PERM_DISABLED:
319f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                return StatusMode.SimPermDisabled;
320f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case UNKNOWN:
321f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                return StatusMode.SimMissing;
322f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        }
323f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        return StatusMode.SimMissing;
324f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    }
325f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
326f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    private static CharSequence concatenate(CharSequence plmn, CharSequence spn) {
327f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        final boolean plmnValid = !TextUtils.isEmpty(plmn);
328f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        final boolean spnValid = !TextUtils.isEmpty(spn);
329f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        if (plmnValid && spnValid) {
330b8726b7002aa39c7a01245212d35ac9296c58a1aSanket Padawe            return new StringBuilder().append(plmn).append(mSeparator).append(spn).toString();
331f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        } else if (plmnValid) {
332f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            return plmn;
333f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        } else if (spnValid) {
334f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            return spn;
335f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        } else {
336f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            return "";
337f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        }
338f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    }
339f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
340f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    private CharSequence getCarrierHelpTextForSimState(IccCardConstants.State simState,
341f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            String plmn, String spn) {
342f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        int carrierHelpTextId = 0;
343f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        StatusMode status = getStatusForIccState(simState);
344f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        switch (status) {
345f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case NetworkLocked:
3465ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller                carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled;
347f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                break;
348f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
349f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case SimMissing:
3505ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller                carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long;
351f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                break;
352f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
353f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case SimPermDisabled:
3545ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller                carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions;
355f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                break;
356f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
357f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case SimMissingLocked:
3585ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Miller                carrierHelpTextId = R.string.keyguard_missing_sim_instructions;
359f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                break;
360f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
361f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case Normal:
362f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case SimLocked:
363f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller            case SimPukLocked:
364f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller                break;
365f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        }
366f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller
367f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller        return mContext.getText(carrierHelpTextId);
368f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller    }
3691d80e977da89a660aff006e93470749b359c2393Victoria Lease
3701d80e977da89a660aff006e93470749b359c2393Victoria Lease    private class CarrierTextTransformationMethod extends SingleLineTransformationMethod {
3711d80e977da89a660aff006e93470749b359c2393Victoria Lease        private final Locale mLocale;
3721d80e977da89a660aff006e93470749b359c2393Victoria Lease        private final boolean mAllCaps;
3731d80e977da89a660aff006e93470749b359c2393Victoria Lease
3741d80e977da89a660aff006e93470749b359c2393Victoria Lease        public CarrierTextTransformationMethod(Context context, boolean allCaps) {
3751d80e977da89a660aff006e93470749b359c2393Victoria Lease            mLocale = context.getResources().getConfiguration().locale;
3761d80e977da89a660aff006e93470749b359c2393Victoria Lease            mAllCaps = allCaps;
3771d80e977da89a660aff006e93470749b359c2393Victoria Lease        }
3781d80e977da89a660aff006e93470749b359c2393Victoria Lease
3791d80e977da89a660aff006e93470749b359c2393Victoria Lease        @Override
3801d80e977da89a660aff006e93470749b359c2393Victoria Lease        public CharSequence getTransformation(CharSequence source, View view) {
3811d80e977da89a660aff006e93470749b359c2393Victoria Lease            source = super.getTransformation(source, view);
3821d80e977da89a660aff006e93470749b359c2393Victoria Lease
3831d80e977da89a660aff006e93470749b359c2393Victoria Lease            if (mAllCaps && source != null) {
3841d80e977da89a660aff006e93470749b359c2393Victoria Lease                source = source.toString().toUpperCase(mLocale);
3851d80e977da89a660aff006e93470749b359c2393Victoria Lease            }
3861d80e977da89a660aff006e93470749b359c2393Victoria Lease
3871d80e977da89a660aff006e93470749b359c2393Victoria Lease            return source;
3881d80e977da89a660aff006e93470749b359c2393Victoria Lease        }
3891d80e977da89a660aff006e93470749b359c2393Victoria Lease    }
390f9cb7ba158c7016d55f121e200f96046ddbc5b70Jim Miller}
391