FileDocCategorySizeDatePackage
OutgoingCallBroadcaster.javaAPI DocAndroid 1.5 API5715Wed May 06 22:42:46 BST 2009com.android.phone

OutgoingCallBroadcaster

public class OutgoingCallBroadcaster extends android.app.Activity
OutgoingCallBroadcaster receives CALL Intents and sends out broadcast Intents that allow other applications to monitor, redirect, or prevent the outgoing call. If not aborted, the broadcasts will reach {@link OutgoingCallReceiver}, and be passed on to {@link InCallScreen}. Emergency calls and calls to voicemail when no number is present are exempt from being broadcast.

Fields Summary
private static final String
PERMISSION
private static final String
TAG
private static final boolean
LOGV
public static final String
EXTRA_ALREADY_CALLED
public static final String
EXTRA_ORIGINAL_URI
private com.android.internal.telephony.Phone
mPhone
Constructors Summary
Methods Summary
protected voidonCreate(android.os.Bundle icicle)


    
        
        super.onCreate(icicle);

        mPhone = PhoneApp.getInstance().phone;

        Intent intent = getIntent();
        if (LOGV) Log.v(TAG, "onResume: Got intent " + intent + ".");

        String action = intent.getAction();
        String number = PhoneNumberUtils.getNumberFromIntent(intent, this);
        if (number != null) {
            number = PhoneNumberUtils.convertKeypadLettersToDigits(number);
            number = PhoneNumberUtils.stripSeparators(number);
        }
        final boolean emergencyNumber =
                (number != null) && PhoneNumberUtils.isEmergencyNumber(number);

        boolean callNow;

        if (getClass().getName().equals(intent.getComponent().getClassName())) {
            // If we were launched directly from the OutgoingCallBroadcaster,
            // not one of its more privileged aliases, then make sure that
            // only the non-privileged actions are allowed.
            if (!Intent.ACTION_CALL.equals(intent.getAction())) {
                Log.w(TAG, "Attempt to deliver non-CALL action; forcing to CALL");
                intent.setAction(Intent.ACTION_CALL);
            }
        }
        
        /* Change CALL_PRIVILEGED into CALL or CALL_EMERGENCY as needed. */
        if (Intent.ACTION_CALL_PRIVILEGED.equals(action)) {
            action = emergencyNumber
                    ? Intent.ACTION_CALL_EMERGENCY
                    : Intent.ACTION_CALL;
            intent.setAction(action);
        }

        if (Intent.ACTION_CALL.equals(action)) {
            if (emergencyNumber) {
                Log.w(TAG, "Cannot call emergency number " + number
                        + " with CALL Intent " + intent + ".");
                finish();
                return;
            }
            callNow = false;
        } else if (Intent.ACTION_CALL_EMERGENCY.equals(action)) {
            if (!emergencyNumber) {
                Log.w(TAG, "Cannot call non-emergency number " + number
                        + " with EMERGENCY_CALL Intent " + intent + ".");
                finish();
                return;
            }
            callNow = true;
        } else {
            Log.e(TAG, "Unhandled Intent " + intent + ".");
            finish();
            return;
        }

        // Make sure the screen is turned on.  This is probably the right
        // thing to do, and more importantly it works around an issue in the
        // activity manager where we will not launch activities consistently
        // when the screen is off (since it is trying to keep them paused
        // and has...  issues).
        //
        // Also, this ensures the device stays awake while doing the following
        // broadcast; technically we should be holding a wake lock here
        // as well.
        PhoneApp.getInstance().wakeUpScreen();
        
        /* If number is null, we're probably trying to call a non-existent voicemail number or
         * something else fishy.  Whatever the problem, there's no number, so there's no point
         * in allowing apps to modify the number. */
        if (number == null) callNow = true;

        if (callNow) {
            intent.setClass(this, InCallScreen.class);
            startActivity(intent);
        }

        Intent broadcastIntent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL);
        if (number != null) broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, number);
        broadcastIntent.putExtra(EXTRA_ALREADY_CALLED, callNow);
        broadcastIntent.putExtra(EXTRA_ORIGINAL_URI, intent.getData().toString());
        if (LOGV) Log.v(TAG, "Broadcasting intent " + broadcastIntent + ".");
        sendOrderedBroadcast(broadcastIntent, PERMISSION, null, null,
                             Activity.RESULT_OK, number, null);

        finish();