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.systemui.statusbar.connectivity 18 19 import android.telephony.ServiceState 20 import android.telephony.SignalStrength 21 import android.telephony.TelephonyDisplayInfo 22 import android.telephony.TelephonyManager 23 import com.android.settingslib.Utils 24 import com.android.settingslib.mobile.MobileStatusTracker.MobileStatus 25 import com.android.settingslib.mobile.TelephonyIcons 26 import java.lang.IllegalArgumentException 27 28 /** 29 * Box for all policy-related state used in [MobileSignalController] 30 */ 31 internal class MobileState( 32 @JvmField var networkName: String? = null, 33 @JvmField var networkNameData: String? = null, 34 @JvmField var dataSim: Boolean = false, 35 @JvmField var dataConnected: Boolean = false, 36 @JvmField var isEmergency: Boolean = false, 37 @JvmField var airplaneMode: Boolean = false, 38 @JvmField var carrierNetworkChangeMode: Boolean = false, 39 @JvmField var isDefault: Boolean = false, 40 @JvmField var userSetup: Boolean = false, 41 @JvmField var roaming: Boolean = false, 42 @JvmField var dataState: Int = TelephonyManager.DATA_DISCONNECTED, 43 // Tracks the on/off state of the defaultDataSubscription 44 @JvmField var defaultDataOff: Boolean = false 45 ) : ConnectivityState() { 46 47 @JvmField var telephonyDisplayInfo = TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN, 48 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE) 49 @JvmField var serviceState: ServiceState? = null 50 @JvmField var signalStrength: SignalStrength? = null 51 52 /** @return true if this state is disabled or not default data */ 53 val isDataDisabledOrNotDefault: Boolean 54 get() = (iconGroup === TelephonyIcons.DATA_DISABLED || 55 iconGroup === TelephonyIcons.NOT_DEFAULT_DATA) && userSetup 56 57 /** @return if this state is considered to have inbound activity */ 58 fun hasActivityIn(): Boolean { 59 return dataConnected && !carrierNetworkChangeMode && activityIn 60 } 61 62 /** @return if this state is considered to have outbound activity */ 63 fun hasActivityOut(): Boolean { 64 return dataConnected && !carrierNetworkChangeMode && activityOut 65 } 66 67 /** @return true if this state should show a RAT icon in quick settings */ 68 fun showQuickSettingsRatIcon(): Boolean { 69 return dataConnected || isDataDisabledOrNotDefault 70 } 71 72 override fun copyFrom(other: ConnectivityState) { 73 val o = other as? MobileState ?: throw IllegalArgumentException( 74 "MobileState can only update from another MobileState") 75 76 super.copyFrom(o) 77 networkName = o.networkName 78 networkNameData = o.networkNameData 79 dataSim = o.dataSim 80 dataConnected = o.dataConnected 81 isEmergency = o.isEmergency 82 airplaneMode = o.airplaneMode 83 carrierNetworkChangeMode = o.carrierNetworkChangeMode 84 isDefault = o.isDefault 85 userSetup = o.userSetup 86 roaming = o.roaming 87 dataState = o.dataState 88 defaultDataOff = o.defaultDataOff 89 90 telephonyDisplayInfo = o.telephonyDisplayInfo 91 serviceState = o.serviceState 92 signalStrength = o.signalStrength 93 } 94 95 fun isDataConnected(): Boolean { 96 return connected && dataState == TelephonyManager.DATA_CONNECTED 97 } 98 99 /** @return the current voice service state, or -1 if null */ 100 fun getVoiceServiceState(): Int { 101 return serviceState?.state ?: -1 102 } 103 104 fun isNoCalling(): Boolean { 105 return serviceState?.state != ServiceState.STATE_IN_SERVICE 106 } 107 108 fun getOperatorAlphaShort(): String { 109 return serviceState?.operatorAlphaShort ?: "" 110 } 111 112 fun isCdma(): Boolean { 113 return signalStrength != null && !signalStrength!!.isGsm 114 } 115 116 fun isEmergencyOnly(): Boolean { 117 return serviceState != null && serviceState!!.isEmergencyOnly 118 } 119 120 fun isInService(): Boolean { 121 return Utils.isInService(serviceState) 122 } 123 124 fun isRoaming(): Boolean { 125 return serviceState != null && serviceState!!.roaming 126 } 127 128 fun setFromMobileStatus(mobileStatus: MobileStatus) { 129 activityIn = mobileStatus.activityIn 130 activityOut = mobileStatus.activityOut 131 dataSim = mobileStatus.dataSim 132 carrierNetworkChangeMode = mobileStatus.carrierNetworkChangeMode 133 dataState = mobileStatus.dataState 134 signalStrength = mobileStatus.signalStrength 135 telephonyDisplayInfo = mobileStatus.telephonyDisplayInfo 136 serviceState = mobileStatus.serviceState 137 } 138 139 override fun toString(builder: StringBuilder) { 140 super.toString(builder) 141 builder.append(',') 142 builder.append("dataSim=$dataSim,") 143 builder.append("networkName=$networkName,") 144 builder.append("networkNameData=$networkNameData,") 145 builder.append("dataConnected=$dataConnected,") 146 builder.append("roaming=$roaming,") 147 builder.append("isDefault=$isDefault,") 148 builder.append("isEmergency=$isEmergency,") 149 builder.append("airplaneMode=$airplaneMode,") 150 builder.append("carrierNetworkChangeMode=$carrierNetworkChangeMode,") 151 builder.append("userSetup=$userSetup,") 152 builder.append("dataState=$dataState,") 153 builder.append("defaultDataOff=$defaultDataOff,") 154 155 // Computed properties 156 builder.append("showQuickSettingsRatIcon=${showQuickSettingsRatIcon()},") 157 builder.append("voiceServiceState=${getVoiceServiceState()},") 158 builder.append("isInService=${isInService()},") 159 160 builder.append("serviceState=${serviceState?.minLog() ?: "(null)"},") 161 builder.append("signalStrength=${signalStrength?.minLog() ?: "(null)"},") 162 builder.append("displayInfo=$telephonyDisplayInfo") 163 } 164 165 override fun equals(other: Any?): Boolean { 166 if (this === other) return true 167 if (javaClass != other?.javaClass) return false 168 if (!super.equals(other)) return false 169 170 other as MobileState 171 172 if (networkName != other.networkName) return false 173 if (networkNameData != other.networkNameData) return false 174 if (dataSim != other.dataSim) return false 175 if (dataConnected != other.dataConnected) return false 176 if (isEmergency != other.isEmergency) return false 177 if (airplaneMode != other.airplaneMode) return false 178 if (carrierNetworkChangeMode != other.carrierNetworkChangeMode) return false 179 if (isDefault != other.isDefault) return false 180 if (userSetup != other.userSetup) return false 181 if (roaming != other.roaming) return false 182 if (dataState != other.dataState) return false 183 if (defaultDataOff != other.defaultDataOff) return false 184 if (telephonyDisplayInfo != other.telephonyDisplayInfo) return false 185 if (serviceState != other.serviceState) return false 186 if (signalStrength != other.signalStrength) return false 187 188 return true 189 } 190 191 override fun hashCode(): Int { 192 var result = super.hashCode() 193 result = 31 * result + (networkName?.hashCode() ?: 0) 194 result = 31 * result + (networkNameData?.hashCode() ?: 0) 195 result = 31 * result + dataSim.hashCode() 196 result = 31 * result + dataConnected.hashCode() 197 result = 31 * result + isEmergency.hashCode() 198 result = 31 * result + airplaneMode.hashCode() 199 result = 31 * result + carrierNetworkChangeMode.hashCode() 200 result = 31 * result + isDefault.hashCode() 201 result = 31 * result + userSetup.hashCode() 202 result = 31 * result + roaming.hashCode() 203 result = 31 * result + dataState 204 result = 31 * result + defaultDataOff.hashCode() 205 result = 31 * result + telephonyDisplayInfo.hashCode() 206 result = 31 * result + (serviceState?.hashCode() ?: 0) 207 result = 31 * result + (signalStrength?.hashCode() ?: 0) 208 return result 209 } 210 } 211 212 /** toString() is a little more verbose than we need. Just log the fields we read */ 213 private fun ServiceState.minLog(): String { 214 return "serviceState={" + 215 "state=$state," + 216 "isEmergencyOnly=$isEmergencyOnly," + 217 "roaming=$roaming," + 218 "operatorNameAlphaShort=$operatorAlphaShort}" 219 } 220 221 private fun SignalStrength.minLog(): String { 222 return "signalStrength={" + 223 "isGsm=$isGsm," + 224 "level=$level}" 225 } 226