1 /*
2  * Copyright (C) 2022 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.systemui.statusbar.pipeline.mobile.data.repository
18 
19 import android.telephony.CarrierConfigManager
20 import android.telephony.SubscriptionManager
21 import com.android.settingslib.SignalIcon.MobileIconGroup
22 import com.android.settingslib.mobile.MobileMappings
23 import com.android.settingslib.mobile.MobileMappings.Config
24 import com.android.systemui.statusbar.pipeline.mobile.data.model.ServiceStateModel
25 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
26 import kotlinx.coroutines.flow.Flow
27 import kotlinx.coroutines.flow.StateFlow
28 
29 /**
30  * Repo for monitoring the complete active subscription info list, to be consumed and filtered based
31  * on various policy
32  */
33 interface MobileConnectionsRepository {
34     /** Observable list of current mobile subscriptions */
35     val subscriptions: StateFlow<List<SubscriptionModel>>
36 
37     /**
38      * Observable for the subscriptionId of the current mobile data connection. Null if we don't
39      * have a valid subscription id
40      */
41     val activeMobileDataSubscriptionId: StateFlow<Int?>
42 
43     /** Repo that tracks the current [activeMobileDataSubscriptionId] */
44     val activeMobileDataRepository: StateFlow<MobileConnectionRepository?>
45 
46     /**
47      * Observable event for when the active data sim switches but the group stays the same. E.g.,
48      * CBRS switching would trigger this
49      */
50     val activeSubChangedInGroupEvent: Flow<Unit>
51 
52     /** Tracks [SubscriptionManager.getDefaultDataSubscriptionId] */
53     val defaultDataSubId: StateFlow<Int>
54 
55     /**
56      * True if the default network connection is a mobile-like connection and false otherwise.
57      *
58      * This is typically shown by having [android.net.NetworkCapabilities.TRANSPORT_CELLULAR], but
59      * there are edge cases (like carrier merged wifi) that could also result in the default
60      * connection being mobile-like.
61      */
62     val mobileIsDefault: StateFlow<Boolean>
63 
64     /**
65      * True if the device currently has a carrier merged connection.
66      *
67      * See [CarrierMergedConnectionRepository] for more info.
68      */
69     val hasCarrierMergedConnection: Flow<Boolean>
70 
71     /** True if the default network connection is validated and false otherwise. */
72     val defaultConnectionIsValidated: StateFlow<Boolean>
73 
74     /** Get or create a repository for the line of service for the given subscription ID */
getRepoForSubIdnull75     fun getRepoForSubId(subId: Int): MobileConnectionRepository
76 
77     /**
78      * [Config] is an object that tracks relevant configuration flags for a given subscription ID.
79      * In the case of [MobileMappings], it's hard-coded to check the default data subscription's
80      * config, so this will apply to every icon that we care about.
81      *
82      * Relevant bits in the config are things like
83      * [CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL]
84      *
85      * This flow will produce whenever the default data subscription or the carrier config changes.
86      */
87     val defaultDataSubRatConfig: StateFlow<Config>
88 
89     /** The icon mapping from network type to [MobileIconGroup] for the default subscription */
90     val defaultMobileIconMapping: Flow<Map<String, MobileIconGroup>>
91 
92     /** Fallback [MobileIconGroup] in the case where there is no icon in the mapping */
93     val defaultMobileIconGroup: Flow<MobileIconGroup>
94 
95     /**
96      * [deviceServiceState] is equivalent to the last [Intent.ACTION_SERVICE_STATE] broadcast with a
97      * subscriptionId of -1 (aka [SubscriptionManager.INVALID_SUBSCRIPTION_ID]).
98      *
99      * While each [MobileConnectionsRepository] listens for the service state of each subscription,
100      * there is potentially a service state associated with the device itself. This value can be
101      * used to calculate e.g., the emergency calling capability of the device (as opposed to the
102      * emergency calling capability of an individual mobile connection)
103      *
104      * Note: this is a [StateFlow] using an eager sharing strategy.
105      */
106     val deviceServiceState: StateFlow<ServiceStateModel?>
107 
108     /**
109      * If any active SIM on the device is in
110      * [android.telephony.TelephonyManager.SIM_STATE_PIN_REQUIRED] or
111      * [android.telephony.TelephonyManager.SIM_STATE_PUK_REQUIRED] or
112      * [android.telephony.TelephonyManager.SIM_STATE_PERM_DISABLED]
113      */
114     val isAnySimSecure: Flow<Boolean>
115 
116     /**
117      * Returns whether any active SIM on the device is in
118      * [android.telephony.TelephonyManager.SIM_STATE_PIN_REQUIRED] or
119      * [android.telephony.TelephonyManager.SIM_STATE_PUK_REQUIRED] or
120      * [android.telephony.TelephonyManager.SIM_STATE_PERM_DISABLED].
121      *
122      * Note: Unfortunately, we cannot name this [isAnySimSecure] due to a conflict with the flow
123      * name above (Java code-gen is having issues with it).
124      */
125     fun getIsAnySimSecure(): Boolean
126 
127     /**
128      * Checks if any subscription has [android.telephony.TelephonyManager.getEmergencyCallbackMode]
129      * == true
130      */
131     suspend fun isInEcmMode(): Boolean
132 }
133