blob: fdf5ffd4438444e39eae3487fa1f245d759d5a40 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.pipeline.mobile.data.model
import android.annotation.IntRange
import android.telephony.CellSignalStrength
import android.telephony.TelephonyCallback.CarrierNetworkListener
import android.telephony.TelephonyCallback.DataActivityListener
import android.telephony.TelephonyCallback.DataConnectionStateListener
import android.telephony.TelephonyCallback.DisplayInfoListener
import android.telephony.TelephonyCallback.ServiceStateListener
import android.telephony.TelephonyCallback.SignalStrengthsListener
import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyManager
import com.android.systemui.log.table.Diffable
import com.android.systemui.log.table.TableRowLogger
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Disconnected
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
/**
* Data class containing all of the relevant information for a particular line of service, known as
* a Subscription in the telephony world. These models are the result of a single telephony listener
* which has many callbacks which each modify some particular field on this object.
*
* The design goal here is to de-normalize fields from the system into our model fields below. So
* any new field that needs to be tracked should be copied into this data class rather than
* threading complex system objects through the pipeline.
*/
data class MobileConnectionModel(
/** Fields below are from [ServiceStateListener.onServiceStateChanged] */
val isEmergencyOnly: Boolean = false,
val isRoaming: Boolean = false,
/**
* See [android.telephony.ServiceState.getOperatorAlphaShort], this value is defined as the
* current registered operator name in short alphanumeric format. In some cases this name might
* be preferred over other methods of calculating the network name
*/
val operatorAlphaShort: String? = null,
/**
* TODO (b/263167683): Clarify this field
*
* This check comes from [com.android.settingslib.Utils.isInService]. It is intended to be a
* mapping from a ServiceState to a notion of connectivity. Notably, it will consider a
* connection to be in-service if either the voice registration state is IN_SERVICE or the data
* registration state is IN_SERVICE and NOT IWLAN.
*/
val isInService: Boolean = false,
/** Fields below from [SignalStrengthsListener.onSignalStrengthsChanged] */
val isGsm: Boolean = false,
@IntRange(from = 0, to = 4)
val cdmaLevel: Int = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN,
@IntRange(from = 0, to = 4)
val primaryLevel: Int = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN,
/** Fields below from [DataConnectionStateListener.onDataConnectionStateChanged] */
val dataConnectionState: DataConnectionState = Disconnected,
/**
* Fields below from [DataActivityListener.onDataActivity]. See [TelephonyManager] for the
* values
*/
val dataActivityDirection: DataActivityModel =
DataActivityModel(
hasActivityIn = false,
hasActivityOut = false,
),
/** Fields below from [CarrierNetworkListener.onCarrierNetworkChange] */
val carrierNetworkChangeActive: Boolean = false,
/** Fields below from [DisplayInfoListener.onDisplayInfoChanged]. */
/**
* [resolvedNetworkType] is the [TelephonyDisplayInfo.getOverrideNetworkType] if it exists or
* [TelephonyDisplayInfo.getNetworkType]. This is used to look up the proper network type icon
*/
val resolvedNetworkType: ResolvedNetworkType = ResolvedNetworkType.UnknownNetworkType,
) : Diffable<MobileConnectionModel> {
override fun logDiffs(prevVal: MobileConnectionModel, row: TableRowLogger) {
if (prevVal.dataConnectionState != dataConnectionState) {
row.logChange(COL_CONNECTION_STATE, dataConnectionState.name)
}
if (prevVal.isEmergencyOnly != isEmergencyOnly) {
row.logChange(COL_EMERGENCY, isEmergencyOnly)
}
if (prevVal.isRoaming != isRoaming) {
row.logChange(COL_ROAMING, isRoaming)
}
if (prevVal.operatorAlphaShort != operatorAlphaShort) {
row.logChange(COL_OPERATOR, operatorAlphaShort)
}
if (prevVal.isInService != isInService) {
row.logChange(COL_IS_IN_SERVICE, isInService)
}
if (prevVal.isGsm != isGsm) {
row.logChange(COL_IS_GSM, isGsm)
}
if (prevVal.cdmaLevel != cdmaLevel) {
row.logChange(COL_CDMA_LEVEL, cdmaLevel)
}
if (prevVal.primaryLevel != primaryLevel) {
row.logChange(COL_PRIMARY_LEVEL, primaryLevel)
}
if (prevVal.dataActivityDirection != dataActivityDirection) {
row.logChange(COL_ACTIVITY_DIRECTION, dataActivityDirection.toString())
}
if (prevVal.carrierNetworkChangeActive != carrierNetworkChangeActive) {
row.logChange(COL_CARRIER_NETWORK_CHANGE, carrierNetworkChangeActive)
}
if (prevVal.resolvedNetworkType != resolvedNetworkType) {
row.logChange(COL_RESOLVED_NETWORK_TYPE, resolvedNetworkType.toString())
}
}
override fun logFull(row: TableRowLogger) {
row.logChange(COL_CONNECTION_STATE, dataConnectionState.name)
row.logChange(COL_EMERGENCY, isEmergencyOnly)
row.logChange(COL_ROAMING, isRoaming)
row.logChange(COL_OPERATOR, operatorAlphaShort)
row.logChange(COL_IS_IN_SERVICE, isInService)
row.logChange(COL_IS_GSM, isGsm)
row.logChange(COL_CDMA_LEVEL, cdmaLevel)
row.logChange(COL_PRIMARY_LEVEL, primaryLevel)
row.logChange(COL_ACTIVITY_DIRECTION, dataActivityDirection.toString())
row.logChange(COL_CARRIER_NETWORK_CHANGE, carrierNetworkChangeActive)
row.logChange(COL_RESOLVED_NETWORK_TYPE, resolvedNetworkType.toString())
}
companion object {
const val COL_EMERGENCY = "EmergencyOnly"
const val COL_ROAMING = "Roaming"
const val COL_OPERATOR = "OperatorName"
const val COL_IS_IN_SERVICE = "IsInService"
const val COL_IS_GSM = "IsGsm"
const val COL_CDMA_LEVEL = "CdmaLevel"
const val COL_PRIMARY_LEVEL = "PrimaryLevel"
const val COL_CONNECTION_STATE = "ConnectionState"
const val COL_ACTIVITY_DIRECTION = "DataActivity"
const val COL_CARRIER_NETWORK_CHANGE = "CarrierNetworkChangeActive"
const val COL_RESOLVED_NETWORK_TYPE = "NetworkType"
}
}