1 /*
2  * Copyright (C) 2021 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  */
16 
17 package com.android.telephony.qns;
18 
19 import static android.telephony.BarringInfo.BARRING_SERVICE_TYPE_EMERGENCY;
20 import static android.telephony.BarringInfo.BARRING_SERVICE_TYPE_MMTEL_VOICE;
21 
22 import android.annotation.NonNull;
23 import android.content.Context;
24 import android.net.NetworkCapabilities;
25 import android.os.Binder;
26 import android.os.Handler;
27 import android.os.HandlerThread;
28 import android.telephony.AccessNetworkConstants;
29 import android.telephony.Annotation;
30 import android.telephony.BarringInfo;
31 import android.telephony.CallState;
32 import android.telephony.NetworkRegistrationInfo;
33 import android.telephony.NrVopsSupportInfo;
34 import android.telephony.PreciseDataConnectionState;
35 import android.telephony.ServiceState;
36 import android.telephony.SubscriptionManager;
37 import android.telephony.TelephonyCallback;
38 import android.telephony.TelephonyManager;
39 import android.telephony.VopsSupportInfo;
40 import android.telephony.ims.ImsReasonInfo;
41 import android.telephony.ims.MediaQualityStatus;
42 import android.util.Log;
43 
44 import com.android.internal.annotations.VisibleForTesting;
45 
46 import java.io.PrintWriter;
47 import java.util.ArrayList;
48 import java.util.HashMap;
49 import java.util.List;
50 import java.util.Objects;
51 import java.util.concurrent.ConcurrentHashMap;
52 import java.util.concurrent.Executor;
53 import java.util.function.Consumer;
54 
55 /*
56  * QnsTelephonyListener
57  * Tracks Cellular ServiceState per each slot.
58  */
59 class QnsTelephonyListener {
60 
61     private static final Archiving<PreciseDataConnectionState>
62             sArchivingPreciseDataConnectionState = new Archiving<>();
63     private final String mLogTag;
64     private final int mSlotIndex;
65     private final Context mContext;
66     private final SubscriptionManager mSubscriptionManager;
67     private final Handler mHandler;
68     private final HandlerThread mHandlerThread;
69     QnsRegistrantList mCallStateListener = new QnsRegistrantList();
70     QnsRegistrantList mSrvccStateListener = new QnsRegistrantList();
71     QnsRegistrantList mSubscriptionIdListener = new QnsRegistrantList();
72     QnsRegistrantList mIwlanServiceStateListener = new QnsRegistrantList();
73     QnsRegistrantList mImsCallDropDisconnectCauseListener = new QnsRegistrantList();
74     List<Consumer<List<CallState>>> mCallStatesConsumerList = new ArrayList<>();
75     List<Consumer<Integer>> mSrvccStateConsumerList = new ArrayList<>();
76     List<Consumer<MediaQualityStatus>> mMediaQualityConsumerList = new ArrayList<>();
77     protected ConcurrentHashMap<Integer, QnsRegistrantList> mQnsTelephonyInfoRegistrantMap =
78             new ConcurrentHashMap<>();
79     protected ConcurrentHashMap<Integer, QnsRegistrantList> mNetCapabilityRegistrantMap =
80             new ConcurrentHashMap<>();
81     protected QnsTelephonyInfo mLastQnsTelephonyInfo = new QnsTelephonyInfo();
82     protected QnsTelephonyInfoIms mLastQnsTelephonyInfoIms = new QnsTelephonyInfoIms();
83     protected ServiceState mLastServiceState = new ServiceState();
84     protected HashMap<Integer, PreciseDataConnectionState> mLastPreciseDataConnectionState =
85             new HashMap<>();
86     private int mSubId;
87     @VisibleForTesting TelephonyListener mTelephonyListener;
88     private int mCoverage;
89     @Annotation.CallState private int mCallState;
90 
91     @VisibleForTesting
92     final SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionsChangeListener =
93             new SubscriptionManager.OnSubscriptionsChangedListener() {
94                 @Override
95                 public void onSubscriptionsChanged() {
96                     int newSubId = QnsUtils.getSubId(mContext, mSlotIndex);
97                     if ((mSubId != newSubId)
98                             && (newSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID)) {
99                         stopTelephonyListener(mSubId); // old
100                         mSubId = newSubId;
101                         onSubscriptionIdChanged(newSubId);
102                         startTelephonyListener(newSubId); // new
103                     }
104                 }
105             };
106 
107     /** Default constructor. */
QnsTelephonyListener(@onNull Context context, int slotIndex)108     QnsTelephonyListener(@NonNull Context context, int slotIndex) {
109         mLogTag = QnsTelephonyListener.class.getSimpleName() + "_" + slotIndex;
110         mSlotIndex = slotIndex;
111         mContext = context;
112 
113         mSubscriptionManager = mContext.getSystemService(SubscriptionManager.class);
114         mHandlerThread = new HandlerThread(QnsTelephonyListener.class.getSimpleName());
115         mHandlerThread.start();
116         mHandler = new Handler(mHandlerThread.getLooper());
117 
118         mSubId = QnsUtils.getSubId(mContext, mSlotIndex);
119         startTelephonyListener(mSubId);
120 
121         if (mSubscriptionManager != null) {
122             mSubscriptionManager.addOnSubscriptionsChangedListener(
123                     new QnsUtils.QnsExecutor(mHandler), mSubscriptionsChangeListener);
124         }
125     }
126 
registrationStateToServiceState(int registrationState)127     private static int registrationStateToServiceState(int registrationState) {
128         switch (registrationState) {
129             case NetworkRegistrationInfo.REGISTRATION_STATE_HOME:
130             case NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING:
131                 return ServiceState.STATE_IN_SERVICE;
132             default:
133                 return ServiceState.STATE_OUT_OF_SERVICE;
134         }
135     }
136 
notifyQnsTelephonyInfo(QnsTelephonyInfo info)137     protected void notifyQnsTelephonyInfo(QnsTelephonyInfo info) {
138         QnsAsyncResult ar;
139         for (Integer netCapability : mQnsTelephonyInfoRegistrantMap.keySet()) {
140             if (netCapability == NetworkCapabilities.NET_CAPABILITY_IMS
141                     || netCapability == NetworkCapabilities.NET_CAPABILITY_EIMS) {
142                 ar = new QnsAsyncResult(null, mLastQnsTelephonyInfoIms, null);
143             } else {
144                 ar = new QnsAsyncResult(null, info, null);
145             }
146             mQnsTelephonyInfoRegistrantMap.get(netCapability).notifyRegistrants(ar);
147         }
148     }
149 
notifyQnsTelephonyInfoIms(QnsTelephonyInfoIms info)150     protected void notifyQnsTelephonyInfoIms(QnsTelephonyInfoIms info) {
151         QnsAsyncResult ar = new QnsAsyncResult(null, info, null);
152         QnsRegistrantList imsRegList =
153                 mQnsTelephonyInfoRegistrantMap.get(NetworkCapabilities.NET_CAPABILITY_IMS);
154         QnsRegistrantList sosRegList =
155                 mQnsTelephonyInfoRegistrantMap.get(NetworkCapabilities.NET_CAPABILITY_EIMS);
156         if (imsRegList != null) {
157             imsRegList.notifyRegistrants(ar);
158         }
159         if (sosRegList != null) {
160             sosRegList.notifyRegistrants(ar);
161         }
162     }
163 
notifyIwlanServiceStateInfo(boolean isInService)164     protected void notifyIwlanServiceStateInfo(boolean isInService) {
165         mIwlanServiceStateListener.notifyResult(isInService);
166     }
167 
notifyPreciseDataConnectionStateChanged( PreciseDataConnectionState connectionState)168     protected void notifyPreciseDataConnectionStateChanged(
169             PreciseDataConnectionState connectionState) {
170         List<Integer> netCapabilities =
171                 QnsUtils.getNetCapabilitiesFromApnTypeBitmask(
172                         connectionState.getApnSetting().getApnTypeBitmask());
173         QnsAsyncResult ar = new QnsAsyncResult(null, connectionState, null);
174         for (int netCapability : netCapabilities) {
175             PreciseDataConnectionState lastState = getLastPreciseDataConnectionState(netCapability);
176             if (lastState == null || !lastState.equals(connectionState)) {
177                 mLastPreciseDataConnectionState.put(netCapability, connectionState);
178                 sArchivingPreciseDataConnectionState.put(
179                         mSubId, connectionState.getTransportType(), netCapability, connectionState);
180                 QnsRegistrantList netCapabilityRegistrantList =
181                         mNetCapabilityRegistrantMap.get(netCapability);
182                 if (netCapabilityRegistrantList != null) {
183                     netCapabilityRegistrantList.notifyRegistrants(ar);
184                 }
185             } else {
186                 log(
187                         "onPreciseDataConnectionStateChanged state received for netCapability is"
188                                 + " same:"
189                                 + netCapability);
190             }
191         }
192     }
193 
194     /** Get a last QnsTelephonyInfo notified previously. */
getLastQnsTelephonyInfo()195     QnsTelephonyInfo getLastQnsTelephonyInfo() {
196         return mLastQnsTelephonyInfo;
197     }
198 
199     /** Get a last of the precise data connection state per netCapability. */
getLastPreciseDataConnectionState(int netCapability)200     PreciseDataConnectionState getLastPreciseDataConnectionState(int netCapability) {
201         return mLastPreciseDataConnectionState.get(netCapability);
202     }
203 
204     /**
205      * Register an event for QnsTelephonyInfo changed.
206      *
207      * @param netCapability Network Capability to be notified.
208      * @param h the Handler to get event.
209      * @param what the event.
210      * @param userObj user object.
211      * @param notifyImmediately set true if want to notify immediately.
212      */
registerQnsTelephonyInfoChanged( int netCapability, Handler h, int what, Object userObj, boolean notifyImmediately)213     void registerQnsTelephonyInfoChanged(
214             int netCapability, Handler h, int what, Object userObj, boolean notifyImmediately) {
215         if (h != null) {
216             QnsRegistrant r = new QnsRegistrant(h, what, userObj);
217             QnsRegistrantList netCapabilityRegistrantList =
218                     mQnsTelephonyInfoRegistrantMap.get(netCapability);
219             if (netCapabilityRegistrantList == null) {
220                 netCapabilityRegistrantList = new QnsRegistrantList();
221                 mQnsTelephonyInfoRegistrantMap.put(netCapability, netCapabilityRegistrantList);
222             }
223             netCapabilityRegistrantList.add(r);
224 
225             if (notifyImmediately) {
226                 r.notifyRegistrant(new QnsAsyncResult(null, getLastQnsTelephonyInfo(), null));
227             }
228         }
229     }
230 
231     /**
232      * Register an event for Precise Data Connection State Changed.
233      *
234      * @param netCapability Network Capability to be notified.
235      * @param h the handler to get event.
236      * @param what the event.
237      */
registerPreciseDataConnectionStateChanged( int netCapability, Handler h, int what, Object userObj, boolean notifyImmediately)238     void registerPreciseDataConnectionStateChanged(
239             int netCapability, Handler h, int what, Object userObj, boolean notifyImmediately) {
240         if (h != null) {
241             QnsRegistrant r = new QnsRegistrant(h, what, userObj);
242             QnsRegistrantList netCapabilityRegistrantList =
243                     mNetCapabilityRegistrantMap.get(netCapability);
244             if (netCapabilityRegistrantList == null) {
245                 netCapabilityRegistrantList = new QnsRegistrantList();
246                 mNetCapabilityRegistrantMap.put(netCapability, netCapabilityRegistrantList);
247             }
248             netCapabilityRegistrantList.add(r);
249 
250             PreciseDataConnectionState pdcs = getLastPreciseDataConnectionState(netCapability);
251             if (notifyImmediately && pdcs != null) {
252                 r.notifyRegistrant(new QnsAsyncResult(null, pdcs, null));
253             }
254         }
255     }
256 
257     /**
258      * Register an event for CallState changed.
259      *
260      * @param h the Handler to get event.
261      * @param what the event.
262      * @param userObj user object.
263      * @param notifyImmediately set true if want to notify immediately.
264      */
registerCallStateListener(Handler h, int what, Object userObj, boolean notifyImmediately)265     void registerCallStateListener(Handler h, int what, Object userObj, boolean notifyImmediately) {
266         log("registerCallStateListener");
267         if (h != null) {
268             QnsRegistrant r = new QnsRegistrant(h, what, userObj);
269             mCallStateListener.add(r);
270 
271             if (notifyImmediately) {
272                 r.notifyRegistrant(new QnsAsyncResult(null, mCallState, null));
273             }
274         }
275     }
276 
277     /**
278      * Register an event for SRVCC state changed.
279      *
280      * @param h the Handler to get event.
281      * @param what the event.
282      * @param userObj user object.
283      */
registerSrvccStateListener(Handler h, int what, Object userObj)284     void registerSrvccStateListener(Handler h, int what, Object userObj) {
285         log("registerSrvccStateListener");
286         if (h != null) {
287             QnsRegistrant r = new QnsRegistrant(h, what, userObj);
288             mSrvccStateListener.add(r);
289         }
290     }
291 
292     /**
293      * Register an event for subscription Id changed.
294      *
295      * @param h the Handler to get event.
296      * @param what the event.
297      * @param userObj user object.
298      */
registerSubscriptionIdListener(Handler h, int what, Object userObj)299     void registerSubscriptionIdListener(Handler h, int what, Object userObj) {
300         log("registerSubscriptionIdListener");
301         if (h != null) {
302             QnsRegistrant r = new QnsRegistrant(h, what, userObj);
303             mSubscriptionIdListener.add(r);
304         }
305     }
306 
307     /**
308      * Register an event for iwlan service state changed.
309      *
310      * @param h the Handler to get event.
311      * @param what the event.
312      * @param userObj user object.
313      */
registerIwlanServiceStateListener(Handler h, int what, Object userObj)314     void registerIwlanServiceStateListener(Handler h, int what, Object userObj) {
315         log("registerIwlanServiceStateListener");
316         if (h != null) {
317             QnsRegistrant r = new QnsRegistrant(h, what, userObj);
318             mIwlanServiceStateListener.add(r);
319 
320             NetworkRegistrationInfo lastIwlanNrs =
321                     mLastServiceState.getNetworkRegistrationInfo(
322                             NetworkRegistrationInfo.DOMAIN_PS,
323                             AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
324             if (lastIwlanNrs != null) {
325                 r.notifyRegistrant(
326                         new QnsAsyncResult(null, lastIwlanNrs.isNetworkRegistered(), null));
327             }
328         }
329     }
330 
331     /**
332      * Register an event for ImsCallDropDisconnectCause changed.
333      *
334      * @param h the Handler to get event.
335      * @param what the event.
336      * @param userObj user object.
337      */
registerImsCallDropDisconnectCauseListener(Handler h, int what, Object userObj)338     void registerImsCallDropDisconnectCauseListener(Handler h, int what, Object userObj) {
339         log("registerImsCallDropDisconnectCauseListener");
340         if (h != null) {
341             QnsRegistrant r = new QnsRegistrant(h, what, userObj);
342             mImsCallDropDisconnectCauseListener.add(r);
343         }
344     }
345 
346     /**
347      * Unregister an event for QnsTelephonyInfo changed.
348      *
349      * @param netCapability Network Capability to be notified.
350      * @param h the handler to get event.
351      */
unregisterQnsTelephonyInfoChanged(int netCapability, Handler h)352     void unregisterQnsTelephonyInfoChanged(int netCapability, Handler h) {
353         if (h != null) {
354             QnsRegistrantList netCapabilityRegistrantList =
355                     mQnsTelephonyInfoRegistrantMap.get(netCapability);
356             if (netCapabilityRegistrantList != null) {
357                 netCapabilityRegistrantList.remove(h);
358             }
359         }
360     }
361 
362     /**
363      * Unregister an event for Precise Data Connectio State Changed.
364      *
365      * @param netCapability Network Capability to be notified.
366      * @param h the handler to get event.
367      */
unregisterPreciseDataConnectionStateChanged(int netCapability, Handler h)368     void unregisterPreciseDataConnectionStateChanged(int netCapability, Handler h) {
369         if (h != null) {
370             QnsRegistrantList netCapabilityRegistrantList =
371                     mNetCapabilityRegistrantMap.get(netCapability);
372             if (netCapabilityRegistrantList != null) {
373                 netCapabilityRegistrantList.remove(h);
374             }
375         }
376     }
377 
378     /**
379      * Unregister an event for CallState changed.
380      *
381      * @param h the handler to get event.
382      */
unregisterCallStateChanged(Handler h)383     void unregisterCallStateChanged(Handler h) {
384         log("unregisterCallStateChanged");
385         if (h != null) {
386             mCallStateListener.remove(h);
387         }
388     }
389 
390     /**
391      * Unregister an event for SRVCC state changed.
392      *
393      * @param h the handler to get event.
394      */
unregisterSrvccStateChanged(Handler h)395     void unregisterSrvccStateChanged(Handler h) {
396         log("unregisterSrvccStateChanged");
397         if (h != null) {
398             mSrvccStateListener.remove(h);
399         }
400     }
401 
402     /**
403      * Unregister an event for subscription Id changed.
404      *
405      * @param h the handler to get event.
406      */
unregisterSubscriptionIdChanged(Handler h)407     void unregisterSubscriptionIdChanged(Handler h) {
408         log("unregisterSubscriptionIdChanged");
409         if (h != null) {
410             mSubscriptionIdListener.remove(h);
411         }
412     }
413 
414     /**
415      * Unregister an event for iwlan service state changed.
416      *
417      * @param h the handler to get event.
418      */
unregisterIwlanServiceStateChanged(Handler h)419     void unregisterIwlanServiceStateChanged(Handler h) {
420         log("unregisterIwlanServiceStateChanged");
421         if (h != null) {
422             mIwlanServiceStateListener.remove(h);
423         }
424     }
425 
426     /**
427      * Unregister an event for ImsCallDropDisconnectCause state changed.
428      *
429      * @param h the handler to get event.
430      */
unregisterImsCallDropDisconnectCauseListener(Handler h)431     void unregisterImsCallDropDisconnectCauseListener(Handler h) {
432         log("unregisterImsCallDropDisconnectCauseListener");
433         if (h != null) {
434             mImsCallDropDisconnectCauseListener.remove(h);
435         }
436     }
437 
createTelephonyListener()438     private void createTelephonyListener() {
439         if (mTelephonyListener == null) {
440             mTelephonyListener = new TelephonyListener(mContext.getMainExecutor());
441             mTelephonyListener.setServiceStateListener(
442                     (ServiceState serviceState) -> {
443                         onServiceStateChanged(serviceState);
444                     });
445             mTelephonyListener.setPreciseDataConnectionStateListener(
446                     (PreciseDataConnectionState connectionState) -> {
447                         onPreciseDataConnectionStateChanged(connectionState);
448                     });
449             mTelephonyListener.setBarringInfoListener(
450                     (BarringInfo barringInfo) -> {
451                         onBarringInfoChanged(barringInfo);
452                     });
453             mTelephonyListener.setCallStateListener(
454                     (int callState) -> {
455                         onCallStateChanged(callState);
456                     });
457             mTelephonyListener.setSrvccStateListener(
458                     (int srvccState) -> {
459                         onSrvccStateChanged(srvccState);
460                     });
461             mTelephonyListener.setImsCallDisconnectCauseListener(
462                     (ImsReasonInfo imsReasonInfo) -> {
463                         onImsCallDisconnectCauseChanged(imsReasonInfo);
464                     });
465         }
466     }
467 
stopTelephonyListener(int subId)468     protected void stopTelephonyListener(int subId) {
469         if (mTelephonyListener == null) {
470             return;
471         }
472         mTelephonyListener.unregister(subId);
473         cleanupQnsTelephonyListenerSettings();
474     }
475 
startTelephonyListener(int subId)476     protected void startTelephonyListener(int subId) {
477         if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
478             return;
479         }
480         if (mTelephonyListener == null) {
481             createTelephonyListener();
482         }
483         mTelephonyListener.register(mContext, subId);
484     }
485 
cleanupQnsTelephonyListenerSettings()486     private void cleanupQnsTelephonyListenerSettings() {
487         log("cleanupQnsTelephonyListenerSettings");
488         mLastQnsTelephonyInfo = new QnsTelephonyInfo();
489         mLastQnsTelephonyInfoIms = new QnsTelephonyInfoIms();
490         mLastServiceState = new ServiceState();
491         mLastPreciseDataConnectionState = new HashMap<>();
492         // mCoverage, keep previous state.
493         mCallState = QnsConstants.CALL_TYPE_IDLE;
494     }
495 
onServiceStateChanged(ServiceState serviceState)496     protected void onServiceStateChanged(ServiceState serviceState) {
497         QnsTelephonyInfo newInfo = new QnsTelephonyInfo(mLastQnsTelephonyInfo);
498 
499         NetworkRegistrationInfo newIwlanNrs =
500                 serviceState.getNetworkRegistrationInfo(
501                         NetworkRegistrationInfo.DOMAIN_PS,
502                         AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
503         NetworkRegistrationInfo oldIwlanNrs =
504                 mLastServiceState.getNetworkRegistrationInfo(
505                         NetworkRegistrationInfo.DOMAIN_PS,
506                         AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
507 
508         if (newIwlanNrs != null
509                 && (oldIwlanNrs == null
510                         || newIwlanNrs.isNetworkRegistered()
511                                 != oldIwlanNrs.isNetworkRegistered())) {
512             log("Iwlan is in service: " + newIwlanNrs.isNetworkRegistered());
513             notifyIwlanServiceStateInfo(newIwlanNrs.isNetworkRegistered());
514         }
515 
516         NetworkRegistrationInfo newWwanNrs =
517                 serviceState.getNetworkRegistrationInfo(
518                         NetworkRegistrationInfo.DOMAIN_PS,
519                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
520         NetworkRegistrationInfo oldWwanNrs =
521                 mLastServiceState.getNetworkRegistrationInfo(
522                         NetworkRegistrationInfo.DOMAIN_PS,
523                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
524 
525         NetworkRegistrationInfo newWwanCsNrs =
526                 serviceState.getNetworkRegistrationInfo(
527                         NetworkRegistrationInfo.DOMAIN_CS,
528                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
529 
530         // Event for voice registration state changed
531         if (newWwanCsNrs != null) {
532             newInfo.setVoiceNetworkType(newWwanCsNrs.getAccessNetworkTechnology());
533         }
534 
535         // Event for cellular data tech changed
536         if (newWwanNrs != null) {
537             newInfo.setDataNetworkType(newWwanNrs.getAccessNetworkTechnology());
538             newInfo.setDataRegState(
539                     registrationStateToServiceState(newWwanNrs.getNetworkRegistrationState()));
540 
541             // Event for cellular data roaming registration state changed.
542             // Refer roaming state which is not overridden by configs.
543             if (!newWwanNrs.isNetworkRoaming()) {
544                 mCoverage = QnsConstants.COVERAGE_HOME;
545             } else {
546                 mCoverage = QnsConstants.COVERAGE_ROAM;
547             }
548             newInfo.setRegisteredPlmn(newWwanNrs.getRegisteredPlmn());
549             newInfo.setCoverage(mCoverage == QnsConstants.COVERAGE_ROAM);
550         } else {
551             newInfo.setRegisteredPlmn(null);
552         }
553 
554         // Event for cellular ps attach state changed.
555         boolean hasAirplaneModeOnChanged =
556                 mLastServiceState.getState() != ServiceState.STATE_POWER_OFF
557                         && serviceState.getState() == ServiceState.STATE_POWER_OFF;
558         if ((oldWwanNrs == null || !oldWwanNrs.isNetworkRegistered() || hasAirplaneModeOnChanged)
559                 && (newWwanNrs != null && newWwanNrs.isNetworkRegistered())) {
560             newInfo.setCellularAvailable(true);
561         }
562         if ((oldWwanNrs != null && oldWwanNrs.isNetworkRegistered())
563                 && (newWwanNrs == null || !newWwanNrs.isNetworkRegistered())) {
564             newInfo.setCellularAvailable(false);
565         }
566 
567         // Event for VOPS changed
568         boolean vopsSupport = isSupportVoPS(newWwanNrs);
569         boolean vopsEmergencySupport = isSupportEmergencyService(newWwanNrs);
570         boolean vopsSupportChanged = vopsSupport != mLastQnsTelephonyInfoIms.getVopsSupport();
571         boolean vopsEmergencySupportChanged =
572                 vopsEmergencySupport != mLastQnsTelephonyInfoIms.getVopsEmergencySupport();
573 
574         if (!newInfo.equals(mLastQnsTelephonyInfo)) {
575             StringBuilder sb = new StringBuilder();
576             if (newInfo.getVoiceNetworkType() != mLastQnsTelephonyInfo.getVoiceNetworkType()) {
577                 sb.append(" voiceTech:").append(newInfo.getVoiceNetworkType());
578             }
579             if (newInfo.getDataNetworkType() != mLastQnsTelephonyInfo.getDataNetworkType()) {
580                 sb.append(" dataTech:").append(newInfo.getDataNetworkType());
581             }
582             if (newInfo.getDataRegState() != mLastQnsTelephonyInfo.getDataRegState()) {
583                 sb.append(" dataRegState:").append(newInfo.getDataRegState());
584             }
585             if (newInfo.isCoverage() != mLastQnsTelephonyInfo.isCoverage()) {
586                 sb.append(" coverage:").append(newInfo.isCoverage() ? "ROAM" : "HOME");
587             }
588             if (newInfo.isCellularAvailable() != mLastQnsTelephonyInfo.isCellularAvailable()) {
589                 sb.append(" cellAvailable:").append(newInfo.isCellularAvailable());
590             }
591             if (vopsSupportChanged) {
592                 sb.append(" VOPS support:").append(vopsSupport);
593             }
594             if (vopsSupportChanged) {
595                 sb.append(" VOPS emergency support:").append(vopsEmergencySupport);
596             }
597 
598             log("onCellularServiceStateChanged QnsTelephonyInfo:" + sb);
599 
600             mLastQnsTelephonyInfo = newInfo;
601             mLastQnsTelephonyInfoIms =
602                     new QnsTelephonyInfoIms(
603                             newInfo,
604                             vopsSupport,
605                             vopsEmergencySupport,
606                             mLastQnsTelephonyInfoIms.getVoiceBarring(),
607                             mLastQnsTelephonyInfoIms.getEmergencyBarring());
608             mLastServiceState = serviceState;
609             notifyQnsTelephonyInfo(newInfo);
610         } else {
611             if (vopsSupportChanged || vopsEmergencySupportChanged) {
612                 log("onCellularServiceStateChanged VoPS enabled" + vopsSupport);
613                 log("onCellularServiceStateChanged VoPS EMC support" + vopsEmergencySupport);
614                 mLastQnsTelephonyInfoIms.setVopsSupport(vopsSupport);
615                 mLastQnsTelephonyInfoIms.setVopsEmergencySupport(vopsEmergencySupport);
616                 notifyQnsTelephonyInfoIms(mLastQnsTelephonyInfoIms);
617             }
618         }
619         mLastServiceState = serviceState;
620     }
621 
isAirplaneModeEnabled()622     boolean isAirplaneModeEnabled() {
623         return mLastServiceState.getState() == ServiceState.STATE_POWER_OFF;
624     }
625 
isSupportVoPS()626     boolean isSupportVoPS() {
627         try {
628             NetworkRegistrationInfo networkRegInfo =
629                     mLastServiceState.getNetworkRegistrationInfo(
630                             NetworkRegistrationInfo.DOMAIN_PS,
631                             AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
632             return isSupportVoPS(networkRegInfo);
633         } catch (NullPointerException e) {
634             return false;
635         }
636     }
637 
isSupportVoPS(NetworkRegistrationInfo nri)638     private boolean isSupportVoPS(NetworkRegistrationInfo nri) {
639         try {
640             VopsSupportInfo vopsInfo = nri.getDataSpecificInfo().getVopsSupportInfo();
641             if (vopsInfo instanceof NrVopsSupportInfo) {
642                 NrVopsSupportInfo nrVopsInfo = (NrVopsSupportInfo) vopsInfo;
643                 return nrVopsInfo.getVopsSupport()
644                         == NrVopsSupportInfo.NR_STATUS_VOPS_3GPP_SUPPORTED;
645             } else {
646                 return vopsInfo.isVopsSupported();
647             }
648         } catch (NullPointerException e) {
649             return false;
650         }
651     }
652 
isSupportEmergencyService()653     boolean isSupportEmergencyService() {
654         return mLastQnsTelephonyInfoIms.getVopsEmergencySupport();
655     }
656 
isSupportEmergencyService(NetworkRegistrationInfo networkRegInfo)657     private boolean isSupportEmergencyService(NetworkRegistrationInfo networkRegInfo) {
658         try {
659             VopsSupportInfo vopsInfo = networkRegInfo.getDataSpecificInfo().getVopsSupportInfo();
660             if (vopsInfo instanceof NrVopsSupportInfo) {
661                 NrVopsSupportInfo nrVopsInfo = (NrVopsSupportInfo) vopsInfo;
662                 return nrVopsInfo.isEmergencyServiceSupported();
663             } else {
664                 return vopsInfo.isEmergencyServiceSupported();
665             }
666         } catch (NullPointerException e) {
667             return false;
668         }
669     }
670 
onPreciseDataConnectionStateChanged(PreciseDataConnectionState connectionState)671     protected void onPreciseDataConnectionStateChanged(PreciseDataConnectionState connectionState) {
672         if (!validatePreciseDataConnectionStateChanged(connectionState)) {
673             log("invalid onPreciseDataConnectionStateChanged:" + connectionState);
674             return;
675         }
676         log("onPreciseDataConnectionStateChanged state:" + connectionState);
677         notifyPreciseDataConnectionStateChanged(connectionState);
678     }
679 
validatePreciseDataConnectionStateChanged(PreciseDataConnectionState newState)680     private boolean validatePreciseDataConnectionStateChanged(PreciseDataConnectionState newState) {
681         try {
682             if (newState.getState() == TelephonyManager.DATA_CONNECTED
683                     || newState.getState() == TelephonyManager.DATA_HANDOVER_IN_PROGRESS) {
684                 List<Integer> netCapabilities =
685                         QnsUtils.getNetCapabilitiesFromApnTypeBitmask(
686                                 newState.getApnSetting().getApnTypeBitmask());
687                 for (int netCapability : netCapabilities) {
688                     PreciseDataConnectionState lastState =
689                             getLastPreciseDataConnectionState(netCapability);
690                     PreciseDataConnectionState archiveState =
691                             sArchivingPreciseDataConnectionState.get(
692                                     mSubId, newState.getTransportType(), netCapability);
693                     if (archiveState.equals(newState) && lastState == null) {
694                         return false;
695                     }
696                 }
697             }
698         } catch (Exception e) {
699             log("got Exception in validatePreciseDataConnectionStateChanged:" + e);
700         }
701         return true;
702     }
703 
isVoiceBarring()704     boolean isVoiceBarring() {
705         return mLastQnsTelephonyInfoIms.getVoiceBarring();
706     }
707 
isEmergencyBarring()708     boolean isEmergencyBarring() {
709         return mLastQnsTelephonyInfoIms.getEmergencyBarring();
710     }
711 
onBarringInfoChanged(BarringInfo barringInfo)712     protected void onBarringInfoChanged(BarringInfo barringInfo) {
713         boolean voiceBarringByFactor =
714                 barringInfo
715                                 .getBarringServiceInfo(BARRING_SERVICE_TYPE_MMTEL_VOICE)
716                                 .getConditionalBarringFactor()
717                         == 100;
718         boolean emergencyBarringByFactor =
719                 barringInfo
720                                 .getBarringServiceInfo(BARRING_SERVICE_TYPE_EMERGENCY)
721                                 .getConditionalBarringFactor()
722                         == 100;
723         log(
724                 "onBarringInfoChanged voiceBarringByFactor:"
725                         + voiceBarringByFactor
726                         + " emergencyBarringFactor"
727                         + emergencyBarringByFactor);
728         boolean changed = false;
729         if (mLastQnsTelephonyInfoIms.getVoiceBarring() != voiceBarringByFactor) {
730             log(" onBarringInfoChanged voiceBarring changed:" + voiceBarringByFactor);
731             mLastQnsTelephonyInfoIms.setVoiceBarring(voiceBarringByFactor);
732             changed = true;
733         }
734         if (mLastQnsTelephonyInfoIms.getEmergencyBarring() != emergencyBarringByFactor) {
735             log(" onBarringInfoChanged emergencyBarring changed:" + emergencyBarringByFactor);
736             mLastQnsTelephonyInfoIms.setEmergencyBarring(emergencyBarringByFactor);
737             changed = true;
738         }
739         if (changed) {
740             notifyQnsTelephonyInfoIms(mLastQnsTelephonyInfoIms);
741         }
742     }
743 
onCallStateChanged(int callState)744     protected void onCallStateChanged(int callState) {
745         mCallState = callState;
746         mCallStateListener.notifyResult(callState);
747     }
748 
onSrvccStateChanged(int srvccState)749     protected void onSrvccStateChanged(int srvccState) {
750         mSrvccStateListener.notifyResult(srvccState);
751     }
752 
onSubscriptionIdChanged(int subId)753     protected void onSubscriptionIdChanged(int subId) {
754         mSubscriptionIdListener.notifyResult(subId);
755     }
756 
onImsCallDisconnectCauseChanged(ImsReasonInfo imsReasonInfo)757     protected void onImsCallDisconnectCauseChanged(ImsReasonInfo imsReasonInfo) {
758         mImsCallDropDisconnectCauseListener.notifyResult(imsReasonInfo);
759     }
760 
log(String s)761     protected void log(String s) {
762         Log.d(mLogTag, s);
763     }
764 
close()765     void close() {
766         mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionsChangeListener);
767         mHandlerThread.quitSafely();
768         if (mTelephonyListener != null) {
769             mTelephonyListener.unregister(mSubId);
770         }
771         mNetCapabilityRegistrantMap.clear();
772         mQnsTelephonyInfoRegistrantMap.clear();
773         mLastPreciseDataConnectionState.clear();
774         mIwlanServiceStateListener.removeAll();
775     }
776 
777     /** Listener for change of service state. */
778     protected interface OnServiceStateListener {
779         /** Notify the cellular service state changed. */
onServiceStateChanged(ServiceState serviceState)780         void onServiceStateChanged(ServiceState serviceState);
781     }
782 
783     /** Listener for change of precise data connection state. */
784     protected interface OnPreciseDataConnectionStateListener {
785         /** Notify the PreciseDataConnectionState changed. */
onPreciseDataConnectionStateChanged(PreciseDataConnectionState connectionState)786         void onPreciseDataConnectionStateChanged(PreciseDataConnectionState connectionState);
787     }
788 
789     protected interface OnBarringInfoListener {
790         /** Notify the Barring info changed. */
onBarringInfoChanged(BarringInfo barringInfo)791         void onBarringInfoChanged(BarringInfo barringInfo);
792     }
793 
794     protected interface OnCallStateListener {
795         /** Notify the Call state changed. */
onCallStateChanged(@nnotation.CallState int state)796         void onCallStateChanged(@Annotation.CallState int state);
797     }
798 
799     protected interface OnSrvccStateChangedCallback {
800         /** Notify the Call state changed. */
onSrvccStateChanged(@nnotation.SrvccState int state)801         void onSrvccStateChanged(@Annotation.SrvccState int state);
802     }
803 
804     protected interface OnCallStatesChangedCallback {
805         /** Notify the Call state changed. */
onCallStatesChanged(List<CallState> callStateList)806         void onCallStatesChanged(List<CallState> callStateList);
807     }
808 
809     protected interface OnImsCallDisconnectCauseListener {
810         /** Notify the call disconnected cause changed. */
onImsCallDisconnectCauseChanged(@onNull ImsReasonInfo imsReasonInfo)811         void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo);
812     }
813 
814     protected static class Archiving<V> {
815         protected HashMap<String, V> mArchiving = new HashMap<>();
816 
Archiving()817         Archiving() {}
818 
getKey(int subId, int transportType, int netCapability)819         private String getKey(int subId, int transportType, int netCapability) {
820             return subId + "_" + transportType + "_" + netCapability;
821         }
822 
put(int subId, int transportType, int netCapability, V v)823         void put(int subId, int transportType, int netCapability, V v) {
824             mArchiving.put(getKey(subId, transportType, netCapability), v);
825         }
826 
get(int subId, int transportType, int netCapability)827         V get(int subId, int transportType, int netCapability) {
828             return mArchiving.get(getKey(subId, transportType, netCapability));
829         }
830     }
831 
832     class QnsTelephonyInfoIms extends QnsTelephonyInfo {
833         private boolean mVopsSupport;
834         private boolean mVopsEmergencySupport;
835         private boolean mVoiceBarring;
836         private boolean mEmergencyBarring;
837 
QnsTelephonyInfoIms()838         QnsTelephonyInfoIms() {
839             super();
840             mVoiceBarring = false;
841             mVopsSupport = false;
842             mEmergencyBarring = false;
843             mVopsEmergencySupport = false;
844         }
845 
QnsTelephonyInfoIms( QnsTelephonyInfo info, boolean vopsSupport, boolean vopsEmergencySupport, boolean voiceBarring, boolean emergencyBarring)846         QnsTelephonyInfoIms(
847                 QnsTelephonyInfo info,
848                 boolean vopsSupport,
849                 boolean vopsEmergencySupport,
850                 boolean voiceBarring,
851                 boolean emergencyBarring) {
852             super(info);
853             mVopsSupport = vopsSupport;
854             mVopsEmergencySupport = vopsEmergencySupport;
855             mVoiceBarring = voiceBarring;
856             mEmergencyBarring = emergencyBarring;
857         }
858 
getVopsSupport()859         boolean getVopsSupport() {
860             return mVopsSupport;
861         }
862 
setVopsSupport(boolean support)863         void setVopsSupport(boolean support) {
864             mVopsSupport = support;
865         }
866 
getVopsEmergencySupport()867         boolean getVopsEmergencySupport() {
868             return mVopsEmergencySupport;
869         }
870 
setVopsEmergencySupport(boolean support)871         void setVopsEmergencySupport(boolean support) {
872             mVopsEmergencySupport = support;
873         }
874 
getVoiceBarring()875         boolean getVoiceBarring() {
876             return mVoiceBarring;
877         }
878 
setVoiceBarring(boolean barring)879         void setVoiceBarring(boolean barring) {
880             mVoiceBarring = barring;
881         }
882 
getEmergencyBarring()883         boolean getEmergencyBarring() {
884             return mEmergencyBarring;
885         }
886 
setEmergencyBarring(boolean barring)887         void setEmergencyBarring(boolean barring) {
888             mEmergencyBarring = barring;
889         }
890 
891         @Override
equals(Object o)892         public boolean equals(Object o) {
893             boolean equal = super.equals(o);
894             if (equal) {
895                 if (!(o instanceof QnsTelephonyInfoIms)) return false;
896                 equal =
897                         (this.mVoiceBarring == ((QnsTelephonyInfoIms) o).getVoiceBarring())
898                                 && (this.mVopsSupport == ((QnsTelephonyInfoIms) o).getVopsSupport())
899                                 && (this.mVopsEmergencySupport
900                                         == ((QnsTelephonyInfoIms) o).getVopsEmergencySupport())
901                                 && (this.mEmergencyBarring
902                                         == ((QnsTelephonyInfoIms) o).getEmergencyBarring());
903             }
904             return equal;
905         }
906 
907         @Override
toString()908         public String toString() {
909             return "QnsTelephonyInfoIms{"
910                     + "mVopsSupport="
911                     + mVopsSupport
912                     + ", mVopsEmergencySupport="
913                     + mVopsEmergencySupport
914                     + ", mVoiceBarring="
915                     + mVoiceBarring
916                     + ", mEmergencyBarring="
917                     + mEmergencyBarring
918                     + ", mVoiceNetworkType="
919                     + getVoiceNetworkType()
920                     + ", mDataRegState="
921                     + getDataRegState()
922                     + ", mDataNetworkType="
923                     + getDataNetworkType()
924                     + ", mCoverage="
925                     + mCoverage
926                     + ", mRegisteredPlmn='"
927                     + getRegisteredPlmn()
928                     + "'"
929                     + ", mCellularAvailable="
930                     + isCellularAvailable()
931                     + '}';
932         }
933 
isCellularAvailable( int netCapability, boolean checkVops, boolean checkBarring, boolean volteRoamingSupported)934         boolean isCellularAvailable(
935                 int netCapability,
936                 boolean checkVops,
937                 boolean checkBarring,
938                 boolean volteRoamingSupported) {
939             if (netCapability == NetworkCapabilities.NET_CAPABILITY_IMS) {
940                 return super.isCellularAvailable()
941                         && (!checkVops || mVopsSupport)
942                         && (!checkBarring || !mVoiceBarring)
943                         && volteRoamingSupported;
944             } else if (netCapability == NetworkCapabilities.NET_CAPABILITY_EIMS) {
945                 return super.isCellularAvailable()
946                         && (!checkVops || mVopsEmergencySupport)
947                         && (!checkBarring && !mEmergencyBarring);
948             }
949             return false;
950         }
951     }
952 
953     class QnsTelephonyInfo {
954         private int mVoiceNetworkType;
955         private int mDataRegState;
956         private int mDataNetworkType;
957         private boolean mCoverage;
958         private String mRegisteredPlmn;
959         private boolean mCellularAvailable;
960 
QnsTelephonyInfo()961         QnsTelephonyInfo() {
962             mVoiceNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
963             mDataRegState = ServiceState.STATE_OUT_OF_SERVICE;
964             mDataNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
965             mCoverage = false; // home
966             mCellularAvailable = false; // not available
967             mRegisteredPlmn = "";
968         }
969 
QnsTelephonyInfo(QnsTelephonyInfo info)970         QnsTelephonyInfo(QnsTelephonyInfo info) {
971             mVoiceNetworkType = info.mVoiceNetworkType;
972             mDataRegState = info.mDataRegState;
973             mDataNetworkType = info.mDataNetworkType;
974             mCoverage = info.mCoverage;
975             mCellularAvailable = info.mCellularAvailable;
976             mRegisteredPlmn = info.mRegisteredPlmn;
977         }
978 
getVoiceNetworkType()979         int getVoiceNetworkType() {
980             return mVoiceNetworkType;
981         }
982 
setVoiceNetworkType(int voiceNetworkType)983         void setVoiceNetworkType(int voiceNetworkType) {
984             mVoiceNetworkType = voiceNetworkType;
985         }
986 
getDataRegState()987         int getDataRegState() {
988             return mDataRegState;
989         }
990 
setDataRegState(int dataRegState)991         void setDataRegState(int dataRegState) {
992             mDataRegState = dataRegState;
993         }
994 
getDataNetworkType()995         int getDataNetworkType() {
996             return mDataNetworkType;
997         }
998 
setDataNetworkType(int dataNetworkType)999         void setDataNetworkType(int dataNetworkType) {
1000             mDataNetworkType = dataNetworkType;
1001         }
1002 
getRegisteredPlmn()1003         String getRegisteredPlmn() {
1004             return mRegisteredPlmn;
1005         }
1006 
setRegisteredPlmn(String plmn)1007         void setRegisteredPlmn(String plmn) {
1008             if (plmn == null) {
1009                 mRegisteredPlmn = "";
1010             } else {
1011                 mRegisteredPlmn = plmn;
1012             }
1013         }
1014 
1015         @Override
equals(Object o)1016         public boolean equals(Object o) {
1017             if (this == o) return true;
1018             if (!(o instanceof QnsTelephonyInfo)) return false;
1019             QnsTelephonyInfo that = (QnsTelephonyInfo) o;
1020             return mVoiceNetworkType == that.mVoiceNetworkType
1021                     && mDataRegState == that.mDataRegState
1022                     && mDataNetworkType == that.mDataNetworkType
1023                     && mCoverage == that.mCoverage
1024                     && mRegisteredPlmn.equals(that.mRegisteredPlmn)
1025                     && mCellularAvailable == that.mCellularAvailable;
1026         }
1027 
1028         @Override
hashCode()1029         public int hashCode() {
1030             return Objects.hash(
1031                     mVoiceNetworkType,
1032                     mDataRegState,
1033                     mDataNetworkType,
1034                     mCoverage,
1035                     mCellularAvailable);
1036         }
1037 
1038         @Override
toString()1039         public String toString() {
1040             return "QnsTelephonyInfo{"
1041                     + "mVoiceNetworkType="
1042                     + mVoiceNetworkType
1043                     + ", mDataRegState="
1044                     + mDataRegState
1045                     + ", mDataNetworkType="
1046                     + mDataNetworkType
1047                     + ", mCoverage="
1048                     + mCoverage
1049                     + ", mRegisteredPlmn='"
1050                     + mRegisteredPlmn
1051                     + "'"
1052                     + ", mCellularAvailable="
1053                     + mCellularAvailable
1054                     + '}';
1055         }
1056 
isCoverage()1057         boolean isCoverage() {
1058             return mCoverage;
1059         }
1060 
setCoverage(boolean coverage)1061         void setCoverage(boolean coverage) {
1062             mCoverage = coverage;
1063         }
1064 
isCellularAvailable()1065         boolean isCellularAvailable() {
1066             return mCellularAvailable;
1067         }
1068 
setCellularAvailable(boolean cellularAvailable)1069         void setCellularAvailable(boolean cellularAvailable) {
1070             mCellularAvailable = cellularAvailable;
1071         }
1072     }
1073 
1074     /** {@link TelephonyCallback} to listen to Cellular Service State Changed. */
1075     protected class TelephonyListener extends TelephonyCallback
1076             implements TelephonyCallback.ServiceStateListener,
1077                     TelephonyCallback.PreciseDataConnectionStateListener,
1078                     TelephonyCallback.BarringInfoListener,
1079                     TelephonyCallback.CallStateListener,
1080                     TelephonyCallback.SrvccStateListener,
1081                     TelephonyCallback.CallAttributesListener,
1082                     TelephonyCallback.MediaQualityStatusChangedListener,
1083                     TelephonyCallback.ImsCallDisconnectCauseListener {
1084         private final Executor mExecutor;
1085         private OnServiceStateListener mServiceStateListener;
1086         private OnPreciseDataConnectionStateListener mPreciseDataConnectionStateListener;
1087         private OnBarringInfoListener mBarringInfoListener;
1088         private OnCallStateListener mCallStateListener;
1089         private OnSrvccStateChangedCallback mSrvccStateCallback;
1090         private OnSrvccStateChangedCallback mSrvccStateListener;
1091         private OnCallStatesChangedCallback mCallStatesCallback;
1092         private OnImsCallDisconnectCauseListener mImsCallDisconnectCauseListener;
1093         private TelephonyManager mTelephonyManager;
1094 
TelephonyListener(Executor executor)1095         TelephonyListener(Executor executor) {
1096             super();
1097             mExecutor = executor;
1098         }
1099 
setServiceStateListener(OnServiceStateListener listener)1100         void setServiceStateListener(OnServiceStateListener listener) {
1101             mServiceStateListener = listener;
1102         }
1103 
setPreciseDataConnectionStateListener(OnPreciseDataConnectionStateListener listener)1104         void setPreciseDataConnectionStateListener(OnPreciseDataConnectionStateListener listener) {
1105             mPreciseDataConnectionStateListener = listener;
1106         }
1107 
setBarringInfoListener(OnBarringInfoListener listener)1108         void setBarringInfoListener(OnBarringInfoListener listener) {
1109             mBarringInfoListener = listener;
1110         }
1111 
setCallStateListener(OnCallStateListener listener)1112         void setCallStateListener(OnCallStateListener listener) {
1113             mCallStateListener = listener;
1114         }
1115 
setSrvccStateCallback(OnSrvccStateChangedCallback callback)1116         void setSrvccStateCallback(OnSrvccStateChangedCallback callback) {
1117             mSrvccStateCallback = callback;
1118         }
1119 
setSrvccStateListener(OnSrvccStateChangedCallback listener)1120         void setSrvccStateListener(OnSrvccStateChangedCallback listener) {
1121             mSrvccStateListener = listener;
1122         }
1123 
setCallStatesCallback(OnCallStatesChangedCallback listener)1124         void setCallStatesCallback(OnCallStatesChangedCallback listener) {
1125             mCallStatesCallback = listener;
1126         }
1127 
setImsCallDisconnectCauseListener(OnImsCallDisconnectCauseListener listener)1128         void setImsCallDisconnectCauseListener(OnImsCallDisconnectCauseListener listener) {
1129             mImsCallDisconnectCauseListener = listener;
1130         }
1131 
1132         /**
1133          * Register a TelephonyCallback for this listener.
1134          *
1135          * @param context the Context
1136          * @param subId the subscription id.
1137          */
register(Context context, int subId)1138         void register(Context context, int subId) {
1139             log("register TelephonyCallback for sub:" + subId);
1140             long identity = Binder.clearCallingIdentity();
1141             try {
1142                 mTelephonyManager =
1143                         context.getSystemService(TelephonyManager.class)
1144                                 .createForSubscriptionId(subId);
1145                 mTelephonyManager.registerTelephonyCallback(
1146                         TelephonyManager.INCLUDE_LOCATION_DATA_NONE, mExecutor, this);
1147             } catch (NullPointerException e) {
1148                 log("got NullPointerException e:" + e);
1149             } finally {
1150                 Binder.restoreCallingIdentity(identity);
1151             }
1152         }
1153 
1154         /**
1155          * Unregister a TelephonyCallback for this listener.
1156          *
1157          * @param subId the subscription id.
1158          */
unregister(int subId)1159         void unregister(int subId) {
1160             log("unregister TelephonyCallback for sub:" + subId);
1161             mTelephonyManager.unregisterTelephonyCallback(this);
1162         }
1163 
1164         @Override
onServiceStateChanged(ServiceState serviceState)1165         public void onServiceStateChanged(ServiceState serviceState) {
1166             if (mServiceStateListener != null) {
1167                 mServiceStateListener.onServiceStateChanged(serviceState);
1168             }
1169         }
1170 
1171         @Override
onPreciseDataConnectionStateChanged( PreciseDataConnectionState connectionState)1172         public void onPreciseDataConnectionStateChanged(
1173                 PreciseDataConnectionState connectionState) {
1174             if (mPreciseDataConnectionStateListener != null) {
1175                 mPreciseDataConnectionStateListener.onPreciseDataConnectionStateChanged(
1176                         connectionState);
1177             }
1178         }
1179 
1180         @Override
onBarringInfoChanged(BarringInfo barringInfo)1181         public void onBarringInfoChanged(BarringInfo barringInfo) {
1182             if (mBarringInfoListener != null) {
1183                 mBarringInfoListener.onBarringInfoChanged(barringInfo);
1184             }
1185         }
1186 
1187         @Override
onCallStateChanged(@nnotation.CallState int state)1188         public void onCallStateChanged(@Annotation.CallState int state) {
1189             if (mCallStateListener != null) {
1190                 mCallStateListener.onCallStateChanged(state);
1191             }
1192         }
1193 
1194         @Override
onSrvccStateChanged(@nnotation.SrvccState int state)1195         public void onSrvccStateChanged(@Annotation.SrvccState int state) {
1196             if (mSrvccStateListener != null) {
1197                 mSrvccStateListener.onSrvccStateChanged(state);
1198             }
1199             for (Consumer<Integer> consumer : mSrvccStateConsumerList) {
1200                 consumer.accept(state);
1201             }
1202         }
1203 
1204         @Override
onCallStatesChanged(List<CallState> callStateList)1205         public void onCallStatesChanged(List<CallState> callStateList) {
1206             for (Consumer<List<CallState>> consumer : mCallStatesConsumerList) {
1207                 consumer.accept(callStateList);
1208             }
1209             if (mCallStatesCallback != null) {
1210                 mCallStatesCallback.onCallStatesChanged(callStateList);
1211             }
1212         }
1213 
1214         @Override
onMediaQualityStatusChanged(MediaQualityStatus status)1215         public void onMediaQualityStatusChanged(MediaQualityStatus status) {
1216             for (Consumer<MediaQualityStatus> consumer : mMediaQualityConsumerList) {
1217                 consumer.accept(status);
1218             }
1219         }
1220 
1221         @Override
onImsCallDisconnectCauseChanged(@onNull ImsReasonInfo imsReasonInfo)1222         public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo) {
1223             if (mImsCallDisconnectCauseListener != null) {
1224                 mImsCallDisconnectCauseListener.onImsCallDisconnectCauseChanged(imsReasonInfo);
1225             }
1226         }
1227     }
1228 
addCallStatesChangedCallback(Consumer<List<CallState>> consumer)1229     void addCallStatesChangedCallback(Consumer<List<CallState>> consumer) {
1230         mCallStatesConsumerList.add(consumer);
1231     }
1232 
removeCallStatesChangedCallback(Consumer<List<CallState>> consumer)1233     void removeCallStatesChangedCallback(Consumer<List<CallState>> consumer) {
1234         mCallStatesConsumerList.remove(consumer);
1235     }
1236 
addSrvccStateChangedCallback(Consumer<Integer> consumer)1237     void addSrvccStateChangedCallback(Consumer<Integer> consumer) {
1238         mSrvccStateConsumerList.add(consumer);
1239     }
1240 
removeSrvccStateChangedCallback(Consumer<Integer> consumer)1241     void removeSrvccStateChangedCallback(Consumer<Integer> consumer) {
1242         mSrvccStateConsumerList.remove(consumer);
1243     }
1244 
addMediaQualityStatusCallback(Consumer<MediaQualityStatus> consumer)1245     void addMediaQualityStatusCallback(Consumer<MediaQualityStatus> consumer) {
1246         mMediaQualityConsumerList.add(consumer);
1247     }
1248 
removeMediaQualityStatusCallback(Consumer<MediaQualityStatus> consumer)1249     void removeMediaQualityStatusCallback(Consumer<MediaQualityStatus> consumer) {
1250         mMediaQualityConsumerList.remove(consumer);
1251     }
1252 
1253     /**
1254      * Dumps the state of {@link QualityMonitor}
1255      *
1256      * @param pw {@link PrintWriter} to write the state of the object.
1257      * @param prefix String to append at start of dumped log.
1258      */
dump(PrintWriter pw, String prefix)1259     void dump(PrintWriter pw, String prefix) {
1260         pw.println(prefix + "------------------------------");
1261         pw.println(prefix + "QnsTelephonyListener[" + mSlotIndex + "]:");
1262         pw.println(prefix + "mLastQnsTelephonyInfo=" + mLastQnsTelephonyInfo);
1263         pw.println(prefix + "mLastQnsTelephonyInfoIms=" + mLastQnsTelephonyInfoIms);
1264         pw.println(prefix + "mLastServiceState=" + mLastServiceState);
1265         pw.println(prefix + "mLastPreciseDataConnectionState=" + mLastPreciseDataConnectionState);
1266     }
1267 }
1268