diff --git a/app/build.gradle b/app/build.gradle index f6ba9432e..6ba381ac7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,7 +59,7 @@ project.tasks['preBuild'].dependsOn 'getGitVersion' repositories { maven { // Replace snapshots by releases for releases ! - url "https://linphone.org/releases/maven_repository" + url "https://linphone.org/snapshots/maven_repository" } } @@ -72,7 +72,7 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 28 - versionCode 4120 + versionCode 4119 versionName "4.1" applicationId getPackageName() multiDexEnabled true @@ -167,7 +167,7 @@ dependencies { debugImplementation project(path: ":linphone-sdk-android", configuration: 'debug') } } else { - implementation "org.linphone:linphone-sdk-android:4.1-366-g1b22291" + implementation "org.linphone:linphone-sdk-android:4.1+" } } if (firebaseEnabled()) { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dee9a8d64..9361ef5cc 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -75,6 +75,7 @@ + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/java/org/linphone/LinphoneActivity.java b/app/src/main/java/org/linphone/LinphoneActivity.java index edd3ceaed..176a329dd 100644 --- a/app/src/main/java/org/linphone/LinphoneActivity.java +++ b/app/src/main/java/org/linphone/LinphoneActivity.java @@ -29,7 +29,6 @@ import android.app.FragmentTransaction; import android.app.KeyguardManager; import android.content.Context; import android.content.Intent; -import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -68,8 +67,7 @@ import java.util.Calendar; import java.util.Date; import java.util.List; import org.linphone.LinphoneManager.AddressType; -import org.linphone.assistant.AssistantActivity; -import org.linphone.assistant.RemoteProvisioningLoginActivity; +import org.linphone.assistant.MenuAssistantActivity; import org.linphone.call.CallActivity; import org.linphone.call.CallIncomingActivity; import org.linphone.call.CallOutgoingActivity; @@ -180,31 +178,6 @@ public class LinphoneActivity extends LinphoneGenericActivity LinphoneService.instance().removeForegroundServiceNotificationIfPossible(); - if (getResources().getBoolean(R.bool.orientation_portrait_only)) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - } - boolean useFirstLoginActivity = - getResources().getBoolean(R.bool.display_account_assistant_at_first_start); - if (LinphonePreferences.instance().isProvisioningLoginViewEnabled()) { - Intent wizard = new Intent(); - wizard.setClass(this, RemoteProvisioningLoginActivity.class); - wizard.putExtra("Domain", LinphoneManager.getInstance().wizardLoginViewDomain); - startActivity(wizard); - finish(); - return; - } else if (savedInstanceState == null - && (useFirstLoginActivity - && LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null - && LinphonePreferences.instance().isFirstLaunch())) { - if (LinphonePreferences.instance().getAccountCount() > 0) { - LinphonePreferences.instance().firstLaunchSuccessful(); - } else { - startActivity(new Intent().setClass(this, AssistantActivity.class)); - finish(); - return; - } - } - if (getResources().getBoolean(R.bool.use_linphone_tag)) { if (getPackageManager() .checkPermission( @@ -1028,7 +1001,7 @@ public class LinphoneActivity extends LinphoneGenericActivity } private void displayAssistant() { - startActivity(new Intent(LinphoneActivity.this, AssistantActivity.class)); + startActivity(new Intent(LinphoneActivity.this, MenuAssistantActivity.class)); } private void displayInapp() { @@ -1649,7 +1622,7 @@ public class LinphoneActivity extends LinphoneGenericActivity new Intent() .setClass( LinphoneManager.getInstance().getContext(), - AssistantActivity.class)); + MenuAssistantActivity.class)); finish(); } } else if (selectedItem.equals(getString(R.string.menu_settings))) { diff --git a/app/src/main/java/org/linphone/LinphoneLauncherActivity.java b/app/src/main/java/org/linphone/LinphoneLauncherActivity.java index eb4e1fbc1..71d2a7629 100644 --- a/app/src/main/java/org/linphone/LinphoneLauncherActivity.java +++ b/app/src/main/java/org/linphone/LinphoneLauncherActivity.java @@ -26,7 +26,7 @@ import android.content.Intent; import android.content.pm.ActivityInfo; import android.os.Bundle; import android.os.Handler; -import org.linphone.assistant.RemoteProvisioningActivity; +import org.linphone.assistant.MenuAssistantActivity; import org.linphone.settings.LinphonePreferences; /** Launch Linphone main activity when Service is ready. */ @@ -62,12 +62,11 @@ public class LinphoneLauncherActivity extends Activity { private void onServiceReady() { final Class classToStart; - /*if (getResources().getBoolean(R.bool.show_tutorials_instead_of_app)) { - classToStart = TutorialLauncherActivity.class; - } else */ - if (getResources().getBoolean(R.bool.display_sms_remote_provisioning_activity) - && LinphonePreferences.instance().isFirstRemoteProvisioning()) { - classToStart = RemoteProvisioningActivity.class; + + boolean useFirstLoginActivity = + getResources().getBoolean(R.bool.display_account_assistant_at_first_start); + if (useFirstLoginActivity && LinphonePreferences.instance().isFirstLaunch()) { + classToStart = MenuAssistantActivity.class; } else { classToStart = LinphoneActivity.class; } @@ -76,8 +75,12 @@ public class LinphoneLauncherActivity extends Activity { new Runnable() { @Override public void run() { - startActivity( - getIntent().setClass(LinphoneLauncherActivity.this, classToStart)); + Intent intent = new Intent(); + intent.setClass(LinphoneLauncherActivity.this, classToStart); + if (getIntent() != null && getIntent().getExtras() != null) { + intent.putExtras(getIntent().getExtras()); + } + startActivity(intent); } }, 500); diff --git a/app/src/main/java/org/linphone/LinphoneManager.java b/app/src/main/java/org/linphone/LinphoneManager.java index 75fe5b326..32da921b3 100644 --- a/app/src/main/java/org/linphone/LinphoneManager.java +++ b/app/src/main/java/org/linphone/LinphoneManager.java @@ -68,7 +68,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Timer; import java.util.TimerTask; -import org.linphone.assistant.AssistantActivity; +import org.linphone.assistant.PhoneAccountLinkingAssistantActivity; import org.linphone.call.CallActivity; import org.linphone.call.CallIncomingActivity; import org.linphone.call.CallManager; @@ -149,7 +149,6 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou private static boolean sExited; public final String configFile; - public String wizardLoginViewDomain = null; /** Called when the activity is first created. */ private final String mLPConfigXsd; @@ -380,7 +379,7 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou } else { progress.dismiss(); progress = null; - if (Build.VERSION.SDK_INT + /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { LinphoneManager.getLc() .reloadMsPlugins( @@ -391,7 +390,7 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou } else { // We need to restart due to bad android linker AssistantActivity.instance().restartApplication(); - } + }*/ } } }); @@ -1497,7 +1496,8 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou new Timestamp( LinphoneActivity.instance() .getResources() - .getInteger(R.integer.popup_time_interval)) + .getInteger( + R.integer.phone_number_linking_popup_time_interval)) .getTime(); long newDate = now + future; @@ -1536,9 +1536,9 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou @Override public void onClick(View view) { Intent assistant = new Intent(); - assistant.setClass(LinphoneActivity.instance(), AssistantActivity.class); - assistant.putExtra("LinkPhoneNumber", true); - assistant.putExtra("LinkPhoneNumberAsk", true); + assistant.setClass( + LinphoneActivity.instance(), + PhoneAccountLinkingAssistantActivity.class); mServiceContext.startActivity(assistant); dialog.dismiss(); } @@ -1639,11 +1639,6 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou LinphonePreferences prefs = LinphonePreferences.instance(); if (state == ConfiguringState.Successful) { - if (prefs.isProvisioningLoginViewEnabled()) { - ProxyConfig proxyConfig = lc.createProxyConfig(); - Address addr = proxyConfig.getIdentityAddress(); - wizardLoginViewDomain = addr.getDomain(); - } prefs.setPushNotificationEnabled(prefs.isPushNotificationEnabled()); } } diff --git a/app/src/main/java/org/linphone/assistant/AccountConnectionAssistantActivity.java b/app/src/main/java/org/linphone/assistant/AccountConnectionAssistantActivity.java new file mode 100644 index 000000000..14c338cfb --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/AccountConnectionAssistantActivity.java @@ -0,0 +1,271 @@ +package org.linphone.assistant; + +/* +AccountConnectionAssistantActivity.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.RelativeLayout; +import android.widget.Switch; +import android.widget.TextView; +import androidx.annotation.Nullable; +import org.linphone.R; +import org.linphone.core.AccountCreator; +import org.linphone.core.AccountCreatorListenerStub; +import org.linphone.core.DialPlan; +import org.linphone.core.tools.Log; + +public class AccountConnectionAssistantActivity extends AssistantActivity { + private RelativeLayout mPhoneNumberConnection, mUsernameConnection; + private Switch mUsernameConnectionSwitch; + private EditText mPrefix, mPhoneNumber, mUsername, mPassword; + private TextView mCountryPicker, mError, mConnect; + private ImageView mPhoneNumberInfos; + + private AccountCreatorListenerStub mListener; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.assistant_account_connection); + + mPhoneNumberConnection = findViewById(R.id.phone_number_form); + + mUsernameConnection = findViewById(R.id.username_form); + + mUsernameConnectionSwitch = findViewById(R.id.username_login); + mUsernameConnectionSwitch.setOnCheckedChangeListener( + new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + mPhoneNumberConnection.setVisibility(isChecked ? View.GONE : View.VISIBLE); + mUsernameConnection.setVisibility(isChecked ? View.VISIBLE : View.GONE); + } + }); + + mConnect = findViewById(R.id.assistant_login); + mConnect.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + mAccountCreator.setDomain(getString(R.string.default_domain)); + mConnect.setEnabled(false); + + if (mUsernameConnectionSwitch.isChecked()) { + mAccountCreator.setUsername(mUsername.getText().toString()); + mAccountCreator.setPassword(mPassword.getText().toString()); + + createProxyConfigAndLeaveAssistant(); + } else { + mAccountCreator.setUsername(mPhoneNumber.getText().toString()); + + AccountCreator.Status status = mAccountCreator.recoverAccount(); + if (status != AccountCreator.Status.RequestOk) { + Log.e("[Account Connection] recoverAccount returned " + status); + mConnect.setEnabled(true); + showGenericErrorDialog(status); + } + } + } + }); + mConnect.setEnabled(false); + + if (getResources().getBoolean(R.bool.use_phone_number_validation)) { + if (getResources().getBoolean(R.bool.isTablet)) { + mUsernameConnectionSwitch.setChecked(true); + } else { + mUsernameConnection.setVisibility(View.GONE); + } + } else { + mPhoneNumberConnection.setVisibility(View.GONE); + findViewById(R.id.username_switch_layout).setVisibility(View.GONE); + } + + mCountryPicker = findViewById(R.id.select_country); + mCountryPicker.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + showCountryPickerDialog(); + } + }); + + mError = findViewById(R.id.phone_number_error); + + mPrefix = findViewById(R.id.dial_code); + mPrefix.setText("+"); + mPrefix.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + String prefix = s.toString(); + if (prefix.startsWith("+")) { + prefix = prefix.substring(1); + } + DialPlan dp = getDialPlanFromPrefix(prefix); + if (dp != null) { + mCountryPicker.setText(dp.getCountry()); + } + + updateConnectButtonAndDisplayError(); + } + }); + + mPhoneNumber = findViewById(R.id.phone_number); + mPhoneNumber.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + updateConnectButtonAndDisplayError(); + } + }); + + mPhoneNumberInfos = findViewById(R.id.info_phone_number); + mPhoneNumberInfos.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + showPhoneNumberDialog(); + } + }); + + mUsername = findViewById(R.id.assistant_username); + mUsername.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + mConnect.setEnabled(s.length() > 0 && mPassword.getText().length() > 0); + } + }); + + mPassword = findViewById(R.id.assistant_password); + mPassword.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + mConnect.setEnabled(s.length() > 0 && mUsername.getText().length() > 0); + } + }); + + mListener = + new AccountCreatorListenerStub() { + @Override + public void onRecoverAccount( + AccountCreator creator, AccountCreator.Status status, String resp) { + Log.i("[Account Connection] onRecoverAccount status is " + status); + if (status.equals(AccountCreator.Status.RequestOk)) { + Intent intent = + new Intent( + AccountConnectionAssistantActivity.this, + PhoneAccountValidationAssistantActivity.class); + intent.putExtra("isLoginVerification", true); + startActivity(intent); + } else { + mConnect.setEnabled(true); + showGenericErrorDialog(status); + } + } + }; + } + + @Override + protected void onResume() { + super.onResume(); + + mAccountCreator.addListener(mListener); + + DialPlan dp = getDialPlanForCurrentCountry(); + displayDialPlan(dp); + + String phoneNumber = getDevicePhoneNumber(); + if (phoneNumber != null) { + mPhoneNumber.setText(phoneNumber); + } + } + + @Override + protected void onPause() { + super.onPause(); + mAccountCreator.removeListener(mListener); + } + + @Override + public void onCountryClicked(DialPlan dialPlan) { + super.onCountryClicked(dialPlan); + displayDialPlan(dialPlan); + } + + private void updateConnectButtonAndDisplayError() { + if (mPrefix.getText().toString().isEmpty() || mPhoneNumber.getText().toString().isEmpty()) + return; + + int status = arePhoneNumberAndPrefixOk(mPrefix, mPhoneNumber); + if (status == AccountCreator.PhoneNumberStatus.Ok.toInt()) { + mConnect.setEnabled(true); + mError.setText(""); + mError.setVisibility(View.INVISIBLE); + } else { + mConnect.setEnabled(false); + mError.setText(getErrorFromPhoneNumberStatus(status)); + mError.setVisibility(View.VISIBLE); + } + } + + private void displayDialPlan(DialPlan dp) { + if (dp != null) { + mPrefix.setText("+" + dp.getCountryCallingCode()); + mCountryPicker.setText(dp.getCountry()); + } + } +} diff --git a/app/src/main/java/org/linphone/assistant/AssistantActivity.java b/app/src/main/java/org/linphone/assistant/AssistantActivity.java index 083d93eb5..98e9ebc24 100644 --- a/app/src/main/java/org/linphone/assistant/AssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/AssistantActivity.java @@ -1,7 +1,8 @@ package org.linphone.assistant; + /* AssistantActivity.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France +Copyright (C) 2019 Belledonne Communications, Grenoble, France This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -18,941 +19,251 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import android.Manifest; -import android.app.ActivityManager; -import android.app.AlarmManager; import android.app.AlertDialog; -import android.app.Dialog; -import android.app.Fragment; -import android.app.FragmentTransaction; -import android.app.PendingIntent; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.res.Configuration; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.view.LayoutInflater; +import android.telephony.TelephonyManager; import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; import android.view.WindowManager; -import android.view.inputmethod.InputMethodManager; -import android.widget.BaseAdapter; -import android.widget.Filter; -import android.widget.Filterable; +import android.widget.EditText; import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.widget.Toast; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; import org.linphone.LinphoneActivity; -import org.linphone.LinphoneLauncherActivity; import org.linphone.LinphoneManager; -import org.linphone.LinphoneService; import org.linphone.R; import org.linphone.core.AccountCreator; -import org.linphone.core.AccountCreatorListener; -import org.linphone.core.Address; -import org.linphone.core.AuthInfo; -import org.linphone.core.ConfiguringState; import org.linphone.core.Core; -import org.linphone.core.CoreListenerStub; import org.linphone.core.DialPlan; import org.linphone.core.Factory; import org.linphone.core.ProxyConfig; -import org.linphone.core.RegistrationState; -import org.linphone.core.TransportType; import org.linphone.core.tools.Log; -import org.linphone.core.tools.OpenH264DownloadHelper; -import org.linphone.fragments.StatusFragment; -import org.linphone.mediastream.Version; import org.linphone.settings.LinphonePreferences; -import org.linphone.utils.LinphoneUtils; import org.linphone.utils.ThemableActivity; -public class AssistantActivity extends ThemableActivity - implements OnClickListener, - ActivityCompat.OnRequestPermissionsResultCallback, - AccountCreatorListener { - private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 201; - private static final int PERMISSIONS_REQUEST_CAMERA = 202; +public abstract class AssistantActivity extends ThemableActivity + implements CountryPicker.CountryPickedListener { + protected static AccountCreator mAccountCreator; - private static AssistantActivity sInstance; + protected View mTopBar, mStatusBar; + protected ImageView mBack; + protected AlertDialog mCountryPickerDialog; - public DialPlan country; - - private ImageView mBack /*, mCancel*/; - private AssistantFragmentsEnum mCurrentFragment; - private AssistantFragmentsEnum mLastFragment; - private AssistantFragmentsEnum mFirstFragment; - private Fragment mFragment; - private LinphonePreferences mPrefs; - private boolean mAccountCreated = false, - mNewAccount = false, - mIsLink = false, - mFromPref = false; - private CoreListenerStub mListener; - private Address mAddress; - private StatusFragment mStatus; - private ProgressDialog mProgress; - private Dialog mDialog; - private boolean mRemoteProvisioningInProgress; - private boolean mEchoCancellerAlreadyDone; - private AccountCreator mAccountCreator; - private CountryListAdapter mCountryListAdapter; - private LinearLayout mTopBar; - - public static AssistantActivity instance() { - return sInstance; - } + protected CountryPicker mCountryPicker; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (getResources().getBoolean(R.bool.orientation_portrait_only)) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + if (mAccountCreator == null) { + String url = LinphonePreferences.instance().getXmlrpcUrl(); + Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + core.loadConfigFromXml(LinphoneManager.getInstance().getDefaultDynamicConfigFile()); + mAccountCreator = core.createAccountCreator(url); } - - setContentView(R.layout.assistant); - initUI(); - - if (getIntent().getBooleanExtra("LinkPhoneNumber", false)) { - mIsLink = true; - if (getIntent().getBooleanExtra("FromPref", false)) mFromPref = true; - displayCreateAccount(); - } else { - mFirstFragment = - getResources().getBoolean(R.bool.assistant_use_linphone_login_as_first_fragment) - ? AssistantFragmentsEnum.LINPHONE_LOGIN - : AssistantFragmentsEnum.WELCOME; - if (mFirstFragment == AssistantFragmentsEnum.WELCOME) { - mFirstFragment = - getResources() - .getBoolean( - R.bool.assistant_use_create_linphone_account_as_first_fragment) - ? AssistantFragmentsEnum.CREATE_ACCOUNT - : AssistantFragmentsEnum.WELCOME; - } - - if (findViewById(R.id.fragment_container) != null) { - if (savedInstanceState == null) { - display(mFirstFragment); - } else { - mCurrentFragment = - (AssistantFragmentsEnum) - savedInstanceState.getSerializable("CurrentFragment"); - } - } - } - if (savedInstanceState != null && savedInstanceState.containsKey("echoCanceller")) { - mEchoCancellerAlreadyDone = savedInstanceState.getBoolean("echoCanceller"); - } else { - mEchoCancellerAlreadyDone = false; - } - mPrefs = LinphonePreferences.instance(); - mStatus.enableSideMenu(false); - - if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) { - mAccountCreator = - LinphoneManager.getLc() - .createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl()); - mAccountCreator.setListener(this); - } - - mCountryListAdapter = new CountryListAdapter(getApplicationContext()); - mListener = - new CoreListenerStub() { - - @Override - public void onConfiguringStatus( - Core lc, final ConfiguringState state, String message) { - if (mProgress != null) mProgress.dismiss(); - if (state == ConfiguringState.Successful) { - goToLinphoneActivity(); - } else if (state == ConfiguringState.Failed) { - Toast.makeText( - AssistantActivity.instance(), - getString(R.string.remote_provisioning_failure), - Toast.LENGTH_LONG) - .show(); - } - } - - @Override - public void onRegistrationStateChanged( - Core lc, ProxyConfig cfg, RegistrationState state, String smessage) { - if (mRemoteProvisioningInProgress) { - if (mProgress != null) mProgress.dismiss(); - if (state == RegistrationState.Ok) { - mRemoteProvisioningInProgress = false; - success(); - } - } else if (mAccountCreated && !mNewAccount) { - if (mAddress != null - && mAddress.asString() - .equals(cfg.getIdentityAddress().asString())) { - if (state == RegistrationState.Ok) { - if (mProgress != null) mProgress.dismiss(); - if (getResources() - .getBoolean(R.bool.use_phone_number_validation) - && cfg.getDomain() - .equals(getString(R.string.default_domain)) - && LinphoneManager.getLc().getDefaultProxyConfig() - != null) { - loadAccountCreator(cfg).isAccountExist(); - } else { - success(); - } - } else if (state == RegistrationState.Failed) { - if (mProgress != null) mProgress.dismiss(); - if (mDialog == null || !mDialog.isShowing()) { - mDialog = createErrorDialog(cfg, smessage); - mDialog.setCancelable(false); - mDialog.show(); - } - } else if (!(state == RegistrationState.Progress)) { - if (mProgress != null) mProgress.dismiss(); - } - } - } - } - }; - sInstance = this; } @Override protected void onResume() { super.onResume(); - Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (lc != null) { - lc.addListener(mListener); - } - } + getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); - @Override - protected void onPause() { - Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (lc != null) { - lc.removeListener(mListener); + mStatusBar = findViewById(R.id.status); + if (getResources().getBoolean(R.bool.assistant_hide_status_bar)) { + mStatusBar.setVisibility(View.GONE); } - super.onPause(); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - outState.putSerializable("CurrentFragment", mCurrentFragment); - outState.putBoolean("echoCanceller", mEchoCancellerAlreadyDone); - super.onSaveInstanceState(outState); - } - - public void updateStatusFragment(StatusFragment fragment) { - mStatus = fragment; - } - - private AccountCreator loadAccountCreator(ProxyConfig cfg) { - ProxyConfig cfgTab[] = LinphoneManager.getLc().getProxyConfigList(); - int n = -1; - for (int i = 0; i < cfgTab.length; i++) { - if (cfgTab[i].equals(cfg)) { - n = i; - break; - } - } - if (n >= 0) { - mAccountCreator.setDomain(mPrefs.getAccountDomain(n)); - mAccountCreator.setUsername(mPrefs.getAccountUsername(n)); - } - return mAccountCreator; - } - - private void initUI() { - mBack = findViewById(R.id.back); - mBack.setOnClickListener(this); - // mCancel = findViewById(R.id.assistant_cancel); - // mCancel.setOnClickListener(this); - - mTopBar = findViewById(R.id.topbar); + mTopBar = findViewById(R.id.top_bar); if (getResources().getBoolean(R.bool.assistant_hide_top_bar)) { mTopBar.setVisibility(View.GONE); } - } - private void changeFragment(Fragment newFragment) { - hideKeyboard(); - FragmentTransaction transaction = getFragmentManager().beginTransaction(); - transaction.replace(R.id.fragment_container, newFragment); - transaction.commitAllowingStateLoss(); + mBack = findViewById(R.id.back); + mBack.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); } @Override - public void onClick(View v) { - int id = v.getId(); - boolean firstLaunch = LinphonePreferences.instance().isFirstLaunch(); - - /*if (id == R.id.assistant_cancel) { - hideKeyboard(); - LinphonePreferences.instance().firstLaunchSuccessful(); - if (getResources().getBoolean(R.bool.assistant_cancel_move_to_back)) { - moveTaskToBack(true); - } else { - if (firstLaunch) startActivity(new Intent().setClass(this, LinphoneActivity.class)); - finish(); - } - } else*/ - if (id == R.id.back) { - hideKeyboard(); - if (mCurrentFragment == AssistantFragmentsEnum.WELCOME) { - LinphonePreferences.instance().firstLaunchSuccessful(); - if (getResources().getBoolean(R.bool.assistant_cancel_move_to_back)) { - moveTaskToBack(true); - } else { - if (firstLaunch) - startActivity(new Intent().setClass(this, LinphoneActivity.class)); - finish(); - } - } else { - onBackPressed(); - } + public void onCountryClicked(DialPlan dialPlan) { + if (mCountryPickerDialog != null) { + mCountryPickerDialog.dismiss(); + mCountryPickerDialog = null; } } - @Override - public void onBackPressed() { - if (mIsLink) { - return; - } - boolean firstLaunch = LinphonePreferences.instance().isFirstLaunch(); - if (mCurrentFragment == mFirstFragment) { - LinphonePreferences.instance().firstLaunchSuccessful(); - if (getResources().getBoolean(R.bool.assistant_cancel_move_to_back)) { - moveTaskToBack(true); - } else { - LinphonePreferences.instance().firstLaunchSuccessful(); - if (firstLaunch) startActivity(new Intent().setClass(this, LinphoneActivity.class)); - finish(); - } - } else if (mCurrentFragment == AssistantFragmentsEnum.LOGIN - || mCurrentFragment == AssistantFragmentsEnum.LINPHONE_LOGIN - || mCurrentFragment == AssistantFragmentsEnum.CREATE_ACCOUNT - || mCurrentFragment == AssistantFragmentsEnum.REMOTE_PROVISIONING) { - displayMenu(); - } else if (mCurrentFragment == AssistantFragmentsEnum.WELCOME) { - if (firstLaunch) startActivity(new Intent().setClass(this, LinphoneActivity.class)); - finish(); - } else if (mCurrentFragment == AssistantFragmentsEnum.COUNTRY_CHOOSER) { - if (mLastFragment.equals(AssistantFragmentsEnum.LINPHONE_LOGIN)) { - displayLoginLinphone(null, null); - } else { - displayCreateAccount(); - } - } else if (mCurrentFragment == AssistantFragmentsEnum.QRCODE_READER) { - displayRemoteProvisioning(""); - } - } - - public void hideKeyboard() { - InputMethodManager imm = - (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - View view = this.getCurrentFocus(); - if (imm != null && view != null) { - imm.hideSoftInputFromWindow(view.getWindowToken(), 0); - } - } - - private void checkAndRequestAudioPermission() { - checkAndRequestPermission( - Manifest.permission.RECORD_AUDIO, PERMISSIONS_REQUEST_RECORD_AUDIO); - } - - private void checkAndRequestVideoPermission() { - checkAndRequestPermission(Manifest.permission.CAMERA, PERMISSIONS_REQUEST_CAMERA); - } - - private void checkAndRequestPermission(String permission, int result) { - int permissionGranted = getPackageManager().checkPermission(permission, getPackageName()); - Log.i( - "[Permission] " - + permission - + " is " - + (permissionGranted == PackageManager.PERMISSION_GRANTED - ? "granted" - : "denied")); - - if (permissionGranted != PackageManager.PERMISSION_GRANTED) { - Log.i("[Permission] Asking for " + permission); - ActivityCompat.requestPermissions(this, new String[] {permission}, result); - } - } - - @Override - public void onRequestPermissionsResult( - int requestCode, String[] permissions, final int[] grantResults) { - for (int i = 0; i < permissions.length; i++) { - Log.i( - "[Permission] " - + permissions[i] - + " is " - + (grantResults[i] == PackageManager.PERMISSION_GRANTED - ? "granted" - : "denied")); - } - - switch (requestCode) { - case PERMISSIONS_REQUEST_CAMERA: - if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - displayQRCodeReader(); - } - break; - case PERMISSIONS_REQUEST_RECORD_AUDIO: - if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - launchEchoCancellerCalibration(); - } else { - isEchoCalibrationFinished(); - } - break; - } - } - - private void launchEchoCancellerCalibration() { - int recordAudio = - getPackageManager() - .checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()); - Log.i( - "[Permission] Record audio permission is " - + (recordAudio == PackageManager.PERMISSION_GRANTED - ? "granted" - : "denied")); - - if (recordAudio == PackageManager.PERMISSION_GRANTED) { - EchoCancellerCalibrationFragment fragment = new EchoCancellerCalibrationFragment(); - fragment.enableEcCalibrationResultSending(true); - changeFragment(fragment); - mCurrentFragment = AssistantFragmentsEnum.ECHO_CANCELLER_CALIBRATION; - mBack.setVisibility(View.VISIBLE); - mBack.setEnabled(false); - } else { - checkAndRequestAudioPermission(); - } - } - - private void configureProxyConfig(AccountCreator accountCreator) { - Core lc = LinphoneManager.getLc(); - ProxyConfig proxyConfig = lc.createProxyConfig(); - AuthInfo authInfo; - - String identity = proxyConfig.getIdentityAddress().asStringUriOnly(); - if (identity == null || accountCreator.getUsername() == null) { - LinphoneUtils.displayErrorAlert(getString(R.string.error), this); - return; - } - identity = identity.replace("?", accountCreator.getUsername()); - Address addr = Factory.instance().createAddress(identity); - addr.setDisplayName(accountCreator.getUsername()); - mAddress = addr; - proxyConfig.edit(); - - proxyConfig.setIdentityAddress(addr); - - if (accountCreator.getPhoneNumber() != null && accountCreator.getPhoneNumber().length() > 0) - proxyConfig.setDialPrefix( - org.linphone.core.Utils.getPrefixFromE164(accountCreator.getPhoneNumber())); - - proxyConfig.done(); - - authInfo = - Factory.instance() - .createAuthInfo( - accountCreator.getUsername(), - null, - accountCreator.getPassword(), - accountCreator.getHa1(), - proxyConfig.getRealm(), - proxyConfig.getDomain()); - - lc.addProxyConfig(proxyConfig); - - lc.addAuthInfo(authInfo); - - lc.setDefaultProxyConfig(proxyConfig); - - if (LinphonePreferences.instance() != null) - LinphonePreferences.instance().setPushNotificationEnabled(true); - - if (!mNewAccount) { - displayRegistrationInProgressDialog(); - } - mAccountCreated = true; - } - - public void linphoneLogIn(AccountCreator accountCreator) { - LinphoneManager.getLc() - .loadConfigFromXml(LinphoneManager.getInstance().getLinphoneDynamicConfigFile()); - configureProxyConfig(accountCreator); - // Restore default values for proxy config - LinphoneManager.getLc() - .loadConfigFromXml(LinphoneManager.getInstance().getDefaultDynamicConfigFile()); - } - - public void genericLogIn( - String username, - String userid, - String password, - String displayname, - String prefix, - String domain, - TransportType transport) { + protected void createProxyConfigAndLeaveAssistant() { Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (core == null) return; - - AuthInfo authInfo = - Factory.instance().createAuthInfo(username, userid, password, null, null, domain); - core.addAuthInfo(authInfo); - - ProxyConfig proxyConfig = core.createProxyConfig(); - - String identity = "sip:" + username + "@" + domain; - Address identityAddr = Factory.instance().createAddress(identity); - if (identityAddr != null) { - identityAddr.setDisplayName(displayname); - proxyConfig.setIdentityAddress(identityAddr); + boolean useLinphoneDefaultValues = + getString(R.string.default_domain).equals(mAccountCreator.getDomain()); + if (useLinphoneDefaultValues) { + core.loadConfigFromXml(LinphoneManager.getInstance().getLinphoneDynamicConfigFile()); } - String proxy = ""; - proxyConfig.setServerAddr(proxy); - proxyConfig.setDialPrefix(prefix); + ProxyConfig proxyConfig = mAccountCreator.configure(); - core.addProxyConfig(proxyConfig); - core.setDefaultProxyConfig(proxyConfig); - - mAccountCreated = true; - success(); - } - - private void display(AssistantFragmentsEnum fragment) { - switch (fragment) { - case WELCOME: - displayMenu(); - break; - case LINPHONE_LOGIN: - displayLoginLinphone(null, null); - break; - case CREATE_ACCOUNT: - displayCreateAccount(); - break; - default: - throw new IllegalStateException("Can't handle " + fragment); + if (useLinphoneDefaultValues) { + // Restore default values + core.loadConfigFromXml(LinphoneManager.getInstance().getDefaultDynamicConfigFile()); } - } - private void displayMenu() { - mFragment = new WelcomeFragment(); - changeFragment(mFragment); - country = null; - mCurrentFragment = AssistantFragmentsEnum.WELCOME; - } - - public void displayLoginGeneric() { - mFragment = new LoginFragment(); - changeFragment(mFragment); - mCurrentFragment = AssistantFragmentsEnum.LOGIN; - } - - public void displayLoginLinphone(String username, String password) { - mFragment = new LinphoneLoginFragment(); - Bundle extras = new Bundle(); - extras.putString("Phone", null); - extras.putString("Dialcode", null); - extras.putString("Username", username); - extras.putString("Password", password); - mFragment.setArguments(extras); - changeFragment(mFragment); - mCurrentFragment = AssistantFragmentsEnum.LINPHONE_LOGIN; - } - - public void displayCreateAccount() { - mFragment = new CreateAccountFragment(); - Bundle extra = new Bundle(); - extra.putBoolean("LinkPhoneNumber", mIsLink); - extra.putBoolean("LinkFromPref", mFromPref); - mFragment.setArguments(extra); - changeFragment(mFragment); - mCurrentFragment = AssistantFragmentsEnum.CREATE_ACCOUNT; - } - - public void displayRemoteProvisioning(String url) { - mFragment = new RemoteProvisioningFragment(); - Bundle extra = new Bundle(); - extra.putString("RemoteUrl", url); - mFragment.setArguments(extra); - changeFragment(mFragment); - mCurrentFragment = AssistantFragmentsEnum.REMOTE_PROVISIONING; - } - - public void displayQRCodeReader() { - if (getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName()) - != PackageManager.PERMISSION_GRANTED) { - checkAndRequestVideoPermission(); - } else { - mFragment = new QrCodeFragment(); - changeFragment(mFragment); - mCurrentFragment = AssistantFragmentsEnum.QRCODE_READER; - } - } - - public void displayCountryChooser() { - mFragment = new CountryListFragment(); - changeFragment(mFragment); - mLastFragment = mCurrentFragment; - mCurrentFragment = AssistantFragmentsEnum.COUNTRY_CHOOSER; - } - - private void launchDownloadCodec() { - if (OpenH264DownloadHelper.isOpenH264DownloadEnabled()) { - OpenH264DownloadHelper downloadHelper = - Factory.instance().createOpenH264DownloadHelper(this); - if (Version.getCpuAbis().contains("armeabi-v7a") - && !Version.getCpuAbis().contains("x86") - && !downloadHelper.isCodecFound()) { - CodecDownloaderFragment codecFragment = new CodecDownloaderFragment(); - changeFragment(codecFragment); - mCurrentFragment = AssistantFragmentsEnum.DOWNLOAD_CODEC; - mBack.setEnabled(false); - } else goToLinphoneActivity(); + if (proxyConfig == null) { + Log.e("[Assistant] Account creator couldn't create proxy config"); + // TODO: display error message } else { + LinphonePreferences.instance().firstLaunchSuccessful(); goToLinphoneActivity(); } } - public void endDownloadCodec() { - goToLinphoneActivity(); - } - - private void displayRegistrationInProgressDialog() { - if (LinphoneManager.getLc().isNetworkReachable()) { - mProgress = ProgressDialog.show(this, null, null); - Drawable d = new ColorDrawable(ContextCompat.getColor(this, R.color.light_grey_color)); - d.setAlpha(200); - mProgress - .getWindow() - .setLayout( - WindowManager.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.MATCH_PARENT); - mProgress.getWindow().setBackgroundDrawable(d); - mProgress.setContentView(R.layout.wait_layout); - mProgress.show(); - } - } - - public void displayRemoteProvisioningInProgressDialog() { - mRemoteProvisioningInProgress = true; - - mProgress = ProgressDialog.show(this, null, null); - Drawable d = new ColorDrawable(ContextCompat.getColor(this, R.color.light_grey_color)); - d.setAlpha(200); - mProgress - .getWindow() - .setLayout( - WindowManager.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.MATCH_PARENT); - mProgress.getWindow().setBackgroundDrawable(d); - mProgress.setContentView(R.layout.wait_layout); - mProgress.show(); - } - - public void displayAssistantConfirm(String username, String password, String email) { - CreateAccountActivationFragment fragment = new CreateAccountActivationFragment(); - mNewAccount = true; - Bundle extras = new Bundle(); - extras.putString("Username", username); - extras.putString("Password", password); - extras.putString("Email", email); - fragment.setArguments(extras); - changeFragment(fragment); - - mCurrentFragment = AssistantFragmentsEnum.CREATE_ACCOUNT_ACTIVATION; - } - - public void displayAssistantCodeConfirm( - String username, String phone, String dialcode, boolean recoverAccount) { - CreateAccountCodeActivationFragment fragment = new CreateAccountCodeActivationFragment(); - mNewAccount = true; - Bundle extras = new Bundle(); - extras.putString("Username", username); - extras.putString("Phone", phone); - extras.putString("Dialcode", dialcode); - extras.putBoolean("RecoverAccount", recoverAccount); - extras.putBoolean("LinkAccount", mIsLink); - fragment.setArguments(extras); - changeFragment(fragment); - - mCurrentFragment = AssistantFragmentsEnum.CREATE_ACCOUNT_CODE_ACTIVATION; - } - - public void displayAssistantLinphoneLogin(String phone, String dialcode) { - LinphoneLoginFragment fragment = new LinphoneLoginFragment(); - mNewAccount = true; - Bundle extras = new Bundle(); - extras.putString("Phone", phone); - extras.putString("Dialcode", dialcode); - fragment.setArguments(extras); - changeFragment(fragment); - - mCurrentFragment = AssistantFragmentsEnum.LINPHONE_LOGIN; - } - - public void isAccountVerified() { - Toast.makeText(this, getString(R.string.assistant_account_validated), Toast.LENGTH_LONG) - .show(); - hideKeyboard(); - success(); - } - - public void isEchoCalibrationFinished() { - launchDownloadCodec(); - } - - private Dialog createErrorDialog(ProxyConfig proxy, String message) { - AlertDialog.Builder builder = new AlertDialog.Builder(this); - if (message.equals("Forbidden")) { - message = getString(R.string.assistant_error_bad_credentials); - } - builder.setMessage(message) - .setTitle(proxy.getState().toString()) - .setPositiveButton( - getString(R.string.continue_text), - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - success(); - } - }) - .setNegativeButton( - getString(R.string.cancel), - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - LinphoneManager.getLc() - .removeProxyConfig( - LinphoneManager.getLc().getDefaultProxyConfig()); - LinphonePreferences.instance().resetDefaultProxyConfig(); - LinphoneManager.getLc().refreshRegisters(); - dialog.dismiss(); - } - }); - return builder.show(); - } - - public void success() { + protected void goToLinphoneActivity() { boolean needsEchoCalibration = LinphoneManager.getLc().isEchoCancellerCalibrationRequired(); - if (needsEchoCalibration && mPrefs.isFirstLaunch()) { - launchEchoCancellerCalibration(); + boolean echoCalibrationDone = + LinphonePreferences.instance().isEchoCancellationCalibrationDone(); + Log.i( + "[Assistant] Echo cancellation calibration required ? " + + needsEchoCalibration + + ", already done ? " + + echoCalibrationDone); + + Intent intent; + if (needsEchoCalibration && !echoCalibrationDone) { + intent = new Intent(this, EchoCancellerCalibrationAssistantActivity.class); } else { - launchDownloadCodec(); + /*boolean openH264 = LinphonePreferences.instance().isOpenH264CodecDownloadEnabled(); + boolean codecFound = + LinphoneManager.getInstance().getOpenH264DownloadHelper().isCodecFound(); + boolean abiSupported = + Version.getCpuAbis().contains("armeabi-v7a") + && !Version.getCpuAbis().contains("x86"); + boolean androidVersionOk = Version.sdkStrictlyBelow(Build.VERSION_CODES.M); + + if (openH264 && abiSupported && androidVersionOk && !codecFound) { + intent = new Intent(this, OpenH264DownloadAssistantActivity.class); + } else {*/ + intent = new Intent(this, LinphoneActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + // } } + startActivity(intent); } - private void goToLinphoneActivity() { - mPrefs.firstLaunchSuccessful(); - startActivity( - new Intent() - .setClass(this, LinphoneActivity.class) - .putExtra("isNewProxyConfig", true)); - finish(); + protected void showPhoneNumberDialog() { + new AlertDialog.Builder(this) + .setTitle(getString(R.string.phone_number_info_title)) + .setMessage( + getString(R.string.phone_number_link_info_content) + + "\n" + + getString( + R.string.phone_number_link_info_content_already_account)) + .show(); } - public void setCoreListener() { - Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (lc != null) { - lc.addListener(mListener); - } - if (mStatus != null) { - mStatus.setCoreListener(); - } + protected void showAccountAlreadyExistsDialog() { + new AlertDialog.Builder(this) + .setTitle(getString(R.string.account_already_exist)) + .setMessage(getString(R.string.assistant_phone_number_unavailable)) + .show(); } - public void restartApplication() { - mPrefs.firstLaunchSuccessful(); + protected void showGenericErrorDialog(AccountCreator.Status status) { + String message; - Intent mStartActivity = new Intent(this, LinphoneLauncherActivity.class); - PendingIntent mPendingIntent = - PendingIntent.getActivity( - this, - (int) System.currentTimeMillis(), - mStartActivity, - PendingIntent.FLAG_CANCEL_CURRENT); - AlarmManager mgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); - mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 500, mPendingIntent); + switch (status) { + // TODO + case PhoneNumberInvalid: + message = getString(R.string.phone_number_invalid); + break; + case WrongActivationCode: + message = getString(R.string.activation_code_invalid); + break; + case PhoneNumberOverused: + message = getString(R.string.phone_number_overuse); + break; + default: + message = getString(R.string.error_unknown); + break; + } - finish(); - stopService(new Intent(Intent.ACTION_MAIN).setClass(this, LinphoneService.class)); - ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); - am.killBackgroundProcesses(getString(R.string.sync_account_type)); - android.os.Process.killProcess(android.os.Process.myPid()); + new AlertDialog.Builder(this) + .setTitle(getString(R.string.error)) + .setMessage(message) + .show(); } - @Override - public void onIsAccountExist( - AccountCreator accountCreator, AccountCreator.Status status, String resp) { - if (status.equals(AccountCreator.Status.AccountExistWithAlias)) { - success(); - } else { - mIsLink = true; - displayCreateAccount(); + protected void showCountryPickerDialog() { + if (mCountryPicker == null) { + mCountryPicker = new CountryPicker(this, this); } - if (mAccountCreator != null) mAccountCreator.setListener(null); + mCountryPickerDialog = + new AlertDialog.Builder(this).setView(mCountryPicker.getView()).show(); } - @Override - public void onCreateAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onActivateAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onLinkAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onActivateAlias( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onIsAccountActivated( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onRecoverAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onIsAccountLinked( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onIsAliasUsed( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onUpdateAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - public CountryListAdapter getCountryListAdapter() { - return mCountryListAdapter; + protected DialPlan getDialPlanForCurrentCountry() { + try { + TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); + String countryIso = tm.getNetworkCountryIso(); + return getDialPlanFromCountryCode(countryIso); + } catch (Exception e) { + Log.e("[Assistant] " + e); + } + return null; } - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - if (mCurrentFragment == AssistantFragmentsEnum.QRCODE_READER) { - this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + protected String getDevicePhoneNumber() { + try { + TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); + return tm.getLine1Number(); + } catch (Exception e) { + Log.e("[Assistant] " + e); } + return null; } - /** - * This class reads a JSON file containing Country-specific phone number description, and allows - * to present them into a ListView - */ - public class CountryListAdapter extends BaseAdapter implements Filterable { + protected DialPlan getDialPlanFromPrefix(String prefix) { + if (prefix == null || prefix.isEmpty()) return null; - private LayoutInflater mInflater; - private final DialPlan[] allCountries; - private List filteredCountries; - private final Context context; + for (DialPlan c : Factory.instance().getDialPlans()) { + if (prefix.equalsIgnoreCase(c.getCountryCallingCode())) return c; + } + return null; + } - CountryListAdapter(Context ctx) { - context = ctx; - allCountries = Factory.instance().getDialPlans(); - filteredCountries = new ArrayList<>(Arrays.asList(allCountries)); + protected DialPlan getDialPlanFromCountryCode(String countryCode) { + if (countryCode == null || countryCode.isEmpty()) return null; + + for (DialPlan c : Factory.instance().getDialPlans()) { + if (countryCode.equalsIgnoreCase(c.getIsoCountryCode())) return c; + } + return null; + } + + protected int arePhoneNumberAndPrefixOk(EditText prefixEditText, EditText phoneNumberEditText) { + String prefix = prefixEditText.getText().toString(); + if (prefix.startsWith("+")) { + prefix = prefix.substring(1); } - public void setInflater(LayoutInflater inf) { - mInflater = inf; - } - - public DialPlan getCountryFromCountryCode(String countryCode) { - countryCode = (countryCode.startsWith("+")) ? countryCode.substring(1) : countryCode; - for (DialPlan c : allCountries) { - if (c.getCountryCallingCode().compareTo(countryCode) == 0) return c; - } - return null; - } - - @Override - public int getCount() { - return filteredCountries.size(); - } - - @Override - public DialPlan getItem(int position) { - return filteredCountries.get(position); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View view; - - if (convertView != null) { - view = convertView; - } else { - view = mInflater.inflate(R.layout.country_cell, parent, false); - } - - DialPlan c = filteredCountries.get(position); - - TextView name = view.findViewById(R.id.country_name); - name.setText(c.getCountry()); - - TextView dial_code = view.findViewById(R.id.country_prefix); - if (context != null) - dial_code.setText( - String.format( - context.getString(R.string.country_code), - c.getCountryCallingCode())); - - view.setTag(c); - return view; - } - - @Override - public Filter getFilter() { - return new Filter() { - @Override - protected FilterResults performFiltering(CharSequence constraint) { - ArrayList filteredCountries = new ArrayList<>(); - for (DialPlan c : allCountries) { - if (c.getCountry().toLowerCase().contains(constraint) - || c.getCountryCallingCode().contains(constraint)) { - filteredCountries.add(c); - } - } - FilterResults filterResults = new FilterResults(); - filterResults.values = filteredCountries; - return filterResults; - } - - @Override - @SuppressWarnings("unchecked") - protected void publishResults(CharSequence constraint, FilterResults results) { - filteredCountries = (List) results.values; - CountryListAdapter.this.notifyDataSetChanged(); - } - }; + String phoneNumber = phoneNumberEditText.getText().toString(); + return mAccountCreator.setPhoneNumber(phoneNumber, prefix); + } + + protected String getErrorFromPhoneNumberStatus(int status) { + AccountCreator.PhoneNumberStatus phoneNumberStatus = + AccountCreator.PhoneNumberStatus.fromInt(status); + switch (phoneNumberStatus) { + case InvalidCountryCode: + return getString(R.string.country_code_invalid); + case TooShort: + return getString(R.string.phone_number_too_short); + case TooLong: + return getString(R.string.phone_number_too_long); + case Invalid: + return getString(R.string.phone_number_invalid); } + return null; } } diff --git a/app/src/main/java/org/linphone/assistant/AssistantFragmentsEnum.java b/app/src/main/java/org/linphone/assistant/AssistantFragmentsEnum.java deleted file mode 100644 index 699555cd6..000000000 --- a/app/src/main/java/org/linphone/assistant/AssistantFragmentsEnum.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.linphone.assistant; -/* -AssistantFragmentsEnum.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -public enum AssistantFragmentsEnum { - WELCOME, - CREATE_ACCOUNT, - CREATE_ACCOUNT_ACTIVATION, - CREATE_ACCOUNT_CODE_ACTIVATION, - LINPHONE_LOGIN, - COUNTRY_CHOOSER, - LOGIN, - REMOTE_PROVISIONING, - ECHO_CANCELLER_CALIBRATION, - DOWNLOAD_CODEC, - QRCODE_READER -} diff --git a/app/src/main/java/org/linphone/assistant/CodecDownloaderFragment.java b/app/src/main/java/org/linphone/assistant/CodecDownloaderFragment.java deleted file mode 100644 index 4d4ec41ee..000000000 --- a/app/src/main/java/org/linphone/assistant/CodecDownloaderFragment.java +++ /dev/null @@ -1,220 +0,0 @@ -package org.linphone.assistant; - -/* -CodecDownloaderFragment.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import android.app.Fragment; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ProgressBar; -import android.widget.TextView; -import org.linphone.LinphoneManager; -import org.linphone.R; -import org.linphone.core.PayloadType; -import org.linphone.core.tools.OpenH264DownloadHelper; -import org.linphone.core.tools.OpenH264DownloadHelperListener; - -public class CodecDownloaderFragment extends Fragment { - private final Handler mHandler = new Handler(); - private TextView mQuestion; - private TextView mDownloading; - private TextView mDownloaded; - private Button mYes; - private Button mNo; - private Button mOk; - private ProgressBar mProgressBar; - private TextView mDownloadingInfo; - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - final View view = inflater.inflate(R.layout.assistant_codec_downloader, container, false); - - mQuestion = view.findViewById(R.id.question); - mDownloading = view.findViewById(R.id.downloading); - mDownloaded = view.findViewById(R.id.downloaded); - mYes = view.findViewById(R.id.answerYes); - mNo = view.findViewById(R.id.answerNo); - mOk = view.findViewById(R.id.answerOk); - mProgressBar = view.findViewById(R.id.progressBar); - mDownloadingInfo = view.findViewById(R.id.downloadingInfo); - - final OpenH264DownloadHelper codecDownloader = - LinphoneManager.getInstance().getOpenH264DownloadHelper(); - final OpenH264DownloadHelperListener codecListener = - new OpenH264DownloadHelperListener() { - - @Override - public void OnProgress(final int current, final int max) { - mHandler.post( - new Runnable() { - @Override - public void run() { - if (current <= max) { - hideAllItems(); - mDownloadingInfo.setText(current + " / " + max); - mDownloadingInfo.setVisibility(View.VISIBLE); - mDownloading.setVisibility(View.VISIBLE); - mProgressBar.setMax(max); - mProgressBar.setProgress(current); - mProgressBar.setVisibility(View.VISIBLE); - } else { - hideAllItems(); - mDownloaded.setVisibility(View.VISIBLE); - if (Build.VERSION.SDK_INT - >= Build.VERSION_CODES.LOLLIPOP_MR1) { - enabledH264(true); - LinphoneManager.getLc() - .reloadMsPlugins( - AssistantActivity.instance() - .getApplicationInfo() - .nativeLibraryDir); - AssistantActivity.instance().endDownloadCodec(); - } else { - // We need to restart due to bad android linker - AssistantActivity.instance().restartApplication(); - } - } - } - }); - } - - @Override - public void OnError(final String error) { - mHandler.post( - new Runnable() { - @Override - public void run() { - hideAllItems(); - mDownloaded.setText("Sorry an error has occurred."); - mDownloaded.setVisibility(View.VISIBLE); - mOk.setVisibility(View.VISIBLE); - enabledH264(false); - AssistantActivity.instance().endDownloadCodec(); - } - }); - } - }; - - codecDownloader.setOpenH264HelperListener(codecListener); - - mYes.setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View v) { - hideAllItems(); - mProgressBar.setVisibility(View.VISIBLE); - codecDownloader.downloadCodec(); - } - }); - - mNo.setOnClickListener( - new View.OnClickListener() { - @Override - public void onClick(View v) { - enabledH264(false); - AssistantActivity.instance().endDownloadCodec(); - } - }); - hideAllItems(); - - if (savedInstanceState != null) { - if (savedInstanceState.containsKey("mQuestion")) - mQuestion.setVisibility((Integer) savedInstanceState.getSerializable("mQuestion")); - else mQuestion.setVisibility(View.VISIBLE); - - if (savedInstanceState.containsKey("mYes")) - mYes.setVisibility((Integer) savedInstanceState.getSerializable("mYes")); - else mYes.setVisibility(View.VISIBLE); - - if (savedInstanceState.containsKey("mNo")) - mNo.setVisibility((Integer) savedInstanceState.getSerializable("mNo")); - else mNo.setVisibility(View.VISIBLE); - - if (savedInstanceState.containsKey("mDownloading")) - mDownloading.setVisibility( - (Integer) savedInstanceState.getSerializable("mDownloading")); - - if (savedInstanceState.containsKey("mDownloaded")) - mDownloaded.setVisibility( - (Integer) savedInstanceState.getSerializable("mDownloaded")); - - if (savedInstanceState.containsKey("context_bar")) - mProgressBar.setVisibility( - (Integer) savedInstanceState.getSerializable("context_bar")); - - if (savedInstanceState.containsKey("mDownloadingInfo")) - mDownloadingInfo.setVisibility( - (Integer) savedInstanceState.getSerializable("mDownloadingInfo")); - - if (savedInstanceState.containsKey("mOk")) - mOk.setVisibility((Integer) savedInstanceState.getSerializable("mOk")); - } else { - mYes.setVisibility(View.VISIBLE); - mQuestion.setVisibility(View.VISIBLE); - mNo.setVisibility(View.VISIBLE); - } - - return view; - } - - @Override - public void onSaveInstanceState(Bundle outState) { - if (mQuestion != null) outState.putSerializable("mQuestion", mQuestion.getVisibility()); - if (mDownloading != null) - outState.putSerializable("mDownloading", mDownloading.getVisibility()); - if (mDownloaded != null) - outState.putSerializable("mDownloaded", mDownloaded.getVisibility()); - if (mYes != null) outState.putSerializable("mYes", mYes.getVisibility()); - if (mNo != null) outState.putSerializable("mNo", mNo.getVisibility()); - if (mOk != null) outState.putSerializable("mOk", mOk.getVisibility()); - if (mProgressBar != null) - outState.putSerializable("context_bar", mProgressBar.getVisibility()); - if (mDownloadingInfo != null) - outState.putSerializable("mDownloadingInfo", mDownloadingInfo.getVisibility()); - super.onSaveInstanceState(outState); - } - - private void hideAllItems() { - if (mQuestion != null) mQuestion.setVisibility(View.INVISIBLE); - if (mDownloading != null) mDownloading.setVisibility(View.INVISIBLE); - if (mDownloaded != null) mDownloaded.setVisibility(View.INVISIBLE); - if (mYes != null) mYes.setVisibility(View.INVISIBLE); - if (mNo != null) mNo.setVisibility(View.INVISIBLE); - if (mOk != null) mOk.setVisibility(View.INVISIBLE); - if (mProgressBar != null) mProgressBar.setVisibility(View.INVISIBLE); - if (mDownloadingInfo != null) mDownloadingInfo.setVisibility(View.INVISIBLE); - } - - private void enabledH264(boolean enable) { - PayloadType h264 = null; - for (PayloadType pt : LinphoneManager.getLc().getVideoPayloadTypes()) { - if (pt.getMimeType().equals("H264")) h264 = pt; - } - - if (h264 != null) { - h264.enable(enable); - } - } -} diff --git a/app/src/main/java/org/linphone/assistant/CountryAdapter.java b/app/src/main/java/org/linphone/assistant/CountryAdapter.java new file mode 100644 index 000000000..cdde6614d --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/CountryAdapter.java @@ -0,0 +1,114 @@ +package org.linphone.assistant; + +/* +CountryAdapter.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.Filter; +import android.widget.Filterable; +import android.widget.TextView; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.linphone.R; +import org.linphone.core.DialPlan; +import org.linphone.core.Factory; + +public class CountryAdapter extends BaseAdapter implements Filterable { + private Context mContext; + private LayoutInflater mInflater; + private final DialPlan[] mAllCountries; + private List mFilteredCountries; + + public CountryAdapter(Context context, LayoutInflater inflater) { + mContext = context; + mInflater = inflater; + mAllCountries = Factory.instance().getDialPlans(); + mFilteredCountries = new ArrayList<>(Arrays.asList(mAllCountries)); + } + + @Override + public int getCount() { + return mFilteredCountries.size(); + } + + @Override + public DialPlan getItem(int position) { + return mFilteredCountries.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View view; + + if (convertView != null) { + view = convertView; + } else { + view = mInflater.inflate(R.layout.country_cell, parent, false); + } + + DialPlan c = mFilteredCountries.get(position); + + TextView name = view.findViewById(R.id.country_name); + name.setText(c.getCountry()); + + TextView dial_code = view.findViewById(R.id.country_prefix); + dial_code.setText( + String.format( + mContext.getString(R.string.country_code), c.getCountryCallingCode())); + + view.setTag(c); + return view; + } + + @Override + public Filter getFilter() { + return new Filter() { + @Override + protected FilterResults performFiltering(CharSequence constraint) { + List filteredCountries = new ArrayList<>(); + for (DialPlan c : mAllCountries) { + if (c.getCountry().toLowerCase().contains(constraint) + || c.getCountryCallingCode().contains(constraint)) { + filteredCountries.add(c); + } + } + FilterResults filterResults = new FilterResults(); + filterResults.values = filteredCountries; + return filterResults; + } + + @Override + @SuppressWarnings("unchecked") + protected void publishResults(CharSequence constraint, FilterResults results) { + mFilteredCountries = (List) results.values; + notifyDataSetChanged(); + } + }; + } +} diff --git a/app/src/main/java/org/linphone/assistant/CountryListFragment.java b/app/src/main/java/org/linphone/assistant/CountryListFragment.java deleted file mode 100644 index 34dbedca7..000000000 --- a/app/src/main/java/org/linphone/assistant/CountryListFragment.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.linphone.assistant; - -/* -CountryListFragment.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import android.app.Fragment; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.ListView; -import org.linphone.R; -import org.linphone.core.DialPlan; - -public class CountryListFragment extends Fragment - implements AdapterView.OnItemClickListener, View.OnClickListener { - private ListView mList; - private EditText mSearch; - private ImageView mClearSearchField; - private AssistantActivity.CountryListAdapter mAdapter; - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - - View view = inflater.inflate(R.layout.assistant_country_list, container, false); - mAdapter = AssistantActivity.instance().getCountryListAdapter(); - mAdapter.setInflater(inflater); - - mSearch = view.findViewById(R.id.search_country); - mClearSearchField = view.findViewById(R.id.clearSearchField); - mClearSearchField.setOnClickListener(this); - - mList = view.findViewById(R.id.countryList); - mList.setAdapter(mAdapter); - mList.setOnItemClickListener(this); - - mSearch.addTextChangedListener( - new TextWatcher() { - @Override - public void beforeTextChanged( - CharSequence s, int start, int count, int after) {} - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - mAdapter.getFilter().filter(s); - } - - @Override - public void afterTextChanged(Editable s) {} - }); - mSearch.setText(""); - - return view; - } - - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - AssistantActivity.instance().country = (DialPlan) view.getTag(); - AssistantActivity.instance().onBackPressed(); - } - - @Override - public void onClick(View v) { - if (v.getId() == R.id.clearSearchField) { - mSearch.setText(""); - } - } -} diff --git a/app/src/main/java/org/linphone/assistant/CountryPicker.java b/app/src/main/java/org/linphone/assistant/CountryPicker.java new file mode 100644 index 000000000..bfeb075db --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/CountryPicker.java @@ -0,0 +1,108 @@ +package org.linphone.assistant; + +/* +CountryPicker.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.content.Context; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.AdapterView; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.ListView; +import org.linphone.R; +import org.linphone.core.DialPlan; + +public class CountryPicker { + private Context mContext; + private LayoutInflater mInflater; + private CountryAdapter mAdapter; + private ListView mList; + private EditText mSearch; + private ImageView mClear; + private CountryPickedListener mListener; + + public CountryPicker(Context context, CountryPickedListener listener) { + mContext = context; + mListener = listener; + mInflater = LayoutInflater.from(mContext); + mAdapter = new CountryAdapter(mContext, mInflater); + } + + private View createView() { + View view = mInflater.inflate(R.layout.assistant_country_list, null, false); + + mList = view.findViewById(R.id.countryList); + mList.setAdapter(mAdapter); + mList.setOnItemClickListener( + new AdapterView.OnItemClickListener() { + @Override + public void onItemClick( + AdapterView parent, View view, int position, long id) { + DialPlan dp = null; + if (position > 0 && position < mAdapter.getCount()) { + dp = mAdapter.getItem(position); + } + + if (mListener != null) { + mListener.onCountryClicked(dp); + } + } + }); + + mSearch = view.findViewById(R.id.search_country); + mSearch.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + mAdapter.getFilter().filter(s); + } + }); + mSearch.setText(""); + + mClear = view.findViewById(R.id.clear_field); + mClear.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + mSearch.setText(""); + } + }); + + return view; + } + + public View getView() { + View view = createView(); + return view; + } + + public interface CountryPickedListener { + void onCountryClicked(DialPlan dialPlan); + } +} diff --git a/app/src/main/java/org/linphone/assistant/CreateAccountActivationFragment.java b/app/src/main/java/org/linphone/assistant/CreateAccountActivationFragment.java deleted file mode 100644 index dc15184a9..000000000 --- a/app/src/main/java/org/linphone/assistant/CreateAccountActivationFragment.java +++ /dev/null @@ -1,138 +0,0 @@ -package org.linphone.assistant; -/* -CreateAccountActivationFragment.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import android.app.Fragment; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.TextView; -import android.widget.Toast; -import org.linphone.LinphoneManager; -import org.linphone.R; -import org.linphone.core.AccountCreator; -import org.linphone.core.AccountCreatorListener; -import org.linphone.settings.LinphonePreferences; - -public class CreateAccountActivationFragment extends Fragment - implements OnClickListener, AccountCreatorListener { - private String mUsername, mPassword; - private Button mCheckAccount; - private TextView mEmail; - private AccountCreator mAccountCreator; - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = - inflater.inflate( - R.layout.assistant_account_creation_email_activation, container, false); - - mAccountCreator = - LinphoneManager.getLc() - .createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl()); - mAccountCreator.setListener(this); - - mUsername = getArguments().getString("Username"); - mPassword = getArguments().getString("Password"); - - mAccountCreator.setUsername(mUsername); - mAccountCreator.setPassword(mPassword); - - mEmail = view.findViewById(R.id.send_email); - mEmail.setText(getArguments().getString("Email")); - - mCheckAccount = view.findViewById(R.id.assistant_check); - mCheckAccount.setOnClickListener(this); - return view; - } - - @Override - public void onClick(View v) { - int id = v.getId(); - if (id == R.id.assistant_check) { - mCheckAccount.setEnabled(false); - mAccountCreator.isAccountActivated(); - } - } - - @Override - public void onIsAccountExist( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onCreateAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onActivateAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onLinkAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onActivateAlias( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onIsAccountActivated( - AccountCreator accountCreator, AccountCreator.Status status, String resp) { - if (AssistantActivity.instance() == null) { - return; - } - if (status.equals(AccountCreator.Status.AccountNotActivated)) { - Toast.makeText( - getActivity(), - getString(R.string.assistant_account_not_validated), - Toast.LENGTH_LONG) - .show(); - } else if (status.equals(AccountCreator.Status.AccountActivated)) { - AssistantActivity.instance().linphoneLogIn(accountCreator); - AssistantActivity.instance().isAccountVerified(); - } else { - Toast.makeText( - getActivity(), - getString(R.string.wizard_server_unavailable), - Toast.LENGTH_LONG) - .show(); - } - mCheckAccount.setEnabled(true); - } - - @Override - public void onRecoverAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onIsAccountLinked( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onIsAliasUsed( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onUpdateAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} -} diff --git a/app/src/main/java/org/linphone/assistant/CreateAccountCodeActivationFragment.java b/app/src/main/java/org/linphone/assistant/CreateAccountCodeActivationFragment.java deleted file mode 100644 index 8354458e3..000000000 --- a/app/src/main/java/org/linphone/assistant/CreateAccountCodeActivationFragment.java +++ /dev/null @@ -1,227 +0,0 @@ -package org.linphone.assistant; -/* -CreateAccountCodeActivationFragment.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -import android.app.Fragment; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.TextView; -import android.widget.Toast; -import org.linphone.LinphoneManager; -import org.linphone.R; -import org.linphone.core.AccountCreator; -import org.linphone.core.AccountCreatorListener; -import org.linphone.settings.LinphonePreferences; - -public class CreateAccountCodeActivationFragment extends Fragment - implements AccountCreatorListener { - private String mUsername, mPhone, mDialcode; - private TextView mTitle, mPhonenumber; - private EditText mCode; - private boolean mRecoverAccount = false, mLinkAccount = false; - private int mCodeLength, mAccountNumber; - private ImageView mBack; - private Button mCheckAccount; - private AccountCreator mAccountCreator; - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = - inflater.inflate( - R.layout.assistant_account_creation_code_activation, container, false); - - mUsername = getArguments().getString("Username"); - mPhone = getArguments().getString("Phone"); - mDialcode = getArguments().getString("Dialcode"); - mRecoverAccount = getArguments().getBoolean("RecoverAccount"); - mLinkAccount = getArguments().getBoolean("LinkAccount"); - mAccountNumber = getArguments().getInt("AccountNumber"); - - mCodeLength = LinphonePreferences.instance().getCodeLength(); - mAccountCreator = - LinphoneManager.getLc() - .createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl()); - mAccountCreator.setListener(this); - mAccountCreator.setUsername(mUsername); - mAccountCreator.setPhoneNumber(mPhone, mDialcode); - - mBack = view.findViewById(R.id.back); - if (mBack != null) mBack.setVisibility(Button.INVISIBLE); - - mTitle = view.findViewById(R.id.title_account_activation); - if (mLinkAccount) { - mTitle.setText(getString(R.string.assistant_link_account)); - } else if (mRecoverAccount) { - mTitle.setText(getString(R.string.assistant_linphone_account)); - } - - mPhonenumber = view.findViewById(R.id.send_phone_number); - mPhonenumber.setText(mAccountCreator.getPhoneNumber()); - - mCode = view.findViewById(R.id.assistant_code); - mCode.addTextChangedListener( - new TextWatcher() { - @Override - public void beforeTextChanged( - CharSequence s, int start, int count, int after) {} - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) {} - - @Override - public void afterTextChanged(Editable s) { - if (s.length() == mCodeLength) { - mCheckAccount.setEnabled(true); - } else { - mCheckAccount.setEnabled(false); - } - } - }); - - mCheckAccount = view.findViewById(R.id.assistant_check); - mCheckAccount.setEnabled(false); - mCheckAccount.setOnClickListener( - new OnClickListener() { - @Override - public void onClick(View v) { - mCheckAccount.setEnabled(false); - mAccountCreator.setActivationCode(mCode.getText().toString()); - if (mLinkAccount) { - linkAccount(); - } else { - activateAccount(); - } - } - }); - - return view; - } - - private void linkAccount() { - mAccountCreator.setUsername( - LinphonePreferences.instance().getAccountUsername(mAccountNumber)); - mAccountCreator.setHa1(LinphonePreferences.instance().getAccountHa1(mAccountNumber)); - mAccountCreator.activateAlias(); - } - - private void activateAccount() { - if (mAccountCreator.getUsername() == null) { - mAccountCreator.setUsername(mAccountCreator.getPhoneNumber()); - } - mAccountCreator.activateAccount(); - } - - @Override - public void onIsAccountExist( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onCreateAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onActivateAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) { - if (AssistantActivity.instance() == null) { - return; - } - if (status.equals(AccountCreator.Status.AccountActivated)) { - mCheckAccount.setEnabled(true); - if (accountCreator.getUsername() != null) { - AssistantActivity.instance().linphoneLogIn(accountCreator); - if (!mRecoverAccount) { - AssistantActivity.instance().isAccountVerified(); - } else { - AssistantActivity.instance().success(); - } - } else { - AssistantActivity.instance().linphoneLogIn(accountCreator); - if (!mRecoverAccount) { - AssistantActivity.instance().isAccountVerified(); - } else { - AssistantActivity.instance().success(); - } - } - } else if (status.equals(AccountCreator.Status.RequestFailed)) { - Toast.makeText( - getActivity(), - getString(R.string.wizard_server_unavailable), - Toast.LENGTH_LONG) - .show(); - } else { - Toast.makeText( - getActivity(), - getString(R.string.assistant_error_confirmation_code), - Toast.LENGTH_LONG) - .show(); - AssistantActivity.instance().displayAssistantLinphoneLogin(mPhone, mDialcode); - } - } - - @Override - public void onLinkAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onActivateAlias( - AccountCreator accountCreator, AccountCreator.Status status, String resp) { - if (AssistantActivity.instance() == null) { - return; - } - if (status.equals(AccountCreator.Status.AccountActivated)) { - LinphonePreferences.instance() - .setPrefix( - mAccountNumber, - org.linphone.core.Utils.getPrefixFromE164( - accountCreator.getPhoneNumber())); - LinphonePreferences.instance().setLinkPopupTime(""); - AssistantActivity.instance().hideKeyboard(); - AssistantActivity.instance().success(); - } - } - - @Override - public void onIsAccountActivated( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onRecoverAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onIsAccountLinked( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onIsAliasUsed( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onUpdateAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} -} diff --git a/app/src/main/java/org/linphone/assistant/CreateAccountFragment.java b/app/src/main/java/org/linphone/assistant/CreateAccountFragment.java deleted file mode 100644 index 37ac55e16..000000000 --- a/app/src/main/java/org/linphone/assistant/CreateAccountFragment.java +++ /dev/null @@ -1,804 +0,0 @@ -package org.linphone.assistant; -/* -CreateAccountFragment.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import android.accounts.Account; -import android.accounts.AccountManager; -import android.app.AlertDialog; -import android.app.Fragment; -import android.content.Context; -import android.os.Build; -import android.os.Bundle; -import android.telephony.TelephonyManager; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.Patterns; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.linphone.LinphoneManager; -import org.linphone.R; -import org.linphone.core.AccountCreator; -import org.linphone.core.AccountCreator.Status; -import org.linphone.core.AccountCreatorListener; -import org.linphone.core.DialPlan; -import org.linphone.settings.LinphonePreferences; -import org.linphone.utils.LinphoneUtils; - -public class CreateAccountFragment extends Fragment - implements CompoundButton.OnCheckedChangeListener, OnClickListener, AccountCreatorListener { - private final Pattern UPPER_CASE_REGEX = Pattern.compile("[A-Z]"); - - private EditText mPhoneNumberEdit, - mUsernameEdit, - mPasswordEdit, - mPasswordConfirmEdit, - mEmailEdit, - mDialCode; - private TextView mPhoneNumberError, - mPasswordError, - mPasswordConfirmError, - mEmailError, - mAssisstantTitle, - mSipUri, - mSkip, - mInstruction; - private ImageView mPhoneNumberInfo; - private boolean mPasswordOk = false; - private boolean mEmailOk = false; - private boolean mConfirmPasswordOk = false; - private boolean mLinkAccount = false; - private Button mCreateAccount, mSelectCountry; - private CheckBox mUseUsername, mUseEmail; - private String mAddressSip = ""; - private int mCountryCode; - private LinearLayout mPhoneNumberLayout, - mUsernameLayout, - mEmailLayout, - mPasswordLayout, - mPasswordConfirmLayout; - private AccountCreator mAccountCreator; - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.assistant_account_creation, container, false); - - // Initialize mAccountCreator - mAccountCreator = - LinphoneManager.getLc() - .createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl()); - mAccountCreator.setListener(this); - mAccountCreator.setDomain(getString(R.string.default_domain)); - - mInstruction = view.findViewById(R.id.message_create_account); - - mCreateAccount = view.findViewById(R.id.assistant_create); - - mPhoneNumberLayout = view.findViewById(R.id.phone_number_layout); - mUsernameLayout = view.findViewById(R.id.username_layout); - mEmailLayout = view.findViewById(R.id.email_layout); - mPasswordLayout = view.findViewById(R.id.password_layout); - mPasswordConfirmLayout = view.findViewById(R.id.password_confirm_layout); - - mUseUsername = view.findViewById(R.id.use_username); - mUseEmail = view.findViewById(R.id.use_email); - - mUsernameEdit = view.findViewById(R.id.username); - - mPhoneNumberError = view.findViewById(R.id.phone_number_error); - mPhoneNumberEdit = view.findViewById(R.id.phone_number); - mSipUri = view.findViewById(R.id.sip_uri); - - mPhoneNumberInfo = view.findViewById(R.id.info_phone_number); - - mSelectCountry = view.findViewById(R.id.select_country); - mDialCode = view.findViewById(R.id.dial_code); - mAssisstantTitle = view.findViewById(R.id.assistant_title); - - mPasswordError = view.findViewById(R.id.password_error); - mPasswordEdit = view.findViewById(R.id.password); - - mPasswordConfirmError = view.findViewById(R.id.confirm_password_error); - mPasswordConfirmEdit = view.findViewById(R.id.confirm_password); - - mEmailError = view.findViewById(R.id.email_error); - mEmailEdit = view.findViewById(R.id.email); - - mSkip = view.findViewById(R.id.assistant_skip); - - // Phone number - if (getResources().getBoolean(R.bool.use_phone_number_validation)) { - getActivity().getApplicationContext(); - // Automatically get the country code from the phone - TelephonyManager tm = - (TelephonyManager) - getActivity() - .getApplicationContext() - .getSystemService(Context.TELEPHONY_SERVICE); - String countryIso = tm.getNetworkCountryIso(); - mCountryCode = org.linphone.core.Utils.getCccFromIso(countryIso.toUpperCase()); - - mPhoneNumberLayout.setVisibility(View.VISIBLE); - - mPhoneNumberInfo.setOnClickListener(this); - mSelectCountry.setOnClickListener(this); - - DialPlan c = AssistantActivity.instance().country; - if (c != null) { - mSelectCountry.setText(c.getCountry()); - mDialCode.setText( - c.getCountryCallingCode().contains("+") - ? c.getCountryCallingCode() - : "+" + c.getCountryCallingCode()); - } else { - c = - AssistantActivity.instance() - .getCountryListAdapter() - .getCountryFromCountryCode(String.valueOf(mCountryCode)); - if (c != null) { - mSelectCountry.setText(c.getCountry()); - mDialCode.setText( - c.getCountryCallingCode().contains("+") - ? c.getCountryCallingCode() - : "+" + c.getCountryCallingCode()); - } - } - - // Allow user to enter a username instead use the phone number as username - if (getResources().getBoolean(R.bool.assistant_allow_username)) { - mUseUsername.setVisibility(View.VISIBLE); - mUseUsername.setOnCheckedChangeListener(this); - } - addPhoneNumberHandler(mPhoneNumberEdit); - addPhoneNumberHandler(mDialCode); - } - - // Password & email address - if (getResources().getBoolean(R.bool.isTablet) - || !getResources().getBoolean(R.bool.use_phone_number_validation)) { - mUseEmail.setVisibility(View.VISIBLE); - mUseEmail.setOnCheckedChangeListener(this); - - if (getResources().getBoolean(R.bool.pre_fill_email_in_assistant)) { - Account[] accounts = - AccountManager.get(getActivity()).getAccountsByType("com.google"); - - for (Account account : accounts) { - if (isEmailCorrect(account.name)) { - String possibleEmail = account.name; - mEmailEdit.setText(possibleEmail); - mAccountCreator.setEmail(possibleEmail); - mEmailOk = true; - break; - } - } - } - - addPasswordHandler(mPasswordEdit); - addConfirmPasswordHandler(mPasswordEdit, mPasswordConfirmEdit); - addEmailHandler(mEmailEdit); - } - - // Hide phone number and display username/email/password - if (!getResources().getBoolean(R.bool.use_phone_number_validation)) { - mUseEmail.setVisibility(View.GONE); - mUseUsername.setVisibility(View.GONE); - - mUsernameLayout.setVisibility(View.VISIBLE); - mPasswordLayout.setVisibility(View.VISIBLE); - mPasswordConfirmLayout.setVisibility(View.VISIBLE); - mEmailLayout.setVisibility(View.VISIBLE); - } - - // Link account with phone number - if (getArguments().getBoolean("LinkPhoneNumber")) { - mLinkAccount = true; - mUseEmail.setVisibility(View.GONE); - mUseUsername.setVisibility(View.GONE); - - mUsernameLayout.setVisibility(View.GONE); - mPasswordLayout.setVisibility(View.GONE); - mPasswordConfirmLayout.setVisibility(View.GONE); - mEmailLayout.setVisibility(View.GONE); - - mSkip.setVisibility(View.VISIBLE); - mSkip.setOnClickListener(this); - - mCreateAccount.setText(getResources().getString(R.string.link_account)); - mAssisstantTitle.setText(getResources().getString(R.string.link_account)); - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mAccountCreator.setLanguage(Locale.getDefault().toLanguageTag()); - } - - addUsernameHandler(mUsernameEdit); - - mCreateAccount.setEnabled(true); - mCreateAccount.setOnClickListener(this); - - return view; - } - - @Override - public void onPause() { - super.onPause(); - mAccountCreator.setListener(null); - } - - private String getUsername() { - if (mUsernameEdit != null) { - String username = mUsernameEdit.getText().toString(); - return username.toLowerCase(Locale.getDefault()); - } - return null; - } - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (buttonView.getId() == R.id.use_username) { - if (isChecked) { - mUsernameLayout.setVisibility(View.VISIBLE); - onTextChanged2(); - } else { - mUsernameLayout.setVisibility(View.GONE); - mAccountCreator.setUsername(null); - onTextChanged2(); - } - } else if (buttonView.getId() == R.id.use_email) { - if (isChecked) { - mDialCode.setBackgroundResource(R.drawable.resizable_textfield); - mPhoneNumberEdit.setBackgroundResource(R.drawable.resizable_textfield); - mUseUsername.setEnabled(false); - mDialCode.setEnabled(false); - mSelectCountry.setEnabled(false); - mPhoneNumberEdit.setEnabled(false); - mEmailLayout.setVisibility(View.VISIBLE); - mPasswordLayout.setVisibility(View.VISIBLE); - mPasswordConfirmLayout.setVisibility(View.VISIBLE); - mUsernameLayout.setVisibility(View.VISIBLE); - mUseUsername.setVisibility(CheckBox.GONE); - mPhoneNumberLayout.setVisibility(LinearLayout.GONE); - mInstruction.setText(getString(R.string.assistant_create_account_part_email)); - } else { - if (!mUseUsername.isChecked()) { - mUsernameLayout.setVisibility(View.GONE); - } - mUseUsername.setEnabled(true); - mDialCode.setEnabled(true); - mSelectCountry.setEnabled(true); - mPhoneNumberEdit.setEnabled(true); - mEmailLayout.setVisibility(View.GONE); - mPasswordLayout.setVisibility(View.GONE); - mPasswordConfirmLayout.setVisibility(View.GONE); - mUseUsername.setVisibility(CheckBox.VISIBLE); - mPhoneNumberLayout.setVisibility(LinearLayout.VISIBLE); - mInstruction.setText(getString(R.string.assistant_create_account_part_1)); - } - } - } - - @Override - public void onClick(View v) { - int id = v.getId(); - if (id == R.id.select_country) { - AssistantActivity.instance().displayCountryChooser(); - } else if (id == R.id.assistant_skip) { - if (getArguments().getBoolean("LinkFromPref")) { - AssistantActivity.instance().finish(); - } else { - AssistantActivity.instance().success(); - } - } else if (id == R.id.info_phone_number) { - if (mLinkAccount) { - new AlertDialog.Builder(getActivity()) - .setTitle(getString(R.string.phone_number_info_title)) - .setMessage( - getString(R.string.phone_number_link_info_content) - + "\n" - + getString( - R.string - .phone_number_link_info_content_already_account)) - .show(); - } else { - new AlertDialog.Builder(getActivity()) - .setTitle(getString(R.string.phone_number_info_title)) - .setMessage(getString(R.string.phone_number_info_content)) - .show(); - } - } else if (id == R.id.assistant_create) { - mCreateAccount.setEnabled(false); - if (mLinkAccount) { - addAlias(); - } else { - if (mUseEmail.isChecked()) mAccountCreator.setPhoneNumber(null, null); - if (getUsername().length() > 0) { - mAccountCreator.isAccountExist(); - } else { - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForUsernameStatus( - AccountCreator.UsernameStatus.TooShort), - AssistantActivity.instance()); - mCreateAccount.setEnabled(true); - } - } - } - } - - private boolean isEmailCorrect(String email) { - Pattern emailPattern = Patterns.EMAIL_ADDRESS; - return emailPattern.matcher(email).matches(); - } - - private boolean isPasswordCorrect(String password) { - return password.length() >= 1; - } - - private void addAlias() { - mAccountCreator.setUsername( - LinphonePreferences.instance() - .getAccountUsername( - LinphonePreferences.instance().getDefaultAccountIndex())); - int status = - mAccountCreator.setPhoneNumber( - mPhoneNumberEdit.getText().toString(), - LinphoneUtils.getCountryCode(mDialCode)); - boolean isOk = status == AccountCreator.PhoneNumberStatus.Ok.toInt(); - if (isOk) { - mAccountCreator.linkAccount(); - } else { - mCreateAccount.setEnabled(true); - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForPhoneNumberStatus(status), AssistantActivity.instance()); - LinphoneUtils.displayError( - isOk, mPhoneNumberError, LinphoneUtils.errorForPhoneNumberStatus(status)); - } - } - - private void createAccount() { - if ((getResources().getBoolean(R.bool.isTablet) - || !getResources().getBoolean(R.bool.use_phone_number_validation)) - && mUseEmail.isChecked()) { - AccountCreator.EmailStatus emailStatus; - AccountCreator.PasswordStatus passwordStatus; - - passwordStatus = mAccountCreator.setPassword(mPasswordEdit.getText().toString()); - emailStatus = mAccountCreator.setEmail(mEmailEdit.getText().toString()); - - if (!mEmailOk) { - LinphoneUtils.displayError( - false, mEmailError, LinphoneUtils.errorForEmailStatus(emailStatus)); - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForEmailStatus(emailStatus), - AssistantActivity.instance()); - } else if (!mPasswordOk) { - LinphoneUtils.displayError( - false, - mPasswordError, - LinphoneUtils.errorForPasswordStatus(passwordStatus)); - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForPasswordStatus(passwordStatus), - AssistantActivity.instance()); - } else if (!mConfirmPasswordOk) { - String msg; - if (mPasswordConfirmEdit - .getText() - .toString() - .equals(mPasswordEdit.getText().toString())) { - msg = getString(R.string.wizard_password_incorrect); - } else { - msg = getString(R.string.wizard_passwords_unmatched); - } - LinphoneUtils.displayError(false, mPasswordError, msg); - LinphoneUtils.displayErrorAlert(msg, AssistantActivity.instance()); - } else { - mAccountCreator.createAccount(); - } - } else { - if (mPhoneNumberEdit.length() > 0 || mDialCode.length() > 1) { - int phoneStatus; - boolean isOk; - phoneStatus = - mAccountCreator.setPhoneNumber( - mPhoneNumberEdit.getText().toString(), - LinphoneUtils.getCountryCode(mDialCode)); - isOk = phoneStatus == AccountCreator.PhoneNumberStatus.Ok.toInt(); - if (!mUseUsername.isChecked() && mAccountCreator.getUsername() == null) { - mAccountCreator.setUsername(mAccountCreator.getPhoneNumber()); - } else { - mAccountCreator.setUsername(mUsernameEdit.getText().toString()); - mAccountCreator.setPhoneNumber( - mPhoneNumberEdit.getText().toString(), mDialCode.getText().toString()); - } - if (isOk) { - mAccountCreator.createAccount(); - } else { - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForPhoneNumberStatus(phoneStatus), - AssistantActivity.instance()); - LinphoneUtils.displayError( - isOk, - mPhoneNumberError, - LinphoneUtils.errorForPhoneNumberStatus(phoneStatus)); - } - } else { - LinphoneUtils.displayErrorAlert( - getString(R.string.assistant_create_account_part_1), - AssistantActivity.instance()); - } - } - mCreateAccount.setEnabled(true); - } - - private int getPhoneNumberStatus() { - int status = - mAccountCreator.setPhoneNumber( - mPhoneNumberEdit.getText().toString(), - LinphoneUtils.getCountryCode(mDialCode)); - mAddressSip = mAccountCreator.getPhoneNumber(); - return status; - } - - private void onTextChanged2() { - String msg = ""; - mAccountCreator.setUsername(getUsername()); - - if (!mUseEmail.isChecked() - && getResources().getBoolean(R.bool.use_phone_number_validation)) { - int status = getPhoneNumberStatus(); - boolean isOk = (status == AccountCreator.PhoneNumberStatus.Ok.toInt()); - LinphoneUtils.displayError( - isOk, mPhoneNumberError, LinphoneUtils.errorForPhoneNumberStatus(status)); - - // Username or phone number - if (getResources().getBoolean(R.bool.assistant_allow_username) - && mUseUsername.isChecked()) { - mAddressSip = getUsername(); - } - - if (!isOk) { - if (status == AccountCreator.PhoneNumberStatus.InvalidCountryCode.toInt()) { - mDialCode.setBackgroundResource(R.drawable.resizable_textfield_error); - mPhoneNumberEdit.setBackgroundResource(R.drawable.resizable_textfield); - } else { - mDialCode.setBackgroundResource(R.drawable.resizable_textfield); - mPhoneNumberEdit.setBackgroundResource(R.drawable.resizable_textfield_error); - } - - } else { - mDialCode.setBackgroundResource(R.drawable.resizable_textfield); - mPhoneNumberEdit.setBackgroundResource(R.drawable.resizable_textfield); - if (!mLinkAccount && mAddressSip.length() > 0) { - msg = - getResources() - .getString( - R.string - .assistant_create_account_phone_number_address) - + " <" - + mAddressSip - + "@" - + getResources().getString(R.string.default_domain) - + ">"; - } - } - } else { - mAddressSip = getUsername(); - if (mAddressSip.length() > 0) { - msg = - getResources() - .getString( - R.string - .assistant_create_account_phone_number_address) - + " "; - } - } - mSipUri.setText(msg); - } - - private void addPhoneNumberHandler(final EditText field) { - field.addTextChangedListener( - new TextWatcher() { - public void afterTextChanged(Editable s) { - if (field.equals(mDialCode)) { - DialPlan c = - AssistantActivity.instance() - .getCountryListAdapter() - .getCountryFromCountryCode( - mDialCode.getText().toString()); - if (c != null) { - AssistantActivity.instance().country = c; - mSelectCountry.setText(c.getCountry()); - } else { - mSelectCountry.setText(R.string.select_your_country); - } - } - } - - public void beforeTextChanged( - CharSequence s, int start, int count, int after) {} - - public void onTextChanged(CharSequence s, int start, int count, int after) { - onTextChanged2(); - } - }); - } - - private void addUsernameHandler(final EditText field) { - field.addTextChangedListener( - new TextWatcher() { - public void afterTextChanged(Editable s) { - Matcher matcher = UPPER_CASE_REGEX.matcher(s); - while (matcher.find()) { - CharSequence upperCaseRegion = - s.subSequence(matcher.start(), matcher.end()); - s.replace( - matcher.start(), - matcher.end(), - upperCaseRegion.toString().toLowerCase()); - } - } - - public void beforeTextChanged( - CharSequence s, int start, int count, int after) {} - - public void onTextChanged(CharSequence s, int start, int count, int after) { - onTextChanged2(); - } - }); - } - - private void addEmailHandler(final EditText field) { - field.addTextChangedListener( - new TextWatcher() { - public void afterTextChanged(Editable s) { - mEmailOk = false; - AccountCreator.EmailStatus status = - mAccountCreator.setEmail(field.getText().toString()); - if (status.equals(AccountCreator.EmailStatus.Ok)) { - mEmailOk = true; - LinphoneUtils.displayError(mEmailOk, mEmailError, ""); - } else { - LinphoneUtils.displayError( - mEmailOk, - mEmailError, - LinphoneUtils.errorForEmailStatus(status)); - } - } - - public void beforeTextChanged( - CharSequence s, int start, int count, int after) {} - - public void onTextChanged(CharSequence s, int start, int count, int after) {} - }); - } - - private void addPasswordHandler(final EditText field1) { - TextWatcher passwordListener = - new TextWatcher() { - public void afterTextChanged(Editable s) { - mPasswordOk = false; - AccountCreator.PasswordStatus status = - mAccountCreator.setPassword(field1.getText().toString()); - if (isPasswordCorrect(field1.getText().toString())) { - mPasswordOk = true; - LinphoneUtils.displayError(mPasswordOk, mPasswordError, ""); - } else { - LinphoneUtils.displayError( - mPasswordOk, - mPasswordError, - LinphoneUtils.errorForPasswordStatus(status)); - } - } - - public void beforeTextChanged( - CharSequence s, int start, int count, int after) {} - - public void onTextChanged(CharSequence s, int start, int count, int after) {} - }; - - field1.addTextChangedListener(passwordListener); - } - - private void addConfirmPasswordHandler(final EditText field1, final EditText field2) { - TextWatcher passwordListener = - new TextWatcher() { - public void afterTextChanged(Editable s) { - mConfirmPasswordOk = false; - if (field1.getText().toString().equals(field2.getText().toString())) { - mConfirmPasswordOk = true; - if (!isPasswordCorrect(field1.getText().toString())) { - LinphoneUtils.displayError( - mPasswordOk, - mPasswordError, - getString(R.string.wizard_password_incorrect)); - } else { - LinphoneUtils.displayError( - mConfirmPasswordOk, mPasswordConfirmError, ""); - } - } else { - LinphoneUtils.displayError( - mConfirmPasswordOk, - mPasswordConfirmError, - getString(R.string.wizard_passwords_unmatched)); - } - } - - public void beforeTextChanged( - CharSequence s, int start, int count, int after) {} - - public void onTextChanged(CharSequence s, int start, int count, int after) {} - }; - field1.addTextChangedListener(passwordListener); - field2.addTextChangedListener(passwordListener); - } - - @Override - public void onIsAccountExist(AccountCreator accountCreator, final Status status, String resp) { - if (status.equals(Status.AccountExist) || status.equals(Status.AccountExistWithAlias)) { - if (mUseEmail.isChecked()) { - mCreateAccount.setEnabled(true); - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForStatus(status), AssistantActivity.instance()); - } else { - accountCreator.isAliasUsed(); - } - } else { - createAccount(); - } - } - - @Override - public void onCreateAccount(AccountCreator accountCreator, Status status, String resp) { - if (status.equals(Status.AccountCreated)) { - if (mUseEmail.isChecked() - || !getResources().getBoolean(R.bool.use_phone_number_validation)) { - AssistantActivity.instance() - .displayAssistantConfirm( - getUsername(), - mPasswordEdit.getText().toString(), - mEmailEdit.getText().toString()); - } else { - AssistantActivity.instance() - .displayAssistantCodeConfirm( - getUsername(), - mPhoneNumberEdit.getText().toString(), - LinphoneUtils.getCountryCode(mDialCode), - false); - } - } else { - mCreateAccount.setEnabled(true); - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForStatus(status), AssistantActivity.instance()); - } - } - - @Override - public void onActivateAccount(AccountCreator accountCreator, Status status, String resp) {} - - @Override - public void onLinkAccount(AccountCreator accountCreator, Status status, String resp) { - if (AssistantActivity.instance() == null) { - return; - } - if (status.equals(Status.RequestOk)) { - AssistantActivity.instance() - .displayAssistantCodeConfirm( - getUsername(), - mPhoneNumberEdit.getText().toString(), - LinphoneUtils.getCountryCode(mDialCode), - false); - } - } - - @Override - public void onActivateAlias(AccountCreator accountCreator, Status status, String resp) { - if (AssistantActivity.instance() == null) { - return; - } - if (status.equals(Status.RequestOk)) { - AssistantActivity.instance() - .displayAssistantCodeConfirm( - getUsername(), - mPhoneNumberEdit.getText().toString(), - LinphoneUtils.getCountryCode(mDialCode), - false); - } - } - - @Override - public void onIsAccountActivated(AccountCreator accountCreator, Status status, String resp) { - if (AssistantActivity.instance() == null) { - return; - } - if (status.equals(Status.AccountNotActivated)) { - if (getResources().getBoolean(R.bool.isTablet) - || !getResources().getBoolean(R.bool.use_phone_number_validation)) { - // mAccountCreator.activateAccount(); // Resend email TODO - } else { - accountCreator.recoverAccount(); // Resend SMS - } - } else { - mCreateAccount.setEnabled(true); - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForStatus(status), AssistantActivity.instance()); - } - } - - @Override - public void onRecoverAccount(AccountCreator accountCreator, Status status, String resp) { - if (AssistantActivity.instance() == null) { - return; - } - if (status.equals(Status.RequestOk)) { - AssistantActivity.instance() - .displayAssistantCodeConfirm( - getUsername(), - mPhoneNumberEdit.getText().toString(), - mDialCode.getText().toString(), - false); - } else { - mCreateAccount.setEnabled(true); - // SMS error - LinphoneUtils.displayErrorAlert( - getString(R.string.request_failed), AssistantActivity.instance()); - } - } - - @Override - public void onIsAccountLinked(AccountCreator accountCreator, Status status, String resp) {} - - @Override - public void onIsAliasUsed(AccountCreator ac, Status status, String resp) { - if (AssistantActivity.instance() == null) { - return; - } - if (status.equals(Status.AliasIsAccount) || status.equals(Status.AliasExist)) { - if (mAccountCreator.getPhoneNumber() != null - && mAccountCreator.getUsername() != null - && mAccountCreator.getPhoneNumber().compareTo(mAccountCreator.getUsername()) - == 0) { - mAccountCreator.isAccountActivated(); - } else { - mCreateAccount.setEnabled(true); - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForStatus(status), AssistantActivity.instance()); - } - } else { - mAccountCreator.isAccountActivated(); - } - } - - @Override - public void onUpdateAccount(AccountCreator accountCreator, Status status, String resp) {} -} diff --git a/app/src/main/java/org/linphone/assistant/EchoCancellerCalibrationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/EchoCancellerCalibrationAssistantActivity.java new file mode 100644 index 000000000..d3f53fe31 --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/EchoCancellerCalibrationAssistantActivity.java @@ -0,0 +1,131 @@ +package org.linphone.assistant; + +/* +EchoCancellerCalibrationAssistantActivity.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.Manifest; +import android.content.Context; +import android.content.pm.PackageManager; +import android.media.AudioManager; +import android.os.Bundle; +import androidx.annotation.Nullable; +import androidx.core.app.ActivityCompat; +import org.linphone.LinphoneManager; +import org.linphone.R; +import org.linphone.core.Core; +import org.linphone.core.CoreListenerStub; +import org.linphone.core.EcCalibratorStatus; +import org.linphone.core.tools.Log; +import org.linphone.settings.LinphonePreferences; + +public class EchoCancellerCalibrationAssistantActivity extends AssistantActivity { + private static final int RECORD_AUDIO_PERMISSION_RESULT = 1; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.assistant_echo_canceller_calibration); + } + + @Override + protected void onStart() { + super.onStart(); + + checkRecordAudioPermissionForEchoCancellerCalibration(); + } + + @Override + protected void onResume() { + super.onResume(); + + LinphonePreferences.instance().setEchoCancellationCalibrationDone(true); + if (isRecordAudioPermissionGranted()) { + startEchoCancellerCalibration(); + } else { + goToLinphoneActivity(); + } + } + + @Override + public void onRequestPermissionsResult( + int requestCode, String[] permissions, final int[] grantResults) { + for (int i = 0; i < permissions.length; i++) { + Log.i( + "[Permission] " + + permissions[i] + + " has been " + + (grantResults[i] == PackageManager.PERMISSION_GRANTED + ? "granted" + : "denied")); + } + + switch (requestCode) { + case RECORD_AUDIO_PERMISSION_RESULT: + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + startEchoCancellerCalibration(); + } else { + // TODO: permission denied, display something to the user + } + break; + } + } + + private boolean isRecordAudioPermissionGranted() { + int permissionGranted = + getPackageManager() + .checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()); + Log.i( + "[Permission] Manifest.permission.RECORD_AUDIO is " + + (permissionGranted == PackageManager.PERMISSION_GRANTED + ? "granted" + : "denied")); + + return permissionGranted == PackageManager.PERMISSION_GRANTED; + } + + private void checkRecordAudioPermissionForEchoCancellerCalibration() { + if (!isRecordAudioPermissionGranted()) { + Log.i("[Permission] Asking for " + Manifest.permission.RECORD_AUDIO); + ActivityCompat.requestPermissions( + this, + new String[] {Manifest.permission.RECORD_AUDIO}, + RECORD_AUDIO_PERMISSION_RESULT); + } + } + + private void startEchoCancellerCalibration() { + LinphoneManager.getLc() + .addListener( + new CoreListenerStub() { + @Override + public void onEcCalibrationResult( + Core core, EcCalibratorStatus status, int delayMs) { + if (status == EcCalibratorStatus.InProgress) return; + core.removeListener(this); + LinphoneManager.getInstance().routeAudioToReceiver(); + goToLinphoneActivity(); + + ((AudioManager) getSystemService(Context.AUDIO_SERVICE)) + .setMode(AudioManager.MODE_NORMAL); + } + }); + LinphoneManager.getInstance().startEcCalibration(); + } +} diff --git a/app/src/main/java/org/linphone/assistant/EchoCancellerCalibrationFragment.java b/app/src/main/java/org/linphone/assistant/EchoCancellerCalibrationFragment.java deleted file mode 100644 index bd463dccc..000000000 --- a/app/src/main/java/org/linphone/assistant/EchoCancellerCalibrationFragment.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.linphone.assistant; - -/* -EchoCancellerCalibrationFragment.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import android.app.Fragment; -import android.os.Build; -import android.os.Bundle; -import android.os.Handler; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import org.linphone.LinphoneManager; -import org.linphone.R; -import org.linphone.core.Core; -import org.linphone.core.CoreListenerStub; -import org.linphone.core.EcCalibratorStatus; -import org.linphone.core.XmlRpcArgType; -import org.linphone.core.XmlRpcRequest; -import org.linphone.core.XmlRpcRequestListener; -import org.linphone.core.XmlRpcSession; -import org.linphone.core.tools.Log; -import org.linphone.settings.LinphonePreferences; - -public class EchoCancellerCalibrationFragment extends Fragment implements XmlRpcRequestListener { - private final Handler mHandler = new Handler(); - private boolean mSendEcCalibrationResult = false; - private CoreListenerStub mListener; - private XmlRpcSession mXmlRpcSession; - private XmlRpcRequest mXmlRpcRequest; - private Runnable mRunFinished; - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.assistant_ec_calibration, container, false); - - mListener = - new CoreListenerStub() { - @Override - public void onEcCalibrationResult( - Core lc, EcCalibratorStatus status, int delay_ms) { - lc.removeListener(mListener); - LinphoneManager.getInstance().routeAudioToReceiver(); - if (mSendEcCalibrationResult) { - sendEcCalibrationResult(status, delay_ms); - } else { - AssistantActivity.instance().isEchoCalibrationFinished(); - } - } - }; - mRunFinished = - new Runnable() { - public void run() { - AssistantActivity.instance().isEchoCalibrationFinished(); - } - }; - - mXmlRpcSession = - LinphoneManager.getLcIfManagerNotDestroyedOrNull() - .createXmlRpcSession(LinphonePreferences.instance().getXmlrpcUrl()); - mXmlRpcRequest = - mXmlRpcSession.createRequest(XmlRpcArgType.None, "add_ec_calibration_result"); - mXmlRpcRequest.setListener(this); - - LinphoneManager.getLc().addListener(mListener); - LinphoneManager.getInstance().startEcCalibration(); - return view; - } - - public void enableEcCalibrationResultSending(boolean enabled) { - mSendEcCalibrationResult = enabled; - } - - @Override - public void onResponse(XmlRpcRequest request) { - mHandler.post(mRunFinished); - } - - private void sendEcCalibrationResult(EcCalibratorStatus status, int delayMs) { - Boolean hasBuiltInEchoCanceler = LinphoneManager.getLc().hasBuiltinEchoCanceller(); - Log.i( - "Add echo canceller calibration result: manufacturer=" - + Build.MANUFACTURER - + " model=" - + Build.MODEL - + " status=" - + status - + " delay=" - + delayMs - + "ms" - + " hasBuiltInEchoCanceler " - + hasBuiltInEchoCanceler); - mXmlRpcRequest.addStringArg(Build.MANUFACTURER); - mXmlRpcRequest.addStringArg(Build.MODEL); - mXmlRpcRequest.addStringArg(status.toString()); - mXmlRpcRequest.addIntArg(delayMs); - mXmlRpcRequest.addIntArg(hasBuiltInEchoCanceler ? 1 : 0); - mXmlRpcSession.sendRequest(mXmlRpcRequest); - } -} diff --git a/app/src/main/java/org/linphone/assistant/EmailAccountCreationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/EmailAccountCreationAssistantActivity.java new file mode 100644 index 000000000..c0f856742 --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/EmailAccountCreationAssistantActivity.java @@ -0,0 +1,270 @@ +package org.linphone.assistant; + +/* +EmailAccountCreationAssistantActivity.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Patterns; +import android.view.View; +import android.widget.EditText; +import android.widget.TextView; +import androidx.annotation.Nullable; +import org.linphone.R; +import org.linphone.core.AccountCreator; +import org.linphone.core.AccountCreatorListenerStub; +import org.linphone.core.tools.Log; + +public class EmailAccountCreationAssistantActivity extends AssistantActivity { + private EditText mUsername, mPassword, mPasswordConfirm, mEmail; + private TextView mCreate, mUsernameError, mPasswordError, mPasswordConfirmError, mEmailError; + + private AccountCreatorListenerStub mListener; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.assistant_email_account_creation); + + mUsernameError = findViewById(R.id.username_error); + mPasswordError = findViewById(R.id.password_error); + mPasswordConfirmError = findViewById(R.id.confirm_password_error); + mEmailError = findViewById(R.id.email_error); + + mUsername = findViewById(R.id.assistant_username); + mUsername.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + AccountCreator.UsernameStatus status = + mAccountCreator.setUsername(s.toString()); + mUsernameError.setVisibility( + status == AccountCreator.UsernameStatus.Ok + ? View.INVISIBLE + : View.VISIBLE); + switch (status) { + case Invalid: + mUsernameError.setText(getString(R.string.username_invalid_size)); + break; + case InvalidCharacters: + mUsernameError.setText(getString(R.string.invalid_characters)); + break; + case TooLong: + mUsernameError.setText(getString(R.string.username_too_long)); + break; + case TooShort: + mUsernameError.setText(getString(R.string.username_too_short)); + break; + } + updateCreateButton(); + } + }); + + mPassword = findViewById(R.id.assistant_password); + mPassword.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + AccountCreator.PasswordStatus status = + mAccountCreator.setPassword(s.toString()); + mPasswordError.setVisibility( + status == AccountCreator.PasswordStatus.Ok + ? View.INVISIBLE + : View.VISIBLE); + + mPasswordConfirmError.setVisibility( + s.toString().equals(mPasswordConfirm.getText().toString()) + ? View.INVISIBLE + : View.VISIBLE); + + switch (status) { + case InvalidCharacters: + mPasswordError.setText(getString(R.string.invalid_characters)); + break; + case TooLong: + mPasswordError.setText(getString(R.string.password_too_long)); + break; + case TooShort: + mPasswordError.setText(getString(R.string.password_too_short)); + break; + } + updateCreateButton(); + } + }); + + mPasswordConfirm = findViewById(R.id.assistant_password_confirmation); + mPasswordConfirm.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + mPasswordConfirmError.setVisibility( + s.toString().equals(mPassword.getText().toString()) + ? View.INVISIBLE + : View.VISIBLE); + updateCreateButton(); + } + }); + + mEmail = findViewById(R.id.assistant_email); + mEmail.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + AccountCreator.EmailStatus status = mAccountCreator.setEmail(s.toString()); + mEmailError.setVisibility( + status == AccountCreator.EmailStatus.Ok + ? View.INVISIBLE + : View.VISIBLE); + updateCreateButton(); + } + }); + + mCreate = findViewById(R.id.assistant_create); + mCreate.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + enableButtonsAndFields(false); + mAccountCreator.setDomain(getString(R.string.default_domain)); + + AccountCreator.Status status = mAccountCreator.isAccountExist(); + if (status != AccountCreator.Status.RequestOk) { + enableButtonsAndFields(true); + Log.e("[Email Account Creation] isAccountExists returned " + status); + showGenericErrorDialog(status); + } + } + }); + mCreate.setEnabled(false); + + mListener = + new AccountCreatorListenerStub() { + public void onIsAccountExist( + AccountCreator creator, AccountCreator.Status status, String resp) { + Log.i("[Email Account Creation] onIsAccountExist status is " + status); + if (status.equals(AccountCreator.Status.AccountExist) + || status.equals(AccountCreator.Status.AccountExistWithAlias)) { + showAccountAlreadyExistsDialog(); + enableButtonsAndFields(true); + } else if (status.equals(AccountCreator.Status.AccountNotExist)) { + status = mAccountCreator.createAccount(); + if (status != AccountCreator.Status.RequestOk) { + Log.e("[Email Account Creation] createAccount returned " + status); + enableButtonsAndFields(true); + showGenericErrorDialog(status); + } + } else { + enableButtonsAndFields(true); + showGenericErrorDialog(status); + } + } + + @Override + public void onCreateAccount( + AccountCreator creator, AccountCreator.Status status, String resp) { + Log.i("[Email Account Creation] onCreateAccount status is " + status); + if (status.equals(AccountCreator.Status.AccountCreated)) { + startActivity( + new Intent( + EmailAccountCreationAssistantActivity.this, + EmailAccountValidationAssistantActivity.class)); + } else { + enableButtonsAndFields(true); + showGenericErrorDialog(status); + } + } + }; + } + + private void enableButtonsAndFields(boolean enable) { + mUsername.setEnabled(enable); + mPassword.setEnabled(enable); + mPasswordConfirm.setEnabled(enable); + mEmail.setEnabled(enable); + mCreate.setEnabled(enable); + } + + private void updateCreateButton() { + mCreate.setEnabled( + mUsername.getText().length() > 0 + && mPassword.getText().toString().length() > 0 + && mEmail.getText().toString().length() > 0 + && mEmailError.getVisibility() == View.INVISIBLE + && mUsernameError.getVisibility() == View.INVISIBLE + && mPasswordError.getVisibility() == View.INVISIBLE + && mPasswordConfirmError.getVisibility() == View.INVISIBLE); + } + + @Override + protected void onResume() { + super.onResume(); + + mAccountCreator.addListener(mListener); + + if (getResources().getBoolean(R.bool.pre_fill_email_in_assistant)) { + Account[] accounts = AccountManager.get(this).getAccountsByType("com.google"); + for (Account account : accounts) { + if (Patterns.EMAIL_ADDRESS.matcher(account.name).matches()) { + String possibleEmail = account.name; + mEmail.setText(possibleEmail); + break; + } + } + } + } + + @Override + protected void onPause() { + super.onPause(); + mAccountCreator.removeListener(mListener); + } +} diff --git a/app/src/main/java/org/linphone/assistant/EmailAccountValidationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/EmailAccountValidationAssistantActivity.java new file mode 100644 index 000000000..4d7bb92aa --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/EmailAccountValidationAssistantActivity.java @@ -0,0 +1,101 @@ +package org.linphone.assistant; + +/* +PhoneAccountValidationAssistantActivity.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; +import androidx.annotation.Nullable; +import org.linphone.R; +import org.linphone.core.AccountCreator; +import org.linphone.core.AccountCreatorListenerStub; +import org.linphone.core.tools.Log; + +public class EmailAccountValidationAssistantActivity extends AssistantActivity { + private TextView mEmail, mFinishCreation; + + private AccountCreatorListenerStub mListener; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.assistant_email_account_validation); + + mEmail = findViewById(R.id.send_email); + mEmail.setText(mAccountCreator.getEmail()); + + mFinishCreation = findViewById(R.id.assistant_check); + mFinishCreation.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + mFinishCreation.setEnabled(false); + + AccountCreator.Status status = mAccountCreator.isAccountActivated(); + if (status != AccountCreator.Status.RequestOk) { + Log.e("[Email Account Validation] activateAccount returned " + status); + mFinishCreation.setEnabled(true); + showGenericErrorDialog(status); + } + } + }); + + mListener = + new AccountCreatorListenerStub() { + @Override + public void onIsAccountActivated( + AccountCreator creator, AccountCreator.Status status, String resp) { + Log.i( + "[Email Account Validation] onIsAccountActivated status is " + + status); + if (status.equals(AccountCreator.Status.AccountActivated)) { + createProxyConfigAndLeaveAssistant(); + } else if (status.equals(AccountCreator.Status.AccountNotActivated)) { + Toast.makeText( + EmailAccountValidationAssistantActivity.this, + getString(R.string.assistant_account_not_validated), + Toast.LENGTH_LONG) + .show(); + mFinishCreation.setEnabled(true); + } else { + showGenericErrorDialog(status); + mFinishCreation.setEnabled(true); + } + } + }; + } + + @Override + protected void onResume() { + super.onResume(); + mAccountCreator.addListener(mListener); + + // Prevent user to go back, it won't be able to come back here after... + mBack.setEnabled(false); + } + + @Override + protected void onPause() { + super.onPause(); + mAccountCreator.removeListener(mListener); + } +} diff --git a/app/src/main/java/org/linphone/assistant/GenericConnectionAssistantActivity.java b/app/src/main/java/org/linphone/assistant/GenericConnectionAssistantActivity.java new file mode 100644 index 000000000..107e24f40 --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/GenericConnectionAssistantActivity.java @@ -0,0 +1,108 @@ +package org.linphone.assistant; + +/* +GenericConnectionAssistantActivity.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.widget.EditText; +import android.widget.RadioGroup; +import android.widget.TextView; +import androidx.annotation.Nullable; +import org.linphone.LinphoneManager; +import org.linphone.R; +import org.linphone.core.AccountCreator; +import org.linphone.core.TransportType; +import org.linphone.settings.LinphonePreferences; + +public class GenericConnectionAssistantActivity extends AssistantActivity implements TextWatcher { + private TextView mLogin; + private EditText mUsername, mPassword, mDomain, mDisplayName; + private RadioGroup mTransport; + + private AccountCreator mAccountCreator; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.assistant_generic_connection); + + mLogin = findViewById(R.id.assistant_login); + mLogin.setEnabled(false); + mLogin.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + configureAccount(); + } + }); + + mUsername = findViewById(R.id.assistant_username); + mUsername.addTextChangedListener(this); + mDisplayName = findViewById(R.id.assistant_display_name); + mDisplayName.addTextChangedListener(this); + mPassword = findViewById(R.id.assistant_password); + mPassword.addTextChangedListener(this); + mDomain = findViewById(R.id.assistant_domain); + mDomain.addTextChangedListener(this); + mTransport = findViewById(R.id.assistant_transports); + + mAccountCreator = + LinphoneManager.getLcIfManagerNotDestroyedOrNull() + .createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl()); + } + + private void configureAccount() { + mAccountCreator.setUsername(mUsername.getText().toString()); + mAccountCreator.setDomain(mDomain.getText().toString()); + mAccountCreator.setPassword(mPassword.getText().toString()); + mAccountCreator.setDisplayName(mDisplayName.getText().toString()); + // TODO: mUserId + + switch (mTransport.getCheckedRadioButtonId()) { + case R.id.transport_udp: + mAccountCreator.setTransport(TransportType.Udp); + break; + case R.id.transport_tcp: + mAccountCreator.setTransport(TransportType.Tcp); + break; + case R.id.transport_tls: + mAccountCreator.setTransport(TransportType.Tls); + break; + } + + createProxyConfigAndLeaveAssistant(); + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + mLogin.setEnabled( + !mUsername.getText().toString().isEmpty() + && !mDomain.getText().toString().isEmpty()); + } + + @Override + public void afterTextChanged(Editable s) {} +} diff --git a/app/src/main/java/org/linphone/assistant/LinphoneLoginFragment.java b/app/src/main/java/org/linphone/assistant/LinphoneLoginFragment.java deleted file mode 100644 index c58cd133d..000000000 --- a/app/src/main/java/org/linphone/assistant/LinphoneLoginFragment.java +++ /dev/null @@ -1,426 +0,0 @@ -package org.linphone.assistant; -/* -LinphoneLoginFragment.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import android.app.AlertDialog; -import android.app.Fragment; -import android.content.Context; -import android.os.Build; -import android.os.Bundle; -import android.telephony.TelephonyManager; -import android.text.Editable; -import android.text.Html; -import android.text.TextWatcher; -import android.text.method.LinkMovementMethod; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import java.util.Locale; -import org.linphone.LinphoneManager; -import org.linphone.R; -import org.linphone.core.AccountCreator; -import org.linphone.core.AccountCreatorListener; -import org.linphone.core.DialPlan; -import org.linphone.settings.LinphonePreferences; -import org.linphone.utils.LinphoneUtils; - -public class LinphoneLoginFragment extends Fragment - implements CompoundButton.OnCheckedChangeListener, - OnClickListener, - TextWatcher, - AccountCreatorListener { - private EditText mLogin, mPassword, mPhoneNumberEdit, mDialCode; - private Button mApply, mSelectCountry; - private CheckBox mUseUsername; - private LinearLayout mPhoneNumberLayout, mUsernameLayout, mPasswordLayout; - private TextView mForgotPassword, mMessagePhoneNumber, mPhoneNumberError; - private AccountCreator mAccountCreator; - private int mCountryCode; - private String mPhone, mUsername, mPwd; - private ImageView mPhoneNumberInfo; - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.assistant_linphone_login, container, false); - - mAccountCreator = - LinphoneManager.getLc() - .createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl()); - mAccountCreator.setListener(this); - - mLogin = view.findViewById(R.id.assistant_username); - mLogin.addTextChangedListener(this); - - mDialCode = view.findViewById(R.id.dial_code); - - mPhoneNumberEdit = view.findViewById(R.id.phone_number); - mPhoneNumberLayout = view.findViewById(R.id.phone_number_layout); - mPhoneNumberError = view.findViewById(R.id.phone_number_error_2); - - mPhoneNumberInfo = view.findViewById(R.id.info_phone_number); - - mUseUsername = view.findViewById(R.id.use_username); - mUsernameLayout = view.findViewById(R.id.username_layout); - mPasswordLayout = view.findViewById(R.id.password_layout); - mPassword = view.findViewById(R.id.assistant_password); - mMessagePhoneNumber = view.findViewById(R.id.message_phone_number); - - mForgotPassword = view.findViewById(R.id.forgot_password); - mSelectCountry = view.findViewById(R.id.select_country); - - mApply = view.findViewById(R.id.assistant_apply); - mApply.setEnabled(true); - mApply.setOnClickListener(this); - - // Phone number - if (getResources().getBoolean(R.bool.use_phone_number_validation)) { - mMessagePhoneNumber.setText(getString(R.string.assistant_create_account_part_1)); - mPhone = getArguments().getString("Phone"); - String prefix = getArguments().getString("Dialcode"); - - getActivity().getApplicationContext(); - // Automatically get the country code from the mPhone - TelephonyManager tm = - (TelephonyManager) - getActivity() - .getApplicationContext() - .getSystemService(Context.TELEPHONY_SERVICE); - String countryIso = tm.getNetworkCountryIso(); - mCountryCode = org.linphone.core.Utils.getCccFromIso(countryIso.toUpperCase()); - - DialPlan c = AssistantActivity.instance().country; - if (c != null) { - mSelectCountry.setText(c.getCountry()); - mDialCode.setText( - c.getCountryCallingCode().contains("+") - ? c.getCountryCallingCode() - : "+" + c.getCountryCallingCode()); - } else { - c = - AssistantActivity.instance() - .getCountryListAdapter() - .getCountryFromCountryCode(String.valueOf(mCountryCode)); - if (c != null) { - mSelectCountry.setText(c.getCountry()); - mDialCode.setText( - c.getCountryCallingCode().contains("+") - ? c.getCountryCallingCode() - : "+" + c.getCountryCallingCode()); - } - } - - mPhoneNumberLayout.setVisibility(View.VISIBLE); - mSelectCountry.setOnClickListener(this); - mPhoneNumberInfo.setOnClickListener(this); - - // Allow user to enter a mUsername instead use the mPhone number as mUsername - if (getResources().getBoolean(R.bool.assistant_allow_username)) { - mUseUsername.setVisibility(View.VISIBLE); - mUseUsername.setOnCheckedChangeListener(this); - } - - if (mPhone != null) mPhoneNumberEdit.setText(mPhone); - if (prefix != null) mDialCode.setText("+" + prefix); - } - - if (getResources().getBoolean(R.bool.assistant_allow_username)) { - mUseUsername.setVisibility(View.VISIBLE); - mUseUsername.setOnCheckedChangeListener(this); - mPassword.addTextChangedListener(this); - mForgotPassword.setText( - Html.fromHtml( - "" - + getString(R.string.forgot_password) - + "")); - mForgotPassword.setMovementMethod(LinkMovementMethod.getInstance()); - } - - // Hide mPhone number and display mUsername/email/mPassword - if (!getResources().getBoolean(R.bool.use_phone_number_validation)) { - mPhoneNumberLayout.setVisibility(View.GONE); - mUseUsername.setVisibility(View.GONE); - - mUsernameLayout.setVisibility(View.VISIBLE); - mPasswordLayout.setVisibility(View.VISIBLE); - } - - // When we come from generic mLogin fragment - mUsername = getArguments().getString("Username"); - mPwd = getArguments().getString("Password"); - if (mUsername != null && mPwd != null) { - mUseUsername.setChecked(true); - onCheckedChanged(mUseUsername, true); - mLogin.setText(mUsername); - mPassword.setText(mPwd); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mAccountCreator.setLanguage(Locale.getDefault().toLanguageTag()); - } - - addPhoneNumberHandler(mDialCode); - addPhoneNumberHandler(mPhoneNumberEdit); - - return view; - } - - private void linphoneLogIn() { - if (mLogin.getText() == null - || mLogin.length() == 0 - || mPassword.getText() == null - || mPassword.length() == 0) { - LinphoneUtils.displayErrorAlert( - getString(R.string.first_launch_no_login_password), - AssistantActivity.instance()); - mApply.setEnabled(true); - return; - } - mAccountCreator.setUsername(mLogin.getText().toString()); - mAccountCreator.setPassword(mPassword.getText().toString()); - mAccountCreator.setDomain(getString(R.string.default_domain)); - mAccountCreator.isAccountExist(); - } - - private int getPhoneNumberStatus() { - mAccountCreator.setDomain(getString(R.string.default_domain)); - return mAccountCreator.setPhoneNumber( - mPhoneNumberEdit.getText().toString(), LinphoneUtils.getCountryCode(mDialCode)); - } - - private void addPhoneNumberHandler(final EditText field) { - field.addTextChangedListener( - new TextWatcher() { - public void afterTextChanged(Editable s) { - if (field.equals(mDialCode)) { - DialPlan c = - AssistantActivity.instance() - .getCountryListAdapter() - .getCountryFromCountryCode( - mDialCode.getText().toString()); - if (c != null) { - AssistantActivity.instance().country = c; - mSelectCountry.setText(c.getCountry()); - } else { - mSelectCountry.setText(R.string.select_your_country); - } - } - } - - public void beforeTextChanged( - CharSequence s, int start, int count, int after) {} - - public void onTextChanged(CharSequence s, int start, int count, int after) { - onTextChanged2(); - } - }); - } - - @Override - public void onResume() { - super.onResume(); - } - - @Override - public void onClick(View v) { - int id = v.getId(); - if (id == R.id.assistant_apply) { - mApply.setEnabled(false); - if (mUseUsername == null || !mUseUsername.isChecked()) { - recoverAccount(); - } else { - linphoneLogIn(); - } - } else if (id == R.id.info_phone_number) { - new AlertDialog.Builder(getActivity()) - .setTitle(getString(R.string.phone_number_info_title)) - .setMessage(getString(R.string.phone_number_link_info_content)) - .show(); - } else if (id == R.id.select_country) { - AssistantActivity.instance().displayCountryChooser(); - } - } - - private void recoverAccount() { - if (mPhoneNumberEdit.getText().length() > 0 || mDialCode.getText().length() > 1) { - int status = getPhoneNumberStatus(); - boolean isOk = status == AccountCreator.PhoneNumberStatus.Ok.toInt(); - if (isOk) { - mAccountCreator.isAliasUsed(); - } else { - mApply.setEnabled(true); - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForPhoneNumberStatus(status), - AssistantActivity.instance()); - LinphoneUtils.displayError( - isOk, mPhoneNumberError, LinphoneUtils.errorForPhoneNumberStatus(status)); - } - } else { - mApply.setEnabled(true); - LinphoneUtils.displayErrorAlert( - getString(R.string.assistant_create_account_part_1), - AssistantActivity.instance()); - } - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - - private void onTextChanged2() { - int status = getPhoneNumberStatus(); - boolean isOk = status == AccountCreator.PhoneNumberStatus.Ok.toInt(); - LinphoneUtils.displayError( - isOk, mPhoneNumberError, LinphoneUtils.errorForPhoneNumberStatus(status)); - if (!isOk) { - if ((1 == (status & AccountCreator.PhoneNumberStatus.InvalidCountryCode.toInt()))) { - mDialCode.setBackgroundResource(R.drawable.resizable_textfield_error); - mPhoneNumberEdit.setBackgroundResource(R.drawable.resizable_textfield); - } else { - mDialCode.setBackgroundResource(R.drawable.resizable_textfield); - mPhoneNumberEdit.setBackgroundResource(R.drawable.resizable_textfield_error); - } - } else { - mAccountCreator.setPhoneNumber( - mPhoneNumberEdit.getText().toString(), mDialCode.getText().toString()); - mDialCode.setBackgroundResource(R.drawable.resizable_textfield); - mPhoneNumberEdit.setBackgroundResource(R.drawable.resizable_textfield); - } - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - onTextChanged2(); - } - - @Override - public void afterTextChanged(Editable s) {} - - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if (buttonView.getId() == R.id.use_username) { - if (isChecked) { - mUsernameLayout.setVisibility(View.VISIBLE); - mPasswordLayout.setVisibility(View.VISIBLE); - mPhoneNumberEdit.setVisibility(EditText.GONE); - mPhoneNumberLayout.setVisibility(LinearLayout.GONE); - mMessagePhoneNumber.setText(getString(R.string.assistant_linphone_login_desc)); - } else { - mUsernameLayout.setVisibility(View.GONE); - mPasswordLayout.setVisibility(View.GONE); - mPhoneNumberEdit.setVisibility(EditText.VISIBLE); - mPhoneNumberLayout.setVisibility(LinearLayout.VISIBLE); - mMessagePhoneNumber.setText(getString(R.string.assistant_create_account_part_1)); - } - } - } - - @Override - public void onIsAccountExist( - AccountCreator accountCreator, AccountCreator.Status status, String resp) { - if (AssistantActivity.instance() == null) { - mApply.setEnabled(true); - return; - } - if (status.equals(AccountCreator.Status.AccountExist) - || status.equals(AccountCreator.Status.AccountExistWithAlias)) { - AssistantActivity.instance().linphoneLogIn(accountCreator); - } else { - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForStatus(status), AssistantActivity.instance()); - } - mApply.setEnabled(true); - } - - @Override - public void onCreateAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onActivateAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onLinkAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onActivateAlias( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onIsAccountActivated( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onRecoverAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) { - if (AssistantActivity.instance() == null) { - mApply.setEnabled(true); - return; - } - if (status.equals(AccountCreator.Status.ServerError)) { - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForStatus(AccountCreator.Status.RequestFailed), - AssistantActivity.instance()); - mApply.setEnabled(true); - } else { - AssistantActivity.instance() - .displayAssistantCodeConfirm( - accountCreator.getUsername(), - mPhoneNumberEdit.getText().toString(), - LinphoneUtils.getCountryCode(mDialCode), - true); - } - } - - @Override - public void onIsAccountLinked( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} - - @Override - public void onIsAliasUsed( - AccountCreator accountCreator, AccountCreator.Status status, String resp) { - if (AssistantActivity.instance() == null) { - mApply.setEnabled(true); - return; - } - if (status.equals(AccountCreator.Status.AliasIsAccount) - || status.equals(AccountCreator.Status.AliasExist)) { - accountCreator.recoverAccount(); - } else { - mApply.setEnabled(true); - LinphoneUtils.displayErrorAlert( - LinphoneUtils.errorForStatus(status), AssistantActivity.instance()); - } - } - - @Override - public void onUpdateAccount( - AccountCreator accountCreator, AccountCreator.Status status, String resp) {} -} diff --git a/app/src/main/java/org/linphone/assistant/LoginFragment.java b/app/src/main/java/org/linphone/assistant/LoginFragment.java deleted file mode 100644 index e8465685e..000000000 --- a/app/src/main/java/org/linphone/assistant/LoginFragment.java +++ /dev/null @@ -1,125 +0,0 @@ -package org.linphone.assistant; -/* -LoginFragment.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import android.app.Fragment; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; -import android.widget.RadioGroup; -import android.widget.Toast; -import org.linphone.R; -import org.linphone.core.TransportType; - -public class LoginFragment extends Fragment implements OnClickListener, TextWatcher { - private EditText mLogin, mUserid, mPassword, mDomain, mDisplayName; - private RadioGroup mTransports; - private Button mApply; - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.assistant_login, container, false); - - mLogin = view.findViewById(R.id.assistant_username); - mLogin.addTextChangedListener(this); - mDisplayName = view.findViewById(R.id.assistant_display_name); - mDisplayName.addTextChangedListener(this); - mUserid = view.findViewById(R.id.assistant_userid); - mUserid.addTextChangedListener(this); - mPassword = view.findViewById(R.id.assistant_password); - mPassword.addTextChangedListener(this); - mDomain = view.findViewById(R.id.assistant_domain); - mDomain.addTextChangedListener(this); - mTransports = view.findViewById(R.id.assistant_transports); - mApply = view.findViewById(R.id.assistant_apply); - mApply.setEnabled(false); - mApply.setOnClickListener(this); - - return view; - } - - @Override - public void onClick(View v) { - int id = v.getId(); - - if (id == R.id.assistant_apply) { - if (mLogin.getText() == null - || mLogin.length() == 0 - || mPassword.getText() == null - || mPassword.length() == 0 - || mDomain.getText() == null - || mDomain.length() == 0) { - Toast.makeText( - getActivity(), - getString(R.string.first_launch_no_login_password), - Toast.LENGTH_LONG) - .show(); - return; - } - - TransportType transport; - if (mTransports.getCheckedRadioButtonId() == R.id.transport_udp) { - transport = TransportType.Udp; - } else { - if (mTransports.getCheckedRadioButtonId() == R.id.transport_tcp) { - transport = TransportType.Tcp; - } else { - transport = TransportType.Tls; - } - } - - if (mDomain.getText().toString().compareTo(getString(R.string.default_domain)) == 0) { - AssistantActivity.instance() - .displayLoginLinphone( - mLogin.getText().toString(), mPassword.getText().toString()); - } else { - AssistantActivity.instance() - .genericLogIn( - mLogin.getText().toString(), - mUserid.getText().toString(), - mPassword.getText().toString(), - mDisplayName.getText().toString(), - null, - mDomain.getText().toString(), - transport); - } - } - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - mApply.setEnabled( - !mLogin.getText().toString().isEmpty() - && !mPassword.getText().toString().isEmpty() - && !mDomain.getText().toString().isEmpty()); - } - - @Override - public void afterTextChanged(Editable s) {} -} diff --git a/app/src/main/java/org/linphone/assistant/MenuAssistantActivity.java b/app/src/main/java/org/linphone/assistant/MenuAssistantActivity.java new file mode 100644 index 000000000..c9ab0d7fe --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/MenuAssistantActivity.java @@ -0,0 +1,164 @@ +package org.linphone.assistant; + +/* +MenuAssistantActivity.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.content.Intent; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.View; +import android.widget.TextView; +import androidx.annotation.Nullable; +import org.linphone.R; +import org.linphone.core.tools.Log; +import org.linphone.settings.LinphonePreferences; + +public class MenuAssistantActivity extends AssistantActivity { + private TextView mAccountCreation, mAccountConnection, mGenericConnection, mRemoteConfiguration; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.assistant_menu); + + Log.e("###"); + + mAccountCreation = findViewById(R.id.account_creation); + mAccountCreation.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent; + if (getResources().getBoolean(R.bool.isTablet) + || !getResources().getBoolean(R.bool.use_phone_number_validation)) { + intent = + new Intent( + MenuAssistantActivity.this, + EmailAccountCreationAssistantActivity.class); + } else { + intent = + new Intent( + MenuAssistantActivity.this, + PhoneAccountCreationAssistantActivity.class); + } + startActivity(intent); + } + }); + + mAccountConnection = findViewById(R.id.account_connection); + mAccountConnection.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + startActivity( + new Intent( + MenuAssistantActivity.this, + AccountConnectionAssistantActivity.class)); + } + }); + if (getResources().getBoolean(R.bool.hide_linphone_accounts_in_assistant)) { + mAccountConnection.setVisibility(View.GONE); + } + + mGenericConnection = findViewById(R.id.generic_connection); + mGenericConnection.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + startActivity( + new Intent( + MenuAssistantActivity.this, + GenericConnectionAssistantActivity.class)); + } + }); + if (getResources().getBoolean(R.bool.hide_generic_accounts_in_assistant)) { + mGenericConnection.setVisibility(View.GONE); + } + + mRemoteConfiguration = findViewById(R.id.remote_configuration); + mRemoteConfiguration.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + startActivity( + new Intent( + MenuAssistantActivity.this, + RemoteConfigurationAssistantActivity.class)); + } + }); + if (getResources().getBoolean(R.bool.hide_remote_provisioning_in_assistant)) { + mRemoteConfiguration.setVisibility(View.GONE); + } + + if (getResources().getBoolean(R.bool.assistant_use_linphone_login_as_first_fragment)) { + startActivity( + new Intent( + MenuAssistantActivity.this, AccountConnectionAssistantActivity.class)); + finish(); + } else if (getResources() + .getBoolean(R.bool.assistant_use_generic_login_as_first_fragment)) { + startActivity( + new Intent( + MenuAssistantActivity.this, GenericConnectionAssistantActivity.class)); + finish(); + } else if (getResources() + .getBoolean(R.bool.assistant_use_create_linphone_account_as_first_fragment)) { + startActivity( + new Intent( + MenuAssistantActivity.this, + PhoneAccountCreationAssistantActivity.class)); + finish(); + } + } + + @Override + protected void onResume() { + super.onResume(); + if (!getResources() + .getBoolean(R.bool.forbid_to_leave_assistant_before_account_configuration)) { + mBack.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + LinphonePreferences.instance().firstLaunchSuccessful(); + goToLinphoneActivity(); + } + }); + } else { + mBack.setEnabled(false); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { + if (getResources() + .getBoolean(R.bool.forbid_to_leave_assistant_before_account_configuration)) { + // Do nothing + return true; + } else { + LinphonePreferences.instance().firstLaunchSuccessful(); + goToLinphoneActivity(); + return true; + } + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/org/linphone/assistant/OpenH264DownloadAssistantActivity.java b/app/src/main/java/org/linphone/assistant/OpenH264DownloadAssistantActivity.java new file mode 100644 index 000000000..316a1da30 --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/OpenH264DownloadAssistantActivity.java @@ -0,0 +1,125 @@ +package org.linphone.assistant; + +/* +OpenH264DownloadAssistantActivity.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.os.Bundle; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.TextView; +import androidx.annotation.Nullable; +import org.linphone.LinphoneManager; +import org.linphone.R; +import org.linphone.core.Core; +import org.linphone.core.PayloadType; +import org.linphone.core.tools.Log; +import org.linphone.core.tools.OpenH264DownloadHelper; +import org.linphone.core.tools.OpenH264DownloadHelperListener; +import org.linphone.settings.LinphonePreferences; + +public class OpenH264DownloadAssistantActivity extends AssistantActivity { + private TextView mYes, mNo; + private ProgressBar mProgress; + + private OpenH264DownloadHelper mHelper; + private OpenH264DownloadHelperListener mListener; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.assistant_openh264_codec_download); + mHelper = LinphoneManager.getInstance().getOpenH264DownloadHelper(); + LinphonePreferences.instance().setOpenH264CodecDownloadEnabled(false); + + mProgress = findViewById(R.id.progress_bar); + + mYes = findViewById(R.id.answer_yes); + mYes.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + mYes.setEnabled(false); + mNo.setEnabled(false); + Log.e("[OpenH264 Downloader] Start download"); + mProgress.setVisibility(View.VISIBLE); + mHelper.downloadCodec(); + } + }); + + mNo = findViewById(R.id.answer_no); + mNo.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + mYes.setEnabled(false); + mNo.setEnabled(false); + Log.e("[OpenH264 Downloader] Download refused"); + goToLinphoneActivity(); + } + }); + + mListener = + new OpenH264DownloadHelperListener() { + @Override + public void OnProgress(int current, int max) { + if (current < max) { + mProgress.setMax(max); + mProgress.setProgress(current); + } else { + Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (core != null) { + core.reloadMsPlugins(getApplicationInfo().nativeLibraryDir); + enableH264(); + } + + goToLinphoneActivity(); + } + } + + @Override + public void OnError(String s) { + Log.e("[OpenH264 Downloader] " + s); + mYes.setEnabled(true); + mNo.setEnabled(true); + } + }; + } + + @Override + protected void onResume() { + super.onResume(); + mHelper.setOpenH264HelperListener(mListener); + } + + @Override + protected void onPause() { + mHelper.setOpenH264HelperListener(null); + super.onPause(); + } + + private void enableH264() { + for (PayloadType pt : LinphoneManager.getLc().getVideoPayloadTypes()) { + if (pt.getMimeType().equals("H264")) { + pt.enable(true); + break; + } + } + } +} diff --git a/app/src/main/java/org/linphone/assistant/PhoneAccountCreationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/PhoneAccountCreationAssistantActivity.java new file mode 100644 index 000000000..d5f5a9886 --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/PhoneAccountCreationAssistantActivity.java @@ -0,0 +1,240 @@ +package org.linphone.assistant; + +/* +PhoneAccountCreationAssistantActivity.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; +import androidx.annotation.Nullable; +import org.linphone.R; +import org.linphone.core.AccountCreator; +import org.linphone.core.AccountCreatorListenerStub; +import org.linphone.core.DialPlan; +import org.linphone.core.tools.Log; + +public class PhoneAccountCreationAssistantActivity extends AssistantActivity { + private TextView mCountryPicker, mError, mSipUri, mCreate; + private EditText mPrefix, mPhoneNumber; + private ImageView mPhoneNumberInfos; + + private AccountCreatorListenerStub mListener; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.assistant_phone_account_creation); + + mCountryPicker = findViewById(R.id.select_country); + mCountryPicker.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + showCountryPickerDialog(); + } + }); + + mError = findViewById(R.id.phone_number_error); + + mSipUri = findViewById(R.id.sip_uri); + + mCreate = findViewById(R.id.assistant_create); + mCreate.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + enableButtonsAndFields(false); + + mAccountCreator.setUsername(mAccountCreator.getPhoneNumber()); + mAccountCreator.setDomain(getString(R.string.default_domain)); + + AccountCreator.Status status = mAccountCreator.isAccountExist(); + if (status != AccountCreator.Status.RequestOk) { + Log.e("[Phone Account Creation] isAccountExists returned " + status); + enableButtonsAndFields(true); + showGenericErrorDialog(status); + } + } + }); + mCreate.setEnabled(false); + + mPrefix = findViewById(R.id.dial_code); + mPrefix.setText("+"); + mPrefix.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + String prefix = s.toString(); + if (prefix.startsWith("+")) { + prefix = prefix.substring(1); + } + DialPlan dp = getDialPlanFromPrefix(prefix); + if (dp != null) { + mCountryPicker.setText(dp.getCountry()); + } + + updateCreateButtonAndDisplayError(); + } + }); + + mPhoneNumber = findViewById(R.id.phone_number); + mPhoneNumber.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + updateCreateButtonAndDisplayError(); + } + }); + + mPhoneNumberInfos = findViewById(R.id.info_phone_number); + mPhoneNumberInfos.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + showPhoneNumberDialog(); + } + }); + + mListener = + new AccountCreatorListenerStub() { + public void onIsAccountExist( + AccountCreator creator, AccountCreator.Status status, String resp) { + Log.i("[Phone Account Creation] onIsAccountExist status is " + status); + if (status.equals(AccountCreator.Status.AccountExist) + || status.equals(AccountCreator.Status.AccountExistWithAlias)) { + showAccountAlreadyExistsDialog(); + enableButtonsAndFields(true); + } else if (status.equals(AccountCreator.Status.AccountNotExist)) { + status = mAccountCreator.createAccount(); + if (status != AccountCreator.Status.RequestOk) { + Log.e("[Phone Account Creation] createAccount returned " + status); + enableButtonsAndFields(true); + showGenericErrorDialog(status); + } + } else { + enableButtonsAndFields(true); + showGenericErrorDialog(status); + } + } + + @Override + public void onCreateAccount( + AccountCreator creator, AccountCreator.Status status, String resp) { + Log.i("[Phone Account Creation] onCreateAccount status is " + status); + if (status.equals(AccountCreator.Status.AccountCreated)) { + startActivity( + new Intent( + PhoneAccountCreationAssistantActivity.this, + PhoneAccountValidationAssistantActivity.class)); + } else { + enableButtonsAndFields(true); + showGenericErrorDialog(status); + } + } + }; + } + + @Override + protected void onResume() { + super.onResume(); + + mAccountCreator.addListener(mListener); + + DialPlan dp = getDialPlanForCurrentCountry(); + displayDialPlan(dp); + + String phoneNumber = getDevicePhoneNumber(); + if (phoneNumber != null) { + mPhoneNumber.setText(phoneNumber); + } + } + + @Override + protected void onPause() { + super.onPause(); + mAccountCreator.removeListener(mListener); + } + + @Override + public void onCountryClicked(DialPlan dialPlan) { + super.onCountryClicked(dialPlan); + displayDialPlan(dialPlan); + } + + private void enableButtonsAndFields(boolean enable) { + mPrefix.setEnabled(enable); + mPhoneNumber.setEnabled(enable); + mCreate.setEnabled(enable); + } + + private void updateCreateButtonAndDisplayError() { + if (mPrefix.getText().toString().isEmpty() || mPhoneNumber.getText().toString().isEmpty()) + return; + + int status = arePhoneNumberAndPrefixOk(mPrefix, mPhoneNumber); + if (status == AccountCreator.PhoneNumberStatus.Ok.toInt()) { + mCreate.setEnabled(true); + mError.setText(""); + mError.setVisibility(View.INVISIBLE); + } else { + mCreate.setEnabled(false); + mError.setText(getErrorFromPhoneNumberStatus(status)); + mError.setVisibility(View.VISIBLE); + } + + String username = mAccountCreator.getPhoneNumber(); + if (username != null) { + String sip = + getString(R.string.assistant_create_account_phone_number_address) + + " "; + mSipUri.setText(sip); + } + } + + private void displayDialPlan(DialPlan dp) { + if (dp != null) { + mPrefix.setText("+" + dp.getCountryCallingCode()); + mCountryPicker.setText(dp.getCountry()); + } + } +} diff --git a/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java b/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java new file mode 100644 index 000000000..f812e923a --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/PhoneAccountLinkingAssistantActivity.java @@ -0,0 +1,275 @@ +package org.linphone.assistant; + +/* +PhoneAccountLinkingAssistantActivity.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.content.Intent; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; +import androidx.annotation.Nullable; +import org.linphone.LinphoneManager; +import org.linphone.R; +import org.linphone.core.AccountCreator; +import org.linphone.core.AccountCreatorListenerStub; +import org.linphone.core.Address; +import org.linphone.core.AuthInfo; +import org.linphone.core.Core; +import org.linphone.core.DialPlan; +import org.linphone.core.ProxyConfig; +import org.linphone.core.tools.Log; + +public class PhoneAccountLinkingAssistantActivity extends AssistantActivity { + private TextView mCountryPicker, mError, mLink; + private EditText mPrefix, mPhoneNumber; + private ImageView mPhoneNumberInfos; + + private AccountCreatorListenerStub mListener; + private ProxyConfig mProxyConfig; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.assistant_phone_account_linking); + + if (getIntent() != null && getIntent().hasExtra("AccountNumber")) { + int proxyConfigIndex = getIntent().getExtras().getInt("AccountNumber"); + Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (core == null) { + Log.e("[Account Linking] Core not available"); + unexpectedError(); + } + + ProxyConfig[] proxyConfigs = core.getProxyConfigList(); + if (proxyConfigIndex >= 0 && proxyConfigIndex < proxyConfigs.length) { + mProxyConfig = proxyConfigs[proxyConfigIndex]; + + Address identity = mProxyConfig.getIdentityAddress(); + if (identity == null) { + Log.e("[Account Linking] Proxy doesn't have an identity address"); + unexpectedError(); + } + mAccountCreator.setUsername(identity.getUsername()); + + AuthInfo authInfo = mProxyConfig.findAuthInfo(); + if (authInfo == null) { + Log.e("[Account Linking] Auth info not found"); + unexpectedError(); + } + mAccountCreator.setHa1(authInfo.getHa1()); + + mAccountCreator.setDomain(getString(R.string.default_domain)); + } else { + Log.e("[Account Linking] Proxy config index out of bounds: " + proxyConfigIndex); + unexpectedError(); + } + } else { + Log.e("[Account Linking] Proxy config index not found"); + unexpectedError(); + } + + mCountryPicker = findViewById(R.id.select_country); + mCountryPicker.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + showCountryPickerDialog(); + } + }); + + mError = findViewById(R.id.phone_number_error); + + mLink = findViewById(R.id.assistant_link); + mLink.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + enableButtonsAndFields(false); + + AccountCreator.Status status = mAccountCreator.isAliasUsed(); + if (status != AccountCreator.Status.RequestOk) { + Log.e("[Phone Account Linking] isAliasUsed returned " + status); + enableButtonsAndFields(true); + showGenericErrorDialog(status); + } + } + }); + mLink.setEnabled(false); + + mPrefix = findViewById(R.id.dial_code); + mPrefix.setText("+"); + mPrefix.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + String prefix = s.toString(); + if (prefix.startsWith("+")) { + prefix = prefix.substring(1); + } + DialPlan dp = getDialPlanFromPrefix(prefix); + if (dp != null) { + mCountryPicker.setText(dp.getCountry()); + } + + updateCreateButtonAndDisplayError(); + } + }); + + mPhoneNumber = findViewById(R.id.phone_number); + mPhoneNumber.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + updateCreateButtonAndDisplayError(); + } + }); + + mPhoneNumberInfos = findViewById(R.id.info_phone_number); + mPhoneNumberInfos.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + showPhoneNumberDialog(); + } + }); + + mListener = + new AccountCreatorListenerStub() { + @Override + public void onIsAliasUsed( + AccountCreator creator, AccountCreator.Status status, String resp) { + Log.i("[Phone Account Linking] onIsAliasUsed status is " + status); + if (status.equals(AccountCreator.Status.AliasNotExist)) { + status = mAccountCreator.linkAccount(); + if (status != AccountCreator.Status.RequestOk) { + Log.e("[Phone Account Linking] linkAccount returned " + status); + enableButtonsAndFields(true); + showGenericErrorDialog(status); + } + } else { + if (status.equals(AccountCreator.Status.AliasIsAccount) + || status.equals(AccountCreator.Status.AliasExist)) { + showAccountAlreadyExistsDialog(); + } else { + showGenericErrorDialog(status); + } + enableButtonsAndFields(true); + } + } + + @Override + public void onLinkAccount( + AccountCreator creator, AccountCreator.Status status, String resp) { + Log.i("[Phone Account Linking] onLinkAccount status is " + status); + if (status.equals(AccountCreator.Status.RequestOk)) { + Intent intent = + new Intent( + PhoneAccountLinkingAssistantActivity.this, + PhoneAccountValidationAssistantActivity.class); + intent.putExtra("isLinkingVerification", true); + startActivity(intent); + } else { + enableButtonsAndFields(true); + showGenericErrorDialog(status); + } + } + }; + } + + @Override + protected void onResume() { + super.onResume(); + + mAccountCreator.addListener(mListener); + + DialPlan dp = getDialPlanForCurrentCountry(); + displayDialPlan(dp); + + String phoneNumber = getDevicePhoneNumber(); + if (phoneNumber != null) { + mPhoneNumber.setText(phoneNumber); + } + } + + @Override + protected void onPause() { + super.onPause(); + mAccountCreator.removeListener(mListener); + } + + @Override + public void onCountryClicked(DialPlan dialPlan) { + super.onCountryClicked(dialPlan); + displayDialPlan(dialPlan); + } + + private void enableButtonsAndFields(boolean enable) { + mPrefix.setEnabled(enable); + mPhoneNumber.setEnabled(enable); + mLink.setEnabled(enable); + } + + private void updateCreateButtonAndDisplayError() { + if (mPrefix.getText().toString().isEmpty() || mPhoneNumber.getText().toString().isEmpty()) + return; + + int status = arePhoneNumberAndPrefixOk(mPrefix, mPhoneNumber); + if (status == AccountCreator.PhoneNumberStatus.Ok.toInt()) { + mLink.setEnabled(true); + mError.setText(""); + mError.setVisibility(View.INVISIBLE); + } else { + mLink.setEnabled(false); + mError.setText(getErrorFromPhoneNumberStatus(status)); + mError.setVisibility(View.VISIBLE); + } + } + + private void displayDialPlan(DialPlan dp) { + if (dp != null) { + mPrefix.setText("+" + dp.getCountryCallingCode()); + mCountryPicker.setText(dp.getCountry()); + } + } + + private void unexpectedError() { + Toast.makeText(this, R.string.error_unknown, Toast.LENGTH_SHORT).show(); + finish(); + } +} diff --git a/app/src/main/java/org/linphone/assistant/PhoneAccountValidationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/PhoneAccountValidationAssistantActivity.java new file mode 100644 index 000000000..1af31cc27 --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/PhoneAccountValidationAssistantActivity.java @@ -0,0 +1,180 @@ +package org.linphone.assistant; + +/* +PhoneAccountValidationAssistantActivity.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.widget.EditText; +import android.widget.TextView; +import androidx.annotation.Nullable; +import org.linphone.R; +import org.linphone.core.AccountCreator; +import org.linphone.core.AccountCreatorListenerStub; +import org.linphone.core.tools.Log; +import org.linphone.settings.LinphonePreferences; + +public class PhoneAccountValidationAssistantActivity extends AssistantActivity { + private TextView mPhoneNumber, mFinishCreation; + private EditText mSmsCode; + private ClipboardManager mClipboard; + + private int mActivationCodeLength; + private boolean mIsLogin, mIsLinking; + private AccountCreatorListenerStub mListener; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.assistant_phone_account_validation); + + mIsLogin = mIsLinking = false; + if (getIntent() != null && getIntent().getBooleanExtra("isLoginVerification", false)) { + findViewById(R.id.title_account_creation).setVisibility(View.VISIBLE); + mIsLogin = true; + } else if (getIntent() != null + && getIntent().getBooleanExtra("isLinkingVerification", false)) { + mIsLinking = true; + findViewById(R.id.title_account_linking).setVisibility(View.VISIBLE); + } else { + findViewById(R.id.title_account_activation).setVisibility(View.VISIBLE); + } + + mActivationCodeLength = + getResources().getInteger(R.integer.phone_number_validation_code_length); + + mPhoneNumber = findViewById(R.id.phone_number); + mPhoneNumber.setText(mAccountCreator.getPhoneNumber()); + + mSmsCode = findViewById(R.id.sms_code); + mSmsCode.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + mFinishCreation.setEnabled(s.length() == mActivationCodeLength); + } + }); + + mFinishCreation = findViewById(R.id.finish_account_creation); + mFinishCreation.setEnabled(false); + mFinishCreation.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + mFinishCreation.setEnabled(false); + mAccountCreator.setActivationCode(mSmsCode.getText().toString()); + + AccountCreator.Status status; + if (mIsLinking) { + status = mAccountCreator.activateAlias(); + } else { + status = mAccountCreator.activateAccount(); + } + if (status != AccountCreator.Status.RequestOk) { + Log.e( + "[Phone Account Validation] " + + (mIsLinking + ? "linkAccount" + : "activateAccount" + " returned ") + + status); + mFinishCreation.setEnabled(true); + showGenericErrorDialog(status); + } + } + }); + + mListener = + new AccountCreatorListenerStub() { + @Override + public void onActivateAccount( + AccountCreator creator, AccountCreator.Status status, String resp) { + Log.i("[Phone Account Validation] onActivateAccount status is " + status); + if (status.equals(AccountCreator.Status.AccountActivated)) { + createProxyConfigAndLeaveAssistant(); + } else { + mFinishCreation.setEnabled(true); + showGenericErrorDialog(status); + + if (status.equals(AccountCreator.Status.WrongActivationCode)) { + // TODO + } + } + } + + @Override + public void onActivateAlias( + AccountCreator creator, AccountCreator.Status status, String resp) { + Log.i("[Phone Account Validation] onActivateAlias status is " + status); + if (status.equals(AccountCreator.Status.AccountActivated)) { + LinphonePreferences.instance().setLinkPopupTime(""); + goToLinphoneActivity(); + } else { + mFinishCreation.setEnabled(true); + showGenericErrorDialog(status); + + if (status.equals(AccountCreator.Status.WrongActivationCode)) { + // TODO + } + } + } + }; + + mClipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); + mClipboard.addPrimaryClipChangedListener( + new ClipboardManager.OnPrimaryClipChangedListener() { + @Override + public void onPrimaryClipChanged() { + ClipData data = mClipboard.getPrimaryClip(); + if (data != null && data.getItemCount() > 0) { + String clip = data.getItemAt(0).getText().toString(); + if (clip.length() == mActivationCodeLength) { + mSmsCode.setText(clip); + } + } + } + }); + } + + @Override + protected void onResume() { + super.onResume(); + mAccountCreator.addListener(mListener); + + // Prevent user to go back, it won't be able to come back here after... + mBack.setEnabled(false); + } + + @Override + protected void onPause() { + super.onPause(); + mAccountCreator.removeListener(mListener); + } +} diff --git a/app/src/main/java/org/linphone/assistant/QrCodeFragment.java b/app/src/main/java/org/linphone/assistant/QrCodeConfigurationAssistantActivity.java similarity index 77% rename from app/src/main/java/org/linphone/assistant/QrCodeFragment.java rename to app/src/main/java/org/linphone/assistant/QrCodeConfigurationAssistantActivity.java index 95a06104a..6bbee59d2 100644 --- a/app/src/main/java/org/linphone/assistant/QrCodeFragment.java +++ b/app/src/main/java/org/linphone/assistant/QrCodeConfigurationAssistantActivity.java @@ -1,8 +1,8 @@ package org.linphone.assistant; /* -QrCodeFragment.java -Copyright (C) 2018 Belledonne Communications, Grenoble, France +QrCodeConfigurationAssistantActivity.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -19,46 +19,46 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import android.app.Fragment; +import android.app.Activity; +import android.content.Intent; import android.os.Bundle; -import android.view.LayoutInflater; import android.view.TextureView; -import android.view.View; -import android.view.ViewGroup; +import androidx.annotation.Nullable; import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.core.Core; import org.linphone.core.CoreListenerStub; import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration; -public class QrCodeFragment extends Fragment { +public class QrCodeConfigurationAssistantActivity extends AssistantActivity { private TextureView mQrcodeView; + private CoreListenerStub mListener; @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.qrcode, container, false); + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); - mQrcodeView = view.findViewById(R.id.qrcodeCaptureSurface); + setContentView(R.layout.assistant_qr_code_remote_configuration); - LinphoneManager.getLc().setNativePreviewWindowId(mQrcodeView); + mQrcodeView = findViewById(R.id.qr_code_capture_texture); mListener = new CoreListenerStub() { @Override public void onQrcodeFound(Core lc, String result) { - enableQrcodeReader(false); - AssistantActivity.instance().displayRemoteProvisioning(result); + Intent resultIntent = new Intent(); + resultIntent.putExtra("URL", result); + setResult(Activity.RESULT_OK, resultIntent); + finish(); } }; - - return view; } private void enableQrcodeReader(boolean enable) { LinphoneManager.getLc().enableQrcodeVideoPreview(enable); LinphoneManager.getLc().enableVideoPreview(enable); + if (enable) { LinphoneManager.getLc().addListener(mListener); } else { @@ -79,6 +79,7 @@ public class QrCodeFragment extends Fragment { } private void launchQrcodeReader() { + LinphoneManager.getLc().setNativePreviewWindowId(mQrcodeView); setBackCamera(); enableQrcodeReader(true); @@ -86,14 +87,13 @@ public class QrCodeFragment extends Fragment { @Override public void onResume() { - launchQrcodeReader(); super.onResume(); + launchQrcodeReader(); } @Override public void onPause() { enableQrcodeReader(false); - // setBackCamera(false); super.onPause(); } } diff --git a/app/src/main/java/org/linphone/assistant/RemoteConfigurationAssistantActivity.java b/app/src/main/java/org/linphone/assistant/RemoteConfigurationAssistantActivity.java new file mode 100644 index 000000000..a5b3999bb --- /dev/null +++ b/app/src/main/java/org/linphone/assistant/RemoteConfigurationAssistantActivity.java @@ -0,0 +1,203 @@ +package org.linphone.assistant; + +/* +RemoteConfigurationAssistantActivity.java +Copyright (C) 2019 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +import android.Manifest; +import android.app.Activity; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Patterns; +import android.view.View; +import android.widget.EditText; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; +import androidx.annotation.Nullable; +import androidx.core.app.ActivityCompat; +import org.linphone.LinphoneManager; +import org.linphone.R; +import org.linphone.core.ConfiguringState; +import org.linphone.core.Core; +import org.linphone.core.CoreListenerStub; +import org.linphone.core.tools.Log; +import org.linphone.settings.LinphonePreferences; + +public class RemoteConfigurationAssistantActivity extends AssistantActivity { + private static final int QR_CODE_ACTIVITY_RESULT = 1; + private static final int CAMERA_PERMISSION_RESULT = 2; + + private TextView mFetchAndApply, mQrCode; + private EditText mRemoteConfigurationUrl; + private RelativeLayout mWaitLayout; + + private CoreListenerStub mListener; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.assistant_remote_configuration); + + mWaitLayout = findViewById(R.id.waitScreen); + mWaitLayout.setVisibility(View.GONE); + + mFetchAndApply = findViewById(R.id.fetch_and_apply_remote_configuration); + mFetchAndApply.setEnabled(false); + mFetchAndApply.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + String url = mRemoteConfigurationUrl.getText().toString(); + if (Patterns.WEB_URL.matcher(url).matches()) { + mWaitLayout.setVisibility(View.VISIBLE); + mFetchAndApply.setEnabled(false); + LinphonePreferences.instance().setRemoteProvisioningUrl(url); + LinphoneManager.getLc().getConfig().sync(); + Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (core != null) { + core.addListener(mListener); + } + LinphoneManager.getInstance().restartCore(); + } else { + // TODO improve error text + Toast.makeText( + RemoteConfigurationAssistantActivity.this, + getString(R.string.remote_provisioning_failure), + Toast.LENGTH_LONG) + .show(); + } + } + }); + + mRemoteConfigurationUrl = findViewById(R.id.remote_configuration_url); + mRemoteConfigurationUrl.addTextChangedListener( + new TextWatcher() { + @Override + public void beforeTextChanged( + CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + mFetchAndApply.setEnabled(!s.toString().isEmpty()); + } + + @Override + public void afterTextChanged(Editable s) {} + }); + mRemoteConfigurationUrl.setText(LinphonePreferences.instance().getRemoteProvisioningUrl()); + + mQrCode = findViewById(R.id.qr_code); + mQrCode.setOnClickListener( + new View.OnClickListener() { + @Override + public void onClick(View v) { + if (checkCameraPermissionForQrCode()) { + startActivityForResult( + new Intent( + RemoteConfigurationAssistantActivity.this, + QrCodeConfigurationAssistantActivity.class), + QR_CODE_ACTIVITY_RESULT); + } + } + }); + + mListener = + new CoreListenerStub() { + @Override + public void onConfiguringStatus( + Core core, ConfiguringState status, String message) { + core.removeListener(mListener); + mWaitLayout.setVisibility(View.GONE); + mFetchAndApply.setEnabled(true); + + if (status == ConfiguringState.Successful) { + LinphonePreferences.instance().firstLaunchSuccessful(); + goToLinphoneActivity(); + } else if (status == ConfiguringState.Failed) { + Toast.makeText( + RemoteConfigurationAssistantActivity.this, + getString(R.string.remote_provisioning_failure), + Toast.LENGTH_LONG) + .show(); + } + } + }; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + if (requestCode == QR_CODE_ACTIVITY_RESULT + && resultCode == Activity.RESULT_OK + && data != null) { + String url = data.getStringExtra("URL"); + mRemoteConfigurationUrl.setText(url); + } + super.onActivityResult(requestCode, resultCode, data); + } + + private boolean checkCameraPermissionForQrCode() { + int permissionGranted = + getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName()); + Log.i( + "[Permission] Manifest.permission.CAMERA is " + + (permissionGranted == PackageManager.PERMISSION_GRANTED + ? "granted" + : "denied")); + + if (permissionGranted != PackageManager.PERMISSION_GRANTED) { + Log.i("[Permission] Asking for " + Manifest.permission.CAMERA); + ActivityCompat.requestPermissions( + this, new String[] {Manifest.permission.CAMERA}, CAMERA_PERMISSION_RESULT); + return false; + } + return true; + } + + @Override + public void onRequestPermissionsResult( + int requestCode, String[] permissions, final int[] grantResults) { + for (int i = 0; i < permissions.length; i++) { + Log.i( + "[Permission] " + + permissions[i] + + " has been " + + (grantResults[i] == PackageManager.PERMISSION_GRANTED + ? "granted" + : "denied")); + } + + switch (requestCode) { + case CAMERA_PERMISSION_RESULT: + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + startActivityForResult( + new Intent( + RemoteConfigurationAssistantActivity.this, + QrCodeConfigurationAssistantActivity.class), + QR_CODE_ACTIVITY_RESULT); + } else { + // TODO: permission denied, display something to the user + } + break; + } + } +} diff --git a/app/src/main/java/org/linphone/assistant/RemoteProvisioningActivity.java b/app/src/main/java/org/linphone/assistant/RemoteProvisioningActivity.java deleted file mode 100644 index 1660f1757..000000000 --- a/app/src/main/java/org/linphone/assistant/RemoteProvisioningActivity.java +++ /dev/null @@ -1,217 +0,0 @@ -package org.linphone.assistant; -/* -RemoteProvisioningActivity.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.view.View; -import android.widget.ProgressBar; -import android.widget.Toast; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import org.linphone.LinphoneLauncherActivity; -import org.linphone.LinphoneManager; -import org.linphone.LinphoneService; -import org.linphone.R; -import org.linphone.core.ConfiguringState; -import org.linphone.core.Core; -import org.linphone.core.CoreListenerStub; -import org.linphone.core.tools.Log; -import org.linphone.settings.LinphonePreferences; -import org.linphone.utils.ThemableActivity; - -public class RemoteProvisioningActivity extends ThemableActivity { - private final Handler mHandler = new Handler(); - private String mConfigUriParam = null; - private ProgressBar mSpinner; - private CoreListenerStub mListener; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.remote_provisioning); - mSpinner = findViewById(R.id.spinner); - - mListener = - new CoreListenerStub() { - @Override - public void onConfiguringStatus( - Core lc, final ConfiguringState state, String message) { - if (mSpinner != null) mSpinner.setVisibility(View.GONE); - if (state == ConfiguringState.Successful) { - goToLinphoneActivity(); - } else if (state == ConfiguringState.Failed) { - Toast.makeText( - RemoteProvisioningActivity.this, - R.string.remote_provisioning_failure, - Toast.LENGTH_LONG) - .show(); - } - } - }; - } - - @Override - protected void onResume() { - super.onResume(); - Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (lc != null) { - lc.addListener(mListener); - } - LinphonePreferences.instance().setContext(this); - - checkIntentForConfigUri(getIntent()); - } - - @Override - protected void onPause() { - Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (lc != null) { - lc.removeListener(mListener); - } - super.onPause(); - } - - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - checkIntentForConfigUri(intent); - } - - private void checkIntentForConfigUri(final Intent intent) { - new Thread( - new Runnable() { - - @Override - public void run() { - Uri openUri = intent.getData(); - if (openUri != null) { - // We expect something like - // linphone-config://http://linphone.org/config.xml - mConfigUriParam = - openUri.getEncodedSchemeSpecificPart() - .substring(2); // Removes the linphone-config:// - try { - mConfigUriParam = - URLDecoder.decode(mConfigUriParam, "UTF-8"); - } catch (UnsupportedEncodingException e) { - Log.e(e); - } - Log.d("Using config uri: " + mConfigUriParam); - } - - if (mConfigUriParam == null) { - if (!LinphonePreferences.instance() - .isFirstRemoteProvisioning()) { - mHandler.post( - new Runnable() { - @Override - public void run() { - goToLinphoneActivity(); - } - }); - } else if (!getResources() - .getBoolean( - R.bool.forbid_app_usage_until_remote_provisioning_completed)) { - // Show this view for a few seconds then go to the dialer - mHandler.postDelayed( - new Runnable() { - @Override - public void run() { - goToLinphoneActivity(); - } - }, - 1500); - } // else we do nothing if there is no config uri parameter and - // if user not allowed to leave this screen - } else { - if (getResources() - .getBoolean( - R.bool.display_confirmation_popup_after_first_configuration) - && !LinphonePreferences.instance() - .isFirstRemoteProvisioning()) { - mHandler.post( - new Runnable() { - @Override - public void run() { - displayDialogConfirmation(); - } - }); - } else { - mHandler.post( - new Runnable() { - @Override - public void run() { - setRemoteProvisioningAddressAndRestart( - mConfigUriParam); - } - }); - } - } - } - }) - .start(); - } - - private void displayDialogConfirmation() { - new AlertDialog.Builder(RemoteProvisioningActivity.this) - .setTitle(getString(R.string.remote_provisioning_again_title)) - .setMessage(getString(R.string.remote_provisioning_again_message)) - .setPositiveButton( - R.string.accept, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - setRemoteProvisioningAddressAndRestart(mConfigUriParam); - } - }) - .setNegativeButton( - R.string.cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - goToLinphoneActivity(); - } - }) - .show(); - } - - private void setRemoteProvisioningAddressAndRestart(final String configUri) { - if (mSpinner != null) mSpinner.setVisibility(View.VISIBLE); - - LinphonePreferences.instance().setContext(this); // Needed, else the next call will crash - LinphonePreferences.instance().setRemoteProvisioningUrl(configUri); - - LinphoneManager.getLc().getConfig().sync(); - LinphoneManager.getInstance().restartCore(); - } - - private void goToLinphoneActivity() { - if (LinphoneService.isReady()) { - LinphoneService.instance() - .setActivityToLaunchOnIncomingReceived("org.linphone.LinphoneLauncherActivity"); - // finish(); // To prevent the user to come back to this page using back button - startActivity(new Intent().setClass(this, LinphoneLauncherActivity.class)); - } else { - finish(); - } - } -} diff --git a/app/src/main/java/org/linphone/assistant/RemoteProvisioningFragment.java b/app/src/main/java/org/linphone/assistant/RemoteProvisioningFragment.java deleted file mode 100644 index e710ac213..000000000 --- a/app/src/main/java/org/linphone/assistant/RemoteProvisioningFragment.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.linphone.assistant; -/* -RemoteProvisioningFragment.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import android.app.Fragment; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; -import org.linphone.LinphoneManager; -import org.linphone.R; -import org.linphone.settings.LinphonePreferences; - -public class RemoteProvisioningFragment extends Fragment implements OnClickListener, TextWatcher { - private EditText mRemoteProvisioningUrl; - private Button mApply, mQrcode; - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.assistant_remote_provisioning, container, false); - - mRemoteProvisioningUrl = view.findViewById(R.id.assistant_remote_provisioning_url); - mRemoteProvisioningUrl.addTextChangedListener(this); - mQrcode = view.findViewById(R.id.assistant_qrcode); - mQrcode.setOnClickListener(this); - mApply = view.findViewById(R.id.assistant_apply); - mApply.setEnabled(false); - mApply.setOnClickListener(this); - - if (getArguments() != null && !getArguments().getString("RemoteUrl").isEmpty()) { - mRemoteProvisioningUrl.setText(getArguments().getString("RemoteUrl")); - } - - return view; - } - - @Override - public void onClick(View v) { - int id = v.getId(); - - if (id == R.id.assistant_apply) { - String url = mRemoteProvisioningUrl.getText().toString(); - AssistantActivity.instance().displayRemoteProvisioningInProgressDialog(); - LinphonePreferences.instance().setRemoteProvisioningUrl(url); - LinphoneManager.getLc().getConfig().sync(); - LinphoneManager.getInstance().restartCore(); - AssistantActivity.instance().setCoreListener(); - } else if (id == R.id.assistant_qrcode) { - AssistantActivity.instance().displayQRCodeReader(); - } - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - mApply.setEnabled(!mRemoteProvisioningUrl.getText().toString().isEmpty()); - } - - @Override - public void afterTextChanged(Editable s) {} -} diff --git a/app/src/main/java/org/linphone/assistant/RemoteProvisioningLoginActivity.java b/app/src/main/java/org/linphone/assistant/RemoteProvisioningLoginActivity.java deleted file mode 100644 index 0869985a3..000000000 --- a/app/src/main/java/org/linphone/assistant/RemoteProvisioningLoginActivity.java +++ /dev/null @@ -1,143 +0,0 @@ -package org.linphone.assistant; -/* -RemoteProvisioningLoginActivity.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import android.app.Activity; -import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Toast; -import org.linphone.LinphoneManager; -import org.linphone.R; -import org.linphone.core.ConfiguringState; -import org.linphone.core.Core; -import org.linphone.core.CoreListenerStub; -import org.linphone.settings.LinphonePreferences; -import org.linphone.utils.ThemableActivity; -import org.linphone.xmlrpc.XmlRpcHelper; -import org.linphone.xmlrpc.XmlRpcListenerBase; - -public class RemoteProvisioningLoginActivity extends ThemableActivity implements OnClickListener { - private EditText mLogin, mPassword, mDomain; - private Button mConnect; - private CoreListenerStub mListener; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.assistant_remote_provisioning_login); - - mLogin = findViewById(R.id.assistant_username); - mPassword = findViewById(R.id.assistant_password); - mDomain = findViewById(R.id.assistant_domain); - - mConnect = findViewById(R.id.assistant_connect); - mConnect.setOnClickListener(this); - - String defaultDomain = getIntent().getStringExtra("Domain"); - if (defaultDomain != null) { - mDomain.setText(defaultDomain); - mDomain.setEnabled(false); - } - - mListener = - new CoreListenerStub() { - @Override - public void onConfiguringStatus( - Core lc, final ConfiguringState state, String message) { - if (state == ConfiguringState.Successful) { - // TODO - } else if (state == ConfiguringState.Failed) { - Toast.makeText( - RemoteProvisioningLoginActivity.this, - R.string.remote_provisioning_failure, - Toast.LENGTH_LONG) - .show(); - } - } - }; - } - - private void cancelWizard() { - if (getResources().getBoolean(R.bool.allow_cancel_remote_provisioning_login_activity)) { - LinphonePreferences.instance().disableProvisioningLoginView(); - setResult(Activity.RESULT_CANCELED); - finish(); - } - } - - private void storeAccount(String username, String password, String domain) { - XmlRpcHelper xmlRpcHelper = new XmlRpcHelper(); - xmlRpcHelper.getRemoteProvisioningFilenameAsync( - new XmlRpcListenerBase() { - @Override - public void onRemoteProvisioningFilenameSent(String result) { - LinphonePreferences.instance().setRemoteProvisioningUrl(result); - LinphoneManager.getInstance().restartCore(); - } - }, - username, - password, - domain); - - LinphonePreferences.instance().firstLaunchSuccessful(); - setResult(Activity.RESULT_OK); - finish(); - } - - @Override - protected void onResume() { - super.onResume(); - Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (lc != null) { - lc.addListener(mListener); - } - } - - @Override - protected void onPause() { - Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (lc != null) { - lc.removeListener(mListener); - } - super.onPause(); - } - - @Override - public void onClick(View v) { - int id = v.getId(); - - if (id == R.id.cancel) { - cancelWizard(); - } - if (id == R.id.assistant_connect) { - storeAccount( - mLogin.getText().toString(), - mPassword.getText().toString(), - mDomain.getText().toString()); - } - } - - @Override - public void onBackPressed() { - cancelWizard(); - } -} diff --git a/app/src/main/java/org/linphone/assistant/WelcomeFragment.java b/app/src/main/java/org/linphone/assistant/WelcomeFragment.java deleted file mode 100644 index 089b8f328..000000000 --- a/app/src/main/java/org/linphone/assistant/WelcomeFragment.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.linphone.assistant; -/* -WelcomeFragment.java -Copyright (C) 2017 Belledonne Communications, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -import android.app.Fragment; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.TextView; -import org.linphone.R; - -public class WelcomeFragment extends Fragment implements OnClickListener { - private TextView mCreateAccount, mLogLinphoneAccount, mLogGenericAccount, mRemoteProvisioning; - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.assistant_welcome, container, false); - - mCreateAccount = view.findViewById(R.id.create_account); - mCreateAccount.setOnClickListener(this); - - mLogLinphoneAccount = view.findViewById(R.id.login_linphone); - if (getResources().getBoolean(R.bool.hide_linphone_accounts_in_assistant)) { - mLogLinphoneAccount.setVisibility(View.GONE); - } else { - mLogLinphoneAccount.setOnClickListener(this); - } - - mLogGenericAccount = view.findViewById(R.id.login_generic); - if (getResources().getBoolean(R.bool.hide_generic_accounts_in_assistant)) { - mLogGenericAccount.setVisibility(View.GONE); - } else { - mLogGenericAccount.setOnClickListener(this); - } - - mRemoteProvisioning = view.findViewById(R.id.remote_provisioning); - if (getResources().getBoolean(R.bool.hide_remote_provisioning_in_assistant)) { - mRemoteProvisioning.setVisibility(View.GONE); - } else { - mRemoteProvisioning.setOnClickListener(this); - } - - return view; - } - - @Override - public void onClick(View v) { - int id = v.getId(); - if (id == R.id.login_generic) { - AssistantActivity.instance().displayLoginGeneric(); - } else if (id == R.id.login_linphone) { - AssistantActivity.instance().displayLoginLinphone(null, null); - } else if (id == R.id.create_account) { - AssistantActivity.instance().displayCreateAccount(); - } else if (id == R.id.remote_provisioning) { - AssistantActivity.instance().displayRemoteProvisioning(""); - } - } -} diff --git a/app/src/main/java/org/linphone/call/CallActivity.java b/app/src/main/java/org/linphone/call/CallActivity.java index da23aeaff..0e8d1772c 100644 --- a/app/src/main/java/org/linphone/call/CallActivity.java +++ b/app/src/main/java/org/linphone/call/CallActivity.java @@ -27,7 +27,6 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -171,10 +170,6 @@ public class CallActivity extends LinphoneGenericActivity super.onCreate(savedInstanceState); sInstance = this; - if (getResources().getBoolean(R.bool.orientation_portrait_only)) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - } - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); Compatibility.setShowWhenLocked(this, true); diff --git a/app/src/main/java/org/linphone/call/CallIncomingActivity.java b/app/src/main/java/org/linphone/call/CallIncomingActivity.java index 62f6adb83..068aa110e 100644 --- a/app/src/main/java/org/linphone/call/CallIncomingActivity.java +++ b/app/src/main/java/org/linphone/call/CallIncomingActivity.java @@ -23,7 +23,6 @@ import android.Manifest; import android.app.KeyguardManager; import android.content.Context; import android.content.Intent; -import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.os.Bundle; import android.view.KeyEvent; @@ -79,10 +78,6 @@ public class CallIncomingActivity extends LinphoneGenericActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (getResources().getBoolean(R.bool.orientation_portrait_only)) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - } - Compatibility.setShowWhenLocked(this, true); Compatibility.setTurnScreenOn(this, true); diff --git a/app/src/main/java/org/linphone/call/CallOutgoingActivity.java b/app/src/main/java/org/linphone/call/CallOutgoingActivity.java index 9fc3e45e9..55fa13bcc 100644 --- a/app/src/main/java/org/linphone/call/CallOutgoingActivity.java +++ b/app/src/main/java/org/linphone/call/CallOutgoingActivity.java @@ -20,7 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import android.Manifest; -import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.os.Bundle; import android.view.Gravity; @@ -63,10 +62,6 @@ public class CallOutgoingActivity extends LinphoneGenericActivity implements OnC protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (getResources().getBoolean(R.bool.orientation_portrait_only)) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - } - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.call_outgoing); diff --git a/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java b/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java index 7e1be930d..1f75c9927 100644 --- a/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java +++ b/app/src/main/java/org/linphone/chat/ChatRoomCreationFragment.java @@ -516,9 +516,6 @@ public class ChatRoomCreationFragment extends Fragment mShareInfos, mSecurityToggle.isChecked()); } - } else if (id == R.id.clearSearchField) { - mSearchField.setQuery("", false); - mSearchAdapter.searchContacts(""); } else if (id == R.id.contactChatDelete) { ContactAddress ca = (ContactAddress) view.getTag(); addOrRemoveContactFromSelection(ca); diff --git a/app/src/main/java/org/linphone/fragments/StatusFragment.java b/app/src/main/java/org/linphone/fragments/StatusFragment.java index e80ddc749..0a3b2f67b 100644 --- a/app/src/main/java/org/linphone/fragments/StatusFragment.java +++ b/app/src/main/java/org/linphone/fragments/StatusFragment.java @@ -40,7 +40,6 @@ import org.linphone.LinphoneActivity; import org.linphone.LinphoneManager; import org.linphone.LinphoneService; import org.linphone.R; -import org.linphone.assistant.AssistantActivity; import org.linphone.call.CallActivity; import org.linphone.call.CallIncomingActivity; import org.linphone.call.CallOutgoingActivity; @@ -165,8 +164,6 @@ public class StatusFragment extends Fragment { ((LinphoneActivity) activity).updateStatusFragment(this); } else if (activity instanceof CallActivity) { ((CallActivity) activity).updateStatusFragment(this); - } else if (activity instanceof AssistantActivity) { - ((AssistantActivity) activity).updateStatusFragment(this); } mIsInCall = activity instanceof CallActivity @@ -176,18 +173,6 @@ public class StatusFragment extends Fragment { return view; } - public void setCoreListener() { - Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (lc != null) { - lc.addListener(mListener); - - ProxyConfig lpc = lc.getDefaultProxyConfig(); - if (lpc != null) { - mListener.onRegistrationStateChanged(lc, lpc, lpc.getState(), null); - } - } - } - @Override public void onDetach() { super.onDetach(); diff --git a/app/src/main/java/org/linphone/settings/AccountSettingsFragment.java b/app/src/main/java/org/linphone/settings/AccountSettingsFragment.java index f89373c81..5625c5fb5 100644 --- a/app/src/main/java/org/linphone/settings/AccountSettingsFragment.java +++ b/app/src/main/java/org/linphone/settings/AccountSettingsFragment.java @@ -32,7 +32,7 @@ import java.util.List; import org.linphone.LinphoneActivity; import org.linphone.LinphoneManager; import org.linphone.R; -import org.linphone.assistant.AssistantActivity; +import org.linphone.assistant.PhoneAccountLinkingAssistantActivity; import org.linphone.core.AVPFMode; import org.linphone.core.Address; import org.linphone.core.AuthInfo; @@ -546,9 +546,9 @@ public class AccountSettingsFragment extends Fragment { @Override public void onClicked() { Intent assistant = new Intent(); - assistant.setClass(LinphoneActivity.instance(), AssistantActivity.class); - assistant.putExtra("LinkPhoneNumber", true); - assistant.putExtra("FromPref", true); + assistant.setClass( + LinphoneActivity.instance(), + PhoneAccountLinkingAssistantActivity.class); assistant.putExtra("AccountNumber", mAccountIndex); startActivity(assistant); } diff --git a/app/src/main/java/org/linphone/settings/LinphonePreferences.java b/app/src/main/java/org/linphone/settings/LinphonePreferences.java index 402a134ed..787f43e1f 100644 --- a/app/src/main/java/org/linphone/settings/LinphonePreferences.java +++ b/app/src/main/java/org/linphone/settings/LinphonePreferences.java @@ -164,13 +164,6 @@ public class LinphonePreferences { return (proxyConf != null) ? proxyConf.getDomain() : ""; } - public void setPrefix(int n, String prefix) { - ProxyConfig prxCfg = getProxyConfig(n); - prxCfg.edit(); - prxCfg.setDialPrefix(prefix); - prxCfg.done(); - } - public boolean isFriendlistsubscriptionEnabled() { if (getConfig().getBool("app", "friendlist_subscription_enabled", false)) { // Old setting, do migration @@ -235,21 +228,6 @@ public class LinphonePreferences { public boolean isAccountEnabled(int n) { return getProxyConfig(n).registerEnabled(); } - - public void resetDefaultProxyConfig() { - if (getLc() == null) return; - int count = getLc().getProxyConfigList().length; - for (int i = 0; i < count; i++) { - if (isAccountEnabled(i)) { - getLc().setDefaultProxyConfig(getProxyConfig(i)); - break; - } - } - - if (getLc().getDefaultProxyConfig() == null) { - getLc().setDefaultProxyConfig(getProxyConfig(0)); - } - } // End of accounts settings // Audio settings @@ -820,20 +798,8 @@ public class LinphonePreferences { LinphoneManager.getInstance().initTunnelFromConf(); } - public boolean isProvisioningLoginViewEnabled() { - - return (getConfig() != null) && getConfig().getBool("app", "show_login_view", false); - } // End of tunnel settings - public void disableProvisioningLoginView() { - if (isProvisioningLoginViewEnabled()) { // Only do it if it was previously enabled - getConfig().setBool("app", "show_login_view", false); - } else { - Log.w("Remote provisioning login view wasn't enabled, ignoring"); - } - } - public boolean isFirstRemoteProvisioning() { return getConfig().getBool("app", "first_remote_provisioning", true); } @@ -1021,10 +987,6 @@ public class LinphonePreferences { getConfig().setInt("app", "auto_answer_delay", time); } - public int getCodeLength() { - return getConfig().getInt("app", "activation_code_length", 0); - } - public void disableFriendsStorage() { getConfig().setBool("misc", "store_friends", false); } @@ -1076,4 +1038,20 @@ public class LinphonePreferences { public void setDeviceName(String name) { getConfig().setString("app", "device_name", name); } + + public boolean isEchoCancellationCalibrationDone() { + return getConfig().getBool("app", "echo_cancellation_calibration_done", false); + } + + public void setEchoCancellationCalibrationDone(boolean done) { + getConfig().setBool("app", "echo_cancellation_calibration_done", done); + } + + public boolean isOpenH264CodecDownloadEnabled() { + return getConfig().getBool("app", "open_h264_download_enabled", true); + } + + public void setOpenH264CodecDownloadEnabled(boolean enable) { + getConfig().setBool("app", "open_h264_download_enabled", enable); + } } diff --git a/app/src/main/java/org/linphone/settings/SettingsFragment.java b/app/src/main/java/org/linphone/settings/SettingsFragment.java index f383c818c..5080c133f 100644 --- a/app/src/main/java/org/linphone/settings/SettingsFragment.java +++ b/app/src/main/java/org/linphone/settings/SettingsFragment.java @@ -153,6 +153,11 @@ public class SettingsFragment extends Fragment { mTunnel.setVisibility(core.tunnelAvailable() ? View.VISIBLE : View.GONE); initAccounts(core); } + + if (getResources().getBoolean(R.bool.hide_accounts)) { + mAccounts.setVisibility(View.GONE); + mAccountsHeader.setVisibility(View.GONE); + } } private void initAccounts(Core core) { diff --git a/app/src/main/java/org/linphone/utils/LinphoneUtils.java b/app/src/main/java/org/linphone/utils/LinphoneUtils.java index 70d4fe5cd..defa58a2a 100644 --- a/app/src/main/java/org/linphone/utils/LinphoneUtils.java +++ b/app/src/main/java/org/linphone/utils/LinphoneUtils.java @@ -33,8 +33,6 @@ import android.text.Spanned; import android.view.KeyEvent; import android.view.View; import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.TextView; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; @@ -45,7 +43,6 @@ import java.util.regex.Pattern; import org.linphone.LinphoneManager; import org.linphone.LinphoneService; import org.linphone.R; -import org.linphone.core.AccountCreator; import org.linphone.core.Address; import org.linphone.core.Call; import org.linphone.core.Call.State; @@ -316,112 +313,6 @@ public final class LinphoneUtils { return sipAddress; } - public static void displayError(boolean isOk, TextView error, String errorText) { - if (isOk) { - error.setVisibility(View.INVISIBLE); - error.setText(""); - } else { - error.setVisibility(View.VISIBLE); - error.setText(errorText); - } - } - - public static String errorForPhoneNumberStatus(int status) { - Context ctxt = getContext(); - if (ctxt != null) { - if (AccountCreator.PhoneNumberStatus.InvalidCountryCode.toInt() - == (status & AccountCreator.PhoneNumberStatus.InvalidCountryCode.toInt())) - return ctxt.getString(R.string.country_code_invalid); - if (AccountCreator.PhoneNumberStatus.TooShort.toInt() - == (status & AccountCreator.PhoneNumberStatus.TooShort.toInt())) - return ctxt.getString(R.string.phone_number_too_short); - if (AccountCreator.PhoneNumberStatus.TooLong.toInt() - == (status & AccountCreator.PhoneNumberStatus.TooLong.toInt())) - return ctxt.getString(R.string.phone_number_too_long); - if (AccountCreator.PhoneNumberStatus.Invalid.toInt() - == (status & AccountCreator.PhoneNumberStatus.Invalid.toInt())) - return ctxt.getString(R.string.phone_number_invalid); - } - return null; - } - - public static String errorForEmailStatus(AccountCreator.EmailStatus status) { - Context ctxt = getContext(); - if (ctxt != null) { - if (status.equals(AccountCreator.EmailStatus.InvalidCharacters) - || status.equals(AccountCreator.EmailStatus.Malformed)) - return ctxt.getString(R.string.invalid_email); - } - return null; - } - - public static String errorForUsernameStatus(AccountCreator.UsernameStatus status) { - Context ctxt = getContext(); - if (ctxt != null) { - if (status.equals(AccountCreator.UsernameStatus.InvalidCharacters)) - return ctxt.getString(R.string.invalid_username); - if (status.equals(AccountCreator.UsernameStatus.TooShort)) - return ctxt.getString(R.string.username_too_short); - if (status.equals(AccountCreator.UsernameStatus.TooLong)) - return ctxt.getString(R.string.username_too_long); - if (status.equals(AccountCreator.UsernameStatus.Invalid)) - return ctxt.getString(R.string.username_invalid_size); - if (status.equals(AccountCreator.UsernameStatus.InvalidCharacters)) - return ctxt.getString(R.string.invalid_display_name); - } - return null; - } - - public static String errorForPasswordStatus(AccountCreator.PasswordStatus status) { - Context ctxt = getContext(); - if (ctxt != null) { - if (status.equals(AccountCreator.PasswordStatus.TooShort)) - return ctxt.getString(R.string.password_too_short); - if (status.equals(AccountCreator.PasswordStatus.TooLong)) - return ctxt.getString(R.string.password_too_long); - } - return null; - } - - public static String errorForStatus(AccountCreator.Status status) { - Context ctxt = getContext(); - Log.e("Status error " + status.name()); - if (ctxt != null) { - if (status.equals(AccountCreator.Status.RequestFailed)) - return ctxt.getString(R.string.request_failed); - if (status.equals(AccountCreator.Status.ServerError)) - return ctxt.getString(R.string.wizard_failed); - if (status.equals(AccountCreator.Status.AccountExist) - || status.equals(AccountCreator.Status.AccountExistWithAlias)) - return ctxt.getString(R.string.account_already_exist); - if (status.equals(AccountCreator.Status.AliasIsAccount) - || status.equals(AccountCreator.Status.AliasExist)) - return ctxt.getString(R.string.assistant_phone_number_unavailable); - if (status.equals(AccountCreator.Status.AccountNotExist)) - return ctxt.getString(R.string.assistant_error_bad_credentials); - if (status.equals(AccountCreator.Status.AliasNotExist)) - return ctxt.getString(R.string.phone_number_not_exist); - if (status.equals(AccountCreator.Status.AliasNotExist) - || status.equals(AccountCreator.Status.AccountNotActivated) - || status.equals(AccountCreator.Status.AccountAlreadyActivated) - || status.equals(AccountCreator.Status.AccountActivated) - || status.equals(AccountCreator.Status.AccountNotCreated) - || status.equals(AccountCreator.Status.RequestOk)) return ""; - } - return null; - } - - public static String getCountryCode(EditText dialCode) { - if (dialCode != null) { - String code = dialCode.getText().toString(); - if (code != null && code.startsWith("+")) { - code = code.substring(1); - } - return code; - } - return null; - } - public static void displayErrorAlert(String msg, Context ctxt) { if (ctxt != null && msg != null) { AlertDialog.Builder builder = new AlertDialog.Builder(ctxt); @@ -484,12 +375,6 @@ public final class LinphoneUtils { imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } - private static Context getContext() { - if (sContext == null && LinphoneManager.isInstanciated()) - sContext = LinphoneManager.getInstance().getContext(); - return sContext; - } - public static ArrayList removeEmptyOneToOneChatRooms(ChatRoom[] rooms) { ArrayList newRooms = new ArrayList<>(); for (ChatRoom room : rooms) { diff --git a/app/src/main/java/org/linphone/utils/ThemableActivity.java b/app/src/main/java/org/linphone/utils/ThemableActivity.java index 871607a51..79e9caa3a 100644 --- a/app/src/main/java/org/linphone/utils/ThemableActivity.java +++ b/app/src/main/java/org/linphone/utils/ThemableActivity.java @@ -19,6 +19,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import android.content.pm.ActivityInfo; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import org.linphone.R; @@ -32,6 +33,10 @@ public class ThemableActivity extends AppCompatActivity { setTheme(R.style.LinphoneStyleDark); } + if (getResources().getBoolean(R.bool.orientation_portrait_only)) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } + super.onCreate(savedInstanceState); } } diff --git a/app/src/main/res/layout-land/assistant_codec_downloader.xml b/app/src/main/res/layout-land/assistant_codec_downloader.xml deleted file mode 100644 index 1d28702ba..000000000 --- a/app/src/main/res/layout-land/assistant_codec_downloader.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - - -