MobileSignalController.java revision 7150d7fa357e00b2904ff3bcf9e06a1014bfbb39
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;
28da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.util.Log;
29da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport android.util.SparseArray;
30da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
31da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport com.android.internal.annotations.VisibleForTesting;
32da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport com.android.internal.telephony.TelephonyIntents;
33da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport com.android.internal.telephony.cdma.EriInfo;
34da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport com.android.systemui.R;
3507b75fe65dcb5b8add8246654c65f95f1191933eJason Monkimport com.android.systemui.statusbar.policy.NetworkController.IconState;
36da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
37c6cc6266c9325f180b1a073f733fdf0a64e9286fJason Monkimport com.android.systemui.statusbar.policy.NetworkControllerImpl.SubscriptionDefaults;
38da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
39da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport java.io.PrintWriter;
4033f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monkimport java.util.BitSet;
41da68f596282e60bee832dff07cc96bf64bd15939Jason Monkimport java.util.Objects;
42da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
43da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
44da68f596282e60bee832dff07cc96bf64bd15939Jason Monkpublic class MobileSignalController extends SignalController<
45da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        MobileSignalController.MobileState, MobileSignalController.MobileIconGroup> {
46da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private final TelephonyManager mPhone;
47c6cc6266c9325f180b1a073f733fdf0a64e9286fJason Monk    private final SubscriptionDefaults mDefaults;
48da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private final String mNetworkNameDefault;
49da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private final String mNetworkNameSeparator;
50da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    @VisibleForTesting
51da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    final PhoneStateListener mPhoneStateListener;
52da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // Save entire info for logging, we only use the id.
53da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private final SubscriptionInfo mSubscriptionInfo;
54da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
55da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // @VisibleForDemoMode
56da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    final SparseArray<MobileIconGroup> mNetworkToIconLookup;
57da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
58da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // Since some pieces of the phone state are interdependent we store it locally,
59da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // this could potentially become part of MobileState for simplification/complication
60da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // of code.
61da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
62da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private int mDataState = TelephonyManager.DATA_DISCONNECTED;
63da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private ServiceState mServiceState;
64da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private SignalStrength mSignalStrength;
65da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private MobileIconGroup mDefaultIcons;
66da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private Config mConfig;
67da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
68da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't
69da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    // need listener lists anymore.
70da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public MobileSignalController(Context context, Config config, boolean hasMobileData,
7107b75fe65dcb5b8add8246654c65f95f1191933eJason Monk            TelephonyManager phone, CallbackHandler callbackHandler,
72c6cc6266c9325f180b1a073f733fdf0a64e9286fJason Monk            NetworkControllerImpl networkController, SubscriptionInfo info,
73c6cc6266c9325f180b1a073f733fdf0a64e9286fJason Monk            SubscriptionDefaults defaults, Looper receiverLooper) {
74da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        super("MobileSignalController(" + info.getSubscriptionId() + ")", context,
7507b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                NetworkCapabilities.TRANSPORT_CELLULAR, callbackHandler,
76da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                networkController);
77da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup = new SparseArray<>();
78da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mConfig = config;
79da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mPhone = phone;
80c6cc6266c9325f180b1a073f733fdf0a64e9286fJason Monk        mDefaults = defaults;
81da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mSubscriptionInfo = info;
8207b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        mPhoneStateListener = new MobilePhoneStateListener(info.getSubscriptionId(),
8307b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                receiverLooper);
84da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkNameSeparator = getStringIfExists(R.string.status_bar_network_name_separator);
85da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkNameDefault = getStringIfExists(
86da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                com.android.internal.R.string.lockscreen_carrier_default);
87da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
88da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mapIconSets();
89da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
90da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mLastState.networkName = mCurrentState.networkName = mNetworkNameDefault;
915504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        mLastState.networkNameData = mCurrentState.networkNameData = mNetworkNameDefault;
92da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mLastState.enabled = mCurrentState.enabled = hasMobileData;
93da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mLastState.iconGroup = mCurrentState.iconGroup = mDefaultIcons;
94da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        // Get initial data sim state.
95da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        updateDataSim();
96da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
97da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
98da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void setConfiguration(Config config) {
99da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mConfig = config;
100da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mapIconSets();
101da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        updateTelephony();
102da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
103da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
104da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public int getDataContentDescription() {
105da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        return getIcons().mDataContentDescription;
106da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
107da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
108da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void setAirplaneMode(boolean airplaneMode) {
109da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mCurrentState.airplaneMode = airplaneMode;
110da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        notifyListenersIfNecessary();
111da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
112da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
11333f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk    @Override
11433f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk    public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) {
11533f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        boolean isValidated = validatedTransports.get(mTransportType);
11633f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        mCurrentState.isDefault = connectedTransports.get(mTransportType);
11733f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        // Only show this as not having connectivity if we are default.
11833f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        mCurrentState.inetCondition = (isValidated || !mCurrentState.isDefault) ? 1 : 0;
11933f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        notifyListenersIfNecessary();
120da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
121da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
122a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn    public void setCarrierNetworkChangeMode(boolean carrierNetworkChangeMode) {
123a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        mCurrentState.carrierNetworkChangeMode = carrierNetworkChangeMode;
1242fdbe128209f02725c645f29bff941efe865da56Andrew Flynn        updateTelephony();
125a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn    }
126a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
127da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    /**
128da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * Start listening for phone state changes.
129da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     */
130da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void registerListener() {
131da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mPhone.listen(mPhoneStateListener,
132da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                PhoneStateListener.LISTEN_SERVICE_STATE
133da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
134da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        | PhoneStateListener.LISTEN_CALL_STATE
135da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
136a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                        | PhoneStateListener.LISTEN_DATA_ACTIVITY
137a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                        | PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE);
138da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
139da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
140da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    /**
141da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * Stop listening for phone state changes.
142da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     */
143da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void unregisterListener() {
144da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mPhone.listen(mPhoneStateListener, 0);
145da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
146da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
147da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    /**
148da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * Produce a mapping of data network types to icon groups for simple and quick use in
149da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * updateTelephony.
150da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     */
151da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private void mapIconSets() {
152da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.clear();
153da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
154da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyIcons.THREE_G);
155da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyIcons.THREE_G);
156da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyIcons.THREE_G);
157da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EHRPD, TelephonyIcons.THREE_G);
158da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UMTS, TelephonyIcons.THREE_G);
159da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
160da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (!mConfig.showAtLeast3G) {
161da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
162da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    TelephonyIcons.UNKNOWN);
163da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE, TelephonyIcons.E);
164da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA, TelephonyIcons.ONE_X);
165da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyIcons.ONE_X);
166da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
167da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mDefaultIcons = TelephonyIcons.G;
168da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
169da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
170da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    TelephonyIcons.THREE_G);
171da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE,
172da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    TelephonyIcons.THREE_G);
173da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA,
174da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    TelephonyIcons.THREE_G);
175da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT,
176da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    TelephonyIcons.THREE_G);
177da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mDefaultIcons = TelephonyIcons.THREE_G;
178da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
179da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
180da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        MobileIconGroup hGroup = TelephonyIcons.THREE_G;
181da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mConfig.hspaDataDistinguishable) {
182da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            hGroup = TelephonyIcons.H;
183da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
184da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSDPA, hGroup);
185da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSUPA, hGroup);
186da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPA, hGroup);
187da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPAP, hGroup);
188da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
189da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mConfig.show4gForLte) {
190da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.FOUR_G);
191da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
192da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.LTE);
193da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
1947150d7fa357e00b2904ff3bcf9e06a1014bfbb39Jason Monk        mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_IWLAN, TelephonyIcons.WFC);
195da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
196da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
197da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    @Override
198da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void notifyListeners() {
199da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        MobileIconGroup icons = getIcons();
200da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
201da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        String contentDescription = getStringIfExists(getContentDescription());
202da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        String dataContentDescription = getStringIfExists(icons.mDataContentDescription);
2035c7daaf7763f4c1fc3eb44430d1b2e5bf11130e1Jeff Davidson
20433f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        // Show icon in QS when we are connected or need to show roaming.
20533f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        boolean showDataIcon = mCurrentState.dataConnected
2065c7daaf7763f4c1fc3eb44430d1b2e5bf11130e1Jeff Davidson                || mCurrentState.iconGroup == TelephonyIcons.ROAMING;
20707b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode,
20807b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                getCurrentIconId(), contentDescription);
20907b75fe65dcb5b8add8246654c65f95f1191933eJason Monk
21007b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        int qsTypeIcon = 0;
21107b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        IconState qsIcon = null;
21207b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        String description = null;
213da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        // Only send data sim callbacks to QS.
214da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mCurrentState.dataSim) {
21533f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk            qsTypeIcon = showDataIcon ? icons.mQsDataType : 0;
21607b75fe65dcb5b8add8246654c65f95f1191933eJason Monk            qsIcon = new IconState(mCurrentState.enabled
21707b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                    && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription);
21807b75fe65dcb5b8add8246654c65f95f1191933eJason Monk            description = mCurrentState.isEmergency ? null : mCurrentState.networkName;
219da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
22007b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        boolean activityIn = mCurrentState.dataConnected
22107b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                        && !mCurrentState.carrierNetworkChangeMode
22207b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                        && mCurrentState.activityIn;
22307b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        boolean activityOut = mCurrentState.dataConnected
22407b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                        && !mCurrentState.carrierNetworkChangeMode
22507b75fe65dcb5b8add8246654c65f95f1191933eJason Monk                        && mCurrentState.activityOut;
22633f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        showDataIcon &= mCurrentState.isDefault;
227da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        int typeIcon = showDataIcon ? icons.mDataType : 0;
2282fdbe128209f02725c645f29bff941efe865da56Andrew Flynn        mCallbackHandler.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
2292fdbe128209f02725c645f29bff941efe865da56Andrew Flynn                activityIn, activityOut, dataContentDescription, description, icons.mIsWide,
2302fdbe128209f02725c645f29bff941efe865da56Andrew Flynn                mSubscriptionInfo.getSubscriptionId());
231a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn    }
232a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
233da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    @Override
234da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    protected MobileState cleanState() {
235da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        return new MobileState();
236da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
237da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
238da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private boolean hasService() {
239da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mServiceState != null) {
240da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // Consider the device to be in service if either voice or data
241da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // service is available. Some SIM cards are marketed as data-only
242da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // and do not support voice service, and on these SIM cards, we
243da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // want to show signal bars for data service as well as the "no
244da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // service" or "emergency calls only" text that indicates that voice
245da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // is not available.
246da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            switch (mServiceState.getVoiceRegState()) {
247da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                case ServiceState.STATE_POWER_OFF:
248da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    return false;
249da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                case ServiceState.STATE_OUT_OF_SERVICE:
250da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                case ServiceState.STATE_EMERGENCY_ONLY:
251da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    return mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
252da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                default:
253da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    return true;
254da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
255da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
256da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            return false;
257da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
258da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
259da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
260da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private boolean isCdma() {
261da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        return (mSignalStrength != null) && !mSignalStrength.isGsm();
262da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
263da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
264da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public boolean isEmergencyOnly() {
265da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        return (mServiceState != null && mServiceState.isEmergencyOnly());
266da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
267da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
268da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private boolean isRoaming() {
269da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (isCdma()) {
270da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            final int iconMode = mServiceState.getCdmaEriIconMode();
271da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            return mServiceState.getCdmaEriIconIndex() != EriInfo.ROAMING_INDICATOR_OFF
272da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    && (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL
273da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH);
274da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
275da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            return mServiceState != null && mServiceState.getRoaming();
276da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
277da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
278da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
279a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn    private boolean isCarrierNetworkChangeActive() {
28055fc8004ad1896da615fd08caca87d1b393d085cAndrew Flynn        return mCurrentState.carrierNetworkChangeMode;
281a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn    }
282a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
283da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void handleBroadcast(Intent intent) {
284da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        String action = intent.getAction();
285da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (action.equals(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION)) {
286da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false),
287da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    intent.getStringExtra(TelephonyIntents.EXTRA_SPN),
2885504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak                    intent.getStringExtra(TelephonyIntents.EXTRA_DATA_SPN),
289da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false),
290da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    intent.getStringExtra(TelephonyIntents.EXTRA_PLMN));
291da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            notifyListenersIfNecessary();
292da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
293da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            updateDataSim();
2948fcab35828144e27a32a95ed9bd83e4f6d83ac21Jason Monk            notifyListenersIfNecessary();
295da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
296da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
297da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
298da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private void updateDataSim() {
299c6cc6266c9325f180b1a073f733fdf0a64e9286fJason Monk        int defaultDataSub = mDefaults.getDefaultDataSubId();
300da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (SubscriptionManager.isValidSubscriptionId(defaultDataSub)) {
301da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.dataSim = defaultDataSub == mSubscriptionInfo.getSubscriptionId();
302da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
303da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // There doesn't seem to be a data sim selected, however if
304da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // there isn't a MobileSignalController with dataSim set, then
305da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // QS won't get any callbacks and will be blank.  Instead
306da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // lets just assume we are the data sim (which will basically
307da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // show one at random) in QS until one is selected.  The user
308da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // should pick one soon after, so we shouldn't be in this state
309da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            // for long.
310da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.dataSim = true;
311da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
312da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
313da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
314da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    /**
315da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * Updates the network's name based on incoming spn and plmn.
316da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     */
3175504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak    void updateNetworkName(boolean showSpn, String spn, String dataSpn,
3185504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            boolean showPlmn, String plmn) {
319da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (CHATTY) {
3205504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn
3215504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak                    + " spn=" + spn + " dataSpn=" + dataSpn
322da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    + " showPlmn=" + showPlmn + " plmn=" + plmn);
323da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
324da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        StringBuilder str = new StringBuilder();
3255504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        StringBuilder strData = new StringBuilder();
326da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (showPlmn && plmn != null) {
327da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            str.append(plmn);
3285504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            strData.append(plmn);
329da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
330da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (showSpn && spn != null) {
331da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            if (str.length() != 0) {
332da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                str.append(mNetworkNameSeparator);
333da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
334da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            str.append(spn);
335da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
336da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (str.length() != 0) {
337da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.networkName = str.toString();
338da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
339da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.networkName = mNetworkNameDefault;
340da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
3415504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        if (showSpn && dataSpn != null) {
3425504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            if (strData.length() != 0) {
3435504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak                strData.append(mNetworkNameSeparator);
3445504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            }
3455504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            strData.append(dataSpn);
3465504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        }
3475504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        if (strData.length() != 0) {
3485504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            mCurrentState.networkNameData = strData.toString();
3495504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        } else {
3505504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            mCurrentState.networkNameData = mNetworkNameDefault;
3515504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        }
352da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
353da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
354da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    /**
355da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * Updates the current state based on mServiceState, mSignalStrength, mDataNetType,
356da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * mDataState, and mSimState.  It should be called any time one of these is updated.
357da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     * This will call listeners if necessary.
358da68f596282e60bee832dff07cc96bf64bd15939Jason Monk     */
359da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    private final void updateTelephony() {
360da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (DEBUG) {
361da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            Log.d(mTag, "updateTelephonySignalStrength: hasService=" + hasService()
362da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    + " ss=" + mSignalStrength);
363da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
364da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mCurrentState.connected = hasService() && mSignalStrength != null;
365da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mCurrentState.connected) {
366da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) {
367da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                mCurrentState.level = mSignalStrength.getCdmaLevel();
368da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            } else {
369da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                mCurrentState.level = mSignalStrength.getLevel();
370da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
371da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
372da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) {
373da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.iconGroup = mNetworkToIconLookup.get(mDataNetType);
374da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        } else {
375da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.iconGroup = mDefaultIcons;
376da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
377da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mCurrentState.dataConnected = mCurrentState.connected
378da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                && mDataState == TelephonyManager.DATA_CONNECTED;
379da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
380a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        if (isCarrierNetworkChangeActive()) {
381a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
382a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        } else if (isRoaming()) {
383da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.iconGroup = TelephonyIcons.ROAMING;
384da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
385da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (isEmergencyOnly() != mCurrentState.isEmergency) {
386da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.isEmergency = isEmergencyOnly();
387da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mNetworkController.recalculateEmergency();
388da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
389da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        // Fill in the network name if we think we have it.
390da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        if (mCurrentState.networkName == mNetworkNameDefault && mServiceState != null
391da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                && mServiceState.getOperatorAlphaShort() != null) {
392da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mCurrentState.networkName = mServiceState.getOperatorAlphaShort();
393da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
394a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
395da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        notifyListenersIfNecessary();
396da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
397da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
398da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    @VisibleForTesting
399da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    void setActivity(int activity) {
400da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mCurrentState.activityIn = activity == TelephonyManager.DATA_ACTIVITY_INOUT
401da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                || activity == TelephonyManager.DATA_ACTIVITY_IN;
402da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        mCurrentState.activityOut = activity == TelephonyManager.DATA_ACTIVITY_INOUT
403da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                || activity == TelephonyManager.DATA_ACTIVITY_OUT;
404da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        notifyListenersIfNecessary();
405da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
406da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
407da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    @Override
408da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    public void dump(PrintWriter pw) {
409da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        super.dump(pw);
410da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        pw.println("  mSubscription=" + mSubscriptionInfo + ",");
411da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        pw.println("  mServiceState=" + mServiceState + ",");
412da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        pw.println("  mSignalStrength=" + mSignalStrength + ",");
413da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        pw.println("  mDataState=" + mDataState + ",");
414da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        pw.println("  mDataNetType=" + mDataNetType + ",");
415da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
416da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
417da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    class MobilePhoneStateListener extends PhoneStateListener {
41807b75fe65dcb5b8add8246654c65f95f1191933eJason Monk        public MobilePhoneStateListener(int subId, Looper looper) {
41907b75fe65dcb5b8add8246654c65f95f1191933eJason Monk            super(subId, looper);
420da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
421da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
422da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
423da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
424da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            if (DEBUG) {
425da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                Log.d(mTag, "onSignalStrengthsChanged signalStrength=" + signalStrength +
426da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
427da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
428da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mSignalStrength = signalStrength;
429da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            updateTelephony();
430da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
431da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
432da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
433da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public void onServiceStateChanged(ServiceState state) {
434da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            if (DEBUG) {
435da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                Log.d(mTag, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
436da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        + " dataState=" + state.getDataRegState());
437da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
438da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mServiceState = state;
439da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            updateTelephony();
440da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
441da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
442da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
443da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public void onDataConnectionStateChanged(int state, int networkType) {
444da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            if (DEBUG) {
445da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                Log.d(mTag, "onDataConnectionStateChanged: state=" + state
446da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                        + " type=" + networkType);
447da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
448da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mDataState = state;
449da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mDataNetType = networkType;
450da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            updateTelephony();
451da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
452da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
453da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
454da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public void onDataActivity(int direction) {
455da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            if (DEBUG) {
456da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                Log.d(mTag, "onDataActivity: direction=" + direction);
457da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            }
458da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            setActivity(direction);
459da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
460a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
461a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        @Override
462a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        public void onCarrierNetworkChange(boolean active) {
463a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            if (DEBUG) {
464a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                Log.d(mTag, "onCarrierNetworkChange: active=" + active);
465a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            }
466a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            mCurrentState.carrierNetworkChangeMode = active;
467a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn
468a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            updateTelephony();
469a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        }
470da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    };
471da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
472da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    static class MobileIconGroup extends SignalController.IconGroup {
473da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        final int mDataContentDescription; // mContentDescriptionDataType
474da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        final int mDataType;
475da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        final boolean mIsWide;
47633f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        final int mQsDataType;
477da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
478da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public MobileIconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc,
479da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                int sbNullState, int qsNullState, int sbDiscState, int qsDiscState,
480da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                int discContentDesc, int dataContentDesc, int dataType, boolean isWide,
48133f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk                int qsDataType) {
4822fdbe128209f02725c645f29bff941efe865da56Andrew Flynn            super(name, sbIcons, qsIcons, contentDesc, sbNullState, qsNullState, sbDiscState,
4832fdbe128209f02725c645f29bff941efe865da56Andrew Flynn                    qsDiscState, discContentDesc);
484da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mDataContentDescription = dataContentDesc;
485da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mDataType = dataType;
486da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mIsWide = isWide;
487da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            mQsDataType = qsDataType;
488da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
489da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
490da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
491da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    static class MobileState extends SignalController.State {
492da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        String networkName;
4935504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak        String networkNameData;
494da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        boolean dataSim;
495da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        boolean dataConnected;
496da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        boolean isEmergency;
497da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        boolean airplaneMode;
498a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn        boolean carrierNetworkChangeMode;
49933f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk        boolean isDefault;
500da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
501da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
502da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public void copyFrom(State s) {
503da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            super.copyFrom(s);
504da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            MobileState state = (MobileState) s;
505da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            dataSim = state.dataSim;
506da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            networkName = state.networkName;
5075504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            networkNameData = state.networkNameData;
508da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            dataConnected = state.dataConnected;
50933f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk            isDefault = state.isDefault;
510da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            isEmergency = state.isEmergency;
511da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            airplaneMode = state.airplaneMode;
512a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            carrierNetworkChangeMode = state.carrierNetworkChangeMode;
513da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
514da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
515da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
516da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        protected void toString(StringBuilder builder) {
517da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            super.toString(builder);
518da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            builder.append(',');
519da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            builder.append("dataSim=").append(dataSim).append(',');
520da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            builder.append("networkName=").append(networkName).append(',');
5215504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak            builder.append("networkNameData=").append(networkNameData).append(',');
522da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            builder.append("dataConnected=").append(dataConnected).append(',');
52333f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk            builder.append("isDefault=").append(isDefault).append(',');
524da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            builder.append("isEmergency=").append(isEmergency).append(',');
525a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            builder.append("airplaneMode=").append(airplaneMode).append(',');
526a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn            builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode);
527da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
528da68f596282e60bee832dff07cc96bf64bd15939Jason Monk
529da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        @Override
530da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        public boolean equals(Object o) {
531da68f596282e60bee832dff07cc96bf64bd15939Jason Monk            return super.equals(o)
532da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    && Objects.equals(((MobileState) o).networkName, networkName)
5335504d39b7f880fa8b8660e5d4b014ec559124cf9Pavel Zhamaitsiak                    && Objects.equals(((MobileState) o).networkNameData, networkNameData)
534da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    && ((MobileState) o).dataSim == dataSim
535da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    && ((MobileState) o).dataConnected == dataConnected
536da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    && ((MobileState) o).isEmergency == isEmergency
537da68f596282e60bee832dff07cc96bf64bd15939Jason Monk                    && ((MobileState) o).airplaneMode == airplaneMode
538a478d70a68696380acbd4a9739dfaaebff61c728Andrew Flynn                    && ((MobileState) o).carrierNetworkChangeMode == carrierNetworkChangeMode
53933f8ae7543fbf7d94266f0f1621ec873aa2542f1Jason Monk                    && ((MobileState) o).isDefault == isDefault;
540da68f596282e60bee832dff07cc96bf64bd15939Jason Monk        }
541da68f596282e60bee832dff07cc96bf64bd15939Jason Monk    }
542da68f596282e60bee832dff07cc96bf64bd15939Jason Monk}
543