FileDocCategorySizeDatePackage
ProxyController.javaAPI DocAndroid 5.1 API25474Thu Mar 12 22:22:54 GMT 2015com.android.internal.telephony

ProxyController

public class ProxyController extends Object

Fields Summary
static final String
LOG_TAG
private static final int
EVENT_NOTIFICATION_RC_CHANGED
private static final int
EVENT_START_RC_RESPONSE
private static final int
EVENT_APPLY_RC_RESPONSE
private static final int
EVENT_FINISH_RC_RESPONSE
private static final int
SET_RC_STATUS_IDLE
private static final int
SET_RC_STATUS_STARTING
private static final int
SET_RC_STATUS_STARTED
private static final int
SET_RC_STATUS_APPLYING
private static final int
SET_RC_STATUS_SUCCESS
private static final int
SET_RC_STATUS_FAIL
private static final int
SET_RC_TIMEOUT_WAITING_MSEC
private static ProxyController
sProxyController
private com.android.internal.telephony.PhoneProxy[]
mProxyPhones
private com.android.internal.telephony.uicc.UiccController
mUiccController
private com.android.internal.telephony.CommandsInterface[]
mCi
private android.content.Context
mContext
private com.android.internal.telephony.dataconnection.DctController
mDctController
private UiccPhoneBookController
mUiccPhoneBookController
private PhoneSubInfoController
mPhoneSubInfoController
private UiccSmsController
mUiccSmsController
android.os.PowerManager.WakeLock
mWakeLock
private int[]
mSetRadioAccessFamilyStatus
private int
mRadioAccessFamilyStatusCounter
private String[]
mLogicalModemIds
private AtomicInteger
mUniqueIdGenerator
private int
mRadioCapabilitySessionId
private int[]
mNewRadioAccessFamily
private int[]
mOldRadioAccessFamily
RadioCapabilityRunnable
mSetRadioCapabilityRunnable
private android.os.Handler
mHandler
Constructors Summary
private ProxyController(android.content.Context context, com.android.internal.telephony.PhoneProxy[] phoneProxy, com.android.internal.telephony.uicc.UiccController uiccController, com.android.internal.telephony.CommandsInterface[] ci)

        logd("Constructor - Enter");

        mContext = context;
        mProxyPhones = phoneProxy;
        mUiccController = uiccController;
        mCi = ci;

        mDctController = DctController.makeDctController(phoneProxy);
        mUiccPhoneBookController = new UiccPhoneBookController(mProxyPhones);
        mPhoneSubInfoController = new PhoneSubInfoController(mProxyPhones);
        mUiccSmsController = new UiccSmsController(mProxyPhones);
        mSetRadioAccessFamilyStatus = new int[mProxyPhones.length];
        mNewRadioAccessFamily = new int[mProxyPhones.length];
        mOldRadioAccessFamily = new int[mProxyPhones.length];
        mLogicalModemIds = new String[mProxyPhones.length];

        // TODO Get logical modem ids assume its just the phoneId as a string for now
        for (int i = 0; i < mProxyPhones.length; i++) {
            mLogicalModemIds[i] = Integer.toString(i);
        }

        mSetRadioCapabilityRunnable = new RadioCapabilityRunnable();

        // wake lock for set radio capability
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
        mWakeLock.setReferenceCounted(false);

        // Clear to be sure we're in the initial state
        clearTransaction();
        for (int i = 0; i < mProxyPhones.length; i++) {
            mProxyPhones[i].registerForRadioCapabilityChanged(
                    mHandler, EVENT_NOTIFICATION_RC_CHANGED, null);
        }
        logd("Constructor - Exit");
    
Methods Summary
private booleancheckAllRadioCapabilitySuccess()

        synchronized(mSetRadioAccessFamilyStatus) {
            for (int i = 0; i < mProxyPhones.length; i++) {
                if (mSetRadioAccessFamilyStatus[i] == SET_RC_STATUS_FAIL) {
                    return false;
                }
            }
            return true;
        }
    
private voidclearTransaction()

        logd("clearTransaction");
        synchronized(mSetRadioAccessFamilyStatus) {
            for (int i = 0; i < mProxyPhones.length; i++) {
                logd("clearTransaction: phoneId=" + i + " status=IDLE");
                mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_IDLE;
                mOldRadioAccessFamily[i] = 0;
                mNewRadioAccessFamily[i] = 0;
            }

            if (mWakeLock.isHeld()) {
                mWakeLock.release();
            }
        }
    
