MobileSignalController.java revision 93fb68fdce8f0d28eaa77704e4b00933260b83dd
1da68f596282e60bee832dff07cc96bf64bd15939Jason Monk/*
2da68f596282e60bee832dff07cc96bf64bd15939Jason Monk * Copyright (C) 2015 The Android Open Source Project
3da68f596282e60bee832dff07cc96bf64bd15939Jason Monk *
4da68f596282e60bee832dff07cc96bf64bd15939Jason Monk * Licensed under the Apache License, Version 2.0 (the "License");
5da68f596282e60bee832dff07cc96bf64bd15939Jason Monk * you may not use this file except in compliance with the License.
6da68f596282e60bee832dff07cc96bf64bd15939Jason Monk * You may obtain a copy of the License at
7da68f596282e60bee832dff07cc96bf64bd15939Jason Monk *
8da68f596282e60bee832dff07cc96bf64bd15939Jason Monk *      http://www.apache.org/licenses/LICENSE-2.0
9da68f596282e60bee832dff07cc96bf64bd15939Jason Monk *
10da68f596282e60bee832dff07cc96bf64bd15939Jason Monk * Unless required by applicable law or agreed to in writing, software
11da68f596282e60bee832dff07cc96bf64bd15939Jason Monk * distributed under the License is distributed on an "AS IS" BASIS,
12da68f596282e60bee832dff07cc96bf64bd15939Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13da68f596282e60bee832dff07cc96bf64bd15939Jason Monk * See the License for the specific language governing permissions and
14da68f596282e60bee832dff07cc96bf64bd15939Jason Monk * limitations under the License.
15da68f596282e60bee832dff07cc96bf64bd15939Jason Monk */
16da68f596282e60bee832dff07cc96bf64bd15939Jason Monkpackage com.android.systemui.statusbar.policy;
17da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
18da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.content.Context;
19da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.content.Intent;
20da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.net.NetworkCapabilities;
2107b75fe65dcb5b8add8246654c65f95f1191933eJason Monkimport android.os.Looper;
22da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.telephony.PhoneStateListener;
23da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.telephony.ServiceState;
24da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.telephony.SignalStrength;
25da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.telephony.SubscriptionInfo;
26da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.telephony.SubscriptionManager;
27da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.telephony.TelephonyManager;
2893fb68fdce8f0d28eaa77704e4b00933260b83ddJason Monkimport android.text.TextUtils;
29da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.util.Log;
30da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.util.SparseArray;
31da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
32da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport com.android.internal.annotations.VisibleForTesting;
33da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport com.android.internal.telephony.TelephonyIntents;
34da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport com.android.internal.telephony.cdma.EriInfo;
35da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport com.android.systemui.R;
3607b75fe65dcb5b8add8246654c65f95f1191933eJason Monkimport com.android.systemui.statusbar.policy.NetworkController.IconState;
37da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
38c6cc6266c9325f180b1a073f733fdf0a64e9286fJason Monkimport com.android.systemui.statusbar.policy.NetworkControllerImpl.SubscriptionDefaults;
39da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
40da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport java.io.PrintWriter;
4133f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monkimport java.util.BitSet;
42da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport java.util.Objects;
43da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
44da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
45da68f596282e60bee832dff07cc96bf64bd15939Jason Monkpublic class MobileSignalController extends SignalController<
46da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        MobileSignalController.MobileState, MobileSignalController.MobileIconGroup> {
47da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private final TelephonyManager mPhone;
48c6cc6266c9325f180b1a073f733fdf0a64e9286fJason Monk    private final SubscriptionDefaults mDefaults;
49da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private final String mNetworkNameDefault;
50da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private final String mNetworkNameSeparator;
51da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    @VisibleForTesting
52da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    final PhoneStateListener mPhoneStateListener;
53da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // Save entire info for logging, we only use the id.
54da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private final SubscriptionInfo mSubscriptionInfo;
55da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
56da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // @VisibleForDemoMode
57da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    final SparseArray<MobileIconGroup> mNetworkToIconLookup;
58da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
59da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // Since some pieces of the phone state are interdependent we store it locally,
60da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // this could potentially become part of MobileState for simplification/complication
61da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // of code.
62da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
63da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private int mDataState = TelephonyManager.DATA_DISCONNECTED;
64da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private ServiceState mServiceState;
65da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private SignalStrength mSignalStrength;
66da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private MobileIconGroup mDefaultIcons;
67da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private Config mConfig;
68da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
69da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't
70da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // need listener lists anymore.
71da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public MobileSignalController(Context context, Config config, boolean hasMobileData,
7207b75fe65dcb5b8add8246654c65f95f1191933eJason Monk            TelephonyManager phone, CallbackHandler callbackHandler,
73c6cc6266c9325f180b1a073f733fdf0a64e9286fJason Monk            NetworkControllerImpl networkController, SubscriptionInfo info,
74c6cc6266c9325f180b1a073f733fdf0a64e9286fJason Monk            SubscriptionDefaults defaults, Looper receiverLooper) {
75da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        super("MobileSignalController(" + info.getSubscriptionId() + ")", context,
7607b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                NetworkCapabilities.TRANSPORT_CELLULAR, callbackHandler,
77da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                networkController);
78da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup = new SparseArray<>();
79da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mConfig = config;
80da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mPhone = phone;
81c6cc6266c9325f180b1a073f733fdf0a64e9286fJason Monk        mDefaults = defaults;
82da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mSubscriptionInfo = info;
8307b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        mPhoneStateListener = new MobilePhoneStateListener(info.getSubscriptionId(),
8407b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                receiverLooper);
85da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkNameSeparator = getStringIfExists(R.string.status_bar_network_name_separator);
86da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkNameDefault = getStringIfExists(
87da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                com.android.internal.R.string.lockscreen_carrier_default);
88da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
89da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mapIconSets();
90da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
91da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mLastState.networkName = mCurrentState.networkName = mNetworkNameDefault;
925504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        mLastState.networkNameData = mCurrentState.networkNameData = mNetworkNameDefault;
93da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mLastState.enabled = mCurrentState.enabled = hasMobileData;
94da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mLastState.iconGroup = mCurrentState.iconGroup = mDefaultIcons;
95da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        // Get initial data sim state.
96da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        updateDataSim();
97da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
98da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
99da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void setConfiguration(Config config) {
100da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mConfig = config;
101da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mapIconSets();
102da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        updateTelephony();
103da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
104da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
105da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public int getDataContentDescription() {
106da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        return getIcons().mDataContentDescription;
107da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
108da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
109da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void setAirplaneMode(boolean airplaneMode) {
110da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mCurrentState.airplaneMode = airplaneMode;
111da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        notifyListenersIfNecessary();
112da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
113da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
11433f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk    @Override
11533f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk    public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) {
11633f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        boolean isValidated = validatedTransports.get(mTransportType);
11733f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        mCurrentState.isDefault = connectedTransports.get(mTransportType);
11833f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        // Only show this as not having connectivity if we are default.
11933f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        mCurrentState.inetCondition = (isValidated || !mCurrentState.isDefault) ? 1 : 0;
12033f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        notifyListenersIfNecessary();
121da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
122da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
123a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn    public void setCarrierNetworkChangeMode(boolean carrierNetworkChangeMode) {
124a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        mCurrentState.carrierNetworkChangeMode = carrierNetworkChangeMode;
1252fdbe128209f02725c645f29bff941efe865da56Andrew Flynn        updateTelephony();
126a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn    }
127a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
128da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    /**
129da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * Start listening for phone state changes.
130da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     */
131da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void registerListener() {
132da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mPhone.listen(mPhoneStateListener,
133da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                PhoneStateListener.LISTEN_SERVICE_STATE
134da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
135da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        | PhoneStateListener.LISTEN_CALL_STATE
136da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
137a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                        | PhoneStateListener.LISTEN_DATA_ACTIVITY
138a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                        | PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE);
139da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
140da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
141da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    /**
142da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * Stop listening for phone state changes.
143da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     */
144da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void unregisterListener() {
145da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mPhone.listen(mPhoneStateListener, 0);
146da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
147da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
148da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    /**
149da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * Produce a mapping of data network types to icon groups for simple and quick use in
150da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * updateTelephony.
151da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     */
152da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private void mapIconSets() {
153da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.clear();
154da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
155da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyIcons.THREE_G);
156da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyIcons.THREE_G);
157da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyIcons.THREE_G);
158da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EHRPD, TelephonyIcons.THREE_G);
159da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UMTS, TelephonyIcons.THREE_G);
160da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
161da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (!mConfig.showAtLeast3G) {
162da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
163da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    TelephonyIcons.UNKNOWN);
164da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE, TelephonyIcons.E);
165da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA, TelephonyIcons.ONE_X);
166da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyIcons.ONE_X);
167da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
168da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mDefaultIcons = TelephonyIcons.G;
169da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
170da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
171da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    TelephonyIcons.THREE_G);
172da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE,
173da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    TelephonyIcons.THREE_G);
174da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA,
175da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    TelephonyIcons.THREE_G);
176da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT,
177da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    TelephonyIcons.THREE_G);
178da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mDefaultIcons = TelephonyIcons.THREE_G;
179da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
180da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
181da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        MobileIconGroup hGroup = TelephonyIcons.THREE_G;
182da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mConfig.hspaDataDistinguishable) {
183da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            hGroup = TelephonyIcons.H;
184da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
185da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSDPA, hGroup);
186da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSUPA, hGroup);
187da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPA, hGroup);
188da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPAP, hGroup);
189da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
190da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mConfig.show4gForLte) {
191da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.FOUR_G);
192da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
193da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.LTE);
194da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
1957150d7fa357e00b2904ff3bcf9e06a1014bfbb39Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_IWLAN, TelephonyIcons.WFC);
196da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
197da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
198da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    @Override
199da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void notifyListeners() {
200da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        MobileIconGroup icons = getIcons();
201da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
202da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        String contentDescription = getStringIfExists(getContentDescription());
203da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        String dataContentDescription = getStringIfExists(icons.mDataContentDescription);
2045c7daaf7763f4c1fc3eb44430d1b2e5bf11130e1Jeff Davidson
20533f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        // Show icon in QS when we are connected or need to show roaming.
20633f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        boolean showDataIcon = mCurrentState.dataConnected
2075c7daaf7763f4c1fc3eb44430d1b2e5bf11130e1Jeff Davidson                || mCurrentState.iconGroup == TelephonyIcons.ROAMING;
20807b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode,
20907b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                getCurrentIconId(), contentDescription);
21007b75fe65dcb5b8add8246654c65f95f1191933eJason Monk
21107b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        int qsTypeIcon = 0;
21207b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        IconState qsIcon = null;
21307b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        String description = null;
214da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        // Only send data sim callbacks to QS.
215da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mCurrentState.dataSim) {
21633f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk            qsTypeIcon = showDataIcon ? icons.mQsDataType : 0;
21707b75fe65dcb5b8add8246654c65f95f1191933eJason Monk            qsIcon = new IconState(mCurrentState.enabled
21807b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                    && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription);
21907b75fe65dcb5b8add8246654c65f95f1191933eJason Monk            description = mCurrentState.isEmergency ? null : mCurrentState.networkName;
220da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
22107b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        boolean activityIn = mCurrentState.dataConnected
22207b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                        && !mCurrentState.carrierNetworkChangeMode
22307b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                        && mCurrentState.activityIn;
22407b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        boolean activityOut = mCurrentState.dataConnected
22507b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                        && !mCurrentState.carrierNetworkChangeMode
22607b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                        && mCurrentState.activityOut;
22761633f18611731d7011facbfe3d14f3ec83d86a3Jason Monk        showDataIcon &= mCurrentState.isDefault
22861633f18611731d7011facbfe3d14f3ec83d86a3Jason Monk                || mCurrentState.iconGroup == TelephonyIcons.ROAMING;
229da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        int typeIcon = showDataIcon ? icons.mDataType : 0;
2302fdbe128209f02725c645f29bff941efe865da56Andrew Flynn        mCallbackHandler.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
2312fdbe128209f02725c645f29bff941efe865da56Andrew Flynn                activityIn, activityOut, dataContentDescription, description, icons.mIsWide,
2322fdbe128209f02725c645f29bff941efe865da56Andrew Flynn                mSubscriptionInfo.getSubscriptionId());
233a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn    }
234a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
235da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    @Override
236da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    protected MobileState cleanState() {
237da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        return new MobileState();
238da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
239da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
240da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private boolean hasService() {
241da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mServiceState != null) {
242da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // Consider the device to be in service if either voice or data
243da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // service is available. Some SIM cards are marketed as data-only
244da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // and do not support voice service, and on these SIM cards, we
245da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // want to show signal bars for data service as well as the "no
246da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // service" or "emergency calls only" text that indicates that voice
247da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // is not available.
248da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            switch (mServiceState.getVoiceRegState()) {
249da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                case ServiceState.STATE_POWER_OFF:
250da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    return false;
251da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                case ServiceState.STATE_OUT_OF_SERVICE:
252da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                case ServiceState.STATE_EMERGENCY_ONLY:
253da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    return mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
254da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                default:
255da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    return true;
256da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
257da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
258da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            return false;
259da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
260da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
261da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
262da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private boolean isCdma() {
263da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        return (mSignalStrength != null) && !mSignalStrength.isGsm();
264da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
265da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
266da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public boolean isEmergencyOnly() {
267da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        return (mServiceState != null && mServiceState.isEmergencyOnly());
268da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
269da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
270da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private boolean isRoaming() {
271da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (isCdma()) {
272da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            final int iconMode = mServiceState.getCdmaEriIconMode();
273da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            return mServiceState.getCdmaEriIconIndex() != EriInfo.ROAMING_INDICATOR_OFF
274da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    && (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL
275da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH);
276da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
277da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            return mServiceState != null && mServiceState.getRoaming();
278da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
279da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
280da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
281a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn    private boolean isCarrierNetworkChangeActive() {
28255fc8004ad1896da615fd08caca87d1b393d085cAndrew Flynn        return mCurrentState.carrierNetworkChangeMode;
283a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn    }
284a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
285da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void handleBroadcast(Intent intent) {
286da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        String action = intent.getAction();
287da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (action.equals(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION)) {
288da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false),
289da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    intent.getStringExtra(TelephonyIntents.EXTRA_SPN),
2905504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak                    intent.getStringExtra(TelephonyIntents.EXTRA_DATA_SPN),
291da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false),
292da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    intent.getStringExtra(TelephonyIntents.EXTRA_PLMN));
293da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            notifyListenersIfNecessary();
294da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
295da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            updateDataSim();
2968fcab35828144e27a32a95ed9bd83e4f6d83ac21Jason Monk            notifyListenersIfNecessary();
297da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
298da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
299da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
300da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private void updateDataSim() {
301c6cc6266c9325f180b1a073f733fdf0a64e9286fJason Monk        int defaultDataSub = mDefaults.getDefaultDataSubId();
302da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (SubscriptionManager.isValidSubscriptionId(defaultDataSub)) {
303da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.dataSim = defaultDataSub == mSubscriptionInfo.getSubscriptionId();
304da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
305da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // There doesn't seem to be a data sim selected, however if
306da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // there isn't a MobileSignalController with dataSim set, then
307da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // QS won't get any callbacks and will be blank.  Instead
308da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // lets just assume we are the data sim (which will basically
309da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // show one at random) in QS until one is selected.  The user
310da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // should pick one soon after, so we shouldn't be in this state
311da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // for long.
312da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.dataSim = true;
313da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
314da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
315da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
316da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    /**
317da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * Updates the network's name based on incoming spn and plmn.
318da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     */
3195504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak    void updateNetworkName(boolean showSpn, String spn, String dataSpn,
3205504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            boolean showPlmn, String plmn) {
321da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (CHATTY) {
3225504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn
3235504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak                    + " spn=" + spn + " dataSpn=" + dataSpn
324da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    + " showPlmn=" + showPlmn + " plmn=" + plmn);
325da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
326da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        StringBuilder str = new StringBuilder();
3275504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        StringBuilder strData = new StringBuilder();
328da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (showPlmn && plmn != null) {
329da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            str.append(plmn);
3305504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            strData.append(plmn);
331da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
332da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (showSpn && spn != null) {
333da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            if (str.length() != 0) {
334da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                str.append(mNetworkNameSeparator);
335da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
336da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            str.append(spn);
337da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
338da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (str.length() != 0) {
339da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.networkName = str.toString();
340da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
341da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.networkName = mNetworkNameDefault;
342da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
3435504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        if (showSpn && dataSpn != null) {
3445504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            if (strData.length() != 0) {
3455504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak                strData.append(mNetworkNameSeparator);
3465504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            }
3475504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            strData.append(dataSpn);
3485504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        }
3495504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        if (strData.length() != 0) {
3505504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            mCurrentState.networkNameData = strData.toString();
3515504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        } else {
3525504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            mCurrentState.networkNameData = mNetworkNameDefault;
3535504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        }
354da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
355da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
356da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    /**
357da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * Updates the current state based on mServiceState, mSignalStrength, mDataNetType,
358da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * mDataState, and mSimState.  It should be called any time one of these is updated.
359da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * This will call listeners if necessary.
360da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     */
361da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private final void updateTelephony() {
362da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (DEBUG) {
363da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            Log.d(mTag, "updateTelephonySignalStrength: hasService=" + hasService()
364da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    + " ss=" + mSignalStrength);
365da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
366da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mCurrentState.connected = hasService() && mSignalStrength != null;
367da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mCurrentState.connected) {
368da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) {
369da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                mCurrentState.level = mSignalStrength.getCdmaLevel();
370da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            } else {
371da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                mCurrentState.level = mSignalStrength.getLevel();
372da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
373da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
374da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) {
375da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.iconGroup = mNetworkToIconLookup.get(mDataNetType);
376da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
377da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.iconGroup = mDefaultIcons;
378da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
379da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mCurrentState.dataConnected = mCurrentState.connected
380da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                && mDataState == TelephonyManager.DATA_CONNECTED;
381da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
382a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        if (isCarrierNetworkChangeActive()) {
383a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
384a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        } else if (isRoaming()) {
385da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.iconGroup = TelephonyIcons.ROAMING;
386da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
387da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (isEmergencyOnly() != mCurrentState.isEmergency) {
388da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.isEmergency = isEmergencyOnly();
389da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkController.recalculateEmergency();
390da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
391da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        // Fill in the network name if we think we have it.
392da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mCurrentState.networkName == mNetworkNameDefault && mServiceState != null
39393fb68fdce8f0d28eaa77704e4b00933260b83ddJason Monk                && !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) {
394da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.networkName = mServiceState.getOperatorAlphaShort();
395da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
396a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
397da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        notifyListenersIfNecessary();
398da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
399da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
400da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    @VisibleForTesting
401da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    void setActivity(int activity) {
402da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mCurrentState.activityIn = activity == TelephonyManager.DATA_ACTIVITY_INOUT
403da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                || activity == TelephonyManager.DATA_ACTIVITY_IN;
404da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mCurrentState.activityOut = activity == TelephonyManager.DATA_ACTIVITY_INOUT
405da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                || activity == TelephonyManager.DATA_ACTIVITY_OUT;
406da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        notifyListenersIfNecessary();
407da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
408da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
409da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    @Override
410da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void dump(PrintWriter pw) {
411da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        super.dump(pw);
412da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        pw.println("  mSubscription=" + mSubscriptionInfo + ",");
413da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        pw.println("  mServiceState=" + mServiceState + ",");
414da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        pw.println("  mSignalStrength=" + mSignalStrength + ",");
415da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        pw.println("  mDataState=" + mDataState + ",");
416da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        pw.println("  mDataNetType=" + mDataNetType + ",");
417da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
418da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
419da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    class MobilePhoneStateListener extends PhoneStateListener {
42007b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        public MobilePhoneStateListener(int subId, Looper looper) {
42107b75fe65dcb5b8add8246654c65f95f1191933eJason Monk            super(subId, looper);
422da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
423da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
424da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
425da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
426da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            if (DEBUG) {
427da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                Log.d(mTag, "onSignalStrengthsChanged signalStrength=" + signalStrength +
428da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
429da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
430da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mSignalStrength = signalStrength;
431da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            updateTelephony();
432da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
433da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
434da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
435da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public void onServiceStateChanged(ServiceState state) {
436da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            if (DEBUG) {
437da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                Log.d(mTag, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
438da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        + " dataState=" + state.getDataRegState());
439da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
440da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mServiceState = state;
441da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            updateTelephony();
442da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
443da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
444da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
445da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public void onDataConnectionStateChanged(int state, int networkType) {
446da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            if (DEBUG) {
447da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                Log.d(mTag, "onDataConnectionStateChanged: state=" + state
448da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        + " type=" + networkType);
449da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
450da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mDataState = state;
451da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mDataNetType = networkType;
452da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            updateTelephony();
453da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
454da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
455da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
456da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public void onDataActivity(int direction) {
457da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            if (DEBUG) {
458da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                Log.d(mTag, "onDataActivity: direction=" + direction);
459da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
460da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            setActivity(direction);
461da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
462a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
463a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        @Override
464a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        public void onCarrierNetworkChange(boolean active) {
465a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            if (DEBUG) {
466a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                Log.d(mTag, "onCarrierNetworkChange: active=" + active);
467a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            }
468a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            mCurrentState.carrierNetworkChangeMode = active;
469a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
470a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            updateTelephony();
471a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        }
472da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    };
473da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
474da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    static class MobileIconGroup extends SignalController.IconGroup {
475da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        final int mDataContentDescription; // mContentDescriptionDataType
476da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        final int mDataType;
477da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        final boolean mIsWide;
47833f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        final int mQsDataType;
479da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
480da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public MobileIconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc,
481da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                int sbNullState, int qsNullState, int sbDiscState, int qsDiscState,
482da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                int discContentDesc, int dataContentDesc, int dataType, boolean isWide,
48333f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk                int qsDataType) {
4842fdbe128209f02725c645f29bff941efe865da56Andrew Flynn            super(name, sbIcons, qsIcons, contentDesc, sbNullState, qsNullState, sbDiscState,
4852fdbe128209f02725c645f29bff941efe865da56Andrew Flynn                    qsDiscState, discContentDesc);
486da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mDataContentDescription = dataContentDesc;
487da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mDataType = dataType;
488da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mIsWide = isWide;
489da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mQsDataType = qsDataType;
490da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
491da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
492da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
493da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    static class MobileState extends SignalController.State {
494da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        String networkName;
4955504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        String networkNameData;
496da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        boolean dataSim;
497da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        boolean dataConnected;
498da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        boolean isEmergency;
499da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        boolean airplaneMode;
500a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        boolean carrierNetworkChangeMode;
50133f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        boolean isDefault;
502da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
503da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
504da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public void copyFrom(State s) {
505da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            super.copyFrom(s);
506da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            MobileState state = (MobileState) s;
507da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            dataSim = state.dataSim;
508da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            networkName = state.networkName;
5095504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            networkNameData = state.networkNameData;
510da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            dataConnected = state.dataConnected;
51133f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk            isDefault = state.isDefault;
512da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            isEmergency = state.isEmergency;
513da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            airplaneMode = state.airplaneMode;
514a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            carrierNetworkChangeMode = state.carrierNetworkChangeMode;
515da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
516da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
517da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
518da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        protected void toString(StringBuilder builder) {
519da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            super.toString(builder);
520da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            builder.append(',');
521da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            builder.append("dataSim=").append(dataSim).append(',');
522da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            builder.append("networkName=").append(networkName).append(',');
5235504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            builder.append("networkNameData=").append(networkNameData).append(',');
524da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            builder.append("dataConnected=").append(dataConnected).append(',');
52533f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk            builder.append("isDefault=").append(isDefault).append(',');
526da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            builder.append("isEmergency=").append(isEmergency).append(',');
527a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            builder.append("airplaneMode=").append(airplaneMode).append(',');
528a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode);
529da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
530da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
531da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
532da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public boolean equals(Object o) {
533da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            return super.equals(o)
534da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    && Objects.equals(((MobileState) o).networkName, networkName)
5355504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak                    && Objects.equals(((MobileState) o).networkNameData, networkNameData)
536da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    && ((MobileState) o).dataSim == dataSim
537da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    && ((MobileState) o).dataConnected == dataConnected
538da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    && ((MobileState) o).isEmergency == isEmergency
539da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    && ((MobileState) o).airplaneMode == airplaneMode
540a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                    && ((MobileState) o).carrierNetworkChangeMode == carrierNetworkChangeMode
54133f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk                    && ((MobileState) o).isDefault == isDefault;
542da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
543da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
544da68f596282e60bee832dff07cc96bf64bd15939Jason Monk}
545