blob: 86a2c8f7c64f7fef3015310276521eba0beabd9d [file] [log] [blame]
/*
* 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 android.telephony.cts;
import android.hardware.radio.RadioError;
import android.hardware.radio.RadioIndicationType;
import android.hardware.radio.RadioResponseInfo;
import android.hardware.radio.config.IRadioConfig;
import android.hardware.radio.config.IRadioConfigIndication;
import android.hardware.radio.config.IRadioConfigResponse;
import android.hardware.radio.config.PhoneCapability;
import android.hardware.radio.config.SimSlotStatus;
import android.hardware.radio.config.SlotPortMapping;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
public class IRadioConfigImpl extends IRadioConfig.Stub {
private static final String TAG = "MRCFG";
private final MockModemService mService;
private IRadioConfigResponse mRadioConfigResponse;
private IRadioConfigIndication mRadioConfigIndication;
private static MockModemConfigInterface[] sMockModemConfigInterfaces;
private Object mCacheUpdateMutex;
private final Handler mHandler;
private int mSubId;
// ***** Events
static final int EVENT_NUM_OF_LIVE_MODEM_CHANGED = 1;
static final int EVENT_PHONE_CAPABILITY_CHANGED = 2;
static final int EVENT_SIM_SLOT_STATUS_CHANGED = 3;
// ***** Cache of modem attributes/status
private int mSlotNum = 1;
private byte mNumOfLiveModems = 1;
private PhoneCapability mPhoneCapability = new PhoneCapability();
private SimSlotStatus[] mSimSlotStatus;
public IRadioConfigImpl(
MockModemService service, MockModemConfigInterface[] interfaces, int instanceId) {
Log.d(TAG, "Instantiated");
this.mService = service;
sMockModemConfigInterfaces = interfaces;
mSlotNum = mService.getNumPhysicalSlots();
mSimSlotStatus = new SimSlotStatus[mSlotNum];
mCacheUpdateMutex = new Object();
mHandler = new IRadioConfigHandler();
mSubId = instanceId;
// Register events
sMockModemConfigInterfaces[mSubId].registerForNumOfLiveModemChanged(
mHandler, EVENT_NUM_OF_LIVE_MODEM_CHANGED, null);
sMockModemConfigInterfaces[mSubId].registerForPhoneCapabilityChanged(
mHandler, EVENT_PHONE_CAPABILITY_CHANGED, null);
sMockModemConfigInterfaces[mSubId].registerForSimSlotStatusChanged(
mHandler, EVENT_SIM_SLOT_STATUS_CHANGED, null);
}
/** Handler class to handle callbacks */
private final class IRadioConfigHandler extends Handler {
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
synchronized (mCacheUpdateMutex) {
switch (msg.what) {
case EVENT_NUM_OF_LIVE_MODEM_CHANGED:
Log.d(TAG, "Received EVENT_NUM_OF_LIVE_MODEM_CHANGED");
ar = (AsyncResult) msg.obj;
if (ar != null && ar.exception == null) {
mNumOfLiveModems = (byte) ar.result;
Log.i(TAG, "Number of live modem: " + mNumOfLiveModems);
} else {
Log.e(TAG, msg.what + " failure. Exception: " + ar.exception);
}
break;
case EVENT_PHONE_CAPABILITY_CHANGED:
Log.d(TAG, "Received EVENT_PHONE_CAPABILITY_CHANGED");
ar = (AsyncResult) msg.obj;
if (ar != null && ar.exception == null) {
mPhoneCapability = (PhoneCapability) ar.result;
Log.i(TAG, "Phone capability: " + mPhoneCapability);
} else {
Log.e(TAG, msg.what + " failure. Exception: " + ar.exception);
}
break;
case EVENT_SIM_SLOT_STATUS_CHANGED:
Log.d(TAG, "Received EVENT_SIM_SLOT_STATUS_CHANGED");
ar = (AsyncResult) msg.obj;
if (ar != null && ar.exception == null) {
mSimSlotStatus = (SimSlotStatus[]) ar.result;
for (int i = 0; i < mSlotNum; i++) {
Log.i(TAG, "Sim slot status: " + mSimSlotStatus[i]);
}
unsolSimSlotsStatusChanged();
} else {
Log.e(TAG, msg.what + " failure. Exception: " + ar.exception);
}
break;
}
}
}
}
// Implementation of IRadioConfig functions
@Override
public void getHalDeviceCapabilities(int serial) {
Log.d(TAG, "getHalDeviceCapabilities");
boolean modemReducedFeatureSet1 = false;
RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
try {
mRadioConfigResponse.getHalDeviceCapabilitiesResponse(rsp, modemReducedFeatureSet1);
} catch (RemoteException ex) {
Log.e(
TAG,
"Failed to invoke getHalDeviceCapabilitiesResponse from AIDL. Exception" + ex);
}
}
@Override
public void getNumOfLiveModems(int serial) {
Log.d(TAG, "getNumOfLiveModems");
byte numoflivemodem;
synchronized (mCacheUpdateMutex) {
numoflivemodem = mNumOfLiveModems;
}
RadioResponseInfo rsp = mService.makeSolRsp(serial);
try {
mRadioConfigResponse.getNumOfLiveModemsResponse(rsp, numoflivemodem);
} catch (RemoteException ex) {
Log.e(TAG, "Failed to invoke getNumOfLiveModemsResponse from AIDL. Exception" + ex);
}
}
@Override
public void getPhoneCapability(int serial) {
Log.d(TAG, "getPhoneCapability");
PhoneCapability phoneCapability;
synchronized (mCacheUpdateMutex) {
phoneCapability = mPhoneCapability;
}
RadioResponseInfo rsp = mService.makeSolRsp(serial);
try {
mRadioConfigResponse.getPhoneCapabilityResponse(rsp, phoneCapability);
} catch (RemoteException ex) {
Log.e(TAG, "Failed to invoke getPhoneCapabilityResponse from AIDL. Exception" + ex);
}
}
@Override
public void getSimSlotsStatus(int serial) {
Log.d(TAG, "getSimSlotsStatus");
SimSlotStatus[] slotStatus;
synchronized (mCacheUpdateMutex) {
if (mSlotNum < 1) {
Log.d(TAG, "No slot information is retured.");
slotStatus = null;
} else {
slotStatus = mSimSlotStatus;
}
}
RadioResponseInfo rsp = mService.makeSolRsp(serial);
try {
mRadioConfigResponse.getSimSlotsStatusResponse(rsp, slotStatus);
} catch (RemoteException ex) {
Log.e(TAG, "Failed to invoke getSimSlotsStatusResponse from AIDL. Exception" + ex);
}
}
@Override
public void setNumOfLiveModems(int serial, byte numOfLiveModems) {
Log.d(TAG, "setNumOfLiveModems");
// TODO: cache value
RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
try {
mRadioConfigResponse.setNumOfLiveModemsResponse(rsp);
} catch (RemoteException ex) {
Log.e(TAG, "Failed to invoke setNumOfLiveModemsResponse from AIDL. Exception" + ex);
}
}
@Override
public void setPreferredDataModem(int serial, byte modemId) {
Log.d(TAG, "setPreferredDataModem");
// TODO: cache value
RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
try {
mRadioConfigResponse.setPreferredDataModemResponse(rsp);
} catch (RemoteException ex) {
Log.e(TAG, "Failed to invoke setPreferredDataModemResponse from AIDL. Exception" + ex);
}
}
@Override
public void setResponseFunctions(
IRadioConfigResponse radioConfigResponse,
IRadioConfigIndication radioConfigIndication) {
Log.d(TAG, "setResponseFunctions");
mRadioConfigResponse = radioConfigResponse;
mRadioConfigIndication = radioConfigIndication;
mService.countDownLatch(MockModemService.LATCH_RADIO_INTERFACES_READY);
}
@Override
public void setSimSlotsMapping(int serial, SlotPortMapping[] slotMap) {
Log.d(TAG, "setSimSlotsMapping");
// TODO: cache value
RadioResponseInfo rsp = mService.makeSolRsp(serial, RadioError.REQUEST_NOT_SUPPORTED);
try {
mRadioConfigResponse.setSimSlotsMappingResponse(rsp);
} catch (RemoteException ex) {
Log.e(TAG, "Failed to invoke setSimSlotsMappingResponse from AIDL. Exception" + ex);
}
}
public void unsolSimSlotsStatusChanged() {
Log.d(TAG, "unsolSimSlotsStatusChanged");
SimSlotStatus[] slotStatus;
if (mRadioConfigIndication != null) {
synchronized (mCacheUpdateMutex) {
if (mSlotNum < 1) {
Log.d(TAG, "No slot information is retured.");
slotStatus = null;
} else {
slotStatus = mSimSlotStatus;
}
}
try {
mRadioConfigIndication.simSlotsStatusChanged(
RadioIndicationType.UNSOLICITED, slotStatus);
} catch (RemoteException ex) {
Log.e(TAG, "Failed to invoke simSlotsStatusChanged from AIDL. Exception" + ex);
}
} else {
Log.e(TAG, "null mRadioConfigIndication");
}
}
}