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

Commit fa2944d9 authored by Yong Zhang's avatar Yong Zhang Committed by Wink Saville
Browse files

Replace loop-delay in setPowerStateToDesired() with async approach

Issues to be addressed:
The method setPowerStateToDesired() in CdmaServiceStateTracker class sends
a msg to CdmaDataConnectionTracker class to deactive data call, and then starts
a loop which calls SystemClock.sleep() to wait for several seconds.The purpose
of this is to wait for data-disconnection before sending RADIO_POWER off request.
However, the CdmaServiceStateTracker and CdmaDataConnectionTracker are running in
the same process so that the CdmaDataConnectionTracker is not able to process the
message to deactive data before the loop ends.

The patch includes the following changes:
1) In setPowerStateToDesired() in CdmaServiceStateTracker, replace implementation
   of loop-delay by sending a delayed msg to set RADIO_POWER off.

2) In CdmaDataConnectionTracker, when getting EVENT_DISCONNECT_DONE, call a new
   method in CdmaServiceStateTracker to process pending request to turn RADIO_POWER
   off.
parent e6a9bcb7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ public abstract class ServiceStateTracker extends Handler {
    protected static final int EVENT_NV_READY                          = 35;
    protected static final int EVENT_ERI_FILE_LOADED                   = 36;
    protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE       = 37;
    protected static final int EVENT_SET_RADIO_POWER_OFF               = 38;

    //***** Time Zones
    protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
+5 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import com.android.internal.telephony.DataConnection.FailCause;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.RetryManager;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;

import java.util.ArrayList;
@@ -770,6 +771,10 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
            reason = (String) ar.userObj;
        }
        setState(State.IDLE);

        CdmaServiceStateTracker ssTracker = mCdmaPhone.mSST;
        ssTracker.processPendingRadioPowerOffAfterDataOff();

        phone.notifyDataConnection(reason);
        if (retryAfterDisconnected(reason)) {
          trySetupData(reason);
+45 −12
Original line number Diff line number Diff line
@@ -131,6 +131,8 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
    private boolean isEriTextLoaded = false;
    private boolean isSubscriptionFromRuim = false;

    private boolean mPendingRadioPowerOffAfterDataOff = false;

    // Registration Denied Reason, General/Authentication Failure, used only for debugging purposes
    private String mRegistrationDeniedReason;

@@ -520,6 +522,16 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
            }
            break;

        case EVENT_SET_RADIO_POWER_OFF:
            synchronized(this) {
                if (mPendingRadioPowerOffAfterDataOff) {
                    if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
                    cm.setRadioPower(false, null);
                    mPendingRadioPowerOffAfterDataOff = false;
                }
            }
            break;

        default:
            Log.e(LOG_TAG, "Unhandled message with number: " + msg.what);
        break;
@@ -548,20 +560,23 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
            msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF;
            dcTracker.sendMessage(msg);

            // Poll data state up to 50 times, with a 100ms delay
            // totaling 5 sec.
            // TODO: change the 5 seconds wait from blocking to non-blocking.
            for (int i = 0; i < 50; i++) {
            synchronized(this) {
                if (!mPendingRadioPowerOffAfterDataOff) {
                    DataConnectionTracker.State currentState = dcTracker.getState();
                    if (currentState != DataConnectionTracker.State.CONNECTED
                            && currentState != DataConnectionTracker.State.DISCONNECTING) {
                    if (DBG) log("Data shutdown complete.");
                    break;
                }
                SystemClock.sleep(DATA_STATE_POLL_SLEEP_MS);
                        if (DBG) log("Data disconnected, turn off radio right away.");
                        cm.setRadioPower(false, null);
                    }
            // If it's on and available and we want it off..
                    else if (sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF, 5000)) {
                        if (DBG) log("Wait 5 sec for data to be disconnected, then turn off radio.");
                        mPendingRadioPowerOffAfterDataOff = true;
                    } else {
                        Log.w(LOG_TAG, "Cannot send delayed Msg, turn off radio right away.");
                        cm.setRadioPower(false, null);
                    }
                }
            }
        } // Otherwise, we're in the desired state
    }

@@ -1582,4 +1597,22 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
    public boolean isMinInfoReady() {
        return mIsMinInfoReady;
    }

    /**
     * process the pending request to turn radio off after data is disconnected
     *
     * return true if there is pending request to process; false otherwise.
     */
    public boolean processPendingRadioPowerOffAfterDataOff() {
        synchronized(this) {
            if (mPendingRadioPowerOffAfterDataOff) {
                if (DBG) log("Process pending request to turn radio off.");
                removeMessages(EVENT_SET_RADIO_POWER_OFF);
                cm.setRadioPower(false, null);
                mPendingRadioPowerOffAfterDataOff = false;
                return true;
            }
            return false;
        }
    }
}