summaryrefslogtreecommitdiffstats
path: root/src/com/android/phone/SipCallOptionHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/phone/SipCallOptionHandler.java')
-rw-r--r--src/com/android/phone/SipCallOptionHandler.java499
1 files changed, 0 insertions, 499 deletions
diff --git a/src/com/android/phone/SipCallOptionHandler.java b/src/com/android/phone/SipCallOptionHandler.java
deleted file mode 100644
index 47c5702d3..000000000
--- a/src/com/android/phone/SipCallOptionHandler.java
+++ /dev/null
@@ -1,499 +0,0 @@
-/**
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.phone;
-
-import com.android.internal.telephony.CallManager;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.phone.sip.SipProfileDb;
-import com.android.phone.sip.SipSettings;
-import com.android.phone.sip.SipSharedPreferences;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.Uri;
-import android.net.sip.SipException;
-import android.net.sip.SipManager;
-import android.net.sip.SipProfile;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.TextView;
-
-import java.util.List;
-
-/**
- * Activity that selects the proper phone type for an outgoing call.
- *
- * This activity determines which Phone type (SIP or PSTN) should be used
- * for an outgoing phone call, depending on the outgoing "number" (which
- * may be either a PSTN number or a SIP address) as well as the user's SIP
- * preferences. In some cases this activity has no interaction with the
- * user, but in other cases it may (by bringing up a dialog if the user's
- * preference is "Ask for each call".)
- */
-public class SipCallOptionHandler extends Activity implements
- DialogInterface.OnClickListener, DialogInterface.OnCancelListener,
- CompoundButton.OnCheckedChangeListener {
- static final String TAG = "SipCallOptionHandler";
- private static final boolean DBG =
- (PhoneGlobals.DBG_LEVEL >= 1) && (SystemProperties.getInt("ro.debuggable", 0) == 1);
-
- static final int DIALOG_SELECT_PHONE_TYPE = 0;
- static final int DIALOG_SELECT_OUTGOING_SIP_PHONE = 1;
- static final int DIALOG_START_SIP_SETTINGS = 2;
- static final int DIALOG_NO_INTERNET_ERROR = 3;
- static final int DIALOG_NO_VOIP = 4;
- static final int DIALOG_SELECT_WIFI_CALL = 5;
- static final int DIALOG_SIZE = 6;
-
- private Intent mIntent;
- private List<SipProfile> mProfileList;
- private String mCallOption;
- private String mNumber;
- private SipSharedPreferences mSipSharedPreferences;
- private SipProfileDb mSipProfileDb;
- private Dialog[] mDialogs = new Dialog[DIALOG_SIZE];
- private SipProfile mOutgoingSipProfile;
- private TextView mUnsetPriamryHint;
- private boolean mUseSipPhone = false;
- private boolean mMakePrimary = false;
- private ComponentName mThirdPartyCallComponent;
-
- private static final int EVENT_DELAYED_FINISH = 1;
-
- private static final int DELAYED_FINISH_TIME = 2000; // msec
-
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == EVENT_DELAYED_FINISH) {
- finish();
- } else {
- Log.wtf(TAG, "Unknown message id: " + msg.what);
- }
- }
- };
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- Intent intent = getIntent();
- String action = intent.getAction();
-
- // This activity is only ever launched with the
- // ACTION_SIP_SELECT_PHONE action.
- if (!OutgoingCallBroadcaster.ACTION_SIP_SELECT_PHONE.equals(action)) {
- Log.wtf(TAG, "onCreate: got intent action '" + action + "', expected "
- + OutgoingCallBroadcaster.ACTION_SIP_SELECT_PHONE);
- finish();
- return;
- }
-
- // mIntent is a copy of the original CALL intent that started the
- // whole outgoing-call sequence. This intent will ultimately be
- // passed to CallController.placeCall() after displaying the SIP
- // call options dialog (if necessary).
- mIntent = (Intent) intent.getParcelableExtra(OutgoingCallBroadcaster.EXTRA_NEW_CALL_INTENT);
- if (mIntent == null) {
- finish();
- return;
- }
-
- // Allow this activity to be visible in front of the keyguard.
- // (This is only necessary for obscure scenarios like the user
- // initiating a call and then immediately pressing the Power
- // button.)
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
-
- // If we're trying to make a SIP call, return a SipPhone if one is
- // available.
- //
- // - If it's a sip: URI, this is definitely a SIP call, regardless
- // of whether the data is a SIP address or a regular phone
- // number.
- //
- // - If this is a tel: URI but the data contains an "@" character
- // (see PhoneNumberUtils.isUriNumber()) we consider that to be a
- // SIP number too.
- //
- // TODO: Eventually we may want to disallow that latter case
- // (e.g. "tel:foo@example.com").
- //
- // TODO: We should also consider moving this logic into the
- // CallManager, where it could be made more generic.
- // (For example, each "telephony provider" could be allowed
- // to register the URI scheme(s) that it can handle, and the
- // CallManager would then find the best match for every
- // outgoing call.)
-
- boolean voipSupported = PhoneUtils.isVoipSupported();
- if (DBG) Log.v(TAG, "voipSupported: " + voipSupported);
- mSipProfileDb = new SipProfileDb(this);
- mSipSharedPreferences = new SipSharedPreferences(this);
- mCallOption = mSipSharedPreferences.getSipCallOption();
- if (DBG) Log.v(TAG, "Call option: " + mCallOption);
- Uri uri = mIntent.getData();
- String scheme = uri.getScheme();
- mNumber = PhoneNumberUtils.getNumberFromIntent(mIntent, this);
- boolean isInCellNetwork = PhoneGlobals.getInstance().phoneMgr.isRadioOn();
- boolean isKnownCallScheme = Constants.SCHEME_TEL.equals(scheme)
- || Constants.SCHEME_SIP.equals(scheme);
- boolean isRegularCall = Constants.SCHEME_TEL.equals(scheme)
- && !PhoneNumberUtils.isUriNumber(mNumber);
-
- // Bypass the handler if the call scheme is not sip or tel.
- if (!isKnownCallScheme) {
- setResultAndFinish();
- return;
- }
-
- // Check if VoIP feature is supported.
- if (!voipSupported) {
- if (!isRegularCall) {
- showDialog(DIALOG_NO_VOIP);
- }
- return;
- }
-
- // Since we are not sure if anyone has touched the number during
- // the NEW_OUTGOING_CALL broadcast, we just check if the provider
- // put their gateway information in the intent. If so, it means
- // someone has changed the destination number. We then make the
- // call via the default pstn network. However, if one just alters
- // the destination directly, then we still let it go through the
- // Internet call option process.
- if (!CallGatewayManager.hasPhoneProviderExtras(mIntent)) {
- if (!isNetworkConnected()) {
- if (!isRegularCall) {
- showDialog(DIALOG_NO_INTERNET_ERROR);
- return;
- }
- } else {
- if (mCallOption.equals(Settings.System.SIP_ASK_ME_EACH_TIME)
- && isRegularCall && isInCellNetwork) {
- showDialog(DIALOG_SELECT_PHONE_TYPE);
- return;
- }
- if (!mCallOption.equals(Settings.System.SIP_ADDRESS_ONLY)
- || !isRegularCall) {
- mUseSipPhone = true;
- }
- }
- }
-
- if (mUseSipPhone) {
- // If there is no sip profile and it is a regular call, then we
- // should use pstn network instead.
- if ((mSipProfileDb.getProfilesCount() > 0) || !isRegularCall) {
- startGetPrimarySipPhoneThread();
- return;
- } else {
- mUseSipPhone = false;
- }
- setResultAndFinish();
- }
- }
-
- /**
- * Starts a delayed finish() in order to give the UI
- * some time to start up.
- */
- private void startDelayedFinish() {
- mHandler.sendEmptyMessageDelayed(EVENT_DELAYED_FINISH, DELAYED_FINISH_TIME);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- if (isFinishing()) return;
- for (Dialog dialog : mDialogs) {
- if (dialog != null) dialog.dismiss();
- }
- finish();
- }
-
- protected Dialog onCreateDialog(int id) {
- Dialog dialog;
- switch(id) {
- case DIALOG_SELECT_PHONE_TYPE:
- dialog = new AlertDialog.Builder(this)
- .setTitle(R.string.pick_outgoing_call_phone_type)
- .setIconAttribute(android.R.attr.alertDialogIcon)
- .setSingleChoiceItems(R.array.phone_type_values, -1, this)
- .setNegativeButton(android.R.string.cancel, this)
- .setOnCancelListener(this)
- .create();
- break;
- case DIALOG_SELECT_OUTGOING_SIP_PHONE:
- dialog = new AlertDialog.Builder(this)
- .setTitle(R.string.pick_outgoing_sip_phone)
- .setIconAttribute(android.R.attr.alertDialogIcon)
- .setSingleChoiceItems(getProfileNameArray(), -1, this)
- .setNegativeButton(android.R.string.cancel, this)
- .setOnCancelListener(this)
- .create();
- addMakeDefaultCheckBox(dialog);
- break;
- case DIALOG_START_SIP_SETTINGS:
- dialog = new AlertDialog.Builder(this)
- .setTitle(R.string.no_sip_account_found_title)
- .setMessage(R.string.no_sip_account_found)
- .setIconAttribute(android.R.attr.alertDialogIcon)
- .setPositiveButton(R.string.sip_menu_add, this)
- .setNegativeButton(android.R.string.cancel, this)
- .setOnCancelListener(this)
- .create();
- break;
- case DIALOG_NO_INTERNET_ERROR:
- boolean wifiOnly = SipManager.isSipWifiOnly(this);
- dialog = new AlertDialog.Builder(this)
- .setTitle(wifiOnly ? R.string.no_wifi_available_title
- : R.string.no_internet_available_title)
- .setMessage(wifiOnly ? R.string.no_wifi_available
- : R.string.no_internet_available)
- .setIconAttribute(android.R.attr.alertDialogIcon)
- .setPositiveButton(android.R.string.ok, this)
- .setOnCancelListener(this)
- .create();
- break;
- case DIALOG_NO_VOIP:
- dialog = new AlertDialog.Builder(this)
- .setTitle(R.string.no_voip)
- .setIconAttribute(android.R.attr.alertDialogIcon)
- .setPositiveButton(android.R.string.ok, this)
- .setOnCancelListener(this)
- .create();
- break;
- case DIALOG_SELECT_WIFI_CALL:
- dialog = new AlertDialog.Builder(this)
- .setMessage(R.string.choose_wifi_for_call_msg)
- .setPositiveButton(R.string.choose_wifi_for_call_yes, this)
- .setNegativeButton(R.string.choose_wifi_for_call_no, this)
- .setCancelable(false)
- .create();
- break;
- default:
- dialog = null;
- }
- if (dialog != null) {
- mDialogs[id] = dialog;
- }
- return dialog;
- }
-
- private void addMakeDefaultCheckBox(Dialog dialog) {
- LayoutInflater inflater = (LayoutInflater) getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- View view = inflater.inflate(
- com.android.internal.R.layout.always_use_checkbox, null);
- CheckBox makePrimaryCheckBox =
- (CheckBox)view.findViewById(com.android.internal.R.id.alwaysUse);
- makePrimaryCheckBox.setText(R.string.remember_my_choice);
- makePrimaryCheckBox.setOnCheckedChangeListener(this);
- mUnsetPriamryHint = (TextView)view.findViewById(
- com.android.internal.R.id.clearDefaultHint);
- mUnsetPriamryHint.setText(R.string.reset_my_choice_hint);
- mUnsetPriamryHint.setVisibility(View.GONE);
- ((AlertDialog)dialog).setView(view);
- }
-
- private CharSequence[] getProfileNameArray() {
- CharSequence[] entries = new CharSequence[mProfileList.size()];
- int i = 0;
- for (SipProfile p : mProfileList) {
- entries[i++] = p.getProfileName();
- }
- return entries;
- }
-
- public void onClick(DialogInterface dialog, int id) {
- if(dialog == mDialogs[DIALOG_SELECT_WIFI_CALL]) {
- if (id == DialogInterface.BUTTON_NEGATIVE) {
- setResultAndFinish();
- }
- return;
- } else if (id == DialogInterface.BUTTON_NEGATIVE) {
- // button negative is cancel
- finish();
- return;
- } else if(dialog == mDialogs[DIALOG_SELECT_PHONE_TYPE]) {
- String selection = getResources().getStringArray(
- R.array.phone_type_values)[id];
- if (DBG) Log.v(TAG, "User pick phone " + selection);
- if (selection.equals(getString(R.string.internet_phone))) {
- mUseSipPhone = true;
- startGetPrimarySipPhoneThread();
- return;
- }
- } else if (dialog == mDialogs[DIALOG_SELECT_OUTGOING_SIP_PHONE]) {
- mOutgoingSipProfile = mProfileList.get(id);
- } else if ((dialog == mDialogs[DIALOG_NO_INTERNET_ERROR])
- || (dialog == mDialogs[DIALOG_NO_VOIP])) {
- finish();
- return;
- } else {
- if (id == DialogInterface.BUTTON_POSITIVE) {
- // Redirect to sip settings and drop the call.
- Intent newIntent = new Intent(this, SipSettings.class);
- newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(newIntent);
- }
- finish();
- return;
- }
- setResultAndFinish();
- }
-
- public void onCancel(DialogInterface dialog) {
- finish();
- }
-
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- mMakePrimary = isChecked;
- if (isChecked) {
- mUnsetPriamryHint.setVisibility(View.VISIBLE);
- } else {
- mUnsetPriamryHint.setVisibility(View.INVISIBLE);
- }
- }
-
- private void createSipPhoneIfNeeded(SipProfile p) {
- CallManager cm = PhoneGlobals.getInstance().mCM;
- if (PhoneUtils.getSipPhoneFromUri(cm, p.getUriString()) != null) return;
-
- // Create the phone since we can not find it in CallManager
- try {
- SipManager.newInstance(this).open(p);
- Phone phone = PhoneFactory.makeSipPhone(p.getUriString());
- if (phone != null) {
- cm.registerPhone(phone);
- } else {
- Log.e(TAG, "cannot make sipphone profile" + p);
- }
- } catch (SipException e) {
- Log.e(TAG, "cannot open sip profile" + p, e);
- }
- }
-
- private void setResultAndFinish() {
- runOnUiThread(new Runnable() {
- public void run() {
- if (mOutgoingSipProfile != null) {
- if (!isNetworkConnected()) {
- showDialog(DIALOG_NO_INTERNET_ERROR);
- return;
- }
- if (DBG) Log.v(TAG, "primary SIP URI is " +
- mOutgoingSipProfile.getUriString());
- createSipPhoneIfNeeded(mOutgoingSipProfile);
- mIntent.putExtra(OutgoingCallBroadcaster.EXTRA_SIP_PHONE_URI,
- mOutgoingSipProfile.getUriString());
- if (mMakePrimary) {
- mSipSharedPreferences.setPrimaryAccount(
- mOutgoingSipProfile.getUriString());
- }
- }
-
- if (mUseSipPhone && mOutgoingSipProfile == null) {
- showDialog(DIALOG_START_SIP_SETTINGS);
- return;
- } else {
- // Woo hoo -- it's finally OK to initiate the outgoing call!
- PhoneGlobals.getInstance().callController.placeCall(mIntent);
- }
- startDelayedFinish();
- }
- });
- }
-
- private boolean isNetworkConnected() {
- ConnectivityManager cm = (ConnectivityManager) getSystemService(
- Context.CONNECTIVITY_SERVICE);
- if (cm != null) {
- NetworkInfo ni = cm.getActiveNetworkInfo();
- if ((ni == null) || !ni.isConnected()) return false;
-
- return ((ni.getType() == ConnectivityManager.TYPE_WIFI)
- || !SipManager.isSipWifiOnly(this));
- }
- return false;
- }
-
- private void startGetPrimarySipPhoneThread() {
- new Thread(new Runnable() {
- public void run() {
- getPrimarySipPhone();
- }
- }).start();
- }
-
- private void getPrimarySipPhone() {
- String primarySipUri = mSipSharedPreferences.getPrimaryAccount();
-
- mOutgoingSipProfile = getPrimaryFromExistingProfiles(primarySipUri);
- if (mOutgoingSipProfile == null) {
- if ((mProfileList != null) && (mProfileList.size() > 0)) {
- runOnUiThread(new Runnable() {
- public void run() {
- showDialog(DIALOG_SELECT_OUTGOING_SIP_PHONE);
- }
- });
- return;
- }
- }
- setResultAndFinish();
- }
-
- private SipProfile getPrimaryFromExistingProfiles(String primarySipUri) {
- mProfileList = mSipProfileDb.retrieveSipProfileList();
- if (mProfileList == null) return null;
- for (SipProfile p : mProfileList) {
- if (p.getUriString().equals(primarySipUri)) return p;
- }
- return null;
- }
-
- private boolean isConnectedToWifi() {
- ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
- if (cm != null) {
- NetworkInfo ni = cm.getActiveNetworkInfo();
- return ni != null && ni.isConnected() && ni.getType() == ConnectivityManager.TYPE_WIFI;
- }
- return false;
- }
-}