private voidcompleteRadioCapabilityTransaction()

        // Create the intent to broadcast
        Intent intent;
        boolean success = checkAllRadioCapabilitySuccess();
        logd("onFinishRadioCapabilityResponse: success=" + success);
        if (success) {
            ArrayList<RadioAccessFamily> phoneRAFList = new ArrayList<RadioAccessFamily>();
            for (int i = 0; i < mProxyPhones.length; i++) {
                int raf = mProxyPhones[i].getRadioAccessFamily();
                logd("radioAccessFamily[" + i + "]=" + raf);
                RadioAccessFamily phoneRC = new RadioAccessFamily(i, raf);
                phoneRAFList.add(phoneRC);
            }
            intent = new Intent(TelephonyIntents.ACTION_SET_RADIO_CAPABILITY_DONE);
            intent.putParcelableArrayListExtra(TelephonyIntents.EXTRA_RADIO_ACCESS_FAMILY,
                    phoneRAFList);
        } else {
            intent = new Intent(TelephonyIntents.ACTION_SET_RADIO_CAPABILITY_FAILED);
        }

        // Reinitialize
        clearTransaction();

        // Broadcast that we're done
        mContext.sendBroadcast(intent);
    
public voiddisableDataConnectivity(int sub, android.os.Message dataCleanedUpMsg)

        mProxyPhones[sub].setInternalDataEnabled(false, dataCleanedUpMsg);
    
public voiddump(java.io.FileDescriptor fd, java.io.PrintWriter pw, java.lang.String[] args)

        try {
            mDctController.dump(fd, pw, args);
        } catch (Exception e) {
            e.printStackTrace();
        }
    
public voidenableDataConnectivity(int sub)

        mProxyPhones[sub].setInternalDataEnabled(true);
    
public static com.android.internal.telephony.ProxyControllergetInstance(android.content.Context context, com.android.internal.telephony.PhoneProxy[] phoneProxy, com.android.internal.telephony.uicc.UiccController uiccController, com.android.internal.telephony.CommandsInterface[] ci)


    //***** Class Methods
          
                
        if (sProxyController == null) {
            sProxyController = new ProxyController(context, phoneProxy, uiccController, ci);
        }
        return sProxyController;
    
public static com.android.internal.telephony.ProxyControllergetInstance()

        return sProxyController;
    
public intgetRadioAccessFamily(int phoneId)
Get phone radio type and access technology.

param
phoneId which phone you want to get
return
phone radio type and access technology for input phone ID

        if (phoneId >= mProxyPhones.length) {
            return RadioAccessFamily.RAF_UNKNOWN;
        } else {
            return mProxyPhones[phoneId].getRadioAccessFamily();
        }
    
public booleanisDataDisconnected(int subId)

        int phoneId = SubscriptionController.getInstance().getPhoneId(subId);

        if (phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount()) {
            Phone activePhone = mProxyPhones[phoneId].getActivePhone();
            return ((PhoneBase) activePhone).mDcTracker.isDisconnected();
        } else {
            return false;
        }
    
private voidissueFinish(int status, int sessionId)

        // Issue FINISH
        synchronized(mSetRadioAccessFamilyStatus) {
            for (int i = 0; i < mProxyPhones.length; i++) {
                if (mSetRadioAccessFamilyStatus[i] != SET_RC_STATUS_FAIL) {
                    logd("issueFinish: phoneId=" + i + " sessionId=" + sessionId
                            + " status=" + status);
                    sendRadioCapabilityRequest(
                        i,
                        sessionId,
                        RadioCapability.RC_PHASE_FINISH,
                        mOldRadioAccessFamily[i],
                        mLogicalModemIds[i],
                        status,
                        EVENT_FINISH_RC_RESPONSE);
                    if (status == RadioCapability.RC_STATUS_FAIL) {
                        logd("issueFinish: phoneId: " + i + " status: FAIL");
                        // At least one failed, mark them all failed.
                        mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_FAIL;
                    }
                } else {
                    logd("issueFinish: Ignore already FAIL, Phone" + i + " sessionId=" + sessionId
                            + " status=" + status);
                }
            }
        }
    
private voidlogd(java.lang.String string)

        Rlog.d(LOG_TAG, string);
    
private voidloge(java.lang.String string)

        Rlog.e(LOG_TAG, string);
    
private voidonApplyRadioCapabilityResponse(android.os.Message msg)
Handle APPLY response

param
msg obj field isa RadioCapability

        RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result;
        if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) {
            logd("onApplyRadioCapabilityResponse: Ignore session=" + mRadioCapabilitySessionId
                    + " rc=" + rc);
            return;
        }
        logd("onApplyRadioCapabilityResponse: rc=" + rc);
        if (((AsyncResult) msg.obj).exception != null) {
            synchronized (mSetRadioAccessFamilyStatus) {
                logd("onApplyRadioCapabilityResponse: Error response session=" + rc.getSession());
                int id = rc.getPhoneId();
                logd("onApplyRadioCapabilityResponse: phoneId=" + id + " status=FAIL");
                mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
            }
        } else {
            logd("onApplyRadioCapabilityResponse: Valid start expecting notification rc=" + rc);
        }
    
