script-astra/Android/Sdk/sources/android-35/com/android/internal/telephony/VoiceIndication.java
localadmin 4380f00a78 init
2025-01-20 18:15:20 +03:00

458 lines
21 KiB
Java

/*
* Copyright (C) 2021 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.internal.telephony;
import static android.telephony.TelephonyManager.HAL_SERVICE_VOICE;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CALL_RING;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_CALL_WAITING;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_INFO_REC;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_OTA_PROVISION_STATUS;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_EMERGENCY_NUMBER_LIST;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ON_SS;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ON_USSD;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESEND_INCALL_MUTE;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RINGBACK_TONE;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SRVCC_STATE_NOTIFY;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_CALL_SETUP;
import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_CC_ALPHA_NOTIFY;
import android.hardware.radio.voice.IRadioVoiceIndication;
import android.os.AsyncResult;
import android.telephony.emergency.EmergencyNumber;
import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
import com.android.internal.telephony.cdma.CdmaInformationRecords;
import com.android.internal.telephony.gsm.SsData;
import java.util.ArrayList;
import java.util.List;
/**
* Interface declaring unsolicited radio indications for voice APIs.
*/
public class VoiceIndication extends IRadioVoiceIndication.Stub {
private final RIL mRil;
public VoiceIndication(RIL ril) {
mRil = ril;
}
/**
* Ring indication for an incoming call (eg, RING or CRING event).
* The rate of these events is controlled by ro.telephony.call_ring.delay and has a default
* value of 3000 (3 seconds) if absent.
* @param indicationType Type of radio indication
* @param isGsm true for GSM & false for CDMA
* @param record CDMA signal information record
*/
public void callRing(int indicationType, boolean isGsm,
android.hardware.radio.voice.CdmaSignalInfoRecord record) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
char[] response = null;
// Ignore record for gsm
if (!isGsm) {
// TODO: Clean this up with a parcelable class for better self-documentation
response = new char[4];
response[0] = (char) (record.isPresent ? 1 : 0);
response[1] = (char) record.signalType;
response[2] = (char) record.alertPitch;
response[3] = (char) record.signal;
mRil.writeMetricsCallRing(response);
}
if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_CALL_RING, response);
if (mRil.mRingRegistrant != null) {
mRil.mRingRegistrant.notifyRegistrant(new AsyncResult(null, response, null));
}
}
/**
* Indicates when call state has changed. Redundant or extraneous invocations are tolerated.
* @param indicationType Type of radio indication
*/
public void callStateChanged(int indicationType) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED);
mRil.mCallStateRegistrants.notifyRegistrants();
}
/**
* Indicates when CDMA radio receives a call waiting indication.
* @param indicationType Type of radio indication
* @param callWaitingRecord Cdma CallWaiting information
*/
public void cdmaCallWaiting(int indicationType,
android.hardware.radio.voice.CdmaCallWaiting callWaitingRecord) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
// TODO: create a CdmaCallWaitingNotification constructor that takes in these fields to make
// sure no fields are missing
CdmaCallWaitingNotification notification = new CdmaCallWaitingNotification();
notification.number = callWaitingRecord.number;
notification.numberPresentation = CdmaCallWaitingNotification.presentationFromCLIP(
callWaitingRecord.numberPresentation);
notification.name = callWaitingRecord.name;
notification.namePresentation = notification.numberPresentation;
notification.isPresent = callWaitingRecord.signalInfoRecord.isPresent ? 1 : 0;
notification.signalType = callWaitingRecord.signalInfoRecord.signalType;
notification.alertPitch = callWaitingRecord.signalInfoRecord.alertPitch;
notification.signal = callWaitingRecord.signalInfoRecord.signal;
notification.numberType = callWaitingRecord.numberType;
notification.numberPlan = callWaitingRecord.numberPlan;
if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_CDMA_CALL_WAITING, notification);
mRil.mCallWaitingInfoRegistrants.notifyRegistrants(
new AsyncResult(null, notification, null));
}
/**
* Indicates when CDMA radio receives one or more info recs.
* @param indicationType Type of radio indication
* @param records New CDMA information
*/
public void cdmaInfoRec(int indicationType,
android.hardware.radio.voice.CdmaInformationRecord[] records) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
for (int i = 0; i < records.length; i++) {
android.hardware.radio.voice.CdmaInformationRecord record = records[i];
int id = record.name;
CdmaInformationRecords cdmaInformationRecords;
switch (id) {
case CdmaInformationRecords.RIL_CDMA_DISPLAY_INFO_REC:
case CdmaInformationRecords.RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
CdmaInformationRecords.CdmaDisplayInfoRec cdmaDisplayInfoRec =
new CdmaInformationRecords.CdmaDisplayInfoRec(id,
record.display[0].alphaBuf);
cdmaInformationRecords = new CdmaInformationRecords(cdmaDisplayInfoRec);
break;
case CdmaInformationRecords.RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
case CdmaInformationRecords.RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
case CdmaInformationRecords.RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
android.hardware.radio.voice.CdmaNumberInfoRecord numInfoRecord =
record.number[0];
CdmaInformationRecords.CdmaNumberInfoRec cdmaNumberInfoRec =
new CdmaInformationRecords.CdmaNumberInfoRec(id, numInfoRecord.number,
numInfoRecord.numberType, numInfoRecord.numberPlan,
numInfoRecord.pi, numInfoRecord.si);
cdmaInformationRecords = new CdmaInformationRecords(cdmaNumberInfoRec);
break;
case CdmaInformationRecords.RIL_CDMA_SIGNAL_INFO_REC:
android.hardware.radio.voice.CdmaSignalInfoRecord signalInfoRecord =
record.signal[0];
CdmaInformationRecords.CdmaSignalInfoRec cdmaSignalInfoRec =
new CdmaInformationRecords.CdmaSignalInfoRec(
signalInfoRecord.isPresent ? 1 : 0, signalInfoRecord.signalType,
signalInfoRecord.alertPitch, signalInfoRecord.signal);
cdmaInformationRecords = new CdmaInformationRecords(cdmaSignalInfoRec);
break;
case CdmaInformationRecords.RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
android.hardware.radio.voice.CdmaRedirectingNumberInfoRecord
redirectingNumberInfoRecord = record.redir[0];
CdmaInformationRecords.CdmaRedirectingNumberInfoRec
cdmaRedirectingNumberInfoRec =
new CdmaInformationRecords.CdmaRedirectingNumberInfoRec(
redirectingNumberInfoRecord.redirectingNumber.number,
redirectingNumberInfoRecord.redirectingNumber.numberType,
redirectingNumberInfoRecord.redirectingNumber.numberPlan,
redirectingNumberInfoRecord.redirectingNumber.pi,
redirectingNumberInfoRecord.redirectingNumber.si,
redirectingNumberInfoRecord.redirectingReason);
cdmaInformationRecords = new CdmaInformationRecords(
cdmaRedirectingNumberInfoRec);
break;
case CdmaInformationRecords.RIL_CDMA_LINE_CONTROL_INFO_REC:
android.hardware.radio.voice.CdmaLineControlInfoRecord lineControlInfoRecord =
record.lineCtrl[0];
CdmaInformationRecords.CdmaLineControlInfoRec cdmaLineControlInfoRec =
new CdmaInformationRecords.CdmaLineControlInfoRec(
lineControlInfoRecord.lineCtrlPolarityIncluded,
lineControlInfoRecord.lineCtrlToggle,
lineControlInfoRecord.lineCtrlReverse,
lineControlInfoRecord.lineCtrlPowerDenial);
cdmaInformationRecords = new CdmaInformationRecords(cdmaLineControlInfoRec);
break;
case CdmaInformationRecords.RIL_CDMA_T53_CLIR_INFO_REC:
CdmaInformationRecords.CdmaT53ClirInfoRec cdmaT53ClirInfoRec =
new CdmaInformationRecords.CdmaT53ClirInfoRec(record.clir[0].cause);
cdmaInformationRecords = new CdmaInformationRecords(cdmaT53ClirInfoRec);
break;
case CdmaInformationRecords.RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
android.hardware.radio.voice.CdmaT53AudioControlInfoRecord
audioControlInfoRecord = record.audioCtrl[0];
CdmaInformationRecords.CdmaT53AudioControlInfoRec cdmaT53AudioControlInfoRec =
new CdmaInformationRecords.CdmaT53AudioControlInfoRec(
audioControlInfoRecord.upLink,
audioControlInfoRecord.downLink);
cdmaInformationRecords = new CdmaInformationRecords(cdmaT53AudioControlInfoRec);
break;
default:
throw new RuntimeException("RIL_UNSOL_CDMA_INFO_REC: unsupported record. Got "
+ CdmaInformationRecords.idToString(id) + " ");
}
if (mRil.isLogOrTrace()) {
mRil.unsljLogRet(RIL_UNSOL_CDMA_INFO_REC, cdmaInformationRecords);
}
mRil.notifyRegistrantsCdmaInfoRec(cdmaInformationRecords);
}
}
/**
* Indicates when CDMA radio receives an update of the progress of an OTASP/OTAPA call.
* @param indicationType Type of radio indication
* @param status CDMA OTA provision status
*/
public void cdmaOtaProvisionStatus(int indicationType, int status) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
int[] response = new int[] {status};
if (mRil.isLogOrTrace()) {
mRil.unsljLogRet(RIL_UNSOL_CDMA_OTA_PROVISION_STATUS, response);
}
mRil.mOtaProvisionRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
}
/**
* Indicates current emergency number list.
* @param indicationType Type of radio indication
* @param emergencyNumberList Current list of emergency numbers known to radio
*/
public void currentEmergencyNumberList(int indicationType,
android.hardware.radio.voice.EmergencyNumber[] emergencyNumberList) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
List<EmergencyNumber> response = new ArrayList<>(emergencyNumberList.length);
for (android.hardware.radio.voice.EmergencyNumber enHal : emergencyNumberList) {
EmergencyNumber emergencyNumber = new EmergencyNumber(enHal.number,
MccTable.countryCodeForMcc(enHal.mcc), enHal.mnc, enHal.categories,
RILUtils.primitiveArrayToArrayList(enHal.urns), enHal.sources,
EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
response.add(emergencyNumber);
}
if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_EMERGENCY_NUMBER_LIST, response);
// Cache emergency number list from last indication.
mRil.cacheEmergencyNumberListIndication(response);
// Notify emergency number list from radio to registrants
mRil.mEmergencyNumberListRegistrants.notifyRegistrants(
new AsyncResult(null, response, null));
}
/**
* Indicates that the radio system selection module has autonomously entered emergency
* callback mode.
* @param indicationType Type of radio indication
*/
public void enterEmergencyCallbackMode(int indicationType) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE);
if (mRil.mEmergencyCallbackModeRegistrant != null) {
mRil.mEmergencyCallbackModeRegistrant.notifyRegistrant();
}
}
/**
* Indicates when Emergency Callback Mode ends. Indicates that the radio system selection module
* has proactively exited emergency callback mode.
* @param indicationType Type of radio indication
*/
public void exitEmergencyCallbackMode(int indicationType) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE);
mRil.mExitEmergencyCallbackModeRegistrants.notifyRegistrants();
}
/**
* Indicates that network doesn't have in-band information, need to play out-band tone.
* @param indicationType Type of radio indication
* @param start true = start play ringback tone, false = stop playing ringback tone
*/
public void indicateRingbackTone(int indicationType, boolean start) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
if (mRil.isLogOrTrace()) mRil.unsljLogvRet(RIL_UNSOL_RINGBACK_TONE, start);
mRil.mRingbackToneRegistrants.notifyRegistrants(new AsyncResult(null, start, null));
}
/**
* Indicates when Supplementary service(SS) response is received when DIAL/USSD/SS is changed to
* SS by call control.
* @param indicationType Type of radio indication
* @param ss StkCcUnsolSsResult
*/
public void onSupplementaryServiceIndication(int indicationType,
android.hardware.radio.voice.StkCcUnsolSsResult ss) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
int num;
SsData ssData = new SsData();
ssData.serviceType = ssData.ServiceTypeFromRILInt(ss.serviceType);
ssData.requestType = ssData.RequestTypeFromRILInt(ss.requestType);
ssData.teleserviceType = ssData.TeleserviceTypeFromRILInt(ss.teleserviceType);
ssData.serviceClass = ss.serviceClass; // This is service class sent in the SS request.
ssData.result = ss.result; // This is the result of the SS request.
if (ssData.serviceType.isTypeCF() && ssData.requestType.isTypeInterrogation()) {
android.hardware.radio.voice.CfData cfData = ss.cfData[0];
num = cfData.cfInfo.length;
ssData.cfInfo = new CallForwardInfo[num];
for (int i = 0; i < num; i++) {
android.hardware.radio.voice.CallForwardInfo cfInfo = cfData.cfInfo[i];
ssData.cfInfo[i] = new CallForwardInfo();
ssData.cfInfo[i].status = cfInfo.status;
ssData.cfInfo[i].reason = cfInfo.reason;
ssData.cfInfo[i].serviceClass = cfInfo.serviceClass;
ssData.cfInfo[i].toa = cfInfo.toa;
ssData.cfInfo[i].number = cfInfo.number;
ssData.cfInfo[i].timeSeconds = cfInfo.timeSeconds;
mRil.riljLog("[SS Data] CF Info " + i + " : " + ssData.cfInfo[i]);
}
} else {
android.hardware.radio.voice.SsInfoData ssInfo = ss.ssInfo[0];
num = ssInfo.ssInfo.length;
ssData.ssInfo = new int[num];
for (int i = 0; i < num; i++) {
ssData.ssInfo[i] = ssInfo.ssInfo[i];
mRil.riljLog("[SS Data] SS Info " + i + " : " + ssData.ssInfo[i]);
}
}
if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_ON_SS, ssData);
if (mRil.mSsRegistrant != null) {
mRil.mSsRegistrant.notifyRegistrant(new AsyncResult(null, ssData, null));
}
}
/**
* Indicates when a new USSD message is received. The USSD session is assumed to persist if the
* type code is REQUEST, otherwise the current session (if any) is assumed to have terminated.
* @param indicationType Type of radio indication
* @param ussdModeType USSD type code
* @param msg Message string in UTF-8, if applicable
*/
public void onUssd(int indicationType, int ussdModeType, String msg) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
if (mRil.isLogOrTrace()) mRil.unsljLogMore(RIL_UNSOL_ON_USSD, "" + ussdModeType);
// TODO: Clean this up with a parcelable class for better self-documentation
String[] resp = new String[]{"" + ussdModeType, msg};
if (mRil.mUSSDRegistrant != null) {
mRil.mUSSDRegistrant.notifyRegistrant(new AsyncResult(null, resp, null));
}
}
/**
* Indicates that framework/application must reset the uplink mute state.
* @param indicationType Type of radio indication
*/
public void resendIncallMute(int indicationType) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
if (mRil.isLogOrTrace()) mRil.unsljLog(RIL_UNSOL_RESEND_INCALL_MUTE);
mRil.mResendIncallMuteRegistrants.notifyRegistrants();
}
/**
* Indicates when Single Radio Voice Call Continuity (SRVCC) progress state has changed.
* @param indicationType Type of radio indication
* @param state New SRVCC State
*/
public void srvccStateNotify(int indicationType, int state) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
int[] response = new int[] {state};
if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_SRVCC_STATE_NOTIFY, response);
mRil.writeMetricsSrvcc(state);
mRil.mSrvccStateRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
}
/**
* Indicates when there is an ALPHA from UICC during Call Control.
* @param indicationType Type of radio indication
* @param alpha ALPHA string from UICC in UTF-8 format
*/
public void stkCallControlAlphaNotify(int indicationType, String alpha) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_STK_CC_ALPHA_NOTIFY, alpha);
if (mRil.mCatCcAlphaRegistrant != null) {
mRil.mCatCcAlphaRegistrant.notifyRegistrant(new AsyncResult(null, alpha, null));
}
}
/**
* Indicates when SIM wants application to setup a voice call.
* @param indicationType Type of radio indication
* @param timeout Timeout value in milliseconds for setting up voice call
*/
public void stkCallSetup(int indicationType, long timeout) {
mRil.processIndication(HAL_SERVICE_VOICE, indicationType);
if (mRil.isLogOrTrace()) mRil.unsljLogRet(RIL_UNSOL_STK_CALL_SETUP, timeout);
if (mRil.mCatCallSetUpRegistrant != null) {
mRil.mCatCallSetUpRegistrant.notifyRegistrant(new AsyncResult(null, timeout, null));
}
}
@Override
public String getInterfaceHash() {
return IRadioVoiceIndication.HASH;
}
@Override
public int getInterfaceVersion() {
return IRadioVoiceIndication.VERSION;
}
}