package org.thoughtcrime.redphone.pstn; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.ResultReceiver; import android.telephony.TelephonyManager; import android.util.Log; import org.thoughtcrime.redphone.RedPhoneService; import org.thoughtcrime.securesms.service.WebRtcCallService; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Listens for incoming PSTN calls and rejects them if a RedPhone call is already in progress. * * Unstable use of reflection employed to gain access to ITelephony. * */ public class IncomingPstnCallReceiver extends BroadcastReceiver { private static final String TAG = IncomingPstnCallReceiver.class.getName(); @Override public void onReceive(Context context, Intent intent) { Log.w(TAG, "Checking incoming call..."); if (intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER) == null) { Log.w(TAG, "Telephony event does not contain number..."); return; } if (!intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) { Log.w(TAG, "Telephony event is not state rining..."); return; } InCallListener listener = new InCallListener(context, new Handler()); WebRtcCallService.isCallActive(context, listener); RedPhoneService.isCallActive(context, listener); } private static class InCallListener extends ResultReceiver { private final Context context; InCallListener(Context context, Handler handler) { super(handler); this.context = context.getApplicationContext(); } protected void onReceiveResult(int resultCode, Bundle resultData) { if (resultCode == 1) { Log.w(TAG, "Attempting to deny incoming PSTN call."); TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); try { Method getTelephony = tm.getClass().getDeclaredMethod("getITelephony"); getTelephony.setAccessible(true); Object telephonyService = getTelephony.invoke(tm); Method endCall = telephonyService.getClass().getDeclaredMethod("endCall"); endCall.invoke(telephonyService); Log.w(TAG, "Denied Incoming Call."); } catch (NoSuchMethodException e) { Log.w(TAG, "Unable to access ITelephony API", e); } catch (IllegalAccessException e) { Log.w(TAG, "Unable to access ITelephony API", e); } catch (InvocationTargetException e) { Log.w(TAG, "Unable to access ITelephony API", e); } } } } }