voidonFinishRadioCapabilityResponse(android.os.Message msg)
Handle the FINISH Phase response

param
msg obj field isa RadioCapability

        RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result;
        if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) {
            logd("onFinishRadioCapabilityResponse: Ignore session=" + mRadioCapabilitySessionId
                    + " rc=" + rc);
            return;
        }
        synchronized (mSetRadioAccessFamilyStatus) {
            logd(" onFinishRadioCapabilityResponse mRadioAccessFamilyStatusCounter="
                    + mRadioAccessFamilyStatusCounter);
            mRadioAccessFamilyStatusCounter--;
            if (mRadioAccessFamilyStatusCounter == 0) {
                completeRadioCapabilityTransaction();
            }
        }
    
private voidonNotificationRadioCapabilityChanged(android.os.Message msg)
Handle the notification unsolicited response associated with the APPLY

param
msg obj field isa RadioCapability

        RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result;
        if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) {
            logd("onNotificationRadioCapabilityChanged: Ignore session=" + mRadioCapabilitySessionId
                    + " rc=" + rc);
            return;
        }
        synchronized (mSetRadioAccessFamilyStatus) {
            logd("onNotificationRadioCapabilityChanged: rc=" + rc);
            // skip the overdue response by checking sessionId
            if (rc.getSession() != mRadioCapabilitySessionId) {
                logd("onNotificationRadioCapabilityChanged: Ignore session="
                        + mRadioCapabilitySessionId + " rc=" + rc);
                return;
            }

            int id = rc.getPhoneId();
            if ((((AsyncResult) msg.obj).exception != null) ||
                    (rc.getStatus() == RadioCapability.RC_STATUS_FAIL)) {
                logd("onNotificationRadioCapabilityChanged: phoneId=" + id + " status=FAIL");
                mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
            } else {
                logd("onNotificationRadioCapabilityChanged: phoneId=" + id + " status=SUCCESS");
                mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_SUCCESS;
            }

            mRadioAccessFamilyStatusCounter--;
            if (mRadioAccessFamilyStatusCounter == 0) {
                logd("onNotificationRadioCapabilityChanged: removing callback from handler");
                mHandler.removeCallbacks(mSetRadioCapabilityRunnable);
                resetRadioAccessFamilyStatusCounter();
                boolean success = checkAllRadioCapabilitySuccess();
                logd("onNotificationRadioCapabilityChanged: APPLY URC success=" + success);
                int status;
                if (success) {
                    status = RadioCapability.RC_STATUS_SUCCESS;
                } else {
                    status = RadioCapability.RC_STATUS_FAIL;
                }
                issueFinish(status, mRadioCapabilitySessionId);
            }
        }
    
private voidonStartRadioCapabilityResponse(android.os.Message msg)
Handle START response

param
msg obj field isa RadioCapability


                  
        
        synchronized (mSetRadioAccessFamilyStatus) {
            RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result;
            if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) {
                logd("onStartRadioCapabilityResponse: Ignore session=" + mRadioCapabilitySessionId
                        + " rc=" + rc);
                return;
            }
            mRadioAccessFamilyStatusCounter--;
            int id = rc.getPhoneId();
            if (((AsyncResult) msg.obj).exception != null) {
                logd("onStartRadioCapabilityResponse: Error response session=" + rc.getSession());
                logd("onStartRadioCapabilityResponse: phoneId=" + id + " status=FAIL");
                mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
            } else {
                logd("onStartRadioCapabilityResponse: phoneId=" + id + " status=STARTED");
                mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_STARTED;
            }

            if (mRadioAccessFamilyStatusCounter == 0) {
                resetRadioAccessFamilyStatusCounter();
                boolean success = checkAllRadioCapabilitySuccess();
                logd("onStartRadioCapabilityResponse: success=" + success);
                if (!success) {
                    issueFinish(RadioCapability.RC_STATUS_FAIL,
                            mRadioCapabilitySessionId);
                } else {
                    // All logical modem accepted the new radio access family, issue the APPLY
                    for (int i = 0; i < mProxyPhones.length; i++) {
                        sendRadioCapabilityRequest(
                            i,
                            mRadioCapabilitySessionId,
                            RadioCapability.RC_PHASE_APPLY,
                            mNewRadioAccessFamily[i],
                            mLogicalModemIds[i],
                            RadioCapability.RC_STATUS_NONE,
                            EVENT_APPLY_RC_RESPONSE);

                        logd("onStartRadioCapabilityResponse: phoneId=" + i + " status=APPLYING");
                        mSetRadioAccessFamilyStatus[i] = SET_RC_STATUS_APPLYING;
                    }
                }
            }
        }
    
