diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 65f00d0da..e67e25b03 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -110,6 +110,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values-FR/strings.xml b/res/values-FR/strings.xml
index 9c295ef9a..6e39b05e4 100644
--- a/res/values-FR/strings.xml
+++ b/res/values-FR/strings.xml
@@ -400,4 +400,6 @@
%i messages non lus
Renvoyer
+
+ Erreur durant le téléchargement ou l\'application de la configuration distante...
diff --git a/res/values-RU/strings.xml b/res/values-RU/strings.xml
index 0b460aa61..1d307d256 100755
--- a/res/values-RU/strings.xml
+++ b/res/values-RU/strings.xml
@@ -451,4 +451,6 @@
%i unread messages
Retry
+
+ Failed to download or apply remote provisioning profile...
diff --git a/res/values/non_localizable_custom.xml b/res/values/non_localizable_custom.xml
index 51f536c59..64a4cff87 100644
--- a/res/values/non_localizable_custom.xml
+++ b/res/values/non_localizable_custom.xml
@@ -71,6 +71,11 @@
false
true
+
+ false
+ false
+ false
+
true
false
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 547ad3498..86e21287a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -451,4 +451,6 @@
%i unread messages
Retry
+
+ Failed to download or apply remote provisioning profile...
diff --git a/src/org/linphone/LinphoneLauncherActivity.java b/src/org/linphone/LinphoneLauncherActivity.java
index d5ea65294..7ac7a70c2 100644
--- a/src/org/linphone/LinphoneLauncherActivity.java
+++ b/src/org/linphone/LinphoneLauncherActivity.java
@@ -21,6 +21,7 @@ package org.linphone;
import static android.content.Intent.ACTION_MAIN;
import org.linphone.mediastream.Log;
+import org.linphone.setup.RemoteProvisioningActivity;
import org.linphone.tutorials.TutorialLauncherActivity;
import android.app.Activity;
@@ -72,6 +73,8 @@ public class LinphoneLauncherActivity extends Activity {
final Class extends Activity> 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;
} else {
classToStart = LinphoneActivity.class;
}
diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java
index 3f7b72af8..523d3a42b 100644
--- a/src/org/linphone/LinphoneManager.java
+++ b/src/org/linphone/LinphoneManager.java
@@ -40,6 +40,7 @@ import org.linphone.LinphoneSimpleListener.LinphoneOnAudioChangedListener.AudioS
import org.linphone.LinphoneSimpleListener.LinphoneOnComposingReceivedListener;
import org.linphone.LinphoneSimpleListener.LinphoneOnDTMFReceivedListener;
import org.linphone.LinphoneSimpleListener.LinphoneOnMessageReceivedListener;
+import org.linphone.LinphoneSimpleListener.LinphoneOnRemoteProvisioningListener;
import org.linphone.LinphoneSimpleListener.LinphoneServiceListener;
import org.linphone.compatibility.Compatibility;
import org.linphone.core.CallDirection;
@@ -74,6 +75,7 @@ import org.linphone.mediastream.Version;
import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration;
import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration.AndroidCamera;
import org.linphone.mediastream.video.capture.hwconf.Hacks;
+import org.linphone.setup.RemoteProvisioningActivity;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
@@ -1369,10 +1371,22 @@ public class LinphoneManager implements LinphoneCoreListener {
if (composingReceivedListener != null)
composingReceivedListener.onComposingReceived(cr);
}
+
+ private LinphoneOnRemoteProvisioningListener remoteProvisioningListener;
+ public void setOnRemoteProvisioningListener(LinphoneOnRemoteProvisioningListener listener) {
+ remoteProvisioningListener = listener;
+ }
@Override
public void configuringStatus(LinphoneCore lc,
RemoteProvisioningState state, String message) {
Log.d("Remote provisioning status = " + state.toString() + " (" + message + ")");
+ if (RemoteProvisioningActivity.getInstance() != null) {
+ RemoteProvisioningActivity.getInstance().onConfiguringStatus(state);
+ }
+
+ if (remoteProvisioningListener != null) {
+ remoteProvisioningListener.onConfiguringStatus(state);
+ }
if (state == RemoteProvisioningState.ConfiguringSuccessful) {
if (LinphonePreferences.instance().isProvisioningLoginViewEnabled()) {
diff --git a/src/org/linphone/LinphonePreferences.java b/src/org/linphone/LinphonePreferences.java
index 4bdcf3bab..6e4ad7ba3 100644
--- a/src/org/linphone/LinphonePreferences.java
+++ b/src/org/linphone/LinphonePreferences.java
@@ -988,4 +988,12 @@ public class LinphonePreferences {
Log.w("Remote provisioning login view wasn't enabled, ignoring");
}
}
+
+ public void firstRemoteProvisioningSuccessful() {
+ getConfig().setBool("app", "first_remote_provisioning", false);
+ }
+
+ public boolean isFirstRemoteProvisioning() {
+ return getConfig().getBool("app", "first_remote_provisioning", true);
+ }
}
diff --git a/src/org/linphone/LinphoneSimpleListener.java b/src/org/linphone/LinphoneSimpleListener.java
index 9064199e3..282f89189 100644
--- a/src/org/linphone/LinphoneSimpleListener.java
+++ b/src/org/linphone/LinphoneSimpleListener.java
@@ -25,6 +25,7 @@ import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneCore.GlobalState;
import org.linphone.core.LinphoneCore.RegistrationState;
+import org.linphone.core.LinphoneCore.RemoteProvisioningState;
import android.content.Context;
import android.net.ConnectivityManager;
@@ -80,4 +81,7 @@ public interface LinphoneSimpleListener {
public static interface LinphoneOnComposingReceivedListener extends LinphoneSimpleListener {
void onComposingReceived(LinphoneChatRoom room);
}
+ public static interface LinphoneOnRemoteProvisioningListener extends LinphoneSimpleListener {
+ void onConfiguringStatus(RemoteProvisioningState state);
+ }
}
diff --git a/src/org/linphone/setup/RemoteProvisioningActivity.java b/src/org/linphone/setup/RemoteProvisioningActivity.java
new file mode 100644
index 000000000..39640bc46
--- /dev/null
+++ b/src/org/linphone/setup/RemoteProvisioningActivity.java
@@ -0,0 +1,156 @@
+package org.linphone.setup;
+/*
+RemoteProvisioningActivity.java
+Copyright (C) 2014 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 static android.content.Intent.ACTION_MAIN;
+
+import org.linphone.LinphoneActivity;
+import org.linphone.LinphoneLauncherActivity;
+import org.linphone.LinphonePreferences;
+import org.linphone.LinphoneService;
+import org.linphone.LinphoneSimpleListener.LinphoneOnRemoteProvisioningListener;
+import org.linphone.R;
+import org.linphone.core.LinphoneCore.RemoteProvisioningState;
+import org.linphone.mediastream.Log;
+
+import android.app.Activity;
+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;
+
+/**
+ * @author Sylvain Berfini
+ */
+public class RemoteProvisioningActivity extends Activity implements LinphoneOnRemoteProvisioningListener {
+ private static RemoteProvisioningActivity instance = null;
+
+ private Handler mHandler = new Handler();
+ private String configUriParam = null;
+ private ProgressBar spinner;
+
+ public static RemoteProvisioningActivity getInstance() {
+ return instance;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.remote_provisioning);
+ spinner = (ProgressBar) findViewById(R.id.spinner);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ instance = this;
+
+ checkIntentForConfigUri(getIntent());
+ }
+
+ @Override
+ protected void onPause() {
+ instance = null;
+ super.onPause();
+ }
+
+ @Override
+ public void onConfiguringStatus(RemoteProvisioningState state) {
+ if (spinner != null) spinner.setVisibility(View.GONE);
+ if (state == RemoteProvisioningState.ConfiguringSuccessful) {
+ goToLinphoneActivity();
+ } else if (state == RemoteProvisioningState.ConfiguringFailed) {
+ Toast.makeText(this, R.string.remote_provisioning_failure, Toast.LENGTH_LONG).show();
+ }
+ }
+
+ @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
+ configUriParam = openUri.getEncodedSchemeSpecificPart().substring(2); // Removes the linphone-config://
+ Log.d("Using config uri: " + configUriParam);
+ }
+
+ if (configUriParam == 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()) {
+ // TODO: show confirmation popup
+ } else {
+ setRemoteProvisioningAddressAndRestart(configUriParam);
+ }
+ }
+ }
+ }).start();
+ }
+
+ private void setRemoteProvisioningAddressAndRestart(String configUri) {
+ if (spinner != null) spinner.setVisibility(View.VISIBLE);
+
+ LinphonePreferences.instance().setRemoteProvisioningUrl(configUri);
+ LinphonePreferences.instance().firstRemoteProvisioningSuccessful();
+
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ // Restart Linphone
+ stopService(new Intent(ACTION_MAIN).setClass(RemoteProvisioningActivity.this, LinphoneService.class));
+ Intent intent = new Intent();
+ intent.setClass(RemoteProvisioningActivity.this, LinphoneLauncherActivity.class);
+ startActivity(intent);
+ }
+ }, 1000);
+ }
+
+ private void goToLinphoneActivity() {
+ LinphoneService.instance().setActivityToLaunchOnIncomingReceived(LinphoneActivity.class);
+ finish(); // To prevent the user to come back to this page using back button
+ startActivity(new Intent().setClass(this, LinphoneActivity.class).setData(getIntent().getData()));
+ }
+}