diff --git a/res/drawable-hdpi/transfer_call_default.png b/res/drawable-hdpi/transfer_call_default.png new file mode 100644 index 000000000..b67e4509e Binary files /dev/null and b/res/drawable-hdpi/transfer_call_default.png differ diff --git a/res/drawable-hdpi/transfer_call_disabled.png b/res/drawable-hdpi/transfer_call_disabled.png new file mode 100644 index 000000000..0307f6bf8 Binary files /dev/null and b/res/drawable-hdpi/transfer_call_disabled.png differ diff --git a/res/drawable-hdpi/transfer_call_over.png b/res/drawable-hdpi/transfer_call_over.png new file mode 100644 index 000000000..9f3e9ac36 Binary files /dev/null and b/res/drawable-hdpi/transfer_call_over.png differ diff --git a/res/drawable-mdpi/transfer_call_default.png b/res/drawable-mdpi/transfer_call_default.png new file mode 100644 index 000000000..5aca8f393 Binary files /dev/null and b/res/drawable-mdpi/transfer_call_default.png differ diff --git a/res/drawable-mdpi/transfer_call_disabled.png b/res/drawable-mdpi/transfer_call_disabled.png new file mode 100644 index 000000000..980d22d90 Binary files /dev/null and b/res/drawable-mdpi/transfer_call_disabled.png differ diff --git a/res/drawable-mdpi/transfer_call_over.png b/res/drawable-mdpi/transfer_call_over.png new file mode 100644 index 000000000..dac92025a Binary files /dev/null and b/res/drawable-mdpi/transfer_call_over.png differ diff --git a/res/drawable/plus.xml b/res/drawable/add_call.xml similarity index 100% rename from res/drawable/plus.xml rename to res/drawable/add_call.xml diff --git a/res/drawable/transfer_call.xml b/res/drawable/transfer_call.xml new file mode 100644 index 000000000..68248239d --- /dev/null +++ b/res/drawable/transfer_call.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/res/layout/dialer.xml b/res/layout/dialer.xml index 2b620844e..e3afe8c62 100644 --- a/res/layout/dialer.xml +++ b/res/layout/dialer.xml @@ -13,6 +13,7 @@ android:textSize="22dp" android:background="@drawable/dialer_address_background" android:inputType="textEmailAddress" + android:hint="@string/addressHint" android:paddingLeft="20dp" android:paddingRight="20dp" android:layout_weight="0.4" diff --git a/res/values/strings.xml b/res/values/strings.xml index 9e18302af..5a8a8bcde 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -166,153 +166,157 @@ g729 Codecs Place a call -Debug -Report issue -Describe problem here -Error generating bug report -Logs not found. -Reading logs, may takes time... -Send bug report with... -About -Audio -Exit -Prefix -Advanced -Settings -Proxy -Domain* -Password* -Username* -Hello World, Linphone! -SIP Account -wrong user name -wrong password -Wrong domain -Wrong settings -Dialer -Contact -Cannot call %s -Yes -No -Dismiss -Continue -Never remind me -%s, do you want to go to the settings page ? -<P ALIGN=CENTER>No SIP account has been configured yet, do you want to go to the settings page ?<br/><br/> Need help ?<br/> "http://www.linphone.org/m/help"</p> -<P ALIGN=CENTER>Welcome to Linphone SIP phone<br/><br/> If you are new to SIP, have a look at<br/> "http://www.linphone.org/m/help"</p> -Starting echo cancelation audio calibration -Cannot initiate a new call because a call is already engaged -History -Cannot build destination address from [%s] -Clear -Cannot get call parameters -Cannot create default call parameters -Cannot invite destination address [%s] - -started -Removes the echo heard by other end (not recommended) -Removes the echo heard by other end (brute force method) -Stun server -Calibrating... -Calibrated [%s ms] -failed -Enter your username and password to connect to the service. -Username -Password -Connect -Please enter your login and password -Couldn\'t connect; check your login and password and start again - -AMR codec might not be present on your phone -VP8 -Media encryption -None -SRTP -ZRTP - -Your correspondent would like to switch to video -Accept video -Deny video - -pref_nb_accounts_extra -pref_default_account -SIP Accounts - -Use wifi only - -An error occurred, try again later. -Server unreachable, verify your internet connection. -This username is already in use. -Your username is not valid. -Your email is not valid. -Your password is not valid (6 characters min). -Passwords entered are different. - -SIP proxy hostname or ip address (optional) -Route all calls through SIP proxy -Example: john if your account is john@sip.linphone.org -sip.linphone.org if your account is john@sip.linphone.org - -Delete -Chat -Call -Add to contacts -CONNECTED -NOT CONNECTED -CONNECTING -ERROR - - -Add to contacts button - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Account Setup Assistant -This assistant will help you to use a SIP account for your calls. -Create an account on linphone.org -I already have a linphone.org account -I already have a SIP account -Enter your linphone.org username and password -Apply -username -password -domain -confirm password -email -Create Account -An email has been sent to the address you gave. In order to activate your account, you need to click on the link inside it. Once it is done, come back here and click on the button above. -Check -Your account has not been validated yet. -Your account has been validated. + + Debug + Report issue + Describe problem here + Error generating bug report + Logs not found. + Reading logs, may takes time... + Send bug report with... + About + Audio + Exit + Prefix + Advanced + Settings + Proxy + Domain* + Password* + Username* + Hello World, Linphone! + SIP Account + wrong user name + wrong password + Wrong domain + Wrong settings + Dialer + Contact + Cannot call %s + Yes + No + Dismiss + Continue + Never remind me + %s, do you want to go to the settings page ? + <P ALIGN=CENTER>No SIP account has been configured yet, do you want to go to the settings page ?<br/><br/> Need help ?<br/> "http://www.linphone.org/m/help"</p> + <P ALIGN=CENTER>Welcome to Linphone SIP phone<br/><br/> If you are new to SIP, have a look at<br/> "http://www.linphone.org/m/help"</p> + Starting echo cancelation audio calibration + Cannot initiate a new call because a call is already engaged + History + Cannot build destination address from [%s] + Clear + Cannot get call parameters + Cannot create default call parameters + Cannot invite destination address [%s] + + started + Removes the echo heard by other end (not recommended) + Removes the echo heard by other end (brute force method) + Stun server + Calibrating... + Calibrated [%s ms] + failed + Enter your username and password to connect to the service. + Username + Password + Connect + Please enter your login and password + Couldn\'t connect; check your login and password and start again + + AMR codec might not be present on your phone + VP8 + Media encryption + None + SRTP + ZRTP + + Your correspondent would like to switch to video + Accept video + Deny video + + pref_nb_accounts_extra + pref_default_account + SIP Accounts + + Use wifi only + + An error occurred, try again later. + Server unreachable, verify your internet connection. + This username is already in use. + Your username is not valid. + Your email is not valid. + Your password is not valid (6 characters min). + Passwords entered are different. + + SIP proxy hostname or ip address (optional) + Route all calls through SIP proxy + Example: john if your account is john@sip.linphone.org + sip.linphone.org if your account is john@sip.linphone.org + + Delete + Chat + Call + Add to contacts + CONNECTED + NOT CONNECTED + CONNECTING + ERROR + + Number or adress + + + Add to contacts button + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Account Setup Assistant + This assistant will help you to use a SIP account for your calls. + Create an account on linphone.org + I already have a linphone.org account + I already have a SIP account + Enter your linphone.org username and password + Apply + username + password + domain + confirm password + email + Create Account + An email has been sent to the address you gave. In order to activate your account, you need to click on the link inside it. Once it is done, come back here and click on the button above. + Check + Your account has not been validated yet. + Your account has been validated. + diff --git a/src/org/linphone/DialerFragment.java b/src/org/linphone/DialerFragment.java index 1e7e4be96..05ae80e69 100644 --- a/src/org/linphone/DialerFragment.java +++ b/src/org/linphone/DialerFragment.java @@ -18,6 +18,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ import org.linphone.compatibility.Compatibility; +import org.linphone.core.LinphoneCore; import org.linphone.ui.AddressAware; import org.linphone.ui.AddressText; import org.linphone.ui.CallButton; @@ -39,11 +40,13 @@ import android.widget.ImageView; */ public class DialerFragment extends Fragment { private static DialerFragment instance; + private static boolean isCallTransferOngoing = false; + public boolean mVisible; private AddressText mAddress; private CallButton mCall; private ImageView mAddContact; - private OnClickListener addContactListener, cancelListener; + private OnClickListener addContactListener, cancelListener, transferListener; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -59,7 +62,11 @@ public class DialerFragment extends Fragment { mCall = (CallButton) view.findViewById(R.id.Call); mCall.setAddressWidget(mAddress); if (LinphoneActivity.isInstanciated() && LinphoneManager.getLc().getCallsNb() > 0) { - mCall.setImageResource(R.drawable.plus); + if (isCallTransferOngoing) { + mCall.setImageResource(R.drawable.transfer_call); + } else { + mCall.setImageResource(R.drawable.add_call); + } } else { mCall.setImageResource(R.drawable.call); } @@ -69,6 +76,7 @@ public class DialerFragment extends Fragment { numpad.setAddressWidget(mAddress); mAddContact = (ImageView) view.findViewById(R.id.addContact); + addContactListener = new OnClickListener() { @Override public void onClick(View v) { @@ -82,8 +90,21 @@ public class DialerFragment extends Fragment { LinphoneActivity.instance().resetClassicMenuLayoutAndGoBackToCallIfStillRunning(); } }; + transferListener = new OnClickListener() { + @Override + public void onClick(View v) { + LinphoneCore lc = LinphoneManager.getLc(); + if (lc.getCurrentCall() == null) { + return; + } + lc.transferCall(lc.getCurrentCall(), mAddress.getText().toString()); + isCallTransferOngoing = false; + LinphoneActivity.instance().resetClassicMenuLayoutAndGoBackToCallIfStillRunning(); + } + }; + mAddContact.setEnabled(!(LinphoneActivity.isInstanciated() && LinphoneManager.getLc().getCallsNb() > 0)); - resetLayout(); + resetLayout(isCallTransferOngoing); if (getArguments() != null) { String number = getArguments().getString("SipUri"); @@ -123,17 +144,24 @@ public class DialerFragment extends Fragment { LinphoneActivity.instance().selectMenu(FragmentsAvailable.DIALER); LinphoneActivity.instance().updateDialerFragment(this); } - resetLayout(); + resetLayout(isCallTransferOngoing); } - public void resetLayout() { + public void resetLayout(boolean callTransfer) { + isCallTransferOngoing = callTransfer; if (LinphoneManager.getLc() != null && LinphoneManager.getLc().getCallsNb() > 0) { - mCall.setImageResource(R.drawable.plus); - mAddress.setText(""); + if (isCallTransferOngoing) { + mCall.setImageResource(R.drawable.transfer_call); + mCall.setExternalClickListener(transferListener); + } else { + mCall.setImageResource(R.drawable.add_call); + mCall.resetClickListener(); + } mAddContact.setEnabled(true); mAddContact.setImageResource(R.drawable.cancel); mAddContact.setOnClickListener(cancelListener); } else { + mAddress.setText(""); mCall.setImageResource(R.drawable.call); mAddContact.setEnabled(true); mAddContact.setImageResource(R.drawable.add_contact); diff --git a/src/org/linphone/InCallActivity.java b/src/org/linphone/InCallActivity.java index 0333034a2..5bbb7a512 100644 --- a/src/org/linphone/InCallActivity.java +++ b/src/org/linphone/InCallActivity.java @@ -30,6 +30,7 @@ import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration; import org.linphone.ui.Numpad; import android.app.Activity; +import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; @@ -242,7 +243,7 @@ public class InCallActivity extends FragmentActivity implements } } else if (id == R.id.transfer) { - //TODO Call Transfer + goBackToDialerAndDisplayTransferButton(); } else if (id == R.id.options) { hideOrDisplayCallOptions(); @@ -579,11 +580,21 @@ public class InCallActivity extends FragmentActivity implements } addCall.startAnimation(anim); } + transfer.setEnabled(LinphoneManager.getLc().getCurrentCall() != null); } } public void goBackToDialer() { - setResult(Activity.RESULT_FIRST_USER); + Intent intent = new Intent(); + intent.putExtra("Transfer", false); + setResult(Activity.RESULT_FIRST_USER, intent); + finish(); + } + + private void goBackToDialerAndDisplayTransferButton() { + Intent intent = new Intent(); + intent.putExtra("Transfer", true); + setResult(Activity.RESULT_FIRST_USER, intent); finish(); } @@ -614,6 +625,8 @@ public class InCallActivity extends FragmentActivity implements } }); } + + transfer.setEnabled(LinphoneManager.getLc().getCurrentCall() != null); } @Override diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index 815fb1d7b..ce4f6f37b 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -595,7 +595,9 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene AddressType address = new AddressText(this, null); address.setDisplayedName(name); address.setText(number); - LinphoneManager.getInstance().newOutgoingCall(address); + if (LinphoneManager.getLc().getCallsNb() == 0) { + LinphoneManager.getInstance().newOutgoingCall(address); + } } public void setAddressAndGoToDialer(String number) { @@ -726,10 +728,10 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene contactsHandler.start(); } - private void initInCallMenuLayout() { + private void initInCallMenuLayout(boolean callTransfer) { selectMenu(FragmentsAvailable.DIALER); if (dialerFragment != null) { - ((DialerFragment) dialerFragment).resetLayout(); + ((DialerFragment) dialerFragment).resetLayout(callTransfer); } } @@ -738,7 +740,7 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene @Override public void run() { if (dialerFragment != null) { - ((DialerFragment) dialerFragment).resetLayout(); + ((DialerFragment) dialerFragment).resetLayout(false); } if (LinphoneManager.getLc().getCallsNb() > 0) { @@ -781,8 +783,9 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene } } else if (requestCode == callActivity) { + boolean callTransfer = data == null ? false : data.getBooleanExtra("Transfer", false); if (LinphoneManager.getLc().getCallsNb() > 0) { - initInCallMenuLayout(); + initInCallMenuLayout(callTransfer); } else { resetClassicMenuLayoutAndGoBackToCallIfStillRunning(); } diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index d68b7eb4c..d3eb9802c 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -692,7 +692,13 @@ public final class LinphoneManager implements LinphoneCoreListener { //init network state NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo(); - mLc.setNetworkReachable(networkInfo !=null? networkInfo.getState() == NetworkInfo.State.CONNECTED:false); + SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(mServiceContext); + boolean wifiOnly = pref.getBoolean(getString(R.string.pref_wifi_only_key), false); + boolean isConnected = false; + if (networkInfo != null) { + isConnected = networkInfo.getState() == NetworkInfo.State.CONNECTED && (networkInfo.getTypeName().equals("WIFI") || (networkInfo.getTypeName().equals("mobile") && !wifiOnly)); + } + mLc.setNetworkReachable(isConnected); } catch (LinphoneCoreException e) { throw new LinphoneConfigException(getString(R.string.wrong_settings),e); } @@ -820,14 +826,14 @@ public final class LinphoneManager implements LinphoneCoreListener { I/Linphone( 8397): Managing tunnel I/Linphone( 8397): WIFI connected: setting network reachable */ - public void connectivityChanged(NetworkInfo eventInfo, ConnectivityManager cm) { - NetworkInfo activeInfo = cm.getActiveNetworkInfo(); + public void connectivityChanged(ConnectivityManager cm, boolean noConnectivity) { + NetworkInfo eventInfo = cm.getActiveNetworkInfo(); - if (eventInfo.getState() == NetworkInfo.State.DISCONNECTED) { - Log.i(eventInfo.getTypeName()," disconnected: setting network unreachable"); + if (noConnectivity || eventInfo == null || eventInfo.getState() == NetworkInfo.State.DISCONNECTED) { + Log.i("No connectivity: setting network unreachable"); mLc.setNetworkReachable(false); } else if (eventInfo.getState() == NetworkInfo.State.CONNECTED){ - manageTunnelServer(activeInfo); + manageTunnelServer(eventInfo); SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(mServiceContext); boolean wifiOnly = pref.getBoolean(getString(R.string.pref_wifi_only_key), false); if (eventInfo.getTypeName().equals("WIFI") || (eventInfo.getTypeName().equals("mobile") && !wifiOnly)) { @@ -840,20 +846,6 @@ public final class LinphoneManager implements LinphoneCoreListener { } } - - - - - - - - - - - - - - public interface EcCalibrationListener { void onEcCalibrationStatus(EcCalibratorStatus status, int delayMs); } diff --git a/src/org/linphone/NetworkManager.java b/src/org/linphone/NetworkManager.java index ac2fb0c39..652f2c970 100644 --- a/src/org/linphone/NetworkManager.java +++ b/src/org/linphone/NetworkManager.java @@ -18,15 +18,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone; -import org.linphone.core.Log; - import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.preference.PreferenceManager; @@ -39,34 +34,9 @@ public class NetworkManager extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo lNetworkInfo = cm.getActiveNetworkInfo(); - Log.i("Network info [",lNetworkInfo,"]"); Boolean lNoConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,false); - - - if (!LinphoneService.isReady()) { - Log.i("Network broadcast received while Linphone service not ready"); - return; - } - - - if (lNoConnectivity | ((lNetworkInfo.getState() == NetworkInfo.State.DISCONNECTED) /*&& !lIsFailOver*/)) { - LinphoneManager.getLc().setNetworkReachable(false); - } else if (lNetworkInfo.getState() == NetworkInfo.State.CONNECTED){ - SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context); - boolean wifiOnly = pref.getBoolean(context.getString(R.string.pref_wifi_only_key), false); - if (lNetworkInfo.getTypeName().equals("WIFI") || (lNetworkInfo.getTypeName().equals("mobile") && !wifiOnly)) { - LinphoneManager.getLc().setNetworkReachable(true); - } else { - LinphoneManager.getLc().setNetworkReachable(false); - } - } else { - // Other unhandled events - } - - LinphoneManager.getInstance().connectivityChanged(lNetworkInfo, cm); + LinphoneManager.getInstance().connectivityChanged(cm, lNoConnectivity); } } diff --git a/src/org/linphone/StatusFragment.java b/src/org/linphone/StatusFragment.java index 0607a99c4..3f0599b40 100644 --- a/src/org/linphone/StatusFragment.java +++ b/src/org/linphone/StatusFragment.java @@ -342,8 +342,11 @@ public class StatusFragment extends Fragment { checkBox.setChecked(true); checkBox.setEnabled(false); - LinphoneManager.getLc().setDefaultProxyConfig(accounts[selectedPosition]); - LinphoneManager.getLc().refreshRegisters(); + LinphoneCore lc = LinphoneManager.getLc(); + lc.setDefaultProxyConfig(accounts[selectedPosition]); + if (lc.isNetworkReachable()) { + lc.refreshRegisters(); + } } } }; diff --git a/src/org/linphone/VideoCallFragment.java b/src/org/linphone/VideoCallFragment.java index 9b8f30fb5..5e1d10400 100644 --- a/src/org/linphone/VideoCallFragment.java +++ b/src/org/linphone/VideoCallFragment.java @@ -49,7 +49,7 @@ public class VideoCallFragment extends Fragment implements OnGestureListener, On private AndroidVideoWindowImpl androidVideoWindowImpl; private InCallActivity inCallActivity; private GestureDetector mGestureDetector; - private float mZoomFactor; + private float mZoomFactor = 1; private float mZoomCenterX, mZoomCenterY; @SuppressWarnings("deprecation") // Warning useless because value is ignored and automatically set by new APIs. diff --git a/src/org/linphone/ui/CallButton.java b/src/org/linphone/ui/CallButton.java index 9acbb74eb..918912036 100644 --- a/src/org/linphone/ui/CallButton.java +++ b/src/org/linphone/ui/CallButton.java @@ -35,10 +35,10 @@ import android.widget.Toast; public class CallButton extends ImageView implements OnClickListener, AddressAware { private AddressText mAddress; - public void setAddressWidget(AddressText a) {mAddress = a;} + public void setAddressWidget(AddressText a) { mAddress = a; } - private OnClickListener externalClickListener; - public void setExternalClickListener(OnClickListener e) {externalClickListener = e;} + public void setExternalClickListener(OnClickListener e) { setOnClickListener(e); } + public void resetClickListener() { setOnClickListener(this); } public CallButton(Context context, AttributeSet attrs) { super(context, attrs); @@ -56,17 +56,11 @@ public class CallButton extends ImageView implements OnClickListener, AddressAwa LinphoneManager.getInstance().terminateCall(); onWrongDestinationAddress(); }; - - if (externalClickListener != null) externalClickListener.onClick(v); } - protected void onWrongDestinationAddress() { - Toast toast = Toast.makeText(getContext() + Toast.makeText(getContext() ,String.format(getResources().getString(R.string.warning_wrong_destination_address),mAddress.getText().toString()) - ,Toast.LENGTH_LONG); - toast.show(); + ,Toast.LENGTH_LONG).show(); } - - }