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

Commit 9c2a3be8 authored by Jaikumar Ganesh's avatar Jaikumar Ganesh
Browse files

Fix thread safety in DataConnectionTracker.

All the methods in DataConnectionTracker should be called only through
the handler. Fix this as trySetupData was being called in the broadcast receiver.

Tested: Airplane mode and GPRS retry.
parent 4ee0a751
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ public abstract class DataConnectionTracker extends Handler {
    protected static final int EVENT_NV_READY = 31;
    protected static final int EVENT_PS_RESTRICT_ENABLED = 32;
    protected static final int EVENT_PS_RESTRICT_DISABLED = 33;
    public static final int EVENT_CLEAN_UP_CONNECTION = 34;

    //***** Constants
    protected static final int RECONNECT_DELAY_INITIAL_MILLIS = 5 * 1000;
@@ -226,6 +227,7 @@ public abstract class DataConnectionTracker extends Handler {
    protected abstract void onDisconnectDone(AsyncResult ar);
    protected abstract void onVoiceCallStarted();
    protected abstract void onVoiceCallEnded();
    protected abstract void onCleanUpConnection(boolean tearDown, String reason);

  //***** Overridden from Handler
    public void handleMessage (Message msg) {
@@ -272,18 +274,17 @@ public abstract class DataConnectionTracker extends Handler {
                onVoiceCallEnded();
                break;

            case EVENT_CLEAN_UP_CONNECTION:
                boolean tearDown = (msg.arg1 == 0) ? false : true;
                onCleanUpConnection(tearDown, (String)msg.obj);
                break;

            default:
                Log.e("DATA", "Unidentified event = " + msg.what);
                break;
        }
    }

    /**
     * Simply tear down data connections due to radio off 
     * and don't setup again.
     */
    public abstract void cleanConnectionBeforeRadioOff();

    /**
     * Report the current state of data connectivity (enabled or disabled)
     * @return {@code false} if data connectivity has been explicitly disabled,
+7 −8
Original line number Diff line number Diff line
@@ -262,14 +262,6 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
        Log.d(LOG_TAG, "dataEnabled[DEFAULT_PROFILE]=" + dataEnabled[EXTERNAL_NETWORK_DEFAULT_ID]);
    }

    /**
     * Simply tear down data connections due to radio off
     * and don't setup again.
     */
    public void cleanConnectionBeforeRadioOff() {
        cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
    }

    /**
     * The data connection is expected to be setup while device
     *  1. has ruim card or non-volatile data store
@@ -821,6 +813,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
        }
    }

    /**
     * @override com.android.internal.telephony.DataConnectionTracker
     */
    protected void onCleanUpConnection(boolean tearDown, String reason) {
        cleanUpConnection(tearDown, reason);
    }

    private boolean tryAgain(FailCause cause) {
        return (cause != FailCause.RADIO_NOT_AVAILABLE)
            && (cause != FailCause.RADIO_OFF)
+7 −4
Original line number Diff line number Diff line
@@ -449,7 +449,10 @@ final class CdmaServiceStateTracker extends ServiceStateTracker {
                        (dcTracker.getAnyDataEnabled() ? 1 : 0) );
                EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_DATA_STATE_RADIO_OFF, val);
            }
            dcTracker.cleanConnectionBeforeRadioOff();
            Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
            msg.arg1 = 1; // tearDown is true
            msg.obj = CDMAPhone.REASON_RADIO_TURNED_OFF;
            sendMessage(msg);

            // Poll data state up to 15 times, with a 100ms delay
            // totaling 1.5 sec. Normal data disable action will finish in 100ms.
+30 −34
Original line number Diff line number Diff line
@@ -28,10 +28,9 @@ import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.INetStatService;
import android.os.Message;
import android.os.RemoteException;
@@ -42,7 +41,6 @@ import android.preference.PreferenceManager;
import android.provider.Checkin;
import android.provider.Settings;
import android.provider.Telephony;
import android.provider.Settings.SettingNotFoundException;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
@@ -52,11 +50,10 @@ import android.util.Log;

import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.DataConnection.FailCause;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.TelephonyEventLog;
import com.android.internal.telephony.DataConnection.FailCause;

import java.io.IOException;
import java.util.ArrayList;
@@ -177,9 +174,12 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {

                String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
                if (state == State.FAILED) {
                    cleanUpConnection(false, reason);
                    Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
                    msg.arg1 = 0; // tearDown is false
                    msg.obj = (String) reason;
                    sendMessage(msg);
                }
                trySetupData(reason);
                sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                final android.net.NetworkInfo networkInfo = (NetworkInfo)
                        intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
@@ -495,14 +495,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
        }
    }

    /**
     * Simply tear down data connections due to radio off 
     * and don't setup again.
     */
    public void cleanConnectionBeforeRadioOff() {
        cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
    }

    /**
     * Report the current state of data connectivity (enabled or disabled) for
     * the default APN.
@@ -1416,6 +1408,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
        }
    }

    protected void onCleanUpConnection(boolean tearDown, String reason) {
        cleanUpConnection(tearDown, reason);
    }

    private boolean tryNextApn(FailCause cause) {
        return (cause != FailCause.RADIO_NOT_AVAILABLE)
                && (cause != FailCause.RADIO_OFF)
+11 −12
Original line number Diff line number Diff line
@@ -16,7 +16,13 @@

package com.android.internal.telephony.gsm;

import com.android.internal.telephony.Phone;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ALPHA;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISROAMING;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_NUMERIC;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
@@ -50,21 +56,11 @@ import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;
import com.android.internal.telephony.TelephonyIntents;

import static com.android.internal.telephony.TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ALPHA;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISROAMING;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_NUMERIC;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
@@ -541,7 +537,10 @@ final class GsmServiceStateTracker extends ServiceStateTracker {
                        (dcTracker.getAnyDataEnabled() ? 1 : 0) );
                EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_DATA_STATE_RADIO_OFF, val);
            }
            dcTracker.cleanConnectionBeforeRadioOff();
            Message msg = dcTracker.obtainMessage(DataConnectionTracker.EVENT_CLEAN_UP_CONNECTION);
            msg.arg1 = 1; // tearDown is true
            msg.obj = GSMPhone.REASON_RADIO_TURNED_OFF;
            sendMessage(msg);

            // poll data state up to 15 times, with a 100ms delay
            // totaling 1.5 sec. Normal data disable action will finish in 100ms.