diff options
Diffstat (limited to 'src/com/android')
-rw-r--r-- | src/com/android/phone/CallFeaturesSetting.java | 8 | ||||
-rw-r--r-- | src/com/android/phone/OutgoingCallBroadcaster.java | 30 | ||||
-rw-r--r-- | src/com/android/phone/PhoneUtils.java | 16 | ||||
-rw-r--r-- | src/com/android/phone/SipBroadcastReceiver.java | 145 | ||||
-rw-r--r-- | src/com/android/phone/SipCallOptionHandler.java | 499 | ||||
-rw-r--r-- | src/com/android/phone/SipUtil.java | 35 | ||||
-rw-r--r-- | src/com/android/phone/sip/SipEditor.java | 657 | ||||
-rw-r--r-- | src/com/android/phone/sip/SipProfileDb.java | 144 | ||||
-rw-r--r-- | src/com/android/phone/sip/SipSettings.java | 514 | ||||
-rw-r--r-- | src/com/android/phone/sip/SipSharedPreferences.java | 109 | ||||
-rw-r--r-- | src/com/android/services/telephony/SipConnection.java | 79 | ||||
-rw-r--r-- | src/com/android/services/telephony/SipConnectionService.java | 169 | ||||
-rw-r--r-- | src/com/android/services/telephony/TelephonyCallServiceProvider.java | 5 |
13 files changed, 6 insertions, 2404 deletions
diff --git a/src/com/android/phone/CallFeaturesSetting.java b/src/com/android/phone/CallFeaturesSetting.java index 289767d3f..377ca95fd 100644 --- a/src/com/android/phone/CallFeaturesSetting.java +++ b/src/com/android/phone/CallFeaturesSetting.java @@ -68,7 +68,8 @@ import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.cdma.TtyIntent; -import com.android.phone.sip.SipSharedPreferences; +import com.android.services.telephony.sip.SipSharedPreferences; +import com.android.services.telephony.sip.SipUtil; import java.util.Collection; import java.util.HashMap; @@ -1751,10 +1752,11 @@ public class CallFeaturesSetting extends PreferenceActivity private void createSipCallSettings() { // Add Internet call settings. - if (PhoneUtils.isVoipSupported()) { + if (SipUtil.isVoipSupported(this)) { mSipManager = SipManager.newInstance(this); mSipSharedPreferences = new SipSharedPreferences(this); - addPreferencesFromResource(R.xml.sip_settings_category); + addPreferencesFromResource( + com.android.services.telephony.sip.R.xml.sip_settings_category); mButtonSipCallOptions = getSipCallOptionPreference(); mButtonSipCallOptions.setOnPreferenceChangeListener(this); mButtonSipCallOptions.setValueIndex( diff --git a/src/com/android/phone/OutgoingCallBroadcaster.java b/src/com/android/phone/OutgoingCallBroadcaster.java index 636a259d0..fc5cdab9c 100644 --- a/src/com/android/phone/OutgoingCallBroadcaster.java +++ b/src/com/android/phone/OutgoingCallBroadcaster.java @@ -309,35 +309,7 @@ public class OutgoingCallBroadcaster extends Activity */ private void startSipCallOptionHandler(Context context, Intent intent, Uri uri, String number) { - if (VDBG) { - Log.i(TAG, "startSipCallOptionHandler..."); - Log.i(TAG, "- intent: " + intent); - Log.i(TAG, "- uri: " + uri); - Log.i(TAG, "- number: " + number); - } - - // Create a copy of the original CALL intent that started the whole - // outgoing-call sequence. This intent will ultimately be passed to - // CallController.placeCall() after the SipCallOptionHandler step. - - Intent newIntent = new Intent(Intent.ACTION_CALL, uri); - newIntent.putExtra(EXTRA_ACTUAL_NUMBER_TO_DIAL, number); - CallGatewayManager.checkAndCopyPhoneProviderExtras(intent, newIntent); - - // Finally, launch the SipCallOptionHandler, with the copy of the - // original CALL intent stashed away in the EXTRA_NEW_CALL_INTENT - // extra. - - Intent selectPhoneIntent = new Intent(ACTION_SIP_SELECT_PHONE, uri); - selectPhoneIntent.setClass(context, SipCallOptionHandler.class); - selectPhoneIntent.putExtra(EXTRA_NEW_CALL_INTENT, newIntent); - selectPhoneIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - if (DBG) { - Log.v(TAG, "startSipCallOptionHandler(): " + - "calling startActivity: " + selectPhoneIntent); - } - context.startActivity(selectPhoneIntent); - // ...and see SipCallOptionHandler.onCreate() for the next step of the sequence. + // TODO(sail): Remove this code. } /** diff --git a/src/com/android/phone/PhoneUtils.java b/src/com/android/phone/PhoneUtils.java index 9452fc5f6..60950a5a5 100644 --- a/src/com/android/phone/PhoneUtils.java +++ b/src/com/android/phone/PhoneUtils.java @@ -31,7 +31,6 @@ import android.content.res.Configuration; import android.graphics.drawable.Drawable; import android.media.AudioManager; import android.net.Uri; -import android.net.sip.SipManager; import android.os.AsyncResult; import android.os.Handler; import android.os.Message; @@ -2647,21 +2646,6 @@ public class PhoneUtils { return (state == Call.State.INCOMING && !PhoneGlobals.getInstance().mCM.hasActiveFgCall()); } - private static boolean sVoipSupported = false; - static { - PhoneGlobals app = PhoneGlobals.getInstance(); - sVoipSupported = SipManager.isVoipSupported(app) - && app.getResources().getBoolean(com.android.internal.R.bool.config_built_in_sip_phone) - && app.getResources().getBoolean(com.android.internal.R.bool.config_voice_capable); - } - - /** - * @return true if this device supports voice calls using the built-in SIP stack. - */ - public static boolean isVoipSupported() { - return sVoipSupported; - } - public static String getPresentationString(Context context, int presentation) { String name = context.getString(R.string.unknown); if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) { diff --git a/src/com/android/phone/SipBroadcastReceiver.java b/src/com/android/phone/SipBroadcastReceiver.java deleted file mode 100644 index 8fdc7f730..000000000 --- a/src/com/android/phone/SipBroadcastReceiver.java +++ /dev/null @@ -1,145 +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.PhoneConstants; -import com.android.internal.telephony.PhoneFactory; -import com.android.internal.telephony.sip.SipPhone; -import com.android.phone.sip.SipProfileDb; -import com.android.phone.sip.SipSharedPreferences; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.net.sip.SipAudioCall; -import android.net.sip.SipException; -import android.net.sip.SipManager; -import android.net.sip.SipProfile; -import android.telephony.Rlog; -import java.util.List; - -/** - * Broadcast receiver that handles SIP-related intents. - */ -public class SipBroadcastReceiver extends BroadcastReceiver { - private static final String TAG = SipBroadcastReceiver.class.getSimpleName(); - private static final boolean DBG = true; - private SipSharedPreferences mSipSharedPreferences; - - @Override - public void onReceive(Context context, final Intent intent) { - String action = intent.getAction(); - - if (!PhoneUtils.isVoipSupported()) { - if (DBG) log("SIP VOIP not supported: " + action); - return; - } - mSipSharedPreferences = new SipSharedPreferences(context); - - if (action.equals(SipManager.ACTION_SIP_INCOMING_CALL)) { - takeCall(intent); - } else if (action.equals(SipManager.ACTION_SIP_ADD_PHONE)) { - String localSipUri = intent.getStringExtra(SipManager.EXTRA_LOCAL_URI); - SipPhone phone = PhoneFactory.makeSipPhone(localSipUri); - if (phone != null) { - CallManager.getInstance().registerPhone(phone); - } - if (DBG) log("onReceive: add phone" + localSipUri + " #phones=" - + CallManager.getInstance().getAllPhones().size()); - } else if (action.equals(SipManager.ACTION_SIP_REMOVE_PHONE)) { - String localSipUri = intent.getStringExtra(SipManager.EXTRA_LOCAL_URI); - removeSipPhone(localSipUri); - if (DBG) log("onReceive: remove phone: " + localSipUri + " #phones=" - + CallManager.getInstance().getAllPhones().size()); - } else if (action.equals(SipManager.ACTION_SIP_SERVICE_UP)) { - if (DBG) log("onReceive: start auto registration"); - registerAllProfiles(); - } else { - if (DBG) log("onReceive: action not processed: " + action); - return; - } - } - - private void removeSipPhone(String sipUri) { - for (Phone phone : CallManager.getInstance().getAllPhones()) { - if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) { - if (((SipPhone) phone).getSipUri().equals(sipUri)) { - CallManager.getInstance().unregisterPhone(phone); - return; - } - } - } - if (DBG) log("RemoveSipPhone: failed:cannot find phone with uri " + sipUri); - } - - private void takeCall(Intent intent) { - Context phoneContext = PhoneGlobals.getInstance(); - try { - SipAudioCall sipAudioCall = SipManager.newInstance(phoneContext) - .takeAudioCall(intent, null); - for (Phone phone : CallManager.getInstance().getAllPhones()) { - if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_SIP) { - if (((SipPhone) phone).canTake(sipAudioCall)) { - if (DBG) log("takeCall: SIP call: " + intent); - return; - } - } - } - if (DBG) log("takeCall: not taken, drop SIP call: " + intent); - } catch (SipException e) { - loge("takeCall: error incoming SIP call", e); - } - } - - private void registerAllProfiles() { - final Context context = PhoneGlobals.getInstance(); - new Thread(new Runnable() { - @Override - public void run() { - SipManager sipManager = SipManager.newInstance(context); - SipProfileDb profileDb = new SipProfileDb(context); - List<SipProfile> sipProfileList = - profileDb.retrieveSipProfileList(); - for (SipProfile profile : sipProfileList) { - try { - if (!profile.getAutoRegistration() && - !profile.getUriString().equals( - mSipSharedPreferences.getPrimaryAccount())) { - continue; - } - sipManager.open(profile, - SipUtil.createIncomingCallPendingIntent(), - null); - if (DBG) log("registerAllProfiles: profile=" + profile); - } catch (SipException e) { - loge("registerAllProfiles: failed" + profile.getProfileName(), e); - } - } - }} - ).start(); - } - - private void log(String s) { - Rlog.d(TAG, s); - } - - private void loge(String s, Throwable t) { - Rlog.e(TAG, s, t); - } -} 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; - } -} diff --git a/src/com/android/phone/SipUtil.java b/src/com/android/phone/SipUtil.java deleted file mode 100644 index a901d5850..000000000 --- a/src/com/android/phone/SipUtil.java +++ /dev/null @@ -1,35 +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 android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.net.sip.SipManager; - -public class SipUtil { - private SipUtil() { - } - - public static PendingIntent createIncomingCallPendingIntent() { - Context phoneContext = PhoneGlobals.getInstance(); - Intent intent = new Intent(phoneContext, SipBroadcastReceiver.class); - intent.setAction(SipManager.ACTION_SIP_INCOMING_CALL); - return PendingIntent.getBroadcast(phoneContext, 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT); - } -} diff --git a/src/com/android/phone/sip/SipEditor.java b/src/com/android/phone/sip/SipEditor.java deleted file mode 100644 index 8145c94a3..000000000 --- a/src/com/android/phone/sip/SipEditor.java +++ /dev/null @@ -1,657 +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.sip; - -import com.android.internal.telephony.CallManager; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneConstants; -import com.android.phone.R; -import com.android.phone.SipUtil; - -import android.app.ActionBar; -import android.app.AlertDialog; -import android.content.Intent; -import android.net.sip.SipManager; -import android.net.sip.SipProfile; -import android.os.Bundle; -import android.os.Parcelable; -import android.preference.CheckBoxPreference; -import android.preference.EditTextPreference; -import android.preference.ListPreference; -import android.preference.Preference; -import android.preference.PreferenceActivity; -import android.preference.PreferenceGroup; -import android.text.TextUtils; -import android.util.Log; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.Button; -import android.widget.Toast; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.Arrays; - -/** - * The activity class for editing a new or existing SIP profile. - */ -public class SipEditor extends PreferenceActivity - implements Preference.OnPreferenceChangeListener { - private static final int MENU_SAVE = Menu.FIRST; - private static final int MENU_DISCARD = Menu.FIRST + 1; - private static final int MENU_REMOVE = Menu.FIRST + 2; - - private static final String TAG = SipEditor.class.getSimpleName(); - private static final String KEY_PROFILE = "profile"; - private static final String GET_METHOD_PREFIX = "get"; - private static final char SCRAMBLED = '*'; - private static final int NA = 0; - - private PrimaryAccountSelector mPrimaryAccountSelector; - private AdvancedSettings mAdvancedSettings; - private SipSharedPreferences mSharedPreferences; - private boolean mDisplayNameSet; - private boolean mHomeButtonClicked; - private boolean mUpdateRequired; - private boolean mUpdatedFieldIsEmpty; - - private SipManager mSipManager; - private SipProfileDb mProfileDb; - private SipProfile mOldProfile; - private CallManager mCallManager; - private Button mRemoveButton; - - enum PreferenceKey { - Username(R.string.username, 0, R.string.default_preference_summary), - Password(R.string.password, 0, R.string.default_preference_summary), - DomainAddress(R.string.domain_address, 0, R.string.default_preference_summary), - DisplayName(R.string.display_name, 0, R.string.display_name_summary), - ProxyAddress(R.string.proxy_address, 0, R.string.optional_summary), - Port(R.string.port, R.string.default_port, R.string.default_port), - Transport(R.string.transport, R.string.default_transport, NA), - SendKeepAlive(R.string.send_keepalive, R.string.sip_system_decide, NA), - AuthUserName(R.string.auth_username, 0, R.string.optional_summary); - - final int text; - final int initValue; - final int defaultSummary; - Preference preference; - - /** - * @param key The key name of the preference. - * @param initValue The initial value of the preference. - * @param defaultSummary The default summary value of the preference - * when the preference value is empty. - */ - PreferenceKey(int text, int initValue, int defaultSummary) { - this.text = text; - this.initValue = initValue; - this.defaultSummary = defaultSummary; - } - - String getValue() { - if (preference instanceof EditTextPreference) { - return ((EditTextPreference) preference).getText(); - } else if (preference instanceof ListPreference) { - return ((ListPreference) preference).getValue(); - } - throw new RuntimeException("getValue() for the preference " + this); - } - - void setValue(String value) { - if (preference instanceof EditTextPreference) { - String oldValue = getValue(); - ((EditTextPreference) preference).setText(value); - if (this != Password) { - Log.v(TAG, this + ": setValue() " + value + ": " + oldValue - + " --> " + getValue()); - } - } else if (preference instanceof ListPreference) { - ((ListPreference) preference).setValue(value); - } - - if (TextUtils.isEmpty(value)) { - preference.setSummary(defaultSummary); - } else if (this == Password) { - preference.setSummary(scramble(value)); - } else if ((this == DisplayName) - && value.equals(getDefaultDisplayName())) { - preference.setSummary(defaultSummary); - } else { - preference.setSummary(value); - } - } - } - - @Override - public void onResume() { - super.onResume(); - mHomeButtonClicked = false; - if (mCallManager.getState() != PhoneConstants.State.IDLE) { - mAdvancedSettings.show(); - getPreferenceScreen().setEnabled(false); - if (mRemoveButton != null) mRemoveButton.setEnabled(false); - } else { - getPreferenceScreen().setEnabled(true); - if (mRemoveButton != null) mRemoveButton.setEnabled(true); - } - } - - @Override - public void onCreate(Bundle savedInstanceState) { - Log.v(TAG, "start profile editor"); - super.onCreate(savedInstanceState); - - mSipManager = SipManager.newInstance(this); - mSharedPreferences = new SipSharedPreferences(this); - mProfileDb = new SipProfileDb(this); - mCallManager = CallManager.getInstance(); - - setContentView(R.layout.sip_settings_ui); - addPreferencesFromResource(R.xml.sip_edit); - - SipProfile p = mOldProfile = (SipProfile) ((savedInstanceState == null) - ? getIntent().getParcelableExtra(SipSettings.KEY_SIP_PROFILE) - : savedInstanceState.getParcelable(KEY_PROFILE)); - - PreferenceGroup screen = (PreferenceGroup) getPreferenceScreen(); - for (int i = 0, n = screen.getPreferenceCount(); i < n; i++) { - setupPreference(screen.getPreference(i)); - } - - if (p == null) { - screen.setTitle(R.string.sip_edit_new_title); - } - - mAdvancedSettings = new AdvancedSettings(); - mPrimaryAccountSelector = new PrimaryAccountSelector(p); - - loadPreferencesFromProfile(p); - } - - @Override - public void onPause() { - Log.v(TAG, "SipEditor onPause(): finishing? " + isFinishing()); - if (!isFinishing()) { - mHomeButtonClicked = true; - validateAndSetResult(); - } - super.onPause(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - menu.add(0, MENU_DISCARD, 0, R.string.sip_menu_discard) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - menu.add(0, MENU_SAVE, 0, R.string.sip_menu_save) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - menu.add(0, MENU_REMOVE, 0, R.string.remove_sip_account) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - MenuItem removeMenu = menu.findItem(MENU_REMOVE); - removeMenu.setVisible(mOldProfile != null); - menu.findItem(MENU_SAVE).setEnabled(mUpdateRequired); - return super.onPrepareOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case MENU_SAVE: - validateAndSetResult(); - return true; - - case MENU_DISCARD: - finish(); - return true; - - case MENU_REMOVE: { - setRemovedProfileAndFinish(); - return true; - } - } - return super.onOptionsItemSelected(item); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - switch (keyCode) { - case KeyEvent.KEYCODE_BACK: - validateAndSetResult(); - return true; - } - return super.onKeyDown(keyCode, event); - } - - private void saveAndRegisterProfile(SipProfile p) throws IOException { - if (p == null) return; - mProfileDb.saveProfile(p); - if (p.getAutoRegistration() - || mSharedPreferences.isPrimaryAccount(p.getUriString())) { - try { - mSipManager.open(p, SipUtil.createIncomingCallPendingIntent(), - null); - } catch (Exception e) { - Log.e(TAG, "register failed: " + p.getUriString(), e); - } - } - } - - private void deleteAndUnregisterProfile(SipProfile p) { - if (p == null) return; - mProfileDb.deleteProfile(p); - unregisterProfile(p.getUriString()); - } - - private void unregisterProfile(String uri) { - try { - mSipManager.close(uri); - } catch (Exception e) { - Log.e(TAG, "unregister failed: " + uri, e); - } - } - - private void setRemovedProfileAndFinish() { - Intent intent = new Intent(this, SipSettings.class); - setResult(RESULT_FIRST_USER, intent); - Toast.makeText(this, R.string.removing_account, Toast.LENGTH_SHORT) - .show(); - replaceProfile(mOldProfile, null); - // do finish() in replaceProfile() in a background thread - } - - private void showAlert(Throwable e) { - String msg = e.getMessage(); - if (TextUtils.isEmpty(msg)) msg = e.toString(); - showAlert(msg); - } - - private void showAlert(final String message) { - if (mHomeButtonClicked) { - Log.v(TAG, "Home button clicked, don't show dialog: " + message); - return; - } - runOnUiThread(new Runnable() { - @Override - public void run() { - new AlertDialog.Builder(SipEditor.this) - .setTitle(android.R.string.dialog_alert_title) - .setIconAttribute(android.R.attr.alertDialogIcon) - .setMessage(message) - .setPositiveButton(R.string.alert_dialog_ok, null) - .show(); - } - }); - } - - private boolean isEditTextEmpty(PreferenceKey key) { - EditTextPreference pref = (EditTextPreference) key.preference; - return TextUtils.isEmpty(pref.getText()) - || pref.getSummary().equals(getString(key.defaultSummary)); - } - - private void validateAndSetResult() { - boolean allEmpty = true; - CharSequence firstEmptyFieldTitle = null; - for (PreferenceKey key : PreferenceKey.values()) { - Preference p = key.preference; - if (p instanceof EditTextPreference) { - EditTextPreference pref = (EditTextPreference) p; - boolean fieldEmpty = isEditTextEmpty(key); - if (allEmpty && !fieldEmpty) allEmpty = false; - - // use default value if display name is empty - if (fieldEmpty) { - switch (key) { - case DisplayName: - pref.setText(getDefaultDisplayName()); - break; - case AuthUserName: - case ProxyAddress: - // optional; do nothing - break; - case Port: - pref.setText(getString(R.string.default_port)); - break; - default: - if (firstEmptyFieldTitle == null) { - firstEmptyFieldTitle = pref.getTitle(); - } - } - } else if (key == PreferenceKey.Port) { - int port = Integer.parseInt(PreferenceKey.Port.getValue()); - if ((port < 1000) || (port > 65534)) { - showAlert(getString(R.string.not_a_valid_port)); - return; - } - } - } - } - - if (allEmpty || !mUpdateRequired) { - finish(); - return; - } else if (firstEmptyFieldTitle != null) { - showAlert(getString(R.string.empty_alert, firstEmptyFieldTitle)); - return; - } - try { - SipProfile profile = createSipProfile(); - Intent intent = new Intent(this, SipSettings.class); - intent.putExtra(SipSettings.KEY_SIP_PROFILE, (Parcelable) profile); - setResult(RESULT_OK, intent); - Toast.makeText(this, R.string.saving_account, Toast.LENGTH_SHORT) - .show(); - - replaceProfile(mOldProfile, profile); - // do finish() in replaceProfile() in a background thread - } catch (Exception e) { - Log.w(TAG, "Can not create new SipProfile", e); - showAlert(e); - } - } - - private void unregisterOldPrimaryAccount() { - String primaryAccountUri = mSharedPreferences.getPrimaryAccount(); - Log.v(TAG, "old primary: " + primaryAccountUri); - if ((primaryAccountUri != null) - && !mSharedPreferences.isReceivingCallsEnabled()) { - Log.v(TAG, "unregister old primary: " + primaryAccountUri); - unregisterProfile(primaryAccountUri); - } - } - - private void replaceProfile(final SipProfile oldProfile, - final SipProfile newProfile) { - // Replace profile in a background thread as it takes time to access the - // storage; do finish() once everything goes fine. - // newProfile may be null if the old profile is to be deleted rather - // than being modified. - new Thread(new Runnable() { - public void run() { - try { - // if new profile is primary, unregister the old primary account - if ((newProfile != null) && mPrimaryAccountSelector.isSelected()) { - unregisterOldPrimaryAccount(); - } - - mPrimaryAccountSelector.commit(newProfile); - deleteAndUnregisterProfile(oldProfile); - saveAndRegisterProfile(newProfile); - finish(); - } catch (Exception e) { - Log.e(TAG, "Can not save/register new SipProfile", e); - showAlert(e); - } - } - }, "SipEditor").start(); - } - - private String getProfileName() { - return PreferenceKey.Username.getValue() + "@" - + PreferenceKey.DomainAddress.getValue(); - } - - private SipProfile createSipProfile() throws Exception { - return new SipProfile.Builder( - PreferenceKey.Username.getValue(), - PreferenceKey.DomainAddress.getValue()) - .setProfileName(getProfileName()) - .setPassword(PreferenceKey.Password.getValue()) - .setOutboundProxy(PreferenceKey.ProxyAddress.getValue()) - .setProtocol(PreferenceKey.Transport.getValue()) - .setDisplayName(PreferenceKey.DisplayName.getValue()) - .setPort(Integer.parseInt(PreferenceKey.Port.getValue())) - .setSendKeepAlive(isAlwaysSendKeepAlive()) - .setAutoRegistration( - mSharedPreferences.isReceivingCallsEnabled()) - .setAuthUserName(PreferenceKey.AuthUserName.getValue()) - .build(); - } - - public boolean onPreferenceChange(Preference pref, Object newValue) { - if (!mUpdateRequired) { - mUpdateRequired = true; - if (mOldProfile != null) { - unregisterProfile(mOldProfile.getUriString()); - } - } - if (pref instanceof CheckBoxPreference) { - invalidateOptionsMenu(); - return true; - } - String value = (newValue == null) ? "" : newValue.toString(); - if (TextUtils.isEmpty(value)) { - pref.setSummary(getPreferenceKey(pref).defaultSummary); - } else if (pref == PreferenceKey.Password.preference) { - pref.setSummary(scramble(value)); - } else { - pref.setSummary(value); - } - - if (pref == PreferenceKey.DisplayName.preference) { - ((EditTextPreference) pref).setText(value); - checkIfDisplayNameSet(); - } - - // SAVE menu should be enabled once the user modified some preference. - invalidateOptionsMenu(); - return true; - } - - private PreferenceKey getPreferenceKey(Preference pref) { - for (PreferenceKey key : PreferenceKey.values()) { - if (key.preference == pref) return key; - } - throw new RuntimeException("not possible to reach here"); - } - - private void loadPreferencesFromProfile(SipProfile p) { - if (p != null) { - Log.v(TAG, "Edit the existing profile : " + p.getProfileName()); - try { - Class profileClass = SipProfile.class; - for (PreferenceKey key : PreferenceKey.values()) { - Method meth = profileClass.getMethod(GET_METHOD_PREFIX - + getString(key.text), (Class[])null); - if (key == PreferenceKey.SendKeepAlive) { - boolean value = ((Boolean) - meth.invoke(p, (Object[]) null)).booleanValue(); - key.setValue(getString(value - ? R.string.sip_always_send_keepalive - : R.string.sip_system_decide)); - } else { - Object value = meth.invoke(p, (Object[])null); - key.setValue((value == null) ? "" : value.toString()); - } - } - checkIfDisplayNameSet(); - } catch (Exception e) { - Log.e(TAG, "Can not load pref from profile", e); - } - } else { - Log.v(TAG, "Edit a new profile"); - for (PreferenceKey key : PreferenceKey.values()) { - key.preference.setOnPreferenceChangeListener(this); - - // FIXME: android:defaultValue in preference xml file doesn't - // work. Even if we setValue() for each preference in the case - // of (p != null), the dialog still shows android:defaultValue, - // not the value set by setValue(). This happens if - // android:defaultValue is not empty. Is it a bug? - if (key.initValue != 0) { - key.setValue(getString(key.initValue)); - } - } - mDisplayNameSet = false; - } - } - - private boolean isAlwaysSendKeepAlive() { - ListPreference pref = (ListPreference) - PreferenceKey.SendKeepAlive.preference; - return getString(R.string.sip_always_send_keepalive).equals( - pref.getValue()); - } - - private void setCheckBox(PreferenceKey key, boolean checked) { - CheckBoxPreference pref = (CheckBoxPreference) key.preference; - pref.setChecked(checked); - } - - private void setupPreference(Preference pref) { - pref.setOnPreferenceChangeListener(this); - for (PreferenceKey key : PreferenceKey.values()) { - String name = getString(key.text); - if (name.equals(pref.getKey())) { - key.preference = pref; - return; - } - } - } - - private void checkIfDisplayNameSet() { - String displayName = PreferenceKey.DisplayName.getValue(); - mDisplayNameSet = !TextUtils.isEmpty(displayName) - && !displayName.equals(getDefaultDisplayName()); - Log.d(TAG, "displayName set? " + mDisplayNameSet); - if (mDisplayNameSet) { - PreferenceKey.DisplayName.preference.setSummary(displayName); - } else { - PreferenceKey.DisplayName.setValue(""); - } - } - - private static String getDefaultDisplayName() { - return PreferenceKey.Username.getValue(); - } - - private static String scramble(String s) { - char[] cc = new char[s.length()]; - Arrays.fill(cc, SCRAMBLED); - return new String(cc); - } - - // only takes care of the primary account setting in SipSharedSettings - private class PrimaryAccountSelector { - private CheckBoxPreference mCheckbox; - private final boolean mWasPrimaryAccount; - - // @param profile profile to be edited; null if adding new profile - PrimaryAccountSelector(SipProfile profile) { - mCheckbox = (CheckBoxPreference) getPreferenceScreen() - .findPreference(getString(R.string.set_primary)); - boolean noPrimaryAccountSet = - !mSharedPreferences.hasPrimaryAccount(); - boolean editNewProfile = (profile == null); - mWasPrimaryAccount = !editNewProfile - && mSharedPreferences.isPrimaryAccount( - profile.getUriString()); - - Log.v(TAG, " noPrimaryAccountSet: " + noPrimaryAccountSet); - Log.v(TAG, " editNewProfile: " + editNewProfile); - Log.v(TAG, " mWasPrimaryAccount: " + mWasPrimaryAccount); - - mCheckbox.setChecked(mWasPrimaryAccount - || (editNewProfile && noPrimaryAccountSet)); - } - - boolean isSelected() { - return mCheckbox.isChecked(); - } - - // profile is null if the user removes it - void commit(SipProfile profile) { - if ((profile != null) && mCheckbox.isChecked()) { - mSharedPreferences.setPrimaryAccount(profile.getUriString()); - } else if (mWasPrimaryAccount) { - mSharedPreferences.unsetPrimaryAccount(); - } - Log.d(TAG, " primary account changed to : " - + mSharedPreferences.getPrimaryAccount()); - } - } - - private class AdvancedSettings - implements Preference.OnPreferenceClickListener { - private Preference mAdvancedSettingsTrigger; - private Preference[] mPreferences; - private boolean mShowing = false; - - AdvancedSettings() { - mAdvancedSettingsTrigger = getPreferenceScreen().findPreference( - getString(R.string.advanced_settings)); - mAdvancedSettingsTrigger.setOnPreferenceClickListener(this); - - loadAdvancedPreferences(); - } - - private void loadAdvancedPreferences() { - PreferenceGroup screen = (PreferenceGroup) getPreferenceScreen(); - - addPreferencesFromResource(R.xml.sip_advanced_edit); - PreferenceGroup group = (PreferenceGroup) screen.findPreference( - getString(R.string.advanced_settings_container)); - screen.removePreference(group); - - mPreferences = new Preference[group.getPreferenceCount()]; - int order = screen.getPreferenceCount(); - for (int i = 0, n = mPreferences.length; i < n; i++) { - Preference pref = group.getPreference(i); - pref.setOrder(order++); - setupPreference(pref); - mPreferences[i] = pref; - } - } - - void show() { - mShowing = true; - mAdvancedSettingsTrigger.setSummary(R.string.advanced_settings_hide); - PreferenceGroup screen = (PreferenceGroup) getPreferenceScreen(); - for (Preference pref : mPreferences) { - screen.addPreference(pref); - Log.v(TAG, "add pref " + pref.getKey() + ": order=" + pref.getOrder()); - } - } - - private void hide() { - mShowing = false; - mAdvancedSettingsTrigger.setSummary(R.string.advanced_settings_show); - PreferenceGroup screen = (PreferenceGroup) getPreferenceScreen(); - for (Preference pref : mPreferences) { - screen.removePreference(pref); - } - } - - public boolean onPreferenceClick(Preference preference) { - Log.v(TAG, "optional settings clicked"); - if (!mShowing) { - show(); - } else { - hide(); - } - return true; - } - } -} diff --git a/src/com/android/phone/sip/SipProfileDb.java b/src/com/android/phone/sip/SipProfileDb.java deleted file mode 100644 index a51dfb955..000000000 --- a/src/com/android/phone/sip/SipProfileDb.java +++ /dev/null @@ -1,144 +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.sip; - -import com.android.internal.os.AtomicFile; - -import android.content.Context; -import android.net.sip.SipProfile; -import android.util.Log; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Utility class that helps perform operations on the SipProfile database. - */ -public class SipProfileDb { - private static final String TAG = SipProfileDb.class.getSimpleName(); - - private static final String PROFILES_DIR = "/profiles/"; - private static final String PROFILE_OBJ_FILE = ".pobj"; - - private String mProfilesDirectory; - private SipSharedPreferences mSipSharedPreferences; - private int mProfilesCount = -1; - - public SipProfileDb(Context context) { - mProfilesDirectory = context.getFilesDir().getAbsolutePath() - + PROFILES_DIR; - mSipSharedPreferences = new SipSharedPreferences(context); - } - - public void deleteProfile(SipProfile p) { - synchronized(SipProfileDb.class) { - deleteProfile(new File(mProfilesDirectory + p.getProfileName())); - if (mProfilesCount < 0) retrieveSipProfileListInternal(); - mSipSharedPreferences.setProfilesCount(--mProfilesCount); - } - } - - private void deleteProfile(File file) { - if (file.isDirectory()) { - for (File child : file.listFiles()) deleteProfile(child); - } - file.delete(); - } - - public void saveProfile(SipProfile p) throws IOException { - synchronized(SipProfileDb.class) { - if (mProfilesCount < 0) retrieveSipProfileListInternal(); - File f = new File(mProfilesDirectory + p.getProfileName()); - if (!f.exists()) f.mkdirs(); - AtomicFile atomicFile = - new AtomicFile(new File(f, PROFILE_OBJ_FILE)); - FileOutputStream fos = null; - ObjectOutputStream oos = null; - try { - fos = atomicFile.startWrite(); - oos = new ObjectOutputStream(fos); - oos.writeObject(p); - oos.flush(); - mSipSharedPreferences.setProfilesCount(++mProfilesCount); - atomicFile.finishWrite(fos); - } catch (IOException e) { - atomicFile.failWrite(fos); - throw e; - } finally { - if (oos != null) oos.close(); - } - } - } - - public int getProfilesCount() { - return (mProfilesCount < 0) ? - mSipSharedPreferences.getProfilesCount() : mProfilesCount; - } - - public List<SipProfile> retrieveSipProfileList() { - synchronized(SipProfileDb.class) { - return retrieveSipProfileListInternal(); - } - } - - private List<SipProfile> retrieveSipProfileListInternal() { - List<SipProfile> sipProfileList = Collections.synchronizedList( - new ArrayList<SipProfile>()); - - File root = new File(mProfilesDirectory); - String[] dirs = root.list(); - if (dirs == null) return sipProfileList; - for (String dir : dirs) { - File f = new File(new File(root, dir), PROFILE_OBJ_FILE); - if (!f.exists()) continue; - try { - SipProfile p = deserialize(f); - if (p == null) continue; - if (!dir.equals(p.getProfileName())) continue; - - sipProfileList.add(p); - } catch (IOException e) { - Log.e(TAG, "retrieveProfileListFromStorage()", e); - } - } - mProfilesCount = sipProfileList.size(); - mSipSharedPreferences.setProfilesCount(mProfilesCount); - return sipProfileList; - } - - private SipProfile deserialize(File profileObjectFile) throws IOException { - AtomicFile atomicFile = new AtomicFile(profileObjectFile); - ObjectInputStream ois = null; - try { - ois = new ObjectInputStream(atomicFile.openRead()); - SipProfile p = (SipProfile) ois.readObject(); - return p; - } catch (ClassNotFoundException e) { - Log.w(TAG, "deserialize a profile: " + e); - } finally { - if (ois!= null) ois.close(); - } - return null; - } -} diff --git a/src/com/android/phone/sip/SipSettings.java b/src/com/android/phone/sip/SipSettings.java deleted file mode 100644 index d58386c11..000000000 --- a/src/com/android/phone/sip/SipSettings.java +++ /dev/null @@ -1,514 +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.sip; - -import com.android.internal.telephony.CallManager; -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneConstants; -import com.android.phone.CallFeaturesSetting; -import com.android.phone.R; -import com.android.phone.SipUtil; - -import android.app.ActionBar; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.net.sip.SipErrorCode; -import android.net.sip.SipException; -import android.net.sip.SipManager; -import android.net.sip.SipProfile; -import android.net.sip.SipRegistrationListener; -import android.os.Bundle; -import android.os.Parcelable; -import android.os.Process; -import android.preference.CheckBoxPreference; -import android.preference.Preference; -import android.preference.Preference.OnPreferenceClickListener; -import android.preference.PreferenceActivity; -import android.preference.PreferenceCategory; -import android.text.TextUtils; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; - -import java.io.IOException; -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * The PreferenceActivity class for managing sip profile preferences. - */ -public class SipSettings extends PreferenceActivity { - public static final String SIP_SHARED_PREFERENCES = "SIP_PREFERENCES"; - - private static final int MENU_ADD_ACCOUNT = Menu.FIRST; - - static final String KEY_SIP_PROFILE = "sip_profile"; - - private static final String BUTTON_SIP_RECEIVE_CALLS = - "sip_receive_calls_key"; - private static final String PREF_SIP_LIST = "sip_account_list"; - private static final String TAG = "SipSettings"; - - private static final int REQUEST_ADD_OR_EDIT_SIP_PROFILE = 1; - - private PackageManager mPackageManager; - private SipManager mSipManager; - private CallManager mCallManager; - private SipProfileDb mProfileDb; - - private SipProfile mProfile; // profile that's being edited - - private CheckBoxPreference mButtonSipReceiveCalls; - private PreferenceCategory mSipListContainer; - private Map<String, SipPreference> mSipPreferenceMap; - private List<SipProfile> mSipProfileList; - private SipSharedPreferences mSipSharedPreferences; - private int mUid = Process.myUid(); - - private class SipPreference extends Preference { - SipProfile mProfile; - SipPreference(Context c, SipProfile p) { - super(c); - setProfile(p); - } - - SipProfile getProfile() { - return mProfile; - } - - void setProfile(SipProfile p) { - mProfile = p; - setTitle(getProfileName(p)); - updateSummary(mSipSharedPreferences.isReceivingCallsEnabled() - ? getString(R.string.registration_status_checking_status) - : getString(R.string.registration_status_not_receiving)); - } - - void updateSummary(String registrationStatus) { - int profileUid = mProfile.getCallingUid(); - boolean isPrimary = mProfile.getUriString().equals( - mSipSharedPreferences.getPrimaryAccount()); - Log.v(TAG, "profile uid is " + profileUid + " isPrimary:" - + isPrimary + " registration:" + registrationStatus - + " Primary:" + mSipSharedPreferences.getPrimaryAccount() - + " status:" + registrationStatus); - String summary = ""; - if ((profileUid > 0) && (profileUid != mUid)) { - // from third party apps - summary = getString(R.string.third_party_account_summary, - getPackageNameFromUid(profileUid)); - } else if (isPrimary) { - summary = getString(R.string.primary_account_summary_with, - registrationStatus); - } else { - summary = registrationStatus; - } - setSummary(summary); - } - } - - private String getPackageNameFromUid(int uid) { - try { - String[] pkgs = mPackageManager.getPackagesForUid(uid); - ApplicationInfo ai = - mPackageManager.getApplicationInfo(pkgs[0], 0); - return ai.loadLabel(mPackageManager).toString(); - } catch (PackageManager.NameNotFoundException e) { - Log.e(TAG, "cannot find name of uid " + uid, e); - } - return "uid:" + uid; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mSipManager = SipManager.newInstance(this); - mSipSharedPreferences = new SipSharedPreferences(this); - mProfileDb = new SipProfileDb(this); - - mPackageManager = getPackageManager(); - setContentView(R.layout.sip_settings_ui); - addPreferencesFromResource(R.xml.sip_setting); - mSipListContainer = (PreferenceCategory) findPreference(PREF_SIP_LIST); - registerForReceiveCallsCheckBox(); - mCallManager = CallManager.getInstance(); - - updateProfilesStatus(); - - ActionBar actionBar = getActionBar(); - if (actionBar != null) { - // android.R.id.home will be triggered in onOptionsItemSelected() - actionBar.setDisplayHomeAsUpEnabled(true); - } - } - - @Override - public void onResume() { - super.onResume(); - - if (mCallManager.getState() != PhoneConstants.State.IDLE) { - mButtonSipReceiveCalls.setEnabled(false); - } else { - mButtonSipReceiveCalls.setEnabled(true); - } - } - - @Override - protected void onDestroy() { - super.onDestroy(); - unregisterForContextMenu(getListView()); - } - - @Override - protected void onActivityResult(final int requestCode, final int resultCode, - final Intent intent) { - if (resultCode != RESULT_OK && resultCode != RESULT_FIRST_USER) return; - new Thread() { - @Override - public void run() { - try { - if (mProfile != null) { - Log.v(TAG, "Removed Profile:" + mProfile.getProfileName()); - deleteProfile(mProfile); - } - - SipProfile profile = intent.getParcelableExtra(KEY_SIP_PROFILE); - if (resultCode == RESULT_OK) { - Log.v(TAG, "New Profile Name:" + profile.getProfileName()); - addProfile(profile); - } - updateProfilesStatus(); - } catch (IOException e) { - Log.v(TAG, "Can not handle the profile : " + e.getMessage()); - } - } - }.start(); - } - - private void registerForReceiveCallsCheckBox() { - mButtonSipReceiveCalls = (CheckBoxPreference) findPreference - (BUTTON_SIP_RECEIVE_CALLS); - mButtonSipReceiveCalls.setChecked( - mSipSharedPreferences.isReceivingCallsEnabled()); - mButtonSipReceiveCalls.setOnPreferenceClickListener( - new OnPreferenceClickListener() { - public boolean onPreferenceClick(Preference preference) { - final boolean enabled = - ((CheckBoxPreference) preference).isChecked(); - new Thread(new Runnable() { - public void run() { - handleSipReceiveCallsOption(enabled); - } - }).start(); - return true; - } - }); - } - - private synchronized void handleSipReceiveCallsOption(boolean enabled) { - mSipSharedPreferences.setReceivingCallsEnabled(enabled); - List<SipProfile> sipProfileList = mProfileDb.retrieveSipProfileList(); - for (SipProfile p : sipProfileList) { - String sipUri = p.getUriString(); - p = updateAutoRegistrationFlag(p, enabled); - try { - if (enabled) { - mSipManager.open(p, - SipUtil.createIncomingCallPendingIntent(), null); - } else { - mSipManager.close(sipUri); - if (mSipSharedPreferences.isPrimaryAccount(sipUri)) { - // re-open in order to make calls - mSipManager.open(p); - } - } - } catch (Exception e) { - Log.e(TAG, "register failed", e); - } - } - updateProfilesStatus(); - } - - private SipProfile updateAutoRegistrationFlag( - SipProfile p, boolean enabled) { - SipProfile newProfile = new SipProfile.Builder(p) - .setAutoRegistration(enabled) - .build(); - try { - mProfileDb.deleteProfile(p); - mProfileDb.saveProfile(newProfile); - } catch (Exception e) { - Log.e(TAG, "updateAutoRegistrationFlag error", e); - } - return newProfile; - } - - private void updateProfilesStatus() { - new Thread(new Runnable() { - @Override - public void run() { - try { - retrieveSipLists(); - } catch (Exception e) { - Log.e(TAG, "isRegistered", e); - } - } - }).start(); - } - - private String getProfileName(SipProfile profile) { - String profileName = profile.getProfileName(); - if (TextUtils.isEmpty(profileName)) { - profileName = profile.getUserName() + "@" + profile.getSipDomain(); - } - return profileName; - } - - private void retrieveSipLists() { - mSipPreferenceMap = new LinkedHashMap<String, SipPreference>(); - mSipProfileList = mProfileDb.retrieveSipProfileList(); - processActiveProfilesFromSipService(); - Collections.sort(mSipProfileList, new Comparator<SipProfile>() { - @Override - public int compare(SipProfile p1, SipProfile p2) { - return getProfileName(p1).compareTo(getProfileName(p2)); - } - - public boolean equals(SipProfile p) { - // not used - return false; - } - }); - mSipListContainer.removeAll(); - for (SipProfile p : mSipProfileList) { - addPreferenceFor(p); - } - - if (!mSipSharedPreferences.isReceivingCallsEnabled()) return; - for (SipProfile p : mSipProfileList) { - if (mUid == p.getCallingUid()) { - try { - mSipManager.setRegistrationListener( - p.getUriString(), createRegistrationListener()); - } catch (SipException e) { - Log.e(TAG, "cannot set registration listener", e); - } - } - } - } - - private void processActiveProfilesFromSipService() { - SipProfile[] activeList = mSipManager.getListOfProfiles(); - for (SipProfile activeProfile : activeList) { - SipProfile profile = getProfileFromList(activeProfile); - if (profile == null) { - mSipProfileList.add(activeProfile); - } else { - profile.setCallingUid(activeProfile.getCallingUid()); - } - } - } - - private SipProfile getProfileFromList(SipProfile activeProfile) { - for (SipProfile p : mSipProfileList) { - if (p.getUriString().equals(activeProfile.getUriString())) { - return p; - } - } - return null; - } - - private void addPreferenceFor(SipProfile p) { - String status; - Log.v(TAG, "addPreferenceFor profile uri" + p.getUri()); - SipPreference pref = new SipPreference(this, p); - mSipPreferenceMap.put(p.getUriString(), pref); - mSipListContainer.addPreference(pref); - - pref.setOnPreferenceClickListener( - new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference pref) { - handleProfileClick(((SipPreference) pref).mProfile); - return true; - } - }); - } - - private void handleProfileClick(final SipProfile profile) { - int uid = profile.getCallingUid(); - if (uid == mUid || uid == 0) { - startSipEditor(profile); - return; - } - new AlertDialog.Builder(this) - .setTitle(R.string.alert_dialog_close) - .setIconAttribute(android.R.attr.alertDialogIcon) - .setPositiveButton(R.string.close_profile, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int w) { - deleteProfile(profile); - unregisterProfile(profile); - } - }) - .setNegativeButton(android.R.string.cancel, null) - .show(); - } - - private void unregisterProfile(final SipProfile p) { - // run it on background thread for better UI response - new Thread(new Runnable() { - @Override - public void run() { - try { - mSipManager.close(p.getUriString()); - } catch (Exception e) { - Log.e(TAG, "unregister failed, SipService died?", e); - } - } - }, "unregisterProfile").start(); - } - - void deleteProfile(SipProfile p) { - mSipProfileList.remove(p); - SipPreference pref = mSipPreferenceMap.remove(p.getUriString()); - mSipListContainer.removePreference(pref); - } - - private void addProfile(SipProfile p) throws IOException { - try { - mSipManager.setRegistrationListener(p.getUriString(), - createRegistrationListener()); - } catch (Exception e) { - Log.e(TAG, "cannot set registration listener", e); - } - mSipProfileList.add(p); - addPreferenceFor(p); - } - - private void startSipEditor(final SipProfile profile) { - mProfile = profile; - Intent intent = new Intent(this, SipEditor.class); - intent.putExtra(KEY_SIP_PROFILE, (Parcelable) profile); - startActivityForResult(intent, REQUEST_ADD_OR_EDIT_SIP_PROFILE); - } - - private void showRegistrationMessage(final String profileUri, - final String message) { - runOnUiThread(new Runnable() { - @Override - public void run() { - SipPreference pref = mSipPreferenceMap.get(profileUri); - if (pref != null) { - pref.updateSummary(message); - } - } - }); - } - - private SipRegistrationListener createRegistrationListener() { - return new SipRegistrationListener() { - @Override - public void onRegistrationDone(String profileUri, long expiryTime) { - showRegistrationMessage(profileUri, getString( - R.string.registration_status_done)); - } - - @Override - public void onRegistering(String profileUri) { - showRegistrationMessage(profileUri, getString( - R.string.registration_status_registering)); - } - - @Override - public void onRegistrationFailed(String profileUri, int errorCode, - String message) { - switch (errorCode) { - case SipErrorCode.IN_PROGRESS: - showRegistrationMessage(profileUri, getString( - R.string.registration_status_still_trying)); - break; - case SipErrorCode.INVALID_CREDENTIALS: - showRegistrationMessage(profileUri, getString( - R.string.registration_status_invalid_credentials)); - break; - case SipErrorCode.SERVER_UNREACHABLE: - showRegistrationMessage(profileUri, getString( - R.string.registration_status_server_unreachable)); - break; - case SipErrorCode.DATA_CONNECTION_LOST: - if (SipManager.isSipWifiOnly(getApplicationContext())){ - showRegistrationMessage(profileUri, getString( - R.string.registration_status_no_wifi_data)); - } else { - showRegistrationMessage(profileUri, getString( - R.string.registration_status_no_data)); - } - break; - case SipErrorCode.CLIENT_ERROR: - showRegistrationMessage(profileUri, getString( - R.string.registration_status_not_running)); - break; - default: - showRegistrationMessage(profileUri, getString( - R.string.registration_status_failed_try_later, - message)); - } - } - }; - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - super.onCreateOptionsMenu(menu); - menu.add(0, MENU_ADD_ACCOUNT, 0, R.string.add_sip_account) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - return true; - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - menu.findItem(MENU_ADD_ACCOUNT).setEnabled( - mCallManager.getState() == PhoneConstants.State.IDLE); - return super.onPrepareOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - final int itemId = item.getItemId(); - switch (itemId) { - case android.R.id.home: { - CallFeaturesSetting.goUpToTopLevelSetting(this); - return true; - } - case MENU_ADD_ACCOUNT: { - startSipEditor(null); - return true; - } - } - return super.onOptionsItemSelected(item); - } -} diff --git a/src/com/android/phone/sip/SipSharedPreferences.java b/src/com/android/phone/sip/SipSharedPreferences.java deleted file mode 100644 index e15db64ed..000000000 --- a/src/com/android/phone/sip/SipSharedPreferences.java +++ /dev/null @@ -1,109 +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.sip; - -import com.android.phone.R; - -import android.content.ContentResolver; -import android.content.Context; -import android.content.SharedPreferences; -import android.provider.Settings; -import android.provider.Settings.SettingNotFoundException; -import android.text.TextUtils; -import android.util.Log; - -/** - * Wrapper for SIP's shared preferences. - */ -public class SipSharedPreferences { - private static final String SIP_SHARED_PREFERENCES = "SIP_PREFERENCES"; - private static final String KEY_PRIMARY_ACCOUNT = "primary"; - private static final String KEY_NUMBER_OF_PROFILES = "profiles"; - - private SharedPreferences mPreferences; - private Context mContext; - - public SipSharedPreferences(Context context) { - mPreferences = context.getSharedPreferences( - SIP_SHARED_PREFERENCES, Context.MODE_WORLD_READABLE); - mContext = context; - } - - public void setPrimaryAccount(String accountUri) { - SharedPreferences.Editor editor = mPreferences.edit(); - editor.putString(KEY_PRIMARY_ACCOUNT, accountUri); - editor.apply(); - } - - public void unsetPrimaryAccount() { - setPrimaryAccount(null); - } - - /** Returns the primary account URI or null if it does not exist. */ - public String getPrimaryAccount() { - return mPreferences.getString(KEY_PRIMARY_ACCOUNT, null); - } - - public boolean isPrimaryAccount(String accountUri) { - return accountUri.equals( - mPreferences.getString(KEY_PRIMARY_ACCOUNT, null)); - } - - public boolean hasPrimaryAccount() { - return !TextUtils.isEmpty( - mPreferences.getString(KEY_PRIMARY_ACCOUNT, null)); - } - - public void setProfilesCount(int number) { - SharedPreferences.Editor editor = mPreferences.edit(); - editor.putInt(KEY_NUMBER_OF_PROFILES, number); - editor.apply(); - } - - public int getProfilesCount() { - return mPreferences.getInt(KEY_NUMBER_OF_PROFILES, 0); - } - - public void setSipCallOption(String option) { - Settings.System.putString(mContext.getContentResolver(), - Settings.System.SIP_CALL_OPTIONS, option); - } - - public String getSipCallOption() { - String option = Settings.System.getString(mContext.getContentResolver(), - Settings.System.SIP_CALL_OPTIONS); - return (option != null) ? option - : mContext.getString(R.string.sip_address_only); - } - - public void setReceivingCallsEnabled(boolean enabled) { - Settings.System.putInt(mContext.getContentResolver(), - Settings.System.SIP_RECEIVE_CALLS, (enabled ? 1 : 0)); - } - - public boolean isReceivingCallsEnabled() { - try { - return (Settings.System.getInt(mContext.getContentResolver(), - Settings.System.SIP_RECEIVE_CALLS) != 0); - } catch (SettingNotFoundException e) { - Log.d("SIP", "ReceiveCall option is not set; use default value"); - return false; - } - } - - // TODO: back up to Android Backup -} diff --git a/src/com/android/services/telephony/SipConnection.java b/src/com/android/services/telephony/SipConnection.java deleted file mode 100644 index 133a42d05..000000000 --- a/src/com/android/services/telephony/SipConnection.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2014 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.services.telephony; - -import android.telecomm.Connection; - -/** - * A {@link Connection} object for SIP calls. - */ -public class SipConnection extends TelephonyConnection { - - public SipConnection(com.android.internal.telephony.Connection connection) { - super(connection); - } - - // TODO: Fill in the below methods - - /** {@inheritDoc} */ - @Override - protected void onPlayDtmfTone(char c) { - super.onPlayDtmfTone(c); - } - - /** {@inheritDoc} */ - @Override - protected void onStopDtmfTone() { - super.onStopDtmfTone(); - } - - /** {@inheritDoc} */ - @Override - protected void onDisconnect() { - super.onDisconnect(); - } - - /** {@inheritDoc} */ - @Override - protected void onAbort() { - super.onAbort(); - } - - /** {@inheritDoc} */ - @Override - public void onHold() { - super.onHold(); - } - - /** {@inheritDoc} */ - @Override - protected void onUnhold() { - super.onUnhold(); - } - - /** {@inheritDoc} */ - @Override - protected void onAnswer() { - super.onAnswer(); - } - - /** {@inheritDoc} */ - @Override - protected void onReject() { - super.onReject(); - } -} diff --git a/src/com/android/services/telephony/SipConnectionService.java b/src/com/android/services/telephony/SipConnectionService.java deleted file mode 100644 index ea364bd4f..000000000 --- a/src/com/android/services/telephony/SipConnectionService.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2014 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.services.telephony; - -import android.content.Context; -import android.net.sip.SipException; -import android.net.sip.SipManager; -import android.net.sip.SipProfile; -import android.net.Uri; -import android.os.AsyncTask; -import android.provider.Settings; -import android.telephony.PhoneNumberUtils; - -import com.android.internal.telephony.Phone; -import com.android.internal.telephony.PhoneFactory; -import com.android.internal.telephony.sip.SipPhone; -import com.android.phone.Constants; -import com.android.phone.PhoneUtils; -import com.android.phone.sip.SipProfileDb; -import com.android.phone.sip.SipSharedPreferences; -import android.telecomm.Connection; -import android.telecomm.ConnectionRequest; -import android.telecomm.Response; - -import java.util.HashMap; - -/** - * Connection service that uses the SIP phone. - */ -public class SipConnectionService extends TelephonyConnectionService { - private static HashMap<String, SipPhone> sSipPhones = new HashMap<String, SipPhone>(); - - /** {@inheritDoc} */ - @Override - public void onCreateConnections( - ConnectionRequest request, - OutgoingCallResponse callback) { - new GetSipProfileTask(this, request, callback).execute(); - super.onCreateConnections(request, callback); - } - - /** {@inheritDoc} */ - @Override - public void onCreateIncomingConnection( - ConnectionRequest request, - Response<ConnectionRequest, Connection> callback) { - super.onCreateIncomingConnection(request, callback); - // TODO: fill in - } - - /** {@inheritDoc} */ - @Override - protected boolean canCall(Uri handle) { - return shouldUseSipPhone(handle.getScheme(), handle.getSchemeSpecificPart()); - } - - /** {@inheritDoc} */ - @Override - protected TelephonyConnection onCreateTelephonyConnection( - ConnectionRequest request, - Phone phone, - com.android.internal.telephony.Connection connection) { - return new SipConnection(connection); - } - - private boolean shouldUseSipPhone(String scheme, String number) { - // Scheme must be "sip" or "tel". - boolean isKnownCallScheme = Constants.SCHEME_TEL.equals(scheme) - || Constants.SCHEME_SIP.equals(scheme); - if (!isKnownCallScheme) { - return false; - } - - // Is voip supported - boolean voipSupported = PhoneUtils.isVoipSupported(); - if (!voipSupported) { - return false; - } - - // Check SIP address only - SipSharedPreferences sipSharedPreferences = new SipSharedPreferences(this); - String callOption = sipSharedPreferences.getSipCallOption(); - boolean isRegularNumber = Constants.SCHEME_TEL.equals(scheme) - && !PhoneNumberUtils.isUriNumber(number); - if (callOption.equals(Settings.System.SIP_ADDRESS_ONLY) && isRegularNumber) { - return false; - } - - // Check if no SIP profiles. - SipProfileDb sipProfileDb = new SipProfileDb(this); - if (sipProfileDb.getProfilesCount() == 0 && isRegularNumber) { - return false; - } - - return true; - } - - /** - * Asynchronously looks up the SIP profile to use for the given call. - */ - private class GetSipProfileTask extends AsyncTask<Void, Void, SipProfile> { - private final ConnectionRequest mRequest; - private final OutgoingCallResponse mResponse; - private final SipProfileDb mSipProfileDb; - private final SipSharedPreferences mSipSharedPreferences; - - GetSipProfileTask( - Context context, - ConnectionRequest request, - OutgoingCallResponse response) { - mRequest = request; - mResponse = response; - mSipProfileDb = new SipProfileDb(context); - mSipSharedPreferences = new SipSharedPreferences(context); - } - - @Override - protected SipProfile doInBackground(Void... params) { - String primarySipUri = mSipSharedPreferences.getPrimaryAccount(); - for (SipProfile profile : mSipProfileDb.retrieveSipProfileList()) { - if (profile.getUriString().equals(primarySipUri)) { - return profile; - } - } - // TODO(sail): Handle non-primary profiles by showing dialog. - return null; - } - - @Override - protected void onPostExecute(SipProfile profile) { - onSipProfileChosen(profile, mRequest, mResponse); - } - } - - private void onSipProfileChosen( - SipProfile profile, - ConnectionRequest request, - OutgoingCallResponse response) { - SipPhone phone = null; - if (profile != null) { - String sipUri = profile.getUriString(); - phone = sSipPhones.get(sipUri); - if (phone == null) { - try { - SipManager.newInstance(this).open(profile); - phone = (SipPhone) PhoneFactory.makeSipPhone(sipUri); - sSipPhones.put(sipUri, phone); - } catch (SipException e) { - Log.e(this, e, "Failed to make a SIP phone"); - } - } - } - startCallWithPhone(phone, request, response); - } -} diff --git a/src/com/android/services/telephony/TelephonyCallServiceProvider.java b/src/com/android/services/telephony/TelephonyCallServiceProvider.java index 12bb2afaf..5225759fa 100644 --- a/src/com/android/services/telephony/TelephonyCallServiceProvider.java +++ b/src/com/android/services/telephony/TelephonyCallServiceProvider.java @@ -34,11 +34,6 @@ public class TelephonyCallServiceProvider extends CallServiceProvider { .setConnectionService(PstnConnectionService.class) .setNetworkType(CallServiceDescriptor.FLAG_PSTN) .build()); - descriptors.add(CallServiceDescriptor.newBuilder(this) - .setConnectionService(SipConnectionService.class) - .setNetworkType(CallServiceDescriptor.FLAG_WIFI | - CallServiceDescriptor.FLAG_MOBILE) - .build()); response.setCallServiceDescriptors(descriptors); } } |