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

Commit dd52e437 authored by Kolja Dummann's avatar Kolja Dummann
Browse files

samsung ril: fix 2g/3g toggle while data call is running

this fixes a problem in the samsung modem code where the
modem is unable to switch the preferred networktype while
a data call is running. The modem might sent a wrong radio
type when the network type is switched during a datacall.
That caused some phones to crash cause they thought they
were CDMA instead of GSM.

This patch basicly does:

check if data connection is up -> disable dataconnection if up ->
wait for dataconnection down -> send request for network type ->
wait for result -> enable dataconnection again -> inform caller
that network type was switched

Change-Id: I940d08a0fcba87d741ebd62ebb00a93039ff8540
parent 7724d343
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -224,7 +224,7 @@ public class RIL extends BaseCommands implements CommandsInterface {
    RILSender mSender;
    Thread mReceiverThread;
    RILReceiver mReceiver;
    private Context mContext;
    protected Context mContext;
    WakeLock mWakeLock;
    int mWakeLockTimeout;
    // The number of requests pending to be sent out, it increases before calling
+121 −1
Original line number Diff line number Diff line
@@ -3,7 +3,12 @@ package com.android.internal.telephony;
import java.util.ArrayList;
import java.util.Collections;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.os.Message;
import android.os.AsyncResult;
import android.os.Parcel;
@@ -808,4 +813,119 @@ public SamsungRIL(Context context, int networkMode, int cdmaSubscription) {
                    + namePresentation;
        }
    }
    @Override
    public void setPreferredNetworkType(int networkType , Message response) {
		/* Samsung modem implementation does bad things when a datacall is running
		 * while switching the preferred networktype.
		 */
		ConnectivityManager cm =
            (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);

		if(cm.getMobileDataEnabled())
		{
			ConnectivityHandler handler = new ConnectivityHandler(mContext);
			handler.setPreferedNetworkType(networkType, response);
		} else {
			sendPreferedNetworktype(networkType, response);
		}
    }


	//Sends the real RIL request to the modem.
	private void sendPreferedNetworktype(int networkType, Message response) {
		RILRequest rr = RILRequest.obtain(
                RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, response);

        rr.mp.writeInt(1);
        rr.mp.writeInt(networkType);

        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                + " : " + networkType);

        send(rr);
	}
	/* private class that does the handling for the dataconnection
	 * dataconnection is done async, so we send the request for disabling it,
	 * wait for the response, set the prefered networktype and notify the
	 * real sender with its result.
	 */
	private class ConnectivityHandler extends Handler{

		private static final int MESSAGE_SET_PREFERRED_NETWORK_TYPE = 30;
		private Context mContext;
		private int mDesiredNetworkType;
		//the original message, we need it for calling back the original caller when done
		private Message mNetworktypeResponse;
		private ConnectivityBroadcastReceiver mConnectivityReceiver =  new ConnectivityBroadcastReceiver();

		public ConnectivityHandler(Context context)
		{
			mContext = context;
		}

		private void startListening() {
	        IntentFilter filter = new IntentFilter();
	        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
	        mContext.registerReceiver(mConnectivityReceiver, filter);
		}

		private synchronized void stopListening() {
	        mContext.unregisterReceiver(mConnectivityReceiver);
		}

		public void setPreferedNetworkType(int networkType, Message response)
		{
			Log.d(LOG_TAG, "Mobile Dataconnection is online setting it down");
			 mDesiredNetworkType = networkType;
			 mNetworktypeResponse = response;
			 ConnectivityManager cm =
                 (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
			 //start listening for the connectivity change broadcast
			 startListening();
			 cm.setMobileDataEnabled(false);
		}

		  @Override
		  public void handleMessage(Message msg) {
			  switch(msg.what) {
			  //networktype was set, now we can enable the dataconnection again
			  case MESSAGE_SET_PREFERRED_NETWORK_TYPE:
					ConnectivityManager cm =
			                   (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE);

					Log.d(LOG_TAG, "preferred NetworkType set upping Mobile Dataconnection");

					cm.setMobileDataEnabled(true);
					//everything done now call back that we have set the networktype
					AsyncResult.forMessage(mNetworktypeResponse, null, null);
					mNetworktypeResponse.sendToTarget();
					mNetworktypeResponse = null;
					break;
			  default:
			        throw new RuntimeException("unexpected event not handled");
			  }
		  }

			private class ConnectivityBroadcastReceiver extends BroadcastReceiver {

		        @Override
		        public void onReceive(Context context, Intent intent) {
		            String action = intent.getAction();
		            if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
		                Log.w(LOG_TAG, "onReceived() called with " + intent);
		                return;
		            }
		            boolean noConnectivity =
		                intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);

		            if (noConnectivity) {
						//Ok dataconnection is down, now set the networktype
						Log.w(LOG_TAG, "Mobile Dataconnection is now down setting preferred NetworkType");
						stopListening();
						sendPreferedNetworktype(mDesiredNetworkType, obtainMessage(MESSAGE_SET_PREFERRED_NETWORK_TYPE));
						mDesiredNetworkType = -1;
		            }
		        }
		    }
		}
	}