From ece73d2494776a88520e876d8eed9c2e98aad563 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Mon, 28 Jan 2013 20:03:32 -0700 Subject: Rebrand funcitions in jni/ --- jni/jbcrypto.cpp | 4 ++-- jni/jniglue.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jni/jbcrypto.cpp b/jni/jbcrypto.cpp index 8bc6fb8d..1c3e3ca9 100644 --- a/jni/jbcrypto.cpp +++ b/jni/jbcrypto.cpp @@ -17,7 +17,7 @@ extern "C" { -jbyteArray Java_de_blinkt_openvpn_OpenVpnManagementThread_rsasign(JNIEnv* env, jclass, jbyteArray from, jint pkeyRef); +jbyteArray Java_se_leap_openvpn_OpenVpnManagementThread_rsasign(JNIEnv* env, jclass, jbyteArray from, jint pkeyRef); } int jniThrowException(JNIEnv* env, const char* className, const char* msg) { @@ -41,7 +41,7 @@ int jniThrowException(JNIEnv* env, const char* className, const char* msg) { } -jbyteArray Java_de_blinkt_openvpn_OpenVpnManagementThread_rsasign(JNIEnv* env, jclass, jbyteArray from, jint pkeyRef) { +jbyteArray Java_se_leap_openvpn_OpenVpnManagementThread_rsasign(JNIEnv* env, jclass, jbyteArray from, jint pkeyRef) { // EVP_MD_CTX* ctx = reinterpret_cast(ctxRef); EVP_PKEY* pkey = reinterpret_cast(pkeyRef); diff --git a/jni/jniglue.c b/jni/jniglue.c index 82b54d16..143cd10b 100644 --- a/jni/jniglue.c +++ b/jni/jniglue.c @@ -16,7 +16,7 @@ void android_openvpn_log(int level,const char* prefix,const char* prefix_sep,con __android_log_print(ANDROID_LOG_DEBUG,"openvpn","%s%s%s",prefix,prefix_sep,m1); } -void Java_de_blinkt_openvpn_OpenVpnManagementThread_jniclose(JNIEnv *env,jclass jo, jint fd) { +void Java_se_leap_openvpn_OpenVpnManagementThread_jniclose(JNIEnv *env,jclass jo, jint fd) { int ret = close(fd); } -- cgit v1.2.3 From 2226626398dbf2b6f21eacaa6b3c27b4ddf85850 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Tue, 29 Jan 2013 20:18:41 -0700 Subject: LEAP icons! Yay! Addresses #1527 #1580 --- res/drawable-hdpi/icon.png | Bin 2624 -> 4254 bytes res/drawable-ldpi/icon.png | Bin 0 -> 1517 bytes res/drawable-mdpi/icon.png | Bin 3442 -> 2320 bytes res/drawable-xhdpi/icon.png | Bin 2994 -> 6320 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 res/drawable-ldpi/icon.png diff --git a/res/drawable-hdpi/icon.png b/res/drawable-hdpi/icon.png index b7a83e9a..a07db1ef 100644 Binary files a/res/drawable-hdpi/icon.png and b/res/drawable-hdpi/icon.png differ diff --git a/res/drawable-ldpi/icon.png b/res/drawable-ldpi/icon.png new file mode 100644 index 00000000..6f25cd07 Binary files /dev/null and b/res/drawable-ldpi/icon.png differ diff --git a/res/drawable-mdpi/icon.png b/res/drawable-mdpi/icon.png index 9748722f..4b3456ff 100644 Binary files a/res/drawable-mdpi/icon.png and b/res/drawable-mdpi/icon.png differ diff --git a/res/drawable-xhdpi/icon.png b/res/drawable-xhdpi/icon.png index 622315b6..dbb53eef 100644 Binary files a/res/drawable-xhdpi/icon.png and b/res/drawable-xhdpi/icon.png differ -- cgit v1.2.3 From 6b5f766c9a1643c3c87bd396d1a23e49144ca813 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Tue, 29 Jan 2013 20:22:50 -0700 Subject: Many strings... Resolves #1527 #1580 but opened #1582 #1583 --- res/values-ca/strings.xml | 6 +++--- res/values-cs/strings.xml | 10 +++++----- res/values-de/strings.xml | 10 +++++----- res/values-es/strings.xml | 10 +++++----- res/values-et/strings.xml | 10 +++++----- res/values-fr/strings.xml | 10 +++++----- res/values-id/strings.xml | 8 ++++---- res/values-it/strings.xml | 10 +++++----- res/values-ja/strings.xml | 10 +++++----- res/values-ko/strings.xml | 10 +++++----- res/values-nl/strings.xml | 4 ++-- res/values-no/strings.xml | 8 ++++---- res/values-ro/strings.xml | 8 ++++---- res/values-ru/strings.xml | 10 +++++----- res/values-uk/strings.xml | 10 +++++----- res/values-zh-rCN/strings.xml | 10 +++++----- res/values-zh-rTW/strings.xml | 10 +++++----- res/values/strings.xml | 15 +++++++++------ 18 files changed, 86 insertions(+), 83 deletions(-) diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index b9f2f07c..5131250a 100755 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -1,7 +1,7 @@ - OpenVPN per Android + LEAP per Android Adreá del servidor: Port del servidor: Lloc @@ -15,7 +15,7 @@ Fitxer PKCS12 Certificat CA Quan a - Quan a OpenVPN per Android + Quan a LEAP per Android Llista de VPNs configurades Perfils VPN Tipus @@ -64,7 +64,7 @@ Rutes IPv6: %s Envia el fitxer de registre Envia - Fitxer de registre de ICS OpenVPN + Fitxer de registre de LEAP Android S\'ha copiat l\'entrada al porta-retalls Mode Tap No es pot utiltizar el mode tap amb la api no rootejada. L\'aplicació no suporta tap diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 5a1039bc..6d2c6a5a 100755 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -1,7 +1,7 @@ - OpenVPN pro Android + LEAP pro Android Adresa serveru: Port serveru: Lokace @@ -16,10 +16,10 @@ PKCS12 soubor CA certifikát Je třeba vybrat certifikát - Zdrojové kódy a seznam problémů je na http://code.google.com/p/ics-openvpn/ + Zdrojové kódy a seznam problémů je na https://github.com/leapcode/leap_android/ Tento program používá následující komponenty; viz zdrojový kód pro detaily o licenci O programu - O programu OpenVPN pro Android + O programu LEAP pro Android Seznam všech nakonfigurovaných VPN Všechny VPN Typ @@ -110,7 +110,7 @@ %1$s %2$s Odeslat soubor s logem Odeslat - ICS OpenVPN logovací soubor + LEAP Android logovací soubor Záznam z logu zkopírován do schránky Tap mód Tap mód není možný bez rootovského VPN API, proto tato aplikace nemá podporu pro tap @@ -202,7 +202,7 @@ Používám proxy %1$s %2$d Použít systémovou proxy K připojení použít systémové nastavení pro HTTP/HTTPS. - K přispění můžeš využít <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">PayPal</a> + OpenVPN se opětovně připojí k VPN, pokud byla aktivní před vypnutím/restartem systému. Přečti si oddíl o varování před připojením než použiješ tuto možnost. Znovu připoj po restartu Ignorovat diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 4f8d8ca8..f079ba53 100755 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -1,7 +1,7 @@ - OpenVPN für Android + LEAP für Android Server: Server Port: Ort @@ -16,10 +16,10 @@ PKCS12 Datei CA Zertifikat Kein Zertifikat ausgewählt - Quellcode und Issue Tracker sind verfügbar unter http://code.google.com/p/ics-openvpn/ + Quellcode und Issue Tracker sind verfügbar unter https://github.com/leapcode/leap_android/ Dieses Programm nutzt die folgenden Komponenten. Die kompletten Lizenzdetails sind im Quelltext verfügbar. Über - Über OpenVPN für Android + Über LEAP für Android Alle konfigurierten VPN Profile VPN Liste Typ @@ -110,7 +110,7 @@ %1$s %2$s Sende Logdatei Sende - ICS OpenVPN log Datei + LEAP Android log Datei Log Eintrag in die Zwischenablage kopiert Tap Mode Die VPN API von Android, die ohne rooten des Telefons funktioniert, unterstützt nur den tun Modus. Das Unterstützen des Tap Modus ist daher nicht möglich. @@ -202,7 +202,7 @@ Benutzt Proxy %1$s %2$d Benutze System Proxys Benutze die System weiten Einstellungen für HTTP/HTTPS Proxys beim Verbinden. - <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">Spenden mit PayPal</a> + OpenVPN wird bei einem Neustart des Telefon das beim herunterfahren/neu starten aktive VPN wieder verbinden. Bitte lesen Sie die FAQ \"Warnung beim Verbinden\" FAQ bevor Sie diese Option verwenden. Nach Neustart verbinden Ignorieren diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 521985db..e1979c05 100755 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -1,7 +1,7 @@ - OpenVPN para Android + LEAP para Android Dirección del servidor: Puerto del servidor: Ubicación @@ -16,10 +16,10 @@ Archivo PKCS12 Certificado de la CA Debe seleccionar un certificado - Codigo fuente y sistema de reporte de errores disponibles en http://code.google.com/p/ics-openvpn/ + Codigo fuente y sistema de reporte de errores disponibles en https://github.com/leapcode/leap_android/ El programa utiliza los siguientes componentes. Vea los códigos fuentes para obtener más información sobre las licencias Acerca de - Acerca de OpenVPN para Android + Acerca de LEAP para Android Lista de todas las VPN configuradas Perfiles VPN Tipo @@ -110,7 +110,7 @@ %1$s %2$s Enviar el archivo de registro Enviar - Archivo de registro de OpenVPN de ICS + Archivo de registro de LEAP de Android Entrada de registro copiada al Portapapeles Modo Tap El Modo tap no es posible sin la API VPN de root. Por lo tanto la aplicacion no puede dar soporte a tap @@ -199,7 +199,7 @@ Usando proxy %1$s %2$d Usar el proxy del sistema Utilice la configuración del sistema para los proxies HTTP/HTTPS a conectar. - Usted puede <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">donar con PayPal</a> + OpenVPN volvera a conectar a una VPN si estaba activa en el apagado/reinicio del sistema. Por favor lea la P+F de advertencia de conexión antes de usar esta opción. Vuelva a conectar al reiniciar Ignorar diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index 9a4c6717..4e13e539 100755 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -1,7 +1,7 @@ - OpenVPN Androidile + LEAP Androidile Serveri aadress: Serveri port: Asukoht @@ -16,10 +16,10 @@ PKCS12 fail CA sertifikaat Peate valima sertifikaadi - Lähtetekst ja probleemihaldur asuvad veebilehel http://code.google.com/p/ics-openvpn/ + Lähtetekst ja probleemihaldur asuvad veebilehel https://github.com/leapcode/leap_android/ Programmis kasutatakse järgnevaid komponente. Detailse litsenseerimisinfo leiate lähtekoodist Lähemalt - Täpsemalt programmist OpenVPN Androidile + Täpsemalt programmist LEAP Androidile Kõigi seadistatud VPN kanalite nimekiri VPN profiilid Tüüp @@ -110,7 +110,7 @@ %1$s %2$s Saada logifail Saada - ICS OpenVPN logifail + LEAP Androidile logifail Logikirje kopeeriti lõikepuhvrisse Tap liides VPNService API ei toeta tap liidest. Seega ei ole ruutimata seadmel selle programmiga tap liidese kasutamine võimalik @@ -202,7 +202,7 @@ Kasutusel proxy %1$s %2$d Kasuta süsteemset proxy\'t Kasuta ühendumisel süsteemse HTTP/HTTPS proxy konfiguratsiooni. - Sul on võimalus <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">annetada PayPal vahendusel</a> + Kui VPN oli süsteemi uuestilaadimisel/sulgemisel aktiivne siis taastatakse seadme käivitamisel OpenVPN ühendus. Palun lugege enne selle valiku kasutamist läbi ühendumise hoiatuse KKK. Uuestilaadimisel ühendu uuesti Ignoreeri diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 9da62050..f031c5fd 100755 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -1,7 +1,7 @@ - "OpenVPN pour Android" + "LEAP pour Android" "Adresse du serveur:" "Port:" "Emplacement" @@ -16,10 +16,10 @@ "Fichier PKCS12" "Certificat CA" "Vous devez sélectionner un certificat" - "Le code source et le tracker de bugs est disponible ici: http://code.google.com/p/ics-openvpn/ " + "Le code source et le tracker de bugs est disponible ici: https://github.com/leapcode/leap_android/ " "Le programme utilise les composants suivants. Voir le code source pour plus de détails sur les licences." "À propos" - "À propos d\'OpenVPN pour Android" + "À propos d\'LEAP pour Android" "Liste de tous les VPN configurés" "Vos VPNs" "Type" @@ -109,7 +109,7 @@ "%1$s %2$s" "Envoyer le fichier de log" "Envoyer" - "Fichier de log OpenVPN ICS" + "Fichier de log LEAP Android" "Entrée du log copiée" "Mode TAP" "Le mode TAP est indisponible avec l\'API non root VPN. Par conséquent, cette application ne peut pas supporter TAP" @@ -202,7 +202,7 @@ Sur certaines images, cette notification joue un son.\nAndroid à introduit ces "Utilisation du proxy %1$s %2$d" "Utiliser le proxy système" "Utiliser la configuration générale du système pour que les proxy HTTP / HTTPS se connectent." - "Vous pouvez faire un <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&cmd=_s-xclick\">don avec PayPal</ a> " + "Reconnecter OpenVPN automatiquement si une connexion était active lors de l\'extinction/redémarrage de l\'appareil. Veuillez lire l\'avertissement de connexion dans la FAQ avant d\'utiliser cette option." "Connexion automatique au redémarrage" "Ignorer" diff --git a/res/values-id/strings.xml b/res/values-id/strings.xml index 857cde22..fbf2231e 100755 --- a/res/values-id/strings.xml +++ b/res/values-id/strings.xml @@ -1,7 +1,7 @@ - OpenVPN untuk Android + LEAP untuk Android Alamat Server: Port server: Lokasi @@ -19,7 +19,7 @@ Kode program dan perekam masalah tersedia di Aplikasi memakai komponen berikut; lihat kode program untuk lebih jelas mengenai lisensi Tentang... - Tentang OpenVPN untuk Android + Tentang LEAP untuk Android Daftar konfigurasi VPN Profil VPN Tipe @@ -110,7 +110,7 @@ %1$s %2$s Kirim berkas catatan Kirim - Berkas catatan ICS OpenVPN + Berkas catatan LEAP Android Salin catatan masuk ke clipboard Mode TAP Mode TAP tidak diijinkan tanpa VPN API non admin/root. Karena itu aplikasi ini tidak dapat memberikan dukungan mode TAP @@ -202,7 +202,7 @@ Menggunakan proxy %1$ s %2$ d Gunakan sistem proxy Gunakan konfigurasi lebih luas untuk menyambung system melalui proxy HTTP/HTTPS - Anda dapat melakukan donasi <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">dengan PayPal</a> + OpenVPN akan menyambung kembali VPN jika VPN aktif pada saat sistem reboot/shutdown. Silakan baca FAQ tentang peringatan sambungan sebelum menggunakan pilihan ini. Koneksi ulang saat perangkat dihidupkan kembali Abaikan diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index a8f39816..84072b1e 100755 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -1,7 +1,7 @@ - OpenVPN per Android + LEAP per Android Indirizzo server: Porta del server: Posizione @@ -16,10 +16,10 @@ File PKCS12 Certificato CA Devi selezionare un certificato - Il codice sorgente e il bug tracker sono disponibili all\'indirizzo http://code.google.com/p/ics-openvpn/ + Il codice sorgente e il bug tracker sono disponibili all\'indirizzo https://github.com/leapcode/leap_android/ Questo programma usa i seguenti componenti; guarda il codice sorgente per i dettagli completi sulle licenze Informazioni - Informazioni su OpenVPN per Android + Informazioni su LEAP per Android Elenco connessioni VPN configurate Profili VPN Tipo @@ -110,7 +110,7 @@ %1$s %2$s Invia il file di log Invia - File log di OpenVPN ICS + File log di LEAP Android Voce di registro copiata negli appunti Modalità TAP La modalità TAP non è disponibile con le VPN API non root @@ -205,7 +205,7 @@ nel bug tracker).</p><p>Si è visto che ai firmware ufficiali della Si sta utilizzando il proxy %1$s %2$d Utilizza il proxy di sistema Utilizza la configurazione generale del sistema relativa ai proxy HTTP/HTTPS per connettersi. - Puoi <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">donare tramite PayPal</a> + OpenVPN is riconnetterà alla VPN se era in funzione durante un riavvio od un spegnimento dell\'apparecchio. Leggi con attenzione le FAQ con gli avvertimenti sulla connessione prima di scegliere questa opzione. Riconnetti al riavvio Ignora diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index aec401af..170b6c25 100755 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -1,7 +1,7 @@ - OpenVPN for Android + LEAP Android サーバアドレス ポート番号 場所 @@ -16,10 +16,10 @@ PKCS12ファイル CA 証明書 証明書を選択する必要があります。 - ソースコードと問題管理は以下で: http://code.google.com/p/ics-openvpn/ + ソースコードと問題管理は以下で: https://github.com/leapcode/leap_android/ プログラムは、次のコンポーネントを使用します。完全な詳細についてはソース上のライセンスを参照してください。 バージョン情報 - OpenVPN for Androidについて + LEAP Androidについて 設定されたすべてのVPN VPNプロファイル 種別 @@ -111,7 +111,7 @@ %1$s %2$s ログ ファイルを送信します。 送信 - ICS OpenVPN ログ ファイル + LEAP Android ログ ファイル クリップ ボードにコピーされたログ エントリ TAPモード TAPモードは非root化環境では動作しません。よってこのアプリケーションではTAPをサポートできません。 @@ -222,7 +222,7 @@ Androidはあなた自身の安全性のために、これらを迂回できな プロキシを使用します %1$s %2$d システムのプロキシ設定を使用 システム全体の構成の HTTP/HTTPS プロキシ接続を使用します。 - 以下のURLより寄付いただけます。 <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">PayPalで寄付</a> + OpenVPNはシステムの再起動やシャットダウン時に再接続するようになります。このオプションを使用する前にFAQをご一読ください。 システム起動後に再接続 無視 diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index dd83c09d..fbf069d3 100755 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -1,7 +1,7 @@ - 안드로이드용 OpenVPN + 안드로이드용 LEAP 서버 주소: 서버 포트: 위치 @@ -16,10 +16,10 @@ PKCS12 파일 CA 인증서 인증서를 선택 해야 합니다 - 소스 코드와 문제 추적기는 http://code.google.com/p/ics-openvpn/에서 사용할 수 있습니다 + 소스 코드와 문제 추적기는 https://github.com/leapcode/leap_android/에서 사용할 수 있습니다 프로그램은 다음 구성 요소를 사용합니다. 라이선스에 대 한 자세한 내용은 소스를 참조 하십시오 소개 - 안드로이드용 OpenVPN 소개 + 안드로이드용 LEAP 소개 설정된 VPN의 목록 VPN 프로파일 유형 @@ -110,7 +110,7 @@ %1$s %2$s 로그 파일 보내기 보내기 - ICS OpenVPN 로그 파일 + LEAP 로그 파일 클립보드로 로그 복사 Tap 모드 Tap 모드는 루트가 아닌 VPN API에서는 불가능합니다. 따라서 본앱은 tap지원을 제공할 수 없습니다 @@ -202,7 +202,7 @@ 프록시 %1$s %2$d 을 사용 시스템 프록시를 사용 연결시 전 시스템 설정에 있는 HTTP/HTTPS 프록시를 사용합니다. - 당신은 <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">PayPal을 사용하여 기부할 수 있습니다.</a> + OpenVPN은 시스템 재부팅/종료에 활성화 되었으면 VPN을 다시 연결합니다. 이 옵션을 사용 하기 전에 연결 경고 FAQ를 읽어 보시기 바랍니다. 재부팅시 다시 연결 무시 diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 5403ae06..459c80ec 100755 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -1,7 +1,7 @@ - OpenVPN voor Android + LEAP voor Android Server Adres: Server Poort: Locatie @@ -15,7 +15,7 @@ PKCS12 Bestand CA Certificaat Over - Over OpenVPN voor Android + Over LEAP voor Android Lijst van alle geconfigureerde VPN verbindingen VPN Profielen Type diff --git a/res/values-no/strings.xml b/res/values-no/strings.xml index 1ee26c0d..99b97277 100755 --- a/res/values-no/strings.xml +++ b/res/values-no/strings.xml @@ -1,7 +1,7 @@ - OpenVPN for Android + LEAP Android Server adresse: Server port: Plassering @@ -15,7 +15,7 @@ PKCS12 fil CA-sertifikat Om - Om OpenVPN for Android + Om LEAP Android Liste over alle konfigurerte VPN-tilkoblinger VPN-profiler Type @@ -63,7 +63,7 @@ %1$s %2$s Send loggfilen Send - ICS OpenVPN loggfil + LEAP Android loggfil Tap modus FAQ Vanlige spørsmål og noen råd @@ -124,7 +124,7 @@ Bruker proxy %1$s %2$d Bruk systemet proxy Bruk global systemkonfigurasjon for HTTP/HTTPS proxy for å koble til. - Du kan <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">donere med PayPal</a> + Koble til på nytt ved restart Ignorer Start på nytt diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 842d9352..43d6c17f 100755 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -1,7 +1,7 @@ - OpenVPN pentru Android + LEAP pentru Android Adresa server: Port server: Locaţie @@ -16,10 +16,10 @@ Fişier PKCS12 Certificat CA Trebuie să selectați un certificat - Cod sursă şi tracker probleme disponibile la http://code.google.com/p/ics-openvpn/ + Cod sursă şi tracker probleme disponibile la https://github.com/leapcode/leap_android/ Acest program utilizează următoarele componente; a se vedea codul sursă pentru mai multe detalii despre licente Despre - Despre OpenVPN pentru Android + Despre LEAP pentru Android Lista tuturor VPN-urilor configurate Profile VPN Tip @@ -107,7 +107,7 @@ %1$s %2$s Trimite fişier jurnal Trimite - Fişier jurnal OpenVPN ICS + Fişier jurnal LEAP Android Mod Tap FAQ Copiere linii jurnal diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index a4a9feed..ee1fed82 100755 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -1,7 +1,7 @@ - OpenVPN для Android + LEAP для Android Адрес сервера: Порт сервера: Расположение @@ -16,10 +16,10 @@ PKCS12 файл CA сертификат Вам необходимо выбрать сертификат - Исходники и информация о версиях находятся по адресу http://code.google.com/p/ics-openvpn/ + Исходники и информация о версиях находятся по адресу https://github.com/leapcode/leap_android/ Данная программа использует следующие компоненты; смотрите исходный код для получения подробной информации о лицензии О программе - Описание OpenVPN для Android + Описание LEAP для Android Список всех туннелей VPN Профили VPN Тип @@ -110,7 +110,7 @@ %1$s %2$s Отправить файл журнала Отправить - ICS OpenVPN файла лога + LEAP Android файла лога Скопировать лог в буфер обмена Режим TAP Режим TAP невозможен на устройствах без root-а. Поэтому это приложение не поддерживает TAP @@ -202,7 +202,7 @@ Используется прокси-сервер %1$s %2$d Использовать прокси-сервер системы Использовать системную конфигурацию прокси HTTP/HTTPS для соединения. - Вы можете <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">пожертвовать с PayPal</a> + OpenVPN будет переподключаться, если он был активен в момент выключения/перезагрузки. Пожалуйста, прочтите FAQ перед тем, как использовать эту настройку. Переподключение после перезагрузки Игнорировать diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 54f48fa4..20cd0d6a 100755 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -1,7 +1,7 @@ - OpenVPN для Android + LEAP для Android Адреса сервера: Порт сервера: Розташування @@ -16,10 +16,10 @@ Файл PKCS12 Сертифікат CA Потрібно вибрати сертифікат - Початковий код і відстеження проблем доступні по http://code.google.com/p/ics-openvpn/ + Початковий код і відстеження проблем доступні по https://github.com/leapcode/leap_android/ Ця програма використовує такі компоненти; перегляньте вихідний код для повної інформації про ліцензії Про - Про OpenVPN для Android + Про LEAP для Android Список всіх налаштованих VPN VPN профілі Тип @@ -110,7 +110,7 @@ %1$s %2$s Надіслати файл журналу Надіслати - ICS OpenVPN файл журналу + LEAP Android файл журналу Скопійовано запис журналу до буферу обміну TAP режим TAP режим не можливий в VPN API без рут. З цієї причини цей додаток не може надати підтримку TAP @@ -202,7 +202,7 @@ Використовується проксі %1$s %2$d Використовувати системний проксі Використовувати системну конфігурацію HTTP/HTTPS проксі для з\'єднання. - Ви можете <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">пожертвувати через PayPal</a> + OpenVPN буде перепідключатися, якщо він був активний в момент вимикання/перезавантаження. Будь ласка, прочитайте ЧаП перед тим, як використовувати цей параметр. Перепідключати при перезавантаженні Ігнорувати diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 74a672ad..0d6f4d2c 100755 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -1,7 +1,7 @@ - OpenVPN Android版 + LEAP Android版 服务器地址: 服务器端口: 地点 @@ -16,10 +16,10 @@ PKCS12 文件 CA 证书 您必须选择一个证书 - 请前往 http://code.google.com/p/ics-openvpn/ 源码或提供问题反馈 + 请前往 https://github.com/leapcode/leap_android/ 源码或提供问题反馈 本程序使用以下组件,请在 Licenses 查看源码获取更详细内容。 关于 - 关于 OpenVPN for Android + 关于 LEAP Android 已完成配置的 VPN 列表 VPN 配置文件 类型 @@ -98,7 +98,7 @@ %1$s %2$s 发送日志文件 发送 - ICS OpenVPN 日志文件 + LEAP Android 日志文件 日志条目已复制剪贴板 Tap 模式 常见问题 @@ -168,7 +168,7 @@ 获取代理设置时出错:%s 使用代理 %1$s %2$d 使用系统代理 - 您可以 < href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS & amp; cmd = _s xclick\"> 通过 PayPal 捐助</a> + 重启时重新连接 忽略 重启 diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 23e9c002..76404d12 100755 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -1,7 +1,7 @@ - OpenVPN for Android + LEAP Android 伺服器地址: 伺服器端口: 位置 @@ -16,10 +16,10 @@ PKCS12 檔案 CA證書 您必須選擇一個憑證 - 取得原始碼與個案追蹤,可上 http://code.google.com/p/ics-openvpn/ + 取得原始碼與個案追蹤,可上 https://github.com/leapcode/leap_android/ 本程序使用了以下元件,其作者和授權資訊如下 關於 - 關於 OpenVPN for Android + 關於 LEAP Android 列出所有已設置的VPN VPN設定檔 類型 @@ -99,7 +99,7 @@ %1$s %2$s 分享記錄檔 分享 - ICS OpenVPN 記錄檔 + LEAP Android 記錄檔 已將記錄複製到剪貼簿 Tap模式 Android內置的VPN API並不支援Tap介面,故此本程序並不支援Tap模式。 @@ -167,7 +167,7 @@ 使用代理伺服器 %1$s %2$d 使用系統代理 使用系統配置的 HTTP/HTTPS 代理伺服器進行連接。 - 你可以透過 <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">PayPal</a> 提供捐助 + 如果在重新開機或關機前正連接VPN,開機時自動重新連接。在使用這個選項之前請先閱讀連線警告FAQ。 開機時重新連接 忽略 diff --git a/res/values/strings.xml b/res/values/strings.xml index a101d024..4b029b22 100755 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2,7 +2,7 @@ - OpenVPN for Android + LEAP for Android Server Address: Server Port: Location @@ -17,10 +17,10 @@ PKCS12 File CA Certificate You must select a certificate - Source code and issue tracker available at http://code.google.com/p/ics-openvpn/ + Source code and issue tracker available at https://github.com/leapcode/leap_android/ This program uses the following components; see the source code for full details on the licenses About - About OpenVPN for Android + About LEAP for Android List of all configured VPNs VPN Profiles Type @@ -111,7 +111,7 @@ %1$s %2$s Send log file Send - ICS OpenVPN log file + LEAP OpenVPN log file Copied log entry to clip board Tap Mode Tap Mode is not possible with the non root VPN API. Therefore this application cannot provide tap support @@ -203,7 +203,7 @@ Using proxy %1$s %2$d Use system proxy Use the system wide configuration for HTTP/HTTPS proxies to connect. - You can <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">donate with PayPal</a> + OpenVPN will reconnect a VPN if it was active on system reboot/shutdown. Please read the Connection warning FAQ before using this option. Reconnect on reboot Ignore @@ -253,5 +253,8 @@ Connecting (TCP) Authentication failed Waiting for usable network + Hello world! + Settings + LEAP Dashboard - + \ No newline at end of file -- cgit v1.2.3 From 77c76fc1c856f73e1b6d072dbe27242fd707b586 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Wed, 30 Jan 2013 22:22:49 -0700 Subject: Empty Provider.java file --- src/se/leap/leapclient/Provider.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/se/leap/leapclient/Provider.java diff --git a/src/se/leap/leapclient/Provider.java b/src/se/leap/leapclient/Provider.java new file mode 100644 index 00000000..e69de29b -- cgit v1.2.3 From 026ba24b0b3e3c47ce31cad4822e0c4beae1cd5e Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Wed, 30 Jan 2013 22:27:26 -0700 Subject: Provider class filled up quick ;) Resolves #1520 --- src/se/leap/leapclient/Provider.java | 162 +++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) diff --git a/src/se/leap/leapclient/Provider.java b/src/se/leap/leapclient/Provider.java index e69de29b..a25909bf 100644 --- a/src/se/leap/leapclient/Provider.java +++ b/src/se/leap/leapclient/Provider.java @@ -0,0 +1,162 @@ +/** + * + */ +package se.leap.leapclient; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Locale; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import android.content.SharedPreferences; + +/** + * @author Sean Leonard + * + */ +final class Provider implements Serializable { + + private static final long serialVersionUID = 6003835972151761353L; + + private static Provider instance = null; + + // We'll access our preferences here + private static SharedPreferences preferences = null; + // Represents our Provider's provider.json + private static JSONObject definition = null; + + + // Array of what API versions we understand + protected static final String[] API_VERSIONS = {"1"}; // I assume we might encounter arbitrary version "numbers" + // Some API pieces we want to know about + private static final String API_TERM_SERVICES = "services"; + private static final String API_TERM_NAME = "name"; + private static final String API_TERM_DEFAULT_LANGUAGE = "default_language"; + protected static final String[] API_EIP_TYPES = {"openvpn"}; + + private static final String PREFS_EIP_NAME = null; + + + + // What, no individual fields?! We're going to gamble on org.json.JSONObject and JSONArray + // Supporting multiple API versions will probably break this paradigm, + // Forcing me to write a real constructor and rewrite getters/setters + // Also will refactor if i'm instantiating the same local variables all the time + + /** + * + */ + private Provider(SharedPreferences preferences) { + + // Load our preferences from SharedPreferences + // If there's nothing there, we will end up returning a rather empty object + // to whoever called getInstance() and they can run the First Run Wizard + //preferences = context.getgetPreferences(0); // 0 == MODE_PRIVATE, but we don't extend Android's classes... + + // Inflate our provider.json data + try { + definition = new JSONObject( preferences.getString("provider", "") ); + } catch (JSONException e) { + // TODO: handle exception + + // FIXME!! We want "real" data!! + } + } + + protected static Provider getInstance(SharedPreferences preferences){ + if(instance==null){ + instance = new Provider(preferences); + } + return instance; + } + + protected String getName(){ + // Should we pass the locale in, or query the system here? + String lang = Locale.getDefault().getLanguage(); + String name = "Null"; // Should it actually /be/ null, for error conditions? + try { + name = definition.getJSONObject(API_TERM_NAME).getString(lang); + } catch (JSONException e) { + // TODO: Nesting try/catch blocks? Crazy + // Maybe you should actually handle exception? + try { + name = definition.getJSONObject(API_TERM_NAME).getString( definition.getString(API_TERM_DEFAULT_LANGUAGE) ); + } catch (JSONException e2) { + // TODO: Will you handle the exception already? + } + } + + return name; + } + + protected String getDescription(){ + String lang = Locale.getDefault().getLanguage(); + String desc = null; + try { + desc = definition.getJSONObject("description").getString(lang); + } catch (JSONException e) { + // TODO: handle exception!! + try { + desc = definition.getJSONObject("description").getString( definition.getString("default_language") ); + } catch (JSONException e2) { + // TODO: i can't believe you're doing it again! + } + } + + return desc; + } + + public boolean hasEIP() { + JSONArray services = null; + try { + services = definition.getJSONArray(API_TERM_SERVICES); // returns ["openvpn"] + } catch (Exception e) { + // TODO: handle exception + } + for (int i=0;i Date: Wed, 30 Jan 2013 22:34:29 -0700 Subject: Goodbye, hello_world --- res/values/strings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 4b029b22..87b395cb 100755 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -253,7 +253,6 @@ Connecting (TCP) Authentication failed Waiting for usable network - Hello world! Settings LEAP Dashboard -- cgit v1.2.3 From dc10be031f58a334dbf67c8a904d03e302304d42 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Wed, 30 Jan 2013 22:39:33 -0700 Subject: Empty Dashboard.java --- src/se/leap/leapclient/Dashboard.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/se/leap/leapclient/Dashboard.java diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java new file mode 100644 index 00000000..e69de29b -- cgit v1.2.3 From c849913fba3f5b692309570415f85e9bdb8cceeb Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Wed, 30 Jan 2013 22:54:56 -0700 Subject: Beginnings of a Dashboard Activity Matching layout and menu XML And don't forget strings --- res/layout/client_dashboard.xml | 56 +++++++++++++++++++++++++++ res/menu/client_dashboard.xml | 10 +++++ res/values/strings.xml | 2 + src/se/leap/leapclient/Dashboard.java | 71 +++++++++++++++++++++++++++++++++++ 4 files changed, 139 insertions(+) create mode 100644 res/layout/client_dashboard.xml create mode 100644 res/menu/client_dashboard.xml diff --git a/res/layout/client_dashboard.xml b/res/layout/client_dashboard.xml new file mode 100644 index 00000000..599a0972 --- /dev/null +++ b/res/layout/client_dashboard.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/menu/client_dashboard.xml b/res/menu/client_dashboard.xml new file mode 100644 index 00000000..cafeb15e --- /dev/null +++ b/res/menu/client_dashboard.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 87b395cb..606cb3bb 100755 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -255,5 +255,7 @@ Waiting for usable network Settings LEAP Dashboard + Provider: + No provider configured \ No newline at end of file diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index e69de29b..50c267b3 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -0,0 +1,71 @@ +package se.leap.leapclient; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +import se.leap.openvpn.AboutFragment; +import se.leap.openvpn.MainActivity; +import android.app.Activity; +import android.app.Fragment; +import android.app.FragmentTransaction; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.AssetManager; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewStub; +import android.widget.CompoundButton; +import android.widget.Switch; +import android.widget.TextView; + +public class Dashboard extends Activity { + + private static SharedPreferences preferences; + private static Provider provider; + + private TextView providerNameTV; + private TextView eipTypeTV; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.client_dashboard); + + preferences = getPreferences(MODE_PRIVATE); + + // Get our provider + provider = Provider.getInstance(preferences); + + // Set provider name in textview + providerNameTV = (TextView) findViewById(R.id.providerName); + providerNameTV.setText(provider.getName()); + providerNameTV.setTextSize(28); // TODO maybe to some calculating, or a marquee? + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.client_dashboard, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item){ + Intent intent; + // Handle item selection + switch (item.getItemId()){ + case R.id.legacy_interface: + // TODO call se.leap.openvpn.MainActivity + intent = new Intent(this,MainActivity.class); + startActivity(intent); + return true; + default: + return super.onOptionsItemSelected(item); + } + + } + +} -- cgit v1.2.3 From 12de321bdd1e6b19dba35b03771f550ce2ddd31c Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Wed, 30 Jan 2013 22:56:59 -0700 Subject: Switch the Launcher Activity, resolves #1526 --- AndroidManifest.xml | 18 +++++++++++------- README.txt | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b4df9219..7162576a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -53,12 +53,6 @@ - - - - - - + + + + + + + + - + \ No newline at end of file diff --git a/README.txt b/README.txt index 17b9f50a..f6690f5a 100644 --- a/README.txt +++ b/README.txt @@ -39,5 +39,5 @@ public class StartOpenVPNActivity extends Activity { or from the shell: -am start -a android.intent.action.MAIN -n se.leap.openvpn/.LaunchVPN -e se.leap.openvpn.shortcutProfileName Home +am start -a android.intent.action.VPNLEGACY -n se.leap.openvpn/.LaunchVPN -e se.leap.openvpn.shortcutProfileName Home -- cgit v1.2.3 From 4bcb53cff01cb13530e1011fb6d5ac105be1ba25 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Wed, 30 Jan 2013 23:10:26 -0700 Subject: Put some About love in the menu Needs attention, as the AboutFragment does not fill the layout You can still see providerLine Creates Issue #1592 --- res/menu/client_dashboard.xml | 1 + src/se/leap/leapclient/Dashboard.java | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/res/menu/client_dashboard.xml b/res/menu/client_dashboard.xml index cafeb15e..87e7ae62 100644 --- a/res/menu/client_dashboard.xml +++ b/res/menu/client_dashboard.xml @@ -5,6 +5,7 @@ android:orderInCategory="100" android:showAsAction="never" android:title="@string/menu_settings"/> + \ No newline at end of file diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index 50c267b3..3e8f35a4 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -57,6 +57,17 @@ public class Dashboard extends Activity { Intent intent; // Handle item selection switch (item.getItemId()){ + case R.id.about_leap: + // TODO move se.leap.openvpn.AboutFragment into our package + Fragment aboutFragment = new AboutFragment(); + FragmentTransaction trans = getFragmentManager().beginTransaction(); + trans.replace(R.id.dashboardLayout, aboutFragment); + trans.addToBackStack(null); + trans.commit(); + + //intent = new Intent(this,AboutFragment.class); + //startActivity(intent); + return true; case R.id.legacy_interface: // TODO call se.leap.openvpn.MainActivity intent = new Intent(this,MainActivity.class); -- cgit v1.2.3 From fea68f17a1a69bc3710e1b1b743e0d0ded95234a Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Wed, 30 Jan 2013 23:23:13 -0700 Subject: FIXME!! Here there be dragons. Of the "fake data seeded by seedy functions" variety, And there shady json files...Creates Issue #1593 --- assets/providers/bitmask.net_eip-service.json | 42 ++++++++++++++++++++++ assets/providers/bitmask.net_provider.json | 25 +++++++++++++ src/se/leap/leapclient/Dashboard.java | 51 +++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 assets/providers/bitmask.net_eip-service.json create mode 100644 assets/providers/bitmask.net_provider.json diff --git a/assets/providers/bitmask.net_eip-service.json b/assets/providers/bitmask.net_eip-service.json new file mode 100644 index 00000000..6ac2fed6 --- /dev/null +++ b/assets/providers/bitmask.net_eip-service.json @@ -0,0 +1,42 @@ +{ + "clusters": [ + { + "label": { + "en": "Location Unknown" + }, + "name": "location_unknown" + } + ], + "gateways": [ + { + "capabilities": { + "adblock": false, + "filter_dns": true, + "ports": [ + "1194", + "443", + "53", + "80" + ], + "protocols": [ + "tcp", + "udp" + ], + "transport": [ + "openvpn" + ], + "user_ips": false + }, + "cluster": "location_unknown", + "host": "aligator.bitmask.net", + "ip_address": "176.53.69.121" + } + ], + "openvpn_configuration": { + "auth": "SHA1", + "cipher": "AES-128-CBC", + "tls-cipher": "DHE-RSA-AES128-SHA" + }, + "serial": 1, + "version": 1 +} \ No newline at end of file diff --git a/assets/providers/bitmask.net_provider.json b/assets/providers/bitmask.net_provider.json new file mode 100644 index 00000000..d61be196 --- /dev/null +++ b/assets/providers/bitmask.net_provider.json @@ -0,0 +1,25 @@ +{ + "api_uri": "https://api.bitmask.net:4430", + "api_version": "1", + "ca_cert_fingerprint": "SHA256: 0f17c033115f6b76ff67871872303ff65034efe7dd1b910062ca323eb4da5c7e", + "ca_cert_uri": "https://bitmask.net/ca.crt", + "default_language": "en", + "description": { + "el": "Bitmask είναι ένα έργο του LEAP με σκοπό τον έλεγχο της απόδοσης και της αξιοπιστίας του λογισμικού LEAP. Bitmask τρέχει για τις τελευταίες αιμορραγία άκρο του κώδικα LEAP, και θα έχει πιθανότατα περισσότερες δυνατότητες και λιγότερα αξιοπιστία από άλλους φορείς παροχής υπηρεσιών.", + "en": "Bitmask is a project of LEAP with the purpose to test the performance and reliability of the LEAP software. Bitmask runs on the latest bleeding edge of the LEAP code, and will likely have more features and less reliability than other service providers.", + "es": "Bitmask es un proyecto de LEAP con el propósito de probar el rendimiento y la fiabilidad del software LEAP. Bitmask corre la última versión del código LEAP, y es de esperar que tenga más funciones y menos fiabilidad que los proveedores de servicios." + }, + "domain": "bitmask.net", + "enrollment_policy": "open", + "languages": [ + "el", + "en", + "es" + ], + "name": { + "en": "Bitmask" + }, + "services": [ + "openvpn" + ] +} \ No newline at end of file diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index 3e8f35a4..cc215be9 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -36,6 +36,10 @@ public class Dashboard extends Activity { preferences = getPreferences(MODE_PRIVATE); + // FIXME provider data!! get parmegv's work so we can stop (or lessen) faking it + if ( !preferences.contains("provider") ) + fixmePrefsFaker(preferences); + // Get our provider provider = Provider.getInstance(preferences); @@ -45,6 +49,53 @@ public class Dashboard extends Activity { providerNameTV.setTextSize(28); // TODO maybe to some calculating, or a marquee? } + // FIXME!! We don't want you around here once we have something /real/ going on + private void fixmePrefsFaker(SharedPreferences fakeit) { + SharedPreferences.Editor fakes = fakeit.edit(); + + AssetManager am = getAssets(); + BufferedReader prov = null; + try { + prov = new BufferedReader(new InputStreamReader(am.open("providers/bitmask.net_provider.json"))); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + BufferedReader serv = null; + try { + serv = new BufferedReader(new InputStreamReader(am.open("providers/bitmask.net_eip-service.json"))); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + StringBuilder provider = new StringBuilder(); + StringBuilder eip = new StringBuilder(); + + String line; + try { + while ((line = prov.readLine()) != null){ + provider.append(line); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + String providerjson = provider.toString(); + try { + while ((line = serv.readLine()) != null){ + eip.append(line); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + String eipjson = eip.toString(); + + fakes.putString("provider", providerjson); + fakes.putString("eip", eipjson); + fakes.commit(); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. -- cgit v1.2.3 From b6e47ac59c3e853b23d4392eec33bbeb2f068f17 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Wed, 30 Jan 2013 23:35:42 -0700 Subject: Add EIP Service item in Dashboard --- res/layout/client_dashboard.xml | 23 +++++++++++++++++++++++ res/layout/eip_overview.xml | 27 +++++++++++++++++++++++++++ res/values/strings.xml | 1 + src/se/leap/leapclient/Dashboard.java | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 res/layout/eip_overview.xml diff --git a/res/layout/client_dashboard.xml b/res/layout/client_dashboard.xml index 599a0972..9d9b7a40 100644 --- a/res/layout/client_dashboard.xml +++ b/res/layout/client_dashboard.xml @@ -53,4 +53,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/res/layout/eip_overview.xml b/res/layout/eip_overview.xml new file mode 100644 index 00000000..d8defcbc --- /dev/null +++ b/res/layout/eip_overview.xml @@ -0,0 +1,27 @@ + + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 606cb3bb..f18c9920 100755 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -257,5 +257,6 @@ LEAP Dashboard Provider: No provider configured + EIP \ No newline at end of file diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index cc215be9..5835acb8 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -47,6 +47,10 @@ public class Dashboard extends Activity { providerNameTV = (TextView) findViewById(R.id.providerName); providerNameTV.setText(provider.getName()); providerNameTV.setTextSize(28); // TODO maybe to some calculating, or a marquee? + + // TODO Inflate layout fragments for provider's services + if ( provider.hasEIP() ) + serviceItemEIP(); } // FIXME!! We don't want you around here once we have something /real/ going on @@ -96,6 +100,35 @@ public class Dashboard extends Activity { fakes.commit(); } + private void serviceItemEIP() { + // FIXME Provider service (eip/openvpn) + View eipOverview = ((ViewStub) findViewById(R.id.eipOverviewStub)).inflate(); + + // Set our EIP type title + eipTypeTV = (TextView) findViewById(R.id.eipType); + eipTypeTV.setText(provider.getEIPType()); + + // TODO Bind our switch to run our EIP + // What happens when our VPN stops running? does it call the listener? + Switch eipSwitch = (Switch) findViewById(R.id.eipSwitch); + eipSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if ( isChecked ){ + //TODO startVPN(); + } else { + //TODO stopVPN(); + } + } + }); + + //TODO write our info into the view fragment that will expand with details and a settings button + // TODO set eip overview subview + // TODO make eip type clickable, show subview + // TODO attach vpn status feedback to eip overview view + // TODO attach settings button to something + } + @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. -- cgit v1.2.3 From d21e8390e90437f0d053374f8e304ca3f592beb9 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Wed, 30 Jan 2013 23:37:33 -0700 Subject: More fun with EIP item entry. Added parts to expand listing for quick info and settings access --- res/layout/eip_overview.xml | 33 +++++++++++++++++++++++++++++++++ res/values/strings.xml | 2 ++ src/se/leap/leapclient/Dashboard.java | 5 +++++ 3 files changed, 40 insertions(+) diff --git a/res/layout/eip_overview.xml b/res/layout/eip_overview.xml index d8defcbc..21d4ae38 100644 --- a/res/layout/eip_overview.xml +++ b/res/layout/eip_overview.xml @@ -13,6 +13,8 @@ android:layout_marginBottom="10dp" android:layout_marginLeft="15dp" android:layout_toLeftOf="@+id/eipSwitch" + android:clickable="false" + android:onClick="toggleOverview" android:text="@string/eip_type_active" android:textAppearance="?android:attr/textAppearanceLarge" /> @@ -24,4 +26,35 @@ android:layout_alignParentTop="true" android:layout_marginRight="10dp" /> + + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index f18c9920..09252355 100755 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -257,6 +257,8 @@ LEAP Dashboard Provider: No provider configured + Access EIP connection settings + Status unknown EIP \ No newline at end of file diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index 5835acb8..7d0b5e0f 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -163,4 +163,9 @@ public class Dashboard extends Activity { } + @SuppressWarnings("unused") + private void toggleOverview() { + // TODO Expand the one line overview item to show some details + } + } -- cgit v1.2.3 From 92c32b0b96938009af55ed28920472f22a4614ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 31 Jan 2013 22:12:21 +0100 Subject: Problems with downloaded file, the emulator cannot find the file downloaded. Seen http://code.google.com/p/android/issues/detail?id=18462 and decided to look for another solution. First solution thought (and going to be the next test): HTTP Get request :) --- AndroidManifest.xml | 6 + assets/urls/bitmask.url | 6 + res/layout/activity_provider_list.xml | 10 ++ src/se/leap/leapclient/Dashboard.java | 4 +- src/se/leap/leapclient/ProviderAPI.java | 15 ++ src/se/leap/leapclient/ProviderListActivity.java | 187 +++++++++++++++++++++++ src/se/leap/leapclient/ProviderListContent.java | 77 ++++++++++ src/se/leap/leapclient/ProviderListFragment.java | 150 ++++++++++++++++++ 8 files changed, 453 insertions(+), 2 deletions(-) create mode 100644 assets/urls/bitmask.url create mode 100644 res/layout/activity_provider_list.xml create mode 100644 src/se/leap/leapclient/ProviderAPI.java create mode 100644 src/se/leap/leapclient/ProviderListActivity.java create mode 100644 src/se/leap/leapclient/ProviderListContent.java create mode 100644 src/se/leap/leapclient/ProviderListFragment.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7162576a..438b6887 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -25,6 +25,7 @@ + @@ -150,6 +151,11 @@ + + + \ No newline at end of file diff --git a/assets/urls/bitmask.url b/assets/urls/bitmask.url new file mode 100644 index 00000000..132e295d --- /dev/null +++ b/assets/urls/bitmask.url @@ -0,0 +1,6 @@ +{ + "name" : "bitmask", + "json_provider" : "https://bitmask.net/provider.json", + "cert" : "https://bitmask.net/1/cert", + "json_eip_service" : "https://api.bitmask.net:4430/1/config/eip-service.json" +} \ No newline at end of file diff --git a/res/layout/activity_provider_list.xml b/res/layout/activity_provider_list.xml new file mode 100644 index 00000000..6a6dafec --- /dev/null +++ b/res/layout/activity_provider_list.xml @@ -0,0 +1,10 @@ + diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index 7d0b5e0f..84ddab27 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -37,8 +37,8 @@ public class Dashboard extends Activity { preferences = getPreferences(MODE_PRIVATE); // FIXME provider data!! get parmegv's work so we can stop (or lessen) faking it - if ( !preferences.contains("provider") ) - fixmePrefsFaker(preferences); + if (preferences.contains("provider") ) + startActivity(new Intent(this, ProviderListActivity.class)); // Get our provider provider = Provider.getInstance(preferences); diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java new file mode 100644 index 00000000..6d52e44f --- /dev/null +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -0,0 +1,15 @@ +package se.leap.leapclient; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; + +public class ProviderAPI extends Service { + + @Override + public IBinder onBind(Intent arg0) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/se/leap/leapclient/ProviderListActivity.java b/src/se/leap/leapclient/ProviderListActivity.java new file mode 100644 index 00000000..4964a1fd --- /dev/null +++ b/src/se/leap/leapclient/ProviderListActivity.java @@ -0,0 +1,187 @@ +package se.leap.leapclient; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; + +import se.leap.leapclient.ProviderListContent; +import se.leap.leapclient.ProviderListContent.ProviderItem; +import android.app.DownloadManager; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.AssetManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.support.v4.app.FragmentActivity; + + +/** + * An activity representing a list of Providers. This activity + * has different presentations for handset and tablet-size devices. On + * handsets, the activity presents a list of items, which when touched, + * lead to a {@link DashboardActivity} representing + * item details. On tablets, the activity presents the list of items and + * item details side-by-side using two vertical panes. + *

+ * The activity makes heavy use of fragments. The list of items is a + * {@link ProviderListFragment} and the item details + * (if present) is a {@link DashboardFragment}. + *

+ * This activity also implements the required + * {@link ProviderListFragment.Callbacks} interface + * to listen for item selections. + */ +public class ProviderListActivity extends FragmentActivity + implements ProviderListFragment.Callbacks { + + /** + * Whether or not the activity is in two-pane mode, i.e. running on a tablet + * device. + */ + private boolean mTwoPane; + + private static SharedPreferences preferences; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_provider_list); + + preferences = getPreferences(MODE_PRIVATE); + + loadPreseededProviders(); + + // TODO: If exposing deep links into your app, handle intents here. + } + + private void loadPreseededProviders() { + AssetManager asset_manager = getAssets(); + String[] urls_filepaths = null; + try { + String url_files_folder = "urls"; + //TODO Put that folder in a better place (also inside the "for") + urls_filepaths = asset_manager.list(url_files_folder); + String provider_name = ""; + for(String url_filepath : urls_filepaths) + { + provider_name = url_filepath.subSequence(0, url_filepath.indexOf(".")).toString(); + if(ProviderListContent.ITEMS.isEmpty()) //TODO I have to implement a way of checking if a provider new or is already present in that ITEMS list + ProviderListContent.addItem(new ProviderItem(provider_name, asset_manager.open(url_files_folder + "/" + url_filepath))); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * Callback method from {@link ProviderListFragment.Callbacks} + * indicating that the item with the given ID was selected. + */ + @Override + public void onItemSelected(String id) { + if (mTwoPane) { + + } else { + // In single-pane mode, simply start the detail activity + // for the selected item ID. + + Iterator preseeded_providers_iterator = ProviderListContent.ITEMS.iterator(); + while(preseeded_providers_iterator.hasNext()) + { + ProviderItem current_provider_item = preseeded_providers_iterator.next(); + if(current_provider_item.id.equalsIgnoreCase(id)) + { + ArrayList downloaded_files = downloadFiles(current_provider_item); + try { + parseToSharedPrefs(downloaded_files); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + Intent dashboardIntent = new Intent(this, Dashboard.class); + startActivity(dashboardIntent); + } + } + + private void parseToSharedPrefs(ArrayList downloaded_files) throws IOException { + SharedPreferences.Editor sharedPreferencesEditor = preferences.edit(); + + for(int i = 0; i < downloaded_files.size(); i++) + { + String type_and_filename = downloaded_files.get(i); + String filename = type_and_filename.substring(type_and_filename.indexOf(":")+1, type_and_filename.length()); + + String file_contents = readFileAsString(filename, null); + + if(downloaded_files.get(i).startsWith("provider:")) + sharedPreferencesEditor.putString("provider", file_contents); + else if(downloaded_files.get(i).startsWith("provider:")) + sharedPreferencesEditor.putString("eip", file_contents); + + sharedPreferencesEditor.commit(); + } + } + + public static String readFileAsString(String fileName, String charsetName) + throws java.io.IOException { + java.io.InputStream is = new java.io.FileInputStream(fileName); + try { + final int bufsize = 4096; + int available = is.available(); + byte data[] = new byte[available < bufsize ? bufsize : available]; + int used = 0; + while (true) { + if (data.length - used < bufsize) { + byte newData[] = new byte[data.length << 1]; + System.arraycopy(data, 0, newData, 0, used); + data = newData; + } + int got = is.read(data, used, data.length - used); + if (got <= 0) + break; + used += got; + } + return charsetName != null ? new String(data, 0, used, charsetName) + : new String(data, 0, used); + } finally { + is.close(); + } + } + + private ArrayList downloadFiles(ProviderItem current_provider_item) { + ArrayList paths_to_downloaded_files = new ArrayList(); + + paths_to_downloaded_files.add(downloadProviderJSON("provider_json", current_provider_item.provider_json_url, Environment.DIRECTORY_DOWNLOADS, current_provider_item.name + "_provider.json")); + paths_to_downloaded_files.add(downloadProviderJSON("eip_service_json", current_provider_item.eip_service_json_url, Environment.DIRECTORY_DOWNLOADS, current_provider_item.name + "_eip-service.json")); + + return paths_to_downloaded_files; + } + + private String downloadProviderJSON(String type, String json_url, String target_directory, String filename) { + + DownloadManager.Request request = new DownloadManager.Request(Uri.parse(json_url)); + request.setDescription("Downloading JSON file"); + request.setTitle("JSON file"); + // in order for this if to run, you must use the android 3.2 to compile your app + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + request.allowScanningByMediaScanner(); + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + } + //request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, current_provider_item.name + "_provider.json"); + request.setDestinationInExternalPublicDir(target_directory, filename); + + // get download service and enqueue file + DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); + manager.enqueue(request); + return type + ":" + target_directory + "/" + filename; + + } +} diff --git a/src/se/leap/leapclient/ProviderListContent.java b/src/se/leap/leapclient/ProviderListContent.java new file mode 100644 index 00000000..1fe60159 --- /dev/null +++ b/src/se/leap/leapclient/ProviderListContent.java @@ -0,0 +1,77 @@ +package se.leap.leapclient; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.json.JSONException; +import org.json.JSONObject; + + +public class ProviderListContent { + + /** + * An array of sample (dummy) items. + */ + public static List ITEMS = new ArrayList(); + + /** + * A map of sample (dummy) items, by ID. + */ + public static Map ITEM_MAP = new HashMap(); + + static { + //addItem(new ProviderItem("1", "bitmask", "https://bitmask.net/provider.json", "https://api.bitmask.net:4430/1/config/eip-service.json")); + } + + public static void addItem(ProviderItem item) { + ITEMS.add(item); + ITEM_MAP.put(String.valueOf(ITEMS.size()), item); + } + + /** + * A dummy item representing a piece of content. + */ + public static class ProviderItem { + public String id; + public String name; + public String provider_json_url; + public String eip_service_json_url; + + + public ProviderItem(String id, String name, String provider_json_url, String eip_service_json_url) { + this.id = id; + this.name = name; + this.provider_json_url = provider_json_url; + this.eip_service_json_url = eip_service_json_url; + } + + public ProviderItem(String name, InputStream urls_file_input_stream) { + + try { + byte[] urls_file_bytes = new byte[urls_file_input_stream.available()]; + urls_file_input_stream.read(urls_file_bytes); + String urls_file_content = new String(urls_file_bytes); + JSONObject file_contents = new JSONObject(urls_file_content); + id = name; + this.name = name; + provider_json_url = (String) file_contents.get("json_provider"); + eip_service_json_url = (String) file_contents.get("json_eip_service"); + } catch (JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Override + public String toString() { + return name; + } + } +} diff --git a/src/se/leap/leapclient/ProviderListFragment.java b/src/se/leap/leapclient/ProviderListFragment.java new file mode 100644 index 00000000..717a65c1 --- /dev/null +++ b/src/se/leap/leapclient/ProviderListFragment.java @@ -0,0 +1,150 @@ +package se.leap.leapclient; + +import android.app.Activity; +import android.os.Bundle; +import android.support.v4.app.ListFragment; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.ListView; + +import se.leap.leapclient.ProviderListContent; + +/** + * A list fragment representing a list of Providers. This fragment + * also supports tablet devices by allowing list items to be given an + * 'activated' state upon selection. This helps indicate which item is + * currently being viewed in a {@link DashboardFragment}. + *

+ * Activities containing this fragment MUST implement the {@link Callbacks} + * interface. + */ +public class ProviderListFragment extends ListFragment { + + /** + * The serialization (saved instance state) Bundle key representing the + * activated item position. Only used on tablets. + */ + private static final String STATE_ACTIVATED_POSITION = "activated_position"; + + /** + * The fragment's current callback object, which is notified of list item + * clicks. + */ + private Callbacks mCallbacks = sDummyCallbacks; + + /** + * The current activated item position. Only used on tablets. + */ + private int mActivatedPosition = ListView.INVALID_POSITION; + + /** + * A callback interface that all activities containing this fragment must + * implement. This mechanism allows activities to be notified of item + * selections. + */ + public interface Callbacks { + /** + * Callback for when an item has been selected. + */ + public void onItemSelected(String id); + } + + /** + * A dummy implementation of the {@link Callbacks} interface that does + * nothing. Used only when this fragment is not attached to an activity. + */ + private static Callbacks sDummyCallbacks = new Callbacks() { + @Override + public void onItemSelected(String id) { + } + }; + + /** + * Mandatory empty constructor for the fragment manager to instantiate the + * fragment (e.g. upon screen orientation changes). + */ + public ProviderListFragment() { + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setListAdapter(new ArrayAdapter( + getActivity(), + android.R.layout.simple_list_item_activated_1, + android.R.id.text1, + ProviderListContent.ITEMS)); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + // Restore the previously serialized activated item position. + if (savedInstanceState != null + && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) { + setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION)); + } + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + + // Activities containing this fragment must implement its callbacks. + if (!(activity instanceof Callbacks)) { + throw new IllegalStateException("Activity must implement fragment's callbacks."); + } + + mCallbacks = (Callbacks) activity; + } + + @Override + public void onDetach() { + super.onDetach(); + + // Reset the active callbacks interface to the dummy implementation. + mCallbacks = sDummyCallbacks; + } + + @Override + public void onListItemClick(ListView listView, View view, int position, long id) { + super.onListItemClick(listView, view, position, id); + + // Notify the active callbacks interface (the activity, if the + // fragment is attached to one) that an item has been selected. + mCallbacks.onItemSelected(ProviderListContent.ITEMS.get(position).id); + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + if (mActivatedPosition != ListView.INVALID_POSITION) { + // Serialize and persist the activated item position. + outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition); + } + } + + /** + * Turns on activate-on-click mode. When this mode is on, list items will be + * given the 'activated' state when touched. + */ + public void setActivateOnItemClick(boolean activateOnItemClick) { + // When setting CHOICE_MODE_SINGLE, ListView will automatically + // give items the 'activated' state when touched. + getListView().setChoiceMode(activateOnItemClick + ? ListView.CHOICE_MODE_SINGLE + : ListView.CHOICE_MODE_NONE); + } + + private void setActivatedPosition(int position) { + if (position == ListView.INVALID_POSITION) { + getListView().setItemChecked(mActivatedPosition, false); + } else { + getListView().setItemChecked(position, true); + } + + mActivatedPosition = position; + } +} -- cgit v1.2.3 From 7b9e22e765a1e5eda05ad121684e63c20ff5f049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Fri, 1 Feb 2013 00:13:09 +0100 Subject: I have a handshake failing within an HTTP connection in order to get the eip-service.json file. provider.json downloads and parses itself OK to SharedPreferences. It also does not link OK to the Dashboard, I do not know how to do it properly and I'm so tired (eyes hurting). Beginning with security things :) Happy to have gotten around DownloadManager problem with a simple HTTP connection. --- AndroidManifest.xml | 3 +- src/se/leap/leapclient/Dashboard.java | 3 +- src/se/leap/leapclient/ProviderAPI.java | 64 +++++++++++++++-- src/se/leap/leapclient/ProviderListActivity.java | 89 +++++------------------- 4 files changed, 79 insertions(+), 80 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 438b6887..854a2972 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -70,7 +70,8 @@ - + + diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index 84ddab27..f81c37a7 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -37,7 +37,8 @@ public class Dashboard extends Activity { preferences = getPreferences(MODE_PRIVATE); // FIXME provider data!! get parmegv's work so we can stop (or lessen) faking it - if (preferences.contains("provider") ) + //TODO In my emulator, I always get that contains TRUE. Don't know why, but I've been testing without the "!". + if (!preferences.contains("provider") ) startActivity(new Intent(this, ProviderListActivity.class)); // Get our provider diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 6d52e44f..aefb87fc 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -1,15 +1,67 @@ package se.leap.leapclient; -import android.app.Service; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Scanner; + +import android.app.IntentService; import android.content.Intent; -import android.os.IBinder; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.util.Log; + +public class ProviderAPI extends IntentService { -public class ProviderAPI extends Service { + public ProviderAPI() { + super("ProviderAPI"); + Log.v("ClassName", "Provider API"); + // TODO Auto-generated constructor stub + } @Override - public IBinder onBind(Intent arg0) { - // TODO Auto-generated method stub - return null; + protected void onHandleIntent(Intent task_for) { + Bundle task ; + System.out.println("onHandleIntent called"); + if(!(task = task_for.getBundleExtra("downloadJSONFiles")).isEmpty()) + { + String provider_key = "provider"; + String eip_service_key = "eip"; + String provider_json_url = (String) task.get(provider_key); + String eip_service_json_url = (String) task.get(eip_service_key); + try { + getAndParseSharedPref(provider_key, provider_json_url); + getAndParseSharedPref(eip_service_key, eip_service_json_url); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + private void getAndParseSharedPref(String shared_preferences_key, + String json_url) throws IOException { + URL url = new URL(json_url); + HttpURLConnection urlConnection = (HttpURLConnection) url + .openConnection(); + try { + InputStream in = new BufferedInputStream( + urlConnection.getInputStream()); + String json_file_content = new Scanner(in).useDelimiter("\\A") + .next(); + + SharedPreferences.Editor shared_preferences_editor = ProviderListActivity.shared_preferences + .edit(); + shared_preferences_editor.putString(shared_preferences_key, + json_file_content); + shared_preferences_editor.commit(); + System.out.println("Shared preferences updated: " + ProviderListActivity.shared_preferences.getString(shared_preferences_key, "Default")); + } finally { + urlConnection.disconnect(); + } + } } diff --git a/src/se/leap/leapclient/ProviderListActivity.java b/src/se/leap/leapclient/ProviderListActivity.java index 4964a1fd..9e5796da 100644 --- a/src/se/leap/leapclient/ProviderListActivity.java +++ b/src/se/leap/leapclient/ProviderListActivity.java @@ -1,9 +1,15 @@ package se.leap.leapclient; +import java.io.BufferedInputStream; import java.io.File; import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; import java.util.Iterator; +import java.util.Scanner; import se.leap.leapclient.ProviderListContent; import se.leap.leapclient.ProviderListContent.ProviderItem; @@ -44,14 +50,14 @@ public class ProviderListActivity extends FragmentActivity */ private boolean mTwoPane; - private static SharedPreferences preferences; + static SharedPreferences shared_preferences; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_provider_list); - preferences = getPreferences(MODE_PRIVATE); + shared_preferences = getPreferences(MODE_PRIVATE); loadPreseededProviders(); @@ -96,9 +102,8 @@ public class ProviderListActivity extends FragmentActivity ProviderItem current_provider_item = preseeded_providers_iterator.next(); if(current_provider_item.id.equalsIgnoreCase(id)) { - ArrayList downloaded_files = downloadFiles(current_provider_item); try { - parseToSharedPrefs(downloaded_files); + downloadJSONFiles(current_provider_item); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -111,77 +116,17 @@ public class ProviderListActivity extends FragmentActivity } } - private void parseToSharedPrefs(ArrayList downloaded_files) throws IOException { - SharedPreferences.Editor sharedPreferencesEditor = preferences.edit(); + private void downloadJSONFiles(ProviderItem current_provider_item) throws IOException { + Intent provider_API_command = new Intent(this, ProviderAPI.class); - for(int i = 0; i < downloaded_files.size(); i++) - { - String type_and_filename = downloaded_files.get(i); - String filename = type_and_filename.substring(type_and_filename.indexOf(":")+1, type_and_filename.length()); - - String file_contents = readFileAsString(filename, null); - - if(downloaded_files.get(i).startsWith("provider:")) - sharedPreferencesEditor.putString("provider", file_contents); - else if(downloaded_files.get(i).startsWith("provider:")) - sharedPreferencesEditor.putString("eip", file_contents); - - sharedPreferencesEditor.commit(); - } - } - - public static String readFileAsString(String fileName, String charsetName) - throws java.io.IOException { - java.io.InputStream is = new java.io.FileInputStream(fileName); - try { - final int bufsize = 4096; - int available = is.available(); - byte data[] = new byte[available < bufsize ? bufsize : available]; - int used = 0; - while (true) { - if (data.length - used < bufsize) { - byte newData[] = new byte[data.length << 1]; - System.arraycopy(data, 0, newData, 0, used); - data = newData; - } - int got = is.read(data, used, data.length - used); - if (got <= 0) - break; - used += got; - } - return charsetName != null ? new String(data, 0, used, charsetName) - : new String(data, 0, used); - } finally { - is.close(); - } - } - - private ArrayList downloadFiles(ProviderItem current_provider_item) { - ArrayList paths_to_downloaded_files = new ArrayList(); + Bundle method_and_parameters = new Bundle(); + method_and_parameters.putString("method", "getAndParseSharedPref"); + method_and_parameters.putString("provider", current_provider_item.provider_json_url); + method_and_parameters.putString("eip", current_provider_item.eip_service_json_url); - paths_to_downloaded_files.add(downloadProviderJSON("provider_json", current_provider_item.provider_json_url, Environment.DIRECTORY_DOWNLOADS, current_provider_item.name + "_provider.json")); - paths_to_downloaded_files.add(downloadProviderJSON("eip_service_json", current_provider_item.eip_service_json_url, Environment.DIRECTORY_DOWNLOADS, current_provider_item.name + "_eip-service.json")); + provider_API_command.putExtra("downloadJSONFiles", method_and_parameters); - return paths_to_downloaded_files; - } - - private String downloadProviderJSON(String type, String json_url, String target_directory, String filename) { - - DownloadManager.Request request = new DownloadManager.Request(Uri.parse(json_url)); - request.setDescription("Downloading JSON file"); - request.setTitle("JSON file"); - // in order for this if to run, you must use the android 3.2 to compile your app - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - request.allowScanningByMediaScanner(); - request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); - } - //request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, current_provider_item.name + "_provider.json"); - request.setDestinationInExternalPublicDir(target_directory, filename); - - // get download service and enqueue file - DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); - manager.enqueue(request); - return type + ":" + target_directory + "/" + filename; + startService(provider_API_command); } } -- cgit v1.2.3 From d2bd18ef560d95974117604af899b3a9fcc16dab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 4 Feb 2013 16:35:28 +0100 Subject: Created ConfigHelper with static information such as sharedprefs keys, the saveSharedPrefs method and an unimplemented rescueFromJSONException. Next step: managing HttpsURLConnection for the CertPathValidatorException. --- src/se/leap/leapclient/ConfigHelper.java | 32 ++++++++++++++ src/se/leap/leapclient/Dashboard.java | 3 +- src/se/leap/leapclient/ProviderAPI.java | 55 +++++++++++++----------- src/se/leap/leapclient/ProviderListActivity.java | 3 +- 4 files changed, 64 insertions(+), 29 deletions(-) create mode 100644 src/se/leap/leapclient/ConfigHelper.java diff --git a/src/se/leap/leapclient/ConfigHelper.java b/src/se/leap/leapclient/ConfigHelper.java new file mode 100644 index 00000000..174ff79f --- /dev/null +++ b/src/se/leap/leapclient/ConfigHelper.java @@ -0,0 +1,32 @@ +package se.leap.leapclient; + +import org.json.JSONException; +import org.json.JSONObject; + +import android.content.SharedPreferences; + +public class ConfigHelper { + + final static String downloadJsonFilesBundleExtra = "downloadJSONFiles"; + final static String provider_key = "provider"; + final static String eip_service_key = "eip"; + + static void saveSharedPref(String shared_preferences_key, + JSONObject content) { + + SharedPreferences.Editor shared_preferences_editor = ProviderListActivity.shared_preferences + .edit(); + shared_preferences_editor.putString(shared_preferences_key, + content.toString()); + shared_preferences_editor.commit(); + System.out.println("Shared preferences updated: " + + ProviderListActivity.shared_preferences.getString( + shared_preferences_key, "Default")); + + } + + static void rescueJSONException(JSONException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } +} diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index f81c37a7..84ddab27 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -37,8 +37,7 @@ public class Dashboard extends Activity { preferences = getPreferences(MODE_PRIVATE); // FIXME provider data!! get parmegv's work so we can stop (or lessen) faking it - //TODO In my emulator, I always get that contains TRUE. Don't know why, but I've been testing without the "!". - if (!preferences.contains("provider") ) + if (preferences.contains("provider") ) startActivity(new Intent(this, ProviderListActivity.class)); // Get our provider diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index aefb87fc..40638180 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -5,11 +5,16 @@ import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; +import java.net.URLConnection; import java.util.Scanner; +import javax.net.ssl.HttpsURLConnection; + +import org.json.JSONException; +import org.json.JSONObject; + import android.app.IntentService; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; import android.util.Log; @@ -23,45 +28,45 @@ public class ProviderAPI extends IntentService { @Override protected void onHandleIntent(Intent task_for) { - Bundle task ; + Bundle task; System.out.println("onHandleIntent called"); - if(!(task = task_for.getBundleExtra("downloadJSONFiles")).isEmpty()) - { - String provider_key = "provider"; - String eip_service_key = "eip"; - String provider_json_url = (String) task.get(provider_key); - String eip_service_json_url = (String) task.get(eip_service_key); + if (!(task = task_for.getBundleExtra(ConfigHelper.downloadJsonFilesBundleExtra)).isEmpty()) { + String provider_json_url = (String) task.get(ConfigHelper.provider_key); + String eip_service_json_url = (String) task.get(ConfigHelper.eip_service_key); try { - getAndParseSharedPref(provider_key, provider_json_url); - getAndParseSharedPref(eip_service_key, eip_service_json_url); + JSONObject provider_json = getFromProvider(provider_json_url); + ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); + JSONObject eip_service_json = getFromProvider(eip_service_json_url); + ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); + } catch (JSONException e) { + ConfigHelper.rescueJSONException(e); } } } - private void getAndParseSharedPref(String shared_preferences_key, - String json_url) throws IOException { + private JSONObject getFromProvider(String json_url) throws IOException, JSONException { URL url = new URL(json_url); - HttpURLConnection urlConnection = (HttpURLConnection) url - .openConnection(); + String json_file_content = ""; + URLConnection urlConnection = null; + + if (url.getProtocol().equalsIgnoreCase("https")) { + urlConnection = (HttpsURLConnection) url.openConnection(); + } else if (url.getProtocol().equalsIgnoreCase("http")) { + urlConnection = (HttpURLConnection) url.openConnection(); + } + try { InputStream in = new BufferedInputStream( urlConnection.getInputStream()); - String json_file_content = new Scanner(in).useDelimiter("\\A") - .next(); - - SharedPreferences.Editor shared_preferences_editor = ProviderListActivity.shared_preferences - .edit(); - shared_preferences_editor.putString(shared_preferences_key, - json_file_content); - shared_preferences_editor.commit(); - System.out.println("Shared preferences updated: " + ProviderListActivity.shared_preferences.getString(shared_preferences_key, "Default")); + json_file_content = new Scanner(in).useDelimiter("\\A").next(); } finally { - urlConnection.disconnect(); + ((HttpURLConnection) urlConnection).disconnect(); } - + + return new JSONObject(json_file_content); } } diff --git a/src/se/leap/leapclient/ProviderListActivity.java b/src/se/leap/leapclient/ProviderListActivity.java index 9e5796da..088b464d 100644 --- a/src/se/leap/leapclient/ProviderListActivity.java +++ b/src/se/leap/leapclient/ProviderListActivity.java @@ -120,11 +120,10 @@ public class ProviderListActivity extends FragmentActivity Intent provider_API_command = new Intent(this, ProviderAPI.class); Bundle method_and_parameters = new Bundle(); - method_and_parameters.putString("method", "getAndParseSharedPref"); method_and_parameters.putString("provider", current_provider_item.provider_json_url); method_and_parameters.putString("eip", current_provider_item.eip_service_json_url); - provider_API_command.putExtra("downloadJSONFiles", method_and_parameters); + provider_API_command.putExtra(ConfigHelper.downloadJsonFilesBundleExtra, method_and_parameters); startService(provider_API_command); -- cgit v1.2.3 From 3bab2278ccd8d960e6f8f92f939c81b13832b23a Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Mon, 4 Feb 2013 09:40:16 -0700 Subject: Fix testing conditional looking for saved prefs that made it into last commit --- src/se/leap/leapclient/Dashboard.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index 84ddab27..7bb71c1e 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -36,8 +36,8 @@ public class Dashboard extends Activity { preferences = getPreferences(MODE_PRIVATE); - // FIXME provider data!! get parmegv's work so we can stop (or lessen) faking it - if (preferences.contains("provider") ) + // FIXME We need to StartActivityForResult and move the rest to buildDashboard (called in "else" and onActivityResult) + if ( !preferences.contains("provider") ) startActivity(new Intent(this, ProviderListActivity.class)); // Get our provider -- cgit v1.2.3 From 8ab36864e2a393df077073f8618a4fc55c307522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Mon, 4 Feb 2013 18:44:38 +0100 Subject: Secure HTTP working with certificates downloaded from api.bitmask.net and bitmask.net. Both prefs are downloaded and parsed to SharedPreferences. --- res/raw/leapkeystore.bks | Bin 0 -> 2866 bytes src/se/leap/leapclient/ConfigHelper.java | 1 + src/se/leap/leapclient/LeapHttpClient.java | 58 +++++++++++++++++++++++++++++ src/se/leap/leapclient/ProviderAPI.java | 35 +++++++---------- 4 files changed, 72 insertions(+), 22 deletions(-) create mode 100644 res/raw/leapkeystore.bks create mode 100644 src/se/leap/leapclient/LeapHttpClient.java diff --git a/res/raw/leapkeystore.bks b/res/raw/leapkeystore.bks new file mode 100644 index 00000000..56f6758b Binary files /dev/null and b/res/raw/leapkeystore.bks differ diff --git a/src/se/leap/leapclient/ConfigHelper.java b/src/se/leap/leapclient/ConfigHelper.java index 174ff79f..9b857b0d 100644 --- a/src/se/leap/leapclient/ConfigHelper.java +++ b/src/se/leap/leapclient/ConfigHelper.java @@ -1,5 +1,6 @@ package se.leap.leapclient; + import org.json.JSONException; import org.json.JSONObject; diff --git a/src/se/leap/leapclient/LeapHttpClient.java b/src/se/leap/leapclient/LeapHttpClient.java new file mode 100644 index 00000000..41cb7879 --- /dev/null +++ b/src/se/leap/leapclient/LeapHttpClient.java @@ -0,0 +1,58 @@ +package se.leap.leapclient; + +import java.io.InputStream; +import java.security.KeyStore; + +import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.scheme.PlainSocketFactory; +import org.apache.http.conn.scheme.Scheme; +import org.apache.http.conn.scheme.SchemeRegistry; +import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.SingleClientConnManager; + +import android.content.Context; + +public class LeapHttpClient extends DefaultHttpClient { + final Context context; + + public LeapHttpClient(Context context) { + this.context = context; + } + + @Override + protected ClientConnectionManager createClientConnectionManager() { + SchemeRegistry registry = new SchemeRegistry(); + registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); + // Register for port 443 our SSLSocketFactory with our keystore + // to the ConnectionManager + registry.register(new Scheme("https", newSslSocketFactory(), 443)); + return new SingleClientConnManager(getParams(), registry); + } + + private SSLSocketFactory newSslSocketFactory() { + try { + // Get an instance of the Bouncy Castle KeyStore format + KeyStore trusted = KeyStore.getInstance("BKS"); + // Get the raw resource, which contains the keystore with + // your trusted certificates (root and any intermediate certs) + InputStream in = context.getResources().openRawResource(R.raw.leapkeystore); + try { + // Initialize the keystore with the provided trusted certificates + // Also provide the password of the keystore + trusted.load(in, "uer92jf".toCharArray()); + } finally { + in.close(); + } + // Pass the keystore to the SSLSocketFactory. The factory is responsible + // for the verification of the server certificate. + SSLSocketFactory sf = new SSLSocketFactory(trusted); + // Hostname verification from certificate + // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506 + sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); + return sf; + } catch (Exception e) { + throw new AssertionError(e); + } + } +} diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 40638180..d487ebe3 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -1,15 +1,12 @@ package se.leap.leapclient; -import java.io.BufferedInputStream; import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.net.URLConnection; import java.util.Scanner; -import javax.net.ssl.HttpsURLConnection; - +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; import org.json.JSONObject; @@ -48,23 +45,17 @@ public class ProviderAPI extends IntentService { } private JSONObject getFromProvider(String json_url) throws IOException, JSONException { - URL url = new URL(json_url); + String json_file_content = ""; - URLConnection urlConnection = null; - if (url.getProtocol().equalsIgnoreCase("https")) { - urlConnection = (HttpsURLConnection) url.openConnection(); - } else if (url.getProtocol().equalsIgnoreCase("http")) { - urlConnection = (HttpURLConnection) url.openConnection(); - } - - try { - InputStream in = new BufferedInputStream( - urlConnection.getInputStream()); - json_file_content = new Scanner(in).useDelimiter("\\A").next(); - } finally { - ((HttpURLConnection) urlConnection).disconnect(); - } + DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); + HttpGet get = new HttpGet(json_url); + // Execute the GET call and obtain the response + HttpResponse getResponse = client.execute(get); + HttpEntity responseEntity = getResponse.getEntity(); + + json_file_content = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); + return new JSONObject(json_file_content); } -- cgit v1.2.3 From 4567c97e526154394874b971a29f66c9ca22e6f2 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Tue, 5 Feb 2013 10:35:36 -0700 Subject: Move Dashboard view building code into a function so it does not run when we have no config (createed NullPointerExceptions) --- src/se/leap/leapclient/Dashboard.java | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index 7bb71c1e..a7e84eef 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -36,21 +36,12 @@ public class Dashboard extends Activity { preferences = getPreferences(MODE_PRIVATE); - // FIXME We need to StartActivityForResult and move the rest to buildDashboard (called in "else" and onActivityResult) - if ( !preferences.contains("provider") ) + // Check if we have preferences, run configuration wizard if not + // TODO We should do a better check for config that this! + if (!preferences.contains("provider") ) startActivity(new Intent(this, ProviderListActivity.class)); - - // Get our provider - provider = Provider.getInstance(preferences); - - // Set provider name in textview - providerNameTV = (TextView) findViewById(R.id.providerName); - providerNameTV.setText(provider.getName()); - providerNameTV.setTextSize(28); // TODO maybe to some calculating, or a marquee? - - // TODO Inflate layout fragments for provider's services - if ( provider.hasEIP() ) - serviceItemEIP(); + else + buildDashboard(); } // FIXME!! We don't want you around here once we have something /real/ going on @@ -99,6 +90,20 @@ public class Dashboard extends Activity { fakes.putString("eip", eipjson); fakes.commit(); } + + private void buildDashboard() { + // Get our provider + provider = Provider.getInstance(preferences); + + // Set provider name in textview + providerNameTV = (TextView) findViewById(R.id.providerName); + providerNameTV.setText(provider.getName()); + providerNameTV.setTextSize(28); // TODO maybe to some calculating, or a marquee? + + // TODO Inflate layout fragments for provider's services + if ( provider.hasEIP() ) + serviceItemEIP(); + } private void serviceItemEIP() { // FIXME Provider service (eip/openvpn) -- cgit v1.2.3 From 2045c946b0f67c0415909bb1e459ac00af1359b9 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Tue, 5 Feb 2013 11:05:16 -0700 Subject: Remove function to push data into preferences (it was for testing before we had ProviderList stuff) --- src/se/leap/leapclient/Dashboard.java | 46 ----------------------------------- 1 file changed, 46 deletions(-) diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index a7e84eef..3f32bde3 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -44,52 +44,6 @@ public class Dashboard extends Activity { buildDashboard(); } - // FIXME!! We don't want you around here once we have something /real/ going on - private void fixmePrefsFaker(SharedPreferences fakeit) { - SharedPreferences.Editor fakes = fakeit.edit(); - - AssetManager am = getAssets(); - BufferedReader prov = null; - try { - prov = new BufferedReader(new InputStreamReader(am.open("providers/bitmask.net_provider.json"))); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - BufferedReader serv = null; - try { - serv = new BufferedReader(new InputStreamReader(am.open("providers/bitmask.net_eip-service.json"))); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - StringBuilder provider = new StringBuilder(); - StringBuilder eip = new StringBuilder(); - - String line; - try { - while ((line = prov.readLine()) != null){ - provider.append(line); - } - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - String providerjson = provider.toString(); - try { - while ((line = serv.readLine()) != null){ - eip.append(line); - } - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - String eipjson = eip.toString(); - - fakes.putString("provider", providerjson); - fakes.putString("eip", eipjson); - fakes.commit(); - } private void buildDashboard() { // Get our provider -- cgit v1.2.3 From 1d5f1c320ee67cfadd62aeef056a043bee75096d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Tue, 5 Feb 2013 20:46:33 +0100 Subject: Simplified certificates and urls: only 1 certificate, and no :443 port in eip. Downloads certificate and eip from web, and loads provider from assets. KeyStore not created with latest version of BouncyCastle. Looking forward to file a bug and look for a solution. --- .classpath | 17 ++++----- AndroidManifest.xml | 3 ++ assets/providers/bitmask.net_eip-service.json | 42 ----------------------- assets/urls/bitmask.url | 5 +-- res/raw/leapkeystore.bks | Bin 2866 -> 1487 bytes src/se/leap/leapclient/ConfigHelper.java | 11 +++--- src/se/leap/leapclient/Dashboard.java | 5 +-- src/se/leap/leapclient/LeapHttpClient.java | 2 +- src/se/leap/leapclient/ProviderAPI.java | 21 ++++++++---- src/se/leap/leapclient/ProviderListActivity.java | 25 ++++++++++++-- src/se/leap/leapclient/ProviderListContent.java | 7 +++- 11 files changed, 68 insertions(+), 70 deletions(-) delete mode 100644 assets/providers/bitmask.net_eip-service.json diff --git a/.classpath b/.classpath index 3f9691c5..a5824471 100644 --- a/.classpath +++ b/.classpath @@ -1,8 +1,9 @@ - - - - - - - - + + + + + + + + + diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 854a2972..48ccbda4 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -156,6 +156,9 @@ + + + diff --git a/assets/providers/bitmask.net_eip-service.json b/assets/providers/bitmask.net_eip-service.json deleted file mode 100644 index 6ac2fed6..00000000 --- a/assets/providers/bitmask.net_eip-service.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "clusters": [ - { - "label": { - "en": "Location Unknown" - }, - "name": "location_unknown" - } - ], - "gateways": [ - { - "capabilities": { - "adblock": false, - "filter_dns": true, - "ports": [ - "1194", - "443", - "53", - "80" - ], - "protocols": [ - "tcp", - "udp" - ], - "transport": [ - "openvpn" - ], - "user_ips": false - }, - "cluster": "location_unknown", - "host": "aligator.bitmask.net", - "ip_address": "176.53.69.121" - } - ], - "openvpn_configuration": { - "auth": "SHA1", - "cipher": "AES-128-CBC", - "tls-cipher": "DHE-RSA-AES128-SHA" - }, - "serial": 1, - "version": 1 -} \ No newline at end of file diff --git a/assets/urls/bitmask.url b/assets/urls/bitmask.url index 132e295d..f83ead86 100644 --- a/assets/urls/bitmask.url +++ b/assets/urls/bitmask.url @@ -1,6 +1,7 @@ { "name" : "bitmask", + "assets_json_provider" : "providers/bitmask.net_provider.json", "json_provider" : "https://bitmask.net/provider.json", - "cert" : "https://bitmask.net/1/cert", - "json_eip_service" : "https://api.bitmask.net:4430/1/config/eip-service.json" + "cert" : "https://bitmask.net/ca.crt", + "json_eip_service" : "https://api.bitmask.net/1/config/eip-service.json" } \ No newline at end of file diff --git a/res/raw/leapkeystore.bks b/res/raw/leapkeystore.bks index 56f6758b..2e853ac4 100644 Binary files a/res/raw/leapkeystore.bks and b/res/raw/leapkeystore.bks differ diff --git a/src/se/leap/leapclient/ConfigHelper.java b/src/se/leap/leapclient/ConfigHelper.java index 9b857b0d..be848db0 100644 --- a/src/se/leap/leapclient/ConfigHelper.java +++ b/src/se/leap/leapclient/ConfigHelper.java @@ -10,20 +10,21 @@ public class ConfigHelper { final static String downloadJsonFilesBundleExtra = "downloadJSONFiles"; final static String provider_key = "provider"; + final static String cert_key = "cert"; final static String eip_service_key = "eip"; - static void saveSharedPref(String shared_preferences_key, - JSONObject content) { - + static void saveSharedPref(String shared_preferences_key, JSONObject content) { + SharedPreferences.Editor shared_preferences_editor = ProviderListActivity.shared_preferences .edit(); shared_preferences_editor.putString(shared_preferences_key, content.toString()); shared_preferences_editor.commit(); - System.out.println("Shared preferences updated: " + System.out.println("Shared preferences updated: key = " + + shared_preferences_key + + " Content = " + ProviderListActivity.shared_preferences.getString( shared_preferences_key, "Default")); - } static void rescueJSONException(JSONException e) { diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index 7bb71c1e..02bc704c 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -37,9 +37,10 @@ public class Dashboard extends Activity { preferences = getPreferences(MODE_PRIVATE); // FIXME We need to StartActivityForResult and move the rest to buildDashboard (called in "else" and onActivityResult) - if ( !preferences.contains("provider") ) + if ( !preferences.contains("provider") ) { startActivity(new Intent(this, ProviderListActivity.class)); - + } + // Get our provider provider = Provider.getInstance(preferences); diff --git a/src/se/leap/leapclient/LeapHttpClient.java b/src/se/leap/leapclient/LeapHttpClient.java index 41cb7879..9e1a541b 100644 --- a/src/se/leap/leapclient/LeapHttpClient.java +++ b/src/se/leap/leapclient/LeapHttpClient.java @@ -49,7 +49,7 @@ public class LeapHttpClient extends DefaultHttpClient { SSLSocketFactory sf = new SSLSocketFactory(trusted); // Hostname verification from certificate // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506 - sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); + sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); return sf; } catch (Exception e) { throw new AssertionError(e); diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index d487ebe3..33f7fd74 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -5,6 +5,7 @@ import java.util.Scanner; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; @@ -28,35 +29,41 @@ public class ProviderAPI extends IntentService { Bundle task; System.out.println("onHandleIntent called"); if (!(task = task_for.getBundleExtra(ConfigHelper.downloadJsonFilesBundleExtra)).isEmpty()) { - String provider_json_url = (String) task.get(ConfigHelper.provider_key); + String cert_url = (String) task.get(ConfigHelper.cert_key); String eip_service_json_url = (String) task.get(ConfigHelper.eip_service_key); try { - JSONObject provider_json = getFromProvider(provider_json_url); - ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); - JSONObject eip_service_json = getFromProvider(eip_service_json_url); + String cert_string = getStringFromProvider(cert_url); + JSONObject cert_json = new JSONObject("{ \"certificate\" : \"" + cert_string + "\"}"); + ConfigHelper.saveSharedPref(ConfigHelper.cert_key, cert_json); + JSONObject eip_service_json = getJSONFromProvider(eip_service_json_url); ConfigHelper.saveSharedPref(ConfigHelper.eip_service_key, eip_service_json); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (JSONException e) { ConfigHelper.rescueJSONException(e); + } catch(Exception e) { + e.printStackTrace(); } } } - private JSONObject getFromProvider(String json_url) throws IOException, JSONException { + private String getStringFromProvider(String string_url) throws IOException { String json_file_content = ""; DefaultHttpClient client = new LeapHttpClient(getApplicationContext()); - HttpGet get = new HttpGet(json_url); + HttpGet get = new HttpGet(string_url); // Execute the GET call and obtain the response HttpResponse getResponse = client.execute(get); HttpEntity responseEntity = getResponse.getEntity(); json_file_content = new Scanner(responseEntity.getContent()).useDelimiter("\\A").next(); - + return json_file_content; + } + private JSONObject getJSONFromProvider(String json_url) throws IOException, JSONException { + String json_file_content = getStringFromProvider(json_url); return new JSONObject(json_file_content); } diff --git a/src/se/leap/leapclient/ProviderListActivity.java b/src/se/leap/leapclient/ProviderListActivity.java index 088b464d..808c12ce 100644 --- a/src/se/leap/leapclient/ProviderListActivity.java +++ b/src/se/leap/leapclient/ProviderListActivity.java @@ -1,9 +1,11 @@ package se.leap.leapclient; import java.io.BufferedInputStream; +import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; @@ -11,6 +13,9 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.Scanner; +import org.json.JSONException; +import org.json.JSONObject; + import se.leap.leapclient.ProviderListContent; import se.leap.leapclient.ProviderListContent.ProviderItem; import android.app.DownloadManager; @@ -103,6 +108,7 @@ public class ProviderListActivity extends FragmentActivity if(current_provider_item.id.equalsIgnoreCase(id)) { try { + processAssetsFiles(current_provider_item); downloadJSONFiles(current_provider_item); } catch (IOException e) { // TODO Auto-generated catch block @@ -116,12 +122,27 @@ public class ProviderListActivity extends FragmentActivity } } + private void processAssetsFiles(ProviderItem current_provider_item) { + AssetManager assets_manager = getAssets(); + JSONObject provider_json = new JSONObject(); + try { + String provider_contents = new Scanner(new InputStreamReader(assets_manager.open(current_provider_item.provider_json_assets))).useDelimiter("\\A").next(); + provider_json = new JSONObject(provider_contents); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JSONException e) { + ConfigHelper.rescueJSONException(e); + } + ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); + } + private void downloadJSONFiles(ProviderItem current_provider_item) throws IOException { Intent provider_API_command = new Intent(this, ProviderAPI.class); Bundle method_and_parameters = new Bundle(); - method_and_parameters.putString("provider", current_provider_item.provider_json_url); - method_and_parameters.putString("eip", current_provider_item.eip_service_json_url); + method_and_parameters.putString(ConfigHelper.cert_key, current_provider_item.cert_json_url); + method_and_parameters.putString(ConfigHelper.eip_service_key, current_provider_item.eip_service_json_url); provider_API_command.putExtra(ConfigHelper.downloadJsonFilesBundleExtra, method_and_parameters); diff --git a/src/se/leap/leapclient/ProviderListContent.java b/src/se/leap/leapclient/ProviderListContent.java index 1fe60159..bf8bfa87 100644 --- a/src/se/leap/leapclient/ProviderListContent.java +++ b/src/se/leap/leapclient/ProviderListContent.java @@ -39,14 +39,17 @@ public class ProviderListContent { public String id; public String name; public String provider_json_url; + public String provider_json_assets; public String eip_service_json_url; + public String cert_json_url; - public ProviderItem(String id, String name, String provider_json_url, String eip_service_json_url) { + public ProviderItem(String id, String name, String provider_json_url, String eip_service_json_url, String cert_json_url) { this.id = id; this.name = name; this.provider_json_url = provider_json_url; this.eip_service_json_url = eip_service_json_url; + this.cert_json_url = cert_json_url; } public ProviderItem(String name, InputStream urls_file_input_stream) { @@ -59,7 +62,9 @@ public class ProviderListContent { id = name; this.name = name; provider_json_url = (String) file_contents.get("json_provider"); + provider_json_assets = (String) file_contents.get("assets_json_provider"); eip_service_json_url = (String) file_contents.get("json_eip_service"); + cert_json_url = (String) file_contents.get("cert"); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); -- cgit v1.2.3 From 2fecc0d022e2d3022572c21f14605ee917f71cff Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Tue, 5 Feb 2013 17:30:16 -0700 Subject: Change access modifiers of some functions in Provider.class from public to protected --- src/se/leap/leapclient/Provider.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/se/leap/leapclient/Provider.java b/src/se/leap/leapclient/Provider.java index a25909bf..b5e81c9d 100644 --- a/src/se/leap/leapclient/Provider.java +++ b/src/se/leap/leapclient/Provider.java @@ -109,7 +109,7 @@ final class Provider implements Serializable { return desc; } - public boolean hasEIP() { + protected boolean hasEIP() { JSONArray services = null; try { services = definition.getJSONArray(API_TERM_SERVICES); // returns ["openvpn"] @@ -128,7 +128,7 @@ final class Provider implements Serializable { return false; } - public String getEIPType() { + protected String getEIPType() { // FIXME!!!!! We won't always be providing /only/ OpenVPN, will we? // This will have to hook into some saved choice of EIP transport if ( instance.hasEIP() ) @@ -137,7 +137,7 @@ final class Provider implements Serializable { return null; } - public JSONObject getEIP() { + protected JSONObject getEIP() { // FIXME!!!!! We won't always be providing /only/ OpenVPN, will we? // This will have to hook into some saved choice of EIP transport, cluster, gateway // with possible "choose at random" preference -- cgit v1.2.3 From b4fddc796c11a4da7a81b044857d82d516531095 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Tue, 5 Feb 2013 17:31:01 -0700 Subject: Comments regarding TODOs for changes to ProviderListActivity --- src/se/leap/leapclient/ProviderListActivity.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/se/leap/leapclient/ProviderListActivity.java b/src/se/leap/leapclient/ProviderListActivity.java index 808c12ce..3b1d78e2 100644 --- a/src/se/leap/leapclient/ProviderListActivity.java +++ b/src/se/leap/leapclient/ProviderListActivity.java @@ -96,7 +96,7 @@ public class ProviderListActivity extends FragmentActivity @Override public void onItemSelected(String id) { if (mTwoPane) { - + // TODO Hmmm...is this how we should do this? What if it /is/ two pane? } else { // In single-pane mode, simply start the detail activity // for the selected item ID. @@ -109,6 +109,7 @@ public class ProviderListActivity extends FragmentActivity { try { processAssetsFiles(current_provider_item); + // TODO ask Provider class to save provider.json, setResult(OK), finish() to ConfigurationWizard downloadJSONFiles(current_provider_item); } catch (IOException e) { // TODO Auto-generated catch block -- cgit v1.2.3 From 7cd61e51f9f50b2a8f8258ee829ae313281e5f4b Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Tue, 5 Feb 2013 17:50:16 -0700 Subject: Removed bad .classpath build path requirement of Windows Android support sdk --- .classpath | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.classpath b/.classpath index a5824471..177f415d 100644 --- a/.classpath +++ b/.classpath @@ -1,9 +1,8 @@ - - - - - - - - - + + + + + + + + -- cgit v1.2.3 From 72fd6621a988fcc25d1fa93b977cb7d0a88c96d6 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Tue, 5 Feb 2013 17:51:24 -0700 Subject: Clean up unused imports --- src/se/leap/leapclient/Dashboard.java | 5 ----- src/se/leap/leapclient/ProviderAPI.java | 1 - src/se/leap/leapclient/ProviderListActivity.java | 14 -------------- 3 files changed, 20 deletions(-) diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index 3f32bde3..c3c6a07f 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -1,9 +1,5 @@ package se.leap.leapclient; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - import se.leap.openvpn.AboutFragment; import se.leap.openvpn.MainActivity; import android.app.Activity; @@ -11,7 +7,6 @@ import android.app.Fragment; import android.app.FragmentTransaction; import android.content.Intent; import android.content.SharedPreferences; -import android.content.res.AssetManager; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; diff --git a/src/se/leap/leapclient/ProviderAPI.java b/src/se/leap/leapclient/ProviderAPI.java index 33f7fd74..5a8f9572 100644 --- a/src/se/leap/leapclient/ProviderAPI.java +++ b/src/se/leap/leapclient/ProviderAPI.java @@ -5,7 +5,6 @@ import java.util.Scanner; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.JSONException; diff --git a/src/se/leap/leapclient/ProviderListActivity.java b/src/se/leap/leapclient/ProviderListActivity.java index 3b1d78e2..972e2bf0 100644 --- a/src/se/leap/leapclient/ProviderListActivity.java +++ b/src/se/leap/leapclient/ProviderListActivity.java @@ -1,32 +1,18 @@ package se.leap.leapclient; -import java.io.BufferedInputStream; -import java.io.BufferedReader; -import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; import java.util.Iterator; import java.util.Scanner; import org.json.JSONException; import org.json.JSONObject; -import se.leap.leapclient.ProviderListContent; import se.leap.leapclient.ProviderListContent.ProviderItem; -import android.app.DownloadManager; -import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.AssetManager; -import android.net.Uri; -import android.os.Build; import android.os.Bundle; -import android.os.Environment; import android.support.v4.app.FragmentActivity; -- cgit v1.2.3 From 6e0142a335eafe8a9b0e41b0e968038c0aeabd11 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Thu, 7 Feb 2013 01:33:03 -0700 Subject: Refactor ProviderListActivity.class into ConfigurationWizard.class, Moves towards our wizard flow; Addresses #1497 #1500 --- AndroidManifest.xml | 8 +- res/layout/activity_configuration_wizard.xml | 8 ++ res/menu/activity_configuration_wizard.xml | 9 ++ res/values/strings.xml | 1 + src/se/leap/leapclient/ConfigHelper.java | 4 +- src/se/leap/leapclient/ConfigurationWizard.java | 153 +++++++++++++++++++++++ src/se/leap/leapclient/ProviderListActivity.java | 139 -------------------- src/se/leap/leapclient/ProviderListFragment.java | 4 +- 8 files changed, 176 insertions(+), 150 deletions(-) create mode 100644 res/layout/activity_configuration_wizard.xml create mode 100644 res/menu/activity_configuration_wizard.xml create mode 100644 src/se/leap/leapclient/ConfigurationWizard.java delete mode 100644 src/se/leap/leapclient/ProviderListActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 48ccbda4..56ca7d44 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -152,13 +152,9 @@ - - - - + android:name="se.leap.leapclient.ConfigurationWizard" + android:label="@string/title_activity_configuration_wizard" > diff --git a/res/layout/activity_configuration_wizard.xml b/res/layout/activity_configuration_wizard.xml new file mode 100644 index 00000000..264ccf98 --- /dev/null +++ b/res/layout/activity_configuration_wizard.xml @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/res/menu/activity_configuration_wizard.xml b/res/menu/activity_configuration_wizard.xml new file mode 100644 index 00000000..77f358b6 --- /dev/null +++ b/res/menu/activity_configuration_wizard.xml @@ -0,0 +1,9 @@ +

+ + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 09252355..1a453fa9 100755 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -260,5 +260,6 @@ Access EIP connection settings Status unknown EIP + Configure LEAP
\ No newline at end of file diff --git a/src/se/leap/leapclient/ConfigHelper.java b/src/se/leap/leapclient/ConfigHelper.java index be848db0..b2baed67 100644 --- a/src/se/leap/leapclient/ConfigHelper.java +++ b/src/se/leap/leapclient/ConfigHelper.java @@ -15,7 +15,7 @@ public class ConfigHelper { static void saveSharedPref(String shared_preferences_key, JSONObject content) { - SharedPreferences.Editor shared_preferences_editor = ProviderListActivity.shared_preferences + SharedPreferences.Editor shared_preferences_editor = ConfigurationWizard.shared_preferences .edit(); shared_preferences_editor.putString(shared_preferences_key, content.toString()); @@ -23,7 +23,7 @@ public class ConfigHelper { System.out.println("Shared preferences updated: key = " + shared_preferences_key + " Content = " - + ProviderListActivity.shared_preferences.getString( + + ConfigurationWizard.shared_preferences.getString( shared_preferences_key, "Default")); } diff --git a/src/se/leap/leapclient/ConfigurationWizard.java b/src/se/leap/leapclient/ConfigurationWizard.java new file mode 100644 index 00000000..6a7bd10c --- /dev/null +++ b/src/se/leap/leapclient/ConfigurationWizard.java @@ -0,0 +1,153 @@ +package se.leap.leapclient; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Iterator; +import java.util.Scanner; + +import org.json.JSONException; +import org.json.JSONObject; + +import se.leap.leapclient.ProviderListContent.ProviderItem; +import android.app.Activity; +import android.app.FragmentManager; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.AssetManager; +import android.os.Bundle; + + +/** + * An activity representing a list of Providers. This activity + * has different presentations for handset and tablet-size devices. On + * handsets, the activity presents a list of items, which when touched, + * lead to a {@link DashboardActivity} representing + * item details. On tablets, the activity presents the list of items and + * item details side-by-side using two vertical panes. + *

+ * The activity makes heavy use of fragments. The list of items is a + * {@link ProviderListFragment} and the item details + * (if present) is a {@link DashboardFragment}. + *

+ * This activity also implements the required + * {@link ProviderListFragment.Callbacks} interface + * to listen for item selections. + */ +public class ConfigurationWizard extends Activity + implements ProviderListFragment.Callbacks { + + /** + * Whether or not the activity is in two-pane mode, i.e. running on a tablet + * device. + */ + private boolean mTwoPane; + + static SharedPreferences shared_preferences; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_configuration_wizard); + + shared_preferences = getSharedPreferences(ConfigHelper.PREFERENCES_KEY,MODE_PRIVATE); + + loadPreseededProviders(); + + // Only create our fragments if we're not restoring a saved instance + if ( savedInstanceState == null ){ + // TODO Some welcome screen? + // We will need better flow control when we have more Fragments (e.g. user auth) + ProviderListFragment providerList = new ProviderListFragment(); + + FragmentManager fragmentManager = getFragmentManager(); + fragmentManager.beginTransaction() + .add(R.id.configuration_wizard_layout, providerList, "providerlist") + .commit(); + } + + // TODO: If exposing deep links into your app, handle intents here. + } + + private void loadPreseededProviders() { + AssetManager asset_manager = getAssets(); + String[] urls_filepaths = null; + try { + String url_files_folder = "urls"; + //TODO Put that folder in a better place (also inside the "for") + urls_filepaths = asset_manager.list(url_files_folder); + String provider_name = ""; + for(String url_filepath : urls_filepaths) + { + provider_name = url_filepath.subSequence(0, url_filepath.indexOf(".")).toString(); + if(ProviderListContent.ITEMS.isEmpty()) //TODO I have to implement a way of checking if a provider new or is already present in that ITEMS list + ProviderListContent.addItem(new ProviderItem(provider_name, asset_manager.open(url_files_folder + "/" + url_filepath))); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * Callback method from {@link ProviderListFragment.Callbacks} + * indicating that the item with the given ID was selected. + */ + @Override + public void onItemSelected(String id) { + if (mTwoPane) { + // TODO Hmmm...is this how we should do this? What if it /is/ two pane? + } else { + // In single-pane mode, simply start the detail activity + // for the selected item ID. + + Iterator preseeded_providers_iterator = ProviderListContent.ITEMS.iterator(); + while(preseeded_providers_iterator.hasNext()) + { + ProviderItem current_provider_item = preseeded_providers_iterator.next(); + if(current_provider_item.id.equalsIgnoreCase(id)) + { + try { + processAssetsFiles(current_provider_item); + // TODO ask Provider class to save provider.json, setResult(OK), finish() to ConfigurationWizard + downloadJSONFiles(current_provider_item); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + Intent dashboardIntent = new Intent(this, Dashboard.class); + startActivity(dashboardIntent); + } + } + + private void processAssetsFiles(ProviderItem current_provider_item) { + AssetManager assets_manager = getAssets(); + JSONObject provider_json = new JSONObject(); + try { + String provider_contents = new Scanner(new InputStreamReader(assets_manager.open(current_provider_item.provider_json_assets))).useDelimiter("\\A").next(); + provider_json = new JSONObject(provider_contents); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JSONException e) { + ConfigHelper.rescueJSONException(e); + } + ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); + } + + private void downloadJSONFiles(ProviderItem current_provider_item) throws IOException { + Intent provider_API_command = new Intent(this, ProviderAPI.class); + + Bundle method_and_parameters = new Bundle(); + method_and_parameters.putString(ConfigHelper.cert_key, current_provider_item.cert_json_url); + method_and_parameters.putString(ConfigHelper.eip_service_key, current_provider_item.eip_service_json_url); + + provider_API_command.putExtra(ConfigHelper.downloadJsonFilesBundleExtra, method_and_parameters); + + startService(provider_API_command); + + } +} diff --git a/src/se/leap/leapclient/ProviderListActivity.java b/src/se/leap/leapclient/ProviderListActivity.java deleted file mode 100644 index 972e2bf0..00000000 --- a/src/se/leap/leapclient/ProviderListActivity.java +++ /dev/null @@ -1,139 +0,0 @@ -package se.leap.leapclient; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Iterator; -import java.util.Scanner; - -import org.json.JSONException; -import org.json.JSONObject; - -import se.leap.leapclient.ProviderListContent.ProviderItem; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.AssetManager; -import android.os.Bundle; -import android.support.v4.app.FragmentActivity; - - -/** - * An activity representing a list of Providers. This activity - * has different presentations for handset and tablet-size devices. On - * handsets, the activity presents a list of items, which when touched, - * lead to a {@link DashboardActivity} representing - * item details. On tablets, the activity presents the list of items and - * item details side-by-side using two vertical panes. - *

- * The activity makes heavy use of fragments. The list of items is a - * {@link ProviderListFragment} and the item details - * (if present) is a {@link DashboardFragment}. - *

- * This activity also implements the required - * {@link ProviderListFragment.Callbacks} interface - * to listen for item selections. - */ -public class ProviderListActivity extends FragmentActivity - implements ProviderListFragment.Callbacks { - - /** - * Whether or not the activity is in two-pane mode, i.e. running on a tablet - * device. - */ - private boolean mTwoPane; - - static SharedPreferences shared_preferences; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_provider_list); - - shared_preferences = getPreferences(MODE_PRIVATE); - - loadPreseededProviders(); - - // TODO: If exposing deep links into your app, handle intents here. - } - - private void loadPreseededProviders() { - AssetManager asset_manager = getAssets(); - String[] urls_filepaths = null; - try { - String url_files_folder = "urls"; - //TODO Put that folder in a better place (also inside the "for") - urls_filepaths = asset_manager.list(url_files_folder); - String provider_name = ""; - for(String url_filepath : urls_filepaths) - { - provider_name = url_filepath.subSequence(0, url_filepath.indexOf(".")).toString(); - if(ProviderListContent.ITEMS.isEmpty()) //TODO I have to implement a way of checking if a provider new or is already present in that ITEMS list - ProviderListContent.addItem(new ProviderItem(provider_name, asset_manager.open(url_files_folder + "/" + url_filepath))); - } - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - /** - * Callback method from {@link ProviderListFragment.Callbacks} - * indicating that the item with the given ID was selected. - */ - @Override - public void onItemSelected(String id) { - if (mTwoPane) { - // TODO Hmmm...is this how we should do this? What if it /is/ two pane? - } else { - // In single-pane mode, simply start the detail activity - // for the selected item ID. - - Iterator preseeded_providers_iterator = ProviderListContent.ITEMS.iterator(); - while(preseeded_providers_iterator.hasNext()) - { - ProviderItem current_provider_item = preseeded_providers_iterator.next(); - if(current_provider_item.id.equalsIgnoreCase(id)) - { - try { - processAssetsFiles(current_provider_item); - // TODO ask Provider class to save provider.json, setResult(OK), finish() to ConfigurationWizard - downloadJSONFiles(current_provider_item); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - - Intent dashboardIntent = new Intent(this, Dashboard.class); - startActivity(dashboardIntent); - } - } - - private void processAssetsFiles(ProviderItem current_provider_item) { - AssetManager assets_manager = getAssets(); - JSONObject provider_json = new JSONObject(); - try { - String provider_contents = new Scanner(new InputStreamReader(assets_manager.open(current_provider_item.provider_json_assets))).useDelimiter("\\A").next(); - provider_json = new JSONObject(provider_contents); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (JSONException e) { - ConfigHelper.rescueJSONException(e); - } - ConfigHelper.saveSharedPref(ConfigHelper.provider_key, provider_json); - } - - private void downloadJSONFiles(ProviderItem current_provider_item) throws IOException { - Intent provider_API_command = new Intent(this, ProviderAPI.class); - - Bundle method_and_parameters = new Bundle(); - method_and_parameters.putString(ConfigHelper.cert_key, current_provider_item.cert_json_url); - method_and_parameters.putString(ConfigHelper.eip_service_key, current_provider_item.eip_service_json_url); - - provider_API_command.putExtra(ConfigHelper.downloadJsonFilesBundleExtra, method_and_parameters); - - startService(provider_API_command); - - } -} diff --git a/src/se/leap/leapclient/ProviderListFragment.java b/src/se/leap/leapclient/ProviderListFragment.java index 717a65c1..d83a7bc1 100644 --- a/src/se/leap/leapclient/ProviderListFragment.java +++ b/src/se/leap/leapclient/ProviderListFragment.java @@ -1,14 +1,12 @@ package se.leap.leapclient; import android.app.Activity; +import android.app.ListFragment; import android.os.Bundle; -import android.support.v4.app.ListFragment; import android.view.View; import android.widget.ArrayAdapter; import android.widget.ListView; -import se.leap.leapclient.ProviderListContent; - /** * A list fragment representing a list of Providers. This fragment * also supports tablet devices by allowing list items to be given an -- cgit v1.2.3 From c107e15a1ca7707a7c2351a3c31f3dbd9f156b73 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Thu, 7 Feb 2013 01:34:49 -0700 Subject: Rearrange singleton Provider.class pattern, Fix isolated SharedPreferences silos --- src/se/leap/leapclient/ConfigHelper.java | 1 + src/se/leap/leapclient/Dashboard.java | 5 +++-- src/se/leap/leapclient/Provider.java | 21 +++++++++++++-------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/se/leap/leapclient/ConfigHelper.java b/src/se/leap/leapclient/ConfigHelper.java index b2baed67..eded2504 100644 --- a/src/se/leap/leapclient/ConfigHelper.java +++ b/src/se/leap/leapclient/ConfigHelper.java @@ -12,6 +12,7 @@ public class ConfigHelper { final static String provider_key = "provider"; final static String cert_key = "cert"; final static String eip_service_key = "eip"; + public static final String PREFERENCES_KEY = "LEAPPreferences"; static void saveSharedPref(String shared_preferences_key, JSONObject content) { diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index c3c6a07f..b6110aac 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -29,7 +29,7 @@ public class Dashboard extends Activity { super.onCreate(savedInstanceState); setContentView(R.layout.client_dashboard); - preferences = getPreferences(MODE_PRIVATE); + preferences = getSharedPreferences(ConfigHelper.PREFERENCES_KEY,MODE_PRIVATE); // Check if we have preferences, run configuration wizard if not // TODO We should do a better check for config that this! @@ -42,7 +42,8 @@ public class Dashboard extends Activity { private void buildDashboard() { // Get our provider - provider = Provider.getInstance(preferences); + provider = Provider.getInstance(); + provider.init( this ); // Set provider name in textview providerNameTV = (TextView) findViewById(R.id.providerName); diff --git a/src/se/leap/leapclient/Provider.java b/src/se/leap/leapclient/Provider.java index b5e81c9d..4235acfd 100644 --- a/src/se/leap/leapclient/Provider.java +++ b/src/se/leap/leapclient/Provider.java @@ -11,6 +11,7 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import android.app.Activity; import android.content.SharedPreferences; /** @@ -49,13 +50,24 @@ final class Provider implements Serializable { /** * */ - private Provider(SharedPreferences preferences) { + private Provider() {} + + protected static Provider getInstance(){ + if(instance==null){ + instance = new Provider(); + } + return instance; + } + + protected void init(Activity activity) { // Load our preferences from SharedPreferences // If there's nothing there, we will end up returning a rather empty object // to whoever called getInstance() and they can run the First Run Wizard //preferences = context.getgetPreferences(0); // 0 == MODE_PRIVATE, but we don't extend Android's classes... + // Load SharedPreferences + preferences = activity.getSharedPreferences(ConfigHelper.PREFERENCES_KEY,0); // We don't get MODE_PRIVATE by importing SharedPreferences; i guess it's in Activity? // Inflate our provider.json data try { definition = new JSONObject( preferences.getString("provider", "") ); @@ -66,13 +78,6 @@ final class Provider implements Serializable { } } - protected static Provider getInstance(SharedPreferences preferences){ - if(instance==null){ - instance = new Provider(preferences); - } - return instance; - } - protected String getName(){ // Should we pass the locale in, or query the system here? String lang = Locale.getDefault().getLanguage(); -- cgit v1.2.3 From baaf0fec8894513768f0ba3406a9dfe2d7ad2775 Mon Sep 17 00:00:00 2001 From: Sean Leonard Date: Thu, 7 Feb 2013 01:36:14 -0700 Subject: Change in Dashboard to startActivityForResult() ConfigurationWizard --- src/se/leap/leapclient/ConfigurationWizard.java | 6 ++++-- src/se/leap/leapclient/Dashboard.java | 20 ++++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/se/leap/leapclient/ConfigurationWizard.java b/src/se/leap/leapclient/ConfigurationWizard.java index 6a7bd10c..f759b37e 100644 --- a/src/se/leap/leapclient/ConfigurationWizard.java +++ b/src/se/leap/leapclient/ConfigurationWizard.java @@ -118,8 +118,10 @@ public class ConfigurationWizard extends Activity } } - Intent dashboardIntent = new Intent(this, Dashboard.class); - startActivity(dashboardIntent); + // FIXME!! We're going to have more Fragments and listeners, flow control? + // TODO There is no testing done to know if we're okay... + setResult(RESULT_OK); + finish(); } } diff --git a/src/se/leap/leapclient/Dashboard.java b/src/se/leap/leapclient/Dashboard.java index b6110aac..dce99b1e 100644 --- a/src/se/leap/leapclient/Dashboard.java +++ b/src/se/leap/leapclient/Dashboard.java @@ -18,6 +18,8 @@ import android.widget.TextView; public class Dashboard extends Activity { + protected static final int CONFIGURE_LEAP = 0; + private static SharedPreferences preferences; private static Provider provider; @@ -34,11 +36,25 @@ public class Dashboard extends Activity { // Check if we have preferences, run configuration wizard if not // TODO We should do a better check for config that this! if (!preferences.contains("provider") ) - startActivity(new Intent(this, ProviderListActivity.class)); + startActivityForResult(new Intent(this,ConfigurationWizard.class),CONFIGURE_LEAP); else buildDashboard(); } - + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data){ + if ( requestCode == CONFIGURE_LEAP ) { + if ( resultCode == RESULT_OK ){ + // Configuration done, get our preferences again + preferences = getSharedPreferences(ConfigHelper.PREFERENCES_KEY,MODE_PRIVATE); + + buildDashboard(); + } else { + // Something went wrong... TODO figure out what + // TODO Error dialog + } + } + } private void buildDashboard() { // Get our provider -- cgit v1.2.3 From e3acc71aaedfcf97b2adee907b6587e3c1eadf48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Thu, 7 Feb 2013 21:25:58 +0100 Subject: Button not working from ConfigurationWizard. Trying to test cancel button from created new dialog. --- res/layout/activity_configuration_wizard.xml | 11 +++++++++ res/values/strings.xml | 3 +++ src/se/leap/leapclient/ConfigurationWizard.java | 18 ++++++++++++++ src/se/leap/leapclient/NewProviderDialog.java | 32 +++++++++++++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 src/se/leap/leapclient/NewProviderDialog.java diff --git a/res/layout/activity_configuration_wizard.xml b/res/layout/activity_configuration_wizard.xml index 264ccf98..7a0823d9 100644 --- a/res/layout/activity_configuration_wizard.xml +++ b/res/layout/activity_configuration_wizard.xml @@ -5,4 +5,15 @@ android:layout_height="match_parent" tools:context=".ConfigurationWizard" > +