diff --git a/build.gradle b/build.gradle index 8e6bee13d..b62cfc1e4 100644 --- a/build.gradle +++ b/build.gradle @@ -39,6 +39,8 @@ dependencies { androidTestCompile ('com.android.support.test.espresso:espresso-core:2.2.2') { exclude module: 'support-annotations' } + androidTestCompile group: 'com.jayway.android.robotium', name: 'robotium-solo', version: '5.6.3' + androidTestCompile 'junit:junit:4.12' compile group: 'org.apache.commons', name: 'commons-compress', version: '1.5' if (firebaseEnable()) { compile 'com.google.firebase:firebase-messaging:9.0.0' @@ -148,7 +150,7 @@ android { // Exclude some useless files packagingOptions { - exclude '**//*gdb.*' + exclude '**/*gdb.*' } } diff --git a/src/androidTest/java/org/linphone/AccountAssistant.java b/src/androidTest/java/org/linphone/AccountAssistant.java deleted file mode 100644 index 45d32fcd9..000000000 --- a/src/androidTest/java/org/linphone/AccountAssistant.java +++ /dev/null @@ -1,445 +0,0 @@ -package org.linphone; - -import android.support.test.espresso.ViewInteraction; -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.test.suitebuilder.annotation.LargeTest; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; - -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.hamcrest.Matchers; -import org.hamcrest.TypeSafeMatcher; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.Assert; -import org.junit.runner.RunWith; -import org.linphone.core.LinphoneCore; -import org.linphone.core.LinphoneProxyConfig; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.Espresso.pressBack; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; -import static android.support.test.espresso.action.ViewActions.replaceText; -import static android.support.test.espresso.action.ViewActions.scrollTo; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isClickable; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withParent; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; -import static org.linphone.Utils.waitUi; - -/** - * Created by ecroze on 04/05/17. - */ -@LargeTest -@RunWith(AndroidJUnit4.class) -public class AccountAssistant { - - @Rule - public ActivityTestRule mActivityTestRule = new ActivityTestRule<>(LinphoneLauncherActivity.class); - - @Before - public void launchActivity() { - waitUi(2000); - if (!LinphoneActivity.isInstanciated()) - pressBack(); - } - - @Test - public void LoginLinphone() { - - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.assistant)), - childAtPosition( - withId(R.id.item_list), - 0), - isDisplayed())).perform(click()); - - ViewInteraction button = onView( - Matchers.allOf(withId(R.id.login_linphone), - withText(LinphoneActivity.instance().getString(R.string.assistant_login_linphone)))); - button.perform(scrollTo(), click()); - - ViewInteraction checkBox = onView( - Matchers.allOf(withId(R.id.use_username))); - checkBox.perform(scrollTo(), click()); - - ViewInteraction editText = onView( - Matchers.allOf(withId(R.id.assistant_username), - withParent(withId(R.id.username_layout)))); - editText.perform(scrollTo(), - replaceText(LinphoneActivity.instance().getString(R.string.account_linphone_login)), - closeSoftKeyboard()); - - ViewInteraction editText2 = onView( - Matchers.allOf(withId(R.id.assistant_password), - withParent(withId(R.id.password_layout)))); - editText2.perform(scrollTo(), - replaceText(LinphoneActivity.instance().getString(R.string.account_linphone_pwd)), - closeSoftKeyboard()); - - ViewInteraction button2 = onView( - Matchers.allOf(withId(R.id.assistant_apply))); - button2.perform(scrollTo(), click()); - - waitUi(5000); - - ViewInteraction textView = onView( - Matchers.allOf(withId(R.id.assistant_skip))); - textView.perform(scrollTo(), click()); - - //Delete account - deleteDefaultAccount(); - } - - @Test - public void LoginLinphoneUnknownAccount() { - - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.assistant)), - childAtPosition( - withId(R.id.item_list), - 0), - isDisplayed())).perform(click()); - - ViewInteraction button = onView( - Matchers.allOf(withId(R.id.login_linphone), - withText(LinphoneActivity.instance().getString(R.string.assistant_login_linphone)))); - button.perform(scrollTo(), click()); - - ViewInteraction checkBox = onView( - Matchers.allOf(withId(R.id.use_username))); - checkBox.perform(scrollTo(), click()); - - ViewInteraction editText = onView( - Matchers.allOf(withId(R.id.assistant_username), - withParent(withId(R.id.username_layout)))); - editText.perform(scrollTo(), - replaceText("BadAccount"), - closeSoftKeyboard()); - - ViewInteraction editText2 = onView( - Matchers.allOf(withId(R.id.assistant_password), - withParent(withId(R.id.password_layout)))); - editText2.perform(scrollTo(), - replaceText("BadPassword"), - closeSoftKeyboard()); - - ViewInteraction button2 = onView( - Matchers.allOf(withId(R.id.assistant_apply))); - button2.perform(scrollTo(), click()); - - waitUi(5000); - - ViewInteraction button3 = onView( - allOf(withId(android.R.id.button3), - withText(LinphoneActivity.instance().getString(R.string.ok)), - isDisplayed())); - button3.perform(click()); - } - - @Test - public void LoginLinphoneBadCredentials() { - - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.assistant)), - childAtPosition( - withId(R.id.item_list), - 0), - isDisplayed())).perform(click()); - - ViewInteraction button = onView( - Matchers.allOf(withId(R.id.login_linphone), - withText(LinphoneActivity.instance().getString(R.string.assistant_login_linphone)))); - button.perform(scrollTo(), click()); - - ViewInteraction checkBox = onView( - Matchers.allOf(withId(R.id.use_username))); - checkBox.perform(scrollTo(), click()); - - ViewInteraction editText = onView( - Matchers.allOf(withId(R.id.assistant_username), - withParent(withId(R.id.username_layout)))); - editText.perform(scrollTo(), - replaceText(LinphoneActivity.instance().getString(R.string.account_linphone_login)), - closeSoftKeyboard()); - - ViewInteraction editText2 = onView( - Matchers.allOf(withId(R.id.assistant_password), - withParent(withId(R.id.password_layout)))); - editText2.perform(scrollTo(), - replaceText("BadPassword"), - closeSoftKeyboard()); - - ViewInteraction button2 = onView( - Matchers.allOf(withId(R.id.assistant_apply))); - button2.perform(scrollTo(), click()); - - waitUi(5000); - - ViewInteraction button3 = onView( - allOf(withId(android.R.id.button2), - withText(LinphoneActivity.instance().getString(R.string.cancel)), - isDisplayed())); - button3.perform(click()); - - deleteDefaultAccount(); - } - - @Test - public void LoginLinphoneWithAccountPreferenceChange() { - - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.assistant)), - childAtPosition( - withId(R.id.item_list), - 0), - isDisplayed())).perform(click()); - - ViewInteraction button = onView( - Matchers.allOf(withId(R.id.login_linphone), - withText(LinphoneActivity.instance().getString(R.string.assistant_login_linphone)))); - button.perform(scrollTo(), click()); - - ViewInteraction checkBox = onView( - Matchers.allOf(withId(R.id.use_username))); - checkBox.perform(scrollTo(), click()); - - ViewInteraction editText = onView( - Matchers.allOf(withId(R.id.assistant_username), - withParent(withId(R.id.username_layout)))); - editText.perform(scrollTo(), - replaceText(LinphoneActivity.instance().getString(R.string.account_linphone_login)), - closeSoftKeyboard()); - - ViewInteraction editText2 = onView( - Matchers.allOf(withId(R.id.assistant_password), - withParent(withId(R.id.password_layout)))); - editText2.perform(scrollTo(), - replaceText("BadPassword"), - closeSoftKeyboard()); - - ViewInteraction button2 = onView( - Matchers.allOf(withId(R.id.assistant_apply))); - button2.perform(scrollTo(), click()); - - waitUi(5000); - - ViewInteraction button3 = onView( - allOf(withId(android.R.id.button1), - withText(LinphoneActivity.instance().getString(R.string.continue_text)), - isDisplayed())); - button3.perform(click()); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.menu_settings)), - childAtPosition( - withId(R.id.item_list), - 1), - isDisplayed())).perform(click()); - - //Go on account preference from settings - ViewInteraction linearLayout = onView( - allOf(childAtPosition( - allOf(withId(android.R.id.list), - withParent(withId(R.id.topLayout))), - 1), - isDisplayed())); - linearLayout.perform(click()); - - pressBack(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - //Directly go on account preference by menu - ViewInteraction relativeLayout = onView( - allOf(withId(R.id.default_account), isDisplayed())); - relativeLayout.perform(click()); - - ViewInteraction linearLayout2 = onView( - allOf(childAtPosition( - allOf(withId(android.R.id.list), - withParent(withId(R.id.topLayout))), - 3), - isDisplayed())); - linearLayout2.perform(click()); - - ViewInteraction editText5 = onView( - allOf(withId(android.R.id.edit))); - editText5.perform(scrollTo(), - replaceText(LinphoneActivity.instance().getString(R.string.account_linphone_pwd)), - closeSoftKeyboard()); - - ViewInteraction button4 = onView( - allOf(withId(android.R.id.button1), - withText(LinphoneActivity.instance().getString(R.string.ok)), - isDisplayed())); - button4.perform(click()); - - pressBack(); - - waitUi(1000); - - //Check if register is ok - LinphoneProxyConfig proxyCfg = LinphoneManager.getLc().getDefaultProxyConfig(); - - Assert.assertEquals((proxyCfg.getState() == LinphoneCore.RegistrationState.RegistrationOk), true); - - deleteDefaultAccount(); - } - - @Test - public void LoginGeneric() { - - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.assistant)), - childAtPosition( - withId(R.id.item_list), - 0), - isDisplayed())).perform(click()); - - ViewInteraction button = onView( - Matchers.allOf(withId(R.id.login_generic), - withText(LinphoneActivity.instance().getString(R.string.assistant_login_generic)))); - button.perform(scrollTo(), click()); - - ViewInteraction button2 = onView( - Matchers.allOf(withId(R.id.assistant_apply))); - - //button2.check(matches(not(isClickable()))); - - ViewInteraction editText = onView( - Matchers.allOf(withId(R.id.assistant_username))); - editText.perform(scrollTo(), - replaceText(LinphoneActivity.instance().getString(R.string.account_linphone_login)), - closeSoftKeyboard()); - - //button2.check(matches(not(isClickable()))); - - ViewInteraction editText2 = onView( - Matchers.allOf(withId(R.id.assistant_password))); - editText2.perform(scrollTo(), - replaceText(LinphoneActivity.instance().getString(R.string.account_linphone_pwd)), - closeSoftKeyboard()); - - //button2.check(matches(not(isClickable()))); - - ViewInteraction editText3 = onView( - Matchers.allOf(withId(R.id.assistant_domain))); - editText3.perform(scrollTo(), - replaceText(LinphoneActivity.instance().getString(R.string.account_linphone_domain)), - closeSoftKeyboard()); - - button2.check(matches(isClickable())); - - ViewInteraction radioButton = onView( - allOf(withId(R.id.transport_tcp), - withText(LinphoneActivity.instance().getString(R.string.pref_transport_tcp)), - withParent(withId(R.id.assistant_transports)))); - radioButton.perform(scrollTo(), click()); - - button2.check(matches(isClickable())); - - ViewInteraction radioButton2 = onView( - allOf(withId(R.id.transport_udp), - withText(LinphoneActivity.instance().getString(R.string.pref_transport_udp)), - withParent(withId(R.id.assistant_transports)))); - radioButton2.perform(scrollTo(), click()); - - button2.check(matches(isClickable())); - - ViewInteraction radioButton3 = onView( - allOf(withId(R.id.transport_tls), - withText(LinphoneActivity.instance().getString(R.string.pref_transport_tls)), - withParent(withId(R.id.assistant_transports)))); - radioButton3.perform(scrollTo(), click()); - - button2.check(matches(isClickable())); - - button2.perform(scrollTo(), click()); - - waitUi(5000); - - ViewInteraction textView = onView( - Matchers.allOf(withId(R.id.assistant_skip))); - textView.perform(scrollTo(), click()); - - //Delete account - deleteDefaultAccount(); - } - - private static Matcher childAtPosition( - final Matcher parentMatcher, final int position) { - - return new TypeSafeMatcher() { - @Override - public void describeTo(Description description) { - description.appendText("Child at position " + position + " in parent "); - parentMatcher.describeTo(description); - } - - @Override - public boolean matchesSafely(View view) { - ViewParent parent = view.getParent(); - return parent instanceof ViewGroup && parentMatcher.matches(parent) - && view.equals(((ViewGroup) parent).getChildAt(position)); - } - }; - } - - private void deleteDefaultAccount() { - LinphoneProxyConfig proxyCfg = LinphoneManager.getLc().getDefaultProxyConfig(); - - if (proxyCfg != null) - LinphoneManager.getLc().removeProxyConfig(proxyCfg); - if (LinphoneManager.getLc().getProxyConfigList().length == 0) - LinphoneManager.getLc().setDefaultProxyConfig(null); - } -} diff --git a/src/androidTest/java/org/linphone/Menu.java b/src/androidTest/java/org/linphone/Menu.java deleted file mode 100644 index 9d3d3a508..000000000 --- a/src/androidTest/java/org/linphone/Menu.java +++ /dev/null @@ -1,263 +0,0 @@ -package org.linphone; - -import android.support.test.rule.ActivityTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.test.suitebuilder.annotation.LargeTest; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; - -import org.hamcrest.Description; -import org.hamcrest.Matcher; -import org.hamcrest.Matchers; -import org.hamcrest.TypeSafeMatcher; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.Espresso.pressBack; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withParent; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.linphone.Utils.waitUi; - -/** - * Created by ecroze on 04/05/17. - */ -@LargeTest -@RunWith(AndroidJUnit4.class) -public class Menu { - - @Rule - public ActivityTestRule mActivityTestRule = new ActivityTestRule<>(LinphoneLauncherActivity.class); - - @Before - public void launchActivity() { - waitUi(2000); - if (!LinphoneActivity.isInstanciated()) - pressBack(); - } - - @Test - public void MenuAudio() { - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.menu_settings)), - childAtPosition( - withId(R.id.item_list), - 1), - isDisplayed())).perform(click()); - - onView(Matchers.allOf( - childAtPosition( - Matchers.allOf( - withId(android.R.id.list), - withParent(withId(R.id.topLayout))), - 4), - isDisplayed())).perform(click()); - - pressBack(); - } - - @Test - public void MenuVideo() { - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.menu_settings)), - childAtPosition( - withId(R.id.item_list), - 1), - isDisplayed())).perform(click()); - - onView(Matchers.allOf( - childAtPosition( - Matchers.allOf( - withId(android.R.id.list), - withParent(withId(R.id.topLayout))), - 5), - isDisplayed())).perform(click()); - - pressBack(); - } - - @Test - public void MenuCall() { - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.menu_settings)), - childAtPosition( - withId(R.id.item_list), - 1), - isDisplayed())).perform(click()); - - onView(Matchers.allOf( - childAtPosition( - Matchers.allOf( - withId(android.R.id.list), - withParent(withId(R.id.topLayout))), - 6), - isDisplayed())).perform(click()); - - pressBack(); - } - - @Test - public void MenuChat() { - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.menu_settings)), - childAtPosition( - withId(R.id.item_list), - 1), - isDisplayed())).perform(click()); - - onView(Matchers.allOf( - childAtPosition( - Matchers.allOf( - withId(android.R.id.list), - withParent(withId(R.id.topLayout))), - 7), - isDisplayed())).perform(click()); - - pressBack(); - } - - @Test - public void MenuNetwork() { - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.menu_settings)), - childAtPosition( - withId(R.id.item_list), - 1), - isDisplayed())).perform(click()); - - onView(Matchers.allOf( - childAtPosition( - Matchers.allOf( - withId(android.R.id.list), - withParent(withId(R.id.topLayout))), - 8), - isDisplayed())).perform(click()); - - pressBack(); - } - - @Test - public void MenuAdvanced() { - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.menu_settings)), - childAtPosition( - withId(R.id.item_list), - 1), - isDisplayed())).perform(click()); - - onView(Matchers.allOf( - childAtPosition( - Matchers.allOf( - withId(android.R.id.list), - withParent(withId(R.id.topLayout))), - 9), - isDisplayed())).perform(click()); - - pressBack(); - } - - @Test - public void MenuAbout() { - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.about)), - childAtPosition( - withId(R.id.item_list), - 2), - isDisplayed())).perform(click()); - - pressBack(); - } - - @Test - public void MenuAssitant() { - waitUi(2000); - - LinphoneActivity.instance().displayDialer(); - - onView(withId(R.id.side_menu_button)).perform(click()); - - onView(Matchers.allOf( - withId(R.id.item_name), - withText(LinphoneActivity.instance().getString(R.string.assistant)), - childAtPosition( - withId(R.id.item_list), - 0), - isDisplayed())).perform(click()); - - pressBack(); - } - - private static Matcher childAtPosition( - final Matcher parentMatcher, final int position) { - - return new TypeSafeMatcher() { - @Override - public void describeTo(Description description) { - description.appendText("Child at position " + position + " in parent "); - parentMatcher.describeTo(description); - } - - @Override - public boolean matchesSafely(View view) { - ViewParent parent = view.getParent(); - return parent instanceof ViewGroup && parentMatcher.matches(parent) - && view.equals(((ViewGroup) parent).getChildAt(position)); - } - }; - } -} diff --git a/src/androidTest/java/org/linphone/Utils.java b/src/androidTest/java/org/linphone/Utils.java deleted file mode 100644 index 2398e1b14..000000000 --- a/src/androidTest/java/org/linphone/Utils.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.linphone; - -/** - * Created by ecroze on 04/05/17. - */ - -public class Utils { - public static void waitUi(long time) { - try { - Thread.sleep(time); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } -} diff --git a/src/androidTest/org/linphone/AccountAssistant.java b/src/androidTest/org/linphone/AccountAssistant.java new file mode 100644 index 000000000..0c9f6911b --- /dev/null +++ b/src/androidTest/org/linphone/AccountAssistant.java @@ -0,0 +1,180 @@ +package org.linphone; + +import junit.framework.Assert; + +import org.linphone.assistant.AssistantActivity; +import org.linphone.core.LinphoneProxyConfig; +import org.linphone.mediastream.video.capture.hwconf.Hacks; + +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Button; + +/** + * @author Sylvain Berfini + */ +public class AccountAssistant extends SampleTest { + + @SmallTest + @MediumTest + @LargeTest + public void testAWizardDisplayedAfterInstall() { + LinphonePreferences.instance().setXmlrpcUrl("https://sip3.linphone.org:444/inapp.php"); + solo.waitForActivity("AssistantActivity", 3000); + solo.assertCurrentActivity("Expected Assistant Activity", AssistantActivity.class); + } + + @SmallTest + @MediumTest + @LargeTest + public void testBLoginWithLinphoneAccount() { + solo.waitForActivity("AssistantActivity", 3000); + solo.assertCurrentActivity("Expected Assistant Activity", AssistantActivity.class); + + solo.clickOnView(solo.getView(R.id.login_linphone)); + solo.clickOnView(solo.getView(R.id.use_username)); + solo.enterText((EditText) solo.getView(R.id.assistant_username), aContext.getString(R.string.account_linphone_login)); + solo.enterText((EditText) solo.getView(R.id.assistant_password), aContext.getString(R.string.account_linphone_pwd)); + solo.clickOnView(solo.getView(R.id.assistant_apply)); + + solo.clickOnView(solo.getView(R.id.assistant_skip)); + + solo.sleep(1000); + + //Test download openh264 + if (LinphoneManager.getLc().downloadOpenH264Enabled()) { + Assert.assertTrue(solo.searchText(aContext.getString(R.string.assistant_codec_down_question))); + solo.clickOnView(solo.getView(R.id.answerNo)); + } + + solo.waitForActivity("LinphoneActivity", 8000); + Assert.assertTrue(solo.searchText(aContext.getString(R.string.account_linphone_login) + "@sip.linphone.org")); + + solo.sleep(3000); //Wait for registration to be done + LinphoneProxyConfig[] proxyConfigs = LinphoneManager.getLc().getProxyConfigList(); + Assert.assertEquals(1, proxyConfigs.length); + LinphoneProxyConfig proxyConfig = proxyConfigs[0]; + waitForRegistration(proxyConfig); + + //Check the wizard added sip.linphone.org custom settings + LinphonePreferences prefs = LinphonePreferences.instance(); + String stunServer = prefs.getStunServer(); + Assert.assertEquals(aContext.getString(R.string.default_stun), stunServer); + + String transport = prefs.getAccountTransportKey(0); + Assert.assertEquals(aContext.getString(R.string.pref_transport_tls_key), transport); + + String proxy = prefs.getAccountProxy(0); + Assert.assertEquals("", proxy); + + String username = prefs.getAccountUsername(0); + Assert.assertEquals(aContext.getString(R.string.account_linphone_login), username); + + boolean ice = prefs.isIceEnabled(); + Assert.assertEquals(ice, true); + } + + @LargeTest + public void testCWizardDoesntShowWhenAccountIsConfigured() { + solo.waitForActivity("LinphoneActivity", 2000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @LargeTest + public void testDLoginWithGenericAccount() { + startAssistant(); + + solo.clickOnView(solo.getView(R.id.login_generic)); + solo.enterText((EditText) solo.getView(R.id.assistant_username), aContext.getString(R.string.account_generic_login)); + solo.enterText((EditText) solo.getView(R.id.assistant_password), aContext.getString(R.string.account_generic_pwd)); + solo.enterText((EditText) solo.getView(R.id.assistant_domain), aContext.getString(R.string.account_generic_domain)); + solo.clickOnView(solo.getView(R.id.assistant_apply)); + + if (!Hacks.hasBuiltInEchoCanceller()) + solo.waitForActivity("LinphoneActivity", 8000); + else + solo.waitForActivity("LinphoneActivity", 2000); + Assert.assertTrue(solo.searchText(aContext.getString(R.string.account_generic_login) + "@" + aContext.getString(R.string.account_generic_domain))); + + solo.sleep(3000); //Wait for registration to be done + LinphoneProxyConfig[] proxyConfigs = LinphoneManager.getLc().getProxyConfigList(); + Assert.assertEquals(proxyConfigs.length, 2); + LinphoneProxyConfig proxyConfig = proxyConfigs[1]; + waitForRegistration(proxyConfig); + } + + @LargeTest + public void testECreateNewAccount() { + startAssistant(); + + solo.clickOnView(solo.getView(R.id.create_account)); + + solo.enterText((EditText) solo.getView(R.id.username), iContext.getString(R.string.account_create_login).substring(0, 2)); + solo.sleep(200); + TextView error = (TextView) solo.getView(R.id.username_error); + int sleepingTime = 1500; + Button createAccount = (Button) solo.getView(R.id.assistant_create); + + Assert.assertEquals(error.getText(), aContext.getString(R.string.wizard_username_incorrect)); + Assert.assertFalse(createAccount.isEnabled()); + + solo.clearEditText((EditText) solo.getView(R.id.username)); + solo.enterText((EditText) solo.getView(R.id.username), iContext.getString(R.string.account_linphone_login)); + solo.sleep(sleepingTime * 2); + Assert.assertEquals(error.getText(), aContext.getString(R.string.wizard_username_unavailable)); + Assert.assertFalse(createAccount.isEnabled()); + + solo.enterText((EditText) solo.getView(R.id.password), iContext.getString(R.string.account_create_pwd).substring(0, 2)); + solo.sleep(sleepingTime); + error = (TextView) solo.getView(R.id.confirm_password_error); + Assert.assertEquals(error.getText(), aContext.getString(R.string.wizard_passwords_unmatched)); + Assert.assertFalse(createAccount.isEnabled()); + + solo.clearEditText((EditText) solo.getView(R.id.password)); + solo.enterText((EditText) solo.getView(R.id.password), iContext.getString(R.string.account_create_pwd).substring(0, 2)); + solo.enterText((EditText) solo.getView(R.id.confirm_password), iContext.getString(R.string.account_create_pwd).substring(0,2)); + solo.sleep(sleepingTime); + error = (TextView) solo.getView(R.id.password_error); + Assert.assertEquals(error.getText(), aContext.getString(R.string.wizard_password_incorrect)); + Assert.assertFalse(createAccount.isEnabled()); + + solo.enterText((EditText) solo.getView(R.id.email), iContext.getString(R.string.account_create_email).substring(0, 12)); + solo.sleep(sleepingTime); + error = (TextView) solo.getView(R.id.email_error); + Assert.assertEquals(error.getText(), aContext.getString(R.string.wizard_email_incorrect)); + Assert.assertFalse(createAccount.isEnabled()); + + solo.clearEditText((EditText) solo.getView(R.id.username)); + solo.clearEditText((EditText) solo.getView(R.id.password)); + solo.clearEditText((EditText) solo.getView(R.id.confirm_password)); + solo.clearEditText((EditText) solo.getView(R.id.email)); + solo.enterText((EditText) solo.getView(R.id.username), iContext.getString(R.string.account_create_login)); + solo.enterText((EditText) solo.getView(R.id.password), iContext.getString(R.string.account_create_pwd)); + solo.enterText((EditText) solo.getView(R.id.confirm_password), iContext.getString(R.string.account_create_pwd)); + solo.enterText((EditText) solo.getView(R.id.email), iContext.getString(R.string.account_create_email)); + solo.sleep(sleepingTime); + Assert.assertEquals(error.getText(), ""); + Assert.assertTrue(createAccount.isEnabled()); + } + + @LargeTest + public void testFCancelWizard() { + startAssistant(); + solo.clickOnView(solo.getView(R.id.assistant_cancel)); + + solo.waitForActivity("LinphoneActivity", 2000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + private void startAssistant() { + solo.waitForActivity("LinphoneActivity", 2000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + solo.clickOnView(solo.getView(R.id.side_menu_button)); + solo.clickOnText(aContext.getString(R.string.menu_assistant)); + } +} diff --git a/src/androidTest/org/linphone/AccountManagement.java b/src/androidTest/org/linphone/AccountManagement.java new file mode 100644 index 000000000..b87a2f2f0 --- /dev/null +++ b/src/androidTest/org/linphone/AccountManagement.java @@ -0,0 +1,86 @@ +package org.linphone; + +import junit.framework.Assert; + +import org.linphone.FragmentsAvailable; +import org.linphone.LinphoneActivity; +import org.linphone.LinphoneManager; +import org.linphone.LinphonePreferences; +import org.linphone.core.LinphoneProxyConfig; + +import android.test.suitebuilder.annotation.LargeTest; +/** + * @author Sylvain Berfini + */ +public class AccountManagement extends SampleTest { + + @LargeTest + public void testAEditAccount() { + goToSettings(); + solo.clickOnText(iContext.getString(R.string.account_generic_login) + "@" + iContext.getString(R.string.account_generic_domain)); + solo.clickOnText(aContext.getString(R.string.pref_username)); + solo.enterText(0, "new"); + + solo.clickOnView(solo.getView(android.R.id.button1)); + + solo.goBack(); + solo.goBack(); + solo.waitForFragmentByTag(FragmentsAvailable.DIALER.toString(), 2000); + + LinphoneProxyConfig[] proxyConfigs = LinphoneManager.getLc().getProxyConfigList(); + LinphoneProxyConfig proxyConfig = proxyConfigs[0]; + waitForRegistration(proxyConfig); + Assert.assertEquals(proxyConfigs.length, 2); + proxyConfig = proxyConfigs[1]; + waitForRegistration(proxyConfig); + Assert.assertTrue(proxyConfig.getIdentity(), proxyConfig.getIdentity().contains("new")); + } + + @LargeTest + public void testBDeleteAccount() { + goToSettings(); + solo.clickOnText(iContext.getString(R.string.account_generic_login) + "new"); + selectItemInListOnUIThread(16); + solo.clickLongOnText(aContext.getString(R.string.pref_delete_account)); + + solo.goBack(); + solo.goBack(); + + LinphoneProxyConfig[] proxyConfigs = LinphoneManager.getLc().getProxyConfigList(); + Assert.assertEquals(1, proxyConfigs.length); + } + + @LargeTest + public void testCDisableAccount() { + goToSettings(); + solo.clickOnText(iContext.getString(R.string.account_linphone_login)); + selectItemInListOnUIThread(14); + solo.clickLongOnText(aContext.getString(R.string.pref_disable_account)); + + solo.goBack(); + solo.goBack(); + + Assert.assertFalse(LinphonePreferences.instance().isAccountEnabled(0)); + } + + @LargeTest + public void testDEnableAccount() { + goToSettings(); + solo.clickOnText(iContext.getString(R.string.account_linphone_login)); + selectItemInListOnUIThread(14); + solo.clickLongOnText(aContext.getString(R.string.pref_disable_account)); + + solo.goBack(); + solo.goBack(); + + Assert.assertTrue(LinphonePreferences.instance().isAccountEnabled(0)); + } + + private void goToSettings() { + solo.waitForActivity("LinphoneActivity", 2000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + solo.clickOnView(solo.getView(R.id.side_menu_button)); + solo.clickOnText("Settings"); + } +} diff --git a/src/androidTest/org/linphone/AinitTestEnv.java b/src/androidTest/org/linphone/AinitTestEnv.java new file mode 100644 index 000000000..1ec9a6dfc --- /dev/null +++ b/src/androidTest/org/linphone/AinitTestEnv.java @@ -0,0 +1,24 @@ +package org.linphone; + +import junit.framework.Assert; + +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; + +/** + * @author Sylvain Berfini + */ +public class AinitTestEnv extends SampleTest { + + @SmallTest + @MediumTest + @LargeTest + public void testAInitLinphoneCore() { + LinphoneTestManager.createAndStart(aContext, iContext, 1); + + solo.sleep(5000); + Assert.assertEquals(1, LinphoneTestManager.getLc().getProxyConfigList().length); + waitForRegistration(LinphoneTestManager.getLc().getProxyConfigList()[0]); + } +} diff --git a/src/androidTest/org/linphone/CallsAudio.java b/src/androidTest/org/linphone/CallsAudio.java new file mode 100644 index 000000000..f65d9e0d4 --- /dev/null +++ b/src/androidTest/org/linphone/CallsAudio.java @@ -0,0 +1,486 @@ +package org.linphone; + +import junit.framework.Assert; + +import org.linphone.CallActivity; +import org.linphone.CallIncomingActivity; +import org.linphone.CallOutgoingActivity; +import org.linphone.LinphoneActivity; +import org.linphone.LinphoneManager; +import org.linphone.core.LinphoneCall; +import org.linphone.core.LinphoneCore; +import org.linphone.core.LinphoneCoreException; +import org.linphone.core.PayloadType; + +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; +import android.util.DisplayMetrics; +import android.view.View; + +/** + * @author Sylvain Berfini + */ +public class CallsAudio extends SampleTest { + + @SmallTest + @MediumTest + @LargeTest + public void testAInit() { + //Disable video + goToSettings(); + + selectItemInListOnUIThread(3); + solo.clickOnText(aContext.getString(R.string.pref_video_title)); + solo.clickOnText(aContext.getString(R.string.pref_video_enable_title)); + solo.sleep(500); + + solo.goBack(); + solo.sleep(1000); + Assert.assertFalse(LinphoneManager.getLc().isVideoEnabled()); + } + + @SmallTest + @MediumTest + @LargeTest + public void testBOutgoingCallWithDefaultConfig() { + LinphoneTestManager.getInstance().declineCall = false; // Just in case + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertOutgoingCallIsCorrectlyRunning(); + assertCallIsCorrectlyRunning(); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testCDTMFRFC2833InPCMUCall() { + disableAllEnabledAudioCodecs(); + solo.clickOnText("PCMU"); + goBackToDialerAfterCodecChanges(); + solo.sleep(1000); + + LinphoneManager.getLc().setUseRfc2833ForDtmfs(true); + LinphoneManager.getLc().setUseSipInfoForDtmfs(false); + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(); + + solo.clickOnView(solo.getView(R.id.dialer)); + solo.clickOnView(solo.getView(R.id.Digit3)); + solo.clickOnView(solo.getView(R.id.dialer)); + + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.hang_up)); + + //To enable when issue http://git.linphone.org/mantis/view.php?id=750 will be fixed + //Assert.assertTrue(LinphoneTestManager.getInstance().isDTMFReceived); + LinphoneTestManager.getInstance().isDTMFReceived = false; + + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testDDTMFSIPINFO() { + LinphoneManager.getLc().setUseRfc2833ForDtmfs(false); + LinphoneManager.getLc().setUseSipInfoForDtmfs(true); + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(); + + solo.clickOnView(solo.getView(R.id.dialer)); + solo.clickOnView(solo.getView(R.id.Digit3)); + solo.clickOnView(solo.getView(R.id.dialer)); + + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.hang_up)); + + //To enable when issue http://git.linphone.org/mantis/view.php?id=751 will be fixed + //Assert.assertTrue(LinphoneTestManager.getInstance().isDTMFReceived); + LinphoneTestManager.getInstance().isDTMFReceived = false; + + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testEOutgoingCallToAudioClient() { + LinphoneTestManager.getLc().enableVideo(false, false); + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + solo.waitForActivity("CallOutgoingActivity", 2000); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testFOutgoingCallToVideoClient() { + LinphoneTestManager.getLc().enableVideo(true, true); + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + solo.waitForActivity("CallOutgoingActivity", 5000); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testGOutgoingCallCancelled() { + LinphoneTestManager.getInstance().autoAnswer = false; + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + solo.waitForActivity("CallOutgoingActivity", 200); + solo.assertCurrentActivity("Expected InCall Activity", CallOutgoingActivity.class); + + solo.sleep(2000); + waitForCallState(LinphoneManager.getLc().getCalls()[0],LinphoneCall.State.OutgoingRinging); + + LinphoneTestManager.getInstance().autoAnswer = true; + + solo.clickOnView(solo.getView(R.id.outgoing_hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testHOutgoingCallDeclined() { + LinphoneTestManager.getInstance().autoAnswer = true; // Just in case + LinphoneTestManager.getInstance().declineCall = true; + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + solo.sleep(1500); + Assert.assertTrue(solo.searchText(aContext.getString(R.string.error_call_declined))); + + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + LinphoneTestManager.getInstance().declineCall = false; + } + + @SmallTest + @MediumTest + @LargeTest + public void testIIncomingAudioCall() { + LinphoneTestManager.getInstance().declineCall = false; // Just in case + LinphoneTestManager.getLc().enableVideo(false, false); + + solo.sleep(2000); + try { + LinphoneTestManager.getLc().invite("sip:" + iContext.getString(R.string.account_linphone_login) + "@" + iContext.getString(R.string.account_linphone_domain)); + } catch (LinphoneCoreException e) { + e.printStackTrace(); + } + + solo.waitForActivity("CallIncomingActivity", 2000); + solo.assertCurrentActivity("Expected Incoming Call Activity", CallIncomingActivity.class); + + solo.sleep(1000); + /*View topLayout = solo.getView(R.id.topLayout); + int topLayoutHeigh = topLayout.getMeasuredHeight(); + DisplayMetrics dm = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); + int topOffset = dm.heightPixels - topLayoutHeigh; + int slidersTop = topLayoutHeigh - 80 - topOffset; // 80 is the bottom margin set in incoming.xml + solo.drag(10, topLayout.getMeasuredWidth() - 10, slidersTop, slidersTop, 10);*/ + + solo.clickOnView(solo.getView(R.id.accept)); + + assertCallIsCorrectlyRunning(); + } + + @LargeTest + public void testJIncomingVideoCall() { + LinphoneTestManager.getLc().enableVideo(true, true); + + solo.sleep(2000); + try { + LinphoneTestManager.getLc().invite("sip:" + iContext.getString(R.string.account_linphone_login) + "@" + iContext.getString(R.string.account_linphone_domain)); + } catch (LinphoneCoreException e) { + e.printStackTrace(); + } + + solo.waitForActivity("CallIncomingActivity", 5000); + solo.assertCurrentActivity("Expected Incoming Call Activity", CallIncomingActivity.class); + + /*solo.sleep(1000); + View topLayout = solo.getView(R.id.topLayout); + int topLayoutHeigh = topLayout.getMeasuredHeight(); + DisplayMetrics dm = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); + int topOffset = dm.heightPixels - topLayoutHeigh; + int slidersTop = topLayoutHeigh - 80 - topOffset; // 80 is the bottom margin set in incoming.xml + solo.drag(10, topLayout.getMeasuredWidth() - 10, slidersTop, slidersTop, 10);*/ + + solo.clickOnView(solo.getView(R.id.accept)); + + assertCallIsCorrectlyRunning(); + } + + @MediumTest + @LargeTest + public void testKSelfPauseResumeCall() { + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(); + + solo.clickOnView(solo.getView(R.id.pause)); + solo.sleep(1000); + + waitForCallPaused(LinphoneManager.getLc().getCalls()[0]); + + solo.clickOnView(solo.getView(R.id.call_pause)); + solo.sleep(1000); + + waitForCallResumed(LinphoneManager.getLc().getCalls()[0]); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testLRemotePauseResumeCall() { + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(); + + LinphoneTestManager.getLc().pauseAllCalls(); + solo.sleep(1000); + + waitForCallState(LinphoneManager.getLc().getCalls()[0], LinphoneCall.State.PausedByRemote); + + LinphoneTestManager.getLc().resumeCall(LinphoneTestManager.getLc().getCalls()[0]); + solo.sleep(1000); + + waitForCallResumed(LinphoneManager.getLc().getCalls()[0]); + + solo.clickLongOnScreen(200, 200); //To ensure controls are shown + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @LargeTest + public void testMSwitchOnVideoInCallIsNotAllowed() { + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(); + + Assert.assertFalse(solo.getView(R.id.video).isEnabled()); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @LargeTest + public void testNDeclineIncomingCall() { + LinphoneTestManager.getInstance().declineCall = false; // Just in case + LinphoneTestManager.getLc().enableVideo(false, false); + + solo.sleep(2000); + try { + LinphoneTestManager.getLc().invite("sip:" + iContext.getString(R.string.account_linphone_login) + "@" + iContext.getString(R.string.account_linphone_domain)); + } catch (LinphoneCoreException e) { + e.printStackTrace(); + } + + solo.waitForActivity("CallIncomingActivity", 5000); + solo.assertCurrentActivity("Expected Incoming Call Activity", CallIncomingActivity.class); + + solo.sleep(1000); + View topLayout = solo.getView(R.id.topLayout); + int topLayoutHeigh = topLayout.getMeasuredHeight(); + DisplayMetrics dm = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); + int topOffset = dm.heightPixels - topLayoutHeigh; + int slidersTop = topLayoutHeigh - 80 - topOffset; // 80 is the bottom margin set in incoming.xml + solo.drag(topLayout.getMeasuredWidth() - 10, 10, slidersTop, slidersTop, 10); + } + + @MediumTest + @LargeTest + public void testOCancelledIncomingCall() { + LinphoneTestManager.getInstance().declineCall = false; // Just in case + LinphoneTestManager.getLc().enableVideo(false, false); + + solo.sleep(2000); + try { + LinphoneTestManager.getLc().invite("sip:" + iContext.getString(R.string.account_linphone_login) + "@" + iContext.getString(R.string.account_linphone_domain)); + } catch (LinphoneCoreException e) { + e.printStackTrace(); + } + + solo.waitForActivity("CallIncomingActivity", 5000); + solo.assertCurrentActivity("Expected Incoming Call Activity", CallIncomingActivity.class); + + LinphoneTestManager.getLc().terminateAllCalls(); + + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testPDisplayMissedCallsNumber() { + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + Assert.assertTrue(solo.searchText("1")); + } + + //TODO: Test each audio codec + + private void assertOutgoingCallIsCorrectlyRunning() { + solo.waitForActivity("CallOutgoingActivity", 2000); + solo.assertCurrentActivity("Expected OutgoingCall Activity", CallOutgoingActivity.class); + + LinphoneCall call = LinphoneManager.getLc().getCalls()[0]; + waitForCallState(call, LinphoneCall.State.OutgoingProgress); + } + + private void assertCallIsCorrectlyRunning() { + solo.waitForActivity("CallActivity", 5000); + solo.assertCurrentActivity("Expected InCall Activity", CallActivity.class); + + LinphoneCall call = LinphoneManager.getLc().getCalls()[0]; + waitForCallState(call, LinphoneCall.State.StreamsRunning); + } + + private void goToSettings() { + solo.waitForActivity("LinphoneActivity", 2000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + solo.clickOnView(solo.getView(R.id.side_menu_button)); + solo.clickOnText(aContext.getString(R.string.menu_settings)); + } + + private void goToAudioCodecsSettings() { + goToSettings(); + + selectItemInListOnUIThread(4); + solo.clickOnText(aContext.getString(R.string.pref_audio_title)); + solo.sleep(500); + } + + private boolean isAudioCodecEnabled(String mime, int rate) { + LinphoneCore lc = LinphoneTestManager.getLc(); + for (final PayloadType pt : lc.getAudioCodecs()) { + if (pt.getMime().equals(mime) && pt.getRate() == rate) + return lc.isPayloadTypeEnabled(pt); + } + return false; + } + + private void disableAllEnabledAudioCodecs() { + goToAudioCodecsSettings(); + + if (isAudioCodecEnabled("opus", 48000)) { + solo.clickOnText("opus"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("speex", 16000)) { + solo.clickOnText("speex"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("speex", 8000)) { + solo.clickOnText("speex", 1); + solo.sleep(500); + } + + if (isAudioCodecEnabled("iLBC", 8000)) { + solo.clickOnText("iLBC"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("AMR", 8000)) { + solo.clickOnText("AMR"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("AMRWB", 8000)) { + solo.clickOnText("AMRWB"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("G729", 8000)) { + solo.clickOnText("G729"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("GSM", 8000)) { + solo.clickOnText("GSM"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("G722", 8000)) { + solo.clickOnText("G722"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("SILK", 24000)) { + solo.clickOnText("SILK"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("SILK", 16000)) { + solo.clickOnText("SILK", 1); + solo.sleep(500); + } + + if (isAudioCodecEnabled("SILK", 8000)) { + solo.clickOnText("SILK", 2); + solo.sleep(500); + } + + if (isAudioCodecEnabled("PCMU", 8000)) { + solo.clickOnText("PCMU"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("PCMA", 8000)) { + solo.clickOnText("PCMA"); + solo.sleep(500); + } + } + + private void goBackToDialerAfterCodecChanges() { + solo.goBack(); + solo.goBack(); + + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } +} diff --git a/src/androidTest/org/linphone/CallsVideo.java b/src/androidTest/org/linphone/CallsVideo.java new file mode 100644 index 000000000..13da8c4cd --- /dev/null +++ b/src/androidTest/org/linphone/CallsVideo.java @@ -0,0 +1,569 @@ +package org.linphone; + +import junit.framework.Assert; + +import org.linphone.CallActivity; +import org.linphone.CallIncomingActivity; +import org.linphone.CallOutgoingActivity; +import org.linphone.LinphoneActivity; +import org.linphone.LinphoneManager; +import org.linphone.core.LinphoneCall; +import org.linphone.mediastream.Log; +import org.linphone.core.LinphoneCore; +import org.linphone.core.LinphoneCoreException; +import org.linphone.core.PayloadType; + +import android.test.suitebuilder.annotation.SmallTest; +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.util.DisplayMetrics; +import android.view.View; + +/** + * @author Sylvain Berfini + */ +public class CallsVideo extends SampleTest { + + @SmallTest + @MediumTest + @LargeTest + public void testAInit() { + //Enable video + goToSettings(); + + // enable auto accept and auto share video + goToVideoCodecsSettings(); + solo.sleep(500); + solo.clickOnText(aContext.getString(R.string.pref_video_enable_title)); + solo.clickOnText(aContext.getString(R.string.pref_video_initiate_call_with_video_title)); + solo.clickOnText(aContext.getString(R.string.pref_video_automatically_accept_video_title)); + solo.sleep(500); + solo.goBack(); + + solo.goBack(); + solo.sleep(1000); + Assert.assertTrue(LinphoneManager.getLc().isVideoEnabled()); + Assert.assertTrue(LinphoneManager.getLc().getVideoAutoAcceptPolicy()); + Assert.assertTrue(LinphoneManager.getLc().getVideoAutoInitiatePolicy()); + } + + @SmallTest + @MediumTest + @LargeTest + public void testBOutgoingCallWithDefaultConfig() { + LinphoneTestManager.getInstance().declineCall = false; // Just in case + LinphoneTestManager.getLc().enableVideo(true, true); + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertOutgoingCallIsCorrectlyRunning(); + assertCallIsCorrectlyRunning(); + assertCallIsRunningWithVideo(); + + solo.clickOnView(solo.getView(R.id.video_frame)); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testCDTMFRFC2833InPCMUCall() { + disableAllEnabledAudioCodecs(); + solo.clickOnText("PCMU"); + goBackToDialerAfterCodecChanges(); + solo.sleep(1000); + + LinphoneManager.getLc().setUseRfc2833ForDtmfs(true); + LinphoneManager.getLc().setUseSipInfoForDtmfs(false); + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(); + + solo.clickOnView(solo.getView(R.id.dialer)); + solo.clickOnView(solo.getView(R.id.Digit3)); + solo.clickOnView(solo.getView(R.id.dialer)); + + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.hang_up)); + + //To enable when issue http://git.linphone.org/mantis/view.php?id=750 will be fixed + //Assert.assertTrue(LinphoneTestManager.getInstance().isDTMFReceived); + LinphoneTestManager.getInstance().isDTMFReceived = false; + + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testDDTMFSIPINFO() { + LinphoneManager.getLc().setUseRfc2833ForDtmfs(false); + LinphoneManager.getLc().setUseSipInfoForDtmfs(true); + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(); + + solo.clickOnView(solo.getView(R.id.dialer)); + solo.clickOnView(solo.getView(R.id.Digit3)); + solo.clickOnView(solo.getView(R.id.dialer)); + + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.hang_up)); + + //To enable when issue http://git.linphone.org/mantis/view.php?id=751 will be fixed + //Assert.assertTrue(LinphoneTestManager.getInstance().isDTMFReceived); + LinphoneTestManager.getInstance().isDTMFReceived = false; + + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testEOutgoingCallToAudioClient() { + LinphoneTestManager.getLc().enableVideo(false, false); + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertOutgoingCallIsCorrectlyRunning(); + assertCallIsCorrectlyRunning(); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testFOutgoingCallToVideoClient() { + LinphoneTestManager.getLc().enableVideo(true, true); + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertOutgoingCallIsCorrectlyRunning(); + assertCallIsCorrectlyRunning(); + assertCallIsRunningWithVideo(); + + solo.clickOnView(solo.getView(R.id.video_frame)); + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testGOutgoingCallCancelled() { + LinphoneTestManager.getInstance().autoAnswer = false; + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + solo.waitForActivity("InCallActivity", 5000); + solo.assertCurrentActivity("Expected InCall Activity", CallActivity.class); + + solo.sleep(2000); + waitForCallState(LinphoneManager.getLc().getCalls()[0],LinphoneCall.State.OutgoingRinging); + + LinphoneTestManager.getInstance().autoAnswer = true; + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @LargeTest + public void testHOutgoingCallDeclined() { + LinphoneTestManager.getInstance().autoAnswer = true; // Just in case + LinphoneTestManager.getInstance().declineCall = true; + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + solo.sleep(1500); + Assert.assertTrue(solo.searchText(aContext.getString(R.string.error_call_declined))); + + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + LinphoneTestManager.getInstance().declineCall = false; + } + + @LargeTest + public void testIIncomingAudioCall() { + LinphoneTestManager.getInstance().declineCall = false; // Just in case + LinphoneTestManager.getLc().enableVideo(false, false); + + solo.sleep(2000); + try { + LinphoneTestManager.getLc().invite("sip:" + iContext.getString(R.string.account_linphone_login) + "@" + iContext.getString(R.string.account_linphone_domain)); + } catch (LinphoneCoreException e) { + e.printStackTrace(); + } + + solo.waitForActivity("IncomingCallActivity", 5000); + solo.assertCurrentActivity("Expected Incoming Call Activity", CallIncomingActivity.class); + + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.accept)); + + assertCallIsCorrectlyRunning(); + } + + @SmallTest + @MediumTest + @LargeTest + public void testJIncomingVideoCall() { + LinphoneTestManager.getLc().enableVideo(true, true); + + solo.sleep(2000); + try { + LinphoneTestManager.getLc().invite("sip:" + iContext.getString(R.string.account_linphone_login) + "@" + iContext.getString(R.string.account_linphone_domain)); + } catch (LinphoneCoreException e) { + e.printStackTrace(); + } + + solo.waitForActivity("IncomingCallActivity", 5000); + solo.assertCurrentActivity("Expected Incoming Call Activity", CallIncomingActivity.class); + + solo.clickOnView(solo.getView(R.id.accept)); + + assertCallIsCorrectlyRunning(); + assertCallIsRunningWithVideo(); + } + +// @SmallTest +// @MediumTest +// @LargeTest +// public void testJIncommingCallWithCallPlayer() throws InterruptedException { +// testJIncomingVideoCall(); +// Thread.sleep(2000); +// callPlayerTest(); +// } + + //TODO: Test each video codec + + @MediumTest + @LargeTest + public void testKSelfPauseResumeCall() { + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(); + + solo.clickOnView(solo.getView(R.id.video_frame)); + solo.clickOnView(solo.getView(R.id.pause)); + solo.sleep(1000); + + waitForCallPaused(LinphoneManager.getLc().getCalls()[0]); + solo.clickOnView(solo.getView(R.id.video_frame)); + solo.clickOnView(solo.getView(R.id.call_pause)); + solo.sleep(1000); + + waitForCallResumed(LinphoneManager.getLc().getCalls()[0]); + + solo.clickOnView(solo.getView(R.id.video_frame)); + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testLRemotePauseResumeCall() { + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(); + + LinphoneTestManager.getLc().pauseAllCalls(); + solo.sleep(1000); + + waitForCallState(LinphoneManager.getLc().getCalls()[0], LinphoneCall.State.PausedByRemote); + solo.clickOnView(solo.getView(R.id.video_frame)); + LinphoneTestManager.getLc().resumeCall(LinphoneTestManager.getLc().getCalls()[0]); + solo.sleep(1000); + + waitForCallResumed(LinphoneManager.getLc().getCalls()[0]); + + solo.clickOnView(solo.getView(R.id.video_frame)); + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testMSwitchOffVideoInCall() { + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(); + assertCallIsRunningWithVideo(); + + Assert.assertTrue(solo.getView(R.id.video).isEnabled()); + solo.clickOnView(solo.getView(R.id.video_frame)); + solo.clickOnView(solo.getView(R.id.video)); + solo.sleep(1000); + Assert.assertFalse(LinphoneManager.getLc().getCurrentCall().getCurrentParamsCopy().getVideoEnabled()); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + private void assertCallIsRunningWithVideo() { + LinphoneCall call = LinphoneManager.getLc().getCalls()[0]; + Assert.assertTrue(call.getCurrentParamsCopy().getVideoEnabled()); + } + private void assertOutgoingCallIsCorrectlyRunning() { + solo.waitForActivity("CallOutgoingActivity", 2000); + solo.assertCurrentActivity("Expected OutgoingCall Activity", CallOutgoingActivity.class); + + LinphoneCall call = LinphoneManager.getLc().getCalls()[0]; + + waitForCallState(call, LinphoneCall.State.OutgoingProgress); + } + + private void assertCallIsCorrectlyRunning() { + solo.waitForActivity("CallActivity", 2000); + solo.assertCurrentActivity("Expected InCall Activity", CallActivity.class); + + LinphoneCall call = LinphoneManager.getLc().getCalls()[0]; + + waitForCallState(call, LinphoneCall.State.StreamsRunning); + } + + private void goToSettings() { + solo.waitForActivity("LinphoneActivity", 2000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + solo.clickOnView(solo.getView(R.id.side_menu_button)); + solo.clickOnText(aContext.getString(R.string.menu_settings)); + } + + private void goToAudioCodecsSettings() { + goToSettings(); + + selectItemInListOnUIThread(4); + solo.clickOnText(aContext.getString(R.string.pref_audio_title)); + solo.sleep(500); + } + + private void goToVideoCodecsSettings() { + //goToSettings(); + + selectItemInListOnUIThread(6); + if (solo.searchText(aContext.getString(R.string.pref_video_title), 2)) // Needed in case pref_video_enable_title contains pref_video + solo.clickOnText(aContext.getString(R.string.pref_video_title), 2); + else + solo.clickOnText(aContext.getString(R.string.pref_video_title)); + solo.sleep(500); + } + + private boolean isAudioCodecEnabled(String mime, int rate) { + LinphoneCore lc = LinphoneTestManager.getLc(); + for (final PayloadType pt : lc.getAudioCodecs()) { + if (pt.getMime().equals(mime) && pt.getRate() == rate) + return lc.isPayloadTypeEnabled(pt); + } + return false; + } + + private void disableAllEnabledAudioCodecs() { + goToAudioCodecsSettings(); + + if (isAudioCodecEnabled("opus", 48000)) { + solo.clickOnText("opus"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("speex", 16000)) { + solo.clickOnText("speex"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("speex", 8000)) { + solo.clickOnText("speex", 1); + solo.sleep(500); + } + + if (isAudioCodecEnabled("iLBC", 8000)) { + solo.clickOnText("iLBC"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("AMR", 8000)) { + solo.clickOnText("AMR"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("AMRWB", 8000)) { + solo.clickOnText("AMRWB"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("G729", 8000)) { + solo.clickOnText("G729"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("GSM", 8000)) { + solo.clickOnText("GSM"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("G722", 8000)) { + solo.clickOnText("G722"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("SILK", 24000)) { + solo.clickOnText("SILK"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("SILK", 16000)) { + solo.clickOnText("SILK", 1); + solo.sleep(500); + } + + if (isAudioCodecEnabled("SILK", 8000)) { + solo.clickOnText("SILK", 2); + solo.sleep(500); + } + + if (isAudioCodecEnabled("PCMU", 8000)) { + solo.clickOnText("PCMU"); + solo.sleep(500); + } + + if (isAudioCodecEnabled("PCMA", 8000)) { + solo.clickOnText("PCMA"); + solo.sleep(500); + } + } + + private boolean isVideoCodecEnabled(String mime) { + LinphoneCore lc = LinphoneTestManager.getLc(); + for (final PayloadType pt : lc.getVideoCodecs()) { + if (pt.getMime().equals(mime)) + return lc.isPayloadTypeEnabled(pt); + } + return false; + } + + private void disableAllEnabledVideoCodecs() { + goToVideoCodecsSettings(); + + if (isVideoCodecEnabled("VP8")) { + solo.clickOnText(aContext.getString(R.string.pref_video_codec_vp8_title)); + solo.sleep(500); + } + + if (isVideoCodecEnabled("H264")) { + solo.clickOnText(aContext.getString(R.string.pref_video_codec_h264_title)); + solo.sleep(500); + } + + if (isVideoCodecEnabled("MP4V-ES")) { + solo.clickOnText(aContext.getString(R.string.pref_video_codec_mpeg4_title)); + solo.sleep(500); + } + } + +// private void forceH264Codec() { +// goToVideoCodecsSettings(); +// +// if (isVideoCodecEnabled("VP8")) { +// solo.clickOnText(aContext.getString(R.string.pref_video_codec_vp8_title)); +// solo.sleep(500); +// } +// +// if (!isVideoCodecEnabled("H264")) { +// solo.clickOnText(aContext.getString(R.string.pref_video_codec_h264_title)); +// solo.sleep(500); +// } +// +// if (isVideoCodecEnabled("MP4V-ES")) { +// solo.clickOnText(aContext.getString(R.string.pref_video_codec_mpeg4_title)); +// solo.sleep(500); +// } +// } + +// private void enableAllDisabledVideoCodecs() { +// goToVideoCodecsSettings(); +// +// if (!isVideoCodecEnabled("VP8")) { +// solo.clickOnText(aContext.getString(R.string.pref_video_codec_vp8_title)); +// solo.sleep(500); +// } +// +// if (!isVideoCodecEnabled("H264")) { +// solo.clickOnText(aContext.getString(R.string.pref_video_codec_h264_title)); +// solo.sleep(500); +// } +// +// if (!isVideoCodecEnabled("MP4V-ES")) { +// solo.clickOnText(aContext.getString(R.string.pref_video_codec_mpeg4_title)); +// solo.sleep(500); +// } +// } + + private void goBackToDialerAfterCodecChanges() + { + solo.goBack(); + solo.goBack(); + + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + +// private void callPlayerTest() throws InterruptedException { +// LinphoneCall call = LinphoneTestManager.getLc().getCurrentCall(); +// Assert.assertNotNull(call); +// if(call == null) return; +// LinphonePlayer player = call.getPlayer(); +// Assert.assertNotNull(player); +// if(player == null) return; +// EofListenerImpl eof = new EofListenerImpl(); +// int openResult = player.open("/storage/sdcard0/Movies/test.mkv", eof); +// Assert.assertEquals(openResult, 0); +// if(openResult == 0) { +// Assert.assertEquals(player.start(), 0); +// try { +// Assert.assertTrue(eof.waitForEof(20000)); +// } catch (InterruptedException e) { +// throw e; +// } finally { +// player.close(); +// } +// } +// } +// +// private class EofListenerImpl implements LinphonePlayer.Listener { +// private boolean mEof = false; +// +// @Override +// public void endOfFile(LinphonePlayer player) { +// mEof = true; +// } +// +// public boolean waitForEof(int timeout) throws InterruptedException { +// final int refreshTime = 100; +// int time = 0; +// while(time < timeout && !mEof) { +// Thread.sleep(refreshTime); +// time += refreshTime; +// } +// return time < timeout; +// } +// } +} diff --git a/src/androidTest/org/linphone/Chat.java b/src/androidTest/org/linphone/Chat.java new file mode 100644 index 000000000..ccb28505d --- /dev/null +++ b/src/androidTest/org/linphone/Chat.java @@ -0,0 +1,149 @@ +package org.linphone; + +import junit.framework.Assert; + +import org.linphone.LinphoneActivity; +import org.linphone.core.LinphoneChatMessage; +import org.linphone.core.LinphoneChatMessage.State; +import org.linphone.core.LinphoneChatRoom; +import org.linphone.mediastream.Log; + +import com.robotium.solo.Solo; + +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; +import android.widget.EditText; +import android.widget.AutoCompleteTextView; + + +/** + * @author Sylvain Berfini + */ +public class Chat extends SampleTest { + + @SmallTest + @MediumTest + @LargeTest + public void testAEmptyChatHistory() { + goToChat(); + + LinphoneChatRoom[] chats = LinphoneTestManager.getInstance().getLc().getChatRooms(); + for (LinphoneChatRoom chatroom : chats) { + chatroom.deleteHistory(); + } + + Assert.assertEquals(0, LinphoneActivity.instance().getUnreadMessageCount()); + } + + @LargeTest + public void testBDisplayEmptyChatHistory() { + goToChat(); + + Assert.assertTrue(solo.searchText(aContext.getString(R.string.no_chat_history))); + } + + @SmallTest + @MediumTest + @LargeTest + public void testCSendTextMessage() { + goToChat(); + + solo.clickOnView(solo.getView(R.id.new_discussion)); + solo.enterText((EditText)solo.getView(R.id.search_contact_field), "sip:" + iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + + solo.enterText((EditText)solo.getView(R.id.message), iContext.getString(R.string.chat_test_text_sent)); + solo.clickOnView(solo.getView(R.id.send_message)); + + solo.sleep(1000); + Assert.assertTrue(solo.searchText(iContext.getString(R.string.chat_test_text_sent))); + Assert.assertEquals(iContext.getString(R.string.chat_test_text_sent), LinphoneTestManager.getInstance().lastMessageReceived); + } + + + @LargeTest + public void testDIsNotEmptyChatHistory() { + goToChat(); + Assert.assertTrue(solo.searchText(iContext.getString(R.string.account_test_calls_login))); + } + + @SmallTest + @MediumTest + @LargeTest + public void testEReceiveTextMessage() { + goToChat(); + solo.clickOnText(iContext.getString(R.string.account_test_calls_login)); + + LinphoneChatRoom chatRoom = LinphoneTestManager.getLc().getOrCreateChatRoom("sip:" + iContext.getString(R.string.account_linphone_login) + "@" + iContext.getString(R.string.account_linphone_domain)); + LinphoneChatMessage msg = chatRoom.createLinphoneChatMessage(iContext.getString(R.string.chat_test_text_received)); + chatRoom.sendMessage(msg, new LinphoneChatMessage.StateListener() { + @Override + public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, + State state) { + Log.e("Chat message state = " + state.toString()); + } + }); + + solo.sleep(1000); + Assert.assertTrue(solo.searchText(iContext.getString(R.string.chat_test_text_received))); + } + + @MediumTest + @LargeTest + public void testFDeleteMessage() { + goToChat(); + solo.clickOnText(iContext.getString(R.string.account_test_calls_login)); + + solo.clickLongOnText(iContext.getString(R.string.chat_test_text_received)); + solo.clickOnText(aContext.getString(R.string.delete)); + + solo.sleep(1000); + Assert.assertFalse(solo.searchText(iContext.getString(R.string.chat_test_text_received))); + } + + @MediumTest + @LargeTest + public void testGChatLandscape() { + goToChat(); + + solo.clickOnText(iContext.getString(R.string.account_test_calls_login)); + + solo.sleep(1000); + solo.setActivityOrientation(Solo.LANDSCAPE); + solo.sleep(1000); + + solo.enterText((EditText) solo.getView(R.id.message), iContext.getString(R.string.chat_test_text_sent)); + solo.clickOnView(solo.getView(R.id.send_message)); + + solo.sleep(1000); + Assert.assertTrue(solo.searchText(iContext.getString(R.string.chat_test_text_sent))); + Assert.assertEquals(iContext.getString(R.string.chat_test_text_sent), LinphoneTestManager.getInstance().lastMessageReceived); + + solo.clickOnView(solo.getView(R.id.back)); + + solo.sleep(1000); + Assert.assertTrue(solo.searchText(iContext.getString(R.string.account_test_calls_login))); + } + + @MediumTest + @LargeTest + public void testHDeleteConversation() { + goToChat(); + + /*solo.clickOnText(aContext.getString(R.string.button_edit)); + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.delete)); + solo.clickOnText(aContext.getString(R.string.button_ok)); + + solo.sleep(1000); + Assert.assertTrue(solo.searchText(aContext.getString(R.string.no_chat_history)));*/ + } + + private void goToChat() { + solo.waitForActivity("LinphoneActivity", 2000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + solo.clickOnView(solo.getView(R.id.chat)); + } + +} diff --git a/src/androidTest/org/linphone/ConferenceAndMultiCall.java b/src/androidTest/org/linphone/ConferenceAndMultiCall.java new file mode 100644 index 000000000..80272ea74 --- /dev/null +++ b/src/androidTest/org/linphone/ConferenceAndMultiCall.java @@ -0,0 +1,298 @@ +package org.linphone; + +import java.util.ArrayList; + +import junit.framework.Assert; + +import org.linphone.CallActivity; +import org.linphone.CallIncomingActivity; +import org.linphone.LinphoneActivity; +import org.linphone.LinphoneManager; +import org.linphone.core.LinphoneCall; +import org.linphone.core.LinphoneCoreException; +import org.linphone.mediastream.Log; + +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; +import android.util.DisplayMetrics; +import android.view.View; + +public class ConferenceAndMultiCall extends SampleTest { + + @SmallTest + @MediumTest + @LargeTest + public void testAInit() { + LinphoneTestManager.createAndStart(aContext, iContext, 2); + + solo.sleep(2000); + waitForRegistration(LinphoneTestManager.getLc(2).getProxyConfigList()[0]); + + //Disable video + goToSettings(); + + selectItemInListOnUIThread(3); + solo.clickOnText(aContext.getString(R.string.pref_video_title)); + solo.clickOnText(aContext.getString(R.string.pref_video_enable_title)); + solo.sleep(500); + + solo.goBack(); + solo.sleep(1000); + Assert.assertFalse(LinphoneManager.getLc().isVideoEnabled()); + } + + @SmallTest + @MediumTest + @LargeTest + public void testBSimpleConference() { + LinphoneTestManager.getInstance().declineCall = false; // Just in case + startConference(); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @LargeTest + public void testCRemoveOneFromConference() { + startConference(); + + solo.clickOnView(solo.getView(R.id.conference_pause)); + + Assert.assertEquals(1, LinphoneTestManager.getLc(1).getCallsNb()); + Assert.assertEquals(1, LinphoneTestManager.getLc(2).getCallsNb()); + solo.sleep(1000); + Assert.assertFalse(LinphoneManager.getLc().isInConference()); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @LargeTest + public void testDChangePausedCall() { + startTwoCalls(); + + solo.sleep(2000); + LinphoneCall call1 = LinphoneTestManager.getLc(1).getCalls()[0]; + LinphoneCall call2 = LinphoneTestManager.getLc(2).getCalls()[0]; + waitForCallState(call2,LinphoneCall.State.StreamsRunning); + waitForCallState(call1,LinphoneCall.State.PausedByRemote); + + solo.clickOnView(solo.getView(R.id.call_pause)); + solo.sleep(2000); + waitForCallState(call1,LinphoneCall.State.StreamsRunning); + waitForCallState(call2,LinphoneCall.State.PausedByRemote); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @LargeTest + public void testEPauseAllCalls() { + startTwoCalls(); + + solo.sleep(2000); + LinphoneCall call1 = LinphoneTestManager.getLc(1).getCalls()[0]; + LinphoneCall call2 = LinphoneTestManager.getLc(2).getCalls()[0]; + waitForCallState(call2,LinphoneCall.State.StreamsRunning); + waitForCallState(call1,LinphoneCall.State.PausedByRemote); + + solo.clickOnView(solo.getView(R.id.pause)); + solo.sleep(2000); + waitForCallState(call2,LinphoneCall.State.PausedByRemote); + waitForCallState(call1,LinphoneCall.State.PausedByRemote); + + // All calls are paused, one click on hang_up terminates them all + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @LargeTest + public void testFAddNewCallAndCancelIt() { + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(1); + LinphoneTestManager.getInstance().autoAnswer = false; + + solo.clickOnView(solo.getView(R.id.options)); + solo.clickOnView(solo.getView(R.id.add_call)); + + solo.enterText(0, iContext.getString(R.string.conference_account_login) + "@" + iContext.getString(R.string.conference_account_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + solo.sleep(2000); + solo.clickOnView(solo.getView(R.id.outgoing_hang_up)); + + waitForCallState(LinphoneTestManager.getLc(1).getCalls()[0],LinphoneCall.State.PausedByRemote); + solo.clickOnView(solo.getView(R.id.pause)); + solo.sleep(1000); + waitForCallState(LinphoneTestManager.getLc(1).getCalls()[0],LinphoneCall.State.StreamsRunning); + + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + LinphoneTestManager.getInstance().autoAnswer = true; + } + + @LargeTest + public void testGAddNewCallDeclined() { + LinphoneTestManager.getInstance().autoAnswer = true; // Just in case + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(1); + LinphoneTestManager.getInstance().declineCall = true; + + solo.clickOnView(solo.getView(R.id.options)); + solo.clickOnView(solo.getView(R.id.add_call)); + + solo.enterText(0, iContext.getString(R.string.conference_account_login) + "@" + iContext.getString(R.string.conference_account_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + solo.sleep(2000); + waitForCallState(LinphoneTestManager.getLc(1).getCalls()[0],LinphoneCall.State.PausedByRemote); + + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + LinphoneTestManager.getInstance().declineCall = false; + } + + @LargeTest + public void testHIncomingCallWhileInCallAndDecline() { + LinphoneTestManager.getInstance().declineCall = false; //Just in case + + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(1); + + solo.sleep(2000); + try { + LinphoneTestManager.getLc(2).invite("sip:" + iContext.getString(R.string.account_linphone_login) + "@" + iContext.getString(R.string.account_linphone_domain)); + } catch (LinphoneCoreException e) { + e.printStackTrace(); + } + + solo.waitForActivity("IncomingCallActivity", 5000); + solo.assertCurrentActivity("Expected Incoming call Activity", CallIncomingActivity.class); + + solo.sleep(1000); + View topLayout = solo.getView(R.id.topLayout); + int topLayoutHeigh = topLayout.getMeasuredHeight(); + DisplayMetrics dm = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); + int topOffset = dm.heightPixels - topLayoutHeigh; + int slidersTop = topLayoutHeigh - 80 - topOffset; // 80 is the bottom margin set in incoming.xml + solo.drag(topLayout.getMeasuredWidth() - 10, 10, slidersTop, slidersTop, 10); + + assertCallIsCorrectlyRunning(1); + + solo.sleep(2000); + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @LargeTest + public void testIIncomingCallWhileInCallAndAccept() { + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(1); + + solo.sleep(2000); + try { + LinphoneTestManager.getLc(2).invite("sip:" + iContext.getString(R.string.account_linphone_login) + "@" + iContext.getString(R.string.account_linphone_domain)); + } catch (LinphoneCoreException e) { + e.printStackTrace(); + } + + solo.waitForActivity("IncomingCallActivity", 5000); + solo.assertCurrentActivity("Expected Incoming call Activity", CallIncomingActivity.class); + + solo.sleep(1000); + View topLayout = solo.getView(R.id.topLayout); + int topLayoutHeigh = topLayout.getMeasuredHeight(); + DisplayMetrics dm = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm); + int topOffset = dm.heightPixels - topLayoutHeigh; + int slidersTop = topLayoutHeigh - 80 - topOffset; // 80 is the bottom margin set in incoming.xml + solo.drag(10, topLayout.getMeasuredWidth() - 10, slidersTop, slidersTop, 10); + + solo.sleep(1000); + LinphoneCall call1 = LinphoneTestManager.getLc(1).getCalls()[0]; + waitForCallState(call1,LinphoneCall.State.PausedByRemote); + assertCallIsCorrectlyRunning(2); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + private void goToSettings() { + solo.waitForActivity("LinphoneActivity", 2000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + solo.clickOnView(solo.getView(R.id.side_menu_button)); + solo.clickOnText(aContext.getString(R.string.menu_settings)); + } + + private void startTwoCalls() { + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.clickOnView(solo.getView(R.id.call)); + assertCallIsCorrectlyRunning(1); + + solo.clickOnView(solo.getView(R.id.options)); + solo.clickOnView(solo.getView(R.id.add_call)); + + solo.enterText(0, iContext.getString(R.string.conference_account_login) + "@" + iContext.getString(R.string.conference_account_domain)); + solo.clickOnView(solo.getView(R.id.call)); + assertCallIsCorrectlyRunning(2); + } + + private void startConference() { + startTwoCalls(); + + solo.clickOnView(solo.getView(R.id.options)); + solo.clickOnView(solo.getView(R.id.conference)); + solo.sleep(1000); + + assertCallIsCorrectlyRunning(1); + assertCallIsCorrectlyRunning(2); + Assert.assertTrue(LinphoneManager.getLc().isInConference()); + } + + private void assertCallIsCorrectlyRunning(int lcId) { + solo.waitForActivity("CallActivity", 5000); + solo.assertCurrentActivity("Expected InCall Activity", CallActivity.class); + + solo.sleep(2000); + Assert.assertEquals(1, LinphoneTestManager.getLc(lcId).getCallsNb()); + LinphoneCall call = LinphoneTestManager.getLc(lcId).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); + } + + waitForCallState(call, LinphoneCall.State.StreamsRunning); + } +} diff --git a/src/androidTest/org/linphone/Contacts.java b/src/androidTest/org/linphone/Contacts.java new file mode 100644 index 000000000..83e457364 --- /dev/null +++ b/src/androidTest/org/linphone/Contacts.java @@ -0,0 +1,126 @@ +package org.linphone; + +import junit.framework.Assert; + + +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; + +/** + * @author Sylvain Berfini + */ +public class Contacts extends SampleTest { + + @MediumTest + @LargeTest + public void testAAddContactFromHistoryAndDeleteIt() { + goToHistory(); + + solo.clickOnView(solo.getView(R.id.detail)); + solo.clickOnView(solo.getView(R.id.add_contact)); + solo.clickOnView(solo.getView(R.id.newContact)); + + Assert.assertTrue(solo.searchText(aContext.getString(R.string.account_test_calls_login) + "@" + aContext.getString(R.string.account_test_calls_domain))); + + solo.enterText(0, iContext.getString(R.string.contact_name)); + solo.clickOnView(solo.getView(R.id.ok)); + + Assert.assertTrue(solo.searchText(iContext.getString(R.string.contact_name))); + + solo.clickOnText(iContext.getString(R.string.contact_name)); + solo.clickOnView(solo.getView(R.id.deleteContact)); + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.delete_button)); + + Assert.assertFalse(solo.searchText(iContext.getString(R.string.contact_name))); + } + + @SmallTest + @MediumTest + @LargeTest + public void testBCreateContactWithPhoneNumber() { + goToContacts(); + + solo.clickOnView(solo.getView(R.id.newContact)); + solo.enterText(0, iContext.getString(R.string.contact_name)); + solo.enterText(3, iContext.getString(R.string.contact_number)); + solo.clickOnView(solo.getView(R.id.ok)); + solo.sleep(2000); + Assert.assertTrue(solo.searchText(iContext.getString(R.string.contact_name))); + } + + @MediumTest + @LargeTest + public void testCTestContactFilter1() { + goToContacts(); + + Assert.assertTrue(solo.searchText(iContext.getString(R.string.contact_name))); + solo.clickOnView(solo.getView(R.id.linphone_contacts)); + Assert.assertFalse(solo.searchText(iContext.getString(R.string.contact_name))); + } + + @MediumTest + @LargeTest + public void testDEditContactAddSipAddressAndRemoveNumber() { + goToContacts(); + solo.clickOnView(solo.getView(R.id.all_contacts)); + + solo.clickOnText(iContext.getString(R.string.contact_name)); + solo.clickOnView(solo.getView(R.id.editContact)); + solo.clickOnView(solo.getView(R.id.delete_field)); + solo.enterText(2, iContext.getString(R.string.contact_sip)); + solo.clickOnView(solo.getView(R.id.ok)); + + Assert.assertTrue(solo.searchText(iContext.getString(R.string.contact_sip))); + Assert.assertFalse(solo.searchText(iContext.getString(R.string.contact_number))); + + } + + @MediumTest + @LargeTest + public void testETestContactFilter2() { + goToContacts(); + + Assert.assertTrue(solo.searchText(iContext.getString(R.string.contact_name))); + solo.clickOnView(solo.getView(R.id.linphone_contacts)); + Assert.assertTrue(solo.searchText(iContext.getString(R.string.contact_name))); + } + + @MediumTest + @LargeTest + public void testFStartChatFromContact() { + goToContacts(); + + solo.clickOnText(iContext.getString(R.string.contact_name)); + solo.clickOnView(solo.getView(R.id.contact_chat)); + //Assert.assertTrue(solo.search(aContext.get(R.string.send_message))); + } + + @SmallTest + @MediumTest + @LargeTest + public void testGDeleteContact() { + goToContacts(); + + solo.clickOnText(iContext.getString(R.string.contact_name)); + solo.clickOnView(solo.getView(R.id.deleteContact)); + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.delete_button)); + Assert.assertFalse(solo.searchText(iContext.getString(R.string.contact_name))); + } + + private void goToContacts() { + solo.waitForActivity("LinphoneActivity", 2000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + solo.clickOnView(solo.getView(R.id.contacts)); + } + + private void goToHistory() { + solo.waitForActivity("LinphoneActivity", 2000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + solo.clickOnView(solo.getView(R.id.history)); + } +} diff --git a/src/androidTest/org/linphone/History.java b/src/androidTest/org/linphone/History.java new file mode 100644 index 000000000..d1d52b305 --- /dev/null +++ b/src/androidTest/org/linphone/History.java @@ -0,0 +1,88 @@ +package org.linphone; + +import junit.framework.Assert; + +import org.linphone.CallActivity; +import org.linphone.LinphoneActivity; +import org.linphone.core.LinphoneCall; + +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; + +/** + * @author Sylvain Berfini + */ +public class History extends SampleTest { + + @SmallTest + @MediumTest + @LargeTest + public void testACheckForTestCallInHistory() { + goToHistory(); + + Assert.assertTrue(solo.searchText(aContext.getString(R.string.today))); + Assert.assertTrue(solo.searchText(iContext.getString(R.string.account_test_calls_login))); + } + + @MediumTest + @LargeTest + public void testBFilterMissedCalls() { + goToHistory(); + + solo.clickOnView(solo.getView(R.id.missed_calls)); + Assert.assertTrue(solo.searchText(aContext.getString(R.string.no_missed_call_history))); + } + + public void testCCallBackFromHistory() { + goToHistory(); + + solo.clickOnText(iContext.getString(R.string.account_test_calls_login)); + + solo.waitForActivity("InCallActivity", 5000); + solo.assertCurrentActivity("Expected InCall Activity", CallActivity.class); + + solo.sleep(2000); + Assert.assertEquals(1, LinphoneTestManager.getLc().getCallsNb()); + waitForCallState(LinphoneTestManager.getLc().getCalls()[0],LinphoneCall.State.StreamsRunning); + + solo.clickOnView(solo.getView(R.id.hang_up)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + } + + @MediumTest + @LargeTest + public void testDDeleteOne() { + goToHistory(); + + solo.clickOnView(solo.getView(R.id.edit)); + solo.sleep(500); + solo.clickOnCheckBox(1); + solo.clickOnView(solo.getView(R.id.delete)); + solo.sleep(500); + solo.clickOnView(solo.getView(R.id.delete_button)); + } + + @SmallTest + @MediumTest + @LargeTest + public void testEDeleteAll() { + goToHistory(); + + solo.clickOnView(solo.getView(R.id.edit)); + solo.clickOnView(solo.getView(R.id.select_all)); + solo.clickOnView(solo.getView(R.id.delete)); + solo.sleep(500); + solo.clickOnView(solo.getView(R.id.delete_button)); + + Assert.assertTrue(solo.searchText(aContext.getString(R.string.no_call_history))); + } + + private void goToHistory() { + solo.waitForActivity("LinphoneActivity", 2000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + solo.clickOnView(solo.getView(R.id.history)); + } +} diff --git a/src/androidTest/org/linphone/LinphoneTestManager.java b/src/androidTest/org/linphone/LinphoneTestManager.java new file mode 100644 index 000000000..628676013 --- /dev/null +++ b/src/androidTest/org/linphone/LinphoneTestManager.java @@ -0,0 +1,511 @@ +package org.linphone; + +import java.nio.ByteBuffer; +import java.util.Timer; +import java.util.TimerTask; + +import org.linphone.LinphoneException; +import org.linphone.LinphoneManager; +import org.linphone.LinphoneManager.LinphoneConfigException; +import org.linphone.LinphoneService; +import org.linphone.core.LinphoneAddress; +import org.linphone.core.LinphoneAddress.TransportType; +import org.linphone.core.LinphoneAuthInfo; +import org.linphone.core.LinphoneCall; +import org.linphone.core.LinphoneCall.State; +import org.linphone.core.LinphoneCallStats; +import org.linphone.core.LinphoneChatMessage; +import org.linphone.core.LinphoneChatRoom; +import org.linphone.core.LinphoneContent; +import org.linphone.core.LinphoneCore; +import org.linphone.core.LinphoneCore.AuthMethod; +import org.linphone.core.LinphoneCore.EcCalibratorStatus; +import org.linphone.core.LinphoneCore.GlobalState; +import org.linphone.core.LinphoneCore.MediaEncryption; +import org.linphone.core.LinphoneCore.RegistrationState; +import org.linphone.core.LinphoneCore.RemoteProvisioningState; +import org.linphone.core.LinphoneCore.Transports; +import org.linphone.core.LinphoneCoreException; +import org.linphone.core.LinphoneCoreFactory; +import org.linphone.core.LinphoneCoreListener; +import org.linphone.core.LinphoneCoreListenerBase; +import org.linphone.core.LinphoneEvent; +import org.linphone.core.LinphoneFriend; +import org.linphone.core.LinphoneFriendList; +import org.linphone.core.LinphoneInfoMessage; +import org.linphone.core.LinphoneProxyConfig; +import org.linphone.core.PayloadType; +import org.linphone.core.PublishState; +import org.linphone.core.SubscriptionState; +import org.linphone.mediastream.Log; +import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration; +import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration.AndroidCamera; + +import android.content.Context; +import android.content.pm.PackageManager.NameNotFoundException; +import android.telephony.TelephonyManager; + +public class LinphoneTestManager implements LinphoneCoreListener{ + + private static LinphoneTestManager instance; + private Context mIContext; + private LinphoneCore mLc1, mLc2; + + public String lastMessageReceived; + public boolean isDTMFReceived = false; + public boolean autoAnswer = true; + public boolean declineCall = false; + + private final String linphoneRootCaFile; + private LinphoneCoreListenerBase mListener; + + private Timer mTimer1 = new Timer("Linphone scheduler 1"); + private Timer mTimer2 = new Timer("Linphone scheduler 2"); + + private LinphoneTestManager(Context ac, Context ic) { + mIContext = ic; + linphoneRootCaFile = ac.getFilesDir().getAbsolutePath() + "/rootca.pem"; + } + + public static LinphoneTestManager createAndStart(Context ac, Context ic, int id) { + if (instance == null) + instance = new LinphoneTestManager(ac, ic); + + instance.startLibLinphone(ic, id); + TelephonyManager tm = (TelephonyManager) ac.getSystemService(Context.TELEPHONY_SERVICE); + boolean gsmIdle = tm.getCallState() == TelephonyManager.CALL_STATE_IDLE; + setGsmIdle(gsmIdle, id); + + return instance; + } + + private synchronized void startLibLinphone(Context c, int id) { + try { + LinphoneCoreFactory.instance().setDebugMode(true, "LinphoneTester"); + + final LinphoneCore mLc = LinphoneCoreFactory.instance().createLinphoneCore(this, c); + if (id == 2) { + mLc2 = mLc; + } else { + mLc1 = mLc; + } + + mLc.setContext(c); + try { + String versionName = c.getPackageManager().getPackageInfo(c.getPackageName(), 0).versionName; + if (versionName == null) { + versionName = String.valueOf(c.getPackageManager().getPackageInfo(c.getPackageName(), 0).versionCode); + } + mLc.setUserAgent("LinphoneAndroid", versionName); + } catch (NameNotFoundException e) { + Log.e(e, "cannot get version name"); + } + + mLc.enableIpv6(false); + mLc.setRing(null); + mLc.setRootCA(linphoneRootCaFile); + + int availableCores = Runtime.getRuntime().availableProcessors(); + Log.w("MediaStreamer : " + availableCores + " cores detected and configured"); + mLc.setCpuCount(availableCores); + + Transports t = mLc.getSignalingTransportPorts(); + t.udp = -1; + t.tcp = -1; + mLc.setSignalingTransportPorts(t); + + try { + initFromConf(mLc); + } catch (LinphoneException e) { + Log.w("no config ready yet"); + } + + TimerTask lTask = new TimerTask() { + @Override + public void run() { + mLc.iterate(); + } + }; + + if (id == 2) { + mTimer2.scheduleAtFixedRate(lTask, 0, 20); + } else { + mTimer1.scheduleAtFixedRate(lTask, 0, 20); + } + + resetCameraFromPreferences(); + } + catch (Exception e) { + Log.e(e, "Cannot start linphone"); + } + } + + private void resetCameraFromPreferences() { + boolean useFrontCam = true; + int camId = 0; + AndroidCamera[] cameras = AndroidCameraConfiguration.retrieveCameras(); + for (AndroidCamera androidCamera : cameras) { + if (androidCamera.frontFacing == useFrontCam) + camId = androidCamera.id; + } + LinphoneManager.getLc().setVideoDevice(camId); + } + + public void initFromConf(LinphoneCore mLc) throws LinphoneConfigException, LinphoneCoreException { + LinphoneCoreFactory.instance().setDebugMode(true, "LinphoneTester"); + + initAccounts(mLc); + + mLc.setVideoPolicy(true, true); + mLc.enableVideo(true, true); + + mLc.setUseRfc2833ForDtmfs(false); + mLc.setUseSipInfoForDtmfs(true); + + mLc.setNetworkReachable(true); + } + + public boolean detectVideoCodec(String mime, LinphoneCore mLc) { + for (PayloadType videoCodec : mLc.getVideoCodecs()) { + if (mime.equals(videoCodec.getMime())) return true; + } + return false; + } + + public boolean detectAudioCodec(String mime, LinphoneCore mLc){ + for (PayloadType audioCodec : mLc.getAudioCodecs()) { + if (mime.equals(audioCodec.getMime())) return true; + } + return false; + } + + void initMediaEncryption(LinphoneCore mLc){ + MediaEncryption me = MediaEncryption.None; + mLc.setMediaEncryption(me); + } + + private void initAccounts(LinphoneCore mLc) throws LinphoneCoreException { + mLc.clearAuthInfos(); + mLc.clearProxyConfigs(); + + String username, password, domain; + if (mLc.equals(mLc1)) { + username = mIContext.getString(R.string.account_test_calls_login); + password = mIContext.getString(R.string.account_test_calls_pwd); + domain = mIContext.getString(R.string.account_test_calls_domain); + } else { + username = mIContext.getString(R.string.conference_account_login); + password = mIContext.getString(R.string.conference_account_password); + domain = mIContext.getString(R.string.conference_account_domain); + } + + LinphoneAuthInfo lAuthInfo = LinphoneCoreFactory.instance().createAuthInfo(username, password, null, domain); + mLc.addAuthInfo(lAuthInfo); + String identity = "sip:" + username +"@" + domain; + String proxy = "sip:" + domain; + LinphoneAddress proxyAddr = LinphoneCoreFactory.instance().createLinphoneAddress(proxy); + proxyAddr.setTransport(TransportType.LinphoneTransportTls); + LinphoneProxyConfig proxycon = mLc.createProxyConfig(identity, proxyAddr.asStringUriOnly(), proxyAddr.asStringUriOnly(), true); + mLc.addProxyConfig(proxycon); + mLc.setDefaultProxyConfig(proxycon); + + LinphoneProxyConfig lDefaultProxyConfig = mLc.getDefaultProxyConfig(); + if (lDefaultProxyConfig != null) { + //escape + + lDefaultProxyConfig.setDialEscapePlus(false); + } else if (LinphoneService.isReady()) { + getLc().addListener(this); + this.registrationState(mLc, lDefaultProxyConfig, RegistrationState.RegistrationNone, null); + } + } + + public static synchronized final LinphoneTestManager getInstance() { + return instance; + } + + public static synchronized final LinphoneCore getLc(int i) { + if (i == 2) + return getInstance().mLc2; + return getInstance().mLc1; + } + + public static synchronized final LinphoneCore getLc() { + return getLc(1); + } + + private int savedMaxCallWhileGsmIncall; + private synchronized void preventSIPCalls(LinphoneCore mLc) { + if (savedMaxCallWhileGsmIncall != 0) { + Log.w("SIP calls are already blocked due to GSM call running"); + return; + } + savedMaxCallWhileGsmIncall = mLc.getMaxCalls(); + mLc.setMaxCalls(0); + } + private synchronized void allowSIPCalls(LinphoneCore mLc) { + if (savedMaxCallWhileGsmIncall == 0) { + Log.w("SIP calls are already allowed as no GSM call knowned to be running"); + return; + } + mLc.setMaxCalls(savedMaxCallWhileGsmIncall); + savedMaxCallWhileGsmIncall = 0; + } + public static void setGsmIdle(boolean gsmIdle, int id) { + LinphoneTestManager mThis = instance; + if (mThis == null) return; + if (gsmIdle) { + mThis.allowSIPCalls(LinphoneTestManager.getLc(id)); + } else { + mThis.preventSIPCalls(LinphoneTestManager.getLc(id)); + } + } + + private void doDestroy() { + try { + mTimer1.cancel(); + mTimer2.cancel(); + mLc1.destroy(); + mLc2.destroy(); + } + catch (RuntimeException e) { + e.printStackTrace(); + } + finally { + mLc1 = null; + mLc2 = null; + instance = null; + } + } + + public static synchronized void destroy() { + if (instance == null) return; + instance.doDestroy(); + } + + @Override + public void globalState(LinphoneCore lc, GlobalState state, String message) { + // TODO Auto-generated method stub + + } + + @Override + public void callState(LinphoneCore lc, LinphoneCall call, State cstate, + String message) { + // TODO Auto-generated method stub + Log.e("Call state = " + cstate.toString()); + if (cstate == LinphoneCall.State.IncomingReceived) { + if (declineCall) { + lc.terminateCall(call); + } else if (autoAnswer) { + try { + lc.acceptCall(call); + } catch (LinphoneCoreException e) { + e.printStackTrace(); + } + } + } + } + + @Override + public void callStatsUpdated(LinphoneCore lc, LinphoneCall call, + LinphoneCallStats stats) { + // TODO Auto-generated method stub + + } + + @Override + public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call, + boolean encrypted, String authenticationToken) { + // TODO Auto-generated method stub + + } + + @Override + public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, + RegistrationState cstate, String smessage) { + // TODO Auto-generated method stub + Log.e("Registration state = " + cstate.toString()); + } + + @Override + public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, + String url) { + // TODO Auto-generated method stub + + } + + @Override + public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) { + // TODO Auto-generated method stub + + } + + @Override + public void messageReceived(LinphoneCore lc, LinphoneChatRoom cr, + LinphoneChatMessage message) { + // TODO Auto-generated method stub + Log.e("Message received = " + message.getText()); + lastMessageReceived = message.getText(); + } + + @Override + public void dtmfReceived(LinphoneCore lc, LinphoneCall call, int dtmf) { + // TODO Auto-generated method stub + Log.e("DTMF received = " + dtmf); + isDTMFReceived = true; + } + + @Override + public void notifyReceived(LinphoneCore lc, LinphoneCall call, + LinphoneAddress from, byte[] event) { + // TODO Auto-generated method stub + + } + + @Override + public void show(LinphoneCore lc) { + // TODO Auto-generated method stub + + } + + @Override + public void displayStatus(LinphoneCore lc, String message) { + // TODO Auto-generated method stub + + } + + @Override + public void displayMessage(LinphoneCore lc, String message) { + // TODO Auto-generated method stub + + } + + @Override + public void displayWarning(LinphoneCore lc, String message) { + // TODO Auto-generated method stub + + } + + @Override + public void transferState(LinphoneCore lc, LinphoneCall call, + State new_call_state) { + // TODO Auto-generated method stub + + } + + @Override + public void infoReceived(LinphoneCore lc, LinphoneCall call, + LinphoneInfoMessage info) { + // TODO Auto-generated method stub + + } + + @Override + public void subscriptionStateChanged(LinphoneCore lc, LinphoneEvent ev, + SubscriptionState state) { + // TODO Auto-generated method stub + + } + + @Override + public void notifyReceived(LinphoneCore lc, LinphoneEvent ev, + String eventName, LinphoneContent content) { + // TODO Auto-generated method stub + + } + + @Override + public void publishStateChanged(LinphoneCore lc, LinphoneEvent ev, + PublishState state) { + // TODO Auto-generated method stub + + } + + @Override + public void isComposingReceived(LinphoneCore lc, LinphoneChatRoom cr) { + // TODO Auto-generated method stub + } + + @Override + public void configuringStatus(LinphoneCore lc, + RemoteProvisioningState state, String message) { + // TODO Auto-generated method stub + } + + @Override + public void authInfoRequested(LinphoneCore lc, String realm, + String username, String domain) { + // TODO Auto-generated method stub + + } + + @Override + public void authenticationRequested(LinphoneCore lc, + LinphoneAuthInfo authInfo, AuthMethod method) { + // TODO Auto-generated method stub + + } + + @Override + public void fileTransferProgressIndication(LinphoneCore lc, + LinphoneChatMessage message, LinphoneContent content, int progress) { + // TODO Auto-generated method stub + + } + + @Override + public void fileTransferRecv(LinphoneCore lc, LinphoneChatMessage message, + LinphoneContent content, byte[] buffer, int size) { + // TODO Auto-generated method stub + + } + + @Override + public int fileTransferSend(LinphoneCore lc, LinphoneChatMessage message, + LinphoneContent content, ByteBuffer buffer, int size) { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void uploadProgressIndication(LinphoneCore lc, int offset, int total) { + // TODO Auto-generated method stub + + } + + + @Override + public void uploadStateChanged(LinphoneCore lc, LinphoneCore.LogCollectionUploadState state, + String info) { + // TODO Auto-generated method stub + + } + + @Override + public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status, + int delay_ms, Object data) { + // TODO Auto-generated method stub + + } + + @Override + public void friendListCreated(LinphoneCore lc, LinphoneFriendList list) { + // TODO Auto-generated method stub + } + + @Override + public void friendListRemoved(LinphoneCore lc, LinphoneFriendList list) { + // TODO Auto-generated method stub + } + + @Override + public void networkReachableChanged(LinphoneCore lc, boolean enable) { + // TODO Auto-generated method stub + } + + @Override + public void messageReceivedUnableToDecrypted(LinphoneCore lc, LinphoneChatRoom cr, + LinphoneChatMessage message) { + // TODO Auto-generated method stub + } +} diff --git a/src/androidTest/org/linphone/SampleTest.java b/src/androidTest/org/linphone/SampleTest.java new file mode 100644 index 000000000..72c7a0aa9 --- /dev/null +++ b/src/androidTest/org/linphone/SampleTest.java @@ -0,0 +1,98 @@ +package org.linphone; + +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; + +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; + +/** + * @author Sylvain Berfini + */ +public abstract class SampleTest extends ActivityInstrumentationTestCase2{ + + protected final int STRING_LENGTH_MAX = 20; + + protected Solo solo; + protected Context aContext, iContext; + + public SampleTest() { + super(LinphoneLauncherActivity.class); + } + + @Override + public void setUp() throws Exception { + solo = new Solo(getInstrumentation()); + aContext = getActivity(); + iContext = aContext; + } + + @Override + public void tearDown() throws Exception { + LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (lc != null) { + lc.terminateAllCalls(); + } + solo.finishOpenedActivities(); + } + + protected void selectItemInListOnUIThread(final int item) { + solo.sleep(500); + getActivity().runOnUiThread(new Runnable() { + public void run() { + ListView list = (ListView) solo.getView(android.R.id.list); + list.setSelection(item); + } + }); + } + + protected void waitForRegistration(final LinphoneProxyConfig lpc) { + if(lpc == null) return; + solo.waitForCondition(new Condition() { + @Override + public boolean isSatisfied() { + return RegistrationState.RegistrationOk == lpc.getState(); + } + }, 30000); + } + + protected void waitForCallPaused(final LinphoneCall call) { + if(call == null) return; + solo.waitForCondition(new Condition() { + @Override + public boolean isSatisfied() { + return call.getState().equals(State.Paused) || call.getState().equals(State.Pausing); + } + }, 30000); + } + + protected void waitForCallResumed(final LinphoneCall call) { + if(call == null) return; + solo.waitForCondition(new Condition() { + @Override + public boolean isSatisfied() { + return call.getState().equals(State.Resuming) || call.getState().equals(State.StreamsRunning); + } + }, 30000); + } + + protected void waitForCallState(final LinphoneCall call, final State state) { + if(call == null) return; + solo.waitForCondition(new Condition() { + @Override + public boolean isSatisfied() { + return state.equals(call.getState()); + } + }, 30000); + } +} \ No newline at end of file diff --git a/src/androidTest/org/linphone/Transfer.java b/src/androidTest/org/linphone/Transfer.java new file mode 100644 index 000000000..7a41cfba0 --- /dev/null +++ b/src/androidTest/org/linphone/Transfer.java @@ -0,0 +1,60 @@ +package org.linphone; + +import junit.framework.Assert; + +import org.linphone.CallActivity; +import org.linphone.LinphoneActivity; +import org.linphone.LinphoneManager; +import org.linphone.core.LinphoneCall; +import org.linphone.mediastream.Log; + +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; + +public class Transfer extends SampleTest { + @SmallTest + @MediumTest + @LargeTest + public void testACallTransfer() { + solo.enterText(0, iContext.getString(R.string.account_test_calls_login) + "@" + iContext.getString(R.string.account_test_calls_domain)); + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.call)); + + assertCallIsCorrectlyRunning(); + + solo.clickOnView(solo.getView(R.id.options)); + solo.clickOnView(solo.getView(R.id.transfer)); + solo.waitForActivity("LinphoneActivity", 5000); + solo.assertCurrentActivity("Expected Linphone Activity", LinphoneActivity.class); + + solo.enterText(0, iContext.getString(R.string.conference_account_login) + "@" + iContext.getString(R.string.conference_account_domain)); + solo.sleep(1000); + solo.clickOnView(solo.getView(R.id.call)); // Transfer button as the same id, only the image changes + + solo.sleep(2000); + Assert.assertTrue(LinphoneTestManager.getLc(1).getCallsNb() > 0); + Assert.assertTrue(LinphoneTestManager.getLc(2).getCallsNb() > 0); + LinphoneTestManager.getLc(1).terminateAllCalls(); + solo.sleep(500); + Assert.assertTrue(LinphoneTestManager.getLc(1).getCallsNb() == 0); + Assert.assertTrue(LinphoneTestManager.getLc(2).getCallsNb() == 0); + } + + private void assertCallIsCorrectlyRunning() { + solo.waitForActivity("InCallActivity", 5000); + solo.assertCurrentActivity("Expected InCall Activity", CallActivity.class); + + 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); + } + + waitForCallState(call,LinphoneCall.State.StreamsRunning); + } +} diff --git a/src/androidTest/org/linphone/ZShutdownTestEnv.java b/src/androidTest/org/linphone/ZShutdownTestEnv.java new file mode 100644 index 000000000..2bdba2288 --- /dev/null +++ b/src/androidTest/org/linphone/ZShutdownTestEnv.java @@ -0,0 +1,25 @@ +package org.linphone; + +import static android.content.Intent.ACTION_MAIN; + +import org.linphone.LinphoneService; + +import android.content.Intent; +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.MediumTest; +import android.test.suitebuilder.annotation.SmallTest; + +/** + * @author Sylvain Berfini + */ +public class ZShutdownTestEnv extends SampleTest { + + @SmallTest + @MediumTest + @LargeTest + public void testZShutDownLinphoneCore() { + LinphoneTestManager.destroy(); + aContext.stopService(new Intent(ACTION_MAIN).setClass(aContext, LinphoneService.class)); + } + +}