Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 28e00762 authored by Nazanin Bakhshi's avatar Nazanin Bakhshi Committed by Gerrit Code Review
Browse files

Merge "Add telephony API to switch multi sim config"

parents fad70353 cede6544
Loading
Loading
Loading
Loading
+99 −5
Original line number Diff line number Diff line
@@ -17,7 +17,10 @@
package com.android.internal.telephony;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.SystemProperties;
import android.telephony.PhoneCapability;
import android.telephony.Rlog;
import android.telephony.TelephonyManager;
@@ -30,12 +33,19 @@ import android.util.Log;
 * if they change, and and sends commands to modem to enable or disable phones.
 */
public class PhoneConfigurationManager {
    public static final String DSDA = "dsda";
    public static final String DSDS = "dsds";
    public static final String TSTS = "tsts";
    public static final String SSSS = "";
    private static final String LOG_TAG = "PhoneCfgMgr";
    private static final int EVENT_SWITCH_DSDS_CONFIG_DONE = 100;

    private static PhoneConfigurationManager sInstance = null;
    private final Context mContext;
    private PhoneCapability mStaticCapability;
    private PhoneCapability mCurrentCapability;
    private final RadioConfig mRadioConfig;
    private final MainThreadHandler mHandler;

    /**
     * Init method to instantiate the object
@@ -60,10 +70,10 @@ public class PhoneConfigurationManager {
        mContext = context;
        // TODO: send commands to modem once interface is ready.
        TelephonyManager telephonyManager = new TelephonyManager(context);
        mStaticCapability = telephonyManager.getPhoneCount() == 1
                ? PhoneConfigurationModels.SSSS_CAPABILITY
                : PhoneConfigurationModels.DSDS_CAPABILITY;
        mStaticCapability = PhoneConfigurationModels.DSDS_CAPABILITY;
        mCurrentCapability = mStaticCapability;
        mRadioConfig = RadioConfig.getInstance(mContext);
        mHandler = new MainThreadHandler();

        notifyCapabilityChanged();
    }
@@ -79,6 +89,24 @@ public class PhoneConfigurationManager {
        return sInstance;
    }

    /**
     * Handler class to handle callbacks
     */
    private final class MainThreadHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case EVENT_SWITCH_DSDS_CONFIG_DONE:
                    if (msg.obj != null) {
                        int numOfLiveModems = msg.arg1;
                        setMultiSimProperties(numOfLiveModems);
                    } else {
                        log(msg.what + " failure. Not switching multi-sim config.");
                    }
                    break;
            }
        }
    }

    /**
     * Enable or disable phone
@@ -105,7 +133,6 @@ public class PhoneConfigurationManager {

    /**
     * get static overall phone capabilities for all phones.
     *
     */
    public PhoneCapability getStaticPhoneCapability() {
        return mStaticCapability;
@@ -113,7 +140,6 @@ public class PhoneConfigurationManager {

    /**
     * get configuration related status of each phone.
     *
     */
    public PhoneCapability getCurrentPhoneCapability() {
        return mCurrentCapability;
@@ -129,6 +155,74 @@ public class PhoneConfigurationManager {
        notifier.notifyPhoneCapabilityChanged(mCurrentCapability);
    }

    /**
     * Switch configs to enable multi-sim or switch back to single-sim
     * @param numOfSims number of active sims we want to switch to
     */
    public void switchMultiSimConfig(int numOfSims) {
        if (getStaticPhoneCapability().logicalModemList.size() < numOfSims) {
            log("switchMultiSimConfig: Phone is not capable of enabling "
                    + numOfSims + " sims, exiting!");
            return;
        }
        if (getNumOfActiveSims() != numOfSims) {
            Message callback = Message.obtain(
                    mHandler, EVENT_SWITCH_DSDS_CONFIG_DONE, numOfSims);
            mRadioConfig.setModemsConfig(numOfSims, callback);
        } else {
            log("switchMultiSimConfig: No need to switch. getNumOfActiveSims is already "
                    + numOfSims);
        }
    }

    /**
     * Get how many sims have been activated on the phone
     * NOTE: In order to support more than 3 sims, we need to change this method.
     */
    public int getNumOfActiveSims() {
        String mSimConfig =
                SystemProperties.get(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG);
        int numOfSims;
        switch (mSimConfig) {
            case TSTS:
                numOfSims = 3;
                break;
            case DSDA:
            case DSDS:
                numOfSims = 2;
                break;
            default:
                numOfSims = 1;
        }
        return numOfSims;
    }

    /**
     * Helper method to set system properties for setting multi sim configs,
     * as well as doing the phone reboot
     * NOTE: In order to support more than 3 sims, we need to change this method.
     * @param numOfSims number of active sims
     */
    private void setMultiSimProperties(int numOfSims) {
        String finalMultiSimConfig;
        switch(numOfSims) {
            case 3:
                finalMultiSimConfig = TSTS;
                break;
            case 2:
                finalMultiSimConfig = DSDS;
                break;
            default:
                finalMultiSimConfig = SSSS;
        }

        SystemProperties.set(TelephonyProperties.PROPERTY_MULTI_SIM_CONFIG, finalMultiSimConfig);
        log("setMultiSimProperties: Rebooting due to switching multi-sim config to "
                + finalMultiSimConfig);
        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        pm.reboot("Switching to " + finalMultiSimConfig);
    }

    private static void log(String s) {
        Rlog.d(LOG_TAG, s);
    }
+35 −0
Original line number Diff line number Diff line
@@ -23,11 +23,13 @@ import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SLOT_S
import static com.android.internal.telephony.RILConstants
        .RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_PREFERRED_DATA_MODEM;
import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG;

import android.content.Context;
import android.hardware.radio.V1_0.RadioResponseInfo;
import android.hardware.radio.V1_0.RadioResponseType;
import android.hardware.radio.config.V1_0.IRadioConfig;
import android.hardware.radio.config.V1_1.ModemsConfig;
import android.net.ConnectivityManager;
import android.os.AsyncResult;
import android.os.Handler;
@@ -395,11 +397,44 @@ public class RadioConfig extends Handler {
                return "GET_SLOT_STATUS";
            case RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING:
                return "SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING";
            case RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG:
                return "RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG";
            default:
                return "<unknown request>";
        }
    }

    /**
     * Wrapper function for using IRadioConfig.setModemsConfig(int32_t serial,
     * ModemsConfig modemsConfig) to switch between single-sim and multi-sim.
     */
    public void setModemsConfig(int numOfLiveModems, Message result) {
        IRadioConfig radioConfigProxy = getRadioConfigProxy(result);
        if (radioConfigProxy != null
                && mRadioConfigVersion.greaterOrEqual(RADIO_CONFIG_HAL_VERSION_1_1)) {
            android.hardware.radio.config.V1_1.IRadioConfig radioConfigProxy11 =
                    (android.hardware.radio.config.V1_1.IRadioConfig) radioConfigProxy;
            RILRequest rr = obtainRequest(RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG,
                    result, mDefaultWorkSource);

            if (DBG) {
                logd(rr.serialString() + "> " + requestToString(rr.mRequest)
                        + "numOfLiveModems = " + numOfLiveModems);
            }

            try {
                ModemsConfig modemsConfig = new ModemsConfig();
                modemsConfig.numOfLiveModems = (byte) numOfLiveModems;
                radioConfigProxy11.setModemsConfig(rr.mSerial, modemsConfig);
            } catch (RemoteException | RuntimeException e) {
                resetProxyAndRequestList("setModemsConfig", e);
            }
        }
    }

    // TODO: not needed for now, but if we don't want to use System Properties any more,
    // we need to implement a wrapper function for getModemsConfig as well

    /**
     * Register a handler to get SIM slot status changed notifications.
     */
+38 −6
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.internal.telephony;

import android.hardware.radio.V1_0.RadioError;
import android.hardware.radio.V1_0.RadioResponseInfo;
import android.hardware.radio.config.V1_1.ModemsConfig;
import android.hardware.radio.config.V1_2.IRadioConfigResponse;
import android.telephony.ModemInfo;
import android.telephony.PhoneCapability;
@@ -32,9 +33,10 @@ import java.util.List;
 * This class is the implementation of IRadioConfigResponse interface.
 */
public class RadioConfigResponse extends IRadioConfigResponse.Stub {
    private final RadioConfig mRadioConfig;
    private static final String TAG = "RadioConfigResponse";

    private final RadioConfig mRadioConfig;

    public RadioConfigResponse(RadioConfig radioConfig) {
        mRadioConfig = radioConfig;
    }
@@ -178,18 +180,48 @@ public class RadioConfigResponse extends IRadioConfigResponse.Stub {

    /**
     * Response function for IRadioConfig.setModemsConfigResponse()
     *
     * Currently this is being used as the callback for RadioConfig.setModemsConfig() method
     */
    public void setModemsConfigResponse(RadioResponseInfo info) {
    public void setModemsConfigResponse(RadioResponseInfo responseInfo) {
        RILRequest rr = mRadioConfig.processResponse(responseInfo);

        if (rr != null) {
            if (responseInfo.error == RadioError.NONE) {
                // send response
                RadioResponse.sendMessageResponse(rr.mResult, rr.mRequest);
                Rlog.d(TAG, rr.serialString() + "< "
                        + mRadioConfig.requestToString(rr.mRequest));
            } else {
                rr.onError(responseInfo.error, null);
                Rlog.e(TAG, rr.serialString() + "< "
                        + mRadioConfig.requestToString(rr.mRequest) + " error "
                        + responseInfo.error);
            }
        } else {
            Rlog.e(TAG, "setModemsConfigResponse: Error " + responseInfo.toString());
        }
    }

    /**
     * Response function for IRadioConfig.getModemsConfigResponse()
     *
     */
    public void getModemsConfigResponse(RadioResponseInfo info,
            android.hardware.radio.config.V1_1.ModemsConfig modemsConfig) {
    public void getModemsConfigResponse(RadioResponseInfo responseInfo, ModemsConfig modemsConfig) {
        RILRequest rr = mRadioConfig.processResponse(responseInfo);

        if (rr != null) {
            if (responseInfo.error == RadioError.NONE) {
                // send response
                RadioResponse.sendMessageResponse(rr.mResult, modemsConfig);
                Rlog.d(TAG, rr.serialString() + "< "
                        + mRadioConfig.requestToString(rr.mRequest));
            } else {
                rr.onError(responseInfo.error, modemsConfig);
                Rlog.e(TAG, rr.serialString() + "< "
                        + mRadioConfig.requestToString(rr.mRequest) + " error "
                        + responseInfo.error);
            }
        } else {
            Rlog.e(TAG, "getModemsConfigResponse: Error " + responseInfo.toString());
        }
    }
}