diff --git a/.classpath b/.classpath index 2df25a2b6..63762c92a 100644 --- a/.classpath +++ b/.classpath @@ -4,7 +4,6 @@ - diff --git a/.gitignore b/.gitignore index ee894014f..456fadc1f 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ liblinphone_tester/tests.output tests/linphonetester_* tests/tests.output WORK +.d diff --git a/.gitmodules b/.gitmodules index 6778bad1b..366481017 100644 --- a/.gitmodules +++ b/.gitmodules @@ -55,9 +55,6 @@ [submodule "submodules/externals/libupnp"] path = submodules/externals/libupnp url = git://git.linphone.org/libupnp.git -[submodule "submodules/externals/axmlrpc"] - path = submodules/externals/axmlrpc - url = git://git.linphone.org/axmlrpc.git [submodule "submodules/externals/opus"] path = submodules/externals/opus url = git://git.linphone.org/opus.git diff --git a/ant.properties b/ant.properties index 41ee35579..850216300 100644 --- a/ant.properties +++ b/ant.properties @@ -1,4 +1,4 @@ -source.dir=src:submodules/linphone/mediastreamer2/java/src:submodules/linphone/java/j2se:submodules/linphone/java/common:submodules/linphone/java/impl:submodules/linphone/coreapi/help/java:submodules/externals/axmlrpc/src/main/java +source.dir=src:submodules/linphone/mediastreamer2/java/src:submodules/linphone/java/j2se:submodules/linphone/java/common:submodules/linphone/java/impl:submodules/linphone/coreapi/help/java key.store=bc-android.keystore key.alias=nw8000 version.name=2.5.0 diff --git a/custom_rules.xml b/custom_rules.xml index 45b003dc2..8e0297fe8 100644 --- a/custom_rules.xml +++ b/custom_rules.xml @@ -93,7 +93,7 @@ + includes="org/linphone/mediastream/**/*.class org/linphone/core/**/*.class org/linphone/**/*.class"/> diff --git a/prepare.py b/prepare.py index 468acddef..34709b2a7 100755 --- a/prepare.py +++ b/prepare.py @@ -86,6 +86,7 @@ class AndroidPreparator(prepare.Preparator): self.min_supported_ndk = 10 self.max_supported_ndk = 12 self.unsupported_ndk_version = None + self.min_cmake_version = "3.0" self.release_with_debug_info = True self.veryclean = True self.show_gpl_disclaimer = True diff --git a/res/drawable-xhdpi/contact.png b/res/drawable-xhdpi/contact.png new file mode 100644 index 000000000..266548e17 Binary files /dev/null and b/res/drawable-xhdpi/contact.png differ diff --git a/res/layout-sw533dp-land/assistant_account_creation.xml b/res/layout-sw533dp-land/assistant_account_creation.xml index 43e475558..06a1061c2 100644 --- a/res/layout-sw533dp-land/assistant_account_creation.xml +++ b/res/layout-sw533dp-land/assistant_account_creation.xml @@ -55,7 +55,7 @@ android:id="@+id/username" android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" - android:inputType="text|textEmailAddress" + android:inputType="text|textNoSuggestions" android:contentDescription="@string/content_description_username_field" android:layout_width="match_parent" android:layout_height="40dp" diff --git a/res/layout-sw533dp-land/assistant_linphone_login.xml b/res/layout-sw533dp-land/assistant_linphone_login.xml index 8122c8ccd..1c9d8df64 100644 --- a/res/layout-sw533dp-land/assistant_linphone_login.xml +++ b/res/layout-sw533dp-land/assistant_linphone_login.xml @@ -49,7 +49,7 @@ android:id="@+id/assistant_username" android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" - android:inputType="text|textEmailAddress" + android:inputType="text|textNoSuggestions" android:contentDescription="@string/content_description_username_field" android:layout_width="match_parent" android:layout_height="40dp" @@ -110,7 +110,7 @@ android:id="@+id/assistant_display_name" android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" - android:inputType="textEmailAddress" + android:inputType="textPersonName" android:contentDescription="@string/content_description_display_field" android:layout_width="match_parent" android:layout_height="40dp" diff --git a/res/layout-sw533dp-land/assistant_login.xml b/res/layout-sw533dp-land/assistant_login.xml index 0d02af245..024f51125 100644 --- a/res/layout-sw533dp-land/assistant_login.xml +++ b/res/layout-sw533dp-land/assistant_login.xml @@ -53,7 +53,7 @@ android:id="@+id/assistant_username" android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" - android:inputType="text|textEmailAddress" + android:inputType="text|textNoSuggestions" android:contentDescription="@string/content_description_username_field" android:layout_width="match_parent" android:layout_height="40dp" @@ -107,7 +107,7 @@ android:id="@+id/assistant_display_name" android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" - android:inputType="textEmailAddress" + android:inputType="textPersonName" android:contentDescription="@string/content_description_display_field" android:layout_width="match_parent" android:layout_height="40dp" @@ -132,7 +132,7 @@ android:id="@+id/assistant_domain" android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" - android:inputType="textEmailAddress" + android:inputType="textUri" android:contentDescription="@string/content_description_domain_field" android:layout_width="match_parent" android:layout_height="40dp" diff --git a/res/layout-sw533dp-land/main.xml b/res/layout-sw533dp-land/main.xml index 4ef06a512..1b70202a7 100644 --- a/res/layout-sw533dp-land/main.xml +++ b/res/layout-sw533dp-land/main.xml @@ -77,7 +77,6 @@ @@ -153,7 +153,7 @@ android:id="@+id/email" android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" - android:inputType="text|textEmailAddress" + android:inputType="textEmailAddress" android:contentDescription="@string/content_description_email_field" android:textCursorDrawable="@null" android:layout_width="match_parent" diff --git a/res/layout/assistant_linphone_login.xml b/res/layout/assistant_linphone_login.xml index a1a0dc3aa..9f4d91918 100644 --- a/res/layout/assistant_linphone_login.xml +++ b/res/layout/assistant_linphone_login.xml @@ -45,7 +45,7 @@ android:id="@+id/assistant_username" android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" - android:inputType="text|textEmailAddress" + android:inputType="text|textNoSuggestions" android:contentDescription="@string/content_description_username_field" android:layout_width="match_parent" android:layout_height="40dp" @@ -87,7 +87,7 @@ android:id="@+id/assistant_display_name" android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" - android:inputType="textEmailAddress" + android:inputType="textPersonName" android:contentDescription="@string/content_description_username_field" android:layout_width="match_parent" android:layout_height="40dp" diff --git a/res/layout/assistant_login.xml b/res/layout/assistant_login.xml index 5ae935206..1b031ee94 100644 --- a/res/layout/assistant_login.xml +++ b/res/layout/assistant_login.xml @@ -45,7 +45,7 @@ android:id="@+id/assistant_username" android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" - android:inputType="text|textEmailAddress" + android:inputType="text|textNoSuggestions" android:contentDescription="@string/content_description_username_field" android:layout_width="match_parent" android:layout_height="40dp" @@ -80,7 +80,7 @@ android:id="@+id/assistant_domain" android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" - android:inputType="textEmailAddress" + android:inputType="textUri" android:contentDescription="@string/content_description_domain_field" android:layout_width="match_parent" android:layout_height="40dp" @@ -98,7 +98,7 @@ android:id="@+id/assistant_display_name" android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" - android:inputType="textEmailAddress" + android:inputType="textPersonName" android:contentDescription="@string/content_description_display_field" android:layout_width="match_parent" android:layout_height="40dp" diff --git a/res/layout/assistant_remote_provisioning_login.xml b/res/layout/assistant_remote_provisioning_login.xml index 2608982f8..6bdcb896a 100644 --- a/res/layout/assistant_remote_provisioning_login.xml +++ b/res/layout/assistant_remote_provisioning_login.xml @@ -42,7 +42,7 @@ android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" android:textCursorDrawable="@null" - android:inputType="textEmailAddress" + android:inputType="textNoSuggestions" android:layout_width="match_parent" android:layout_height="40dp" android:paddingLeft="10dp" @@ -84,7 +84,7 @@ android:background="@drawable/resizable_textfield" android:textColor="@color/colorB" android:textCursorDrawable="@null" - android:inputType="textEmailAddress" + android:inputType="textUri" android:layout_width="match_parent" android:layout_height="40dp" android:paddingLeft="10dp" diff --git a/res/layout/chat.xml b/res/layout/chat.xml index 1964fa8d6..7d8274577 100644 --- a/res/layout/chat.xml +++ b/res/layout/chat.xml @@ -94,9 +94,9 @@ android:textColor="@color/colorB" android:imeOptions="flagNoExtractUi" android:textCursorDrawable="@null" - android:inputType="textMultiLine" + android:inputType="textShortMessage|textMultiLine" android:contentDescription="@string/content_description_message" - android:maxLines="3" + android:maxLines="2" android:padding="5dp" android:layout_margin="5dp" android:layout_weight="1" diff --git a/res/layout/contact.xml b/res/layout/contact.xml index d5941ed1c..9f3de8408 100644 --- a/res/layout/contact.xml +++ b/res/layout/contact.xml @@ -72,8 +72,7 @@ android:layout_width="100dp" android:layout_height="100dp" android:adjustViewBounds="true" - android:layout_alignParentLeft="true" - android:layout_marginLeft="5dp"/> + android:layout_alignParentLeft="true"/> + android:layout_alignParentLeft="true"/> @@ -93,13 +91,21 @@ android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content"/> + + + android:paddingTop="10dp"/> diff --git a/res/layout/contact_cell.xml b/res/layout/contact_cell.xml index 0d5615ff8..71dc99392 100644 --- a/res/layout/contact_cell.xml +++ b/res/layout/contact_cell.xml @@ -72,16 +72,31 @@ android:paddingLeft="5dp" android:paddingRight="5dp" /> - + android:layout_marginLeft="10dp"> + + + + + + diff --git a/res/layout/contact_edit.xml b/res/layout/contact_edit.xml index e56628e8c..da442c190 100644 --- a/res/layout/contact_edit.xml +++ b/res/layout/contact_edit.xml @@ -134,6 +134,26 @@ android:gravity="left" android:paddingRight="5dp" android:inputType="textPersonName|textCapWords"/> + + + + diff --git a/res/layout/contacts_list.xml b/res/layout/contacts_list.xml index 2b2536d74..5856688fb 100644 --- a/res/layout/contacts_list.xml +++ b/res/layout/contacts_list.xml @@ -127,6 +127,15 @@ android:fastScrollEnabled="true" android:fastScrollAlwaysVisible="true" android:dividerHeight="1dp" /> + + + + @@ -88,7 +97,6 @@ diff --git a/res/raw/notes_of_the_optimistic.mkv b/res/raw/notes_of_the_optimistic.mkv new file mode 100644 index 000000000..a1d923389 Binary files /dev/null and b/res/raw/notes_of_the_optimistic.mkv differ diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 8bdff422b..6d9035ed2 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -9,9 +9,15 @@ ‫%s مُسجَّل‬ ‫فشل %s في التسجيل‬ + لِنْفُونْ أندرويد %s + Linphone Core %s + رخصة جْنُو العمومية الإصدار 2\n © 2010-2016 Belledonne Communications + www.linphone.org + جهات اتصال Linphone + HH:mm - إسم المستخدم - الإسم المعروض + اسم المستخدم + الاسم المعروض كلمة السر تأكيد كلمة السر النطاق @@ -42,20 +48,20 @@ إنشاء الحساب أنهِ التهئية لقد أُنشِيء حسابك. يُرجى الاطلاع على رسائل بريدك الإلكتروني لتأكيد حسابك. حالما تنتهي من ذلك، عُد إلى هنا واضغط على الزر. - سيمكنك هذا المرشد من إعداد حسابك SIP لإجراء المكالمات. + سيمكنك هذا المرشد من إعداد حساب SIP لإجراء المكالمات. أدخِل اسم المستخدم وكلمة السر لحساب لِنْفُونْ ‫أدخِل اسم المستخدم وكلمة السر الحساب مع نطاق SIP‬ يٌرجى إدخال عنوان التهئية البعيدة النقل استخدم حساب لِنْفُونْ استخدم حساب SIP - اجذب التهئية البعيدة + اجذب التهيئة البعيدة 1/2 2/2 الاسم المعروض (اختياري) هيِّءْ حساب لِنْفُونْ هيِّءْ حساب SIP - اجذب التهئية البعيدة + اجذب التهيئة البعيدة اجذبْ وطبِّق الولوج معايرة مزيل الصدى في طور الإنجاز @@ -71,7 +77,7 @@ كلمة السر غير صحيحة. كلمتا السر غير متطابقتين. سيكون اسم المستخدم هو %s.\r\n\r\nقد يختلف عما أدخلته ليوافق المعايير.\r\nأتقبل ذلك ؟ - يُرجى إدخال إسم المستخدم وكلمة السر + يُرجى إدخال اسم المستخدم وكلمة السر أدخل رقما أو عنوانا @@ -132,7 +138,7 @@ صبيب التنزيل : توصيل ICE : مقاس الفيديو : - مكالمة + المكالمة إرسال السجل إعادة تعيين السجل @@ -212,6 +218,7 @@ إزالة الصدى المسموع من الطرف الآخر معايرة مزيل الصدى يُعايِر... + ‫جرت المعايرة بـ ‪%s ms‬‬ لا وجود لصدى فشِل التحكم في ملائمة الصبيب @@ -224,15 +231,19 @@ أرسِل دائما طلبات الفيديو قبول طلبات الفيديو الواردة قبول طلبات الفيديو دائما + إعداد الفيديو المسبق حجم الفيديو المفضل معدل الإطارات المفضل حد سعة القناة بـ ك.بِتْ/ثانية المراميز - مكالمة + المكالمة إرسال RFC2833 DTMFs إرسال SIP INFO DTMFs عنوان العلبة الصوتية + + المحادثة + خادم المشاركة الشبكة استخدم WiFi فقط @@ -255,7 +266,6 @@ تشغيل التحريكات البدء خلال الإقلاع مهلة الانتظار قبل رفض المكالمة (بالثواني) - خادم المشاركة التهيئة عن بعد الحساب اﻷوَّلي الإسم المعروض @@ -269,18 +279,22 @@ الرجوع لوحة المفاتيح + القائمة تبديل الميكروفون تبديل مكبر الصوت رفض ضع السماعة قبول تحرير + حرر القائمة + صحيح إضافة إلى جهات الاتصال جهة اتصال جديدة - مكالمة + المكالمة مسافة المحادثة إعادة الاتصال + الرجوع إلى لوحة المفاتيح صورة جهة الاتصال إرسال رسالة التفاصيل @@ -288,6 +302,7 @@ إضافة مكالمة محادثة جديدة بحث + ابحث عن جهة الاتصال كل جهات الاتصال جهات اتصال Linphone اتجاه الاتصال @@ -306,9 +321,26 @@ زر الإلغاء حالة الرسالة اجتماع + حقل اسم المستخدم + اعرض حقل الاسم + حقل النطاق + حقل التهيئة البعيدة + حقل تأكيد كلمة السر + حقل البريد الإلكتروني الحساب الافتراضي + أزل تحديد الكل + حدد الكل + احذف التحديد اﻹسم اللقب + ارجع إلى المكالمة + أرسل ملفا + رسالة + الرسائل غير المقروءة تحويل + سماعة الأذن بلوتوث + خيارات المكالمة + توجيه الصوت + مغادرة الاجتماع diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index b9a9e73a3..bb698323b 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -6,11 +6,28 @@ Linphone Linphone Startvorgang + %s registriert + %s konnte nicht registrieren + Linphone Android %s + Linphone-Kern %s + GNU General Public License V2\n © 2010-2016 Belledonne Communications + www.linphone.org + Linphone-Kontakte + EEE, t MMM + jjjj/MM/tt - HH:mm - + tt/MM, HH:mm + tt/MM + HH:mm Benutzername Anzeigename Passwort + Passwortbestätigung + Domain + URL + E-Mail + Sind Sie sicher, dass Sie Ihre Auswahl löschen möchten? Löschen Erneut versuchen Abbrechen @@ -18,34 +35,75 @@ Fortsetzen Über Verweigern + Kein Konto konfiguriert Suchen Ausgehend Eingehend Verpasst Einstellungen + Verbindung Ablehnen Konferenz + der freie SIP-Client + Willkommen + Assistent + Konto erstellen + Konfiguration fertigstellen + Ihr Konto ist erstellt. Bitte überprüfen Sie Ihre E-Mails, um Ihr Konto zu bestätigen. Sobald das gemacht ist, kommen Sie hierher zurück und klicken Sie auf die Schaltfläche. Dieser Assistent wird Ihnen dabei helfen, ein SIP-Konto für Ihre Anrufe zu verwenden. + Geben Sie Ihren Benutzernamen und Passwort des Linphone-Kontos ein + Geben Sie Ihren Benutzernamen und Passwort mit Ihrer SIP-Domäne ein + Bitte geben Sie eine Bereitstellungs-URL an Transport + Linphone-Konto verwenden + SIP-Konto verwenden + Fernkonfiguration abrufen + 1/2 + 2/2 + Anzeigename (optional) + Linphone-Konto konfigurieren + SIP-Konto konfigurieren + Fernkonfiguration abrufen + Abrufen und anwenden + Anmelden + Echounterdrückungskalibrierung läuft + Geben Sie Ihre Anmeldung ein Ihr Konto wurde noch nicht überprüft. Ihr Konto wurde überprüft. + Falscher Benutzername oder Passwort Es ist ein Fehler aufgetreten, versuchen Sie es später nochmal + Server nicht erreichbar, überprüfen Sie Ihre Netzwerkverbindung. Der Benutzername wird bereits verwendet. + Ihr Benutzername ist ungültig. + Ihre E-Mail-Adresse ist ungültig. + Ihr Passwort ist ungültig. + Passwörter stimmen nicht überein. + Ihr Benutzername wird %s sein.\r\n\r\nIt kann von Ihrer Eingabe abweichen, um Anforderungen zu entsprechen.\r\nNehmen Sie an? Bitte geben Sie Ihren Benutzername und Ihr Passwort ein + Passwort vergessen? + Geben Sie eine Nummer oder eine Adresse ein + Kein Anruf in Ihrer Chronik + Kein verpasster Anruf in Ihrer Chronik + Möchten Sie das ausgewählte Anrufprotokoll löschen? Heute Gestern Kein Kontakt in Ihrem Adressbuch. Kein SIP-Kontakt in Ihrem Adressbuch. + Möchten Sie die ausgewählten Kontakte löschen? + Möchten Sie den ausgewählten Kontakt löschen? SIP-Adresse Telefonnummer Vorname Nachname + Keine Gespräche + Möchten Sie das ausgewählte Gespräch löschen? + Möchten Sie die ausgewählte Nachricht löschen? Partner schreibt... Klein Mittel @@ -60,13 +118,23 @@ Bild wird verarbeitet. Je nach Größe der Datei kann dies mehrere Sekunden in Anspruch nehmen Registriert + Nicht registriert Registrierung in Arbeit Registierung fehlgeschlagen ungelesene Nachrichten + Assistent Einstellungen Über + Schließen + eingehender Anruf + ausgehender Anruf + Ihr Partner möchte Video einschalten + Kein aktiver Anruf + Ihr Partner hat den Anruf pausiert + Beim Annehmen des Anrufs ist ein Fehler aufgetreten + ZRTP-Token ist %s\nSie sollten nur annehmen, wenn Sie den gleichen Token wie Ihr Partner haben Unbekannt Audio Video @@ -88,16 +156,20 @@ Warnung: Dienst ist nicht bereit Fehler + Kann Zieladresse aus %s nicht bauen Unbekannter Fehler Anruf abgelehnt Benutzer nicht gefunden Inkompatible Medienparameter + Ihr Partner hat eine niedrige Bandbreite, Video kann nicht gestartet werden Netzwerk ist nicht erreichbar Falsche Anmeldedaten Unzulässig Netzwerkfehler + Herunterladen fehlgeschlagen. Bitte überprüfen Sie Ihre Netzwerkverbindung oder versuchen Sie es später erneut. Fehler beim Herunterladen oder Anwenden des Fernbereitstellungsprofils... Fernbereitstellung + Möchten Sie die Bereitstellungs-URI ändern? SIP-Konto Verwalten @@ -111,13 +183,16 @@ Alle Anrufe üder einen SIP Proxy leiten Beispiel: John, wenn ihr Konto john@sip.example.org ist sip.example.org, wenn Ihr Konto john@sip.example.org ist - Sie müssen Ihr Passwort erneut eingeben, wenn Sie Ihren Benutzernamen und/oder Domain ändern + Sie müssen Ihr Passwort erneut eingeben, wenn Sie Ihren Benutzernamen und/oder Domain bearbeiten Ablaufen AVPF AVPF Standard RTCP Interval in Sekunden (zwischen 1 und 5) Ersetzen + durch 00 + Freundesliste abonnieren Authentifizierungs-Benutzerkennung + Authentifizierungs-Benutzerkennung eingeben (optional) Anzeigename + Anzeigename eingeben (optional) Präfix Transport UDP @@ -147,7 +222,9 @@ Audio Echounterdrückung Entfernt das Echo, das am anderen Ende gehört wird + Echounterdrückungskalibrierung Kalibrierung... + Kalibriert in %s ms Kein Echo fehlgeschlagen Adaptive Ratenregelung @@ -155,20 +232,34 @@ Codecs Video + Videoeinblendung + Anrufvideo in Einblendung anzeigen, wenn Sie außerhalb der Anwendung sind Frontkamera benutzen Videoanrufe starten Immer Videoanfragen senden Eingehende Videoanfragen annehmen Videoanfragen immer annehmen + Videovoreinstellung Bevorzugte Videogröße + Bevorzugte FPS Bandbreitenbegrenzung in kbits/s Codecs Anruf RFC2833 DTMFs senden SIP INFO DTMFs senden + Sprachnachricht-URI + + Nachrichten + Gemeinsamer Server + Nicht bearbeiten, außer Sie wissen, was Sie tun! + LIME-Verschlüsselung verwenden + Deaktiviert + Obligatorisch + Bevorzugt Netzwerk + Nur WiFi verwenden Stun-Server ICE aktivieren UPNP aktivieren @@ -180,12 +271,15 @@ Audioport oder Portbereich (Min.Port-Max.Port) Medienverschlüsselung Push-Benachrichtigungen aktivieren + IPv6 erlauben Erweitert Debug Hintergrundmodus Animationen aktivieren + Dienstbenachrichtigung aktivieren Beim Einschalten starten + Auflegen bei eingehendem Anruf (in Sekunden) Fernbereitstellung Primäres Konto Anzeigename @@ -199,24 +293,30 @@ Zurück Wählgerät + Menü Mikrofon umschalten Lautsprecher umschalten Ablehnen Auflegen Annehmen - Ändern + Bearbeiten + Liste bearbeiten + Gültig Zu Kontakten hinzufügen Neuer Kontakt Call Zurückschalten Nachrichten Zurückrufen + Zurück zum Anrufer Kontaktbild Nachricht senden + Details Löschen Anruf hinzufügen Neue Diskussion Suchen + Kontakt suchen Alle Kontakte Linphone-Kontakte Anrufrichtung @@ -235,9 +335,26 @@ Schaltfläche Abbrechen Nachrichtenstatus Konferenz + Benutzernamenfeld + Anzeigenamenfeld + Domänenfeld + Fernbereitstellungsfeld + Passwortbestätigungsfeld + E-Mail-Feld Standardkonto + Alle abwählen + Alle auswählen + Auswahl löschen Vorname Nachname + Zurück zum Anruf + Datei senden + Nachricht + Ungelesene Chatnachricht Weiterleiten + Ohrhörer Bluetooth + Anrufoptionen + Audioroute + Konferenz beenden diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index bff343ed5..f0b79081c 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -7,6 +7,8 @@ Linphone Iniciando + contactos linphone + HH:mm Nombre de usuario Nombre a mostrar @@ -144,6 +146,8 @@ Llamar Enviar DTMS RFC2833 + + Chat Red Servidor STUN diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index 0462a2b48..cef47c494 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -9,6 +9,12 @@ Rekisteröity kohteeseen %s Epäonnistui rekisteröidä kohteeseen %s + linphone yhteystiedot + VVV, p KKK esim. Maanantai, 1 Tam + vvvv/KK/dd - TT:mm - esim 2012/11/22 - 12:34 + pp/KK, TT:mm esim 22/11, 12:34 + pp/KK esim 22/11 + TT:mm esim. 11:11 Käyttäjätunnus Näytä nimi @@ -232,6 +238,9 @@ Lähetä RFC2833 DTMFs Lähetä SIP INFO DTMFs Ääni postin URI-osoite + + Keskustelu + Jaa palvelin Verkko Käytä vain wifiä @@ -254,7 +263,6 @@ Salli animaatiot Käynnistä laitteen käynnistyessä Saapuva puhelu aikakatkaisu (sekunneissa) - Jaa palvelin Vastapuoli hakee asetuksia Pääasiallinen tili Näytä nimi diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index a87292af8..4dc80e8ca 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -9,6 +9,16 @@ %s enregistré %s n\'a pas pu s\'enregistrer + Linphone Android %s + Linphone Core %s + GNU General Public License V2\n © 2010-2016 Belledonne Communications + www.linphone.org + contacts linphone + EEE, d MMM + dd/MM/yyy - HH:mm - + dd/MM, HH:mm + dd/MM + HH:mm Nom d\'utilisateur Nom d\'affichage @@ -35,6 +45,7 @@ Refuser Conférence + le client SIP libre Bienvenue Assistant @@ -72,6 +83,7 @@ Lorsque cela est fait, cliquez sur le bouton pour continuer. Les mots de passes ne correspondent pas. Votre nom d\'utilisateur sera %s.\r\n\r\nIl peut différer de votre saisie.\r\nContinuer ? Entrez votre nom d\'utilisateur et votre mot de passe + Mot de passe oublié ? Entrez un numéro ou une adresse @@ -177,6 +189,7 @@ Lorsque cela est fait, cliquez sur le bouton pour continuer. AVPF Intervalle AVPF RTCP régulier en secondes (entre 1 et 5) Remplacer + par 00 + Souscrire à la liste d\'amis Identifiant d\'authentification Entrez l\'userid d\'authentification (optionnel) Nom d\'affichage @@ -192,6 +205,7 @@ Lorsque cela est fait, cliquez sur le bouton pour continuer. Comptes SIP Compte par défaut Ajouter un compte + Magasin Tunnel Hôte Port @@ -220,6 +234,8 @@ Lorsque cela est fait, cliquez sur le bouton pour continuer. Codecs Vidéo + Vidéo détachable + Affiche la video d\'un appel en dehors de l\'application Utiliser la caméra en façade Initier les appels en vidéo Toujours envoyer des demandes d\'appels vidéo @@ -232,9 +248,19 @@ Lorsque cela est fait, cliquez sur le bouton pour continuer. Codecs Appel + Utiliser la sonnerie du téléphone + Décrocher automatiquement appels entrants Envoyer les DTMFs RFC2833 Envoyer les DTMFs en SIP INFO URI de boîte vocale + + Chat + Serveur de partage + Ne changez pas cette valeur sans savoir ce que vous faites ! + Encrypter avec LIME + Désactivé + Obligatoire + Préferré Réseau Utiliser WiFi uniquement @@ -255,9 +281,9 @@ Lorsque cela est fait, cliquez sur le bouton pour continuer. Activer les traces de débogage Actif en arrière plan Activer les animations + Notification de service Démarrer au lancement du téléphone Ignorer les appels entrants après (en secondes) - Serveur de partage Configuration distante Compte principal Nom d\'affichage @@ -271,6 +297,7 @@ Lorsque cela est fait, cliquez sur le bouton pour continuer. Retour Dialer + Menu Basculer micro Basculer haut-parleur Refuser @@ -315,11 +342,13 @@ Lorsque cela est fait, cliquez sur le bouton pour continuer. Champ nom d\'utilisateur Champ nom d\'affichage Champ domaine + Champ de configuration distante Champ confirmation du mot de passe Champ email Compte par défaut Tout déselectionner Tout sélectionner + Supprimer la sélection Prénom Nom Retour à l\'appel diff --git a/res/values-he/strings.xml b/res/values-he/strings.xml index 76345d7ff..e5cd6517f 100644 --- a/res/values-he/strings.xml +++ b/res/values-he/strings.xml @@ -67,6 +67,8 @@ וידאו קריאה + + שיחה רשת שרת Stun diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index c9226fa3e..112d9524b 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -9,6 +9,16 @@ %sを登録しました %sの登録に失敗しました + Linphone Android %s + Linphone Core %s + GNU ライセンス V2\n © 2010-2016 Belledonne Communications + www.linphone.org + linphoneにたずねる + EEE, d MMM + yyyy/MM/dd - HH:mm - + dd/MM, HH:mm + dd/MM + HH:mm ユーザー名 表示する名前 @@ -64,19 +74,33 @@ ユーザー名かパスワードが異なります エラーが発生しました。のちほど再試行してください。 このユーザー名はすでに使われています。 + 不適切なユーザー名です + 不適切なメールアドレスです + 不適切なパスワードです + パスワードが一致しません ユーザー名とパスワードを入力してください + パスワードを忘れましたか? + 番号もしくはアドレスを入力してください + 発信履歴がありません + 発信ミス履歴がありません + 本当に選択した通話履歴を削除しますか? 今日 昨日 電話帳に連絡先がありません 電話帳にSIPの連絡先がありません + 本当に選択した連絡先を削除しますか? + 本当に選択した連絡先を削除しますか? SIPアドレス 電話番号 名前 名字 + 新しい会話はありません + 本当に選択した会話を削除しますか? + 本当に選択したメッセージを削除しますか? リモート先が入力中... 小さい 中くらい @@ -103,6 +127,7 @@ 着信 発信 + 有効な発信はありません 不明 オーディオ ビデオ @@ -132,6 +157,7 @@ 不正な証明書です 無断 ネットワークエラー + ダウンロードに失敗しました。ネットワークを確認して再度操作してください。 ダウンロードした、リモートプロビジョニング設定を適用できませんでした... 遠隔準備 @@ -154,6 +180,7 @@ 00 で置き換える ユーザーIDを認証 表示名 + 表示する名前(任意) プレフィックス トランスポート UDP @@ -165,6 +192,7 @@ SIPアカウント デフォルトのアカウント アカウントを追加する + アプリストアで トンネル ホスト名 ポート @@ -183,6 +211,7 @@ オーディオ エコーキャンセル 相手が聞こえるエコーを削除する + エコーキャンセラーの調整 調整中... %s msで調整しました エコーなし @@ -207,6 +236,10 @@ DTMFをRFC2833で送信する DTMFをSIP情報で送信する 音声メールのURI + + チャット + 共有サーバー + 無効にする ネットワーク WiFiのみ @@ -227,8 +260,8 @@ デバッグ バックグラウンド動作 アニメーションを有効にする + サービス通知を有効にする 起動時に開始する - 共有サーバー 遠隔準備 優先アカウント 表示名 @@ -242,18 +275,22 @@ 戻る ダイヤラー + メニュー マイク切り替えトグル スピーカー切り替えトグル 拒否 ハングアップ 受理する 編集 + 編集リスト + 適正 連絡先に追加 新しい連絡先 発信 バックスペース チャット コールバック + ダイヤル画面に戻る 連絡相手の画像 送信メッセージ 詳細 @@ -261,6 +298,7 @@ 追加発信 新しいやりとりを行う 検索 + 連絡先を検索する すべての連絡先 Linphoneでの連絡先 宛先を指定 @@ -279,9 +317,22 @@ キャンセルボタン メッセージ状態 会談 + ユーザー名 + 表示名 + ドメイン + パスワードの再入力 + メールアドレス デフォルトのアカウント + 全ての選択を外す + 全てを選択する 名前 名字 + 発信に戻る + ファイルを送信する + メッセージ + 未読件数 転送 Bluetooth + 発信オプション + 会議を終了する diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index b900a4041..d113654d2 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -7,6 +7,7 @@ Linphone Bezig met opstarten + HH:mm Gebruikersnaam Weergavenaam @@ -94,6 +95,8 @@ Codecs Oproep + + Chat Netwerk Stun-server diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index cf0359110..6445c8332 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -161,6 +161,9 @@ Ligar Enviar RFC2833 DTMFs Enviar SIP INFO DTMFs + + Chat + Servidor de compartilhamento Network Servidor Stun @@ -180,7 +183,6 @@ Em segundo plano Ativar Animações Iniciar na inicialização - Servidor de compartilhamento Provisionamento remoto Conta primária Mostrar nome diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 50ecb988f..96a0910d8 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -2,49 +2,97 @@ Linphone + Служба Linphone Linphone Linphone Загружается + %s зарегистрирован + %s зарегистрировать не удалось Имя пользователя - Display name + Отображаемое имя Пароль + Подтверждение пароля + Домен + URL + Электронная почта + Вы уверены, что хотите удалить выбранное? Удалить - Retry + Повторить Отменить Принять Продолжить О программе - Deny + Отклонить + Нет настроенных аккаунтов + Поиск Исходящий Входящий Пропущенный Настройки + Подключение Отклонить Конференция - Этот помощник поможет Вам настроить учётную запись SIP для звонков. + Добро пожаловать + Ассистент + Создать аккаунт + Завершить настройку + Ваш аккаунт создан. Пожалуйста, проверьте электронную почту, чтобы подтвердить свой аккаунт. Как только это будет сделано, вернитесь сюда и нажмите на кнопку. + Этот ассистент поможет настроить SIP-аккаунт для звонков. + Введите имя пользователя и пароль от аккаунта Linphone + Введите имя пользователя и пароль с доменом SIP + Пожалуйста, введите URL конфигурирования Транспорт + Исп. аккаунт Linphone + Исп. SIP-аккаунт + Удалённое конфигурирование + 1/2 + 2/2 + Отображаемое имя (необязательно) + Настройка аккаунта Linphone + Настройка SIP-аккаунта + Удалённое конфигурирование + Извлечь и применить + Логин + Выполняется калибровка эхоподавления + Введите логин Ваша учётная запись ещё не подтверждена. Ваша учётная запись подтверждена. - Произошла ошибка, попробуйте повторить позже. - Это имя пользователя уже использовано. - Пожалуйста введите имя пользователя и пароль + Неверное имя пользователя или пароль + Произошла ошибка, повторите попытку позже. + Сервер недоступен, проверьте подключение к сети. + Это имя пользователя уже используется. + Неверное имя пользователя. + Неверный адрес эл. почты. + Неверный пароль + Пароли не совпадают. + Ваше имя пользователя будет %s.\r\n\r\nОно может отличаться от введённого для соответствия требованиям.\r\nВы согласны? + Пожалуйста, введите имя пользователя и пароль + Введите номер или адрес + В журнале нет вызовов + В журнале нет пропущенных вызовов + Вы действительно хотите удалить выбранный журнал вызовов? Сегодня Вчера - Нет контакта в Вашей адресной книге. - Нет SIP контакта в Вашей адресной книге. - адрес SIP + В адресной книге нет контактов. + В адресной книге нет SIP контактов. + Вы действительно хотите удалить выбранные контакты? + Вы действительно хотите удалить выбранный контакт? + Адрес SIP Номер телефона Имя Фамилия - Remote is writing... + Нет разговоров + Вы действительно хотите удалить выбранный разговор? + Вы действительно хотите удалить выбранные сообщения? + Собеседник пишет... Маленький Средний Большой @@ -54,69 +102,95 @@ Выбрать источник Картинка сохранена Ошибка, картинка не сохранена - Please wait... + Пожалуйста, подождите... + Обработка изображения может занять несколько секунд в зависимости от размера файла Зарегистрирован + Не зарегистрирован В процессе регистрации Ошибка регистрации + непрочитанных сообщений + Ассистент Настройки О программе + Выход - Неизвестнвй + входящий вызов + исходящий вызов + Ваш собеседник хотел бы включить видео + Нет активного вызова + Ваш собеседник поставил звонок на паузу + Произошла ошибка во время принятия вызова + ZRTP токен %s\nВы должны принять только если у вас тот же токен, как у вашего собеседника + Неизвестный Аудио Видео Кодек: Полоса пропускания загрузки: Полоса пропускания скачивания: Подключение ICE: - Video size: - Звонок + Размер видео: + Вызов + Отправить журнал + Сброс журнала - Идёт Аудио звонок - Звонок на Паузе - Идёт Видео звонок + Идёт аудиозвонок + Звонок на паузе + Идёт видеозвонок начат - %i unread messages + %i непрочитанных сообщений - Внимание : сервис не готов + Внимание: сервис не готов Ошибка - Звонок сброшен + Невозможно установить адрес назначения из %s + Неизвестная ошибка + Вызов сброшен Пользователь не найден Несовместимые параметры потока + У вашего собеседника низкая пропускная способность, видео не может быть запущено Сеть недоступна - Failed to download or apply remote provisioning profile... - Remote provisioning + Неверные учетные данные + Неавторизован + Ошибка сети + Скачать не удалось. Пожалуйста, проверьте сетевое подключение или повторите попытку позже. + Не удалось скачать или применить профиль удалённого конфигурирования... + Удаленное конфигурирование + Вы действительно хотите изменить URI конфигурирования? - Имя SIP - Manage - Деактивировать + SIP-аккаунт + Управление + Отключить Прокси - Сервер* + Домен* Пароль* Имя пользователя* Исходящий прокси - Имя сервера SIP прокси или адрес ip (необязательно) - Отправить все звонки через SIP прокси - Например: john если Ваш адрес john@sip.example.org - sip.example.org если Ваш адрес john@sip.example.org - You have to re-enter your password if you edit the username and/or the domain + Имя сервера SIP прокси или ip адрес (необязательно) + Отправлять все вызовы через SIP прокси + Например: john если ваш адрес john@sip.example.org + sip.example.org если ваш адрес john@sip.example.org + Вы должны повторно ввести ваш пароль, если вы измените имя пользователя и/или домен Истекает + AVPF + AVPF регулярный интервал RTCP в секундах (от 1 до 5) Заменить + на 00 - Auth userid - Display name + Имя для аутентификации + Введите имя для аутентификации (необязательно) + Отображаемое имя + Введите отображаемое имя (необязательно) Префикс Транспорт UDP TCP TLS - Удалить учётную запись - Использовать как основную + Удалить аккаунт + Использовать по умолчанию - Учётные записи SIP - Default account - Добавить учётную запись + SIP-аккаунты + Аккаунт по умолчанию + Добавить аккаунт Туннель Сервер Порт @@ -128,35 +202,47 @@ всегда авто - Отсутствует + Нет Настройки - Разрешить видео + Включить видео Аудио - Шумоподавление - Удаляет эхо, слышимое другой стороной - Настраиваем… + Эхоподавление + Устраняет эхо, слышимое другой стороной + Калибровка эхоподавления + Калибровка… + Откалибровано в %s мс Нет эха - неудавшийся + не удалось + Адаптивное управление скорость + Ограничение битрейта кодека Кодеки Видео Использовать фронтальную камеру - Начинать видео звонки + Начинать видеозвонки Всегда посылать видео запросы - Принимать входящие видео звонки + Принимать входящие видеозвонки Всегда принимать видео запросы - Preferred video size + Предустановка видео + Предпочтительный размер видео + Предпочтительный FPS + Ограничение пропускной способности в Кбит/с Кодеки - Звонок - Послать RFC2833 DTMFs - Послать SIP INFO DTMFs + Вызов + Отправлять RFC2833 DTMFs + Отправлять SIP INFO DTMFs + URI голосовой почты + + Чат + Сервер обмена Сеть + Использовать только WiFi Сервер Stun - Разрешить ICE - Enable UPNP + Включить ICE + Включить UPNP Использовать случайный порт SIP порт занят Видео порт или диапазон портов @@ -164,16 +250,17 @@ Видео порт или диапазон портов (минимум-максимум) Аудио порт или диапазон портов (минимум-максимум) Шифрование потока - Разрешить серверные уведомления + Включить push-уведомления + Разрешить IPv6 - Продвинутые + Дополнительно Отладка Фоновый режим - Разрешить анимацию - Запускаться с системой - Общий сервер - Удалённое резервирование - Основная учётная запись + Включить анимацию + Запуск при загрузке + Отклонение входящего вызова (в секундах) + Удалённое конфигурирование + Основной аккаунт Отображаемое имя Имя пользователя @@ -184,22 +271,65 @@ Использовать аудио хак Galaxy S Назад - Клавиатура + Номеронабиратель + Меню + Переключить микрофон + Переключить динамик Отклонить Положить трубку - Accept + Принять Редактировать - Кнопка добавить к контактам + Редактировать список + Добавить в контакты Новый контакт - Звонок + Вызов Чат + Вернуться к номеронабирателю + Изображение контакта + Отправить сообщение + Подробнее Удалить - Добавить звонок - Добавить звонок + Добавить вызов + Новая дискуссия + Поиск + Поиск контакта + Все контакты + Контакты Linphone + Направление вызова + Все вызовы + Пропущенные вызовы + Переключить видео + Добавить вызов + Пауза + Цифровая клавиатура + Кнопка истории + Кнопка чата + Кнопка контактов + Качество вызова + Шифрование + Переключить камеру + Кнопка отмены + Статус сообщения Конференция - Default account + Поле имени пользователя + Поле отображаемого имени + Поле домена + Поле удалённого конфигурирования + Поле подтверждения пароля + Поле электронной почты + Аккаунт по умолчанию + Отменить выбор + Выбрать всё + Удалить выбранное Имя Фамилия + Вернуться к вызову + Отправить файл + Сообщение + Непрочитанное сообщение чата Перевести + Наушник Bluetooth + Параметры вызова + Выйти из конференции diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 16090a149..6da76c63d 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -7,6 +7,8 @@ Линфон Покрећем се + контакти линфона + ЧЧ:мм Корисничко име Приказано име @@ -167,6 +169,9 @@ Позови Пошаљи РФЦ2833 ДТМФ-е Пошаљи СИП ИНФО ДТФ-е + + Ћаскање + Сервер дељења Мрежа Стун сервер @@ -186,7 +191,6 @@ Режим позадине Укључи анимације Покрени се приликом подизања система - Сервер дељења Прибављање удаљеног Главни налог Приказано име diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 700f548ce..340d48e6e 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -7,6 +7,7 @@ Linphone Startar upp + linphone-kontakter Användarnamn Visningsnamn @@ -132,6 +133,9 @@ Ring Skicka RFC2833 DTMF + + Chatt + Delar server Nätverk Stun-server @@ -145,7 +149,6 @@ Bakgrundsläge Aktivera animeringar Starta vid uppstart - Delar server Primärt konto Visningsnamn Användarnamn diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml index 253027cef..d709cec2c 100644 --- a/res/values-tr/strings.xml +++ b/res/values-tr/strings.xml @@ -6,46 +6,95 @@ Linphone Linphone Başlatılıyor + %s kayıtlı + %s kaydedilemedi + Linphone bağlantıları + SS:dd Kullanıcı adı Görünen ad Parola + Parola doğrulama + Alan adı + URL + Eposta + Seçimlerinizi silmek istediğinizden emin misiniz? Sil Yeniden dene İptal Kabul et - Sürdürmek + Sürdür Hakkında Yoksay + Yapılandırılmış hesap yok Arama Giden Gelen Yanıtsız Ayarlar + Bağlantı Reddet Çoklu görüşme + özgür SIP istemcisi + Hoş geldiniz + Yardımcı + Hesap Oluştur + Yapılandırmayı bitir + Hesabınız oluşturuldu.Hesabınız için geçerli posta adresinize bakın lütfen.Onu yapınca geri dön ve düğmeyi tıkla. Bu yardımcı, aramalarınız için bir SİP hesabı kullanmanıza yardım edecek. + Linphone hesabınızın kullanıcı adı ve parolasını girin + SIP alan adı ile kullanıcı adınız ve parolanızı girin + Lütfen yetkilendirme adresinizi girin Taşıma + Linphone hesabı kullan + SIP hesabı kullan + Uzaktan yapılandırma al + 1/2 + 2/2 + Görünen ad (isteğe bağlı) + Linphone hesabı yapılandır + SIP hesabı yapılandır + Uzaktan yapılandırma al + Al ve uygula + Giriş + Yankı giderme ayarlaması sürüyor + Giriş bilgilerinizi girin Hesabınız henüz onaylanmadı. Hesabınız onaylandı. + Geçersiz kullanıcı adı ve parola Bir hata oluştu,daha sonra tekrar deneyin. + Sunucuya ulaşılamıyor,ağ bağlantınızı kontrol edin. Bu kullanıcı adı zaten kullanılıyor. + Kullanıcı adınız geçersiz. + Epostanız geçersiz. + Parolanız geçersiz. + Parolalar eşleşmiyor. + Kullanıcı adınız %s olacak.\r\n\r\nGereklilikleri sağlaması için sizin girdiğinizden farklı olabilir.\r\nKabul ediyor musunuz? Lütfen giriş adınızı ve parolanızı girin + Numara veya adres girin + Çağrı geçmişiniz boş + Geçmişinizde yanıtsız çağrı yok + Seçilmiş çağrı kayıtlarını silmek ister misin? Bugün Dün Adres defterinizde kimse yok Adres defterinizde SİP bağlantısı yok + Seçilen bağlantıları silmek ister misiniz? + Seçilen bağlantıyı silmek ister misiniz? SİP adresi Telefon numarası Ad Soyadı + görüşme yok + Seçilen görüşmeyi silmek ister misiniz? + Seçilen iletiyi silmek ister misiniz? Karşıdan yazılıyor... Küçük Orta @@ -57,15 +106,26 @@ Resim kaydedildi Hata,resim kaydedilmedi Lütfen bekleyin... + Görüntü işleniyor, dosyanın boyutuna bağlı olarak bir kaç saniye sürebilir Kayıtlı + Kayıtsız Kayıt sürüyor Kayıt başarısız okunmamış iletiler + Yardımcı Ayarlar Hakkında + Çık + Gelen çağrı + Giden çağrı + Görüştüğünüz kişi görüntüyü açmak istiyor + Etkin arama yok + Görüştüğünüz kişi aramayı duraklattı + Gelen aramanın kabulünde bir hata oluştu + ZRTP fişiniz %s\nBunu sadece görüştüğünüz kişinin fişiyle aynıysa kabul etmelisiniz Bilinmeyen Ses Görüntü @@ -87,15 +147,20 @@ Uyarı: hizmet hazır değil Hata + %s dan gidilecek adres inşa edilemiyor Tanımlanmayan hata Reddedilen çağrı Kullanıcı bulunamadı Uyumsuz ortam değişkenleri + Görüştüğünüz kişinin bant genişliği düşük, görüntü başlatılamaz. Ağa erişim yok Referansı kötü Kimlik doğrulanmadı Ağ hatası + İndirme başarısız. Lütfen ağ bağlantınızı gözden geçirin ya da daha sonra tekrar deneyin. + Uzaktan yetkilendirme profili indirilirmesi ya da uygulanması başarısız... Uzaktan yetkilendirme + Uzaktan yetkilendirme adresinizi değiştirmek istiyor musunuz? SİP Hesabı Yönetme @@ -108,11 +173,16 @@ SİP vekil sunucu makine adı veya ip adresi (isteğe bağlı) Bütün çağrıları SİP vekil sunucuya yönlendir Örneğin: John eğer sizin hesabınız john@sip.example.org ise + eğer hesabınız john@sip.example.org ise sip.example.org Kullanıcı adı veya alan adı oluşturduysanız parolanızı tekrar girmeniz gerekir Süresi dolmak AVPF + AVPF düzenli RTCP aralığında ( 1 ile 5 saniye arasında) + +\'yı 00 ile değiştir Kullanıcı kimliği yetkisi + Kullanıcı kimliği doğrulumayı girin (isteğe bağlı) Görünen ad + Görünen adı girin (isteğe bağlı) Önek Taşıma UDP @@ -142,8 +212,10 @@ Ses Yankı giderme Karşıdan gelen yankılı sesi kaldır + Yankı giderme ayarı Ayarlama... - Eko yok + %s ms\'de ayarlandı + Yankı yok başarısız Uyarlanabilir oran denetimi Çözücü bitrate sınırı @@ -155,15 +227,22 @@ Görüntü isteğini her zaman gönder Gelen görüntü isteklerini kabul et Görüntü isteklerini her zaman kabul et + Görüntü ön ayarı Yeğlenen görüntü boyutu + Yeğlenen FPS kbits/s olarak bant genişliği Çözücüler Çağrı RFC2833 DTMF\'yi gönder SIP INFO DTMF\'yi gönder + Sesli posta adresi + + Sohbet + Sunucu paylaşımı + Sadece WİFİ kullan Stun sunucusu İCE Etkin UPNP Etkin @@ -175,13 +254,14 @@ Ses bağlantı noktası veya bağlantı noktası aralığı (minport-maxport) Ortam şifreleme Anlık bildirim etkin + IPv6 ya izin ver Gelişmiş Hata ayıklama Artalan kipi Animasyonlar etkin Başlangıçta çalıştır - Sunucu paylaşımı + Gelen çağrı kapandı (anında) Uzaktan yetkilendirme Ana hesap Görünen ad @@ -189,28 +269,36 @@ Ses kesme Özgün kesme kipi kullan + 0=NORMAL_KİP (öntanımlı), 2=GELEN_ÇAĞRI_KİPİ + API hack yönlendirmesini kullanın Galaxy S ses kesmeyi kullan Geri Telefon numarası çevirici + Menü Mikrofon düğmesi Hoparlör düğmesi Reddet Telefonu kapat Kabul et Düzenle + Liste Düzenle + Geçerli Bağlantılara ekle Yeni bağlantı Çağrı Geri alma Sohbet Geri aramalı + Çeviriciye dön Kayıtlı kişinin resmi İleti gönder + Ayrıntılar Sil Arama ekle Yeni tartışma Arama + Bağlantı ara Tüm bağlantılar Linphone bağlantıları Çağrı yönlendirme @@ -229,9 +317,26 @@ İptal düğmesi İleti durumu Çoklu görüşme + Kullanıcı adı alanı + Görünen ad alanı + Alan adı alanı + Uzaktan yetkilendirme alanı + Parola onaylama alanı + Eposta alanı Öntanımlı hesap + Tüm seçilenleri iptal et + Tümünü seç + Şeçimi Sil Ad Soyadı + Aramaya dön + Bir dosya gönder + İleti + Okunmamış sohbet iletisi Aktarma + Kulaklık Bluetooth + Çağrı seçenekleri + Ses yolu + Görüşmeden çık diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index df11179da..8f70ad4a9 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -1,11 +1,23 @@ + Linphone + Linphone 服務 + Linphone + Linphone + 啟動中 + %s 已註冊 + %s 無法註冊 使用者名稱 顯示名稱 密碼 + 密碼確認 + 網域 + 網址 + 電子郵件 + 你確定要刪除選取的項目嗎? 刪除 重試 取消 @@ -14,28 +26,65 @@ 關於 拒絕 搜尋 + 撥出 + 來電 未接來電 設定 + 連接 拒絕 會議 + 自由的 SIP 客戶端 + 歡迎 + 助理 + 建立帳號 + 完成設定 + 你的帳號已經建立。請檢查你的郵件來驗證你的帳號。完成時,回到這裡並點擊按鈕。 + 這個助理將幫助你使用一個 SIP 帳號來通話。 + 輸入你 Linphone 帳號的使用者名稱和密碼 傳輸 + 使用 Linphone 帳號 + 使用 SIP 帳號 + 1/2 + 2/2 + 顯示名稱(選擇性) + 設定 Linphone 帳號 + 設定 SIP 帳號 + 登入 + 正在進行回音消除器校正 你的帳號還沒被驗證。 你的帳號已經被驗證。 + 不正確的使用者名稱或密碼 發生錯誤,請稍候再試。 + 無法連接到伺服器,請確認你的網路連接。 這個使用者名稱已經被使用。 + 你的使用者名稱無效。 + 你的電子郵件無效。 + 你的密碼無效。 + 密碼不相符 + 輸入號碼或位址 + 歷史中沒有通話 + 歷史中沒有未接來電 + 你想要刪除選取的通話紀錄嗎? 今天 昨天 通訊錄中沒有連絡人。 通訊錄中沒有 SIP 連絡人。 + 你想要刪除選取的聯絡人嗎? + 你想要刪除選取的聯絡人嗎? + SIP 位址 電話號碼 名字 姓氏 + 沒有對話 + 你想要刪除選取的對話嗎? + 你想要刪除選取的訊息嗎? + 對方正在輸入... @@ -48,13 +97,21 @@ 請稍候... 已註冊 + 未註冊 正在註冊 註冊失敗 未讀訊息 + 助理 設定 關於 + 退出 + 來電 + 撥出電話 + 對方想要啟用視訊 + 對方暫停了通話 + 接電話時發生錯誤 未知 音訊 視訊 @@ -64,15 +121,20 @@ 視訊大小: 通話 + 傳送記錄 + 重設記錄 + 已啟動 %i 未讀訊息 關閉 錯誤 未知錯誤 找不到使用者 + 對方的頻寬過低,視訊無法啟動 無法連接網路 網路錯誤 + 下載失敗。請檢查你的網路連接或稍候再試。 SIP 帳號 管理 @@ -82,11 +144,14 @@ 使用者名稱* 以 00 取代 + 顯示名稱 + 輸入顯示名稱(選擇性) + 前綴 傳輸 UDP TCP TLS 刪除這個帳號 + 設為預設值 SIP 帳號 預設帳號 @@ -109,22 +174,30 @@ 音訊 回音消除 移除另一端聽到的回音 + 回音消除器校正 校正中... + 沒有回音 失敗 編碼位元率限制 編碼 視訊 使用前攝影機 - 開始視訊通話 + 發起視訊通話 總是傳送視訊要求 + 接受來電視訊要求 總是接受視訊要求 + 視訊預設 偏好的視訊大小 + 偏好的 FPS 編碼 通話 + + 聊天 網路 + 只使用 WiFi Stun 伺服器 啟用 ICE 啟用 UPNP @@ -135,6 +208,8 @@ 視訊連接埠或連接埠範圍(最小連接埠-最大連接埠) 音訊連接埠或連接埠範圍(最小連接埠-最大連接埠) 媒體加密 + 啟用推播通知 + 允許 IPv6 進階 除錯 @@ -148,20 +223,26 @@ 返回 撥號器 + 功能表 拒絕 掛斷 接受 編輯 + 編輯清單 + 有效 加入到連絡人 新增聯絡人 通話 Backspace 聊天 回播 + 回到撥號器 連絡人圖片 傳送訊息 + 詳細資料 刪除 搜尋 + 搜尋聯絡人 所有聯絡人 Linphone 聯絡人 通話方向 @@ -169,6 +250,7 @@ 未接來電 切換視訊 暫停 + 數字鍵盤 歷史按鈕 聊天按鈕 聯絡人按鈕 @@ -178,9 +260,22 @@ 取消按鈕 訊息狀態 會議 + 使用者名稱欄位 + 顯示名稱欄位 + 網域欄位 + 確認密碼欄位 + 電子郵件欄位 預設帳號 + 取消全選 + 全選 + 刪除選取項目 名字 姓氏 + 回到通話 + 傳送檔案 + 訊息 + 未讀聊天訊息 轉接 藍牙 + 通話選項 diff --git a/res/values/non_localizable_custom.xml b/res/values/non_localizable_custom.xml index 437890f35..d3931db50 100644 --- a/res/values/non_localizable_custom.xml +++ b/res/values/non_localizable_custom.xml @@ -24,6 +24,10 @@ false false + false + false + false + false false false @@ -31,42 +35,26 @@ true false true - false false - false true - false true - true - - true - - false - false - - false - false - - true - false - - false + true + true + false true false false false - false false false false linphone-android@belledonne-communications.com - false linphone-android-photo-temp linphone-android-photo-%s @@ -82,12 +70,9 @@ false - true true - true - false diff --git a/res/values/non_localizable_strings.xml b/res/values/non_localizable_strings.xml index f3c4727f7..7b0463d28 100644 --- a/res/values/non_localizable_strings.xml +++ b/res/values/non_localizable_strings.xml @@ -97,6 +97,7 @@ pref_codecs_key pref_stun_server_key pref_ice_enable_key + pref_turn_enable_key pref_video_codec_vp8_key pref_media_encryption_key none @@ -201,4 +202,6 @@ pref_use_lime_encryption_key + pref_device_ringtone_key + pref_auto_answer_key diff --git a/res/values/strings.xml b/res/values/strings.xml index f6ce8a7d5..7d6534af1 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -110,6 +110,7 @@ Phone number First name Last name + Organization No conversations @@ -270,6 +271,8 @@ Call + Use device ringtone + Auto answer incoming calls Send RFC2833 DTMFs Send SIP INFO DTMFs Voice mail URI @@ -288,6 +291,7 @@ Use WiFi only Stun server Enable ICE + Enable TURN Enable UPNP Use random ports SIP port to use @@ -376,6 +380,7 @@ Delete selection First name Last name + Organization Back to call Send a file Message diff --git a/res/xml/account_preferences.xml b/res/xml/account_preferences.xml index 2e46704d7..41141d672 100644 --- a/res/xml/account_preferences.xml +++ b/res/xml/account_preferences.xml @@ -3,97 +3,113 @@ + android:key="@string/pref_sipaccount_key" + android:persistent="false"> + android:persistent="false"/> + android:persistent="false"/> + android:inputType="textPassword" + android:persistent="false"/> + android:inputType="textUri" + android:persistent="false"/> + android:persistent="false"/> + android:key="@string/pref_advanced_key" + android:persistent="false"> + android:key="@string/pref_transport_key" + android:persistent="false"/> + android:persistent="false"/> + android:persistent="false"/> + android:numeric="integer" + android:persistent="false"/> + android:key="@string/pref_prefix_key" + android:persistent="false"/> + android:key="@string/pref_avpf_key" + android:persistent="false"/> + android:numeric="integer" + android:persistent="false"/> + android:key="@string/pref_escape_plus_key" + android:persistent="false"/> + android:key="@string/pref_friendlist_subscribe_key" + android:persistent="false"/> + android:key="@string/pref_manage_key" + android:persistent="false"> + android:persistent="false"/> + android:persistent="false"/> + android:persistent="false"/> diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index be34cd865..ceadfee7f 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -1,277 +1,389 @@ + + + + android:key="@string/pref_sipaccounts_key" + android:persistent="false"/> + android:key="@string/pref_add_account_key" + android:persistent="false"/> - - - - - - - - - - + android:key="@string/pref_in_app_store_key" + android:persistent="false"/> - + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + android:key="@string/pref_codecs_key" + android:persistent="false"/> - - - - - - - - - - - - - - + android:persistent="false"> - + + + + + + + + + + + + + + + + + + + + + + android:shouldDisableView="true" + android:persistent="false"/> + + - - - - - + + + + + + + + + + + + + - - + + - + + + + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + android:title="@string/pref_primary_account_title"> - + - + - + + android:key="@string/pref_audio_hacks_use_routing_api_key" + android:persistent="false"/> + android:key="@string/pref_audio_hacks_use_galaxys_hack_key" + android:persistent="false"/> + android:numeric="integer" + android:persistent="false"/> diff --git a/src/org/linphone/AboutFragment.java b/src/org/linphone/AboutFragment.java index 86502d948..ed83cb7e7 100644 --- a/src/org/linphone/AboutFragment.java +++ b/src/org/linphone/AboutFragment.java @@ -23,7 +23,6 @@ import org.linphone.core.LinphoneCore.LogCollectionUploadState; import org.linphone.core.LinphoneCoreListenerBase; import org.linphone.mediastream.Log; -import android.app.Dialog; import android.app.Fragment; import android.app.ProgressDialog; import android.content.Context; @@ -32,11 +31,12 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.support.v4.content.ContextCompat; import android.view.LayoutInflater; import android.view.View; -import android.view.WindowManager; import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.view.WindowManager; import android.widget.ImageView; import android.widget.TextView; @@ -104,7 +104,7 @@ public class AboutFragment extends Fragment implements OnClickListener { uploadInProgress = true; progress = ProgressDialog.show(LinphoneActivity.instance(), null, null); - Drawable d = new ColorDrawable(getResources().getColor(R.color.colorE)); + Drawable d = new ColorDrawable(ContextCompat.getColor(getActivity(), R.color.colorE)); d.setAlpha(200); progress.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); progress.getWindow().setBackgroundDrawable(d); diff --git a/src/org/linphone/AccountPreferencesFragment.java b/src/org/linphone/AccountPreferencesFragment.java index 2b8b78538..a7e982cb1 100644 --- a/src/org/linphone/AccountPreferencesFragment.java +++ b/src/org/linphone/AccountPreferencesFragment.java @@ -35,7 +35,6 @@ import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceCategory; import android.preference.PreferenceScreen; -import android.text.InputType; import android.view.WindowManager; /** @@ -280,7 +279,6 @@ public class AccountPreferencesFragment extends PreferencesListFragment { PreferenceCategory account = (PreferenceCategory) getPreferenceScreen().findPreference(getString(R.string.pref_sipaccount_key)); EditTextPreference username = (EditTextPreference) account.getPreference(0); - username.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); username.setOnPreferenceChangeListener(usernameChangedListener); if (!isNewAccount){ username.setText(mPrefs.getAccountUsername(n)); @@ -288,7 +286,6 @@ public class AccountPreferencesFragment extends PreferencesListFragment { } EditTextPreference userid = (EditTextPreference) account.getPreference(1); - userid.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); userid.setOnPreferenceChangeListener(useridChangedListener); if (!isNewAccount){ userid.setText(mPrefs.getAccountUserId(n)); @@ -296,14 +293,12 @@ public class AccountPreferencesFragment extends PreferencesListFragment { } EditTextPreference password = (EditTextPreference) account.getPreference(2); - password.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); password.setOnPreferenceChangeListener(passwordChangedListener); if(!isNewAccount){ password.setText(mPrefs.getAccountPassword(n)); } EditTextPreference domain = (EditTextPreference) account.getPreference(3); - domain.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); domain.setOnPreferenceChangeListener(domainChangedListener); if (!isNewAccount){ domain.setText(mPrefs.getAccountDomain(n)); @@ -311,7 +306,6 @@ public class AccountPreferencesFragment extends PreferencesListFragment { } EditTextPreference displayName = (EditTextPreference) account.getPreference(4); - displayName.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PERSON_NAME); displayName.setOnPreferenceChangeListener(displayNameChangedListener); if (!isNewAccount){ displayName.setText(mPrefs.getAccountDisplayName(n)); @@ -327,7 +321,6 @@ public class AccountPreferencesFragment extends PreferencesListFragment { } mProxyPreference = (EditTextPreference) advanced.getPreference(1); - mProxyPreference.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); mProxyPreference.setOnPreferenceChangeListener(proxyChangedListener); if (!isNewAccount){ mProxyPreference.setText(mPrefs.getAccountProxy(n)); diff --git a/src/org/linphone/CallActivity.java b/src/org/linphone/CallActivity.java index 321d0a80a..2a3f565c6 100644 --- a/src/org/linphone/CallActivity.java +++ b/src/org/linphone/CallActivity.java @@ -43,7 +43,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; -import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -57,6 +56,7 @@ import android.os.Handler; import android.os.PowerManager; import android.os.SystemClock; import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.support.v4.widget.DrawerLayout; import android.view.Gravity; import android.view.KeyEvent; @@ -66,9 +66,6 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; -import android.view.animation.Animation; -import android.view.animation.Animation.AnimationListener; -import android.view.animation.AnimationUtils; import android.widget.AdapterView; import android.widget.Button; import android.widget.Chronometer; @@ -103,11 +100,10 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve private StatusFragment status; private CallAudioFragment audioCallFragment; private CallVideoFragment videoCallFragment; - private boolean isSpeakerEnabled = false, isMicMuted = false, isTransferAllowed, isAnimationDisabled; + private boolean isSpeakerEnabled = false, isMicMuted = false, isTransferAllowed; private LinearLayout mControlsLayout; private Numpad numpad; private int cameraNumber; - private Animation slideOutLeftToRight, slideInRightToLeft, slideInBottomToTop, slideInTopToBottom, slideOutBottomToTop, slideOutTopToBottom; private CountDownTimer timer; private boolean isVideoCallPaused = false; @@ -150,7 +146,6 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve BluetoothManager.getInstance().initBluetooth(); } - isAnimationDisabled = getApplicationContext().getResources().getBoolean(R.bool.disable_animations) || !LinphonePreferences.instance().areAnimationsEnabled(); cameraNumber = AndroidCameraConfiguration.retrieveCameras().length; try { @@ -291,6 +286,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve callFragment = new CallVideoFragment(); videoCallFragment = (CallVideoFragment) callFragment; displayVideoCall(false); + LinphoneManager.getInstance().routeAudioToSpeaker(); isSpeakerEnabled = true; } else { callFragment = new CallAudioFragment(); @@ -421,15 +417,6 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve addCall.setBackgroundResource(R.drawable.options_add_call); } - if (!isAnimationDisabled) { - slideInRightToLeft = AnimationUtils.loadAnimation(this, R.anim.slide_in_right_to_left); - slideOutLeftToRight = AnimationUtils.loadAnimation(this, R.anim.slide_out_left_to_right); - slideInBottomToTop = AnimationUtils.loadAnimation(this, R.anim.slide_in_bottom_to_top); - slideInTopToBottom = AnimationUtils.loadAnimation(this, R.anim.slide_in_top_to_bottom); - slideOutBottomToTop = AnimationUtils.loadAnimation(this, R.anim.slide_out_bottom_to_top); - slideOutTopToBottom = AnimationUtils.loadAnimation(this, R.anim.slide_out_top_to_bottom); - } - if (BluetoothManager.getInstance().isBluetoothHeadsetAvailable()) { try { audioRoute.setVisibility(View.VISIBLE); @@ -962,31 +949,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve public void displayVideoCallControlsIfHidden() { if (mControlsLayout != null) { if (mControlsLayout.getVisibility() != View.VISIBLE) { - if (isAnimationDisabled) { - displayVideoCall(true); - } else { - Animation animation = slideInBottomToTop; - animation.setAnimationListener(new AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - displayVideoCall(true); - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - - @Override - public void onAnimationEnd(Animation animation) { - animation.setAnimationListener(null); - } - }); - mControlsLayout.startAnimation(animation); - if (cameraNumber > 1) { - switchCamera.startAnimation(slideInTopToBottom); - } - pause.startAnimation(slideInTopToBottom); - } + displayVideoCall(true); } resetControlsHidingCallBack(); } @@ -1002,45 +965,13 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve mControlsHandler.postDelayed(mControls = new Runnable() { public void run() { hideNumpad(); - - if (isAnimationDisabled) { - video.setEnabled(true); - transfer.setVisibility(View.INVISIBLE); - addCall.setVisibility(View.INVISIBLE); - conference.setVisibility(View.INVISIBLE); - displayVideoCall(false); - numpad.setVisibility(View.GONE); - options.setImageResource(R.drawable.options_default); - } else { - Animation animation = slideOutTopToBottom; - animation.setAnimationListener(new AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - video.setEnabled(false); // HACK: Used to avoid controls from being hided if video is switched while controls are hiding - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - - @Override - public void onAnimationEnd(Animation animation) { - video.setEnabled(true); // HACK: Used to avoid controls from being hided if video is switched while controls are hiding - transfer.setVisibility(View.INVISIBLE); - addCall.setVisibility(View.INVISIBLE); - conference.setVisibility(View.INVISIBLE); - displayVideoCall(false); - numpad.setVisibility(View.GONE); - options.setImageResource(R.drawable.options_default); - animation.setAnimationListener(null); - } - }); - mControlsLayout.startAnimation(animation); - if (cameraNumber > 1) { - switchCamera.startAnimation(slideOutBottomToTop); - } - pause.startAnimation(slideOutBottomToTop); - } + video.setEnabled(true); + transfer.setVisibility(View.INVISIBLE); + addCall.setVisibility(View.INVISIBLE); + conference.setVisibility(View.INVISIBLE); + displayVideoCall(false); + numpad.setVisibility(View.GONE); + options.setImageResource(R.drawable.options_default); } }, SECONDS_BEFORE_HIDING_CONTROLS); } @@ -1059,29 +990,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve } dialer.setImageResource(R.drawable.footer_dialer); - if (isAnimationDisabled) { - numpad.setVisibility(View.GONE); - } else { - Animation animation = slideOutTopToBottom; - animation.setAnimationListener(new AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - - } - - @Override - public void onAnimationRepeat(Animation animation) { - - } - - @Override - public void onAnimationEnd(Animation animation) { - numpad.setVisibility(View.GONE); - animation.setAnimationListener(null); - } - }); - numpad.startAnimation(animation); - } + numpad.setVisibility(View.GONE); } private void hideOrDisplayNumpad() { @@ -1093,187 +1002,10 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve hideNumpad(); } else { dialer.setImageResource(R.drawable.dialer_alt_back); - if (isAnimationDisabled) { - numpad.setVisibility(View.VISIBLE); - } else { - Animation animation = slideInBottomToTop; - animation.setAnimationListener(new AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - - } - - @Override - public void onAnimationRepeat(Animation animation) { - - } - - @Override - public void onAnimationEnd(Animation animation) { - numpad.setVisibility(View.VISIBLE); - animation.setAnimationListener(null); - } - }); - numpad.startAnimation(animation); - } + numpad.setVisibility(View.VISIBLE); } } - private void hideAnimatedPortraitCallOptions() { - Animation animation = slideOutLeftToRight; - animation.setAnimationListener(new AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - - @Override - public void onAnimationEnd(Animation animation) { - if (isTransferAllowed) { - transfer.setVisibility(View.INVISIBLE); - } - addCall.setVisibility(View.INVISIBLE); - conference.setVisibility(View.INVISIBLE); - animation.setAnimationListener(null); - } - }); - if (isTransferAllowed) { - transfer.startAnimation(animation); - } - addCall.startAnimation(animation); - conference.startAnimation(animation); - } - - private void hideAnimatedLandscapeCallOptions() { - Animation animation = slideOutTopToBottom; - if (isTransferAllowed) { - animation.setAnimationListener(new AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - - @Override - public void onAnimationEnd(Animation animation) { - transfer.setAnimation(null); - transfer.setVisibility(View.INVISIBLE); - - animation = AnimationUtils.loadAnimation(CallActivity.this, R.anim.slide_out_top_to_bottom); // Reload animation to prevent transfer button to blink - animation.setAnimationListener(new AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - - @Override - public void onAnimationEnd(Animation animation) { - addCall.setVisibility(View.INVISIBLE); - } - }); - addCall.startAnimation(animation); - } - }); - transfer.startAnimation(animation); - conference.startAnimation(animation); - } else { - animation.setAnimationListener(new AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - - @Override - public void onAnimationEnd(Animation animation) { - addCall.setVisibility(View.INVISIBLE); - conference.setVisibility(View.INVISIBLE); - } - }); - addCall.startAnimation(animation); - conference.startAnimation(animation); - } - } - - private void showAnimatedPortraitCallOptions() { - Animation animation = slideInRightToLeft; - animation.setAnimationListener(new AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - - @Override - public void onAnimationEnd(Animation animation) { - options.setImageResource(R.drawable.options_default); - if (isTransferAllowed) { - transfer.setVisibility(View.VISIBLE); - } - addCall.setVisibility(View.VISIBLE); - conference.setVisibility(View.VISIBLE); - animation.setAnimationListener(null); - } - }); - if (isTransferAllowed) { - transfer.startAnimation(animation); - } - conference.startAnimation(animation); - addCall.startAnimation(animation); - } - - private void showAnimatedLandscapeCallOptions() { - Animation animation = slideInBottomToTop; - animation.setAnimationListener(new AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - - @Override - public void onAnimationEnd(Animation animation) { - addCall.setAnimation(null); - options.setImageResource(R.drawable.options_default); - addCall.setVisibility(View.VISIBLE); - conference.setVisibility(View.VISIBLE); - if (isTransferAllowed) { - animation.setAnimationListener(new AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { - } - - @Override - public void onAnimationRepeat(Animation animation) { - } - - @Override - public void onAnimationEnd(Animation animation) { - transfer.setVisibility(View.VISIBLE); - } - }); - transfer.startAnimation(animation); - } - conference.startAnimation(animation); - } - }); - addCall.startAnimation(animation); - } - private void hideOrDisplayAudioRoutes() { if (routeSpeaker.getVisibility() == View.VISIBLE) { @@ -1288,40 +1020,21 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve } private void hideOrDisplayCallOptions() { - boolean isOrientationLandscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; - //Hide options if (addCall.getVisibility() == View.VISIBLE) { options.setImageResource(R.drawable.options_default); - if (isAnimationDisabled) { - if (isTransferAllowed) { - transfer.setVisibility(View.INVISIBLE); - } - addCall.setVisibility(View.INVISIBLE); - conference.setVisibility(View.INVISIBLE); - } else { - if (isOrientationLandscape) { - hideAnimatedLandscapeCallOptions(); - } else { - hideAnimatedPortraitCallOptions(); - } + if (isTransferAllowed) { + transfer.setVisibility(View.INVISIBLE); } - //Display options - } else { - if (isAnimationDisabled) { - if (isTransferAllowed) { - transfer.setVisibility(View.VISIBLE); - } - addCall.setVisibility(View.VISIBLE); - conference.setVisibility(View.VISIBLE); - options.setImageResource(R.drawable.options_selected); - } else { - if (isOrientationLandscape) { - showAnimatedLandscapeCallOptions(); - } else { - showAnimatedPortraitCallOptions(); - } + addCall.setVisibility(View.INVISIBLE); + conference.setVisibility(View.INVISIBLE); + } else { //Display options + if (isTransferAllowed) { + transfer.setVisibility(View.VISIBLE); } + addCall.setVisibility(View.VISIBLE); + conference.setVisibility(View.VISIBLE); + options.setImageResource(R.drawable.options_selected); transfer.setEnabled(LinphoneManager.getLc().getCurrentCall() != null); } } @@ -1401,7 +1114,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve private void showAcceptCallUpdateDialog() { final Dialog dialog = new Dialog(this); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); - Drawable d = new ColorDrawable(getResources().getColor(R.color.colorC)); + Drawable d = new ColorDrawable(ContextCompat.getColor(this, R.color.colorC)); d.setAlpha(200); dialog.setContentView(R.layout.dialog); dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.MATCH_PARENT); @@ -1862,12 +1575,6 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve if (count > 0) { missedChats.setText(count + ""); missedChats.setVisibility(View.VISIBLE); - if (!isAnimationDisabled) { - missedChats.startAnimation(AnimationUtils.loadAnimation(this, R.anim.bounce)); - } - if(count > 99){ - //TODO - } } else { missedChats.clearAnimation(); missedChats.setVisibility(View.GONE); diff --git a/src/org/linphone/CallAudioFragment.java b/src/org/linphone/CallAudioFragment.java index a2fed87da..571a5c483 100644 --- a/src/org/linphone/CallAudioFragment.java +++ b/src/org/linphone/CallAudioFragment.java @@ -17,9 +17,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -import android.app.Activity; -import android.os.Bundle; import android.app.Fragment; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -38,20 +37,15 @@ public class CallAudioFragment extends Fragment { View view = inflater.inflate(R.layout.audio, container, false); return view; } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - incallActvityInstance = (CallActivity) activity; - - if (incallActvityInstance != null) { - incallActvityInstance.bindAudioFragment(this); - } - } @Override public void onStart() { super.onStart(); + incallActvityInstance = (CallActivity) getActivity(); + + if (incallActvityInstance != null) { + incallActvityInstance.bindAudioFragment(this); + } // Just to be sure we have incall controls if (incallActvityInstance != null) { diff --git a/src/org/linphone/CallIncomingActivity.java b/src/org/linphone/CallIncomingActivity.java index e33b052ad..b1d35292f 100644 --- a/src/org/linphone/CallIncomingActivity.java +++ b/src/org/linphone/CallIncomingActivity.java @@ -21,6 +21,7 @@ package org.linphone; import java.util.ArrayList; import java.util.List; +import org.linphone.compatibility.Compatibility; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneCall.State; @@ -35,7 +36,6 @@ import android.app.Activity; import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; -import android.os.Build; import android.os.Bundle; import android.os.PowerManager; import android.support.v4.app.ActivityCompat; @@ -89,11 +89,7 @@ public class CallIncomingActivity extends Activity implements LinphoneSliderTrig getWindow().addFlags(flags); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { - isScreenActive = pm.isInteractive(); - } else { - isScreenActive = pm.isScreenOn(); - } + isScreenActive = Compatibility.isScreenOn(pm); final int screenWidth = getResources().getDisplayMetrics().widthPixels; diff --git a/src/org/linphone/CallVideoFragment.java b/src/org/linphone/CallVideoFragment.java index 31d65389e..6d5302f6c 100644 --- a/src/org/linphone/CallVideoFragment.java +++ b/src/org/linphone/CallVideoFragment.java @@ -25,7 +25,6 @@ import org.linphone.mediastream.Log; import org.linphone.mediastream.video.AndroidVideoWindowImpl; import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration; -import android.app.Activity; import android.app.Fragment; import android.os.Bundle; import android.view.GestureDetector; @@ -131,6 +130,15 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On }); return view; } + + @Override + public void onStart() { + super.onStart(); + inCallActivity = (CallActivity) getActivity(); + if (inCallActivity != null) { + inCallActivity.bindVideoFragment(this); + } + } private void fixZOrder(SurfaceView video, SurfaceView preview) { video.setZOrderOnTop(false); @@ -292,15 +300,6 @@ public class CallVideoFragment extends Fragment implements OnGestureListener, On super.onDestroy(); } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - inCallActivity = (CallActivity) activity; - if (inCallActivity != null) { - inCallActivity.bindVideoFragment(this); - } - } @Override public boolean onDown(MotionEvent e) { diff --git a/src/org/linphone/ChatFragment.java b/src/org/linphone/ChatFragment.java index 6c5cdafd8..68508392c 100644 --- a/src/org/linphone/ChatFragment.java +++ b/src/org/linphone/ChatFragment.java @@ -183,7 +183,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC initNewChatConversation(); } - //Manage multiline message = (EditText) view.findViewById(R.id.message); sendImage = (ImageView) view.findViewById(R.id.send_picture); @@ -1027,7 +1026,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC if(search != null) { for (ContactAddress c : searchAdapter.contacts) { String address = c.address; - if(address.startsWith("sip:")) address = address.substring(4); + if (address.startsWith("sip:")) address = address.substring(4); if (c.contact.getFullName().toLowerCase(Locale.getDefault()).startsWith(search.toLowerCase(Locale.getDefault())) || address.toLowerCase(Locale.getDefault()).startsWith(search.toLowerCase(Locale.getDefault()))) { result.add(c); @@ -1045,7 +1044,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC SearchContactsListAdapter(List contactsList) { mInflater = inflater; - if(contactsList == null){ + if (contactsList == null) { contacts = getContactsList(); } else { contacts = contactsList; @@ -1057,7 +1056,13 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC if(ContactsManager.getInstance().hasContacts()) { for (LinphoneContact con : ContactsManager.getInstance().getContacts()) { for (LinphoneNumberOrAddress noa : con.getNumbersOrAddresses()) { - list.add(new ContactAddress(con, noa.getValue())); + String value = noa.getValue(); + // Fix for sip:username compatibility issue + if (value.startsWith("sip:") && !value.contains("@")) { + value = value.substring(4); + value = LinphoneUtils.getFullAddressFromUsername(value); + } + list.add(new ContactAddress(con, value)); } } } @@ -1095,7 +1100,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC } final String a = contact.address; - final LinphoneContact c = contact.contact; + LinphoneContact c = contact.contact; TextView name = (TextView) view.findViewById(R.id.contact_name); name.setText(c.getFullName()); diff --git a/src/org/linphone/ChatListFragment.java b/src/org/linphone/ChatListFragment.java index c303e0554..d5d9fba20 100644 --- a/src/org/linphone/ChatListFragment.java +++ b/src/org/linphone/ChatListFragment.java @@ -55,7 +55,7 @@ import android.widget.TextView; /** * @author Sylvain Berfini */ -public class ChatListFragment extends Fragment implements OnClickListener, OnItemClickListener { +public class ChatListFragment extends Fragment implements OnClickListener, OnItemClickListener, ContactsUpdatedListener { private LayoutInflater mInflater; private List mConversations; private ListView chatList; @@ -193,6 +193,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte @Override public void onResume() { super.onResume(); + ContactsManager.addContactsListener(this); if (LinphoneManager.getLc().getCallsNb() > 0) { backInCall.setVisibility(View.VISIBLE); @@ -219,9 +220,15 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte if (lc != null) { lc.removeListener(mListener); } + ContactsManager.removeContactsListener(this); super.onPause(); } + @Override + public void onContactsUpdated() { + hideAndDisplayMessageIfNoChat(); + } + @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); diff --git a/src/org/linphone/ChatMessage.java b/src/org/linphone/ChatMessage.java index b0c59c8cb..7321409bb 100644 --- a/src/org/linphone/ChatMessage.java +++ b/src/org/linphone/ChatMessage.java @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /** * @author Sylvain Berfini + * @deprecated */ public class ChatMessage { private String message; diff --git a/src/org/linphone/ContactDetailsFragment.java b/src/org/linphone/ContactDetailsFragment.java index b77fa72e9..83130b0b7 100644 --- a/src/org/linphone/ContactDetailsFragment.java +++ b/src/org/linphone/ContactDetailsFragment.java @@ -17,7 +17,6 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneProxyConfig; import android.annotation.SuppressLint; @@ -39,6 +38,7 @@ import android.widget.TextView; public class ContactDetailsFragment extends Fragment implements OnClickListener { private LinphoneContact contact; private ImageView editContact, deleteContact, back; + private TextView organization; private LayoutInflater inflater; private View view; private boolean displayChatAddressOnly = false; @@ -47,22 +47,7 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener @Override public void onClick(View v) { if (LinphoneActivity.isInstanciated()) { - LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (lc != null) { - LinphoneProxyConfig lpc = lc.getDefaultProxyConfig(); - String to; - if (lpc != null) { - String address = v.getTag().toString(); - if (!address.contains("@")) { - to = lpc.normalizePhoneNumber(address); - } else { - to = v.getTag().toString(); - } - } else { - to = v.getTag().toString(); - } - LinphoneActivity.instance().setAddresGoToDialerAndCall(to, contact.getFullName(), contact.getPhotoUri()); - } + LinphoneActivity.instance().setAddresGoToDialerAndCall(v.getTag().toString(), contact.getFullName(), contact.getPhotoUri()); } } }; @@ -91,6 +76,14 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener deleteContact = (ImageView) view.findViewById(R.id.deleteContact); deleteContact.setOnClickListener(this); + + organization = (TextView) view.findViewById(R.id.contactOrganization); + String org = contact.getOrganization(); + if (org != null && !org.isEmpty()) { + organization.setText(org); + } else { + organization.setVisibility(View.GONE); + } back = (ImageView) view.findViewById(R.id.back); if(getResources().getBoolean(R.bool.isTablet)){ @@ -125,13 +118,7 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener boolean skip = false; View v = inflater.inflate(R.layout.contact_control_row, null); - String displayednumberOrAddress = noa.getValue(); - if (displayednumberOrAddress.startsWith("sip:")) { - displayednumberOrAddress = displayednumberOrAddress.replace("sip:", ""); - } - if (displayednumberOrAddress.contains("@")) { - displayednumberOrAddress = displayednumberOrAddress.split("@")[0]; - } + String displayednumberOrAddress = LinphoneUtils.getDisplayableUsernameFromAddress(noa.getValue()); TextView label = (TextView) v.findViewById(R.id.address_label); if (noa.isSIPAddress()) { @@ -156,48 +143,13 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener v.findViewById(R.id.contact_chat).setOnClickListener(chatListener); LinphoneProxyConfig lpc = LinphoneManager.getLc().getDefaultProxyConfig(); if (lpc != null) { - displayednumberOrAddress = lpc.normalizePhoneNumber(displayednumberOrAddress); - String tag = noa.getValue(); - if (!tag.startsWith("sip:")) { - tag = "sip:" + tag; - } - - if (!tag.contains("@")) { - tag = tag + "@" + lpc.getDomain(); - } + String username = lpc.normalizePhoneNumber(LinphoneUtils.getUsernameFromAddress(noa.getValue())); + String tag = LinphoneUtils.getFullAddressFromUsername(username); v.findViewById(R.id.contact_chat).setTag(tag); } else { v.findViewById(R.id.contact_chat).setTag(noa.getValue()); } - /*ImageView friend = (ImageView) v.findViewById(R.id.addFriend); - if (getResources().getBoolean(R.bool.enable_linphone_friends) && !displayChatAddressOnly) { - friend.setVisibility(View.VISIBLE); - - boolean isAlreadyAFriend = LinphoneManager.getLc().findFriendByAddress(finalNumberOrAddress) != null; - if (!isAlreadyAFriend) { - friend.setImageResource(R.drawable.contact_add); - friend.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - if (ContactsManager.getInstance().createNewFriend(contact, finalNumberOrAddress)) { - displayContact(ContactFragment.this.inflater, ContactFragment.this.view); - } - } - }); - } else { - friend.setImageResource(R.drawable.delete); - friend.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - if (ContactsManager.getInstance().removeFriend(finalNumberOrAddress)) { - displayContact(ContactFragment.this.inflater, ContactFragment.this.view); - } - } - }); - } - }*/ - if (getResources().getBoolean(R.bool.disable_chat)) { v.findViewById(R.id.contact_chat).setVisibility(View.GONE); } diff --git a/src/org/linphone/ContactEditorFragment.java b/src/org/linphone/ContactEditorFragment.java index 01865a037..5782846c7 100644 --- a/src/org/linphone/ContactEditorFragment.java +++ b/src/org/linphone/ContactEditorFragment.java @@ -25,8 +25,6 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.List; -import org.linphone.core.LinphoneCore; -import org.linphone.core.LinphoneProxyConfig; import org.linphone.mediastream.Log; import org.linphone.mediastream.Version; @@ -64,7 +62,7 @@ public class ContactEditorFragment extends Fragment { private ImageView cancel, deleteContact, ok; private ImageView addNumber, addSipAddress, contactPicture; private LinearLayout phoneNumbersSection, sipAddressesSection; - private EditText firstName, lastName; + private EditText firstName, lastName, organization; private LayoutInflater inflater; private static final int ADD_PHOTO = 1337; @@ -126,10 +124,6 @@ public class ContactEditorFragment extends Fragment { ok.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - LinphoneProxyConfig lpc = lc != null ? lc.getDefaultProxyConfig() : null; - String defaultDomain = lpc != null ? lpc.getDomain() : null; - if (isNewContact) { boolean areAllFielsEmpty = true; for (LinphoneNumberOrAddress nounoa : numbersAndAddresses) { @@ -150,15 +144,11 @@ public class ContactEditorFragment extends Fragment { } for (LinphoneNumberOrAddress noa : numbersAndAddresses) { if (noa.isSIPAddress() && noa.getValue() != null) { - if (!noa.getValue().contains("@") && defaultDomain != null) { - noa.setValue(noa.getValue() + "@" + defaultDomain); - } - if (!noa.getValue().startsWith("sip:")) { - noa.setValue("sip:" + noa.getValue()); - } + noa.setValue(LinphoneUtils.getFullAddressFromUsername(noa.getValue())); } contact.addOrUpdateNumberOrAddress(noa); } + contact.setOrganization(organization.getText().toString()); contact.save(); getFragmentManager().popBackStackImmediate(); } @@ -213,6 +203,11 @@ public class ContactEditorFragment extends Fragment { public void afterTextChanged(Editable s) { } }); + + organization = (EditText) view.findViewById(R.id.contactOrganization); + if (!isNewContact) { + organization.setText(contact.getOrganization()); + } if (!isNewContact) { String fn = contact.getFirstName(); @@ -331,7 +326,6 @@ public class ContactEditorFragment extends Fragment { final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); File file = new File(Environment.getExternalStorageDirectory(), getString(R.string.temp_photo_name)); pickedPhotoForContactUri = Uri.fromFile(file); - captureIntent.putExtra("crop", "true"); captureIntent.putExtra("outputX", PHOTO_SIZE); captureIntent.putExtra("outputY", PHOTO_SIZE); captureIntent.putExtra("aspectX", 0); @@ -485,10 +479,7 @@ public class ContactEditorFragment extends Fragment { if (firstSipAddressIndex == -1) { firstSipAddressIndex = controls.getChildCount(); } - numberOrAddress = numberOrAddress.replace("sip:", ""); - if (numberOrAddress.contains("@")) { - numberOrAddress = numberOrAddress.split("@")[0]; - } + numberOrAddress = LinphoneUtils.getDisplayableUsernameFromAddress(numberOrAddress); } if ((getResources().getBoolean(R.bool.hide_phone_numbers_in_editor) && !isSIP) || (getResources().getBoolean(R.bool.hide_sip_addresses_in_editor) && isSIP)) { if (forceAddNumber) @@ -513,7 +504,9 @@ public class ContactEditorFragment extends Fragment { final View view = inflater.inflate(R.layout.contact_edit_row, null); final EditText noa = (EditText) view.findViewById(R.id.numoraddr); - noa.setInputType(isSIP ? InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS : InputType.TYPE_CLASS_PHONE); + if (!isSIP) { + noa.setInputType(InputType.TYPE_CLASS_PHONE); + } noa.setText(numberOrAddress); noa.addTextChangedListener(new TextWatcher() { @Override @@ -559,7 +552,9 @@ public class ContactEditorFragment extends Fragment { final EditText noa = (EditText) view.findViewById(R.id.numoraddr); numbersAndAddresses.add(nounoa); noa.setHint(isSip ? getString(R.string.sip_address) : getString(R.string.phone_number)); - noa.setInputType(isSip ? InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS : InputType.TYPE_CLASS_PHONE); + if (!isSip) { + noa.setInputType(InputType.TYPE_CLASS_PHONE); + } noa.requestFocus(); noa.addTextChangedListener(new TextWatcher() { @Override diff --git a/src/org/linphone/ContactsListFragment.java b/src/org/linphone/ContactsListFragment.java index 6c2ffa021..04d2b02cd 100644 --- a/src/org/linphone/ContactsListFragment.java +++ b/src/org/linphone/ContactsListFragment.java @@ -48,6 +48,7 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; +import android.widget.ProgressBar; import android.widget.SectionIndexer; import android.widget.TextView; @@ -67,6 +68,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O private String sipAddressToAdd; private ImageView clearSearchField; private EditText searchField; + private ProgressBar contactsFetchInProgress; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -141,6 +143,8 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O searchContacts(searchField.getText().toString()); } }); + + contactsFetchInProgress = (ProgressBar) view.findViewById(R.id.contactsFetchInProgress); return view; } @@ -339,6 +343,11 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O edit.setEnabled(true); } ContactsManager.getInstance().setLinphoneContactsPrefered(onlyDisplayLinphoneContacts); + if (contactsList.getCount() == 0) { + contactsFetchInProgress.setVisibility(View.VISIBLE); + } else { + contactsFetchInProgress.setVisibility(View.GONE); + } } private void changeContactsToggle() { @@ -476,7 +485,7 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O } } - if(contact.isInLinphoneFriendList()){ + if (contact.isInLinphoneFriendList()) { linphoneFriend.setVisibility(View.VISIBLE); } else { linphoneFriend.setVisibility(View.GONE); @@ -490,6 +499,15 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O } else { icon.setImageResource(R.drawable.avatar); } + + TextView organization = (TextView) view.findViewById(R.id.contactOrganization); + String org = contact.getOrganization(); + if (org != null && !org.isEmpty()) { + organization.setText(org); + organization.setVisibility(View.VISIBLE); + } else { + organization.setVisibility(View.GONE); + } if (isEditMode) { delete.setVisibility(View.VISIBLE); diff --git a/src/org/linphone/ContactsManager.java b/src/org/linphone/ContactsManager.java index 48d42e69d..525882dc1 100644 --- a/src/org/linphone/ContactsManager.java +++ b/src/org/linphone/ContactsManager.java @@ -39,6 +39,7 @@ import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; +import android.os.AsyncTask; import android.os.Handler; import android.os.Message; import android.provider.ContactsContract; @@ -49,14 +50,12 @@ interface ContactsUpdatedListener { } public class ContactsManager extends ContentObserver { - private static final int CONTACTS_UPDATED = 543; - private static ContactsManager instance; private List contacts, sipContacts; - private Account mAccount; private boolean preferLinphoneContacts = false, isContactPresenceDisabled = true, hasContactAccess = false; private ContentResolver contentResolver; private Context context; + private ContactsFetchTask contactsFetchTask; private static ArrayList contactsUpdatedListeners; public static void addContactsListener(ContactsUpdatedListener listener) { @@ -67,16 +66,9 @@ public class ContactsManager extends ContentObserver { } private static Handler handler = new Handler() { - @SuppressWarnings("unchecked") @Override public void handleMessage (Message msg) { - if (msg.what == CONTACTS_UPDATED && msg.obj instanceof List) { - List c = (List) msg.obj; - ContactsManager.getInstance().setContacts(c); - for (ContactsUpdatedListener listener : contactsUpdatedListeners) { - listener.onContactsUpdated(); - } - } + } }; @@ -87,6 +79,13 @@ public class ContactsManager extends ContentObserver { sipContacts = new ArrayList(); } + public void destroy() { + if (contactsFetchTask != null && !contactsFetchTask.isCancelled()) { + contactsFetchTask.cancel(true); + } + instance = null; + } + @Override public void onChange(boolean selfChange) { onChange(selfChange, null); @@ -94,11 +93,7 @@ public class ContactsManager extends ContentObserver { @Override public void onChange(boolean selfChange, Uri uri) { - List contacts = fetchContactsAsync(); - Message msg = handler.obtainMessage(); - msg.what = CONTACTS_UPDATED; - msg.obj = contacts; - handler.sendMessage(msg); + fetchContactsAsync(); } public ContentResolver getContentResolver() { @@ -179,17 +174,13 @@ public class ContactsManager extends ContentObserver { Account[] accounts = accountManager.getAccountsByType(context.getPackageName()); - if(accounts != null && accounts.length == 0) { + if (accounts != null && accounts.length == 0) { Account newAccount = new Account(context.getString(R.string.sync_account_name), context.getPackageName()); try { accountManager.addAccountExplicitly(newAccount, null, null); - mAccount = newAccount; } catch (Exception e) { Log.e(e); - mAccount = null; } - } else { - mAccount = accounts[0]; } initializeContactManager(context, contentResolver); } @@ -228,61 +219,100 @@ public class ContactsManager extends ContentObserver { } } } - - public synchronized void fetchContacts() { - setContacts(fetchContactsAsync()); + + public synchronized void fetchContactsAsync() { + if (contactsFetchTask != null && !contactsFetchTask.isCancelled()) { + contactsFetchTask.cancel(true); + } + contactsFetchTask = new ContactsFetchTask(); + contactsFetchTask.execute(); } - public List fetchContactsAsync() { - List contacts = new ArrayList(); - - if (hasContactsAccess()) { - Cursor c = Compatibility.getContactsCursor(contentResolver, null); - if (c != null) { - while (c.moveToNext()) { - String id = c.getString(c.getColumnIndex(Data.CONTACT_ID)); - LinphoneContact contact = new LinphoneContact(); - contact.setAndroidId(id); - contacts.add(contact); - } - c.close(); - } - } - - for (LinphoneFriend friend : LinphoneManager.getLc().getFriendList()) { - String refkey = friend.getRefKey(); - if (refkey != null) { - boolean found = false; - for (LinphoneContact contact : contacts) { - if (refkey.equals(contact.getAndroidId())) { - contact.setFriend(friend); - found = true; - break; + + private class ContactsFetchTask extends AsyncTask, List> { + @SuppressWarnings("unchecked") + protected List doInBackground(Void... params) { + List contacts = new ArrayList(); + + if (hasContactsAccess()) { + Cursor c = Compatibility.getContactsCursor(contentResolver, null); + if (c != null) { + while (c.moveToNext()) { + String id = c.getString(c.getColumnIndex(Data.CONTACT_ID)); + LinphoneContact contact = new LinphoneContact(); + contact.setAndroidId(id); + contacts.add(contact); } + c.close(); } - if (!found) { + } + + for (LinphoneFriend friend : LinphoneManager.getLc().getFriendList()) { + String refkey = friend.getRefKey(); + if (refkey != null) { + boolean found = false; + for (LinphoneContact contact : contacts) { + if (refkey.equals(contact.getAndroidId())) { + // Native matching contact found, link the friend to it + contact.setFriend(friend); + found = true; + break; + } + } + if (!found) { + if (hasContactAccess) { + // If refkey != null and hasContactAccess but there isn't a native contact with this value, then this contact has been deleted. Let's do the same with the LinphoneFriend + LinphoneManager.getLc().removeFriend(friend); + } else { + // Refkey not null but no contact access => can't link it to native contact so display it on is own + LinphoneContact contact = new LinphoneContact(); + contact.setFriend(friend); + contacts.add(contact); + } + } + } else { + // No refkey so it's a standalone contact LinphoneContact contact = new LinphoneContact(); contact.setFriend(friend); contacts.add(contact); } - } else { - LinphoneContact contact = new LinphoneContact(); - contact.setFriend(friend); - contacts.add(contact); + } + + for (LinphoneContact contact : contacts) { + // This will only get name & picture informations to be able to quickly display contacts list + contact.minimalRefresh(); + } + Collections.sort(contacts); + + // Public the current list of contacts without all the informations populated + publishProgress(contacts); + + for (LinphoneContact contact : contacts) { + // This time fetch all informations including phone numbers and SIP addresses + contact.refresh(); + } + + return contacts; + } + + protected void onProgressUpdate(List... result) { + setContacts(result[0]); + for (ContactsUpdatedListener listener : contactsUpdatedListeners) { + listener.onContactsUpdated(); } } - for (LinphoneContact contact : contacts) { - contact.refresh(); + protected void onPostExecute(List result) { + setContacts(result); + for (ContactsUpdatedListener listener : contactsUpdatedListeners) { + listener.onContactsUpdated(); + } } - Collections.sort(contacts); - - return contacts; } public static String getAddressOrNumberForAndroidContact(ContentResolver resolver, Uri contactUri) { // Phone Numbers - String[] projection = new String[]{ ContactsContract.CommonDataKinds.Phone.NUMBER }; + String[] projection = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER }; Cursor c = resolver.query(contactUri, projection, null, null, null); if (c != null) { while (c.moveToNext()) { diff --git a/src/org/linphone/HistoryDetailFragment.java b/src/org/linphone/HistoryDetailFragment.java index f96b0e955..03169455a 100644 --- a/src/org/linphone/HistoryDetailFragment.java +++ b/src/org/linphone/HistoryDetailFragment.java @@ -36,11 +36,12 @@ import android.widget.TextView; * @author Sylvain Berfini */ public class HistoryDetailFragment extends Fragment implements OnClickListener { - private ImageView dialBack, chat, addToContacts, back; + private ImageView dialBack, chat, addToContacts, goToContact, back; private View view; private ImageView contactPicture, callDirection; private TextView contactName, contactAddress, time, date; private String sipUri, displayName, pictureUri; + private LinphoneContact contact; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -72,6 +73,9 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener { addToContacts = (ImageView) view.findViewById(R.id.add_contact); addToContacts.setOnClickListener(this); + goToContact = (ImageView) view.findViewById(R.id.goto_contact); + goToContact.setOnClickListener(this); + contactPicture = (ImageView) view.findViewById(R.id.contact_picture); contactName = (TextView) view.findViewById(R.id.contact_name); @@ -107,17 +111,19 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener { Log.e(e); } - if(lAddress != null) { + if (lAddress != null) { contactAddress.setText(lAddress.asStringUriOnly()); - LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(lAddress); + contact = ContactsManager.getInstance().findContactFromAddress(lAddress); if (contact != null) { contactName.setText(contact.getFullName()); LinphoneUtils.setImagePictureFromUri(view.getContext(),contactPicture,contact.getPhotoUri(),contact.getThumbnailUri()); - addToContacts.setVisibility(View.INVISIBLE); + addToContacts.setVisibility(View.GONE); + goToContact.setVisibility(View.VISIBLE); } else { contactName.setText(displayName == null ? LinphoneUtils.getAddressDisplayName(sipUri) : displayName); contactPicture.setImageResource(R.drawable.avatar); addToContacts.setVisibility(View.VISIBLE); + goToContact.setVisibility(View.GONE); } } else { contactAddress.setText(sipUri); @@ -165,6 +171,8 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener { Log.e(e); } LinphoneActivity.instance().displayContactsForEdition(uri); + } else if (id == R.id.goto_contact) { + LinphoneActivity.instance().displayContact(contact, false); } } } diff --git a/src/org/linphone/HistoryListFragment.java b/src/org/linphone/HistoryListFragment.java index 9609af2a9..cb4e95dc3 100644 --- a/src/org/linphone/HistoryListFragment.java +++ b/src/org/linphone/HistoryListFragment.java @@ -52,7 +52,7 @@ import android.widget.TextView; /** * @author Sylvain Berfini */ -public class HistoryListFragment extends Fragment implements OnClickListener, OnItemClickListener { +public class HistoryListFragment extends Fragment implements OnClickListener, OnItemClickListener, ContactsUpdatedListener { private ListView historyList; private LayoutInflater mInflater; private TextView noCallHistory, noMissedCallHistory; @@ -198,6 +198,7 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On @Override public void onResume() { super.onResume(); + ContactsManager.addContactsListener(this); if (LinphoneActivity.isInstanciated()) { LinphoneActivity.instance().selectMenu(FragmentsAvailable.HISTORY_LIST); @@ -211,6 +212,17 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext())); } } + + @Override + public void onPause() { + ContactsManager.removeContactsListener(this); + super.onPause(); + } + + @Override + public void onContactsUpdated() { + historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext())); + } @Override public void onClick(View v) { @@ -327,18 +339,20 @@ public class HistoryListFragment extends Fragment implements OnClickListener, On topBar.setVisibility(View.VISIBLE); refresh(); - if (!hideHistoryListAndDisplayMessageIfEmpty()){ + if (!hideHistoryListAndDisplayMessageIfEmpty()) { historyList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE); historyList.setAdapter(new CallHistoryAdapter(getActivity().getApplicationContext())); } - if(getResources().getBoolean(R.bool.isTablet)){ + if (getResources().getBoolean(R.bool.isTablet)) { displayFirstLog(); } } class CallHistoryAdapter extends BaseAdapter { CallHistoryAdapter(Context aContext) { + } + public int getCount() { return mLogs.size(); } diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index e33e90058..0fb419a5f 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -70,6 +70,7 @@ import android.net.Uri; import android.os.Bundle; import android.provider.Settings; import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.support.v4.widget.DrawerLayout; import android.view.Gravity; import android.view.KeyEvent; @@ -81,7 +82,6 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; -import android.view.animation.AnimationUtils; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.BaseAdapter; @@ -104,6 +104,8 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta private static final int PERMISSIONS_REQUEST_OVERLAY = 206; private static final int PERMISSIONS_REQUEST_SYNC = 207; private static final int PERMISSIONS_REQUEST_CONTACTS = 208; + private static final int PERMISSIONS_RECORD_AUDIO_ECHO_CANCELLER = 209; + private static final int PERMISSIONS_READ_EXTERNAL_STORAGE_DEVICE_RINGTONE = 210; private static LinphoneActivity instance; @@ -113,11 +115,12 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta private View contacts_selected, history_selected, dialer_selected, chat_selected; private RelativeLayout mTopBar; private ImageView cancel; - private FragmentsAvailable pendingFragmentTransaction, currentFragment, nextFragment; + private FragmentsAvailable pendingFragmentTransaction, currentFragment; + private Fragment fragment; private List fragmentsHistory; private Fragment.SavedState dialerSavedState; private boolean newProxyConfig; - private boolean isAnimationDisabled = true, emptyFragment = false; + private boolean emptyFragment = false; private OrientationEventListener mOrientationHelper; private LinphoneCoreListenerBase mListener; private LinearLayout mTabBar; @@ -194,9 +197,11 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta initButtons(); initSideMenu(); - currentFragment = nextFragment = FragmentsAvailable.EMPTY; + currentFragment = FragmentsAvailable.EMPTY; if (savedInstanceState == null) { changeCurrentFragment(FragmentsAvailable.DIALER, getIntent().getExtras()); + } else { + currentFragment = (FragmentsAvailable) savedInstanceState.getSerializable("currentFragment"); } mListener = new LinphoneCoreListenerBase(){ @@ -273,8 +278,6 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta LinphoneManager.getLc().setDeviceRotation(rotation); mAlwaysChangingPhoneAngle = rotation; - - updateAnimationsState(); } private void initButtons() { @@ -337,7 +340,6 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta if (newFragmentType == currentFragment && newFragmentType != FragmentsAvailable.CHAT) { return; } - nextFragment = newFragmentType; if (currentFragment == FragmentsAvailable.DIALER) { try { @@ -346,82 +348,77 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta } catch (Exception e) { } } - - Fragment newFragment = null; - + + fragment = null; + switch (newFragmentType) { case HISTORY_LIST: - newFragment = new HistoryListFragment(); - if (isTablet()) { - ((HistoryListFragment) newFragment).displayFirstLog(); - } + fragment = new HistoryListFragment(); break; case HISTORY_DETAIL: - newFragment = new HistoryDetailFragment(); + fragment = new HistoryDetailFragment(); break; case CONTACTS_LIST: checkAndRequestReadContactsPermission(); - newFragment = new ContactsListFragment(); - if (isTablet()) { - ((ContactsListFragment) newFragment).displayFirstContact(); - } + fragment = new ContactsListFragment(); break; case CONTACT_DETAIL: - newFragment = new ContactDetailsFragment(); + fragment = new ContactDetailsFragment(); break; - case CONTACT_EDITOR: - newFragment = new ContactEditorFragment(); + case CONTACT_EDITOR: + fragment = new ContactEditorFragment(); break; case DIALER: - newFragment = new DialerFragment(); + fragment = new DialerFragment(); if (extras == null) { - newFragment.setInitialSavedState(dialerSavedState); + fragment.setInitialSavedState(dialerSavedState); } break; case SETTINGS: - newFragment = new SettingsFragment(); + fragment = new SettingsFragment(); break; case ACCOUNT_SETTINGS: - newFragment = new AccountPreferencesFragment(); + fragment = new AccountPreferencesFragment(); break; case ABOUT: - newFragment = new AboutFragment(); + fragment = new AboutFragment(); break; case EMPTY: - newFragment = new EmptyFragment(); + fragment = new EmptyFragment(); break; case CHAT_LIST: - newFragment = new ChatListFragment(); - if (isTablet()) { - ((ChatListFragment) newFragment).displayFirstChat(); - } + fragment = new ChatListFragment(); break; case CHAT: - newFragment = new ChatFragment(); + fragment = new ChatFragment(); break; default: break; } - if (newFragment != null) { - newFragment.setArguments(extras); + if (fragment != null) { + fragment.setArguments(extras); if (isTablet()) { - changeFragmentForTablets(newFragment, newFragmentType, withoutAnimation); + changeFragmentForTablets(fragment, newFragmentType, withoutAnimation); + switch (newFragmentType) { + case HISTORY_LIST: + ((HistoryListFragment) fragment).displayFirstLog(); + break; + case CONTACTS_LIST: + ((ContactsListFragment) fragment).displayFirstContact(); + break; + case CHAT_LIST: + ((ChatListFragment) fragment).displayFirstChat(); + break; + } } else { - changeFragment(newFragment, newFragmentType, withoutAnimation); + changeFragment(fragment, newFragmentType, withoutAnimation); } } } - private void updateAnimationsState() { - isAnimationDisabled = getResources().getBoolean(R.bool.disable_animations) || !LinphonePreferences.instance().areAnimationsEnabled(); - } - - public boolean isAnimationDisabled() { - return isAnimationDisabled; - } - private void changeFragment(Fragment newFragment, FragmentsAvailable newFragmentType, boolean withoutAnimation) { + FragmentManager fm = getFragmentManager(); FragmentTransaction transaction = fm.beginTransaction(); @@ -449,7 +446,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta fm.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); } } - + transaction.replace(R.id.fragmentContainer, newFragment, newFragmentType.toString()); transaction.commit(); fm.executePendingTransactions(); @@ -784,12 +781,6 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta changeCurrentFragment(FragmentsAvailable.SETTINGS, null); } - public void applyConfigChangesIfNeeded() { - if (nextFragment != FragmentsAvailable.SETTINGS && nextFragment != FragmentsAvailable.ACCOUNT_SETTINGS) { - updateAnimationsState(); - } - } - public void displayDialer() { changeCurrentFragment(FragmentsAvailable.DIALER, null); } @@ -856,9 +847,6 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta if (missedCallsCount > 0) { missedCalls.setText(missedCallsCount + ""); missedCalls.setVisibility(View.VISIBLE); - if (!isAnimationDisabled) { - missedCalls.startAnimation(AnimationUtils.loadAnimation(LinphoneActivity.this, R.anim.bounce)); - } } else { LinphoneManager.getLc().resetMissedCallsCount(); missedCalls.clearAnimation(); @@ -870,12 +858,6 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta if (missedChatCount > 0) { missedChats.setText(missedChatCount + ""); missedChats.setVisibility(View.VISIBLE); - if (!isAnimationDisabled) { - missedChats.startAnimation(AnimationUtils.loadAnimation(LinphoneActivity.this, R.anim.bounce)); - } - if(missedChatCount > 99){ - //TODO - } } else { missedChats.clearAnimation(); missedChats.setVisibility(View.GONE); @@ -899,7 +881,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta public Dialog displayDialog(String text){ Dialog dialog = new Dialog(this); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); - Drawable d = new ColorDrawable(getResources().getColor(R.color.colorC)); + Drawable d = new ColorDrawable(ContextCompat.getColor(this, R.color.colorC)); d.setAlpha(200); dialog.setContentView(R.layout.dialog); dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); @@ -913,7 +895,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta public Dialog displayWrongPasswordDialog(final String username, final String realm, final String domain){ final Dialog dialog = new Dialog(this); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); - Drawable d = new ColorDrawable(getResources().getColor(R.color.colorC)); + Drawable d = new ColorDrawable(ContextCompat.getColor(this, R.color.colorC)); d.setAlpha(200); dialog.setContentView(R.layout.input_dialog); dialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); @@ -1134,6 +1116,7 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta super.onPause(); } + @SuppressWarnings("deprecation") public static boolean isApplicationBroughtToBackground(final Activity activity) { ActivityManager activityManager = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE); List tasks = activityManager.getRunningTasks(1); @@ -1186,6 +1169,14 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta checkAndRequestPermission(Manifest.permission.WRITE_CONTACTS, 0); } + public void checkAndRequestRecordAudioPermissionForEchoCanceller() { + checkAndRequestPermission(Manifest.permission.RECORD_AUDIO, PERMISSIONS_RECORD_AUDIO_ECHO_CANCELLER); + } + + public void checkAndRequestReadExternalStoragePermissionForDeviceRingtone() { + checkAndRequestPermission(Manifest.permission.READ_EXTERNAL_STORAGE, PERMISSIONS_READ_EXTERNAL_STORAGE_DEVICE_RINGTONE); + } + public void checkAndRequestPermissionsToSendImage() { ArrayList permissionsList = new ArrayList(); @@ -1246,9 +1237,19 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta case PERMISSIONS_REQUEST_CONTACTS: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { ContactsManager.getInstance().enableContactsAccess(); - ContactsManager.getInstance().fetchContacts(); - fetchedContactsOnce = true; } + ContactsManager.getInstance().fetchContactsAsync(); + fetchedContactsOnce = true; + break; + case PERMISSIONS_RECORD_AUDIO_ECHO_CANCELLER: + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + ((SettingsFragment) fragment).startEchoCancellerCalibration(); + } else { + ((SettingsFragment) fragment).echoCalibrationFail(); + } + break; + case PERMISSIONS_READ_EXTERNAL_STORAGE_DEVICE_RINGTONE: + ((SettingsFragment) fragment).enableDeviceRingtone(grantResults[0] == PackageManager.PERMISSION_GRANTED); break; } } @@ -1262,12 +1263,18 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta if (contacts == PackageManager.PERMISSION_GRANTED && !fetchedContactsOnce) { ContactsManager.getInstance().enableContactsAccess(); - ContactsManager.getInstance().fetchContacts(); + ContactsManager.getInstance().fetchContactsAsync(); fetchedContactsOnce = true; } else { checkAndRequestReadContactsPermission(); } } + + @Override + protected void onSaveInstanceState(Bundle outState) { + outState.putSerializable("currentFragment", currentFragment); + super.onSaveInstanceState(outState); + } @Override protected void onResume() { @@ -1281,6 +1288,13 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta if (lc != null) { lc.addListener(mListener); } + + if (isTablet()) { + LinearLayout ll = (LinearLayout) findViewById(R.id.fragmentContainer2); + if (currentFragment == FragmentsAvailable.DIALER) { + ll.setVisibility(View.GONE); + } + } refreshAccounts(); @@ -1400,12 +1414,6 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta } else if (LinphoneUtils.onKeyBackGoHome(this, keyCode, event)) { return true; } - } else { - if (isTablet()) { - if (currentFragment == FragmentsAvailable.SETTINGS) { - updateAnimationsState(); - } - } } } return super.onKeyDown(keyCode, event); diff --git a/src/org/linphone/LinphoneContact.java b/src/org/linphone/LinphoneContact.java index 43453a62b..4faf94419 100644 --- a/src/org/linphone/LinphoneContact.java +++ b/src/org/linphone/LinphoneContact.java @@ -20,6 +20,7 @@ package org.linphone; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; @@ -48,7 +49,7 @@ public class LinphoneContact implements Serializable, Comparable addresses; private transient ArrayList changesToCommit; @@ -64,6 +65,15 @@ public class LinphoneContact implements Serializable, Comparable(); hasSipAddress = false; } + + @Override + public int compareTo(LinphoneContact contact) { + String fullName = getFullName(); + String contactFullName = contact.getFullName(); + String firstLetter = fullName == null || fullName.isEmpty() ? "" : fullName.substring(0, 1).toUpperCase(Locale.getDefault()); + String contactfirstLetter = contactFullName == null || contactFullName.isEmpty() ? "" : contactFullName.substring(0, 1).toUpperCase(Locale.getDefault()); + return firstLetter.compareTo(contactfirstLetter); + } public void setFullName(String name) { fullName = name; @@ -117,6 +127,41 @@ public class LinphoneContact implements Serializable, Comparable 0) { try { @@ -364,49 +475,7 @@ public class LinphoneContact implements Serializable, Comparable(); @@ -433,58 +525,42 @@ public class LinphoneContact implements Serializable, Comparable { /** * */ @@ -40,6 +40,15 @@ public class LinphoneNumberOrAddress implements Serializable { this(v, isSip); oldValueForUpdatePurpose = old; } + + @Override + public int compareTo(LinphoneNumberOrAddress noa) { + if (noa.isSIPAddress() == isSIPAddress()) { + return noa.getValue().compareTo(getValue()); + } else { + return isSIPAddress() ? -1 : 1; + } + } public boolean isSIPAddress() { return isSIPAddress; diff --git a/src/org/linphone/LinphonePreferences.java b/src/org/linphone/LinphonePreferences.java index 52f44440c..1c806a06c 100644 --- a/src/org/linphone/LinphonePreferences.java +++ b/src/org/linphone/LinphonePreferences.java @@ -31,19 +31,21 @@ import org.linphone.core.LinphoneAddress.TransportType; import org.linphone.core.LinphoneAuthInfo; import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCore.AdaptiveRateAlgorithm; -import org.linphone.core.LinphoneCore.FirewallPolicy; import org.linphone.core.LinphoneCore.LinphoneLimeState; import org.linphone.core.LinphoneCore.MediaEncryption; import org.linphone.core.LinphoneCore.Transports; import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreFactory; +import org.linphone.core.LinphoneNatPolicy; import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.LpConfig; import org.linphone.core.TunnelConfig; import org.linphone.mediastream.Log; import org.linphone.purchase.Purchasable; +import android.Manifest; import android.content.Context; +import android.content.pm.PackageManager; /** * @author Sylvain Berfini @@ -52,6 +54,7 @@ public class LinphonePreferences { private static final int LINPHONE_CORE_RANDOM_PORT = -1; private static LinphonePreferences instance; private Context mContext; + private String basePath; public static final synchronized LinphonePreferences instance() { if (instance == null) { @@ -66,6 +69,7 @@ public class LinphonePreferences { public void setContext(Context c) { mContext = c; + basePath = mContext.getFilesDir().getAbsolutePath(); } private String getString(int key) { @@ -90,10 +94,10 @@ public class LinphonePreferences { } if (!LinphoneManager.isInstanciated()) { - File linphonerc = new File(mContext.getFilesDir().getAbsolutePath() + "/.linphonerc"); + File linphonerc = new File(basePath + "/.linphonerc"); if (linphonerc.exists()) { return LinphoneCoreFactory.instance().createLpConfig(linphonerc.getAbsolutePath()); - } else { + } else if (mContext != null) { InputStream inputStream = mContext.getResources().openRawResource(R.raw.linphonerc_default); InputStreamReader inputreader = new InputStreamReader(inputStream); BufferedReader buffreader = new BufferedReader(inputreader); @@ -105,13 +109,14 @@ public class LinphonePreferences { text.append('\n'); } } catch (IOException ioe) { - + Log.e(ioe); } return LinphoneCoreFactory.instance().createLpConfigFromString(text.toString()); } + } else { + return LinphoneCoreFactory.instance().createLpConfig(LinphoneManager.getInstance().mLinphoneConfigFile); } - - return LinphoneCoreFactory.instance().createLpConfig(LinphoneManager.getInstance().mLinphoneConfigFile); + return null; } public void removePreviousVersionAuthInfoRemoval() { @@ -904,44 +909,45 @@ public class LinphonePreferences { public boolean isWifiOnlyEnabled() { return getConfig().getBool("app", "wifi_only", false); } + + private LinphoneNatPolicy getOrCreateNatPolicy() { + LinphoneNatPolicy nat = getLc().getNatPolicy(); + if (nat == null) { + nat = getLc().createNatPolicy(); + } + return nat; + } public String getStunServer() { - return getLc().getStunServer(); + LinphoneNatPolicy nat = getOrCreateNatPolicy(); + return nat.getStunServer(); } public void setStunServer(String stun) { - getLc().setStunServer(stun); + LinphoneNatPolicy nat = getOrCreateNatPolicy(); + nat.setStunServer(stun); + if (stun != null && !stun.isEmpty()) { + nat.enableStun(true); + } + getLc().setNatPolicy(nat); } public void setIceEnabled(boolean enabled) { - if (enabled) { - getLc().setFirewallPolicy(FirewallPolicy.UseIce); - } else { - String stun = getStunServer(); - if (stun != null && stun.length() > 0) { - getLc().setFirewallPolicy(FirewallPolicy.UseStun); - } else { - getLc().setFirewallPolicy(FirewallPolicy.NoFirewall); - } - } + LinphoneNatPolicy nat = getOrCreateNatPolicy(); + nat.enableIce(enabled); + getLc().setNatPolicy(nat); + } + + public void setTurnEnabled(boolean enabled) { + LinphoneNatPolicy nat = getOrCreateNatPolicy(); + nat.enableTurn(enabled); + getLc().setNatPolicy(nat); } public void setUpnpEnabled(boolean enabled) { - if (enabled) { - if (isIceEnabled()) { - Log.e("Cannot have both ice and upnp enabled, disabling upnp"); - } else { - getLc().setFirewallPolicy(FirewallPolicy.UseUpnp); - } - } - else { - String stun = getStunServer(); - if (stun != null && stun.length() > 0) { - getLc().setFirewallPolicy(FirewallPolicy.UseStun); - } else { - getLc().setFirewallPolicy(FirewallPolicy.NoFirewall); - } - } + LinphoneNatPolicy nat = getOrCreateNatPolicy(); + nat.enableUpnp(enabled); + getLc().setNatPolicy(nat); } public void useRandomPort(boolean enabled) { @@ -982,11 +988,18 @@ public class LinphonePreferences { } public boolean isUpnpEnabled() { - return getLc().upnpAvailable() && getLc().getFirewallPolicy() == FirewallPolicy.UseUpnp; + LinphoneNatPolicy nat = getOrCreateNatPolicy(); + return nat.upnpEnabled(); } public boolean isIceEnabled() { - return getLc().getFirewallPolicy() == FirewallPolicy.UseIce; + LinphoneNatPolicy nat = getOrCreateNatPolicy(); + return nat.iceEnabled(); + } + + public boolean isTurnEnabled() { + LinphoneNatPolicy nat = getOrCreateNatPolicy(); + return nat.turnEnabled(); } public MediaEncryption getMediaEncryption() { @@ -1076,14 +1089,6 @@ public class LinphonePreferences { return getConfig().getBool("app", "background_mode", true); } - public void setAnimationsEnabled(boolean enabled) { - getConfig().setBool("app", "animations", enabled); - } - - public boolean areAnimationsEnabled() { - return getConfig().getBool("app", "animations", false); - } - public boolean isAutoStartEnabled() { return getConfig().getBool("app", "auto_start", false); } @@ -1327,4 +1332,29 @@ public class LinphonePreferences { } return firstTime; } + + public boolean isDeviceRingtoneEnabled() { + int readExternalStorage = mContext.getPackageManager().checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE, mContext.getPackageName()); + return getConfig().getBool("app", "device_ringtone", true) && readExternalStorage == PackageManager.PERMISSION_GRANTED; + } + + public void enableDeviceRingtone(boolean enable) { + getConfig().setBool("app", "device_ringtone", enable); + } + + public boolean isBisFeatureEnabled() { + return getConfig().getBool("app", "bis_feature", true); + } + + public void enableBisFeature(boolean enable) { + getConfig().setBool("app", "bis_feature", enable); + } + + public boolean isAutoAnswerEnabled() { + return getConfig().getBool("app", "auto_answer", false); + } + + public void enableAutoAnswer(boolean enable) { + getConfig().setBool("app", "auto_answer", enable); + } } diff --git a/src/org/linphone/LinphoneUtils.java b/src/org/linphone/LinphoneUtils.java index 42661832b..48acadff5 100644 --- a/src/org/linphone/LinphoneUtils.java +++ b/src/org/linphone/LinphoneUtils.java @@ -23,10 +23,13 @@ import static android.view.View.VISIBLE; import java.io.BufferedOutputStream; import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.text.SimpleDateFormat; @@ -42,6 +45,7 @@ import java.util.zip.ZipOutputStream; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneCall.State; +import org.linphone.core.LinphoneChatMessage; import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreFactory; @@ -50,6 +54,8 @@ import org.linphone.mediastream.Log; import org.linphone.mediastream.video.capture.hwconf.Hacks; import android.app.Activity; +import android.content.ContentResolver; +import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.res.Resources; @@ -59,7 +65,9 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Build; +import android.os.Environment; import android.provider.MediaStore; +import android.provider.MediaStore.Images; import android.telephony.TelephonyManager; import android.util.TypedValue; import android.view.KeyEvent; @@ -464,5 +472,97 @@ public final class LinphoneUtils { } return extension; } + + public static void recursiveFileRemoval(File root) { + if (!root.delete()) { + if (root.isDirectory()) { + File[] files = root.listFiles(); + if (files != null) { + for (File f : files) { + recursiveFileRemoval(f); + } + } + } + } + } + + public static String getDisplayableUsernameFromAddress(String sipAddress) { + String username = sipAddress; + LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (lc == null) return username; + + if (username.startsWith("sip:")) { + username = username.substring(4); + } + + if (username.contains("@")) { + String domain = username.split("@")[1]; + LinphoneProxyConfig lpc = lc.getDefaultProxyConfig(); + if (lpc != null) { + if (domain.equals(lpc.getDomain())) { + return username.split("@")[0]; + } + } else { + if (domain.equals(LinphoneManager.getInstance().getContext().getString(R.string.default_domain))) { + return username.split("@")[0]; + } + } + } + return username; + } + + public static String getFullAddressFromUsername(String username) { + String sipAddress = username; + LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (lc == null) return sipAddress; + + if (!sipAddress.startsWith("sip:")) { + sipAddress = "sip:" + sipAddress; + } + + if (!sipAddress.contains("@")) { + LinphoneProxyConfig lpc = lc.getDefaultProxyConfig(); + if (lpc != null) { + sipAddress = sipAddress + "@" + lpc.getDomain(); + } else { + sipAddress = sipAddress + "@" + LinphoneManager.getInstance().getContext().getString(R.string.default_domain); + } + } + return sipAddress; + } + + public static void storeImage(Context context, LinphoneChatMessage msg) { + if (msg == null || msg.getFileTransferInformation() == null || msg.getAppData() == null) return; + File file = new File(Environment.getExternalStorageDirectory(), msg.getAppData()); + Bitmap bm = BitmapFactory.decodeFile(file.getPath()); + if (bm == null) return; + + ContentValues values = new ContentValues(); + values.put(Images.Media.TITLE, file.getName()); + String extension = msg.getFileTransferInformation().getSubtype(); + values.put(Images.Media.MIME_TYPE, "image/" + extension); + ContentResolver cr = context.getContentResolver(); + Uri path = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); + + OutputStream stream; + try { + stream = cr.openOutputStream(path); + if (extension != null && extension.toLowerCase(Locale.getDefault()).equals("png")) { + bm.compress(Bitmap.CompressFormat.PNG, 100, stream); + } else { + bm.compress(Bitmap.CompressFormat.JPEG, 100, stream); + } + + stream.close(); + file.delete(); + bm.recycle(); + + msg.setAppData(path.toString()); + } catch (FileNotFoundException e) { + Log.e(e); + } catch (IOException e) { + Log.e(e); + } + } } diff --git a/src/org/linphone/PreferencesMigrator.java b/src/org/linphone/PreferencesMigrator.java index e03a757b1..a18a3e87f 100644 --- a/src/org/linphone/PreferencesMigrator.java +++ b/src/org/linphone/PreferencesMigrator.java @@ -84,7 +84,6 @@ public class PreferencesMigrator { mNewPrefs.setPushNotificationRegistrationID(getPrefString(R.string.push_reg_id_key, null)); mNewPrefs.setDebugEnabled(getPrefBoolean(R.string.pref_debug_key, false)); mNewPrefs.setBackgroundModeEnabled(getPrefBoolean(R.string.pref_background_mode_key, true)); - mNewPrefs.setAnimationsEnabled(getPrefBoolean(R.string.pref_animation_enable_key, false)); mNewPrefs.setAutoStart(getPrefBoolean(R.string.pref_autostart_key, false)); mNewPrefs.setSharingPictureServerUrl(getPrefString(R.string.pref_image_sharing_server_key, null)); mNewPrefs.setRemoteProvisioningUrl(getPrefString(R.string.pref_remote_provisioning_key, null)); diff --git a/src/org/linphone/SettingsFragment.java b/src/org/linphone/SettingsFragment.java index 652a9ed54..2bdd846c6 100644 --- a/src/org/linphone/SettingsFragment.java +++ b/src/org/linphone/SettingsFragment.java @@ -42,7 +42,12 @@ import org.linphone.ui.PreferencesListFragment; import android.app.AlertDialog; import android.content.DialogInterface; +import android.Manifest; +import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.media.AudioManager; import android.os.Bundle; import android.os.Handler; import android.preference.CheckBoxPreference; @@ -62,6 +67,10 @@ public class SettingsFragment extends PreferencesListFragment { private LinphonePreferences mPrefs; private Handler mHandler = new Handler(); private LinphoneCoreListenerBase mListener; + + public SettingsFragment() { + super(R.xml.preferences); + } @Override public void onCreate(Bundle bundle) { @@ -69,14 +78,8 @@ public class SettingsFragment extends PreferencesListFragment { mPrefs = LinphonePreferences.instance(); removePreviousPreferencesFile(); // Required when updating the preferences order - addPreferencesFromResource(R.xml.preferences); - // Init the settings page interface - initSettings(); - setListeners(); - hideSettings(); - - mListener = new LinphoneCoreListenerBase(){ + mListener = new LinphoneCoreListenerBase() { @Override public void ecCalibrationStatus(LinphoneCore lc, final EcCalibratorStatus status, final int delayMs, Object data) { LinphoneManager.getInstance().routeAudioToReceiver(); @@ -88,22 +91,36 @@ public class SettingsFragment extends PreferencesListFragment { echoCancellerCalibration.setSummary(R.string.no_echo); echoCancellation.setChecked(false); LinphonePreferences.instance().setEchoCancellation(false); + ((AudioManager)getActivity().getSystemService(Context.AUDIO_SERVICE)).setMode(AudioManager.MODE_NORMAL); + Log.i("Set audio mode on 'Normal'"); } else if (status == EcCalibratorStatus.Done) { echoCancellerCalibration.setSummary(String.format(getString(R.string.ec_calibrated), delayMs)); echoCancellation.setChecked(true); LinphonePreferences.instance().setEchoCancellation(true); + ((AudioManager)getActivity().getSystemService(Context.AUDIO_SERVICE)).setMode(AudioManager.MODE_NORMAL); + Log.i("Set audio mode on 'Normal'"); } else if (status == EcCalibratorStatus.Failed) { echoCancellerCalibration.setSummary(R.string.failed); echoCancellation.setChecked(true); LinphonePreferences.instance().setEchoCancellation(true); + ((AudioManager)getActivity().getSystemService(Context.AUDIO_SERVICE)).setMode(AudioManager.MODE_NORMAL); + Log.i("Set audio mode on 'Normal'"); } } }; + + initSettings(); + setListeners(); + hideSettings(); } private void removePreviousPreferencesFile() { - File dir = new File(LinphoneActivity.instance().getFilesDir().getAbsolutePath() + "shared_prefs"); - dir.delete(); + SharedPreferences.Editor editor = getPreferenceManager().getSharedPreferences().edit(); + editor.clear(); + editor.commit(); + + File dir = new File(getActivity().getFilesDir().getAbsolutePath() + "shared_prefs"); + LinphoneUtils.recursiveFileRemoval(dir); } // Inits the values or the listener on some settings @@ -159,11 +176,6 @@ public class SettingsFragment extends PreferencesListFragment { hidePreference(R.string.pref_in_app_store_key); } - - if (getResources().getBoolean(R.bool.disable_animations)) { - uncheckAndHidePreference(R.string.pref_animation_enable_key); - } - if (getResources().getBoolean(R.bool.disable_chat)) { findPreference(getString(R.string.pref_image_sharing_server_key)).setLayoutResource(R.layout.hidden); } @@ -173,7 +185,7 @@ public class SettingsFragment extends PreferencesListFragment { } if (!Version.isVideoCapable() || !LinphoneManager.getLcIfManagerNotDestroyedOrNull().isVideoSupported()) { - uncheckAndHidePreference(R.string.pref_video_enable_key); + emptyAndHidePreference(R.string.pref_video_key); } else { if (!AndroidCameraConfiguration.hasFrontCamera()) { uncheckAndHidePreference(R.string.pref_video_use_front_camera_key); @@ -186,7 +198,6 @@ public class SettingsFragment extends PreferencesListFragment { if (getResources().getBoolean(R.bool.hide_camera_settings)) { emptyAndHidePreference(R.string.pref_video_key); - hidePreference(R.string.pref_video_enable_key); } if (getResources().getBoolean(R.bool.disable_every_log)) { @@ -245,14 +256,20 @@ public class SettingsFragment extends PreferencesListFragment { } private void setPreferenceDefaultValueAndSummary(int pref, String value) { - if(value != null) { + if (value != null) { EditTextPreference etPref = (EditTextPreference) findPreference(getString(pref)); - etPref.setText(value); - etPref.setSummary(value); + if (etPref != null) { + etPref.setText(value); + etPref.setSummary(value); + } } } private void initTunnelSettings() { + if (!LinphoneManager.getLc().isTunnelAvailable()) { + return; + } + setPreferenceDefaultValueAndSummary(R.string.pref_tunnel_host_key, mPrefs.getTunnelHost()); setPreferenceDefaultValueAndSummary(R.string.pref_tunnel_port_key, String.valueOf(mPrefs.getTunnelPort())); ListPreference tunnelModePref = (ListPreference) findPreference(getString(R.string.pref_tunnel_mode_key)); @@ -464,7 +481,13 @@ public class SettingsFragment extends PreferencesListFragment { setListPreferenceValues(pref, entries, values); LinphoneLimeState lime = mPrefs.getLimeEncryption(); - pref.setSummary(lime.toString()); + if (lime == LinphoneLimeState.Disabled) { + pref.setSummary(getString(R.string.lime_encryption_entry_disabled)); + } else if (lime == LinphoneLimeState.Mandatory) { + pref.setSummary(getString(R.string.lime_encryption_entry_mandatory)); + } else if (lime == LinphoneLimeState.Preferred) { + pref.setSummary(getString(R.string.lime_encryption_entry_preferred)); + } pref.setValue(lime.toString()); } @@ -576,17 +599,32 @@ public class SettingsFragment extends PreferencesListFragment { @Override public boolean onPreferenceClick(Preference preference) { synchronized (SettingsFragment.this) { - try { - LinphoneManager.getInstance().startEcCalibration(mListener); - preference.setSummary(R.string.ec_calibrating); - } catch (LinphoneCoreException e) { - Log.w(e, "Cannot calibrate EC"); + preference.setSummary(R.string.ec_calibrating); + + int recordAudio = getActivity().getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getActivity().getPackageName()); + if (recordAudio == PackageManager.PERMISSION_GRANTED) { + startEchoCancellerCalibration(); + } else { + LinphoneActivity.instance().checkAndRequestRecordAudioPermissionForEchoCanceller(); } } return true; } }); } + + public void startEchoCancellerCalibration() { + try { + LinphoneManager.getInstance().startEcCalibration(mListener); + } catch (LinphoneCoreException e) { + Log.e(e); + } + } + + public void echoCalibrationFail() { + Preference echoCancellerCalibration = findPreference(getString(R.string.pref_echo_canceller_calibration_key)); + echoCancellerCalibration.setSummary(R.string.failed); + } private void initVideoSettings() { initializePreferredVideoSizePreferences((ListPreference) findPreference(getString(R.string.pref_preferred_video_size_key))); @@ -782,9 +820,14 @@ public class SettingsFragment extends PreferencesListFragment { } private void initCallSettings() { + CheckBoxPreference deviceRingtone = (CheckBoxPreference) findPreference(getString(R.string.pref_device_ringtone_key)); + CheckBoxPreference autoAnswer = (CheckBoxPreference) findPreference(getString(R.string.pref_auto_answer_key)); CheckBoxPreference rfc2833 = (CheckBoxPreference) findPreference(getString(R.string.pref_rfc2833_dtmf_key)); CheckBoxPreference sipInfo = (CheckBoxPreference) findPreference(getString(R.string.pref_sipinfo_dtmf_key)); + deviceRingtone.setChecked(mPrefs.isDeviceRingtoneEnabled()); + autoAnswer.setChecked(mPrefs.isAutoAnswerEnabled()); + if (mPrefs.useRfc2833Dtmfs()) { rfc2833.setChecked(true); sipInfo.setChecked(false); @@ -798,7 +841,63 @@ public class SettingsFragment extends PreferencesListFragment { setPreferenceDefaultValueAndSummary(R.string.pref_voice_mail_key, mPrefs.getVoiceMailUri()); } + public void enableDeviceRingtone(boolean enabled) { + LinphonePreferences.instance().enableDeviceRingtone(enabled); + LinphoneManager.getInstance().enableDeviceRingtone(enabled); + ((CheckBoxPreference)findPreference(getString(R.string.pref_device_ringtone_key))).setChecked(enabled); + } + private void setCallPreferencesListener() { + findPreference(getString(R.string.pref_device_ringtone_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + boolean use = (Boolean) newValue; + if (use) { + int readExternalStorage = getActivity().getPackageManager().checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE, getActivity().getPackageName()); + if (readExternalStorage == PackageManager.PERMISSION_GRANTED) { + mPrefs.enableDeviceRingtone(true); + LinphoneManager.getInstance().enableDeviceRingtone(true); + } else { + LinphoneActivity.instance().checkAndRequestReadExternalStoragePermissionForDeviceRingtone(); + } + } else { + mPrefs.enableDeviceRingtone(false); + LinphoneManager.getInstance().enableDeviceRingtone(false); + } + + return true; + } + }); + + findPreference(getString(R.string.pref_media_encryption_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + String value = newValue.toString(); + MediaEncryption menc = MediaEncryption.None; + if (value.equals(getString(R.string.pref_media_encryption_key_srtp))) + menc = MediaEncryption.SRTP; + else if (value.equals(getString(R.string.pref_media_encryption_key_zrtp))) + menc = MediaEncryption.ZRTP; + else if (value.equals(getString(R.string.pref_media_encryption_key_dtls))) + menc = MediaEncryption.DTLS; + mPrefs.setMediaEncryption(menc); + + preference.setSummary(mPrefs.getMediaEncryption().toString()); + return true; + } + }); + + initMediaEncryptionPreference((ListPreference) findPreference(getString(R.string.pref_media_encryption_key))); + + findPreference(getString(R.string.pref_auto_answer_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + boolean use = (Boolean) newValue; + mPrefs.enableAutoAnswer(use); + return true; + } + }); + findPreference(getString(R.string.pref_rfc2833_dtmf_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { @@ -877,22 +976,14 @@ public class SettingsFragment extends PreferencesListFragment { } private void initNetworkSettings() { - initMediaEncryptionPreference((ListPreference) findPreference(getString(R.string.pref_media_encryption_key))); - ((CheckBoxPreference) findPreference(getString(R.string.pref_wifi_only_key))).setChecked(mPrefs.isWifiOnlyEnabled()); // Disable UPnP if ICE si enabled, or disable ICE if UPnP is enabled CheckBoxPreference ice = (CheckBoxPreference) findPreference(getString(R.string.pref_ice_enable_key)); + CheckBoxPreference turn = (CheckBoxPreference) findPreference(getString(R.string.pref_turn_enable_key)); CheckBoxPreference upnp = (CheckBoxPreference) findPreference(getString(R.string.pref_upnp_enable_key)); ice.setChecked(mPrefs.isIceEnabled()); - if (mPrefs.isIceEnabled()) { - upnp.setEnabled(false); - } else { - upnp.setChecked(mPrefs.isUpnpEnabled()); - if (mPrefs.isUpnpEnabled()) { - ice.setEnabled(false); - } - } + turn.setChecked(mPrefs.isTurnEnabled()); CheckBoxPreference randomPort = (CheckBoxPreference) findPreference(getString(R.string.pref_transport_use_random_ports_key)); randomPort.setChecked(mPrefs.isUsingRandomPort()); @@ -934,20 +1025,26 @@ public class SettingsFragment extends PreferencesListFragment { public boolean onPreferenceChange(Preference preference, Object newValue) { CheckBoxPreference upnp = (CheckBoxPreference) findPreference(getString(R.string.pref_upnp_enable_key)); boolean value = (Boolean) newValue; - upnp.setChecked(false); - upnp.setEnabled(!value); mPrefs.setIceEnabled((Boolean) newValue); return true; } }); + findPreference(getString(R.string.pref_turn_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + CheckBoxPreference upnp = (CheckBoxPreference) findPreference(getString(R.string.pref_upnp_enable_key)); + boolean value = (Boolean) newValue; + mPrefs.setTurnEnabled((Boolean) newValue); + return true; + } + }); + findPreference(getString(R.string.pref_upnp_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { CheckBoxPreference ice = (CheckBoxPreference) findPreference(getString(R.string.pref_ice_enable_key)); boolean value = (Boolean) newValue; - ice.setChecked(false); - ice.setEnabled(!value); mPrefs.setUpnpEnabled(value); return true; } @@ -978,24 +1075,6 @@ public class SettingsFragment extends PreferencesListFragment { } }); - findPreference(getString(R.string.pref_media_encryption_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - String value = newValue.toString(); - MediaEncryption menc = MediaEncryption.None; - if (value.equals(getString(R.string.pref_media_encryption_key_srtp))) - menc = MediaEncryption.SRTP; - else if (value.equals(getString(R.string.pref_media_encryption_key_zrtp))) - menc = MediaEncryption.ZRTP; - else if (value.equals(getString(R.string.pref_media_encryption_key_dtls))) - menc = MediaEncryption.DTLS; - mPrefs.setMediaEncryption(menc); - - preference.setSummary(mPrefs.getMediaEncryption().toString()); - return true; - } - }); - findPreference(getString(R.string.pref_push_notification_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { @@ -1016,7 +1095,6 @@ public class SettingsFragment extends PreferencesListFragment { private void initAdvancedSettings() { ((CheckBoxPreference)findPreference(getString(R.string.pref_debug_key))).setChecked(mPrefs.isDebugEnabled()); ((CheckBoxPreference)findPreference(getString(R.string.pref_background_mode_key))).setChecked(mPrefs.isBackgroundModeEnabled()); - ((CheckBoxPreference)findPreference(getString(R.string.pref_animation_enable_key))).setChecked(mPrefs.areAnimationsEnabled()); ((CheckBoxPreference)findPreference(getString(R.string.pref_service_notification_key))).setChecked(mPrefs.getServiceNotificationVisibility()); ((CheckBoxPreference)findPreference(getString(R.string.pref_autostart_key))).setChecked(mPrefs.isAutoStartEnabled()); setPreferenceDefaultValueAndSummary(R.string.pref_remote_provisioning_key, mPrefs.getRemoteProvisioningUrl()); @@ -1043,15 +1121,6 @@ public class SettingsFragment extends PreferencesListFragment { } }); - findPreference(getString(R.string.pref_animation_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - boolean value = (Boolean) newValue; - mPrefs.setAnimationsEnabled(value); - return true; - } - }); - findPreference(getString(R.string.pref_service_notification_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { @@ -1112,6 +1181,7 @@ public class SettingsFragment extends PreferencesListFragment { public void onResume() { super.onResume(); + // Init the settings page interface initAccounts(); if (LinphoneActivity.isInstanciated()) { @@ -1119,7 +1189,7 @@ public class SettingsFragment extends PreferencesListFragment { } } - + @Override public void onPause() { LinphoneActivity.instance().hideTopBar(); diff --git a/src/org/linphone/StatusFragment.java b/src/org/linphone/StatusFragment.java index f558ee142..0bc785e7e 100644 --- a/src/org/linphone/StatusFragment.java +++ b/src/org/linphone/StatusFragment.java @@ -42,6 +42,7 @@ import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; +import android.support.v4.content.ContextCompat; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -142,6 +143,20 @@ public class StatusFragment extends Fragment { }; + isAttached = true; + Activity activity = getActivity(); + + if (activity instanceof LinphoneActivity) { + ((LinphoneActivity) activity).updateStatusFragment(this); + isInCall = false; + } else if (activity instanceof CallActivity) { + ((CallActivity) activity).updateStatusFragment(this); + isInCall = true; + } else if (activity instanceof AssistantActivity) { + ((AssistantActivity) activity).updateStatusFragment(this); + isInCall = false; + } + return view; } @@ -157,23 +172,6 @@ public class StatusFragment extends Fragment { } } - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - isAttached = true; - - if (activity instanceof LinphoneActivity) { - ((LinphoneActivity) activity).updateStatusFragment(this); - isInCall = false; - } else if (activity instanceof CallActivity) { - ((CallActivity) activity).updateStatusFragment(this); - isInCall = true; - } else if (activity instanceof AssistantActivity) { - ((AssistantActivity) activity).updateStatusFragment(this); - isInCall = false; - } - } - @Override public void onDetach() { super.onDetach(); @@ -399,7 +397,7 @@ public class StatusFragment extends Fragment { if(ZRTPdialog == null || !ZRTPdialog.isShowing()) { ZRTPdialog = new Dialog(getActivity()); ZRTPdialog.requestWindowFeature(Window.FEATURE_NO_TITLE); - Drawable d = new ColorDrawable(getResources().getColor(R.color.colorC)); + Drawable d = new ColorDrawable(ContextCompat.getColor(getActivity(), R.color.colorC)); d.setAlpha(200); ZRTPdialog.setContentView(R.layout.dialog); ZRTPdialog.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); diff --git a/src/org/linphone/assistant/AssistantActivity.java b/src/org/linphone/assistant/AssistantActivity.java index f7b1274ed..810587812 100644 --- a/src/org/linphone/assistant/AssistantActivity.java +++ b/src/org/linphone/assistant/AssistantActivity.java @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import org.linphone.LinphoneActivity; import org.linphone.LinphoneManager; import org.linphone.LinphonePreferences; +import org.linphone.LinphoneUtils; import org.linphone.LinphonePreferences.AccountBuilder; import org.linphone.R; import org.linphone.StatusFragment; @@ -51,6 +52,7 @@ import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; @@ -120,7 +122,7 @@ private static AssistantActivity instance; if (state == RegistrationState.RegistrationOk) { if (progress != null) progress.dismiss(); if (LinphoneManager.getLc().getDefaultProxyConfig() != null) { - launchEchoCancellerCalibration(true); + success(); } } else if (state == RegistrationState.RegistrationFailed) { if (progress != null) progress.dismiss(); @@ -272,24 +274,20 @@ private static AssistantActivity instance; } } - private boolean launchEchoCancellerCalibration(boolean sendEcCalibrationResult) { - if (getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()) == PackageManager.PERMISSION_GRANTED) { - boolean needsEchoCalibration = LinphoneManager.getLc().needsEchoCalibration(); - if (needsEchoCalibration && mPrefs.isFirstLaunch() && !echoCancellerAlreadyDone) { - EchoCancellerCalibrationFragment fragment = new EchoCancellerCalibrationFragment(); - fragment.enableEcCalibrationResultSending(sendEcCalibrationResult); - changeFragment(fragment); - currentFragment = AssistantFragmentsEnum.ECHO_CANCELLER_CALIBRATION; - back.setVisibility(View.VISIBLE); - cancel.setEnabled(false); - echoCancellerAlreadyDone = true; - return true; - } - isEchoCalibrationFinished(); + private void launchEchoCancellerCalibration(boolean sendEcCalibrationResult) { + int recordAudio = getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName()); + Log.i("[Permission] Record audio permission is " + (recordAudio == PackageManager.PERMISSION_GRANTED ? "granted" : "denied")); + + if (recordAudio == PackageManager.PERMISSION_GRANTED) { + EchoCancellerCalibrationFragment fragment = new EchoCancellerCalibrationFragment(); + fragment.enableEcCalibrationResultSending(sendEcCalibrationResult); + changeFragment(fragment); + currentFragment = AssistantFragmentsEnum.ECHO_CANCELLER_CALIBRATION; + back.setVisibility(View.VISIBLE); + cancel.setEnabled(false); } else { checkAndRequestAudioPermission(); } - return false; } private void logIn(String username, String password, String displayName, String domain, TransportType transport, boolean sendEcCalibrationResult) { @@ -379,7 +377,6 @@ private static AssistantActivity instance; } private void launchDownloadCodec() { - Log.i("linphone salut c'est miguel download"); OpenH264DownloadHelper downloadHelper = LinphoneCoreFactory.instance().createOpenH264DownloadHelper(); if (Version.getCpuAbis().contains("armeabi-v7a") && !Version.getCpuAbis().contains("x86") && !downloadHelper.isCodecFound()) { CodecDownloaderFragment codecFragment = new CodecDownloaderFragment(); @@ -388,27 +385,19 @@ private static AssistantActivity instance; back.setVisibility(View.VISIBLE); cancel.setEnabled(false); } else - endDownloadCodec(); + goToLinphoneActivity(); } public void endDownloadCodec() { - success(); + goToLinphoneActivity(); } public void saveCreatedAccount(String username, String password, String displayName, String domain, TransportType transport) { if (accountCreated) return; - if(username.startsWith("sip:")) { - username = username.substring(4); - } - - if (username.contains("@")) - username = username.split("@")[0]; - - if(domain.startsWith("sip:")) { - domain = domain.substring(4); - } + username = LinphoneUtils.getDisplayableUsernameFromAddress(username); + domain = LinphoneUtils.getDisplayableUsernameFromAddress(domain); String identity = "sip:" + username + "@" + domain; try { @@ -486,7 +475,7 @@ private static AssistantActivity instance; public void displayRegistrationInProgressDialog() { if(LinphoneManager.getLc().isNetworkReachable()) { progress = ProgressDialog.show(this, null, null); - Drawable d = new ColorDrawable(getResources().getColor(R.color.colorE)); + Drawable d = new ColorDrawable(ContextCompat.getColor(this, R.color.colorE)); d.setAlpha(200); progress.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); progress.getWindow().setBackgroundDrawable(d); @@ -499,7 +488,7 @@ private static AssistantActivity instance; remoteProvisioningInProgress = true; progress = ProgressDialog.show(this, null, null); - Drawable d = new ColorDrawable(getResources().getColor(R.color.colorE)); + Drawable d = new ColorDrawable(ContextCompat.getColor(this, R.color.colorE)); d.setAlpha(200); progress.getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); progress.getWindow().setBackgroundDrawable(d); @@ -553,6 +542,15 @@ private static AssistantActivity instance; } public void success() { + boolean needsEchoCalibration = LinphoneManager.getLc().needsEchoCalibration(); + if (needsEchoCalibration && mPrefs.isFirstLaunch()) { + launchEchoCancellerCalibration(true); + } else { + launchDownloadCodec(); + } + } + + private void goToLinphoneActivity() { mPrefs.firstLaunchSuccessful(); startActivity(new Intent().setClass(this, LinphoneActivity.class).putExtra("isNewProxyConfig", true)); finish(); diff --git a/src/org/linphone/assistant/CreateAccountActivationFragment.java b/src/org/linphone/assistant/CreateAccountActivationFragment.java index 1bc6b5934..0b1c7e721 100644 --- a/src/org/linphone/assistant/CreateAccountActivationFragment.java +++ b/src/org/linphone/assistant/CreateAccountActivationFragment.java @@ -17,9 +17,13 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -import java.net.URL; - +import org.linphone.LinphoneManager; import org.linphone.R; +import org.linphone.core.LinphoneXmlRpcRequest; +import org.linphone.core.LinphoneXmlRpcRequest.LinphoneXmlRpcRequestListener; +import org.linphone.core.LinphoneXmlRpcRequestImpl; +import org.linphone.core.LinphoneXmlRpcSession; +import org.linphone.core.LinphoneXmlRpcSessionImpl; import android.app.Fragment; import android.os.Bundle; @@ -30,17 +34,16 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.Toast; -import de.timroes.axmlrpc.XMLRPCCallback; -import de.timroes.axmlrpc.XMLRPCClient; -import de.timroes.axmlrpc.XMLRPCException; -import de.timroes.axmlrpc.XMLRPCServerException; /** * @author Sylvain Berfini */ -public class CreateAccountActivationFragment extends Fragment { - private String username, password, domain; +public class CreateAccountActivationFragment extends Fragment implements LinphoneXmlRpcRequestListener { + private String username, password; private Handler mHandler = new Handler(); private Button checkAccount; + private LinphoneXmlRpcSession xmlRpcSession; + private LinphoneXmlRpcRequest xmlRpcRequest; + private Runnable runNotOk, runOk, runNotReachable; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -58,58 +61,49 @@ public class CreateAccountActivationFragment extends Fragment { isAccountVerified(username); } }); - - return view; - } - - private void isAccountVerified(final String username) { - final Runnable runNotReachable = new Runnable() { + + runNotOk = new Runnable() { + public void run() { + checkAccount.setEnabled(true); + Toast.makeText(getActivity(), getString(R.string.assistant_account_not_validated), Toast.LENGTH_LONG).show(); + } + }; + runOk = new Runnable() { + public void run() { + checkAccount.setEnabled(true); + AssistantActivity.instance().saveCreatedAccount(username,password,null, getString(R.string.default_domain),null); + AssistantActivity.instance().isAccountVerified(username); + } + }; + runNotReachable = new Runnable() { public void run() { Toast.makeText(getActivity(), getString(R.string.wizard_server_unavailable), Toast.LENGTH_LONG).show(); } }; - try { - XMLRPCClient client = new XMLRPCClient(new URL(getString(R.string.wizard_url))); - - XMLRPCCallback listener = new XMLRPCCallback() { - Runnable runNotOk = new Runnable() { - public void run() { - checkAccount.setEnabled(true); - Toast.makeText(getActivity(), getString(R.string.assistant_account_not_validated), Toast.LENGTH_LONG).show(); - } - }; - - Runnable runOk = new Runnable() { - public void run() { - checkAccount.setEnabled(true); - AssistantActivity.instance().saveCreatedAccount(username,password,null, getString(R.string.default_domain),null); - AssistantActivity.instance().isAccountVerified(username); - } - }; - - public void onResponse(long id, Object result) { - int answer = (Integer) result; - if (answer != 1) { - mHandler.post(runNotOk); - } else { - mHandler.post(runOk); - } - } - - public void onError(long id, XMLRPCException error) { - mHandler.post(runNotReachable); - } - - public void onServerError(long id, XMLRPCServerException error) { - mHandler.post(runNotReachable); - } - }; + xmlRpcSession = new LinphoneXmlRpcSessionImpl(LinphoneManager.getLcIfManagerNotDestroyedOrNull(), getString(R.string.wizard_url)); + xmlRpcRequest = new LinphoneXmlRpcRequestImpl("check_account_validated", LinphoneXmlRpcRequest.ArgType.Int); + xmlRpcRequest.setListener(this); + + return view; + } - client.callAsync(listener, "check_account_validated", username + "@" + getString(R.string.default_domain)); - } - catch(Exception ex) { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { + int response = request.getIntResponse(); + if (response != 1) { + mHandler.post(runNotOk); + } else { + mHandler.post(runOk); + } + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { mHandler.post(runNotReachable); } } + + private void isAccountVerified(final String username) { + xmlRpcRequest.addStringArg(username + "@" + getString(R.string.default_domain)); + xmlRpcSession.sendRequest(xmlRpcRequest); + } } diff --git a/src/org/linphone/assistant/CreateAccountFragment.java b/src/org/linphone/assistant/CreateAccountFragment.java index c0c1dd1a2..695284546 100644 --- a/src/org/linphone/assistant/CreateAccountFragment.java +++ b/src/org/linphone/assistant/CreateAccountFragment.java @@ -17,20 +17,22 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -import java.net.URL; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.linphone.LinphoneManager; -import org.linphone.LinphoneService; import org.linphone.R; import org.linphone.core.LinphoneProxyConfig; +import org.linphone.core.LinphoneXmlRpcRequest; +import org.linphone.core.LinphoneXmlRpcRequest.LinphoneXmlRpcRequestListener; +import org.linphone.core.LinphoneXmlRpcRequestImpl; +import org.linphone.core.LinphoneXmlRpcSession; +import org.linphone.core.LinphoneXmlRpcSessionImpl; import android.accounts.Account; import android.accounts.AccountManager; import android.app.Fragment; -import android.content.Context; import android.os.Bundle; import android.os.Handler; import android.text.Editable; @@ -45,10 +47,6 @@ import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; -import de.timroes.axmlrpc.XMLRPCCallback; -import de.timroes.axmlrpc.XMLRPCClient; -import de.timroes.axmlrpc.XMLRPCException; -import de.timroes.axmlrpc.XMLRPCServerException; /** * @author Sylvain Berfini */ @@ -63,11 +61,7 @@ public class CreateAccountFragment extends Fragment { private boolean confirmPasswordOk = false; private Button createAccount; private final Pattern UPPER_CASE_REGEX = Pattern.compile("[A-Z]"); - private char[] acceptedChars = new char[]{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '_', '-' }; - private char[] acceptedCharsForPhoneNumbers = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '+' }; - private String inputFilterCharacters; + private LinphoneXmlRpcSession xmlRpcSession; private String getUsername() { String username = usernameEdit.getText().toString(); @@ -96,9 +90,7 @@ public class CreateAccountFragment extends Fragment { addXMLRPCUsernameHandler(usernameEdit, null); - inputFilterCharacters = new String(acceptedChars); if (getResources().getBoolean(R.bool.allow_only_phone_numbers_in_wizard)) { - inputFilterCharacters = new String(acceptedCharsForPhoneNumbers); usernameEdit.setInputType(InputType.TYPE_CLASS_NUMBER); } @@ -126,6 +118,8 @@ public class CreateAccountFragment extends Fragment { } } } + + xmlRpcSession = new LinphoneXmlRpcSessionImpl(LinphoneManager.getLcIfManagerNotDestroyedOrNull(), getString(R.string.wizard_url)); return view; } @@ -152,58 +146,46 @@ public class CreateAccountFragment extends Fragment { } private void isUsernameRegistred(final String username, final ImageView icon) { + final Runnable runNotOk = new Runnable() { + public void run() { + usernameOk = false; + displayError(usernameOk, usernameError, usernameEdit, LinphoneManager.getInstance().getContext().getString(R.string.wizard_username_unavailable)); + createAccount.setEnabled(usernameOk && passwordOk && confirmPasswordOk && emailOk); + } + }; + final Runnable runOk = new Runnable() { + public void run() { + usernameOk = true; + displayError(usernameOk, usernameError, usernameEdit, ""); + createAccount.setEnabled(usernameOk && passwordOk && confirmPasswordOk && emailOk); + } + }; final Runnable runNotReachable = new Runnable() { public void run() { usernameOk = false; - displayError(usernameOk, usernameError, usernameEdit, getResources().getString(R.string.wizard_server_unavailable)); + displayError(usernameOk, usernameError, usernameEdit, LinphoneManager.getInstance().getContext().getString(R.string.wizard_server_unavailable)); createAccount.setEnabled(usernameOk && passwordOk && confirmPasswordOk && emailOk); } }; - try { - XMLRPCClient client = new XMLRPCClient(new URL(getString(R.string.wizard_url))); - - XMLRPCCallback listener = new XMLRPCCallback() { - Runnable runNotOk = new Runnable() { - public void run() { - usernameOk = false; - displayError(usernameOk, usernameError, usernameEdit, getResources().getString(R.string.wizard_username_unavailable)); - createAccount.setEnabled(usernameOk && passwordOk && confirmPasswordOk && emailOk); - } - }; - - Runnable runOk = new Runnable() { - public void run() { - usernameOk = true; - displayError(usernameOk, usernameError, usernameEdit, ""); - createAccount.setEnabled(usernameOk && passwordOk && confirmPasswordOk && emailOk); - } - }; - - public void onResponse(long id, Object result) { - int answer = (Integer) result; - if (answer != 0) { - mHandler.post(runNotOk); - } - else { + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("check_account", LinphoneXmlRpcRequest.ArgType.Int); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { + int response = request.getIntResponse(); + if (response != 0) { + mHandler.post(runNotOk); + } else { mHandler.post(runOk); } - } - - public void onError(long id, XMLRPCException error) { - mHandler.post(runNotReachable); - } - - public void onServerError(long id, XMLRPCServerException error) { - mHandler.post(runNotReachable); - } - }; - - client.callAsync(listener, "check_account", username); - } - catch(Exception ex) { - mHandler.post(runNotReachable); - } + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { + mHandler.post(runNotReachable); + } + } + }); + xmlRpcRequest.addStringArg(username); + xmlRpcSession.sendRequest(xmlRpcRequest); } private boolean isEmailCorrect(String email) { @@ -216,53 +198,43 @@ public class CreateAccountFragment extends Fragment { } private void createAccount(final String username, final String password, String email, boolean suscribe) { + final Runnable runNotOk = new Runnable() { + public void run() { + //TODO errorMessage.setText(R.string.wizard_failed); + } + }; + final Runnable runOk = new Runnable() { + public void run() { + AssistantActivity.instance().displayAssistantConfirm(username, password); + } + }; final Runnable runNotReachable = new Runnable() { public void run() { - //TODO errorMessage.setText(R.string.wizard_server_unavailable); + //TODO errorMessage.setText(R.string.wizard_not_reachable); } }; - final Context context = AssistantActivity.instance() == null ? LinphoneService.instance().getApplicationContext() : AssistantActivity.instance(); - - try { - XMLRPCClient client = new XMLRPCClient(new URL(context.getString(R.string.wizard_url))); - - XMLRPCCallback listener = new XMLRPCCallback() { - Runnable runNotOk = new Runnable() { - public void run() { - //TODO errorMessage.setText(R.string.wizard_failed); + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("create_account_with_useragent", LinphoneXmlRpcRequest.ArgType.Int); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { + int response = request.getIntResponse(); + if (response != 0) { + mHandler.post(runNotOk); + } else { + mHandler.post(runOk); } - }; - - Runnable runOk = new Runnable() { - public void run() { - AssistantActivity.instance().displayAssistantConfirm(username, password); - } - }; - - public void onResponse(long id, Object result) { - int answer = (Integer) result; - if (answer != 0) { - mHandler.post(runNotOk); - } else { - mHandler.post(runOk); - } - } - - public void onError(long id, XMLRPCException error) { - mHandler.post(runNotReachable); - } - - public void onServerError(long id, XMLRPCServerException error) { - mHandler.post(runNotReachable); - } - }; - - client.callAsync(listener, "create_account_with_useragent", username, password, email, LinphoneManager.getInstance().getUserAgent()); - } - catch(Exception ex) { - mHandler.post(runNotReachable); - } + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { + mHandler.post(runNotReachable); + } + } + }); + xmlRpcRequest.addStringArg(username); + xmlRpcRequest.addStringArg(password); + xmlRpcRequest.addStringArg(email); + xmlRpcRequest.addStringArg(LinphoneManager.getInstance().getUserAgent()); + xmlRpcSession.sendRequest(xmlRpcRequest); } private void addXMLRPCUsernameHandler(final EditText field, final ImageView icon) { diff --git a/src/org/linphone/assistant/EchoCancellerCalibrationFragment.java b/src/org/linphone/assistant/EchoCancellerCalibrationFragment.java index c35a5d487..528733d61 100644 --- a/src/org/linphone/assistant/EchoCancellerCalibrationFragment.java +++ b/src/org/linphone/assistant/EchoCancellerCalibrationFragment.java @@ -19,35 +19,37 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -import java.net.URL; - import org.linphone.LinphoneManager; import org.linphone.R; -import org.linphone.core.LinphoneCore.EcCalibratorStatus; import org.linphone.core.LinphoneCore; +import org.linphone.core.LinphoneCore.EcCalibratorStatus; import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreListenerBase; +import org.linphone.core.LinphoneXmlRpcRequest; +import org.linphone.core.LinphoneXmlRpcRequest.LinphoneXmlRpcRequestListener; +import org.linphone.core.LinphoneXmlRpcRequestImpl; +import org.linphone.core.LinphoneXmlRpcSession; +import org.linphone.core.LinphoneXmlRpcSessionImpl; import org.linphone.mediastream.Log; +import android.app.Fragment; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import de.timroes.axmlrpc.XMLRPCCallback; -import de.timroes.axmlrpc.XMLRPCClient; -import de.timroes.axmlrpc.XMLRPCException; -import de.timroes.axmlrpc.XMLRPCServerException; /** * @author Ghislain MARY */ -public class EchoCancellerCalibrationFragment extends Fragment { +public class EchoCancellerCalibrationFragment extends Fragment implements LinphoneXmlRpcRequestListener { private Handler mHandler = new Handler(); private boolean mSendEcCalibrationResult = false; private LinphoneCoreListenerBase mListener; + private LinphoneXmlRpcSession xmlRpcSession; + private LinphoneXmlRpcRequest xmlRpcRequest; + private Runnable runFinished; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -56,7 +58,7 @@ public class EchoCancellerCalibrationFragment extends Fragment { mListener = new LinphoneCoreListenerBase(){ @Override - public void ecCalibrationStatus(LinphoneCore lc,LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data) { + public void ecCalibrationStatus(LinphoneCore lc, LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data) { LinphoneManager.getInstance().routeAudioToReceiver(); if (mSendEcCalibrationResult) { sendEcCalibrationResult(status, delay_ms); @@ -65,6 +67,15 @@ public class EchoCancellerCalibrationFragment extends Fragment { } } }; + runFinished = new Runnable() { + public void run() { + AssistantActivity.instance().isEchoCalibrationFinished(); + } + }; + + xmlRpcSession = new LinphoneXmlRpcSessionImpl(LinphoneManager.getLcIfManagerNotDestroyedOrNull(), getString(R.string.wizard_url)); + xmlRpcRequest = new LinphoneXmlRpcRequestImpl("add_ec_calibration_result", LinphoneXmlRpcRequest.ArgType.None); + xmlRpcRequest.setListener(this); try { LinphoneManager.getInstance().startEcCalibration(mListener); @@ -79,34 +90,19 @@ public class EchoCancellerCalibrationFragment extends Fragment { mSendEcCalibrationResult = enabled; } + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + mHandler.post(runFinished); + } + private void sendEcCalibrationResult(EcCalibratorStatus status, int delayMs) { - try { - XMLRPCClient client = new XMLRPCClient(new URL(getString(R.string.wizard_url))); - - XMLRPCCallback listener = new XMLRPCCallback() { - Runnable runFinished = new Runnable() { - public void run() { - AssistantActivity.instance().isEchoCalibrationFinished(); - } - }; - - public void onResponse(long id, Object result) { - mHandler.post(runFinished); - } - - public void onError(long id, XMLRPCException error) { - mHandler.post(runFinished); - } - - public void onServerError(long id, XMLRPCServerException error) { - mHandler.post(runFinished); - } - }; - - Boolean hasBuiltInEchoCanceler = LinphoneManager.getLc().hasBuiltInEchoCanceler(); - Log.i("Add echo canceller calibration result: manufacturer=" + Build.MANUFACTURER + " model=" + Build.MODEL + " status=" + status + " delay=" + delayMs + "ms" + " hasBuiltInEchoCanceler " + hasBuiltInEchoCanceler); - client.callAsync(listener, "add_ec_calibration_result", Build.MANUFACTURER, Build.MODEL, status.toString(), delayMs, hasBuiltInEchoCanceler); - } - catch(Exception ex) {} + Boolean hasBuiltInEchoCanceler = LinphoneManager.getLc().hasBuiltInEchoCanceler(); + Log.i("Add echo canceller calibration result: manufacturer=" + Build.MANUFACTURER + " model=" + Build.MODEL + " status=" + status + " delay=" + delayMs + "ms" + " hasBuiltInEchoCanceler " + hasBuiltInEchoCanceler); + xmlRpcRequest.addStringArg(Build.MANUFACTURER); + xmlRpcRequest.addStringArg(Build.MODEL); + xmlRpcRequest.addStringArg(status.toString()); + xmlRpcRequest.addIntArg(delayMs); + xmlRpcRequest.addIntArg(hasBuiltInEchoCanceler ? 1 : 0); + xmlRpcSession.sendRequest(xmlRpcRequest); } } diff --git a/src/org/linphone/assistant/RemoteProvisioningLoginActivity.java b/src/org/linphone/assistant/RemoteProvisioningLoginActivity.java index 1d5a90afe..c5d2799a7 100644 --- a/src/org/linphone/assistant/RemoteProvisioningLoginActivity.java +++ b/src/org/linphone/assistant/RemoteProvisioningLoginActivity.java @@ -20,9 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import org.linphone.LinphoneManager; import org.linphone.LinphonePreferences; -import org.linphone.core.LinphoneCoreListenerBase; import org.linphone.R; import org.linphone.core.LinphoneCore; +import org.linphone.core.LinphoneCoreListenerBase; import org.linphone.xmlrpc.XmlRpcHelper; import org.linphone.xmlrpc.XmlRpcListenerBase; @@ -32,7 +32,6 @@ import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; -import android.widget.ImageView; import android.widget.Toast; /** @@ -40,7 +39,6 @@ import android.widget.Toast; */ public class RemoteProvisioningLoginActivity extends Activity implements OnClickListener { private EditText login, password, domain; - private ImageView cancel; private Button connect; private LinphoneCoreListenerBase mListener; @@ -53,9 +51,6 @@ public class RemoteProvisioningLoginActivity extends Activity implements OnClick password = (EditText) findViewById(R.id.assistant_password); domain = (EditText) findViewById(R.id.assistant_domain); - //cancel = (ImageView) findViewById(R.id.cancel); - //cancel.setOnClickListener(this); - connect = (Button) findViewById(R.id.assistant_connect); connect.setOnClickListener(this); @@ -86,8 +81,6 @@ public class RemoteProvisioningLoginActivity extends Activity implements OnClick } private boolean storeAccount(String username, String password, String domain) { - LinphoneCore lc = LinphoneManager.getLc(); - XmlRpcHelper xmlRpcHelper = new XmlRpcHelper(); xmlRpcHelper.getRemoteProvisioningFilenameAsync(new XmlRpcListenerBase() { @Override diff --git a/src/org/linphone/compatibility/Compatibility.java b/src/org/linphone/compatibility/Compatibility.java index 9a6f1ec5a..bab06b2b9 100644 --- a/src/org/linphone/compatibility/Compatibility.java +++ b/src/org/linphone/compatibility/Compatibility.java @@ -36,6 +36,7 @@ import android.database.Cursor; import android.graphics.Bitmap; import android.media.AudioManager; import android.net.Uri; +import android.os.PowerManager; import android.preference.Preference; import android.provider.Settings; import android.view.ViewTreeObserver; @@ -344,4 +345,13 @@ public class Compatibility { } return true; } + + @SuppressWarnings("deprecation") + public static boolean isScreenOn(PowerManager pm) { + if (Version.sdkAboveOrEqual(20)) { + return pm.isInteractive(); + } else { + return pm.isScreenOn(); + } + } } diff --git a/src/org/linphone/gcm/GCMService.java b/src/org/linphone/gcm/GCMService.java index 7d6c24936..42803cf92 100644 --- a/src/org/linphone/gcm/GCMService.java +++ b/src/org/linphone/gcm/GCMService.java @@ -43,19 +43,22 @@ public class GCMService extends GCMBaseIntentService { } - @Override - protected void onError(Context context, String errorId) { + private void initLogger(Context context) { + LinphonePreferences.instance().setContext(context); boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled); LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name)); + } + + @Override + protected void onError(Context context, String errorId) { + initLogger(context); Log.e("Error while registering push notification : " + errorId); } @Override protected void onMessage(Context context, Intent intent) { - boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); - LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled); - LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name)); + initLogger(context); Log.d("Push notification received"); if (!LinphoneService.isReady()) { @@ -70,15 +73,12 @@ public class GCMService extends GCMBaseIntentService { } } }); - } } @Override protected void onRegistered(Context context, String regId) { - boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); - LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled); - LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name)); + initLogger(context); Log.d("Registered push notification : " + regId); LinphonePreferences.instance().setPushNotificationRegistrationID(regId); @@ -86,9 +86,7 @@ public class GCMService extends GCMBaseIntentService { @Override protected void onUnregistered(Context context, String regId) { - boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); - LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled); - LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name)); + initLogger(context); Log.w("Unregistered push notification : " + regId); LinphonePreferences.instance().setPushNotificationRegistrationID(null); diff --git a/src/org/linphone/purchase/InAppPurchaseActivity.java b/src/org/linphone/purchase/InAppPurchaseActivity.java index ecc993a0b..bc806fc66 100644 --- a/src/org/linphone/purchase/InAppPurchaseActivity.java +++ b/src/org/linphone/purchase/InAppPurchaseActivity.java @@ -39,7 +39,6 @@ import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; -import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; diff --git a/src/org/linphone/purchase/InAppPurchaseHelper.java b/src/org/linphone/purchase/InAppPurchaseHelper.java index 729aabb25..5174d2063 100644 --- a/src/org/linphone/purchase/InAppPurchaseHelper.java +++ b/src/org/linphone/purchase/InAppPurchaseHelper.java @@ -339,7 +339,8 @@ public class InAppPurchaseHelper { } private Purchasable verifySignature(String payload, String signature) { - XmlRpcHelper helper = new XmlRpcHelper(); + // TODO FIXME rework to be async + /*XmlRpcHelper helper = new XmlRpcHelper(); if (helper.verifySignature(payload, signature)) { try { JSONObject json = new JSONObject(payload); @@ -350,7 +351,7 @@ public class InAppPurchaseHelper { } catch (JSONException e) { Log.e(e); } - } + }*/ return null; } diff --git a/src/org/linphone/ui/BubbleChat.java b/src/org/linphone/ui/BubbleChat.java index 712c31933..9f0420d27 100644 --- a/src/org/linphone/ui/BubbleChat.java +++ b/src/org/linphone/ui/BubbleChat.java @@ -29,7 +29,6 @@ import java.util.Map.Entry; import org.linphone.LinphoneActivity; import org.linphone.LinphoneContact; import org.linphone.LinphoneManager; -import org.linphone.LinphonePreferences; import org.linphone.LinphoneUtils; import org.linphone.R; import org.linphone.core.LinphoneBuffer; diff --git a/src/org/linphone/ui/CallButton.java b/src/org/linphone/ui/CallButton.java index 82447ca0f..5c29f8567 100644 --- a/src/org/linphone/ui/CallButton.java +++ b/src/org/linphone/ui/CallButton.java @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. package org.linphone.ui; import org.linphone.LinphoneManager; +import org.linphone.LinphonePreferences; import org.linphone.R; import org.linphone.core.CallDirection; import org.linphone.core.LinphoneCallLog; @@ -54,7 +55,7 @@ public class CallButton extends ImageView implements OnClickListener, AddressAwa if (mAddress.getText().length() > 0) { LinphoneManager.getInstance().newOutgoingCall(mAddress); } else { - if (getContext().getResources().getBoolean(R.bool.call_last_log_if_adress_is_empty)) { + if (LinphonePreferences.instance().isBisFeatureEnabled()) { LinphoneCallLog[] logs = LinphoneManager.getLc().getCallLogs(); LinphoneCallLog log = null; for (LinphoneCallLog l : logs) { diff --git a/src/org/linphone/ui/LinphoneOverlay.java b/src/org/linphone/ui/LinphoneOverlay.java index 6cb15ac0d..e4b2fd7f6 100644 --- a/src/org/linphone/ui/LinphoneOverlay.java +++ b/src/org/linphone/ui/LinphoneOverlay.java @@ -26,6 +26,7 @@ public class LinphoneOverlay extends org.linphone.mediastream.video.display.GL2J private float y; private float touchX; private float touchY; + private boolean dragEnabled; private AndroidVideoWindowImpl androidVideoWindowImpl; public LinphoneOverlay(Context context, AttributeSet attrs, int defStyle) { @@ -62,7 +63,7 @@ public class LinphoneOverlay extends org.linphone.mediastream.video.display.GL2J params.width = callParams.getReceivedVideoSize().width; params.height = callParams.getReceivedVideoSize().height; LinphoneManager.getLc().setVideoWindow(androidVideoWindowImpl); - + setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -71,6 +72,13 @@ public class LinphoneOverlay extends org.linphone.mediastream.video.display.GL2J context.startActivity(intent); } }); + setOnLongClickListener(new OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + dragEnabled = true; + return true; + } + }); } public LinphoneOverlay(Context context, AttributeSet attrs) { @@ -95,11 +103,14 @@ public class LinphoneOverlay extends org.linphone.mediastream.video.display.GL2J touchY = event.getY(); break; case MotionEvent.ACTION_MOVE: - updateViewPostion(); + if (dragEnabled) { + updateViewPostion(); + } break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: touchX = touchY = 0; + dragEnabled = false; break; default: break; diff --git a/src/org/linphone/ui/LinphoneSliders.java b/src/org/linphone/ui/LinphoneSliders.java index 4c6dc3f8e..b643255f2 100644 --- a/src/org/linphone/ui/LinphoneSliders.java +++ b/src/org/linphone/ui/LinphoneSliders.java @@ -1,7 +1,5 @@ package org.linphone.ui; -import org.linphone.R; - import android.content.Context; import android.graphics.Canvas; import android.graphics.drawable.Drawable; diff --git a/src/org/linphone/ui/PreferencesListFragment.java b/src/org/linphone/ui/PreferencesListFragment.java index 635813c5a..280b3d3b8 100644 --- a/src/org/linphone/ui/PreferencesListFragment.java +++ b/src/org/linphone/ui/PreferencesListFragment.java @@ -70,7 +70,7 @@ public class PreferencesListFragment extends ListFragment { } // Must be provided - public PreferencesListFragment(){ + public PreferencesListFragment() { } @@ -123,7 +123,7 @@ public class PreferencesListFragment extends ListFragment { m.setAccessible(true); m.invoke(mPreferenceManager); } catch(Exception e) { - Log.e(e); + Log.e("[PreferencesListFragment] onStop " + e); } } @@ -136,7 +136,7 @@ public class PreferencesListFragment extends ListFragment { m.setAccessible(true); m.invoke(mPreferenceManager); } catch(Exception e) { - Log.e(e); + Log.e("[PreferencesListFragment] onDestroy " + e); } } @@ -154,7 +154,7 @@ public class PreferencesListFragment extends ListFragment { m.setAccessible(true); m.invoke(mPreferenceManager, requestCode, resultCode, data); } catch(Exception e) { - Log.e(e); + Log.e("[PreferencesListFragment] onActivityResult " + e); } } @@ -188,7 +188,7 @@ public class PreferencesListFragment extends ListFragment { PreferenceManager preferenceManager = c.newInstance(this.getActivity(), FIRST_REQUEST_CODE); return preferenceManager; } catch(Exception e) { - Log.e(e); + Log.e("[PreferencesListFragment] onCreatePreferenceManager " + e); return null; } } @@ -215,7 +215,7 @@ public class PreferencesListFragment extends ListFragment { postBindPreferences(); } }catch(Exception e){ - Log.e(e); + Log.e("[PreferencesListFragment] setPreferenceScreen " + e); } } @@ -231,7 +231,7 @@ public class PreferencesListFragment extends ListFragment { m.setAccessible(true); return (PreferenceScreen) m.invoke(mPreferenceManager); } catch(Exception e) { - Log.e(e); + Log.e("[PreferencesListFragment] getPreferenceScreen " + e); } return null; @@ -250,7 +250,7 @@ public class PreferencesListFragment extends ListFragment { PreferenceScreen prefScreen = (PreferenceScreen) m.invoke(mPreferenceManager, getActivity(), preferencesResId, getPreferenceScreen()); setPreferenceScreen(prefScreen); } catch(Exception e) { - Log.e(e); + Log.e("[PreferencesListFragment] addPreferencesFromResource " + e); } } @@ -263,6 +263,7 @@ public class PreferencesListFragment extends ListFragment { */ public Preference findPreference(CharSequence key) { if (mPreferenceManager == null) { + Log.e("[PreferencesListFragment] PreferenceManager is null !"); return null; } return mPreferenceManager.findPreference(key); diff --git a/src/org/linphone/ui/SlidingDrawer.java b/src/org/linphone/ui/SlidingDrawer.java index de1ee6e9e..f14139343 100644 --- a/src/org/linphone/ui/SlidingDrawer.java +++ b/src/org/linphone/ui/SlidingDrawer.java @@ -160,6 +160,7 @@ public class SlidingDrawer extends ViewGroup { * @param defStyle * The style to apply to this widget. */ + @SuppressWarnings("deprecation") public SlidingDrawer(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray a = context.obtainStyledAttributes(attrs, diff --git a/src/org/linphone/xmlrpc/XmlRpcHelper.java b/src/org/linphone/xmlrpc/XmlRpcHelper.java index 25d543b8b..3cecd89eb 100644 --- a/src/org/linphone/xmlrpc/XmlRpcHelper.java +++ b/src/org/linphone/xmlrpc/XmlRpcHelper.java @@ -1,16 +1,14 @@ package org.linphone.xmlrpc; -import java.net.MalformedURLException; -import java.net.URL; - +import org.linphone.LinphoneManager; import org.linphone.LinphonePreferences; +import org.linphone.core.LinphoneXmlRpcRequest; +import org.linphone.core.LinphoneXmlRpcRequest.LinphoneXmlRpcRequestListener; +import org.linphone.core.LinphoneXmlRpcRequestImpl; +import org.linphone.core.LinphoneXmlRpcSession; +import org.linphone.core.LinphoneXmlRpcSessionImpl; import org.linphone.mediastream.Log; -import de.timroes.axmlrpc.XMLRPCCallback; -import de.timroes.axmlrpc.XMLRPCClient; -import de.timroes.axmlrpc.XMLRPCException; -import de.timroes.axmlrpc.XMLRPCServerException; - public class XmlRpcHelper { public static final String SERVER_ERROR_INVALID_ACCOUNT = "ERROR_INVALID_ACCOUNT"; public static final String SERVER_ERROR_PURCHASE_CANCELLED = "ERROR_PURCHASE_CANCELLED"; @@ -22,259 +20,119 @@ public class XmlRpcHelper { public static final String CLIENT_ERROR_INVALID_SERVER_URL = "INVALID_SERVER_URL"; public static final String CLIENT_ERROR_SERVER_NOT_REACHABLE = "SERVER_NOT_REACHABLE"; - - private XMLRPCClient mXmlRpcClient; + + private LinphoneXmlRpcSession xmlRpcSession; public XmlRpcHelper() { - try { - mXmlRpcClient = new XMLRPCClient(new URL(LinphonePreferences.instance().getInAppPurchaseValidatingServerUrl())); - } catch (MalformedURLException e) { - Log.e(e); - } + xmlRpcSession = new LinphoneXmlRpcSessionImpl(LinphoneManager.getLcIfManagerNotDestroyedOrNull(), LinphonePreferences.instance().getInAppPurchaseValidatingServerUrl()); } public void createAccountAsync(final XmlRpcListener listener, String username, String email, String password) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("createAccountAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("create_account", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (result.startsWith("ERROR_")) { Log.e(result); listener.onError(result); return; } - listener.onAccountCreated(result); - } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "create_account", username, email, password == null ? "" : password); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public String createAccount(String username, String email, String password) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("create_account", username, email, password == null ? "" : password); - String result = (String)object; - Log.d("createAccount: " + result); - - if (result.startsWith("ERROR_")) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); - return null; + listener.onError(result); } - return result; - - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return null; + }); + xmlRpcRequest.addStringArg(username); + xmlRpcRequest.addStringArg(email); + xmlRpcRequest.addStringArg(password == null ? "" : password); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void getAccountExpireAsync(final XmlRpcListener listener, String username, String password) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("getAccountExpireAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("get_expiration_for_account", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (result.startsWith("ERROR_")) { Log.e(result); listener.onError(result); return; } - listener.onAccountExpireFetched(result); - } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "get_expiration_for_account", username, password); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public String getAccountExpire(String username, String password) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("get_expiration_for_account", username, password); - String result = (String)object; - Log.d("getAccountExpire: " + result); - - if (result.startsWith("ERROR_")) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); - return null; + listener.onError(result); } - return result; - - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return null; + }); + xmlRpcRequest.addStringArg(username); + xmlRpcRequest.addStringArg(password); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void updateAccountExpireAsync(final XmlRpcListener listener, String username, String password, String payload, String signature) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("updateAccountExpireAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("update_expiration_date", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (result.startsWith("ERROR_")) { Log.e(result); listener.onError(result); return; } - listener.onAccountExpireUpdated(result); - } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "update_expiration_date", username, password, payload, signature); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public String updateAccountExpire(String username, String password, String payload, String signature) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("update_expiration_date", username, password, payload, signature); - String result = (String)object; - Log.d("updateAccountExpire: " + result); - - if (result.startsWith("ERROR_")) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); - return null; + listener.onError(result); } - return result; - - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return null; + }); + xmlRpcRequest.addStringArg(username); + xmlRpcRequest.addStringArg(password); + xmlRpcRequest.addStringArg(payload); + xmlRpcRequest.addStringArg(signature); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void activateAccountAsync(final XmlRpcListener listener, String username, String password) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("activateAccountAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("activate_account", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (result.startsWith("ERROR_")) { Log.e(result); listener.onError(result); return; } - listener.onAccountActivated(result); - return; - } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "activate_account", username, password); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public String activateAccount(String gmailAccount, String username, String password) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("activate_account", username, password); - String result = (String)object; - Log.d("activateAccount: " + result); - - if (result.startsWith("ERROR_")) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); - return null; + listener.onError(result); } - return result; - - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return null; + }); + xmlRpcRequest.addStringArg(username); + xmlRpcRequest.addStringArg(password); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void isAccountActivatedAsync(final XmlRpcListener listener, String username) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("isAccountActivatedAsync: " + result); + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("check_account_activated", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if ("OK".equals(result)) { listener.onAccountActivatedFetched(true); return; @@ -283,100 +141,45 @@ public class XmlRpcHelper { listener.onError(result); } listener.onAccountActivatedFetched(false); - } - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "check_account_activated", username); - } - } - - public boolean isAccountActivated(String username) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("check_account_activated", username); - String result = (String)object; - Log.d("isAccountActivated: " + result); - - if ("OK".equals(result)) { - return true; - } else if (!"ERROR_ACCOUNT_NOT_ACTIVATED".equals(result)) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); + listener.onError(result); } - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return false; + }); + xmlRpcRequest.addStringArg(username); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void isTrialAccountAsync(final XmlRpcListener listener, String username, String password) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("isTrialAccountAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("check_account_trial", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (!"NOK".equals(result) && !"OK".equals(result)) { listener.onError(result); } listener.onAccountFetched("OK".equals(result)); + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { + Log.e(result); + listener.onError(result); } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "check_account_trial", username, password); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public boolean isTrialAccount(String username, String password) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("check_account_trial", username, password); - String result = (String)object; - Log.d("isTrialAccount: " + result); - - return "OK".equals(result); - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return false; + }); + xmlRpcRequest.addStringArg(username); + xmlRpcRequest.addStringArg(password); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void isAccountAsync(final XmlRpcListener listener, String username) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("isAccountAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("check_account_activated", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if ("OK".equals(result)) { listener.onAccountFetched(true); return; @@ -385,55 +188,23 @@ public class XmlRpcHelper { listener.onError(result); } listener.onAccountFetched(false); - } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "check_account_activated", username); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public boolean isAccount(String username) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("check_account_activated", username); - String result = (String)object; - Log.d("isAccount: " + result); - - if ("OK".equals(result)) { - return true; - } else if (!"ERROR_ACCOUNT_DOESNT_EXIST".equals(result)) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); + listener.onError(result); } - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return false; + }); + xmlRpcRequest.addStringArg(username); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void changeAccountEmailAsync(final XmlRpcListener listener, String username, String password, String newEmail) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("changeAccountEmailAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("change_email", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (result.startsWith("ERROR_")) { Log.e(result); listener.onError(result); @@ -441,56 +212,25 @@ public class XmlRpcHelper { } listener.onAccountEmailChanged(result); - } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "change_email", username, password, newEmail); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public String changeAccountEmail(String username, String password, String newEmail) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("change_email", username, password, newEmail); - String result = (String)object; - Log.d("changeAccountEmail: " + result); - - if (result.startsWith("ERROR_")) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); - return null; + listener.onError(result); } - return result; - - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return null; + }); + xmlRpcRequest.addStringArg(username); + xmlRpcRequest.addStringArg(password); + xmlRpcRequest.addStringArg(newEmail); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void changeAccountPasswordAsync(final XmlRpcListener listener, String username, String oldPassword, String newPassword) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("changeAccountPasswordAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("change_password", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (result.startsWith("ERROR_")) { Log.e(result); listener.onError(result); @@ -498,56 +238,25 @@ public class XmlRpcHelper { } listener.onAccountPasswordChanged(result); - } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "change_password", username, oldPassword, newPassword); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public String changeAccountPassword(String username, String oldPassword, String newPassword) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("change_password", username, oldPassword, newPassword); - String result = (String)object; - Log.d("changeAccountPassword: " + result); - - if (result.startsWith("ERROR_")) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); - return null; + listener.onError(result); } - return result; - - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return null; + }); + xmlRpcRequest.addStringArg(username); + xmlRpcRequest.addStringArg(oldPassword); + xmlRpcRequest.addStringArg(newPassword); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void changeAccountHashPasswordAsync(final XmlRpcListener listener, String username, String oldPassword, String newPassword) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("changeAccountHashPasswordAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("change_hash", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (result.startsWith("ERROR_")) { Log.e(result); listener.onError(result); @@ -555,56 +264,25 @@ public class XmlRpcHelper { } listener.onAccountPasswordChanged(result); - } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "change_hash", username, oldPassword, newPassword); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public String changeAccountHashPassword(String username, String oldPassword, String newPassword) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("change_hash", username, oldPassword, newPassword); - String result = (String)object; - Log.d("changeAccountHashPassword: " + result); - - if (result.startsWith("ERROR_")) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); - return null; + listener.onError(result); } - return result; - - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return null; + }); + xmlRpcRequest.addStringArg(username); + xmlRpcRequest.addStringArg(oldPassword); + xmlRpcRequest.addStringArg(newPassword); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void sendRecoverPasswordLinkByEmailAsync(final XmlRpcListener listener, String usernameOrEmail) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("sendRecoverPasswordLinkByEmailAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("send_reset_account_password_email", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (result.startsWith("ERROR_")) { Log.e(result); listener.onError(result); @@ -612,56 +290,23 @@ public class XmlRpcHelper { } listener.onRecoverPasswordLinkSent(result); - } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "send_reset_account_password_email", usernameOrEmail); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public String sendRecoverPasswordLinkByEmail(String usernameOrEmail) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("send_reset_account_password_email", usernameOrEmail); - String result = (String)object; - Log.d("sendRecoverPasswordLinkByEmail: " + result); - - if (result.startsWith("ERROR_")) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); - return null; + listener.onError(result); } - return result; - - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return null; + }); + xmlRpcRequest.addStringArg(usernameOrEmail); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void sendActivateAccountLinkByEmailAsync(final XmlRpcListener listener, String usernameOrEmail) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("sendActivateAccountLinkByEmailAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("resend_activation_email", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (result.startsWith("ERROR_")) { Log.e(result); listener.onError(result); @@ -669,56 +314,23 @@ public class XmlRpcHelper { } listener.onActivateAccountLinkSent(result); - } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "resend_activation_email", usernameOrEmail); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public String sendActivateAccountLinkByEmail(String usernameOrEmail) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("resend_activation_email", usernameOrEmail); - String result = (String)object; - Log.d("sendActivateAccountLinkByEmail: " + result); - - if (result.startsWith("ERROR_")) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); - return null; + listener.onError(result); } - return result; - - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return null; + }); + xmlRpcRequest.addStringArg(usernameOrEmail); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void sendUsernameByEmailAsync(final XmlRpcListener listener, String email) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("sendUsernameByEmailAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("recover_username_from_email", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (result.startsWith("ERROR_")) { Log.e(result); listener.onError(result); @@ -726,56 +338,23 @@ public class XmlRpcHelper { } listener.onUsernameSent(result); - } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "recover_username_from_email", email); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public String sendUsernameByEmail(String email) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("recover_username_from_email", email); - String result = (String)object; - Log.d("sendUsernameByEmail: " + result); - - if (result.startsWith("ERROR_")) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); - return null; + listener.onError(result); } - return result; - - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return null; + }); + xmlRpcRequest.addStringArg(email); + xmlRpcSession.sendRequest(xmlRpcRequest); } public void verifySignatureAsync(final XmlRpcListener listener, String payload, String signature) { - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("verifySignatureAsync: " + result); - + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("verify_payload_signature", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (result.startsWith("ERROR_")) { Log.e(result); listener.onError(result); @@ -783,56 +362,24 @@ public class XmlRpcHelper { } listener.onSignatureVerified("OK".equals(result)); - } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "verify_payload_signature", payload, signature); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } - } - - public boolean verifySignature(String payload, String signature) { - if (mXmlRpcClient != null) { - try { - Object object = mXmlRpcClient.call("verify_payload_signature", payload, signature); - String result = (String)object; - Log.d("verifySignature: " + result); - - if (result.startsWith("ERROR_")) { + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { Log.e(result); - return false; + listener.onError(result); } - return "OK".equals(result); - - } catch (XMLRPCException e) { - Log.e(e); } - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - } - return false; + }); + xmlRpcRequest.addStringArg(payload); + xmlRpcRequest.addStringArg(signature); + xmlRpcSession.sendRequest(xmlRpcRequest); } - public void getRemoteProvisioningFilenameAsync(final XmlRpcListener listener,String username, String domain, String password){ - if (mXmlRpcClient != null) { - mXmlRpcClient.callAsync(new XMLRPCCallback() { - @Override - public void onServerError(long id, XMLRPCServerException error) { - Log.e(error); - listener.onError(error.toString()); - } - - @Override - public void onResponse(long id, Object object) { - String result = (String)object; - Log.d("getRemoteProvisioningFilenameAsync: " + result); - + public void getRemoteProvisioningFilenameAsync(final XmlRpcListener listener,String username, String domain, String password) { + LinphoneXmlRpcRequest xmlRpcRequest = new LinphoneXmlRpcRequestImpl("get_remote_provisioning_filename", LinphoneXmlRpcRequest.ArgType.String); + xmlRpcRequest.setListener(new LinphoneXmlRpcRequestListener() { + @Override + public void onXmlRpcRequestResponse(LinphoneXmlRpcRequest request) { + String result = request.getStringResponse(); + if (request.getStatus() == LinphoneXmlRpcRequest.Status.Ok) { if (result.startsWith("ERROR_")) { Log.e(result); listener.onError(result); @@ -840,17 +387,15 @@ public class XmlRpcHelper { } listener.onRemoteProvisioningFilenameSent(result); + } else if (request.getStatus() == LinphoneXmlRpcRequest.Status.Failed) { + Log.e(result); + listener.onError(result); } - - @Override - public void onError(long id, XMLRPCException error) { - Log.e(error); - listener.onError(error.toString()); - } - }, "get_remote_provisioning_filename", username, domain, password); - } else { - Log.e(CLIENT_ERROR_INVALID_SERVER_URL); - listener.onError(CLIENT_ERROR_INVALID_SERVER_URL); - } + } + }); + xmlRpcRequest.addStringArg(username); + xmlRpcRequest.addStringArg(domain); + xmlRpcRequest.addStringArg(password); + xmlRpcSession.sendRequest(xmlRpcRequest); } } diff --git a/submodules/bctoolbox b/submodules/bctoolbox index cedccbe75..2b6e15cdd 160000 --- a/submodules/bctoolbox +++ b/submodules/bctoolbox @@ -1 +1 @@ -Subproject commit cedccbe75ca28f1a7f5ab953d652511b46804fa4 +Subproject commit 2b6e15cddcd3e4480161b3a5a3b3af77317cefd5 diff --git a/submodules/cmake-builder b/submodules/cmake-builder index fa1dbedef..d892c1c39 160000 --- a/submodules/cmake-builder +++ b/submodules/cmake-builder @@ -1 +1 @@ -Subproject commit fa1dbedef5e69cb304dbf77463b05376618795b4 +Subproject commit d892c1c397370d26e646a412d5df6bd5fb103a88 diff --git a/submodules/externals/axmlrpc b/submodules/externals/axmlrpc deleted file mode 160000 index c47eaa453..000000000 --- a/submodules/externals/axmlrpc +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c47eaa453fb75d55d32304413672c16706af85e0 diff --git a/submodules/linphone b/submodules/linphone index d0c6e9766..2974b7ef4 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit d0c6e9766c86fca904db40c17f78cf00eb0e8c0c +Subproject commit 2974b7ef419876105d6142750b4dbb40723e8a87