Advanced AOSP Subsystems
4 min read

Telephony Framework

Overview

The Telephony Framework in Android manages the complex interactions necessary for cellular communication. It handles voice calls, SMS, cellular data connections, network registration, and SIM card management. As cellular technology evolves (from 3G to 4G LTE to 5G NR), the framework abstract away the underlying modem complexities, providing a unified API for applications and system services.

The Framework APIs

Applications interact with telephony services primarily through managers provided by the framework, located in the android.telephony package.

TelephonyManager

TelephonyManager is the primary entry point for querying cellular state and device information. It provides access to network details, signal strength, cellular data state, and subscriber information.

Due to privacy and security concerns, many TelephonyManager methods require specific permissions (like READ_PHONE_STATE or READ_PRIVILEGED_PHONE_STATE).

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

// Querying network operator name
String operatorName = telephonyManager.getNetworkOperatorName();

// Checking data connection state
int dataState = telephonyManager.getDataState();
if (dataState == TelephonyManager.DATA_CONNECTED) {
    // Cellular data is active
}

Listening to State Changes

Applications must often react to changes in the telephony environment (e.g., dropping a call when signal is lost). Historically, this was done via PhoneStateListener, but modern Android utilizes TelephonyCallback for better lifecycle management and multi-SIM support.

TelephonyCallback callback = new TelephonyCallback() {
    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
        if (state == TelephonyManager.CALL_STATE_RINGING) {
            // Handle incoming call notification
        }
    }
};

// Registering the callback
telephonyManager.registerTelephonyCallback(executor, callback);

Subscription Management and Multi-SIM

Modern Android devices frequently support multiple SIM cards (physical Dual-SIM or eSIM combinations). The framework must distinguish between the physical device (the modem) and the logical subscriber identity (the SIM profile).

SubscriptionManager

SubscriptionManager provides APIs to enumerate available subscriptions, determine the active data or voice SIM, and track changes to the SIM state (e.g., when a user inserts a new SIM or toggles an eSIM profile).

Each SIM is identified by a unique subscriptionId (subId). Most TelephonyManager APIs can be pinned to a specific subId to query state for that particular SIM.

SubscriptionManager subManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
List<SubscriptionInfo> activeSubs = subManager.getActiveSubscriptionInfoList();

for (SubscriptionInfo info : activeSubs) {
    int subId = info.getSubscriptionId();
    CharSequence carrierName = info.getCarrierName();
    
    // Create a TelephonyManager specific to this SIM
    TelephonyManager pinnedManager = telephonyManager.createForSubscriptionId(subId);
    int networkType = pinnedManager.getDataNetworkType();
}

Logical vs. Physical Slots

The framework maps physical SIM slots (or eSIM eUICCs) to logical phone instances.

  • Physical Slot Index: The hardware slot (0 or 1).
  • Logical Phone ID: The internal instance handling the modem interface.
  • Subscription ID: The unique identifier for the carrier profile.

The framework dynamically maps these entities as SIM cards are swapped or activated, ensuring that calls and data route to the correct modem context.

Core Telephony Services

Deep within the system_server (and the com.android.phone process), core services manage the telephony logic.

Phone Process and Phone Objects

The com.android.phone process is a persistent system application that houses the core telephony logic. Within this process, the framework instantiates Phone objects (e.g., GsmCdmaPhone).

A Phone object represents a single logical cellular connection and manages its own state machines for:

  • ServiceStateTracker (SST): Manages network registration, signal strength, and roaming state.
  • CallTracker: Manages voice call lifecycles (dialing, active, holding, disconnected).
  • DataConnectionTracker (DCT): Manages APN configurations and the setup/teardown of cellular data PDNs (Packet Data Networks).

Telecom Framework Integration

The Telephony framework does not render the call UI. It handles the modem signaling. When a call connects, the CallTracker communicates with the Telecom Framework (which manages all calls, including VoIP like WhatsApp). The Telecom framework then commands the default Dialer app (the InCallService) to display the incoming call screen.

Debugging Telephony

Telephony issues are notoriously difficult to debug due to dependency on carrier networks and closed-source modem firmware.

# Dump exhaustive telephony state, including active calls, data connections, and signal histories
adb shell dumpsys telephony.registry
adb shell dumpsys activity service TelephonyDebugService

For deeper analysis, engineers use carrier-specific logging tools or capture radio logs:

# Capture logs specifically from the radio buffer
adb logcat -b radio

The radio buffer contains the critical AT commands or proprietary IPC messages flowing between the Telephony framework (via RIL) and the modem, revealing exact network rejection causes or connection failures.