diff --git a/AndroidManifest.xml b/AndroidManifest.xml index e274eb7be..5d5b516f8 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,7 +1,7 @@ + android:versionCode="2411" android:installLocation="auto"> diff --git a/bsed.sh b/bsed.sh index ea7a242fe..b357ae14e 100755 --- a/bsed.sh +++ b/bsed.sh @@ -45,4 +45,4 @@ function patch_strings_in_file() { } patch_strings_in_file libs/armeabi-v7a/liblinphone-armeabi-v7a.so "./obj/local/armeabi-v7a/libffmpeg-linphone-arm.so" "libffmpeg-linphone-arm.so" -patch_strings_in_file libs/armeabi-x86/liblinphone-armeabi-x86.so "./obj/local/armeabi-x86/libffmpeg-linphone-x86.so" "libffmpeg-linphone-x86.so" +patch_strings_in_file libs/x86/liblinphone-x86.so "./obj/local/x86/libffmpeg-linphone-x86.so" "libffmpeg-linphone-x86.so" diff --git a/libs/android-support-v4.jar b/libs/android-support-v4.jar index 1437d24e6..e74b0d77d 100644 Binary files a/libs/android-support-v4.jar and b/libs/android-support-v4.jar differ diff --git a/res/raw-sw600dp/linphonerc_default b/res/raw-sw600dp/linphonerc_default index ec26f80bb..8ee2fbaba 100644 --- a/res/raw-sw600dp/linphonerc_default +++ b/res/raw-sw600dp/linphonerc_default @@ -14,6 +14,7 @@ size=vga [app] sharing_server=https://www.linphone.org:444/lft.php tunnel=disabled +push_notification=1 [tunnel] host= diff --git a/res/raw/linphonerc_default b/res/raw/linphonerc_default index f1e2c9ff2..27dcac0ab 100644 --- a/res/raw/linphonerc_default +++ b/res/raw/linphonerc_default @@ -14,6 +14,7 @@ size=qvga [app] sharing_server=https://www.linphone.org:444/lft.php tunnel=disabled +push_notification=1 [tunnel] host= diff --git a/res/values/non_localizable_custom.xml b/res/values/non_localizable_custom.xml index 47ee3290a..85a8cffd0 100644 --- a/res/values/non_localizable_custom.xml +++ b/res/values/non_localizable_custom.xml @@ -73,7 +73,6 @@ false true false - false false @@ -91,5 +90,6 @@ linphone-android-photo-%s.jpg true + true diff --git a/res/values/non_localizable_strings.xml b/res/values/non_localizable_strings.xml index 5cdfe6343..8830a329b 100644 --- a/res/values/non_localizable_strings.xml +++ b/res/values/non_localizable_strings.xml @@ -67,7 +67,10 @@ pref_video_automatically_accept_video_key pref_video_initiate_call_with_video_key pref_video_enable_key + pref_video_preset_key pref_preferred_video_size_key + pref_preferred_video_fps_key + pref_bandwidth_limit_key pref_animation_enable_key pref_escape_plus_key pref_echo_cancellation_key diff --git a/res/values/strings.xml b/res/values/strings.xml index 5d3295be8..baf5f687c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -112,6 +112,7 @@ Initiate video calls Always send video requests Enable Video + Bandwidth limit in kbits/s Enable Animations Replace + by 00 iLBC might be unavailable depending on ARM processor and Android OS version. diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 7e7af2c14..91a13e99b 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -114,10 +114,23 @@ android:summary="@string/pref_video_automatically_accept_video" android:dependency="@string/pref_video_enable_key"/> + + + + + + 0) { @@ -255,6 +265,11 @@ public class InCallActivity extends FragmentActivity implements OnClickListener audioCallFragment = (AudioCallFragment) callFragment; switchCamera.setVisibility(View.INVISIBLE); } + + if(BluetoothManager.getInstance().isBluetoothHeadsetAvailable()){ + BluetoothManager.getInstance().routeAudioToBluetooth(); + } + callFragment.setArguments(getIntent().getExtras()); getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer, callFragment).commitAllowingStateLoss(); @@ -357,7 +372,7 @@ public class InCallActivity extends FragmentActivity implements OnClickListener slideOutBottomToTop = AnimationUtils.loadAnimation(this, R.anim.slide_out_bottom_to_top); slideOutTopToBottom = AnimationUtils.loadAnimation(this, R.anim.slide_out_top_to_bottom); } - + if (BluetoothManager.getInstance().isBluetoothHeadsetAvailable()) { try { if (routeLayout != null) @@ -507,8 +522,8 @@ public class InCallActivity extends FragmentActivity implements OnClickListener routeBluetooth.setBackgroundResource(R.drawable.route_bluetooth_on); routeReceiver.setBackgroundResource(R.drawable.route_receiver_off); routeSpeaker.setBackgroundResource(R.drawable.route_speaker_off); - hideOrDisplayAudioRoutes(); } + hideOrDisplayAudioRoutes(); } else if (id == R.id.routeReceiver) { LinphoneManager.getInstance().routeAudioToReceiver(); @@ -1049,11 +1064,11 @@ public class InCallActivity extends FragmentActivity implements OnClickListener private void hideOrDisplayAudioRoutes() { if (routeSpeaker.getVisibility() == View.VISIBLE) { - routeSpeaker.setVisibility(View.INVISIBLE); - routeBluetooth.setVisibility(View.INVISIBLE); - routeReceiver.setVisibility(View.INVISIBLE); + routeSpeaker.setVisibility(View.GONE); + routeBluetooth.setVisibility(View.GONE); + routeReceiver.setVisibility(View.GONE); audioRoute.setSelected(false); - } else { + } else { routeSpeaker.setVisibility(View.VISIBLE); routeBluetooth.setVisibility(View.VISIBLE); routeReceiver.setVisibility(View.VISIBLE); diff --git a/src/org/linphone/LinphonePreferences.java b/src/org/linphone/LinphonePreferences.java index 8677bf181..5c018084c 100644 --- a/src/org/linphone/LinphonePreferences.java +++ b/src/org/linphone/LinphonePreferences.java @@ -763,22 +763,58 @@ public class LinphonePreferences { getLc().setVideoPolicy(shouldInitiateVideoCall(), accept); } + public String getVideoPreset() { + String preset = getLc().getVideoPreset(); + if (preset == null) preset = "default"; + return preset; + } + + public void setVideoPreset(String preset) { + if (preset.equals("default")) preset = null; + getLc().setVideoPreset(preset); + preset = getVideoPreset(); + if (!preset.equals("custom")) { + getLc().setPreferredFramerate(0); + } + setPreferredVideoSize(getPreferredVideoSize()); // Apply the bandwidth limit + } + public String getPreferredVideoSize() { //LinphoneCore can only return video size (width and height), not the name return getConfig().getString("video", "size", "qvga"); } public void setPreferredVideoSize(String preferredVideoSize) { - int bandwidth = 512; - if (preferredVideoSize.equals("720p")) { - bandwidth = 1024 + 128; - } else if (preferredVideoSize.equals("qvga")) { - bandwidth = 380; - } else if (preferredVideoSize.equals("qcif")) { - bandwidth = 256; - } - getLc().setPreferredVideoSizeByName(preferredVideoSize); + String preset = getVideoPreset(); + if (!preset.equals("custom")) { + int bandwidth = 512; + if (preferredVideoSize.equals("720p")) { + bandwidth = 1024 + 128; + } else if (preferredVideoSize.equals("vga")) { + bandwidth = 660; + } else if (preferredVideoSize.equals("qvga")) { + bandwidth = 380; + } else if (preferredVideoSize.equals("qcif")) { + bandwidth = 256; + } + setBandwidthLimit(bandwidth); + } + } + + public int getPreferredVideoFps() { + return (int)getLc().getPreferredFramerate(); + } + + public void setPreferredVideoFps(int fps) { + getLc().setPreferredFramerate(fps); + } + + public int getBandwidthLimit() { + return getLc().getDownloadBandwidth(); + } + + public void setBandwidthLimit(int bandwidth) { getLc().setUploadBandwidth(bandwidth); getLc().setDownloadBandwidth(bandwidth); } diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index 8dbe2c88a..2b5ec9c7b 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -35,6 +35,7 @@ import org.linphone.core.LinphoneProxyConfig; import org.linphone.mediastream.Log; import org.linphone.mediastream.Version; +import android.annotation.TargetApi; import android.app.Activity; import android.app.AlarmManager; import android.app.Notification; @@ -116,6 +117,7 @@ public final class LinphoneService extends Service { private String mNotificationTitle; private boolean mDisableRegistrationStatus; private LinphoneCoreListenerBase mListener; + public static int notifcationsPriority = (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41) ? Notification.PRIORITY_DEFAULT : 0); public int getMessageNotifCount() { return mMsgNotifCount; @@ -153,7 +155,7 @@ public final class LinphoneService extends Service { bm = BitmapFactory.decodeResource(getResources(), R.drawable.logo_linphone_57x57); } catch (Exception e) { } - mNotif = Compatibility.createNotification(this, mNotificationTitle, "", R.drawable.status_level, IC_LEVEL_OFFLINE, bm, mNotifContentIntent, true); + mNotif = Compatibility.createNotification(this, mNotificationTitle, "", R.drawable.status_level, IC_LEVEL_OFFLINE, bm, mNotifContentIntent, true,notifcationsPriority); LinphoneManager.createAndStart(LinphoneService.this); @@ -271,6 +273,7 @@ public final class LinphoneService extends Service { } }; + private enum IncallIconState {INCALL, PAUSE, VIDEO, IDLE} private IncallIconState mCurrentIncallIconState = IncallIconState.IDLE; @@ -357,7 +360,7 @@ public final class LinphoneService extends Service { bm = BitmapFactory.decodeResource(getResources(), R.drawable.logo_linphone_57x57); } catch (Exception e) { } - mCustomNotif = Compatibility.createNotification(this, title, message, iconResourceID, 0, bm, notifContentIntent, isOngoingEvent); + mCustomNotif = Compatibility.createNotification(this, title, message, iconResourceID, 0, bm, notifContentIntent, isOngoingEvent,notifcationsPriority); mCustomNotif.defaults |= Notification.DEFAULT_VIBRATE; mCustomNotif.defaults |= Notification.DEFAULT_SOUND; @@ -529,7 +532,7 @@ public final class LinphoneService extends Service { bm = BitmapFactory.decodeResource(getResources(), R.drawable.logo_linphone_57x57); } catch (Exception e) { } - mNotif = Compatibility.createNotification(this, mNotificationTitle, text, R.drawable.status_level, level, bm, mNotifContentIntent, true); + mNotif = Compatibility.createNotification(this, mNotificationTitle, text, R.drawable.status_level, level, bm, mNotifContentIntent, true,notifcationsPriority); notifyWrapper(NOTIF_ID, mNotif); } @@ -551,6 +554,17 @@ public final class LinphoneService extends Service { public IBinder onBind(Intent intent) { return null; } + + @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) + @Override + public void onTaskRemoved(Intent rootIntent) { + if (getResources().getBoolean(R.bool.kill_service_with_task_manager)) { + Log.d("Task removed, stop service"); + LinphoneManager.getLc().setNetworkReachable(false); + stopSelf(); + } + super.onTaskRemoved(rootIntent); + } @Override public synchronized void onDestroy() { diff --git a/src/org/linphone/SettingsFragment.java b/src/org/linphone/SettingsFragment.java index f8949173e..c8a6be492 100644 --- a/src/org/linphone/SettingsFragment.java +++ b/src/org/linphone/SettingsFragment.java @@ -51,6 +51,7 @@ import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceCategory; import android.preference.PreferenceScreen; +import android.widget.EditText; /** * @author Sylvain Berfini @@ -127,8 +128,8 @@ public class SettingsFragment extends PreferencesListFragment { @Override public boolean onPreferenceClick(Preference preference) { Intent intent = new Intent(LinphoneService.instance(), SetupActivity.class); - startActivityForResult(intent, WIZARD_INTENT); - return true; + startActivityForResult(intent, WIZARD_INTENT); + return true; } }); findPreference(getString(R.string.pref_add_account_key)).setOnPreferenceClickListener(new OnPreferenceClickListener() { @@ -136,7 +137,7 @@ public class SettingsFragment extends PreferencesListFragment { public boolean onPreferenceClick(Preference preference) { int nbAccounts = mPrefs.getAccountCount(); LinphoneActivity.instance().displayAccountSettings(nbAccounts); - return true; + return true; } }); findPreference("in_app_store").setOnPreferenceClickListener(new OnPreferenceClickListener() { @@ -437,6 +438,21 @@ public class SettingsFragment extends PreferencesListFragment { pref.setValue(key); } + private void initializeVideoPresetPreferences(ListPreference pref) { + List entries = new ArrayList(); + List values = new ArrayList(); + entries.add("default"); + values.add("default"); + entries.add("high-fps"); + values.add("high-fps"); + entries.add("custom"); + values.add("custom"); + setListPreferenceValues(pref, entries, values); + String value = mPrefs.getVideoPreset(); + pref.setSummary(value); + pref.setValue(value); + } + private void initializePreferredVideoSizePreferences(ListPreference pref) { List entries = new ArrayList(); List values = new ArrayList(); @@ -452,6 +468,25 @@ public class SettingsFragment extends PreferencesListFragment { pref.setValue(value); } + private void initializePreferredVideoFpsPreferences(ListPreference pref) { + List entries = new ArrayList(); + List values = new ArrayList(); + entries.add("none"); + values.add("0"); + for (int i = 5; i <= 30; i += 5) { + String str = Integer.toString(i); + entries.add(str); + values.add(str); + } + setListPreferenceValues(pref, entries, values); + String value = Integer.toString(mPrefs.getPreferredVideoFps()); + if (value.equals("0")) { + value = "none"; + } + pref.setSummary(value); + pref.setValue(value); + } + private static void setListPreferenceValues(ListPreference pref, List entries, List values) { CharSequence[] contents = new CharSequence[entries.size()]; entries.toArray(contents); @@ -545,7 +580,7 @@ public class SettingsFragment extends PreferencesListFragment { findPreference(getString(R.string.pref_adaptive_rate_algorithm_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - mPrefs.setAdaptiveRateAlgorithm(AdaptiveRateAlgorithm.fromString((String)newValue)); + mPrefs.setAdaptiveRateAlgorithm(AdaptiveRateAlgorithm.fromString((String) newValue)); preference.setSummary(String.valueOf(mPrefs.getAdaptiveRateAlgorithm())); return true; } @@ -557,10 +592,10 @@ public class SettingsFragment extends PreferencesListFragment { public boolean onPreferenceChange(Preference preference, Object newValue) { mPrefs.setCodecBitrateLimit(Integer.parseInt(newValue.toString())); LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - int bitrate=Integer.parseInt(newValue.toString()); + int bitrate = Integer.parseInt(newValue.toString()); for (final PayloadType pt : lc.getAudioCodecs()) { - if(lc.payloadTypeIsVbr(pt)){ + if (lc.payloadTypeIsVbr(pt)) { lc.setPayloadTypeBitrate(pt, bitrate); } } @@ -587,7 +622,13 @@ public class SettingsFragment extends PreferencesListFragment { } private void initVideoSettings() { + initializeVideoPresetPreferences((ListPreference) findPreference(getString(R.string.pref_video_preset_key))); initializePreferredVideoSizePreferences((ListPreference) findPreference(getString(R.string.pref_preferred_video_size_key))); + initializePreferredVideoFpsPreferences((ListPreference) findPreference(getString(R.string.pref_preferred_video_fps_key))); + EditTextPreference bandwidth = (EditTextPreference) findPreference(getString(R.string.pref_bandwidth_limit_key)); + bandwidth.setText(Integer.toString(mPrefs.getBandwidthLimit())); + bandwidth.setSummary(bandwidth.getText()); + updateVideoPreferencesAccordingToPreset(); PreferenceCategory codecs = (PreferenceCategory) findPreference(getString(R.string.pref_video_codecs_key)); codecs.removeAll(); @@ -634,6 +675,24 @@ public class SettingsFragment extends PreferencesListFragment { ((CheckBoxPreference) findPreference(getString(R.string.pref_video_automatically_accept_video_key))).setChecked(mPrefs.shouldAutomaticallyAcceptVideoRequests()); } + private void updateVideoPreferencesAccordingToPreset() { + if (mPrefs.getVideoPreset().equals("custom")) { + findPreference(getString(R.string.pref_preferred_video_fps_key)).setEnabled(true); + findPreference(getString(R.string.pref_bandwidth_limit_key)).setEnabled(true); + } else { + findPreference(getString(R.string.pref_preferred_video_fps_key)).setEnabled(false); + findPreference(getString(R.string.pref_bandwidth_limit_key)).setEnabled(false); + } + ((ListPreference) findPreference(getString(R.string.pref_video_preset_key))).setSummary(mPrefs.getVideoPreset()); + int fps = mPrefs.getPreferredVideoFps(); + String fpsStr = Integer.toString(fps); + if (fpsStr.equals("0")) { + fpsStr = "none"; + } + ((ListPreference) findPreference(getString(R.string.pref_preferred_video_fps_key))).setSummary(fpsStr); + ((EditTextPreference) findPreference(getString(R.string.pref_bandwidth_limit_key))).setSummary(Integer.toString(mPrefs.getBandwidthLimit())); + } + private void setVideoPreferencesListener() { findPreference(getString(R.string.pref_video_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override @@ -682,11 +741,39 @@ public class SettingsFragment extends PreferencesListFragment { } }); + findPreference(getString(R.string.pref_video_preset_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + mPrefs.setVideoPreset(newValue.toString()); + preference.setSummary(mPrefs.getVideoPreset()); + updateVideoPreferencesAccordingToPreset(); + return true; + } + }); findPreference(getString(R.string.pref_preferred_video_size_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { mPrefs.setPreferredVideoSize(newValue.toString()); preference.setSummary(mPrefs.getPreferredVideoSize()); + updateVideoPreferencesAccordingToPreset(); + return true; + } + }); + + findPreference(getString(R.string.pref_preferred_video_fps_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + mPrefs.setPreferredVideoFps(Integer.parseInt(newValue.toString())); + updateVideoPreferencesAccordingToPreset(); + return true; + } + }); + + findPreference(getString(R.string.pref_bandwidth_limit_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + mPrefs.setBandwidthLimit(Integer.parseInt(newValue.toString())); + preference.setSummary(newValue.toString()); return true; } }); diff --git a/src/org/linphone/compatibility/ApiElevenPlus.java b/src/org/linphone/compatibility/ApiElevenPlus.java index 1fc9b8409..cce5c9795 100644 --- a/src/org/linphone/compatibility/ApiElevenPlus.java +++ b/src/org/linphone/compatibility/ApiElevenPlus.java @@ -166,4 +166,18 @@ public class ApiElevenPlus { return intent; } + + @SuppressWarnings("deprecation") + public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) { + Notification notif = new Notification.Builder(context) + .setContentTitle(title) + .setContentText(text) + .setContentIntent(intent) + .setSmallIcon(R.drawable.logo_linphone_57x57) + .setAutoCancel(true) + .setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE) + .setWhen(System.currentTimeMillis()).getNotification(); + + return notif; + } } diff --git a/src/org/linphone/compatibility/ApiFivePlus.java b/src/org/linphone/compatibility/ApiFivePlus.java index 39662f067..b0c66f825 100644 --- a/src/org/linphone/compatibility/ApiFivePlus.java +++ b/src/org/linphone/compatibility/ApiFivePlus.java @@ -401,4 +401,20 @@ public class ApiFivePlus { return notif; } + + public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) { + Notification notif = new Notification(); + notif.icon = R.drawable.logo_linphone_57x57; + notif.iconLevel = 0; + notif.when = System.currentTimeMillis(); + notif.flags &= Notification.FLAG_ONGOING_EVENT; + + notif.defaults |= Notification.DEFAULT_VIBRATE; + notif.defaults |= Notification.DEFAULT_SOUND; + notif.defaults |= Notification.DEFAULT_LIGHTS; + + notif.setLatestEventInfo(context, title, text, intent); + + return notif; + } } diff --git a/src/org/linphone/compatibility/ApiSixteenPlus.java b/src/org/linphone/compatibility/ApiSixteenPlus.java index 07e9d97f9..dba56077c 100644 --- a/src/org/linphone/compatibility/ApiSixteenPlus.java +++ b/src/org/linphone/compatibility/ApiSixteenPlus.java @@ -76,7 +76,7 @@ public class ApiSixteenPlus { return notif; } - public static Notification createNotification(Context context, String title, String message, int icon, int level, Bitmap largeIcon, PendingIntent intent, boolean isOngoingEvent) { + public static Notification createNotification(Context context, String title, String message, int icon, int level, Bitmap largeIcon, PendingIntent intent, boolean isOngoingEvent,int priority) { Notification notif; if (largeIcon != null) { @@ -87,6 +87,7 @@ public class ApiSixteenPlus { .setLargeIcon(largeIcon) .setContentIntent(intent) .setWhen(System.currentTimeMillis()) + .setPriority(priority) .build(); } else { notif = new Notification.Builder(context) @@ -95,6 +96,7 @@ public class ApiSixteenPlus { .setSmallIcon(icon, level) .setContentIntent(intent) .setWhen(System.currentTimeMillis()) + .setPriority(priority) .build(); } if (isOngoingEvent) { @@ -107,4 +109,18 @@ public class ApiSixteenPlus { public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) { viewTreeObserver.removeOnGlobalLayoutListener(keyboardListener); } + + public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) { + Notification notif = new Notification.Builder(context) + .setContentTitle(title) + .setContentText(text) + .setSmallIcon(R.drawable.logo_linphone_57x57) + .setAutoCancel(true) + .setContentIntent(intent) + .setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE) + .setWhen(System.currentTimeMillis()) + .build(); + + return notif; + } } diff --git a/src/org/linphone/compatibility/ApiTwentyOnePlus.java b/src/org/linphone/compatibility/ApiTwentyOnePlus.java index e12b228b7..c47fe007b 100644 --- a/src/org/linphone/compatibility/ApiTwentyOnePlus.java +++ b/src/org/linphone/compatibility/ApiTwentyOnePlus.java @@ -78,7 +78,7 @@ public class ApiTwentyOnePlus { return notif; } - public static Notification createNotification(Context context, String title, String message, int icon, int level, Bitmap largeIcon, PendingIntent intent, boolean isOngoingEvent) { + public static Notification createNotification(Context context, String title, String message, int icon, int level, Bitmap largeIcon, PendingIntent intent, boolean isOngoingEvent,int priority) { Notification notif; if (largeIcon != null) { @@ -90,7 +90,7 @@ public class ApiTwentyOnePlus { .setContentIntent(intent) .setCategory(Notification.CATEGORY_SERVICE) .setVisibility(Notification.VISIBILITY_SECRET) - .setPriority(Notification.PRIORITY_DEFAULT) + .setPriority(priority) .build(); } else { notif = new NotificationCompat.Builder(context) @@ -100,7 +100,7 @@ public class ApiTwentyOnePlus { .setContentIntent(intent) .setCategory(Notification.CATEGORY_SERVICE) .setVisibility(Notification.VISIBILITY_SECRET) - .setPriority(Notification.PRIORITY_DEFAULT) + .setPriority(priority) .build(); } @@ -110,4 +110,20 @@ public class ApiTwentyOnePlus { public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) { viewTreeObserver.removeOnGlobalLayoutListener(keyboardListener); } + + public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) { + Notification notif = new NotificationCompat.Builder(context) + .setContentTitle(title) + .setContentText(text) + .setSmallIcon(R.drawable.logo_linphone_57x57) + .setAutoCancel(true) + .setContentIntent(intent) + .setDefaults(Notification.DEFAULT_ALL) + .setCategory(Notification.CATEGORY_MESSAGE) + .setVisibility(Notification.VISIBILITY_PRIVATE) + .setPriority(Notification.PRIORITY_HIGH) + .build(); + + return notif; + } } diff --git a/src/org/linphone/compatibility/Compatibility.java b/src/org/linphone/compatibility/Compatibility.java index e5da3d243..2e8bd3afb 100644 --- a/src/org/linphone/compatibility/Compatibility.java +++ b/src/org/linphone/compatibility/Compatibility.java @@ -153,6 +153,21 @@ public class Compatibility { } } + public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) { + Notification notif = null; + + if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) { + return ApiTwentyOnePlus.createSimpleNotification(context, title, text, intent); + } else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { + notif = ApiSixteenPlus.createSimpleNotification(context, title, text, intent); + } else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { + notif = ApiElevenPlus.createSimpleNotification(context, title, text, intent); + } else { + notif = ApiFivePlus.createSimpleNotification(context, title, text, intent); + } + return notif; + } + public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) { Notification notif = null; String title; @@ -189,11 +204,11 @@ public class Compatibility { return notif; } - public static Notification createNotification(Context context, String title, String message, int icon, int iconLevel, Bitmap largeIcon, PendingIntent intent, boolean isOngoingEvent) { + public static Notification createNotification(Context context, String title, String message, int icon, int iconLevel, Bitmap largeIcon, PendingIntent intent, boolean isOngoingEvent,int priority) { if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) { - return ApiTwentyOnePlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent); + return ApiTwentyOnePlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent,priority); } else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) { - return ApiSixteenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent); + return ApiSixteenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent,priority); } else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) { return ApiElevenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent); } else { diff --git a/src/org/linphone/gcm/GCMService.java b/src/org/linphone/gcm/GCMService.java index 1018fb569..59906ef77 100644 --- a/src/org/linphone/gcm/GCMService.java +++ b/src/org/linphone/gcm/GCMService.java @@ -18,8 +18,11 @@ 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.LinphoneManager; import org.linphone.LinphonePreferences; +import org.linphone.LinphoneService; import org.linphone.R; import org.linphone.UIThreadDispatcher; import org.linphone.mediastream.Log; @@ -47,7 +50,9 @@ public class GCMService extends GCMBaseIntentService { @Override protected void onMessage(Context context, Intent intent) { Log.d("Push notification received"); - if (LinphoneManager.isInstanciated() && LinphoneManager.getLc().getCallsNb() == 0) { + if (!LinphoneService.isReady()) { + startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class)); + } else if (LinphoneManager.isInstanciated() && LinphoneManager.getLc().getCallsNb() == 0) { UIThreadDispatcher.dispatch(new Runnable(){ @Override public void run() { diff --git a/submodules/belle-sip b/submodules/belle-sip index 1ffd89057..ec890e178 160000 --- a/submodules/belle-sip +++ b/submodules/belle-sip @@ -1 +1 @@ -Subproject commit 1ffd890571879bba9a58251dfe7dd5249c011517 +Subproject commit ec890e178427325e7d8cbc53df22d214680e2f85 diff --git a/submodules/linphone b/submodules/linphone index ad1d7c12c..60c0801e2 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit ad1d7c12c9b459660b34d63408b144bf5890f3b6 +Subproject commit 60c0801e2a3cb6d0e158c5c7b9477e4186e36e71 diff --git a/submodules/msopenh264 b/submodules/msopenh264 index 5a8473c09..0722c480d 160000 --- a/submodules/msopenh264 +++ b/submodules/msopenh264 @@ -1 +1 @@ -Subproject commit 5a8473c091d05d9eed67febdd555955f0b925900 +Subproject commit 0722c480d61746e9ab36f76b04ab2f3210890d07 diff --git a/tests/src/org/linphone/test/AccountAssistant.java b/tests/src/org/linphone/test/AccountAssistant.java index 87e24f498..3b08c857f 100644 --- a/tests/src/org/linphone/test/AccountAssistant.java +++ b/tests/src/org/linphone/test/AccountAssistant.java @@ -5,7 +5,6 @@ import junit.framework.Assert; import org.linphone.LinphoneActivity; import org.linphone.LinphoneManager; import org.linphone.LinphonePreferences; -import org.linphone.core.LinphoneCore.RegistrationState; import org.linphone.core.LinphoneProxyConfig; import org.linphone.mediastream.video.capture.hwconf.Hacks; import org.linphone.setup.SetupActivity; @@ -53,8 +52,8 @@ public class AccountAssistant extends SampleTest { LinphoneProxyConfig[] proxyConfigs = LinphoneManager.getLc().getProxyConfigList(); Assert.assertEquals(1, proxyConfigs.length); LinphoneProxyConfig proxyConfig = proxyConfigs[0]; - Assert.assertEquals(RegistrationState.RegistrationOk, proxyConfig.getState()); - + waitForRegistration(proxyConfig); + //Check the wizard added sip.linphone.org custom settings LinphonePreferences prefs = LinphonePreferences.instance(); String stunServer = prefs.getStunServer(); @@ -98,7 +97,7 @@ public class AccountAssistant extends SampleTest { LinphoneProxyConfig[] proxyConfigs = LinphoneManager.getLc().getProxyConfigList(); Assert.assertEquals(proxyConfigs.length, 2); LinphoneProxyConfig proxyConfig = proxyConfigs[1]; - Assert.assertEquals(RegistrationState.RegistrationOk, proxyConfig.getState()); + waitForRegistration(proxyConfig); } @LargeTest diff --git a/tests/src/org/linphone/test/AccountManagement.java b/tests/src/org/linphone/test/AccountManagement.java index d6a1198e2..4423706fb 100644 --- a/tests/src/org/linphone/test/AccountManagement.java +++ b/tests/src/org/linphone/test/AccountManagement.java @@ -6,7 +6,6 @@ import org.linphone.FragmentsAvailable; import org.linphone.LinphoneActivity; import org.linphone.LinphoneManager; import org.linphone.LinphonePreferences; -import org.linphone.core.LinphoneCore.RegistrationState; import org.linphone.core.LinphoneProxyConfig; import android.test.suitebuilder.annotation.LargeTest; @@ -33,7 +32,7 @@ public class AccountManagement extends SampleTest { waitForRegistration(proxyConfig); Assert.assertEquals(proxyConfigs.length, 2); proxyConfig = proxyConfigs[1]; - Assert.assertEquals(RegistrationState.RegistrationOk, proxyConfig.getState()); + waitForRegistration(proxyConfig); Assert.assertTrue(proxyConfig.getIdentity(), proxyConfig.getIdentity().contains("new")); } diff --git a/tests/src/org/linphone/test/AinitTestEnv.java b/tests/src/org/linphone/test/AinitTestEnv.java index 281948074..08777205b 100644 --- a/tests/src/org/linphone/test/AinitTestEnv.java +++ b/tests/src/org/linphone/test/AinitTestEnv.java @@ -2,8 +2,6 @@ package org.linphone.test; import junit.framework.Assert; -import org.linphone.core.LinphoneCore.RegistrationState; - import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; import android.test.suitebuilder.annotation.SmallTest; @@ -21,6 +19,6 @@ public class AinitTestEnv extends SampleTest { solo.sleep(5000); Assert.assertEquals(1, LinphoneTestManager.getLc().getProxyConfigList().length); - Assert.assertEquals(RegistrationState.RegistrationOk, LinphoneTestManager.getLc().getProxyConfigList()[0].getState()); + waitForRegistration(LinphoneTestManager.getLc().getProxyConfigList()[0]); } } diff --git a/tests/src/org/linphone/test/CallsAudio.java b/tests/src/org/linphone/test/CallsAudio.java index 51ea51635..66443e9ac 100644 --- a/tests/src/org/linphone/test/CallsAudio.java +++ b/tests/src/org/linphone/test/CallsAudio.java @@ -18,6 +18,10 @@ import android.test.suitebuilder.annotation.SmallTest; import android.util.DisplayMetrics; import android.view.View; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.List; + /** * @author Sylvain Berfini */ @@ -154,7 +158,7 @@ public class CallsAudio extends SampleTest { solo.assertCurrentActivity("Expected InCall Activity", InCallActivity.class); solo.sleep(2000); - Assert.assertEquals(LinphoneCall.State.OutgoingRinging, LinphoneManager.getLc().getCalls()[0].getState()); + waitForCallState(LinphoneManager.getLc().getCalls()[0],LinphoneCall.State.OutgoingRinging); LinphoneTestManager.getInstance().autoAnswer = true; @@ -246,14 +250,13 @@ public class CallsAudio extends SampleTest { solo.clickOnView(solo.getView(org.linphone.R.id.pause)); solo.sleep(1000); - LinphoneCall.State state = LinphoneManager.getLc().getCalls()[0].getState(); - Assert.assertTrue(LinphoneCall.State.Paused == state || LinphoneCall.State.Pausing == state); + waitForCallPaused(LinphoneManager.getLc().getCalls()[0]); + solo.clickOnView(solo.getView(org.linphone.R.id.pause)); solo.sleep(1000); - - state = LinphoneManager.getLc().getCalls()[0].getState(); - Assert.assertTrue(LinphoneCall.State.Resuming == state || LinphoneCall.State.StreamsRunning == state); + + waitForCallResumed(LinphoneManager.getLc().getCalls()[0]); solo.clickOnView(solo.getView(org.linphone.R.id.hangUp)); solo.waitForActivity("LinphoneActivity", 5000); @@ -270,13 +273,13 @@ public class CallsAudio extends SampleTest { LinphoneTestManager.getLc().pauseAllCalls(); solo.sleep(1000); - - Assert.assertEquals(LinphoneCall.State.PausedByRemote, LinphoneManager.getLc().getCalls()[0].getState()); + + waitForCallState(LinphoneManager.getLc().getCalls()[0], LinphoneCall.State.PausedByRemote); + LinphoneTestManager.getLc().resumeCall(LinphoneTestManager.getLc().getCalls()[0]); solo.sleep(1000); - - LinphoneCall.State state = LinphoneManager.getLc().getCalls()[0].getState(); - Assert.assertTrue(LinphoneCall.State.Resuming == state || LinphoneCall.State.StreamsRunning == state); + + waitForCallResumed(LinphoneManager.getLc().getCalls()[0]); solo.clickLongOnScreen(200, 200); //To ensure controls are shown solo.clickOnView(solo.getView(org.linphone.R.id.hangUp)); @@ -362,15 +365,8 @@ public class CallsAudio extends SampleTest { solo.sleep(2000); LinphoneCall call = LinphoneManager.getLc().getCalls()[0]; - - int retry = 0; - while ((call.getState() == LinphoneCall.State.OutgoingProgress || call.getState() == LinphoneCall.State.IncomingReceived) && retry < 5) { - solo.sleep(1000); - retry++; - Log.w("Call in progress but not running, retry = " + retry); - } - - Assert.assertEquals(LinphoneCall.State.StreamsRunning, call.getState()); + + waitForCallState(call, LinphoneCall.State.StreamsRunning); } private void goToSettings() { diff --git a/tests/src/org/linphone/test/CallsVideo.java b/tests/src/org/linphone/test/CallsVideo.java index 66c44cb5b..270b4ce69 100644 --- a/tests/src/org/linphone/test/CallsVideo.java +++ b/tests/src/org/linphone/test/CallsVideo.java @@ -11,7 +11,6 @@ import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphonePlayer; import org.linphone.core.PayloadType; -import org.linphone.core.LinphoneCore.RegistrationState; import org.linphone.mediastream.Log; import android.test.suitebuilder.annotation.LargeTest; @@ -169,7 +168,7 @@ public class CallsVideo extends SampleTest { solo.assertCurrentActivity("Expected InCall Activity", InCallActivity.class); solo.sleep(2000); - Assert.assertEquals(LinphoneCall.State.OutgoingRinging, LinphoneManager.getLc().getCalls()[0].getState()); + waitForCallState(LinphoneManager.getLc().getCalls()[0],LinphoneCall.State.OutgoingRinging); LinphoneTestManager.getInstance().autoAnswer = true; @@ -273,15 +272,12 @@ public class CallsVideo extends SampleTest { solo.clickOnView(solo.getView(org.linphone.R.id.pause)); solo.sleep(1000); - LinphoneCall.State state = LinphoneManager.getLc().getCalls()[0].getState(); - - - Assert.assertTrue(LinphoneCall.State.Paused == state || LinphoneCall.State.Pausing == state); + + waitForCallPaused(LinphoneManager.getLc().getCalls()[0]); solo.clickOnView(solo.getView(org.linphone.R.id.pause)); solo.sleep(1000); - state = LinphoneManager.getLc().getCalls()[0].getState(); - Assert.assertTrue(LinphoneCall.State.Resuming == state || LinphoneCall.State.StreamsRunning == state); + waitForCallResumed(LinphoneManager.getLc().getCalls()[0]); solo.clickOnView(solo.getView(org.linphone.R.id.hangUp)); solo.waitForActivity("LinphoneActivity", 5000); @@ -298,13 +294,12 @@ public class CallsVideo extends SampleTest { LinphoneTestManager.getLc().pauseAllCalls(); solo.sleep(1000); - - Assert.assertEquals(LinphoneCall.State.PausedByRemote, LinphoneManager.getLc().getCalls()[0].getState()); + + waitForCallState(LinphoneManager.getLc().getCalls()[0], LinphoneCall.State.PausedByRemote); LinphoneTestManager.getLc().resumeCall(LinphoneTestManager.getLc().getCalls()[0]); solo.sleep(1000); - - LinphoneCall.State state = LinphoneManager.getLc().getCalls()[0].getState(); - Assert.assertTrue(LinphoneCall.State.Resuming == state || LinphoneCall.State.StreamsRunning == state); + + waitForCallResumed(LinphoneManager.getLc().getCalls()[0]); solo.clickLongOnScreen(200, 200); //To ensure controls are shown solo.clickOnView(solo.getView(org.linphone.R.id.hangUp)); @@ -342,15 +337,8 @@ public class CallsVideo extends SampleTest { solo.sleep(2000); LinphoneCall call = LinphoneManager.getLc().getCalls()[0]; - - int retry = 0; - while ((call.getState() == LinphoneCall.State.OutgoingProgress || call.getState() == LinphoneCall.State.IncomingReceived) && retry < 5) { - solo.sleep(1000); - retry++; - Log.w("Call in progress but not running, retry = " + retry); - } - - Assert.assertEquals(LinphoneCall.State.StreamsRunning, call.getState()); + + waitForCallState(call, LinphoneCall.State.StreamsRunning); } private void goToSettings() { diff --git a/tests/src/org/linphone/test/ConferenceAndMultiCall.java b/tests/src/org/linphone/test/ConferenceAndMultiCall.java index 76787d0fa..fd3b77972 100644 --- a/tests/src/org/linphone/test/ConferenceAndMultiCall.java +++ b/tests/src/org/linphone/test/ConferenceAndMultiCall.java @@ -28,7 +28,7 @@ public class ConferenceAndMultiCall extends SampleTest { LinphoneTestManager.createAndStart(aContext, iContext, 2); solo.sleep(2000); - Assert.assertEquals(RegistrationState.RegistrationOk, LinphoneTestManager.getLc(2).getProxyConfigList()[0].getState()); + waitForRegistration(LinphoneTestManager.getLc(2).getProxyConfigList()[0]); //Disable video goToSettings(); @@ -79,13 +79,13 @@ public class ConferenceAndMultiCall extends SampleTest { solo.sleep(2000); LinphoneCall call1 = LinphoneTestManager.getLc(1).getCalls()[0]; LinphoneCall call2 = LinphoneTestManager.getLc(2).getCalls()[0]; - Assert.assertEquals(LinphoneCall.State.StreamsRunning, call2.getState()); - Assert.assertEquals(LinphoneCall.State.PausedByRemote, call1.getState()); + waitForCallState(call2,LinphoneCall.State.StreamsRunning); + waitForCallState(call1,LinphoneCall.State.PausedByRemote); solo.clickOnView(solo.getView(org.linphone.R.id.callStatus)); solo.sleep(2000); - Assert.assertEquals(LinphoneCall.State.StreamsRunning, call1.getState()); - Assert.assertEquals(LinphoneCall.State.PausedByRemote, call2.getState()); + waitForCallState(call1,LinphoneCall.State.StreamsRunning); + waitForCallState(call2,LinphoneCall.State.PausedByRemote); solo.clickOnView(solo.getView(org.linphone.R.id.hangUp)); solo.sleep(1000); @@ -101,14 +101,14 @@ public class ConferenceAndMultiCall extends SampleTest { solo.sleep(2000); LinphoneCall call1 = LinphoneTestManager.getLc(1).getCalls()[0]; LinphoneCall call2 = LinphoneTestManager.getLc(2).getCalls()[0]; - Assert.assertEquals(LinphoneCall.State.StreamsRunning, call2.getState()); - Assert.assertEquals(LinphoneCall.State.PausedByRemote, call1.getState()); + waitForCallState(call2,LinphoneCall.State.StreamsRunning); + waitForCallState(call1,LinphoneCall.State.PausedByRemote); ArrayList views = solo.getViews(solo.getView(2)); solo.clickOnView(views.get(2)); // Second call pause button solo.sleep(2000); - Assert.assertEquals(LinphoneCall.State.PausedByRemote, call1.getState()); - Assert.assertEquals(LinphoneCall.State.PausedByRemote, call2.getState()); + waitForCallState(call2,LinphoneCall.State.PausedByRemote); + waitForCallState(call1,LinphoneCall.State.PausedByRemote); // All calls are paused, one click on hangUp terminates them all solo.clickOnView(solo.getView(org.linphone.R.id.hangUp)); @@ -132,11 +132,11 @@ public class ConferenceAndMultiCall extends SampleTest { solo.sleep(2000); solo.clickOnView(solo.getView(org.linphone.R.id.hangUp)); - - Assert.assertEquals(LinphoneCall.State.PausedByRemote, LinphoneTestManager.getLc(1).getCalls()[0].getState()); + + waitForCallState(LinphoneTestManager.getLc(1).getCalls()[0],LinphoneCall.State.PausedByRemote); solo.clickOnView(solo.getView(org.linphone.R.id.pause)); solo.sleep(1000); - Assert.assertEquals(LinphoneCall.State.StreamsRunning, LinphoneTestManager.getLc(1).getCalls()[0].getState()); + waitForCallState(LinphoneTestManager.getLc(1).getCalls()[0],LinphoneCall.State.StreamsRunning); solo.sleep(1000); solo.clickOnView(solo.getView(org.linphone.R.id.hangUp)); @@ -163,7 +163,7 @@ public class ConferenceAndMultiCall extends SampleTest { solo.clickOnView(solo.getView(org.linphone.R.id.Call)); solo.sleep(2000); - Assert.assertEquals(LinphoneCall.State.PausedByRemote, LinphoneTestManager.getLc(1).getCalls()[0].getState()); + waitForCallState(LinphoneTestManager.getLc(1).getCalls()[0],LinphoneCall.State.PausedByRemote); solo.sleep(1000); solo.clickOnView(solo.getView(org.linphone.R.id.hangUp)); @@ -237,7 +237,7 @@ public class ConferenceAndMultiCall extends SampleTest { solo.sleep(1000); LinphoneCall call1 = LinphoneTestManager.getLc(1).getCalls()[0]; - Assert.assertEquals(LinphoneCall.State.PausedByRemote, call1.getState()); + waitForCallState(call1,LinphoneCall.State.PausedByRemote); assertCallIsCorrectlyRunning(2); solo.clickOnView(solo.getView(org.linphone.R.id.hangUp)); @@ -292,7 +292,7 @@ public class ConferenceAndMultiCall extends SampleTest { retry++; Log.w("Call in progress but not running, retry = " + retry); } - - Assert.assertEquals(LinphoneCall.State.StreamsRunning, call.getState()); + + waitForCallState(call, LinphoneCall.State.StreamsRunning); } } diff --git a/tests/src/org/linphone/test/History.java b/tests/src/org/linphone/test/History.java index b2cc2f415..5a45d545d 100644 --- a/tests/src/org/linphone/test/History.java +++ b/tests/src/org/linphone/test/History.java @@ -44,7 +44,7 @@ public class History extends SampleTest { solo.sleep(2000); Assert.assertEquals(1, LinphoneTestManager.getLc().getCallsNb()); - Assert.assertEquals(LinphoneCall.State.StreamsRunning, LinphoneTestManager.getLc().getCalls()[0].getState()); + waitForCallState(LinphoneTestManager.getLc().getCalls()[0],LinphoneCall.State.StreamsRunning); solo.clickOnView(solo.getView(org.linphone.R.id.hangUp)); solo.waitForActivity("LinphoneActivity", 5000); diff --git a/tests/src/org/linphone/test/SampleTest.java b/tests/src/org/linphone/test/SampleTest.java index 308a03c4f..057272681 100644 --- a/tests/src/org/linphone/test/SampleTest.java +++ b/tests/src/org/linphone/test/SampleTest.java @@ -2,6 +2,8 @@ package org.linphone.test; import org.linphone.LinphoneLauncherActivity; import org.linphone.LinphoneManager; +import org.linphone.core.LinphoneCall; +import org.linphone.core.LinphoneCall.State; import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.LinphoneCore.RegistrationState; @@ -9,6 +11,7 @@ import org.linphone.core.LinphoneCore.RegistrationState; import android.content.Context; import android.test.ActivityInstrumentationTestCase2; import android.widget.ListView; +import java.util.List; import com.robotium.solo.Condition; import com.robotium.solo.Solo; @@ -54,11 +57,42 @@ public abstract class SampleTest extends ActivityInstrumentationTestCase2