401 lines
16 KiB
Java
401 lines
16 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_DATA;
|
|
import static android.telephony.TelephonyManager.HAL_SERVICE_IMS;
|
|
import static android.telephony.TelephonyManager.HAL_SERVICE_MESSAGING;
|
|
import static android.telephony.TelephonyManager.HAL_SERVICE_MODEM;
|
|
import static android.telephony.TelephonyManager.HAL_SERVICE_NETWORK;
|
|
import static android.telephony.TelephonyManager.HAL_SERVICE_SIM;
|
|
import static android.telephony.TelephonyManager.HAL_SERVICE_VOICE;
|
|
|
|
import android.content.ComponentName;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.ServiceConnection;
|
|
import android.os.IBinder;
|
|
|
|
import com.android.telephony.Rlog;
|
|
|
|
/** This class provides wrapper APIs for binding interfaces to mock service. */
|
|
public class MockModem {
|
|
private static final String TAG = "MockModem";
|
|
private static final String BIND_IRADIOMODEM = "android.telephony.mockmodem.iradiomodem";
|
|
private static final String BIND_IRADIOSIM = "android.telephony.mockmodem.iradiosim";
|
|
private static final String BIND_IRADIOMESSAGING =
|
|
"android.telephony.mockmodem.iradiomessaging";
|
|
private static final String BIND_IRADIODATA = "android.telephony.mockmodem.iradiodata";
|
|
private static final String BIND_IRADIONETWORK = "android.telephony.mockmodem.iradionetwork";
|
|
private static final String BIND_IRADIOVOICE = "android.telephony.mockmodem.iradiovoice";
|
|
private static final String BIND_IRADIOIMS = "android.telephony.mockmodem.iradioims";
|
|
private static final String BIND_IRADIOCONFIG = "android.telephony.mockmodem.iradioconfig";
|
|
private static final String PHONE_ID = "phone_id";
|
|
|
|
private static final byte DEFAULT_PHONE_ID = 0x00;
|
|
|
|
static final int RADIOCONFIG_SERVICE = RIL.MAX_SERVICE_IDX + 1;
|
|
|
|
static final int BINDER_RETRY_MILLIS = 3 * 100;
|
|
static final int BINDER_MAX_RETRY = 10;
|
|
|
|
private Context mContext;
|
|
private String mServiceName;
|
|
private String mPackageName;
|
|
|
|
private IBinder mModemBinder;
|
|
private IBinder mSimBinder;
|
|
private IBinder mMessagingBinder;
|
|
private IBinder mDataBinder;
|
|
private IBinder mNetworkBinder;
|
|
private IBinder mVoiceBinder;
|
|
private IBinder mImsBinder;
|
|
private IBinder mConfigBinder;
|
|
private ServiceConnection mModemServiceConnection;
|
|
private ServiceConnection mSimServiceConnection;
|
|
private ServiceConnection mMessagingServiceConnection;
|
|
private ServiceConnection mDataServiceConnection;
|
|
private ServiceConnection mNetworkServiceConnection;
|
|
private ServiceConnection mVoiceServiceConnection;
|
|
private ServiceConnection mImsServiceConnection;
|
|
private ServiceConnection mConfigServiceConnection;
|
|
|
|
private byte mPhoneId;
|
|
private String mTag;
|
|
|
|
MockModem(Context context, String serviceName) {
|
|
this(context, serviceName, 0);
|
|
}
|
|
|
|
MockModem(Context context, String serviceName, int phoneId) {
|
|
mPhoneId = (byte) phoneId;
|
|
mTag = TAG + "-" + mPhoneId;
|
|
mContext = context;
|
|
String[] componentInfo = serviceName.split("/", 2);
|
|
mPackageName = componentInfo[0];
|
|
mServiceName = componentInfo[1];
|
|
}
|
|
|
|
private class MockModemConnection implements ServiceConnection {
|
|
private int mService;
|
|
|
|
MockModemConnection(int module) {
|
|
mService = module;
|
|
}
|
|
|
|
@Override
|
|
public void onServiceConnected(ComponentName name, IBinder binder) {
|
|
Rlog.d(mTag, "IRadio " + getModuleName(mService) + " - onServiceConnected");
|
|
|
|
if (mService == HAL_SERVICE_MODEM) {
|
|
mModemBinder = binder;
|
|
} else if (mService == HAL_SERVICE_SIM) {
|
|
mSimBinder = binder;
|
|
} else if (mService == HAL_SERVICE_MESSAGING) {
|
|
mMessagingBinder = binder;
|
|
} else if (mService == HAL_SERVICE_DATA) {
|
|
mDataBinder = binder;
|
|
} else if (mService == HAL_SERVICE_NETWORK) {
|
|
mNetworkBinder = binder;
|
|
} else if (mService == HAL_SERVICE_VOICE) {
|
|
mVoiceBinder = binder;
|
|
} else if (mService == HAL_SERVICE_IMS) {
|
|
mImsBinder = binder;
|
|
} else if (mService == RADIOCONFIG_SERVICE) {
|
|
mConfigBinder = binder;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onServiceDisconnected(ComponentName name) {
|
|
Rlog.d(mTag, "IRadio " + getModuleName(mService) + " - onServiceDisconnected");
|
|
|
|
if (mService == HAL_SERVICE_MODEM) {
|
|
mModemBinder = null;
|
|
} else if (mService == HAL_SERVICE_SIM) {
|
|
mSimBinder = null;
|
|
} else if (mService == HAL_SERVICE_MESSAGING) {
|
|
mMessagingBinder = null;
|
|
} else if (mService == HAL_SERVICE_DATA) {
|
|
mDataBinder = null;
|
|
} else if (mService == HAL_SERVICE_NETWORK) {
|
|
mNetworkBinder = null;
|
|
} else if (mService == HAL_SERVICE_VOICE) {
|
|
mVoiceBinder = null;
|
|
} else if (mService == HAL_SERVICE_IMS) {
|
|
mImsBinder = null;
|
|
} else if (mService == RADIOCONFIG_SERVICE) {
|
|
mConfigBinder = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean bindModuleToMockModemService(
|
|
String actionName, ServiceConnection serviceConnection) {
|
|
return bindModuleToMockModemService(DEFAULT_PHONE_ID, actionName, serviceConnection);
|
|
}
|
|
|
|
private boolean bindModuleToMockModemService(
|
|
byte phoneId, String actionName, ServiceConnection serviceConnection) {
|
|
boolean status = false;
|
|
|
|
Intent intent = new Intent();
|
|
intent.setComponent(new ComponentName(mPackageName, mServiceName));
|
|
intent.setAction(actionName + phoneId);
|
|
intent.putExtra(PHONE_ID, phoneId);
|
|
|
|
status = mContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
|
|
return status;
|
|
}
|
|
|
|
/** waitForBinder */
|
|
public IBinder getServiceBinder(int service) {
|
|
switch (service) {
|
|
case HAL_SERVICE_MODEM:
|
|
return mModemBinder;
|
|
case HAL_SERVICE_SIM:
|
|
return mSimBinder;
|
|
case HAL_SERVICE_MESSAGING:
|
|
return mMessagingBinder;
|
|
case HAL_SERVICE_DATA:
|
|
return mDataBinder;
|
|
case HAL_SERVICE_NETWORK:
|
|
return mNetworkBinder;
|
|
case HAL_SERVICE_VOICE:
|
|
return mVoiceBinder;
|
|
case HAL_SERVICE_IMS:
|
|
return mImsBinder;
|
|
case RADIOCONFIG_SERVICE:
|
|
return mConfigBinder;
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/** Binding interfaces with mock modem service */
|
|
public void bindAllMockModemService() {
|
|
for (int service = RIL.MIN_SERVICE_IDX; service <= RIL.MAX_SERVICE_IDX; service++) {
|
|
bindToMockModemService(service);
|
|
}
|
|
}
|
|
|
|
/** bindToMockModemService */
|
|
public void bindToMockModemService(int service) {
|
|
if (service == RADIOCONFIG_SERVICE) {
|
|
if (mConfigBinder == null) {
|
|
mConfigServiceConnection = new MockModemConnection(RADIOCONFIG_SERVICE);
|
|
|
|
boolean status =
|
|
bindModuleToMockModemService(BIND_IRADIOCONFIG, mConfigServiceConnection);
|
|
if (!status) {
|
|
Rlog.d(mTag, "IRadio Config bind fail");
|
|
mConfigServiceConnection = null;
|
|
}
|
|
} else {
|
|
Rlog.d(mTag, "IRadio Config is bound");
|
|
}
|
|
} else if (service == HAL_SERVICE_MODEM) {
|
|
if (mModemBinder == null) {
|
|
mModemServiceConnection = new MockModemConnection(HAL_SERVICE_MODEM);
|
|
|
|
boolean status =
|
|
bindModuleToMockModemService(
|
|
mPhoneId, BIND_IRADIOMODEM, mModemServiceConnection);
|
|
if (!status) {
|
|
Rlog.d(mTag, "IRadio Modem bind fail");
|
|
mModemServiceConnection = null;
|
|
}
|
|
} else {
|
|
Rlog.d(mTag, "IRadio Modem is bound");
|
|
}
|
|
} else if (service == HAL_SERVICE_SIM) {
|
|
if (mSimBinder == null) {
|
|
mSimServiceConnection = new MockModemConnection(HAL_SERVICE_SIM);
|
|
|
|
boolean status =
|
|
bindModuleToMockModemService(
|
|
mPhoneId, BIND_IRADIOSIM, mSimServiceConnection);
|
|
if (!status) {
|
|
Rlog.d(mTag, "IRadio Sim bind fail");
|
|
mSimServiceConnection = null;
|
|
}
|
|
} else {
|
|
Rlog.d(mTag, "IRadio Sim is bound");
|
|
}
|
|
} else if (service == HAL_SERVICE_MESSAGING) {
|
|
if (mMessagingBinder == null) {
|
|
mMessagingServiceConnection = new MockModemConnection(HAL_SERVICE_MESSAGING);
|
|
|
|
boolean status =
|
|
bindModuleToMockModemService(
|
|
mPhoneId, BIND_IRADIOMESSAGING, mMessagingServiceConnection);
|
|
if (!status) {
|
|
Rlog.d(mTag, "IRadio Messaging bind fail");
|
|
mMessagingServiceConnection = null;
|
|
}
|
|
} else {
|
|
Rlog.d(mTag, "IRadio Messaging is bound");
|
|
}
|
|
} else if (service == HAL_SERVICE_DATA) {
|
|
if (mDataBinder == null) {
|
|
mDataServiceConnection = new MockModemConnection(HAL_SERVICE_DATA);
|
|
|
|
boolean status =
|
|
bindModuleToMockModemService(
|
|
mPhoneId, BIND_IRADIODATA, mDataServiceConnection);
|
|
if (!status) {
|
|
Rlog.d(mTag, "IRadio Data bind fail");
|
|
mDataServiceConnection = null;
|
|
}
|
|
} else {
|
|
Rlog.d(mTag, "IRadio Data is bound");
|
|
}
|
|
} else if (service == HAL_SERVICE_NETWORK) {
|
|
if (mNetworkBinder == null) {
|
|
mNetworkServiceConnection = new MockModemConnection(HAL_SERVICE_NETWORK);
|
|
|
|
boolean status =
|
|
bindModuleToMockModemService(
|
|
mPhoneId, BIND_IRADIONETWORK, mNetworkServiceConnection);
|
|
if (!status) {
|
|
Rlog.d(mTag, "IRadio Network bind fail");
|
|
mNetworkServiceConnection = null;
|
|
}
|
|
} else {
|
|
Rlog.d(mTag, "IRadio Network is bound");
|
|
}
|
|
} else if (service == HAL_SERVICE_VOICE) {
|
|
if (mVoiceBinder == null) {
|
|
mVoiceServiceConnection = new MockModemConnection(HAL_SERVICE_VOICE);
|
|
|
|
boolean status =
|
|
bindModuleToMockModemService(
|
|
mPhoneId, BIND_IRADIOVOICE, mVoiceServiceConnection);
|
|
if (!status) {
|
|
Rlog.d(mTag, "IRadio Voice bind fail");
|
|
mVoiceServiceConnection = null;
|
|
}
|
|
} else {
|
|
Rlog.d(mTag, "IRadio Voice is bound");
|
|
}
|
|
} else if (service == HAL_SERVICE_IMS) {
|
|
if (mImsBinder == null) {
|
|
mImsServiceConnection = new MockModemConnection(HAL_SERVICE_IMS);
|
|
|
|
boolean status =
|
|
bindModuleToMockModemService(
|
|
mPhoneId, BIND_IRADIOIMS, mImsServiceConnection);
|
|
if (!status) {
|
|
Rlog.d(TAG, "IRadio Ims bind fail");
|
|
mImsServiceConnection = null;
|
|
}
|
|
} else {
|
|
Rlog.d(TAG, "IRadio Ims is bound");
|
|
}
|
|
}
|
|
}
|
|
|
|
/** unbindMockModemService */
|
|
public void unbindMockModemService(int service) {
|
|
|
|
if (service == RADIOCONFIG_SERVICE) {
|
|
if (mConfigServiceConnection != null) {
|
|
mContext.unbindService(mConfigServiceConnection);
|
|
mConfigServiceConnection = null;
|
|
mConfigBinder = null;
|
|
Rlog.d(mTag, "unbind IRadio Config");
|
|
}
|
|
} else if (service == HAL_SERVICE_MODEM) {
|
|
if (mModemServiceConnection != null) {
|
|
mContext.unbindService(mModemServiceConnection);
|
|
mModemServiceConnection = null;
|
|
mModemBinder = null;
|
|
Rlog.d(mTag, "unbind IRadio Modem");
|
|
}
|
|
} else if (service == HAL_SERVICE_SIM) {
|
|
if (mSimServiceConnection != null) {
|
|
mContext.unbindService(mSimServiceConnection);
|
|
mSimServiceConnection = null;
|
|
mSimBinder = null;
|
|
Rlog.d(mTag, "unbind IRadio Sim");
|
|
}
|
|
} else if (service == HAL_SERVICE_MESSAGING) {
|
|
if (mMessagingServiceConnection != null) {
|
|
mContext.unbindService(mMessagingServiceConnection);
|
|
mMessagingServiceConnection = null;
|
|
mMessagingBinder = null;
|
|
Rlog.d(mTag, "unbind IRadio Messaging");
|
|
}
|
|
} else if (service == HAL_SERVICE_DATA) {
|
|
if (mDataServiceConnection != null) {
|
|
mContext.unbindService(mDataServiceConnection);
|
|
mDataServiceConnection = null;
|
|
mDataBinder = null;
|
|
Rlog.d(mTag, "unbind IRadio Data");
|
|
}
|
|
} else if (service == HAL_SERVICE_NETWORK) {
|
|
if (mNetworkServiceConnection != null) {
|
|
mContext.unbindService(mNetworkServiceConnection);
|
|
mNetworkServiceConnection = null;
|
|
mNetworkBinder = null;
|
|
Rlog.d(mTag, "unbind IRadio Network");
|
|
}
|
|
} else if (service == HAL_SERVICE_VOICE) {
|
|
if (mVoiceServiceConnection != null) {
|
|
mContext.unbindService(mVoiceServiceConnection);
|
|
mVoiceServiceConnection = null;
|
|
mVoiceBinder = null;
|
|
Rlog.d(mTag, "unbind IRadio Voice");
|
|
}
|
|
} else if (service == HAL_SERVICE_IMS) {
|
|
if (mImsServiceConnection != null) {
|
|
mContext.unbindService(mImsServiceConnection);
|
|
mImsServiceConnection = null;
|
|
mImsBinder = null;
|
|
Rlog.d(TAG, "unbind IRadio Ims");
|
|
}
|
|
}
|
|
}
|
|
|
|
public String getServiceName() {
|
|
return mServiceName;
|
|
}
|
|
|
|
private String getModuleName(int service) {
|
|
switch (service) {
|
|
case HAL_SERVICE_MODEM:
|
|
return "modem";
|
|
case HAL_SERVICE_SIM:
|
|
return "sim";
|
|
case HAL_SERVICE_MESSAGING:
|
|
return "messaging";
|
|
case HAL_SERVICE_DATA:
|
|
return "data";
|
|
case HAL_SERVICE_NETWORK:
|
|
return "network";
|
|
case HAL_SERVICE_VOICE:
|
|
return "voice";
|
|
case HAL_SERVICE_IMS:
|
|
return "ims";
|
|
case RADIOCONFIG_SERVICE:
|
|
return "config";
|
|
default:
|
|
return "none";
|
|
}
|
|
}
|
|
}
|