public voidregisterForAllDataDisconnected(int subId, android.os.Handler h, int what, java.lang.Object obj)

        int phoneId = SubscriptionController.getInstance().getPhoneId(subId);

        if (phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount()) {
            mProxyPhones[phoneId].registerForAllDataDisconnected(h, what, obj);
        }
    
private voidresetRadioAccessFamilyStatusCounter()

        mRadioAccessFamilyStatusCounter = mProxyPhones.length;
    
private voidsendRadioCapabilityRequest(int phoneId, int sessionId, int rcPhase, int radioFamily, java.lang.String logicalModemId, int status, int eventId)

        RadioCapability requestRC = new RadioCapability(
                phoneId, sessionId, rcPhase, radioFamily, logicalModemId, status);
        mProxyPhones[phoneId].setRadioCapability(
                requestRC, mHandler.obtainMessage(eventId));
    
public booleansetRadioCapability(android.telephony.RadioAccessFamily[] rafs)
Set phone radio type and access technology for each phone.

param
rafs an RadioAccessFamily array to indicate all phone's new radio access family. The length of RadioAccessFamily must equal to phone count.
return
false if another session is already active and the request is rejected.

        if (rafs.length != mProxyPhones.length) {
            throw new RuntimeException("Length of input rafs must equal to total phone count");
        }

        // Check if there is any ongoing transaction and throw an exception if there
        // is one as this is a programming error.
        synchronized (mSetRadioAccessFamilyStatus) {
            for (int i = 0; i < mProxyPhones.length; i++) {
                logd("setRadioCapability: mSetRadioAccessFamilyStatus[" + i + "]="
                        + mSetRadioAccessFamilyStatus[i]);
                if (mSetRadioAccessFamilyStatus[i] != SET_RC_STATUS_IDLE) {
                    // TODO: The right behaviour is to cancel previous request and send this.
                    loge("setRadioCapability: Phone[" + i + "] is not idle. Rejecting request.");
                    return false;
                }
            }
        }

        // Clear to be sure we're in the initial state
        clearTransaction();

        // A new sessionId for this transaction
        mRadioCapabilitySessionId = mUniqueIdGenerator.getAndIncrement();

        // Keep a wake lock until we finish radio capability changed
        mWakeLock.acquire();

        // Start timer to make sure all phones respond within a specific time interval.
        // Will send FINISH if a timeout occurs.
        mSetRadioCapabilityRunnable.setTimeoutState(mRadioCapabilitySessionId);
        mHandler.postDelayed(mSetRadioCapabilityRunnable, SET_RC_TIMEOUT_WAITING_MSEC);

        synchronized (mSetRadioAccessFamilyStatus) {
            logd("setRadioCapability: new request session id=" + mRadioCapabilitySessionId);
            mRadioAccessFamilyStatusCounter = rafs.length;
            for (int i = 0; i < rafs.length; i++) {
                int phoneId = rafs[i].getPhoneId();
                logd("setRadioCapability: phoneId=" + phoneId + " status=STARTING");
                mSetRadioAccessFamilyStatus[phoneId] = SET_RC_STATUS_STARTING;
                mOldRadioAccessFamily[phoneId] = mProxyPhones[phoneId].getRadioAccessFamily();
                int requestedRaf = rafs[i].getRadioAccessFamily();
                // TODO Set the new radio access family to the maximum of the requested & supported
                // int supportedRaf = mProxyPhones[i].getSupportedRadioAccessFamily();
                // mNewRadioAccessFamily[phoneId] = requestedRaf & supportedRaf;
                mNewRadioAccessFamily[phoneId] = requestedRaf;
                logd("setRadioCapability: mOldRadioAccessFamily[" + phoneId + "]="
                        + mOldRadioAccessFamily[phoneId]);
                logd("setRadioCapability: mNewRadioAccessFamily[" + phoneId + "]="
                        + mNewRadioAccessFamily[phoneId]);
                sendRadioCapabilityRequest(
                        phoneId,
                        mRadioCapabilitySessionId,
                        RadioCapability.RC_PHASE_START,
                        mOldRadioAccessFamily[phoneId],
                        mLogicalModemIds[phoneId],
                        RadioCapability.RC_STATUS_NONE,
                        EVENT_START_RC_RESPONSE);
            }
        }

        return true;
    
public voidunregisterForAllDataDisconnected(int subId, android.os.Handler h)

        int phoneId = SubscriptionController.getInstance().getPhoneId(subId);

        if (phoneId >= 0 && phoneId < TelephonyManager.getDefault().getPhoneCount()) {
            mProxyPhones[phoneId].unregisterForAllDataDisconnected(h);
        }
    
public voidupdateCurrentCarrierInProvider(int sub)

        mProxyPhones[sub].updateCurrentCarrierInProvider();
    
public voidupdateDataConnectionTracker(int sub)

        mProxyPhones[sub].updateDataConnectionTracker();