• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 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.google.android.iwlan;
18 
19 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
20 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
21 
22 import android.content.Context;
23 import android.content.Intent;
24 import android.net.ConnectivityManager;
25 import android.net.LinkProperties;
26 import android.net.Network;
27 import android.net.NetworkCapabilities;
28 import android.net.NetworkSpecifier;
29 import android.net.TelephonyNetworkSpecifier;
30 import android.net.TransportInfo;
31 import android.net.vcn.VcnTransportInfo;
32 import android.net.vcn.VcnUtils;
33 import android.os.Handler;
34 import android.os.HandlerExecutor;
35 import android.os.HandlerThread;
36 import android.os.IBinder;
37 import android.os.Looper;
38 import android.os.Message;
39 import android.support.annotation.NonNull;
40 import android.telephony.AccessNetworkConstants;
41 import android.telephony.NetworkRegistrationInfo;
42 import android.telephony.NetworkService;
43 import android.telephony.NetworkServiceCallback;
44 import android.telephony.SubscriptionManager;
45 import android.telephony.TelephonyManager;
46 import android.util.Log;
47 
48 import com.android.internal.annotations.VisibleForTesting;
49 
50 import java.util.ArrayList;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.Objects;
54 import java.util.concurrent.ConcurrentHashMap;
55 
56 public class IwlanNetworkService extends NetworkService {
57     private static final String TAG = IwlanNetworkService.class.getSimpleName();
58     private static Context mContext;
59     private IwlanNetworkMonitorCallback mNetworkMonitorCallback;
60     private IwlanOnSubscriptionsChangedListener mSubsChangeListener;
61     private Handler mIwlanNetworkServiceHandler;
62     private HandlerThread mIwlanNetworkServiceHandlerThread;
63     private static boolean sNetworkConnected;
64     private static final Map<Integer, IwlanNetworkServiceProvider> sIwlanNetworkServiceProviders =
65             new ConcurrentHashMap<>();
66     private static final int INVALID_SUB_ID = -1;
67 
68     // The current subscription with the active internet PDN. Need not be the default data sub.
69     // If internet is over WiFi, this value will be INVALID_SUB_ID.
70     private static int mConnectedDataSub = INVALID_SUB_ID;
71 
72     private static final int EVENT_BASE = IwlanEventListener.NETWORK_SERVICE_INTERNAL_EVENT_BASE;
73     private static final int EVENT_NETWORK_REGISTRATION_INFO_REQUEST = EVENT_BASE;
74     private static final int EVENT_CREATE_NETWORK_SERVICE_PROVIDER = EVENT_BASE + 1;
75     private static final int EVENT_REMOVE_NETWORK_SERVICE_PROVIDER = EVENT_BASE + 2;
76 
77     @VisibleForTesting
78     enum Transport {
79         UNSPECIFIED_NETWORK,
80         MOBILE,
81         WIFI
82     }
83 
84     private static Transport sDefaultDataTransport = Transport.UNSPECIFIED_NETWORK;
85 
86     // This callback runs in the same thread as IwlanNetworkServiceHandler
87     static final class IwlanNetworkMonitorCallback extends ConnectivityManager.NetworkCallback {
88         /** Called when the framework connects and has declared a new network ready for use. */
89         @Override
onAvailable(Network network)90         public void onAvailable(Network network) {
91             Log.d(TAG, "onAvailable: " + network);
92         }
93 
94         /**
95          * Called when the network is about to be lost, typically because there are no outstanding
96          * requests left for it. This may be paired with a {@link
97          * ConnectivityManager.NetworkCallback#onAvailable} call with the new replacement network
98          * for graceful handover. This method is not guaranteed to be called before {@link
99          * ConnectivityManager.NetworkCallback#onLost} is called, for example in case a network is
100          * suddenly disconnected.
101          */
102         @Override
onLosing(Network network, int maxMsToLive)103         public void onLosing(Network network, int maxMsToLive) {
104             Log.d(TAG, "onLosing: maxMsToLive: " + maxMsToLive + " network: " + network);
105         }
106 
107         /**
108          * Called when a network disconnects or otherwise no longer satisfies this request or
109          * callback.
110          */
111         @Override
onLost(Network network)112         public void onLost(Network network) {
113             Log.d(TAG, "onLost: " + network);
114             IwlanNetworkService.setConnectedDataSub(INVALID_SUB_ID);
115             IwlanNetworkService.setNetworkConnected(false, Transport.UNSPECIFIED_NETWORK);
116         }
117 
118         /** Called when the network corresponding to this request changes {@link LinkProperties}. */
119         @Override
onLinkPropertiesChanged(Network network, LinkProperties linkProperties)120         public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
121             Log.d(TAG, "onLinkPropertiesChanged: " + linkProperties);
122         }
123 
124         /** Called when access to the specified network is blocked or unblocked. */
125         @Override
onBlockedStatusChanged(Network network, boolean blocked)126         public void onBlockedStatusChanged(Network network, boolean blocked) {
127             // TODO: check if we need to handle this
128             Log.d(TAG, "onBlockedStatusChanged: " + " BLOCKED:" + blocked);
129         }
130 
131         @Override
onCapabilitiesChanged( Network network, NetworkCapabilities networkCapabilities)132         public void onCapabilitiesChanged(
133                 Network network, NetworkCapabilities networkCapabilities) {
134             // onCapabilitiesChanged is guaranteed to be called immediately after onAvailable per
135             // API
136             Log.d(TAG, "onCapabilitiesChanged: " + network);
137             if (networkCapabilities != null) {
138                 if (networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
139                     IwlanNetworkService.setConnectedDataSub(
140                             getConnectedDataSub(
141                                     mContext.getSystemService(ConnectivityManager.class),
142                                     networkCapabilities));
143                     IwlanNetworkService.setNetworkConnected(
144                             true, IwlanNetworkService.Transport.MOBILE);
145                 } else if (networkCapabilities.hasTransport(TRANSPORT_WIFI)) {
146                     IwlanNetworkService.setConnectedDataSub(INVALID_SUB_ID);
147                     IwlanNetworkService.setNetworkConnected(
148                             true, IwlanNetworkService.Transport.WIFI);
149                 } else {
150                     Log.w(TAG, "Network does not have cellular or wifi capability");
151                 }
152             }
153         }
154     }
155 
156     static final class IwlanOnSubscriptionsChangedListener
157             extends SubscriptionManager.OnSubscriptionsChangedListener {
158         /**
159          * Callback invoked when there is any change to any SubscriptionInfo. Typically, this method
160          * invokes {@link SubscriptionManager#getActiveSubscriptionInfoList}
161          */
162         @Override
onSubscriptionsChanged()163         public void onSubscriptionsChanged() {
164             for (IwlanNetworkServiceProvider np : sIwlanNetworkServiceProviders.values()) {
165                 np.subscriptionChanged();
166             }
167         }
168     }
169 
170     @VisibleForTesting
171     class IwlanNetworkServiceProvider extends NetworkServiceProvider {
172         private final IwlanNetworkService mIwlanNetworkService;
173         private final String SUB_TAG;
174         private boolean mIsSubActive = false;
175 
176         /**
177          * Constructor
178          *
179          * @param slotIndex SIM slot id the data service provider associated with.
180          */
IwlanNetworkServiceProvider(int slotIndex, IwlanNetworkService iwlanNetworkService)181         public IwlanNetworkServiceProvider(int slotIndex, IwlanNetworkService iwlanNetworkService) {
182             super(slotIndex);
183             SUB_TAG = TAG + "[" + slotIndex + "]";
184             mIwlanNetworkService = iwlanNetworkService;
185 
186             // Register IwlanEventListener
187             List<Integer> events = new ArrayList<Integer>();
188             events.add(IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT);
189             events.add(IwlanEventListener.CROSS_SIM_CALLING_DISABLE_EVENT);
190             IwlanEventListener.getInstance(mContext, slotIndex)
191                     .addEventListener(events, getIwlanNetworkServiceHandler());
192         }
193 
194         @Override
requestNetworkRegistrationInfo(int domain, NetworkServiceCallback callback)195         public void requestNetworkRegistrationInfo(int domain, NetworkServiceCallback callback) {
196             getIwlanNetworkServiceHandler()
197                     .obtainMessage(
198                             EVENT_NETWORK_REGISTRATION_INFO_REQUEST,
199                             new NetworkRegistrationInfoRequestData(domain, callback, this))
200                     .sendToTarget();
201         }
202 
203         /**
204          * Called when the instance of network service is destroyed (e.g. got unbind or binder died)
205          * or when the network service provider is removed. The extended class should implement this
206          * method to perform cleanup works.
207          */
208         @Override
close()209         public void close() {
210             mIwlanNetworkService.removeNetworkServiceProvider(this);
211             IwlanEventListener.getInstance(mContext, getSlotIndex())
212                     .removeEventListener(getIwlanNetworkServiceHandler());
213         }
214 
215         @VisibleForTesting
subscriptionChanged()216         void subscriptionChanged() {
217             boolean subActive =
218                     getSubscriptionManager()
219                                     .getActiveSubscriptionInfoForSimSlotIndex(getSlotIndex())
220                             != null;
221             if (subActive == mIsSubActive) {
222                 return;
223             }
224             mIsSubActive = subActive;
225             if (subActive) {
226                 Log.d(SUB_TAG, "sub changed from not_ready --> ready");
227             } else {
228                 Log.d(SUB_TAG, "sub changed from ready --> not_ready");
229             }
230 
231             notifyNetworkRegistrationInfoChanged();
232         }
233     }
234 
235     private final class IwlanNetworkServiceHandler extends Handler {
236         private final String TAG = IwlanNetworkServiceHandler.class.getSimpleName();
237 
238         @Override
handleMessage(Message msg)239         public void handleMessage(Message msg) {
240             Log.d(TAG, "msg.what = " + eventToString(msg.what));
241 
242             IwlanNetworkServiceProvider iwlanNetworkServiceProvider;
243             int slotId;
244 
245             switch (msg.what) {
246                 case IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT:
247                 case IwlanEventListener.CROSS_SIM_CALLING_DISABLE_EVENT:
248                     iwlanNetworkServiceProvider = getNetworkServiceProvider(msg.arg1);
249                     iwlanNetworkServiceProvider.notifyNetworkRegistrationInfoChanged();
250                     break;
251 
252                 case EVENT_NETWORK_REGISTRATION_INFO_REQUEST:
253                     NetworkRegistrationInfoRequestData networkRegistrationInfoRequestData =
254                             (NetworkRegistrationInfoRequestData) msg.obj;
255                     int domain = networkRegistrationInfoRequestData.mDomain;
256                     NetworkServiceCallback callback = networkRegistrationInfoRequestData.mCallback;
257                     iwlanNetworkServiceProvider =
258                             networkRegistrationInfoRequestData.mIwlanNetworkServiceProvider;
259 
260                     if (callback == null) {
261                         Log.d(TAG, "Error: callback is null. returning");
262                         return;
263                     }
264                     if (domain != NetworkRegistrationInfo.DOMAIN_PS) {
265                         callback.onRequestNetworkRegistrationInfoComplete(
266                                 NetworkServiceCallback.RESULT_ERROR_UNSUPPORTED, null);
267                         return;
268                     }
269 
270                     NetworkRegistrationInfo.Builder nriBuilder =
271                             new NetworkRegistrationInfo.Builder();
272                     nriBuilder
273                             .setAvailableServices(
274                                     List.of(NetworkRegistrationInfo.SERVICE_TYPE_DATA))
275                             .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
276                             .setEmergencyOnly(!iwlanNetworkServiceProvider.mIsSubActive)
277                             .setDomain(NetworkRegistrationInfo.DOMAIN_PS);
278 
279                     slotId = iwlanNetworkServiceProvider.getSlotIndex();
280                     if (!IwlanNetworkService.isNetworkConnected(
281                             isActiveDataOnOtherSub(slotId),
282                             IwlanHelper.isCrossSimCallingEnabled(mContext, slotId))) {
283                         nriBuilder
284                                 .setRegistrationState(
285                                         NetworkRegistrationInfo
286                                                 .REGISTRATION_STATE_NOT_REGISTERED_SEARCHING)
287                                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_UNKNOWN);
288                         Log.d(
289                                 TAG + "[" + slotId + "]",
290                                 ": reg state" + " REGISTRATION_STATE_NOT_REGISTERED_SEARCHING");
291                     } else {
292                         nriBuilder
293                                 .setRegistrationState(
294                                         NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
295                                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN);
296                         Log.d(TAG + "[" + slotId + "]", ": reg state REGISTRATION_STATE_HOME");
297                     }
298 
299                     callback.onRequestNetworkRegistrationInfoComplete(
300                             NetworkServiceCallback.RESULT_SUCCESS, nriBuilder.build());
301                     break;
302 
303                 case EVENT_CREATE_NETWORK_SERVICE_PROVIDER:
304                     iwlanNetworkServiceProvider = (IwlanNetworkServiceProvider) msg.obj;
305 
306                     if (sIwlanNetworkServiceProviders.isEmpty()) {
307                         initCallback();
308                     }
309 
310                     addIwlanNetworkServiceProvider(iwlanNetworkServiceProvider);
311                     break;
312 
313                 case EVENT_REMOVE_NETWORK_SERVICE_PROVIDER:
314                     iwlanNetworkServiceProvider = (IwlanNetworkServiceProvider) msg.obj;
315                     slotId = iwlanNetworkServiceProvider.getSlotIndex();
316                     IwlanNetworkServiceProvider nsp = sIwlanNetworkServiceProviders.remove(slotId);
317                     if (nsp == null) {
318                         Log.w(
319                                 TAG + "[" + slotId + "]",
320                                 "No NetworkServiceProvider exists for slot!");
321                         return;
322                     }
323                     if (sIwlanNetworkServiceProviders.isEmpty()) {
324                         deinitCallback();
325                     }
326                     break;
327 
328                 default:
329                     throw new IllegalStateException("Unexpected value: " + msg.what);
330             }
331         }
332 
IwlanNetworkServiceHandler(Looper looper)333         IwlanNetworkServiceHandler(Looper looper) {
334             super(looper);
335         }
336     }
337 
338     private static final class NetworkRegistrationInfoRequestData {
339         final int mDomain;
340         final NetworkServiceCallback mCallback;
341         final IwlanNetworkServiceProvider mIwlanNetworkServiceProvider;
342 
NetworkRegistrationInfoRequestData( int domain, NetworkServiceCallback callback, IwlanNetworkServiceProvider nsp)343         private NetworkRegistrationInfoRequestData(
344                 int domain, NetworkServiceCallback callback, IwlanNetworkServiceProvider nsp) {
345             mDomain = domain;
346             mCallback = callback;
347             mIwlanNetworkServiceProvider = nsp;
348         }
349     }
350 
351     /**
352      * Create the instance of {@link NetworkServiceProvider}. Network service provider must override
353      * this method to facilitate the creation of {@link NetworkServiceProvider} instances. The
354      * system will call this method after binding the network service for each active SIM slot id.
355      *
356      * @param slotIndex SIM slot id the network service associated with.
357      * @return Network service object. Null if failed to create the provider (e.g. invalid slot
358      *     index)
359      */
360     @Override
onCreateNetworkServiceProvider(int slotIndex)361     public NetworkServiceProvider onCreateNetworkServiceProvider(int slotIndex) {
362         Log.d(TAG, "onCreateNetworkServiceProvider: slotidx:" + slotIndex);
363 
364         // TODO: validity check slot index
365 
366         IwlanNetworkServiceProvider np = new IwlanNetworkServiceProvider(slotIndex, this);
367         getIwlanNetworkServiceHandler()
368                 .obtainMessage(EVENT_CREATE_NETWORK_SERVICE_PROVIDER, np)
369                 .sendToTarget();
370         return np;
371     }
372 
setConnectedDataSub(int subId)373     static void setConnectedDataSub(int subId) {
374         mConnectedDataSub = subId;
375     }
376 
getConnectedDataSub( ConnectivityManager connectivityManager, NetworkCapabilities networkCapabilities)377     static int getConnectedDataSub(
378             ConnectivityManager connectivityManager, NetworkCapabilities networkCapabilities) {
379         int connectedDataSub = INVALID_SUB_ID;
380         NetworkSpecifier specifier = networkCapabilities.getNetworkSpecifier();
381         TransportInfo transportInfo = networkCapabilities.getTransportInfo();
382 
383         if (specifier instanceof TelephonyNetworkSpecifier telephonyNetworkSpecifier) {
384             connectedDataSub = telephonyNetworkSpecifier.getSubscriptionId();
385         } else if (transportInfo instanceof VcnTransportInfo vcnTransportInfo) {
386             connectedDataSub =
387                     VcnUtils.getSubIdFromVcnCaps(connectivityManager, networkCapabilities);
388         }
389         return connectedDataSub;
390     }
391 
isActiveDataOnOtherSub(int slotId)392     static boolean isActiveDataOnOtherSub(int slotId) {
393         int subId = IwlanHelper.getSubId(mContext, slotId);
394         return mConnectedDataSub != INVALID_SUB_ID && subId != mConnectedDataSub;
395     }
396 
isNetworkConnected(boolean isActiveDataOnOtherSub, boolean isCstEnabled)397     public static boolean isNetworkConnected(boolean isActiveDataOnOtherSub, boolean isCstEnabled) {
398         if (isActiveDataOnOtherSub && isCstEnabled) {
399             // For cross-SIM IWLAN (Transport.MOBILE), an active data PDN must be maintained on the
400             // other subscription.
401             if (sNetworkConnected && (sDefaultDataTransport != Transport.MOBILE)) {
402                 Log.e(TAG, "Internet is on other slot, but default transport is not MOBILE!");
403             }
404             return sNetworkConnected;
405         } else {
406             // For all other cases, only wifi transport can be used.
407             return ((sDefaultDataTransport == Transport.WIFI) && sNetworkConnected);
408         }
409     }
410 
setNetworkConnected(boolean connected, Transport transport)411     public static void setNetworkConnected(boolean connected, Transport transport) {
412         if (connected == sNetworkConnected && transport == sDefaultDataTransport) {
413             return;
414         }
415         if (connected && (transport == IwlanNetworkService.Transport.UNSPECIFIED_NETWORK)) {
416             return;
417         }
418         sNetworkConnected = connected;
419         sDefaultDataTransport = transport;
420 
421         for (IwlanNetworkServiceProvider np : sIwlanNetworkServiceProviders.values()) {
422             np.notifyNetworkRegistrationInfoChanged();
423         }
424     }
425 
addIwlanNetworkServiceProvider(IwlanNetworkServiceProvider np)426     void addIwlanNetworkServiceProvider(IwlanNetworkServiceProvider np) {
427         int slotIndex = np.getSlotIndex();
428         if (sIwlanNetworkServiceProviders.containsKey(slotIndex)) {
429             throw new IllegalStateException(
430                     "NetworkServiceProvider already exists for slot " + slotIndex);
431         }
432         sIwlanNetworkServiceProviders.put(slotIndex, np);
433     }
434 
removeNetworkServiceProvider(IwlanNetworkServiceProvider np)435     public void removeNetworkServiceProvider(IwlanNetworkServiceProvider np) {
436         getIwlanNetworkServiceHandler()
437                 .obtainMessage(EVENT_REMOVE_NETWORK_SERVICE_PROVIDER, np)
438                 .sendToTarget();
439     }
440 
initCallback()441     void initCallback() {
442         // register for default network callback
443         mNetworkMonitorCallback = new IwlanNetworkMonitorCallback();
444         getConnectivityManager()
445                 .registerSystemDefaultNetworkCallback(
446                         mNetworkMonitorCallback, getIwlanNetworkServiceHandler());
447         Log.d(TAG, "Registered with Connectivity Service");
448 
449         /* register with subscription manager */
450         mSubsChangeListener = new IwlanOnSubscriptionsChangedListener();
451         getSubscriptionManager()
452                 .addOnSubscriptionsChangedListener(
453                         new HandlerExecutor(getIwlanNetworkServiceHandler()), mSubsChangeListener);
454         Log.d(TAG, "Registered with Subscription Service");
455     }
456 
deinitCallback()457     void deinitCallback() {
458         // deinit network related stuff
459         getConnectivityManager().unregisterNetworkCallback(mNetworkMonitorCallback);
460         mNetworkMonitorCallback = null;
461 
462         // deinit subscription manager related stuff
463         getSubscriptionManager().removeOnSubscriptionsChangedListener(mSubsChangeListener);
464         mSubsChangeListener = null;
465         if (mIwlanNetworkServiceHandlerThread != null) {
466             mIwlanNetworkServiceHandlerThread.quit();
467             mIwlanNetworkServiceHandlerThread = null;
468         }
469         mIwlanNetworkServiceHandler = null;
470     }
471 
472     @VisibleForTesting
setAppContext(Context appContext)473     void setAppContext(Context appContext) {
474         mContext = appContext;
475     }
476 
477     @VisibleForTesting
getNetworkServiceProvider(int slotIndex)478     IwlanNetworkServiceProvider getNetworkServiceProvider(int slotIndex) {
479         return sIwlanNetworkServiceProviders.get(slotIndex);
480     }
481 
482     @VisibleForTesting
getNetworkMonitorCallback()483     IwlanNetworkMonitorCallback getNetworkMonitorCallback() {
484         return mNetworkMonitorCallback;
485     }
486 
487     @VisibleForTesting
488     @NonNull
getIwlanNetworkServiceHandler()489     Handler getIwlanNetworkServiceHandler() {
490         if (mIwlanNetworkServiceHandler == null) {
491             mIwlanNetworkServiceHandler = new IwlanNetworkServiceHandler(getLooper());
492         }
493         return mIwlanNetworkServiceHandler;
494     }
495 
496     @VisibleForTesting
getLooper()497     Looper getLooper() {
498         mIwlanNetworkServiceHandlerThread = new HandlerThread("IwlanNetworkServiceThread");
499         mIwlanNetworkServiceHandlerThread.start();
500         return mIwlanNetworkServiceHandlerThread.getLooper();
501     }
502 
eventToString(int event)503     private static String eventToString(int event) {
504         return switch (event) {
505             case IwlanEventListener.CROSS_SIM_CALLING_ENABLE_EVENT ->
506                     "CROSS_SIM_CALLING_ENABLE_EVENT";
507             case IwlanEventListener.CROSS_SIM_CALLING_DISABLE_EVENT ->
508                     "CROSS_SIM_CALLING_DISABLE_EVENT";
509             case EVENT_NETWORK_REGISTRATION_INFO_REQUEST ->
510                     "EVENT_NETWORK_REGISTRATION_INFO_REQUEST";
511             case EVENT_CREATE_NETWORK_SERVICE_PROVIDER -> "EVENT_CREATE_NETWORK_SERVICE_PROVIDER";
512             case EVENT_REMOVE_NETWORK_SERVICE_PROVIDER -> "EVENT_REMOVE_NETWORK_SERVICE_PROVIDER";
513             default -> "Unknown(" + event + ")";
514         };
515     }
516 
517     @Override
onCreate()518     public void onCreate() {
519         mContext = getApplicationContext();
520     }
521 
522     @Override
onBind(Intent intent)523     public IBinder onBind(Intent intent) {
524         Log.d(TAG, "IwlanNetworkService onBind");
525         return super.onBind(intent);
526     }
527 
528     @NonNull
getConnectivityManager()529     ConnectivityManager getConnectivityManager() {
530         return Objects.requireNonNull(mContext.getSystemService(ConnectivityManager.class));
531     }
532 
533     @NonNull
getSubscriptionManager()534     SubscriptionManager getSubscriptionManager() {
535         return Objects.requireNonNull(mContext.getSystemService(SubscriptionManager.class));
536     }
537 }
538