blob: 75231448ccfc356d48313807c96f6f5fb9ae307b [file] [log] [blame]
Jason Monkda68f592015-01-07 10:55:58 -05001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.systemui.statusbar.policy;
17
18import android.content.Context;
19import android.content.Intent;
Jason Monk0288de02017-02-23 14:48:05 -050020import android.database.ContentObserver;
Jason Monkda68f592015-01-07 10:55:58 -050021import android.net.NetworkCapabilities;
Jason Monk0288de02017-02-23 14:48:05 -050022import android.os.Handler;
Jason Monk07b75fe2015-05-14 16:47:03 -040023import android.os.Looper;
Bill Lin767c0db2019-08-15 20:42:06 +080024import android.os.Message;
Jason Monk0288de02017-02-23 14:48:05 -050025import android.provider.Settings.Global;
Jayachandran Ca6f9b6d2019-11-07 17:26:02 -080026import android.telephony.CellSignalStrength;
27import android.telephony.CellSignalStrengthCdma;
Jack Yue27d3fd2019-03-15 14:49:53 -070028import android.telephony.NetworkRegistrationInfo;
Jason Monkda68f592015-01-07 10:55:58 -050029import android.telephony.PhoneStateListener;
30import android.telephony.ServiceState;
31import android.telephony.SignalStrength;
32import android.telephony.SubscriptionInfo;
33import android.telephony.SubscriptionManager;
34import android.telephony.TelephonyManager;
Evan Laird83c87e52019-09-24 19:14:05 -040035import android.text.Html;
Jason Monk93fb68f2015-07-20 11:43:56 -040036import android.text.TextUtils;
Jason Monkda68f592015-01-07 10:55:58 -050037import android.util.Log;
38import android.util.SparseArray;
39
40import com.android.internal.annotations.VisibleForTesting;
Jason Monkda68f592015-01-07 10:55:58 -050041import com.android.internal.telephony.TelephonyIntents;
42import com.android.internal.telephony.cdma.EriInfo;
SongFerngWang8cfb4d52018-08-21 18:04:29 +080043import com.android.settingslib.Utils;
Gus Prevasab336792018-11-14 13:52:20 -050044import com.android.settingslib.graph.SignalDrawable;
Antony Sargentc026de32019-05-21 16:29:04 -070045import com.android.settingslib.net.SignalStrengthUtil;
Jason Monkda68f592015-01-07 10:55:58 -050046import com.android.systemui.R;
Jason Monk07b75fe2015-05-14 16:47:03 -040047import com.android.systemui.statusbar.policy.NetworkController.IconState;
Jason Monke06b0652016-03-02 16:35:27 -050048import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
Jason Monkda68f592015-01-07 10:55:58 -050049import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
Jason Monkc6cc6262015-06-11 11:10:15 -040050import com.android.systemui.statusbar.policy.NetworkControllerImpl.SubscriptionDefaults;
Jason Monkda68f592015-01-07 10:55:58 -050051
52import java.io.PrintWriter;
Jason Monk33f8ae72015-05-08 10:45:15 -040053import java.util.BitSet;
Jason Monkda68f592015-01-07 10:55:58 -050054import java.util.Objects;
Jayachandran Ca6f9b6d2019-11-07 17:26:02 -080055import java.util.List;
SongFerngWang3cbcf752019-03-21 23:14:20 +080056import java.util.regex.Matcher;
57import java.util.regex.Pattern;
Jason Monkda68f592015-01-07 10:55:58 -050058
59
60public class MobileSignalController extends SignalController<
61 MobileSignalController.MobileState, MobileSignalController.MobileIconGroup> {
Bill Lin767c0db2019-08-15 20:42:06 +080062
63 // The message to display Nr5G icon gracfully by CarrierConfig timeout
64 private static final int MSG_DISPLAY_GRACE = 1;
65
Jason Monkda68f592015-01-07 10:55:58 -050066 private final TelephonyManager mPhone;
Jason Monkc6cc6262015-06-11 11:10:15 -040067 private final SubscriptionDefaults mDefaults;
Jason Monkda68f592015-01-07 10:55:58 -050068 private final String mNetworkNameDefault;
69 private final String mNetworkNameSeparator;
Jason Monk0288de02017-02-23 14:48:05 -050070 private final ContentObserver mObserver;
Jason Monkda68f592015-01-07 10:55:58 -050071 @VisibleForTesting
72 final PhoneStateListener mPhoneStateListener;
73 // Save entire info for logging, we only use the id.
Jason Monk66845a32015-08-03 11:09:41 -040074 final SubscriptionInfo mSubscriptionInfo;
Jason Monkda68f592015-01-07 10:55:58 -050075
76 // @VisibleForDemoMode
77 final SparseArray<MobileIconGroup> mNetworkToIconLookup;
78
79 // Since some pieces of the phone state are interdependent we store it locally,
80 // this could potentially become part of MobileState for simplification/complication
81 // of code.
Jason Monkda68f592015-01-07 10:55:58 -050082 private int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
83 private int mDataState = TelephonyManager.DATA_DISCONNECTED;
84 private ServiceState mServiceState;
85 private SignalStrength mSignalStrength;
86 private MobileIconGroup mDefaultIcons;
87 private Config mConfig;
Bill Lin767c0db2019-08-15 20:42:06 +080088 private final Handler mDisplayGraceHandler;
andychoub935e682019-04-11 23:40:49 +080089 @VisibleForTesting
90 boolean mInflateSignalStrengths = false;
Bill Lin767c0db2019-08-15 20:42:06 +080091 @VisibleForTesting
92 boolean mIsShowingIconGracefully = false;
SongFerngWang3cbcf752019-03-21 23:14:20 +080093 // Some specific carriers have 5GE network which is special LTE CA network.
94 private static final int NETWORK_TYPE_LTE_CA_5GE = TelephonyManager.MAX_NETWORK_TYPE + 1;
Jason Monkda68f592015-01-07 10:55:58 -050095
96 // TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't
97 // need listener lists anymore.
98 public MobileSignalController(Context context, Config config, boolean hasMobileData,
Jason Monk07b75fe2015-05-14 16:47:03 -040099 TelephonyManager phone, CallbackHandler callbackHandler,
Jason Monkc6cc6262015-06-11 11:10:15 -0400100 NetworkControllerImpl networkController, SubscriptionInfo info,
101 SubscriptionDefaults defaults, Looper receiverLooper) {
Jason Monkda68f592015-01-07 10:55:58 -0500102 super("MobileSignalController(" + info.getSubscriptionId() + ")", context,
Jason Monk07b75fe2015-05-14 16:47:03 -0400103 NetworkCapabilities.TRANSPORT_CELLULAR, callbackHandler,
Jason Monkda68f592015-01-07 10:55:58 -0500104 networkController);
105 mNetworkToIconLookup = new SparseArray<>();
106 mConfig = config;
107 mPhone = phone;
Jason Monkc6cc6262015-06-11 11:10:15 -0400108 mDefaults = defaults;
Jason Monkda68f592015-01-07 10:55:58 -0500109 mSubscriptionInfo = info;
chen xu84a90872019-03-28 15:44:12 -0700110 mPhoneStateListener = new MobilePhoneStateListener(receiverLooper);
Evan Laird83c87e52019-09-24 19:14:05 -0400111 mNetworkNameSeparator = getStringIfExists(R.string.status_bar_network_name_separator)
112 .toString();
Jason Monkda68f592015-01-07 10:55:58 -0500113 mNetworkNameDefault = getStringIfExists(
Evan Laird83c87e52019-09-24 19:14:05 -0400114 com.android.internal.R.string.lockscreen_carrier_default).toString();
Jason Monkda68f592015-01-07 10:55:58 -0500115
116 mapIconSets();
117
Jason Monk00aa9d42015-08-10 10:12:02 -0400118 String networkName = info.getCarrierName() != null ? info.getCarrierName().toString()
119 : mNetworkNameDefault;
120 mLastState.networkName = mCurrentState.networkName = networkName;
121 mLastState.networkNameData = mCurrentState.networkNameData = networkName;
Jason Monkda68f592015-01-07 10:55:58 -0500122 mLastState.enabled = mCurrentState.enabled = hasMobileData;
123 mLastState.iconGroup = mCurrentState.iconGroup = mDefaultIcons;
124 // Get initial data sim state.
125 updateDataSim();
Jason Monk0288de02017-02-23 14:48:05 -0500126 mObserver = new ContentObserver(new Handler(receiverLooper)) {
127 @Override
128 public void onChange(boolean selfChange) {
129 updateTelephony();
130 }
131 };
Bill Lin767c0db2019-08-15 20:42:06 +0800132
133 mDisplayGraceHandler = new Handler(receiverLooper) {
134 @Override
135 public void handleMessage(Message msg) {
136 if (msg.what == MSG_DISPLAY_GRACE) {
137 mIsShowingIconGracefully = false;
138 updateTelephony();
139 }
140 }
141 };
Jason Monkda68f592015-01-07 10:55:58 -0500142 }
143
144 public void setConfiguration(Config config) {
145 mConfig = config;
andychou9e396282019-04-10 20:49:06 +0800146 updateInflateSignalStrength();
Jason Monkda68f592015-01-07 10:55:58 -0500147 mapIconSets();
148 updateTelephony();
149 }
150
Jason Monkda68f592015-01-07 10:55:58 -0500151 public void setAirplaneMode(boolean airplaneMode) {
152 mCurrentState.airplaneMode = airplaneMode;
153 notifyListenersIfNecessary();
154 }
155
Jason Monkfd57ea72016-04-29 13:37:58 -0400156 public void setUserSetupComplete(boolean userSetup) {
157 mCurrentState.userSetup = userSetup;
158 notifyListenersIfNecessary();
159 }
160
Jason Monk33f8ae72015-05-08 10:45:15 -0400161 @Override
162 public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) {
163 boolean isValidated = validatedTransports.get(mTransportType);
164 mCurrentState.isDefault = connectedTransports.get(mTransportType);
165 // Only show this as not having connectivity if we are default.
166 mCurrentState.inetCondition = (isValidated || !mCurrentState.isDefault) ? 1 : 0;
167 notifyListenersIfNecessary();
Jason Monkda68f592015-01-07 10:55:58 -0500168 }
169
Andrew Flynna478d702015-04-14 23:33:45 -0400170 public void setCarrierNetworkChangeMode(boolean carrierNetworkChangeMode) {
171 mCurrentState.carrierNetworkChangeMode = carrierNetworkChangeMode;
Andrew Flynn2fdbe122015-06-01 16:34:21 -0400172 updateTelephony();
Andrew Flynna478d702015-04-14 23:33:45 -0400173 }
174
Jason Monkda68f592015-01-07 10:55:58 -0500175 /**
176 * Start listening for phone state changes.
177 */
178 public void registerListener() {
179 mPhone.listen(mPhoneStateListener,
180 PhoneStateListener.LISTEN_SERVICE_STATE
181 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
182 | PhoneStateListener.LISTEN_CALL_STATE
183 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
Andrew Flynna478d702015-04-14 23:33:45 -0400184 | PhoneStateListener.LISTEN_DATA_ACTIVITY
Fabian Kozynskiaaf78972019-07-08 10:02:08 -0400185 | PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE
186 | PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
Jason Monk0288de02017-02-23 14:48:05 -0500187 mContext.getContentResolver().registerContentObserver(Global.getUriFor(Global.MOBILE_DATA),
188 true, mObserver);
189 mContext.getContentResolver().registerContentObserver(Global.getUriFor(
190 Global.MOBILE_DATA + mSubscriptionInfo.getSubscriptionId()),
191 true, mObserver);
Jason Monkda68f592015-01-07 10:55:58 -0500192 }
193
194 /**
195 * Stop listening for phone state changes.
196 */
197 public void unregisterListener() {
198 mPhone.listen(mPhoneStateListener, 0);
Jason Monk0288de02017-02-23 14:48:05 -0500199 mContext.getContentResolver().unregisterContentObserver(mObserver);
Jason Monkda68f592015-01-07 10:55:58 -0500200 }
201
202 /**
203 * Produce a mapping of data network types to icon groups for simple and quick use in
204 * updateTelephony.
205 */
206 private void mapIconSets() {
207 mNetworkToIconLookup.clear();
208
209 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyIcons.THREE_G);
210 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyIcons.THREE_G);
211 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyIcons.THREE_G);
212 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EHRPD, TelephonyIcons.THREE_G);
213 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UMTS, TelephonyIcons.THREE_G);
Wileen Chiu4105ab02015-09-18 15:17:54 -0700214 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_TD_SCDMA, TelephonyIcons.THREE_G);
Jason Monkda68f592015-01-07 10:55:58 -0500215
216 if (!mConfig.showAtLeast3G) {
217 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
218 TelephonyIcons.UNKNOWN);
219 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE, TelephonyIcons.E);
220 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA, TelephonyIcons.ONE_X);
221 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyIcons.ONE_X);
222
223 mDefaultIcons = TelephonyIcons.G;
224 } else {
225 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_UNKNOWN,
226 TelephonyIcons.THREE_G);
227 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_EDGE,
228 TelephonyIcons.THREE_G);
229 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_CDMA,
230 TelephonyIcons.THREE_G);
231 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_1xRTT,
232 TelephonyIcons.THREE_G);
233 mDefaultIcons = TelephonyIcons.THREE_G;
234 }
235
236 MobileIconGroup hGroup = TelephonyIcons.THREE_G;
Amin Shaikhf5830ca2018-03-09 14:06:50 -0500237 MobileIconGroup hPlusGroup = TelephonyIcons.THREE_G;
vagdevi3f2b9a52019-08-09 09:45:14 -0700238 if (mConfig.show4gFor3g) {
239 hGroup = TelephonyIcons.FOUR_G;
240 hPlusGroup = TelephonyIcons.FOUR_G;
241 } else if (mConfig.hspaDataDistinguishable) {
Jason Monkda68f592015-01-07 10:55:58 -0500242 hGroup = TelephonyIcons.H;
Amin Shaikhf5830ca2018-03-09 14:06:50 -0500243 hPlusGroup = TelephonyIcons.H_PLUS;
Jason Monkda68f592015-01-07 10:55:58 -0500244 }
vagdevi3f2b9a52019-08-09 09:45:14 -0700245
Jason Monkda68f592015-01-07 10:55:58 -0500246 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSDPA, hGroup);
247 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSUPA, hGroup);
248 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPA, hGroup);
Amin Shaikhf5830ca2018-03-09 14:06:50 -0500249 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_HSPAP, hPlusGroup);
Jason Monkda68f592015-01-07 10:55:58 -0500250
251 if (mConfig.show4gForLte) {
252 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.FOUR_G);
Robert Greenwalt37d34ba2016-07-27 14:54:34 -0700253 if (mConfig.hideLtePlus) {
254 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE_CA,
255 TelephonyIcons.FOUR_G);
256 } else {
257 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE_CA,
258 TelephonyIcons.FOUR_G_PLUS);
259 }
Jason Monkda68f592015-01-07 10:55:58 -0500260 } else {
261 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE, TelephonyIcons.LTE);
Robert Greenwalt37d34ba2016-07-27 14:54:34 -0700262 if (mConfig.hideLtePlus) {
263 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE_CA,
264 TelephonyIcons.LTE);
265 } else {
266 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_LTE_CA,
267 TelephonyIcons.LTE_PLUS);
268 }
Jason Monkda68f592015-01-07 10:55:58 -0500269 }
SongFerngWang3cbcf752019-03-21 23:14:20 +0800270 mNetworkToIconLookup.put(NETWORK_TYPE_LTE_CA_5GE,
271 TelephonyIcons.LTE_CA_5G_E);
Jason Monk7150d7f2015-07-09 10:14:12 -0400272 mNetworkToIconLookup.put(TelephonyManager.NETWORK_TYPE_IWLAN, TelephonyIcons.WFC);
Jason Monkda68f592015-01-07 10:55:58 -0500273 }
274
andychou9e396282019-04-10 20:49:06 +0800275 private void updateInflateSignalStrength() {
Antony Sargentc026de32019-05-21 16:29:04 -0700276 mInflateSignalStrengths = SignalStrengthUtil.shouldInflateSignalStrength(mContext,
277 mSubscriptionInfo.getSubscriptionId());
andychou9e396282019-04-10 20:49:06 +0800278 }
279
Jason Monk48edc0c2017-04-10 15:01:27 -0400280 private int getNumLevels() {
andychou9e396282019-04-10 20:49:06 +0800281 if (mInflateSignalStrengths) {
Jason Monk43c14d12017-06-22 11:20:04 -0400282 return SignalStrength.NUM_SIGNAL_STRENGTH_BINS + 1;
283 }
Jason Monk48edc0c2017-04-10 15:01:27 -0400284 return SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
285 }
286
287 @Override
288 public int getCurrentIconId() {
289 if (mCurrentState.iconGroup == TelephonyIcons.CARRIER_NETWORK_CHANGE) {
290 return SignalDrawable.getCarrierChangeState(getNumLevels());
291 } else if (mCurrentState.connected) {
Jason Monk43c14d12017-06-22 11:20:04 -0400292 int level = mCurrentState.level;
andychou9e396282019-04-10 20:49:06 +0800293 if (mInflateSignalStrengths) {
Jason Monk43c14d12017-06-22 11:20:04 -0400294 level++;
295 }
Amin Shaikhaf4c1932018-03-08 10:29:56 -0500296 boolean dataDisabled = mCurrentState.userSetup
Fabian Kozynskic7bc84b2019-03-11 13:57:31 -0400297 && (mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED
Evan Laird2ea99c12019-09-19 16:52:58 -0400298 || (mCurrentState.iconGroup == TelephonyIcons.NOT_DEFAULT_DATA
299 && mCurrentState.defaultDataOff));
Amin Shaikhaf4c1932018-03-08 10:29:56 -0500300 boolean noInternet = mCurrentState.inetCondition == 0;
301 boolean cutOut = dataDisabled || noInternet;
302 return SignalDrawable.getState(level, getNumLevels(), cutOut);
Jason Monk48edc0c2017-04-10 15:01:27 -0400303 } else if (mCurrentState.enabled) {
304 return SignalDrawable.getEmptyState(getNumLevels());
305 } else {
306 return 0;
307 }
308 }
309
310 @Override
Jason Monk01df36f2017-06-07 13:02:47 -0400311 public int getQsCurrentIconId() {
312 return getCurrentIconId();
313 }
314
315 @Override
Jason Monke06b0652016-03-02 16:35:27 -0500316 public void notifyListeners(SignalCallback callback) {
Jason Monkda68f592015-01-07 10:55:58 -0500317 MobileIconGroup icons = getIcons();
318
Evan Laird83c87e52019-09-24 19:14:05 -0400319 String contentDescription = getStringIfExists(getContentDescription()).toString();
320 CharSequence dataContentDescriptionHtml = getStringIfExists(icons.mDataContentDescription);
321
322 //TODO: Hacky
323 // The data content description can sometimes be shown in a text view and might come to us
324 // as HTML. Strip any styling here so that listeners don't have to care
325 CharSequence dataContentDescription = Html.fromHtml(
326 dataContentDescriptionHtml.toString(), 0).toString();
Amin Shaikh43ad7fe2018-03-05 14:34:44 -0500327 if (mCurrentState.inetCondition == 0) {
328 dataContentDescription = mContext.getString(R.string.data_connection_no_internet);
329 }
Fabian Kozynskic7bc84b2019-03-11 13:57:31 -0400330 final boolean dataDisabled = (mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED
Evan Laird2ea99c12019-09-19 16:52:58 -0400331 || (mCurrentState.iconGroup == TelephonyIcons.NOT_DEFAULT_DATA))
Jason Monkfd57ea72016-04-29 13:37:58 -0400332 && mCurrentState.userSetup;
Jeff Davidson5c7daaf2015-01-27 16:24:32 -0800333
Jason Monk0f0de132016-12-19 15:36:13 -0500334 // Show icon in QS when we are connected or data is disabled.
Jason Monk7e6c83c2017-04-26 14:35:24 -0400335 boolean showDataIcon = mCurrentState.dataConnected || dataDisabled;
Jason Monk07b75fe2015-05-14 16:47:03 -0400336 IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode,
337 getCurrentIconId(), contentDescription);
338
Jason Monk7e6c83c2017-04-26 14:35:24 -0400339 int qsTypeIcon = 0;
340 IconState qsIcon = null;
Evan Laird83c87e52019-09-24 19:14:05 -0400341 CharSequence description = null;
Jason Monk7e6c83c2017-04-26 14:35:24 -0400342 // Only send data sim callbacks to QS.
343 if (mCurrentState.dataSim) {
Evan Laird9dcd3222017-12-04 14:31:48 -0500344 qsTypeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon) ? icons.mQsDataType : 0;
Jason Monk7e6c83c2017-04-26 14:35:24 -0400345 qsIcon = new IconState(mCurrentState.enabled
Jason Monk01df36f2017-06-07 13:02:47 -0400346 && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription);
Jason Monk7e6c83c2017-04-26 14:35:24 -0400347 description = mCurrentState.isEmergency ? null : mCurrentState.networkName;
348 }
Jason Monk07b75fe2015-05-14 16:47:03 -0400349 boolean activityIn = mCurrentState.dataConnected
Jason Monk0288de02017-02-23 14:48:05 -0500350 && !mCurrentState.carrierNetworkChangeMode
351 && mCurrentState.activityIn;
Jason Monk07b75fe2015-05-14 16:47:03 -0400352 boolean activityOut = mCurrentState.dataConnected
Jason Monk0288de02017-02-23 14:48:05 -0500353 && !mCurrentState.carrierNetworkChangeMode
354 && mCurrentState.activityOut;
Jason Monk0f0de132016-12-19 15:36:13 -0500355 showDataIcon &= mCurrentState.isDefault || dataDisabled;
Wenting Xiong63364fe2017-02-07 19:12:27 +0800356 int typeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon) ? icons.mDataType : 0;
Jason Monk7e6c83c2017-04-26 14:35:24 -0400357 callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
Evan Laird83c87e52019-09-24 19:14:05 -0400358 activityIn, activityOut, dataContentDescription, dataContentDescriptionHtml,
359 description, icons.mIsWide, mSubscriptionInfo.getSubscriptionId(),
360 mCurrentState.roaming);
Andrew Flynna478d702015-04-14 23:33:45 -0400361 }
362
Jason Monkda68f592015-01-07 10:55:58 -0500363 @Override
364 protected MobileState cleanState() {
365 return new MobileState();
366 }
367
Jason Monkda68f592015-01-07 10:55:58 -0500368 private boolean isCdma() {
369 return (mSignalStrength != null) && !mSignalStrength.isGsm();
370 }
371
372 public boolean isEmergencyOnly() {
373 return (mServiceState != null && mServiceState.isEmergencyOnly());
374 }
375
376 private boolean isRoaming() {
Shishir Agrawal7ef5b882017-06-26 12:06:03 -0700377 // During a carrier change, roaming indications need to be supressed.
378 if (isCarrierNetworkChangeActive()) {
379 return false;
380 }
Jason Monke1531982017-09-05 11:20:30 -0400381 if (isCdma() && mServiceState != null) {
Jason Monkda68f592015-01-07 10:55:58 -0500382 final int iconMode = mServiceState.getCdmaEriIconMode();
383 return mServiceState.getCdmaEriIconIndex() != EriInfo.ROAMING_INDICATOR_OFF
384 && (iconMode == EriInfo.ROAMING_ICON_MODE_NORMAL
Jason Monk0288de02017-02-23 14:48:05 -0500385 || iconMode == EriInfo.ROAMING_ICON_MODE_FLASH);
Jason Monkda68f592015-01-07 10:55:58 -0500386 } else {
387 return mServiceState != null && mServiceState.getRoaming();
388 }
389 }
390
Andrew Flynna478d702015-04-14 23:33:45 -0400391 private boolean isCarrierNetworkChangeActive() {
Andrew Flynn55fc8002015-05-29 08:33:46 -0400392 return mCurrentState.carrierNetworkChangeMode;
Andrew Flynna478d702015-04-14 23:33:45 -0400393 }
394
Jason Monkda68f592015-01-07 10:55:58 -0500395 public void handleBroadcast(Intent intent) {
396 String action = intent.getAction();
397 if (action.equals(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION)) {
398 updateNetworkName(intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false),
399 intent.getStringExtra(TelephonyIntents.EXTRA_SPN),
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700400 intent.getStringExtra(TelephonyIntents.EXTRA_DATA_SPN),
Jason Monkda68f592015-01-07 10:55:58 -0500401 intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false),
402 intent.getStringExtra(TelephonyIntents.EXTRA_PLMN));
403 notifyListenersIfNecessary();
404 } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
405 updateDataSim();
Jason Monk8fcab352015-06-29 10:57:00 -0400406 notifyListenersIfNecessary();
Jason Monkda68f592015-01-07 10:55:58 -0500407 }
408 }
409
410 private void updateDataSim() {
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400411 int activeDataSubId = mDefaults.getActiveDataSubId();
412 if (SubscriptionManager.isValidSubscriptionId(activeDataSubId)) {
413 mCurrentState.dataSim = activeDataSubId == mSubscriptionInfo.getSubscriptionId();
Jason Monkda68f592015-01-07 10:55:58 -0500414 } else {
415 // There doesn't seem to be a data sim selected, however if
416 // there isn't a MobileSignalController with dataSim set, then
417 // QS won't get any callbacks and will be blank. Instead
418 // lets just assume we are the data sim (which will basically
419 // show one at random) in QS until one is selected. The user
420 // should pick one soon after, so we shouldn't be in this state
421 // for long.
422 mCurrentState.dataSim = true;
423 }
Jason Monkda68f592015-01-07 10:55:58 -0500424 }
425
SongFerngWang3cbcf752019-03-21 23:14:20 +0800426 private boolean isCarrierSpecificDataIcon() {
427 if (mConfig.patternOfCarrierSpecificDataIcon == null
428 || mConfig.patternOfCarrierSpecificDataIcon.length() == 0) {
429 return false;
430 }
431
432 Pattern stringPattern = Pattern.compile(mConfig.patternOfCarrierSpecificDataIcon);
433 String[] operatorNames = new String[]{mServiceState.getOperatorAlphaLongRaw(),
434 mServiceState.getOperatorAlphaShortRaw()};
435 for (String opName : operatorNames) {
436 if (!TextUtils.isEmpty(opName)) {
437 Matcher matcher = stringPattern.matcher(opName);
438 if (matcher.find()) {
439 return true;
440 }
441 }
442 }
443 return false;
444 }
445
Jason Monkda68f592015-01-07 10:55:58 -0500446 /**
447 * Updates the network's name based on incoming spn and plmn.
448 */
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700449 void updateNetworkName(boolean showSpn, String spn, String dataSpn,
450 boolean showPlmn, String plmn) {
Jason Monkda68f592015-01-07 10:55:58 -0500451 if (CHATTY) {
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700452 Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn
453 + " spn=" + spn + " dataSpn=" + dataSpn
Jason Monkda68f592015-01-07 10:55:58 -0500454 + " showPlmn=" + showPlmn + " plmn=" + plmn);
455 }
456 StringBuilder str = new StringBuilder();
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700457 StringBuilder strData = new StringBuilder();
Jason Monkda68f592015-01-07 10:55:58 -0500458 if (showPlmn && plmn != null) {
459 str.append(plmn);
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700460 strData.append(plmn);
Jason Monkda68f592015-01-07 10:55:58 -0500461 }
462 if (showSpn && spn != null) {
463 if (str.length() != 0) {
464 str.append(mNetworkNameSeparator);
465 }
466 str.append(spn);
467 }
468 if (str.length() != 0) {
469 mCurrentState.networkName = str.toString();
470 } else {
471 mCurrentState.networkName = mNetworkNameDefault;
472 }
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700473 if (showSpn && dataSpn != null) {
474 if (strData.length() != 0) {
475 strData.append(mNetworkNameSeparator);
476 }
477 strData.append(dataSpn);
478 }
479 if (strData.length() != 0) {
480 mCurrentState.networkNameData = strData.toString();
481 } else {
482 mCurrentState.networkNameData = mNetworkNameDefault;
483 }
Jason Monkda68f592015-01-07 10:55:58 -0500484 }
485
486 /**
Jayachandran Ca6f9b6d2019-11-07 17:26:02 -0800487 * Extracts the CellSignalStrengthCdma from SignalStrength then returns the level
488 */
489 private final int getCdmaLevel() {
490 List<CellSignalStrengthCdma> signalStrengthCdma =
491 mSignalStrength.getCellSignalStrengths(CellSignalStrengthCdma.class);
492 if (!signalStrengthCdma.isEmpty()) {
493 return signalStrengthCdma.get(0).getLevel();
494 }
495 return CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
496 }
497
498 /**
Jason Monkda68f592015-01-07 10:55:58 -0500499 * Updates the current state based on mServiceState, mSignalStrength, mDataNetType,
500 * mDataState, and mSimState. It should be called any time one of these is updated.
501 * This will call listeners if necessary.
502 */
503 private final void updateTelephony() {
504 if (DEBUG) {
SongFerngWang8cfb4d52018-08-21 18:04:29 +0800505 Log.d(mTag, "updateTelephonySignalStrength: hasService=" +
506 Utils.isInService(mServiceState) + " ss=" + mSignalStrength);
Jason Monkda68f592015-01-07 10:55:58 -0500507 }
Evan Laird2ea99c12019-09-19 16:52:58 -0400508 checkDefaultData();
SongFerngWang8cfb4d52018-08-21 18:04:29 +0800509 mCurrentState.connected = Utils.isInService(mServiceState)
510 && mSignalStrength != null;
Jason Monkda68f592015-01-07 10:55:58 -0500511 if (mCurrentState.connected) {
512 if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) {
Jayachandran Ca6f9b6d2019-11-07 17:26:02 -0800513 mCurrentState.level = getCdmaLevel();
Jason Monkda68f592015-01-07 10:55:58 -0500514 } else {
515 mCurrentState.level = mSignalStrength.getLevel();
516 }
517 }
Pengquan Menga62d32b2018-12-06 17:38:38 -0800518
519 // When the device is camped on a 5G Non-Standalone network, the data network type is still
520 // LTE. In this case, we first check which 5G icon should be shown.
521 MobileIconGroup nr5GIconGroup = getNr5GIconGroup();
Bill Lin767c0db2019-08-15 20:42:06 +0800522 if (mConfig.nrIconDisplayGracePeriodMs > 0) {
523 nr5GIconGroup = adjustNr5GIconGroupByDisplayGraceTime(nr5GIconGroup);
524 }
525
Pengquan Menga62d32b2018-12-06 17:38:38 -0800526 if (nr5GIconGroup != null) {
527 mCurrentState.iconGroup = nr5GIconGroup;
528 } else if (mNetworkToIconLookup.indexOfKey(mDataNetType) >= 0) {
Jason Monkda68f592015-01-07 10:55:58 -0500529 mCurrentState.iconGroup = mNetworkToIconLookup.get(mDataNetType);
530 } else {
531 mCurrentState.iconGroup = mDefaultIcons;
532 }
533 mCurrentState.dataConnected = mCurrentState.connected
Jason Monk7e6c83c2017-04-26 14:35:24 -0400534 && mDataState == TelephonyManager.DATA_CONNECTED;
Jason Monkda68f592015-01-07 10:55:58 -0500535
Jason Monk0f0de132016-12-19 15:36:13 -0500536 mCurrentState.roaming = isRoaming();
Andrew Flynna478d702015-04-14 23:33:45 -0400537 if (isCarrierNetworkChangeActive()) {
538 mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
Wenting Xiong63364fe2017-02-07 19:12:27 +0800539 } else if (isDataDisabled() && !mConfig.alwaysShowDataRatIcon) {
Fabian Kozynskic7bc84b2019-03-11 13:57:31 -0400540 if (mSubscriptionInfo.getSubscriptionId()
541 != mDefaults.getDefaultDataSubId()) {
542 mCurrentState.iconGroup = TelephonyIcons.NOT_DEFAULT_DATA;
543 } else {
544 mCurrentState.iconGroup = TelephonyIcons.DATA_DISABLED;
545 }
Jason Monkda68f592015-01-07 10:55:58 -0500546 }
547 if (isEmergencyOnly() != mCurrentState.isEmergency) {
548 mCurrentState.isEmergency = isEmergencyOnly();
549 mNetworkController.recalculateEmergency();
550 }
551 // Fill in the network name if we think we have it.
Fabian Kozynskia9091992019-03-25 11:08:32 -0400552 if (mCurrentState.networkName.equals(mNetworkNameDefault) && mServiceState != null
Jason Monk93fb68f2015-07-20 11:43:56 -0400553 && !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) {
Jason Monkda68f592015-01-07 10:55:58 -0500554 mCurrentState.networkName = mServiceState.getOperatorAlphaShort();
555 }
Fabian Kozynskia9091992019-03-25 11:08:32 -0400556 // If this is the data subscription, update the currentState data name
557 if (mCurrentState.networkNameData.equals(mNetworkNameDefault) && mServiceState != null
558 && mCurrentState.dataSim
559 && !TextUtils.isEmpty(mServiceState.getDataOperatorAlphaShort())) {
560 mCurrentState.networkNameData = mServiceState.getDataOperatorAlphaShort();
561 }
Andrew Flynna478d702015-04-14 23:33:45 -0400562
Jason Monkda68f592015-01-07 10:55:58 -0500563 notifyListenersIfNecessary();
564 }
565
Evan Laird2ea99c12019-09-19 16:52:58 -0400566 /**
567 * If we are controlling the NOT_DEFAULT_DATA icon, check the status of the other one
568 */
569 private void checkDefaultData() {
570 if (mCurrentState.iconGroup != TelephonyIcons.NOT_DEFAULT_DATA) {
571 mCurrentState.defaultDataOff = false;
572 return;
573 }
574
575 mCurrentState.defaultDataOff = mNetworkController.isDataControllerDisabled();
576 }
577
578 void onMobileDataChanged() {
579 checkDefaultData();
580 notifyListenersIfNecessary();
581 }
582
Pengquan Menga62d32b2018-12-06 17:38:38 -0800583 private MobileIconGroup getNr5GIconGroup() {
584 if (mServiceState == null) return null;
585
Jack Yu20d71402019-03-16 23:00:35 -0700586 int nrState = mServiceState.getNrState();
587 if (nrState == NetworkRegistrationInfo.NR_STATE_CONNECTED) {
Pengquan Menga62d32b2018-12-06 17:38:38 -0800588 // Check if the NR 5G is using millimeter wave and the icon is config.
589 if (mServiceState.getNrFrequencyRange() == ServiceState.FREQUENCY_RANGE_MMWAVE) {
590 if (mConfig.nr5GIconMap.containsKey(Config.NR_CONNECTED_MMWAVE)) {
591 return mConfig.nr5GIconMap.get(Config.NR_CONNECTED_MMWAVE);
592 }
593 }
594
595 // If NR 5G is not using millimeter wave or there is no icon for millimeter wave, we
596 // check the normal 5G icon.
597 if (mConfig.nr5GIconMap.containsKey(Config.NR_CONNECTED)) {
598 return mConfig.nr5GIconMap.get(Config.NR_CONNECTED);
599 }
Jack Yu20d71402019-03-16 23:00:35 -0700600 } else if (nrState == NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED) {
SongFerngWang52dada72019-08-14 16:59:29 +0800601 if (mCurrentState.activityDormant) {
602 if (mConfig.nr5GIconMap.containsKey(Config.NR_NOT_RESTRICTED_RRC_IDLE)) {
603 return mConfig.nr5GIconMap.get(Config.NR_NOT_RESTRICTED_RRC_IDLE);
604 }
605 } else {
606 if (mConfig.nr5GIconMap.containsKey(Config.NR_NOT_RESTRICTED_RRC_CON)) {
607 return mConfig.nr5GIconMap.get(Config.NR_NOT_RESTRICTED_RRC_CON);
608 }
Pengquan Menga62d32b2018-12-06 17:38:38 -0800609 }
Jack Yu20d71402019-03-16 23:00:35 -0700610 } else if (nrState == NetworkRegistrationInfo.NR_STATE_RESTRICTED) {
Pengquan Menga62d32b2018-12-06 17:38:38 -0800611 if (mConfig.nr5GIconMap.containsKey(Config.NR_RESTRICTED)) {
612 return mConfig.nr5GIconMap.get(Config.NR_RESTRICTED);
613 }
614 }
615
616 return null;
617 }
618
Bill Lin767c0db2019-08-15 20:42:06 +0800619 /**
620 * The function to adjust MobileIconGroup depend on CarrierConfig's time
621 * nextIconGroup == null imply next state could be 2G/3G/4G/4G+
622 * nextIconGroup != null imply next state will be 5G/5G+
623 * Flag : mIsShowingIconGracefully
624 * ---------------------------------------------------------------------------------
625 * | Last state | Current state | Flag | Action |
626 * ---------------------------------------------------------------------------------
627 * | 5G/5G+ | 2G/3G/4G/4G+ | true | return previous IconGroup |
628 * | 5G/5G+ | 5G/5G+ | true | Bypass |
629 * | 2G/3G/4G/4G+ | 5G/5G+ | true | Bypass |
630 * | 2G/3G/4G/4G+ | 2G/3G/4G/4G+ | true | Bypass |
631 * | SS.connected | SS.disconnect | T|F | Reset timer |
632 * |NETWORK_TYPE_LTE|!NETWORK_TYPE_LTE| T|F | Reset timer |
633 * | 5G/5G+ | 2G/3G/4G/4G+ | false| Bypass |
634 * | 5G/5G+ | 5G/5G+ | false| Bypass |
635 * | 2G/3G/4G/4G+ | 5G/5G+ | false| SendMessageDelay(time), flag->true |
636 * | 2G/3G/4G/4G+ | 2G/3G/4G/4G+ | false| Bypass |
637 * ---------------------------------------------------------------------------------
638 */
639 private MobileIconGroup adjustNr5GIconGroupByDisplayGraceTime(
640 MobileIconGroup candidateIconGroup) {
641 if (mIsShowingIconGracefully && candidateIconGroup == null) {
642 candidateIconGroup = (MobileIconGroup) mCurrentState.iconGroup;
643 } else if (!mIsShowingIconGracefully && candidateIconGroup != null
644 && mLastState.iconGroup != candidateIconGroup) {
645 mDisplayGraceHandler.sendMessageDelayed(
646 mDisplayGraceHandler.obtainMessage(MSG_DISPLAY_GRACE),
647 mConfig.nrIconDisplayGracePeriodMs);
648 mIsShowingIconGracefully = true;
649 } else if (!mCurrentState.connected || mDataState == TelephonyManager.DATA_DISCONNECTED
650 || candidateIconGroup == null) {
651 mDisplayGraceHandler.removeMessages(MSG_DISPLAY_GRACE);
652 mIsShowingIconGracefully = false;
653 candidateIconGroup = null;
654 }
655
656 return candidateIconGroup;
657 }
658
Evan Laird2ea99c12019-09-19 16:52:58 -0400659 boolean isDataDisabled() {
Malcolm Chen04be9d12019-06-11 19:48:38 -0700660 return !mPhone.isDataCapable();
Jason Monk1a95c862016-01-27 15:18:41 -0500661 }
662
Jason Monkda68f592015-01-07 10:55:58 -0500663 @VisibleForTesting
664 void setActivity(int activity) {
665 mCurrentState.activityIn = activity == TelephonyManager.DATA_ACTIVITY_INOUT
666 || activity == TelephonyManager.DATA_ACTIVITY_IN;
667 mCurrentState.activityOut = activity == TelephonyManager.DATA_ACTIVITY_INOUT
668 || activity == TelephonyManager.DATA_ACTIVITY_OUT;
SongFerngWang52dada72019-08-14 16:59:29 +0800669 mCurrentState.activityDormant = activity == TelephonyManager.DATA_ACTIVITY_DORMANT;
670
Jason Monkda68f592015-01-07 10:55:58 -0500671 notifyListenersIfNecessary();
672 }
673
674 @Override
675 public void dump(PrintWriter pw) {
676 super.dump(pw);
677 pw.println(" mSubscription=" + mSubscriptionInfo + ",");
678 pw.println(" mServiceState=" + mServiceState + ",");
679 pw.println(" mSignalStrength=" + mSignalStrength + ",");
680 pw.println(" mDataState=" + mDataState + ",");
681 pw.println(" mDataNetType=" + mDataNetType + ",");
andychou9e396282019-04-10 20:49:06 +0800682 pw.println(" mInflateSignalStrengths=" + mInflateSignalStrengths + ",");
Malcolm Chen04be9d12019-06-11 19:48:38 -0700683 pw.println(" isDataDisabled=" + isDataDisabled() + ",");
Bill Lin767c0db2019-08-15 20:42:06 +0800684 pw.println(" mIsShowingIconGracefully=" + mIsShowingIconGracefully + ",");
Jason Monkda68f592015-01-07 10:55:58 -0500685 }
686
687 class MobilePhoneStateListener extends PhoneStateListener {
chen xu84a90872019-03-28 15:44:12 -0700688 public MobilePhoneStateListener(Looper looper) {
689 super(looper);
Jason Monkda68f592015-01-07 10:55:58 -0500690 }
691
692 @Override
693 public void onSignalStrengthsChanged(SignalStrength signalStrength) {
694 if (DEBUG) {
695 Log.d(mTag, "onSignalStrengthsChanged signalStrength=" + signalStrength +
696 ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
697 }
698 mSignalStrength = signalStrength;
699 updateTelephony();
700 }
701
702 @Override
703 public void onServiceStateChanged(ServiceState state) {
704 if (DEBUG) {
705 Log.d(mTag, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
706 + " dataState=" + state.getDataRegState());
707 }
708 mServiceState = state;
SongFerngWang3cbcf752019-03-21 23:14:20 +0800709 if (mServiceState != null) {
710 updateDataNetType(mServiceState.getDataNetworkType());
Robert Greenwaltea0d71392016-07-28 18:50:10 -0700711 }
Jason Monkda68f592015-01-07 10:55:58 -0500712 updateTelephony();
713 }
714
715 @Override
716 public void onDataConnectionStateChanged(int state, int networkType) {
717 if (DEBUG) {
718 Log.d(mTag, "onDataConnectionStateChanged: state=" + state
719 + " type=" + networkType);
720 }
721 mDataState = state;
SongFerngWang3cbcf752019-03-21 23:14:20 +0800722 updateDataNetType(networkType);
Jason Monkda68f592015-01-07 10:55:58 -0500723 updateTelephony();
724 }
725
SongFerngWang3cbcf752019-03-21 23:14:20 +0800726 private void updateDataNetType(int networkType) {
727 mDataNetType = networkType;
728 if (mDataNetType == TelephonyManager.NETWORK_TYPE_LTE) {
729 if (isCarrierSpecificDataIcon()) {
730 mDataNetType = NETWORK_TYPE_LTE_CA_5GE;
731 } else if (mServiceState != null && mServiceState.isUsingCarrierAggregation()) {
732 mDataNetType = TelephonyManager.NETWORK_TYPE_LTE_CA;
733 }
734 }
735 }
736
Jason Monkda68f592015-01-07 10:55:58 -0500737 @Override
738 public void onDataActivity(int direction) {
739 if (DEBUG) {
740 Log.d(mTag, "onDataActivity: direction=" + direction);
741 }
742 setActivity(direction);
743 }
Andrew Flynna478d702015-04-14 23:33:45 -0400744
745 @Override
746 public void onCarrierNetworkChange(boolean active) {
747 if (DEBUG) {
748 Log.d(mTag, "onCarrierNetworkChange: active=" + active);
749 }
750 mCurrentState.carrierNetworkChangeMode = active;
751
752 updateTelephony();
753 }
Fabian Kozynskiaaf78972019-07-08 10:02:08 -0400754
755 @Override
756 public void onActiveDataSubscriptionIdChanged(int subId) {
757 if (DEBUG) Log.d(mTag, "onActiveDataSubscriptionIdChanged: subId=" + subId);
758 updateDataSim();
759 updateTelephony();
760 }
Jason Monkda68f592015-01-07 10:55:58 -0500761 };
762
763 static class MobileIconGroup extends SignalController.IconGroup {
764 final int mDataContentDescription; // mContentDescriptionDataType
765 final int mDataType;
766 final boolean mIsWide;
Jason Monk33f8ae72015-05-08 10:45:15 -0400767 final int mQsDataType;
Jason Monkda68f592015-01-07 10:55:58 -0500768
769 public MobileIconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc,
770 int sbNullState, int qsNullState, int sbDiscState, int qsDiscState,
Amin Shaikhd64e6262018-03-08 10:08:13 -0500771 int discContentDesc, int dataContentDesc, int dataType, boolean isWide) {
Andrew Flynn2fdbe122015-06-01 16:34:21 -0400772 super(name, sbIcons, qsIcons, contentDesc, sbNullState, qsNullState, sbDiscState,
773 qsDiscState, discContentDesc);
Jason Monkda68f592015-01-07 10:55:58 -0500774 mDataContentDescription = dataContentDesc;
775 mDataType = dataType;
776 mIsWide = isWide;
Amin Shaikhd64e6262018-03-08 10:08:13 -0500777 mQsDataType = dataType; // TODO: remove this field
Jason Monkda68f592015-01-07 10:55:58 -0500778 }
779 }
780
781 static class MobileState extends SignalController.State {
782 String networkName;
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700783 String networkNameData;
Jason Monkda68f592015-01-07 10:55:58 -0500784 boolean dataSim;
785 boolean dataConnected;
786 boolean isEmergency;
787 boolean airplaneMode;
Andrew Flynna478d702015-04-14 23:33:45 -0400788 boolean carrierNetworkChangeMode;
Jason Monk33f8ae72015-05-08 10:45:15 -0400789 boolean isDefault;
Jason Monkfd57ea72016-04-29 13:37:58 -0400790 boolean userSetup;
Jason Monk0f0de132016-12-19 15:36:13 -0500791 boolean roaming;
Evan Laird2ea99c12019-09-19 16:52:58 -0400792 boolean defaultDataOff; // Tracks the on/off state of the defaultDataSubscription
Jason Monkda68f592015-01-07 10:55:58 -0500793
794 @Override
795 public void copyFrom(State s) {
796 super.copyFrom(s);
797 MobileState state = (MobileState) s;
798 dataSim = state.dataSim;
799 networkName = state.networkName;
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700800 networkNameData = state.networkNameData;
Jason Monkda68f592015-01-07 10:55:58 -0500801 dataConnected = state.dataConnected;
Jason Monk33f8ae72015-05-08 10:45:15 -0400802 isDefault = state.isDefault;
Jason Monkda68f592015-01-07 10:55:58 -0500803 isEmergency = state.isEmergency;
804 airplaneMode = state.airplaneMode;
Andrew Flynna478d702015-04-14 23:33:45 -0400805 carrierNetworkChangeMode = state.carrierNetworkChangeMode;
Jason Monkfd57ea72016-04-29 13:37:58 -0400806 userSetup = state.userSetup;
Jason Monk0f0de132016-12-19 15:36:13 -0500807 roaming = state.roaming;
Evan Laird2ea99c12019-09-19 16:52:58 -0400808 defaultDataOff = state.defaultDataOff;
Jason Monkda68f592015-01-07 10:55:58 -0500809 }
810
811 @Override
812 protected void toString(StringBuilder builder) {
813 super.toString(builder);
814 builder.append(',');
815 builder.append("dataSim=").append(dataSim).append(',');
816 builder.append("networkName=").append(networkName).append(',');
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700817 builder.append("networkNameData=").append(networkNameData).append(',');
Jason Monkda68f592015-01-07 10:55:58 -0500818 builder.append("dataConnected=").append(dataConnected).append(',');
Jason Monk0f0de132016-12-19 15:36:13 -0500819 builder.append("roaming=").append(roaming).append(',');
Jason Monk33f8ae72015-05-08 10:45:15 -0400820 builder.append("isDefault=").append(isDefault).append(',');
Jason Monkda68f592015-01-07 10:55:58 -0500821 builder.append("isEmergency=").append(isEmergency).append(',');
Andrew Flynna478d702015-04-14 23:33:45 -0400822 builder.append("airplaneMode=").append(airplaneMode).append(',');
Jason Monkfd57ea72016-04-29 13:37:58 -0400823 builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode)
824 .append(',');
Evan Laird2ea99c12019-09-19 16:52:58 -0400825 builder.append("userSetup=").append(userSetup).append(',');
826 builder.append("defaultDataOff=").append(defaultDataOff);
Jason Monkda68f592015-01-07 10:55:58 -0500827 }
828
829 @Override
830 public boolean equals(Object o) {
831 return super.equals(o)
832 && Objects.equals(((MobileState) o).networkName, networkName)
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700833 && Objects.equals(((MobileState) o).networkNameData, networkNameData)
Jason Monkda68f592015-01-07 10:55:58 -0500834 && ((MobileState) o).dataSim == dataSim
835 && ((MobileState) o).dataConnected == dataConnected
836 && ((MobileState) o).isEmergency == isEmergency
837 && ((MobileState) o).airplaneMode == airplaneMode
Andrew Flynna478d702015-04-14 23:33:45 -0400838 && ((MobileState) o).carrierNetworkChangeMode == carrierNetworkChangeMode
Jason Monkfd57ea72016-04-29 13:37:58 -0400839 && ((MobileState) o).userSetup == userSetup
Jason Monk0f0de132016-12-19 15:36:13 -0500840 && ((MobileState) o).isDefault == isDefault
Evan Laird2ea99c12019-09-19 16:52:58 -0400841 && ((MobileState) o).roaming == roaming
842 && ((MobileState) o).defaultDataOff == defaultDataOff;
Jason Monkda68f592015-01-07 10:55:58 -0500843 }
844 }
845}