blob: 3a1feaa2de141b10f5c3b086503725ac2d2f14ab [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
Hall Liu5a95a702020-01-06 19:04:10 -080018import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
19import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
20
Jason Monkda68f592015-01-07 10:55:58 -050021import android.content.Context;
22import android.content.Intent;
Jason Monk0288de02017-02-23 14:48:05 -050023import android.database.ContentObserver;
Jason Monkda68f592015-01-07 10:55:58 -050024import android.net.NetworkCapabilities;
Jason Monk0288de02017-02-23 14:48:05 -050025import android.os.Handler;
Jason Monk07b75fe2015-05-14 16:47:03 -040026import android.os.Looper;
Bill Lin767c0db2019-08-15 20:42:06 +080027import android.os.Message;
Jason Monk0288de02017-02-23 14:48:05 -050028import android.provider.Settings.Global;
Daniel Brightaa819042020-01-10 18:05:01 -080029import android.telephony.Annotation;
Jayachandran C7803cfa2020-01-21 15:01:12 -080030import android.telephony.CdmaEriInformation;
Jayachandran Ca6f9b6d2019-11-07 17:26:02 -080031import android.telephony.CellSignalStrength;
32import android.telephony.CellSignalStrengthCdma;
Jack Yue27d3fd2019-03-15 14:49:53 -070033import android.telephony.NetworkRegistrationInfo;
Jason Monkda68f592015-01-07 10:55:58 -050034import android.telephony.PhoneStateListener;
35import android.telephony.ServiceState;
36import android.telephony.SignalStrength;
37import android.telephony.SubscriptionInfo;
38import android.telephony.SubscriptionManager;
39import android.telephony.TelephonyManager;
Jason Monk93fb68f2015-07-20 11:43:56 -040040import android.text.TextUtils;
Jason Monkda68f592015-01-07 10:55:58 -050041import android.util.Log;
Jason Monkda68f592015-01-07 10:55:58 -050042
43import com.android.internal.annotations.VisibleForTesting;
SongFerngWang8cfb4d52018-08-21 18:04:29 +080044import com.android.settingslib.Utils;
Gus Prevasab336792018-11-14 13:52:20 -050045import com.android.settingslib.graph.SignalDrawable;
Antony Sargentc026de32019-05-21 16:29:04 -070046import com.android.settingslib.net.SignalStrengthUtil;
Jason Monkda68f592015-01-07 10:55:58 -050047import com.android.systemui.R;
Jason Monk07b75fe2015-05-14 16:47:03 -040048import com.android.systemui.statusbar.policy.NetworkController.IconState;
Jason Monke06b0652016-03-02 16:35:27 -050049import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
Jason Monkda68f592015-01-07 10:55:58 -050050import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
Jason Monkc6cc6262015-06-11 11:10:15 -040051import com.android.systemui.statusbar.policy.NetworkControllerImpl.SubscriptionDefaults;
Jason Monkda68f592015-01-07 10:55:58 -050052
53import java.io.PrintWriter;
Jason Monk33f8ae72015-05-08 10:45:15 -040054import java.util.BitSet;
Daniel Brightaa819042020-01-10 18:05:01 -080055import java.util.HashMap;
Jayachandran Ca6f9b6d2019-11-07 17:26:02 -080056import java.util.List;
Daniel Brightaa819042020-01-10 18:05:01 -080057import java.util.Map;
SongFerngWang2b1ea8d2019-11-20 02:11:09 +080058import java.util.Objects;
59import java.util.concurrent.Executor;
SongFerngWang3cbcf752019-03-21 23:14:20 +080060import java.util.regex.Matcher;
61import java.util.regex.Pattern;
Jason Monkda68f592015-01-07 10:55:58 -050062
63
64public class MobileSignalController extends SignalController<
65 MobileSignalController.MobileState, MobileSignalController.MobileIconGroup> {
Bill Lin767c0db2019-08-15 20:42:06 +080066
67 // The message to display Nr5G icon gracfully by CarrierConfig timeout
68 private static final int MSG_DISPLAY_GRACE = 1;
69
Jason Monkda68f592015-01-07 10:55:58 -050070 private final TelephonyManager mPhone;
Jason Monkc6cc6262015-06-11 11:10:15 -040071 private final SubscriptionDefaults mDefaults;
Jason Monkda68f592015-01-07 10:55:58 -050072 private final String mNetworkNameDefault;
73 private final String mNetworkNameSeparator;
Jason Monk0288de02017-02-23 14:48:05 -050074 private final ContentObserver mObserver;
Jason Monkda68f592015-01-07 10:55:58 -050075 @VisibleForTesting
76 final PhoneStateListener mPhoneStateListener;
77 // Save entire info for logging, we only use the id.
Jason Monk66845a32015-08-03 11:09:41 -040078 final SubscriptionInfo mSubscriptionInfo;
Jason Monkda68f592015-01-07 10:55:58 -050079
80 // @VisibleForDemoMode
Daniel Brightaa819042020-01-10 18:05:01 -080081 final Map<String, MobileIconGroup> mNetworkToIconLookup;
Jason Monkda68f592015-01-07 10:55:58 -050082
83 // Since some pieces of the phone state are interdependent we store it locally,
84 // this could potentially become part of MobileState for simplification/complication
85 // of code.
Jason Monkda68f592015-01-07 10:55:58 -050086 private int mDataNetType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
Daniel Brightaa819042020-01-10 18:05:01 -080087 private boolean mCA = false;
88 private boolean mCAPlus = false;
Jason Monkda68f592015-01-07 10:55:58 -050089 private int mDataState = TelephonyManager.DATA_DISCONNECTED;
90 private ServiceState mServiceState;
91 private SignalStrength mSignalStrength;
92 private MobileIconGroup mDefaultIcons;
93 private Config mConfig;
Bill Lin767c0db2019-08-15 20:42:06 +080094 private final Handler mDisplayGraceHandler;
andychoub935e682019-04-11 23:40:49 +080095 @VisibleForTesting
96 boolean mInflateSignalStrengths = false;
Bill Lin767c0db2019-08-15 20:42:06 +080097 @VisibleForTesting
98 boolean mIsShowingIconGracefully = false;
Jason Monkda68f592015-01-07 10:55:58 -050099
100 // TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't
101 // need listener lists anymore.
102 public MobileSignalController(Context context, Config config, boolean hasMobileData,
Jason Monk07b75fe2015-05-14 16:47:03 -0400103 TelephonyManager phone, CallbackHandler callbackHandler,
Jason Monkc6cc6262015-06-11 11:10:15 -0400104 NetworkControllerImpl networkController, SubscriptionInfo info,
105 SubscriptionDefaults defaults, Looper receiverLooper) {
Jason Monkda68f592015-01-07 10:55:58 -0500106 super("MobileSignalController(" + info.getSubscriptionId() + ")", context,
Jason Monk07b75fe2015-05-14 16:47:03 -0400107 NetworkCapabilities.TRANSPORT_CELLULAR, callbackHandler,
Jason Monkda68f592015-01-07 10:55:58 -0500108 networkController);
Daniel Brightaa819042020-01-10 18:05:01 -0800109 mNetworkToIconLookup = new HashMap<>();
Jason Monkda68f592015-01-07 10:55:58 -0500110 mConfig = config;
111 mPhone = phone;
Jason Monkc6cc6262015-06-11 11:10:15 -0400112 mDefaults = defaults;
Jason Monkda68f592015-01-07 10:55:58 -0500113 mSubscriptionInfo = info;
Jayachandran Cff50c8e2019-10-30 16:41:59 -0700114 mPhoneStateListener = new MobilePhoneStateListener((new Handler(receiverLooper))::post);
Jason Monkda68f592015-01-07 10:55:58 -0500115 mNetworkNameSeparator = getStringIfExists(R.string.status_bar_network_name_separator);
116 mNetworkNameDefault = getStringIfExists(
117 com.android.internal.R.string.lockscreen_carrier_default);
118
119 mapIconSets();
120
Jason Monk00aa9d42015-08-10 10:12:02 -0400121 String networkName = info.getCarrierName() != null ? info.getCarrierName().toString()
122 : mNetworkNameDefault;
123 mLastState.networkName = mCurrentState.networkName = networkName;
124 mLastState.networkNameData = mCurrentState.networkNameData = networkName;
Jason Monkda68f592015-01-07 10:55:58 -0500125 mLastState.enabled = mCurrentState.enabled = hasMobileData;
126 mLastState.iconGroup = mCurrentState.iconGroup = mDefaultIcons;
127 // Get initial data sim state.
128 updateDataSim();
Jason Monk0288de02017-02-23 14:48:05 -0500129 mObserver = new ContentObserver(new Handler(receiverLooper)) {
130 @Override
131 public void onChange(boolean selfChange) {
132 updateTelephony();
133 }
134 };
Bill Lin767c0db2019-08-15 20:42:06 +0800135
136 mDisplayGraceHandler = new Handler(receiverLooper) {
137 @Override
138 public void handleMessage(Message msg) {
139 if (msg.what == MSG_DISPLAY_GRACE) {
140 mIsShowingIconGracefully = false;
141 updateTelephony();
142 }
143 }
144 };
Jason Monkda68f592015-01-07 10:55:58 -0500145 }
146
147 public void setConfiguration(Config config) {
148 mConfig = config;
andychou9e396282019-04-10 20:49:06 +0800149 updateInflateSignalStrength();
Jason Monkda68f592015-01-07 10:55:58 -0500150 mapIconSets();
151 updateTelephony();
152 }
153
Jason Monkda68f592015-01-07 10:55:58 -0500154 public int getDataContentDescription() {
155 return getIcons().mDataContentDescription;
156 }
157
Jason Monkda68f592015-01-07 10:55:58 -0500158 public void setAirplaneMode(boolean airplaneMode) {
159 mCurrentState.airplaneMode = airplaneMode;
160 notifyListenersIfNecessary();
161 }
162
Jason Monkfd57ea72016-04-29 13:37:58 -0400163 public void setUserSetupComplete(boolean userSetup) {
164 mCurrentState.userSetup = userSetup;
165 notifyListenersIfNecessary();
166 }
167
Jason Monk33f8ae72015-05-08 10:45:15 -0400168 @Override
169 public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) {
170 boolean isValidated = validatedTransports.get(mTransportType);
171 mCurrentState.isDefault = connectedTransports.get(mTransportType);
172 // Only show this as not having connectivity if we are default.
173 mCurrentState.inetCondition = (isValidated || !mCurrentState.isDefault) ? 1 : 0;
174 notifyListenersIfNecessary();
Jason Monkda68f592015-01-07 10:55:58 -0500175 }
176
Andrew Flynna478d702015-04-14 23:33:45 -0400177 public void setCarrierNetworkChangeMode(boolean carrierNetworkChangeMode) {
178 mCurrentState.carrierNetworkChangeMode = carrierNetworkChangeMode;
Andrew Flynn2fdbe122015-06-01 16:34:21 -0400179 updateTelephony();
Andrew Flynna478d702015-04-14 23:33:45 -0400180 }
181
Jason Monkda68f592015-01-07 10:55:58 -0500182 /**
183 * Start listening for phone state changes.
184 */
185 public void registerListener() {
186 mPhone.listen(mPhoneStateListener,
187 PhoneStateListener.LISTEN_SERVICE_STATE
188 | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
189 | PhoneStateListener.LISTEN_CALL_STATE
190 | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
Andrew Flynna478d702015-04-14 23:33:45 -0400191 | PhoneStateListener.LISTEN_DATA_ACTIVITY
Fabian Kozynskiaaf78972019-07-08 10:02:08 -0400192 | PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE
193 | PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
Jason Monk0288de02017-02-23 14:48:05 -0500194 mContext.getContentResolver().registerContentObserver(Global.getUriFor(Global.MOBILE_DATA),
195 true, mObserver);
196 mContext.getContentResolver().registerContentObserver(Global.getUriFor(
197 Global.MOBILE_DATA + mSubscriptionInfo.getSubscriptionId()),
198 true, mObserver);
Jason Monkda68f592015-01-07 10:55:58 -0500199 }
200
201 /**
202 * Stop listening for phone state changes.
203 */
204 public void unregisterListener() {
205 mPhone.listen(mPhoneStateListener, 0);
Jason Monk0288de02017-02-23 14:48:05 -0500206 mContext.getContentResolver().unregisterContentObserver(mObserver);
Jason Monkda68f592015-01-07 10:55:58 -0500207 }
208
209 /**
210 * Produce a mapping of data network types to icon groups for simple and quick use in
211 * updateTelephony.
212 */
213 private void mapIconSets() {
214 mNetworkToIconLookup.clear();
215
Daniel Brightaa819042020-01-10 18:05:01 -0800216 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_EVDO_0),
217 TelephonyIcons.THREE_G);
218 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_EVDO_A),
219 TelephonyIcons.THREE_G);
220 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_EVDO_B),
221 TelephonyIcons.THREE_G);
222 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_EHRPD),
223 TelephonyIcons.THREE_G);
224 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_UMTS),
225 TelephonyIcons.THREE_G);
226 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_TD_SCDMA),
227 TelephonyIcons.THREE_G);
Jason Monkda68f592015-01-07 10:55:58 -0500228
229 if (!mConfig.showAtLeast3G) {
Daniel Brightaa819042020-01-10 18:05:01 -0800230 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_UNKNOWN),
Jason Monkda68f592015-01-07 10:55:58 -0500231 TelephonyIcons.UNKNOWN);
Daniel Brightaa819042020-01-10 18:05:01 -0800232 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_EDGE),
233 TelephonyIcons.E);
234 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_CDMA),
235 TelephonyIcons.ONE_X);
236 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_1xRTT),
237 TelephonyIcons.ONE_X);
Jason Monkda68f592015-01-07 10:55:58 -0500238
239 mDefaultIcons = TelephonyIcons.G;
240 } else {
Daniel Brightaa819042020-01-10 18:05:01 -0800241 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_UNKNOWN),
Jason Monkda68f592015-01-07 10:55:58 -0500242 TelephonyIcons.THREE_G);
Daniel Brightaa819042020-01-10 18:05:01 -0800243 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_EDGE),
Jason Monkda68f592015-01-07 10:55:58 -0500244 TelephonyIcons.THREE_G);
Daniel Brightaa819042020-01-10 18:05:01 -0800245 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_CDMA),
Jason Monkda68f592015-01-07 10:55:58 -0500246 TelephonyIcons.THREE_G);
Daniel Brightaa819042020-01-10 18:05:01 -0800247 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_1xRTT),
Jason Monkda68f592015-01-07 10:55:58 -0500248 TelephonyIcons.THREE_G);
249 mDefaultIcons = TelephonyIcons.THREE_G;
250 }
251
252 MobileIconGroup hGroup = TelephonyIcons.THREE_G;
Amin Shaikhf5830ca2018-03-09 14:06:50 -0500253 MobileIconGroup hPlusGroup = TelephonyIcons.THREE_G;
vagdevi3f2b9a52019-08-09 09:45:14 -0700254 if (mConfig.show4gFor3g) {
255 hGroup = TelephonyIcons.FOUR_G;
256 hPlusGroup = TelephonyIcons.FOUR_G;
257 } else if (mConfig.hspaDataDistinguishable) {
Jason Monkda68f592015-01-07 10:55:58 -0500258 hGroup = TelephonyIcons.H;
Amin Shaikhf5830ca2018-03-09 14:06:50 -0500259 hPlusGroup = TelephonyIcons.H_PLUS;
Jason Monkda68f592015-01-07 10:55:58 -0500260 }
vagdevi3f2b9a52019-08-09 09:45:14 -0700261
Daniel Brightaa819042020-01-10 18:05:01 -0800262 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_HSDPA), hGroup);
263 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_HSUPA), hGroup);
264 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_HSPA), hGroup);
265 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_HSPAP), hPlusGroup);
Jason Monkda68f592015-01-07 10:55:58 -0500266
267 if (mConfig.show4gForLte) {
Daniel Brightaa819042020-01-10 18:05:01 -0800268 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_LTE),
269 TelephonyIcons.FOUR_G);
Robert Greenwalt37d34ba2016-07-27 14:54:34 -0700270 if (mConfig.hideLtePlus) {
Daniel Brightaa819042020-01-10 18:05:01 -0800271 mNetworkToIconLookup.put(toIconKeyCA(TelephonyManager.NETWORK_TYPE_LTE),
Robert Greenwalt37d34ba2016-07-27 14:54:34 -0700272 TelephonyIcons.FOUR_G);
273 } else {
Daniel Brightaa819042020-01-10 18:05:01 -0800274 mNetworkToIconLookup.put(toIconKeyCA(TelephonyManager.NETWORK_TYPE_LTE),
Robert Greenwalt37d34ba2016-07-27 14:54:34 -0700275 TelephonyIcons.FOUR_G_PLUS);
276 }
Jason Monkda68f592015-01-07 10:55:58 -0500277 } else {
Daniel Brightaa819042020-01-10 18:05:01 -0800278 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_LTE),
279 TelephonyIcons.LTE);
Robert Greenwalt37d34ba2016-07-27 14:54:34 -0700280 if (mConfig.hideLtePlus) {
Daniel Brightaa819042020-01-10 18:05:01 -0800281 mNetworkToIconLookup.put(toIconKeyCA(TelephonyManager.NETWORK_TYPE_LTE),
Robert Greenwalt37d34ba2016-07-27 14:54:34 -0700282 TelephonyIcons.LTE);
283 } else {
Daniel Brightaa819042020-01-10 18:05:01 -0800284 mNetworkToIconLookup.put(toIconKeyCA(TelephonyManager.NETWORK_TYPE_LTE),
Robert Greenwalt37d34ba2016-07-27 14:54:34 -0700285 TelephonyIcons.LTE_PLUS);
286 }
Jason Monkda68f592015-01-07 10:55:58 -0500287 }
Daniel Brightaa819042020-01-10 18:05:01 -0800288 mNetworkToIconLookup.put(toIconKeyCAPlus(TelephonyManager.NETWORK_TYPE_LTE),
SongFerngWang3cbcf752019-03-21 23:14:20 +0800289 TelephonyIcons.LTE_CA_5G_E);
Daniel Brightaa819042020-01-10 18:05:01 -0800290 mNetworkToIconLookup.put(toIconKey(TelephonyManager.NETWORK_TYPE_IWLAN),
291 TelephonyIcons.WFC);
292 }
293
294 private String getIconKey() {
295 if (mCA) {
296 return toIconKeyCA(mDataNetType);
297 } else if (mCAPlus) {
298 return toIconKeyCAPlus(mDataNetType);
299 } else {
300 return toIconKey(mDataNetType);
301 }
302 }
303
304 // Some specific carriers have 5GE network which is special CA network.
305 private String toIconKeyCAPlus(@Annotation.NetworkType int networkType) {
306 return toIconKeyCA(networkType) + "_Plus";
307 }
308
309 private String toIconKeyCA(@Annotation.NetworkType int networkType) {
310 return toIconKey(networkType) + "_CA";
311 }
312
313 private String toIconKey(@Annotation.NetworkType int networkType) {
314 return Integer.toString(networkType);
Jason Monkda68f592015-01-07 10:55:58 -0500315 }
316
andychou9e396282019-04-10 20:49:06 +0800317 private void updateInflateSignalStrength() {
Antony Sargentc026de32019-05-21 16:29:04 -0700318 mInflateSignalStrengths = SignalStrengthUtil.shouldInflateSignalStrength(mContext,
319 mSubscriptionInfo.getSubscriptionId());
andychou9e396282019-04-10 20:49:06 +0800320 }
321
Jason Monk48edc0c2017-04-10 15:01:27 -0400322 private int getNumLevels() {
andychou9e396282019-04-10 20:49:06 +0800323 if (mInflateSignalStrengths) {
Jason Monk43c14d12017-06-22 11:20:04 -0400324 return SignalStrength.NUM_SIGNAL_STRENGTH_BINS + 1;
325 }
Jason Monk48edc0c2017-04-10 15:01:27 -0400326 return SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
327 }
328
329 @Override
330 public int getCurrentIconId() {
331 if (mCurrentState.iconGroup == TelephonyIcons.CARRIER_NETWORK_CHANGE) {
332 return SignalDrawable.getCarrierChangeState(getNumLevels());
333 } else if (mCurrentState.connected) {
Jason Monk43c14d12017-06-22 11:20:04 -0400334 int level = mCurrentState.level;
andychou9e396282019-04-10 20:49:06 +0800335 if (mInflateSignalStrengths) {
Jason Monk43c14d12017-06-22 11:20:04 -0400336 level++;
337 }
Amin Shaikhaf4c1932018-03-08 10:29:56 -0500338 boolean dataDisabled = mCurrentState.userSetup
Fabian Kozynskic7bc84b2019-03-11 13:57:31 -0400339 && (mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED
Evan Laird2ea99c12019-09-19 16:52:58 -0400340 || (mCurrentState.iconGroup == TelephonyIcons.NOT_DEFAULT_DATA
341 && mCurrentState.defaultDataOff));
Amin Shaikhaf4c1932018-03-08 10:29:56 -0500342 boolean noInternet = mCurrentState.inetCondition == 0;
343 boolean cutOut = dataDisabled || noInternet;
344 return SignalDrawable.getState(level, getNumLevels(), cutOut);
Jason Monk48edc0c2017-04-10 15:01:27 -0400345 } else if (mCurrentState.enabled) {
346 return SignalDrawable.getEmptyState(getNumLevels());
347 } else {
348 return 0;
349 }
350 }
351
352 @Override
Jason Monk01df36f2017-06-07 13:02:47 -0400353 public int getQsCurrentIconId() {
354 return getCurrentIconId();
355 }
356
357 @Override
Jason Monke06b0652016-03-02 16:35:27 -0500358 public void notifyListeners(SignalCallback callback) {
Jason Monkda68f592015-01-07 10:55:58 -0500359 MobileIconGroup icons = getIcons();
360
361 String contentDescription = getStringIfExists(getContentDescription());
362 String dataContentDescription = getStringIfExists(icons.mDataContentDescription);
Amin Shaikh43ad7fe2018-03-05 14:34:44 -0500363 if (mCurrentState.inetCondition == 0) {
364 dataContentDescription = mContext.getString(R.string.data_connection_no_internet);
365 }
Fabian Kozynskic7bc84b2019-03-11 13:57:31 -0400366 final boolean dataDisabled = (mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED
Evan Laird2ea99c12019-09-19 16:52:58 -0400367 || (mCurrentState.iconGroup == TelephonyIcons.NOT_DEFAULT_DATA))
Jason Monkfd57ea72016-04-29 13:37:58 -0400368 && mCurrentState.userSetup;
Jeff Davidson5c7daaf2015-01-27 16:24:32 -0800369
Jason Monk0f0de132016-12-19 15:36:13 -0500370 // Show icon in QS when we are connected or data is disabled.
Jason Monk7e6c83c2017-04-26 14:35:24 -0400371 boolean showDataIcon = mCurrentState.dataConnected || dataDisabled;
Jason Monk07b75fe2015-05-14 16:47:03 -0400372 IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode,
373 getCurrentIconId(), contentDescription);
374
Jason Monk7e6c83c2017-04-26 14:35:24 -0400375 int qsTypeIcon = 0;
376 IconState qsIcon = null;
377 String description = null;
378 // Only send data sim callbacks to QS.
379 if (mCurrentState.dataSim) {
Evan Laird9dcd3222017-12-04 14:31:48 -0500380 qsTypeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon) ? icons.mQsDataType : 0;
Jason Monk7e6c83c2017-04-26 14:35:24 -0400381 qsIcon = new IconState(mCurrentState.enabled
Jason Monk01df36f2017-06-07 13:02:47 -0400382 && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription);
Jason Monk7e6c83c2017-04-26 14:35:24 -0400383 description = mCurrentState.isEmergency ? null : mCurrentState.networkName;
384 }
Jason Monk07b75fe2015-05-14 16:47:03 -0400385 boolean activityIn = mCurrentState.dataConnected
Jason Monk0288de02017-02-23 14:48:05 -0500386 && !mCurrentState.carrierNetworkChangeMode
387 && mCurrentState.activityIn;
Jason Monk07b75fe2015-05-14 16:47:03 -0400388 boolean activityOut = mCurrentState.dataConnected
Jason Monk0288de02017-02-23 14:48:05 -0500389 && !mCurrentState.carrierNetworkChangeMode
390 && mCurrentState.activityOut;
Jason Monk0f0de132016-12-19 15:36:13 -0500391 showDataIcon &= mCurrentState.isDefault || dataDisabled;
Wenting Xiong63364fe2017-02-07 19:12:27 +0800392 int typeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon) ? icons.mDataType : 0;
Jason Monk7e6c83c2017-04-26 14:35:24 -0400393 callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
394 activityIn, activityOut, dataContentDescription, description, icons.mIsWide,
395 mSubscriptionInfo.getSubscriptionId(), mCurrentState.roaming);
Andrew Flynna478d702015-04-14 23:33:45 -0400396 }
397
Jason Monkda68f592015-01-07 10:55:58 -0500398 @Override
399 protected MobileState cleanState() {
400 return new MobileState();
401 }
402
Jason Monkda68f592015-01-07 10:55:58 -0500403 private boolean isCdma() {
404 return (mSignalStrength != null) && !mSignalStrength.isGsm();
405 }
406
407 public boolean isEmergencyOnly() {
408 return (mServiceState != null && mServiceState.isEmergencyOnly());
409 }
410
411 private boolean isRoaming() {
Shishir Agrawal7ef5b882017-06-26 12:06:03 -0700412 // During a carrier change, roaming indications need to be supressed.
413 if (isCarrierNetworkChangeActive()) {
414 return false;
415 }
Jason Monke1531982017-09-05 11:20:30 -0400416 if (isCdma() && mServiceState != null) {
Jayachandran C7803cfa2020-01-21 15:01:12 -0800417 final int iconMode = mPhone.getCdmaEriInformation().getEriIconMode();
418 return mPhone.getCdmaEriInformation().getEriIconIndex() != CdmaEriInformation.ERI_OFF
419 && (iconMode == CdmaEriInformation.ERI_ICON_MODE_NORMAL
420 || iconMode == CdmaEriInformation.ERI_ICON_MODE_FLASH);
Jason Monkda68f592015-01-07 10:55:58 -0500421 } else {
422 return mServiceState != null && mServiceState.getRoaming();
423 }
424 }
425
Andrew Flynna478d702015-04-14 23:33:45 -0400426 private boolean isCarrierNetworkChangeActive() {
Andrew Flynn55fc8002015-05-29 08:33:46 -0400427 return mCurrentState.carrierNetworkChangeMode;
Andrew Flynna478d702015-04-14 23:33:45 -0400428 }
429
Jason Monkda68f592015-01-07 10:55:58 -0500430 public void handleBroadcast(Intent intent) {
431 String action = intent.getAction();
Meng Wang57f56552020-01-17 16:58:40 -0800432 if (action.equals(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED)) {
433 updateNetworkName(intent.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, false),
434 intent.getStringExtra(TelephonyManager.EXTRA_SPN),
435 intent.getStringExtra(TelephonyManager.EXTRA_DATA_SPN),
436 intent.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false),
437 intent.getStringExtra(TelephonyManager.EXTRA_PLMN));
Jason Monkda68f592015-01-07 10:55:58 -0500438 notifyListenersIfNecessary();
Jayachandran C041e7692019-12-20 16:20:02 -0800439 } else if (action.equals(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
Jason Monkda68f592015-01-07 10:55:58 -0500440 updateDataSim();
Jason Monk8fcab352015-06-29 10:57:00 -0400441 notifyListenersIfNecessary();
Jason Monkda68f592015-01-07 10:55:58 -0500442 }
443 }
444
445 private void updateDataSim() {
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400446 int activeDataSubId = mDefaults.getActiveDataSubId();
447 if (SubscriptionManager.isValidSubscriptionId(activeDataSubId)) {
448 mCurrentState.dataSim = activeDataSubId == mSubscriptionInfo.getSubscriptionId();
Jason Monkda68f592015-01-07 10:55:58 -0500449 } else {
450 // There doesn't seem to be a data sim selected, however if
451 // there isn't a MobileSignalController with dataSim set, then
452 // QS won't get any callbacks and will be blank. Instead
453 // lets just assume we are the data sim (which will basically
454 // show one at random) in QS until one is selected. The user
455 // should pick one soon after, so we shouldn't be in this state
456 // for long.
457 mCurrentState.dataSim = true;
458 }
Jason Monkda68f592015-01-07 10:55:58 -0500459 }
460
SongFerngWang3cbcf752019-03-21 23:14:20 +0800461 private boolean isCarrierSpecificDataIcon() {
462 if (mConfig.patternOfCarrierSpecificDataIcon == null
463 || mConfig.patternOfCarrierSpecificDataIcon.length() == 0) {
464 return false;
465 }
466
467 Pattern stringPattern = Pattern.compile(mConfig.patternOfCarrierSpecificDataIcon);
468 String[] operatorNames = new String[]{mServiceState.getOperatorAlphaLongRaw(),
469 mServiceState.getOperatorAlphaShortRaw()};
470 for (String opName : operatorNames) {
471 if (!TextUtils.isEmpty(opName)) {
472 Matcher matcher = stringPattern.matcher(opName);
473 if (matcher.find()) {
474 return true;
475 }
476 }
477 }
478 return false;
479 }
480
Jason Monkda68f592015-01-07 10:55:58 -0500481 /**
482 * Updates the network's name based on incoming spn and plmn.
483 */
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700484 void updateNetworkName(boolean showSpn, String spn, String dataSpn,
485 boolean showPlmn, String plmn) {
Jason Monkda68f592015-01-07 10:55:58 -0500486 if (CHATTY) {
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700487 Log.d("CarrierLabel", "updateNetworkName showSpn=" + showSpn
488 + " spn=" + spn + " dataSpn=" + dataSpn
Jason Monkda68f592015-01-07 10:55:58 -0500489 + " showPlmn=" + showPlmn + " plmn=" + plmn);
490 }
491 StringBuilder str = new StringBuilder();
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700492 StringBuilder strData = new StringBuilder();
Jason Monkda68f592015-01-07 10:55:58 -0500493 if (showPlmn && plmn != null) {
494 str.append(plmn);
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700495 strData.append(plmn);
Jason Monkda68f592015-01-07 10:55:58 -0500496 }
497 if (showSpn && spn != null) {
498 if (str.length() != 0) {
499 str.append(mNetworkNameSeparator);
500 }
501 str.append(spn);
502 }
503 if (str.length() != 0) {
504 mCurrentState.networkName = str.toString();
505 } else {
506 mCurrentState.networkName = mNetworkNameDefault;
507 }
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700508 if (showSpn && dataSpn != null) {
509 if (strData.length() != 0) {
510 strData.append(mNetworkNameSeparator);
511 }
512 strData.append(dataSpn);
513 }
514 if (strData.length() != 0) {
515 mCurrentState.networkNameData = strData.toString();
516 } else {
517 mCurrentState.networkNameData = mNetworkNameDefault;
518 }
Jason Monkda68f592015-01-07 10:55:58 -0500519 }
520
521 /**
Jayachandran Ca6f9b6d2019-11-07 17:26:02 -0800522 * Extracts the CellSignalStrengthCdma from SignalStrength then returns the level
523 */
524 private final int getCdmaLevel() {
525 List<CellSignalStrengthCdma> signalStrengthCdma =
526 mSignalStrength.getCellSignalStrengths(CellSignalStrengthCdma.class);
527 if (!signalStrengthCdma.isEmpty()) {
528 return signalStrengthCdma.get(0).getLevel();
529 }
530 return CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
531 }
532
533 /**
Jason Monkda68f592015-01-07 10:55:58 -0500534 * Updates the current state based on mServiceState, mSignalStrength, mDataNetType,
535 * mDataState, and mSimState. It should be called any time one of these is updated.
536 * This will call listeners if necessary.
537 */
538 private final void updateTelephony() {
539 if (DEBUG) {
SongFerngWang8cfb4d52018-08-21 18:04:29 +0800540 Log.d(mTag, "updateTelephonySignalStrength: hasService=" +
541 Utils.isInService(mServiceState) + " ss=" + mSignalStrength);
Jason Monkda68f592015-01-07 10:55:58 -0500542 }
Evan Laird2ea99c12019-09-19 16:52:58 -0400543 checkDefaultData();
SongFerngWang8cfb4d52018-08-21 18:04:29 +0800544 mCurrentState.connected = Utils.isInService(mServiceState)
545 && mSignalStrength != null;
Jason Monkda68f592015-01-07 10:55:58 -0500546 if (mCurrentState.connected) {
547 if (!mSignalStrength.isGsm() && mConfig.alwaysShowCdmaRssi) {
Jayachandran Ca6f9b6d2019-11-07 17:26:02 -0800548 mCurrentState.level = getCdmaLevel();
Jason Monkda68f592015-01-07 10:55:58 -0500549 } else {
550 mCurrentState.level = mSignalStrength.getLevel();
551 }
552 }
Pengquan Menga62d32b2018-12-06 17:38:38 -0800553
554 // When the device is camped on a 5G Non-Standalone network, the data network type is still
555 // LTE. In this case, we first check which 5G icon should be shown.
556 MobileIconGroup nr5GIconGroup = getNr5GIconGroup();
Bill Lin767c0db2019-08-15 20:42:06 +0800557 if (mConfig.nrIconDisplayGracePeriodMs > 0) {
558 nr5GIconGroup = adjustNr5GIconGroupByDisplayGraceTime(nr5GIconGroup);
559 }
560
Daniel Brightaa819042020-01-10 18:05:01 -0800561 String iconKey = getIconKey();
Pengquan Menga62d32b2018-12-06 17:38:38 -0800562 if (nr5GIconGroup != null) {
563 mCurrentState.iconGroup = nr5GIconGroup;
Daniel Brightaa819042020-01-10 18:05:01 -0800564 } else if (mNetworkToIconLookup.get(iconKey) != null) {
565 mCurrentState.iconGroup = mNetworkToIconLookup.get(iconKey);
Jason Monkda68f592015-01-07 10:55:58 -0500566 } else {
567 mCurrentState.iconGroup = mDefaultIcons;
568 }
569 mCurrentState.dataConnected = mCurrentState.connected
Jason Monk7e6c83c2017-04-26 14:35:24 -0400570 && mDataState == TelephonyManager.DATA_CONNECTED;
Jason Monkda68f592015-01-07 10:55:58 -0500571
Jason Monk0f0de132016-12-19 15:36:13 -0500572 mCurrentState.roaming = isRoaming();
Andrew Flynna478d702015-04-14 23:33:45 -0400573 if (isCarrierNetworkChangeActive()) {
574 mCurrentState.iconGroup = TelephonyIcons.CARRIER_NETWORK_CHANGE;
Wenting Xiong63364fe2017-02-07 19:12:27 +0800575 } else if (isDataDisabled() && !mConfig.alwaysShowDataRatIcon) {
Fabian Kozynskic7bc84b2019-03-11 13:57:31 -0400576 if (mSubscriptionInfo.getSubscriptionId()
577 != mDefaults.getDefaultDataSubId()) {
578 mCurrentState.iconGroup = TelephonyIcons.NOT_DEFAULT_DATA;
579 } else {
580 mCurrentState.iconGroup = TelephonyIcons.DATA_DISABLED;
581 }
Jason Monkda68f592015-01-07 10:55:58 -0500582 }
583 if (isEmergencyOnly() != mCurrentState.isEmergency) {
584 mCurrentState.isEmergency = isEmergencyOnly();
585 mNetworkController.recalculateEmergency();
586 }
587 // Fill in the network name if we think we have it.
Fabian Kozynskia9091992019-03-25 11:08:32 -0400588 if (mCurrentState.networkName.equals(mNetworkNameDefault) && mServiceState != null
Jason Monk93fb68f2015-07-20 11:43:56 -0400589 && !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) {
Jason Monkda68f592015-01-07 10:55:58 -0500590 mCurrentState.networkName = mServiceState.getOperatorAlphaShort();
591 }
Fabian Kozynskia9091992019-03-25 11:08:32 -0400592 // If this is the data subscription, update the currentState data name
593 if (mCurrentState.networkNameData.equals(mNetworkNameDefault) && mServiceState != null
594 && mCurrentState.dataSim
SongFerngWang2b1ea8d2019-11-20 02:11:09 +0800595 && !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) {
596 mCurrentState.networkNameData = mServiceState.getOperatorAlphaShort();
Fabian Kozynskia9091992019-03-25 11:08:32 -0400597 }
Andrew Flynna478d702015-04-14 23:33:45 -0400598
Jason Monkda68f592015-01-07 10:55:58 -0500599 notifyListenersIfNecessary();
600 }
601
Evan Laird2ea99c12019-09-19 16:52:58 -0400602 /**
603 * If we are controlling the NOT_DEFAULT_DATA icon, check the status of the other one
604 */
605 private void checkDefaultData() {
606 if (mCurrentState.iconGroup != TelephonyIcons.NOT_DEFAULT_DATA) {
607 mCurrentState.defaultDataOff = false;
608 return;
609 }
610
611 mCurrentState.defaultDataOff = mNetworkController.isDataControllerDisabled();
612 }
613
614 void onMobileDataChanged() {
615 checkDefaultData();
616 notifyListenersIfNecessary();
617 }
618
Pengquan Menga62d32b2018-12-06 17:38:38 -0800619 private MobileIconGroup getNr5GIconGroup() {
620 if (mServiceState == null) return null;
621
Jack Yu20d71402019-03-16 23:00:35 -0700622 int nrState = mServiceState.getNrState();
623 if (nrState == NetworkRegistrationInfo.NR_STATE_CONNECTED) {
Pengquan Menga62d32b2018-12-06 17:38:38 -0800624 // Check if the NR 5G is using millimeter wave and the icon is config.
625 if (mServiceState.getNrFrequencyRange() == ServiceState.FREQUENCY_RANGE_MMWAVE) {
626 if (mConfig.nr5GIconMap.containsKey(Config.NR_CONNECTED_MMWAVE)) {
627 return mConfig.nr5GIconMap.get(Config.NR_CONNECTED_MMWAVE);
628 }
629 }
630
631 // If NR 5G is not using millimeter wave or there is no icon for millimeter wave, we
632 // check the normal 5G icon.
633 if (mConfig.nr5GIconMap.containsKey(Config.NR_CONNECTED)) {
634 return mConfig.nr5GIconMap.get(Config.NR_CONNECTED);
635 }
Jack Yu20d71402019-03-16 23:00:35 -0700636 } else if (nrState == NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED) {
SongFerngWang52dada72019-08-14 16:59:29 +0800637 if (mCurrentState.activityDormant) {
638 if (mConfig.nr5GIconMap.containsKey(Config.NR_NOT_RESTRICTED_RRC_IDLE)) {
639 return mConfig.nr5GIconMap.get(Config.NR_NOT_RESTRICTED_RRC_IDLE);
640 }
641 } else {
642 if (mConfig.nr5GIconMap.containsKey(Config.NR_NOT_RESTRICTED_RRC_CON)) {
643 return mConfig.nr5GIconMap.get(Config.NR_NOT_RESTRICTED_RRC_CON);
644 }
Pengquan Menga62d32b2018-12-06 17:38:38 -0800645 }
Jack Yu20d71402019-03-16 23:00:35 -0700646 } else if (nrState == NetworkRegistrationInfo.NR_STATE_RESTRICTED) {
Pengquan Menga62d32b2018-12-06 17:38:38 -0800647 if (mConfig.nr5GIconMap.containsKey(Config.NR_RESTRICTED)) {
648 return mConfig.nr5GIconMap.get(Config.NR_RESTRICTED);
649 }
650 }
651
652 return null;
653 }
654
Bill Lin767c0db2019-08-15 20:42:06 +0800655 /**
656 * The function to adjust MobileIconGroup depend on CarrierConfig's time
657 * nextIconGroup == null imply next state could be 2G/3G/4G/4G+
658 * nextIconGroup != null imply next state will be 5G/5G+
659 * Flag : mIsShowingIconGracefully
660 * ---------------------------------------------------------------------------------
661 * | Last state | Current state | Flag | Action |
662 * ---------------------------------------------------------------------------------
663 * | 5G/5G+ | 2G/3G/4G/4G+ | true | return previous IconGroup |
664 * | 5G/5G+ | 5G/5G+ | true | Bypass |
665 * | 2G/3G/4G/4G+ | 5G/5G+ | true | Bypass |
666 * | 2G/3G/4G/4G+ | 2G/3G/4G/4G+ | true | Bypass |
667 * | SS.connected | SS.disconnect | T|F | Reset timer |
668 * |NETWORK_TYPE_LTE|!NETWORK_TYPE_LTE| T|F | Reset timer |
669 * | 5G/5G+ | 2G/3G/4G/4G+ | false| Bypass |
670 * | 5G/5G+ | 5G/5G+ | false| Bypass |
671 * | 2G/3G/4G/4G+ | 5G/5G+ | false| SendMessageDelay(time), flag->true |
672 * | 2G/3G/4G/4G+ | 2G/3G/4G/4G+ | false| Bypass |
673 * ---------------------------------------------------------------------------------
674 */
675 private MobileIconGroup adjustNr5GIconGroupByDisplayGraceTime(
676 MobileIconGroup candidateIconGroup) {
677 if (mIsShowingIconGracefully && candidateIconGroup == null) {
678 candidateIconGroup = (MobileIconGroup) mCurrentState.iconGroup;
679 } else if (!mIsShowingIconGracefully && candidateIconGroup != null
680 && mLastState.iconGroup != candidateIconGroup) {
681 mDisplayGraceHandler.sendMessageDelayed(
682 mDisplayGraceHandler.obtainMessage(MSG_DISPLAY_GRACE),
683 mConfig.nrIconDisplayGracePeriodMs);
684 mIsShowingIconGracefully = true;
685 } else if (!mCurrentState.connected || mDataState == TelephonyManager.DATA_DISCONNECTED
686 || candidateIconGroup == null) {
687 mDisplayGraceHandler.removeMessages(MSG_DISPLAY_GRACE);
688 mIsShowingIconGracefully = false;
689 candidateIconGroup = null;
690 }
691
692 return candidateIconGroup;
693 }
694
Evan Laird2ea99c12019-09-19 16:52:58 -0400695 boolean isDataDisabled() {
Shuo Qian29141582020-01-02 15:18:01 -0800696 return !mPhone.isDataConnectionEnabled();
Jason Monk1a95c862016-01-27 15:18:41 -0500697 }
698
Jason Monkda68f592015-01-07 10:55:58 -0500699 @VisibleForTesting
700 void setActivity(int activity) {
701 mCurrentState.activityIn = activity == TelephonyManager.DATA_ACTIVITY_INOUT
702 || activity == TelephonyManager.DATA_ACTIVITY_IN;
703 mCurrentState.activityOut = activity == TelephonyManager.DATA_ACTIVITY_INOUT
704 || activity == TelephonyManager.DATA_ACTIVITY_OUT;
SongFerngWang52dada72019-08-14 16:59:29 +0800705 mCurrentState.activityDormant = activity == TelephonyManager.DATA_ACTIVITY_DORMANT;
706
Jason Monkda68f592015-01-07 10:55:58 -0500707 notifyListenersIfNecessary();
708 }
709
710 @Override
711 public void dump(PrintWriter pw) {
712 super.dump(pw);
713 pw.println(" mSubscription=" + mSubscriptionInfo + ",");
714 pw.println(" mServiceState=" + mServiceState + ",");
715 pw.println(" mSignalStrength=" + mSignalStrength + ",");
716 pw.println(" mDataState=" + mDataState + ",");
717 pw.println(" mDataNetType=" + mDataNetType + ",");
Daniel Brightaa819042020-01-10 18:05:01 -0800718 pw.println(" mCA=" + mCA + ",");
719 pw.println(" mCAPlus=" + mCAPlus + ",");
andychou9e396282019-04-10 20:49:06 +0800720 pw.println(" mInflateSignalStrengths=" + mInflateSignalStrengths + ",");
Malcolm Chen04be9d12019-06-11 19:48:38 -0700721 pw.println(" isDataDisabled=" + isDataDisabled() + ",");
Bill Lin767c0db2019-08-15 20:42:06 +0800722 pw.println(" mIsShowingIconGracefully=" + mIsShowingIconGracefully + ",");
Jason Monkda68f592015-01-07 10:55:58 -0500723 }
724
725 class MobilePhoneStateListener extends PhoneStateListener {
Jayachandran Cff50c8e2019-10-30 16:41:59 -0700726 public MobilePhoneStateListener(Executor executor) {
727 super(executor);
Jason Monkda68f592015-01-07 10:55:58 -0500728 }
729
730 @Override
731 public void onSignalStrengthsChanged(SignalStrength signalStrength) {
732 if (DEBUG) {
733 Log.d(mTag, "onSignalStrengthsChanged signalStrength=" + signalStrength +
734 ((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
735 }
736 mSignalStrength = signalStrength;
737 updateTelephony();
738 }
739
740 @Override
741 public void onServiceStateChanged(ServiceState state) {
742 if (DEBUG) {
SongFerngWang2670cba2019-12-23 19:21:14 +0800743 Log.d(mTag, "onServiceStateChanged voiceState=" + state.getState()
744 + " dataState=" + state.getDataRegistrationState());
Jason Monkda68f592015-01-07 10:55:58 -0500745 }
746 mServiceState = state;
SongFerngWang3cbcf752019-03-21 23:14:20 +0800747 if (mServiceState != null) {
Hall Liu5a95a702020-01-06 19:04:10 -0800748 NetworkRegistrationInfo regInfo = mServiceState.getNetworkRegistrationInfo(
749 DOMAIN_PS, TRANSPORT_TYPE_WWAN);
750 if (regInfo != null) {
751 updateDataNetType(regInfo.getAccessNetworkTechnology());
752 }
Robert Greenwaltea0d71392016-07-28 18:50:10 -0700753 }
Jason Monkda68f592015-01-07 10:55:58 -0500754 updateTelephony();
755 }
756
757 @Override
758 public void onDataConnectionStateChanged(int state, int networkType) {
759 if (DEBUG) {
760 Log.d(mTag, "onDataConnectionStateChanged: state=" + state
761 + " type=" + networkType);
762 }
763 mDataState = state;
SongFerngWang3cbcf752019-03-21 23:14:20 +0800764 updateDataNetType(networkType);
Jason Monkda68f592015-01-07 10:55:58 -0500765 updateTelephony();
766 }
767
SongFerngWang3cbcf752019-03-21 23:14:20 +0800768 private void updateDataNetType(int networkType) {
769 mDataNetType = networkType;
Daniel Brightaa819042020-01-10 18:05:01 -0800770 mCA = false;
771 mCAPlus = false;
SongFerngWang3cbcf752019-03-21 23:14:20 +0800772 if (mDataNetType == TelephonyManager.NETWORK_TYPE_LTE) {
773 if (isCarrierSpecificDataIcon()) {
Daniel Brightaa819042020-01-10 18:05:01 -0800774 mCAPlus = true;
SongFerngWang3cbcf752019-03-21 23:14:20 +0800775 } else if (mServiceState != null && mServiceState.isUsingCarrierAggregation()) {
Daniel Brightaa819042020-01-10 18:05:01 -0800776 mCA = true;
SongFerngWang3cbcf752019-03-21 23:14:20 +0800777 }
778 }
779 }
780
Jason Monkda68f592015-01-07 10:55:58 -0500781 @Override
782 public void onDataActivity(int direction) {
783 if (DEBUG) {
784 Log.d(mTag, "onDataActivity: direction=" + direction);
785 }
786 setActivity(direction);
787 }
Andrew Flynna478d702015-04-14 23:33:45 -0400788
789 @Override
790 public void onCarrierNetworkChange(boolean active) {
791 if (DEBUG) {
792 Log.d(mTag, "onCarrierNetworkChange: active=" + active);
793 }
794 mCurrentState.carrierNetworkChangeMode = active;
795
796 updateTelephony();
797 }
Fabian Kozynskiaaf78972019-07-08 10:02:08 -0400798
799 @Override
800 public void onActiveDataSubscriptionIdChanged(int subId) {
801 if (DEBUG) Log.d(mTag, "onActiveDataSubscriptionIdChanged: subId=" + subId);
802 updateDataSim();
803 updateTelephony();
804 }
Jason Monkda68f592015-01-07 10:55:58 -0500805 };
806
807 static class MobileIconGroup extends SignalController.IconGroup {
808 final int mDataContentDescription; // mContentDescriptionDataType
809 final int mDataType;
810 final boolean mIsWide;
Jason Monk33f8ae72015-05-08 10:45:15 -0400811 final int mQsDataType;
Jason Monkda68f592015-01-07 10:55:58 -0500812
813 public MobileIconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc,
814 int sbNullState, int qsNullState, int sbDiscState, int qsDiscState,
Amin Shaikhd64e6262018-03-08 10:08:13 -0500815 int discContentDesc, int dataContentDesc, int dataType, boolean isWide) {
Andrew Flynn2fdbe122015-06-01 16:34:21 -0400816 super(name, sbIcons, qsIcons, contentDesc, sbNullState, qsNullState, sbDiscState,
817 qsDiscState, discContentDesc);
Jason Monkda68f592015-01-07 10:55:58 -0500818 mDataContentDescription = dataContentDesc;
819 mDataType = dataType;
820 mIsWide = isWide;
Amin Shaikhd64e6262018-03-08 10:08:13 -0500821 mQsDataType = dataType; // TODO: remove this field
Jason Monkda68f592015-01-07 10:55:58 -0500822 }
823 }
824
825 static class MobileState extends SignalController.State {
826 String networkName;
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700827 String networkNameData;
Jason Monkda68f592015-01-07 10:55:58 -0500828 boolean dataSim;
829 boolean dataConnected;
830 boolean isEmergency;
831 boolean airplaneMode;
Andrew Flynna478d702015-04-14 23:33:45 -0400832 boolean carrierNetworkChangeMode;
Jason Monk33f8ae72015-05-08 10:45:15 -0400833 boolean isDefault;
Jason Monkfd57ea72016-04-29 13:37:58 -0400834 boolean userSetup;
Jason Monk0f0de132016-12-19 15:36:13 -0500835 boolean roaming;
Evan Laird2ea99c12019-09-19 16:52:58 -0400836 boolean defaultDataOff; // Tracks the on/off state of the defaultDataSubscription
Jason Monkda68f592015-01-07 10:55:58 -0500837
838 @Override
839 public void copyFrom(State s) {
840 super.copyFrom(s);
841 MobileState state = (MobileState) s;
842 dataSim = state.dataSim;
843 networkName = state.networkName;
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700844 networkNameData = state.networkNameData;
Jason Monkda68f592015-01-07 10:55:58 -0500845 dataConnected = state.dataConnected;
Jason Monk33f8ae72015-05-08 10:45:15 -0400846 isDefault = state.isDefault;
Jason Monkda68f592015-01-07 10:55:58 -0500847 isEmergency = state.isEmergency;
848 airplaneMode = state.airplaneMode;
Andrew Flynna478d702015-04-14 23:33:45 -0400849 carrierNetworkChangeMode = state.carrierNetworkChangeMode;
Jason Monkfd57ea72016-04-29 13:37:58 -0400850 userSetup = state.userSetup;
Jason Monk0f0de132016-12-19 15:36:13 -0500851 roaming = state.roaming;
Evan Laird2ea99c12019-09-19 16:52:58 -0400852 defaultDataOff = state.defaultDataOff;
Jason Monkda68f592015-01-07 10:55:58 -0500853 }
854
855 @Override
856 protected void toString(StringBuilder builder) {
857 super.toString(builder);
858 builder.append(',');
859 builder.append("dataSim=").append(dataSim).append(',');
860 builder.append("networkName=").append(networkName).append(',');
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700861 builder.append("networkNameData=").append(networkNameData).append(',');
Jason Monkda68f592015-01-07 10:55:58 -0500862 builder.append("dataConnected=").append(dataConnected).append(',');
Jason Monk0f0de132016-12-19 15:36:13 -0500863 builder.append("roaming=").append(roaming).append(',');
Jason Monk33f8ae72015-05-08 10:45:15 -0400864 builder.append("isDefault=").append(isDefault).append(',');
Jason Monkda68f592015-01-07 10:55:58 -0500865 builder.append("isEmergency=").append(isEmergency).append(',');
Andrew Flynna478d702015-04-14 23:33:45 -0400866 builder.append("airplaneMode=").append(airplaneMode).append(',');
Jason Monkfd57ea72016-04-29 13:37:58 -0400867 builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode)
868 .append(',');
Evan Laird2ea99c12019-09-19 16:52:58 -0400869 builder.append("userSetup=").append(userSetup).append(',');
870 builder.append("defaultDataOff=").append(defaultDataOff);
Jason Monkda68f592015-01-07 10:55:58 -0500871 }
872
873 @Override
874 public boolean equals(Object o) {
875 return super.equals(o)
876 && Objects.equals(((MobileState) o).networkName, networkName)
Pavel Zhamaitsiak5504d392015-03-27 09:24:47 -0700877 && Objects.equals(((MobileState) o).networkNameData, networkNameData)
Jason Monkda68f592015-01-07 10:55:58 -0500878 && ((MobileState) o).dataSim == dataSim
879 && ((MobileState) o).dataConnected == dataConnected
880 && ((MobileState) o).isEmergency == isEmergency
881 && ((MobileState) o).airplaneMode == airplaneMode
Andrew Flynna478d702015-04-14 23:33:45 -0400882 && ((MobileState) o).carrierNetworkChangeMode == carrierNetworkChangeMode
Jason Monkfd57ea72016-04-29 13:37:58 -0400883 && ((MobileState) o).userSetup == userSetup
Jason Monk0f0de132016-12-19 15:36:13 -0500884 && ((MobileState) o).isDefault == isDefault
Evan Laird2ea99c12019-09-19 16:52:58 -0400885 && ((MobileState) o).roaming == roaming
886 && ((MobileState) o).defaultDataOff == defaultDataOff;
Jason Monkda68f592015-01-07 10:55:58 -0500887 }
888 }
889}