diff --git a/qt/i2pd_qt/android/.gitignore b/qt/i2pd_qt/android/.gitignore deleted file mode 100644 index 2c41ac3e..00000000 --- a/qt/i2pd_qt/android/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/gen/ diff --git a/qt/i2pd_qt/android/AndroidManifest.xml b/qt/i2pd_qt/android/AndroidManifest.xml deleted file mode 100644 index 8eb723e7..00000000 --- a/qt/i2pd_qt/android/AndroidManifest.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/qt/i2pd_qt/android/build.gradle b/qt/i2pd_qt/android/build.gradle deleted file mode 100644 index ef416b0b..00000000 --- a/qt/i2pd_qt/android/build.gradle +++ /dev/null @@ -1,57 +0,0 @@ -buildscript { - repositories { - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:1.1.0' - } -} - -allprojects { - repositories { - jcenter() - } -} - -apply plugin: 'com.android.application' - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) -} - -android { - /******************************************************* - * The following variables: - * - androidBuildToolsVersion, - * - androidCompileSdkVersion - * - qt5AndroidDir - holds the path to qt android files - * needed to build any Qt application - * on Android. - * - * are defined in gradle.properties file. This file is - * updated by QtCreator and androiddeployqt tools. - * Changing them manually might break the compilation! - *******************************************************/ - - compileSdkVersion androidCompileSdkVersion.toInteger() - - buildToolsVersion androidBuildToolsVersion - - sourceSets { - main { - manifest.srcFile 'AndroidManifest.xml' - java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java'] - aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl'] - res.srcDirs = [qt5AndroidDir + '/res', 'res'] - resources.srcDirs = ['src'] - renderscript.srcDirs = ['src'] - assets.srcDirs = ['assets'] - jniLibs.srcDirs = ['libs'] - } - } - - lintOptions { - abortOnError false - } -} diff --git a/qt/i2pd_qt/android/libs/android-support-v4.jar b/qt/i2pd_qt/android/libs/android-support-v4.jar deleted file mode 100644 index 2ff47f4f..00000000 Binary files a/qt/i2pd_qt/android/libs/android-support-v4.jar and /dev/null differ diff --git a/qt/i2pd_qt/android/project.properties b/qt/i2pd_qt/android/project.properties deleted file mode 100644 index 4d07452b..00000000 --- a/qt/i2pd_qt/android/project.properties +++ /dev/null @@ -1,14 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system edit -# "ant.properties", and override values to adapt the script to your -# project structure. -# -# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): -#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt - -# Project target. -target=android-11 diff --git a/qt/i2pd_qt/android/res/drawable-hdpi/icon.png b/qt/i2pd_qt/android/res/drawable-hdpi/icon.png deleted file mode 100644 index 9a2f7404..00000000 Binary files a/qt/i2pd_qt/android/res/drawable-hdpi/icon.png and /dev/null differ diff --git a/qt/i2pd_qt/android/res/drawable/itoopie_notification_icon.png b/qt/i2pd_qt/android/res/drawable/itoopie_notification_icon.png deleted file mode 100644 index fa99e7fc..00000000 Binary files a/qt/i2pd_qt/android/res/drawable/itoopie_notification_icon.png and /dev/null differ diff --git a/qt/i2pd_qt/android/res/layout/splash.xml b/qt/i2pd_qt/android/res/layout/splash.xml deleted file mode 100644 index 476d91a8..00000000 --- a/qt/i2pd_qt/android/res/layout/splash.xml +++ /dev/null @@ -1,4 +0,0 @@ - - diff --git a/qt/i2pd_qt/android/res/values-de/strings.xml b/qt/i2pd_qt/android/res/values-de/strings.xml deleted file mode 100644 index 320d9ec3..00000000 --- a/qt/i2pd_qt/android/res/values-de/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Ministro-Dienst wurde nicht gefunden.\nAnwendung kann nicht gestartet werden - Diese Anwendung benötigt den Ministro-Dienst. Möchten Sie ihn installieren? - In Ihrer Anwendung ist ein schwerwiegender Fehler aufgetreten, sie kann nicht fortgesetzt werden - diff --git a/qt/i2pd_qt/android/res/values-el/strings.xml b/qt/i2pd_qt/android/res/values-el/strings.xml deleted file mode 100644 index 3cab212f..00000000 --- a/qt/i2pd_qt/android/res/values-el/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Δεν ήταν δυνατή η εύρεση της υπηρεσίας Ministro. Δεν είναι δυνατή η εκκίνηση της εφαρμογής. - Η εφαρμογή απαιτεί την υπηρεσία Ministro. Να εγκατασταθεί η υπηρεσία? - Παρουσιάστηκε ένα κρίσιμο σφάλμα και η εφαρμογή δεν μπορεί να συνεχίσει. - diff --git a/qt/i2pd_qt/android/res/values-es/strings.xml b/qt/i2pd_qt/android/res/values-es/strings.xml deleted file mode 100644 index cf0b54d0..00000000 --- a/qt/i2pd_qt/android/res/values-es/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Servicio Ministro inesistente. Imposible ejecutar la aplicación. - Esta aplicación requiere el servicio Ministro. Instalarlo? - La aplicación ha causado un error grave y no es posible continuar. - diff --git a/qt/i2pd_qt/android/res/values-et/strings.xml b/qt/i2pd_qt/android/res/values-et/strings.xml deleted file mode 100644 index d55a3c14..00000000 --- a/qt/i2pd_qt/android/res/values-et/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Ei suuda leida Ministro teenust.\nProgrammi ei saa käivitada. - See programm vajab Ministro teenust.\nKas soovite paigaldada? - Programmiga juhtus fataalne viga.\nKahjuks ei saa jätkata. - diff --git a/qt/i2pd_qt/android/res/values-fa/strings.xml b/qt/i2pd_qt/android/res/values-fa/strings.xml deleted file mode 100644 index a8d1b874..00000000 --- a/qt/i2pd_qt/android/res/values-fa/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - سرویس Ministro را پیدا نمی‌کند. برنامه نمی‌تواند آغاز شود. - این نرم‌افزار به سرویس Ministro احتیاج دارد. آیا دوست دارید آن را نصب کنید؟ - خطایی اساسی در برنامه‌تان رخ داد و اجرای برنامه نمی‌تواند ادامه یابد. - diff --git a/qt/i2pd_qt/android/res/values-fr/strings.xml b/qt/i2pd_qt/android/res/values-fr/strings.xml deleted file mode 100644 index efc0fb6e..00000000 --- a/qt/i2pd_qt/android/res/values-fr/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Le service Ministro est introuvable.\nL\'application ne peut pas démarrer. - Cette application requiert le service Ministro. Voulez-vous l\'installer? - Votre application a rencontré une erreur fatale et ne peut pas continuer. - diff --git a/qt/i2pd_qt/android/res/values-id/strings.xml b/qt/i2pd_qt/android/res/values-id/strings.xml deleted file mode 100644 index aaa5bda0..00000000 --- a/qt/i2pd_qt/android/res/values-id/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Layanan Ministro tidak bisa ditemukan.\nAplikasi tidak bisa dimulai. - Aplikasi ini membutuhkan layanan Ministro. Apakah Anda ingin menginstalnya? - Aplikasi Anda mengalami kesalahan fatal dan tidak dapat melanjutkan. - diff --git a/qt/i2pd_qt/android/res/values-it/strings.xml b/qt/i2pd_qt/android/res/values-it/strings.xml deleted file mode 100644 index 4773419c..00000000 --- a/qt/i2pd_qt/android/res/values-it/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Servizio Ministro inesistente. Impossibile eseguire \nl\'applicazione. - Questa applicazione richiede il servizio Ministro.Installarlo? - L\'applicazione ha provocato un errore grave e non puo\' continuare. - diff --git a/qt/i2pd_qt/android/res/values-ja/strings.xml b/qt/i2pd_qt/android/res/values-ja/strings.xml deleted file mode 100644 index ba1cfda9..00000000 --- a/qt/i2pd_qt/android/res/values-ja/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Ministroサービスが見つかりません。\nアプリケーションが起動できません。 - このアプリケーションにはMinistroサービスが必要です。 インストールしてもよろしいですか? - アプリケーションで致命的なエラーが発生したため続行できません。 - diff --git a/qt/i2pd_qt/android/res/values-ms/strings.xml b/qt/i2pd_qt/android/res/values-ms/strings.xml deleted file mode 100644 index 6e3952ea..00000000 --- a/qt/i2pd_qt/android/res/values-ms/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Tidak jumpa servis Ministro.\nAplikasi tidak boleh dimulakan. - Aplikasi ini memerlukan servis Ministro. Adakah anda ingin pasang servis itu? - Aplikasi anda menemui ralat muat dan tidak boleh diteruskan. - diff --git a/qt/i2pd_qt/android/res/values-nb/strings.xml b/qt/i2pd_qt/android/res/values-nb/strings.xml deleted file mode 100644 index 8a550e99..00000000 --- a/qt/i2pd_qt/android/res/values-nb/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Kan ikke finne tjenesten Ministro. Applikasjonen kan ikke starte. - Denne applikasjonen krever tjenesten Ministro. Vil du installere denne? - Applikasjonen fikk en kritisk feil og kan ikke fortsette - diff --git a/qt/i2pd_qt/android/res/values-nl/strings.xml b/qt/i2pd_qt/android/res/values-nl/strings.xml deleted file mode 100644 index 8a45a724..00000000 --- a/qt/i2pd_qt/android/res/values-nl/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - De Ministro service is niet gevonden.\nDe applicatie kan niet starten. - Deze applicatie maakt gebruik van de Ministro service. Wilt u deze installeren? - Er is een fatale fout in de applicatie opgetreden. De applicatie kan niet verder gaan. - diff --git a/qt/i2pd_qt/android/res/values-pl/strings.xml b/qt/i2pd_qt/android/res/values-pl/strings.xml deleted file mode 100644 index 9fefc92d..00000000 --- a/qt/i2pd_qt/android/res/values-pl/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Usługa Ministro nie została znaleziona.\nAplikacja nie może zostać uruchomiona. - Aplikacja wymaga usługi Ministro. Czy chcesz ją zainstalować? - Wystąpił błąd krytyczny. Aplikacja zostanie zamknięta. - diff --git a/qt/i2pd_qt/android/res/values-pt-rBR/strings.xml b/qt/i2pd_qt/android/res/values-pt-rBR/strings.xml deleted file mode 100644 index 67ac3f9f..00000000 --- a/qt/i2pd_qt/android/res/values-pt-rBR/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Não foi possível encontrar o serviço Ministro.\nA aplicação não pode iniciar. - Essa aplicação requer o serviço Ministro. Gostaria de instalá-lo? - Sua aplicação encontrou um erro fatal e não pode continuar. - diff --git a/qt/i2pd_qt/android/res/values-ro/strings.xml b/qt/i2pd_qt/android/res/values-ro/strings.xml deleted file mode 100644 index f88a442b..00000000 --- a/qt/i2pd_qt/android/res/values-ro/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Serviciul Ministro nu poate fi găsit.\nAplicaţia nu poate porni. - Această aplicaţie necesită serviciul Ministro.\nDoriţi să-l instalaţi? - Aplicaţia dumneavoastră a întâmpinat o eroare fatală şi nu poate continua. - diff --git a/qt/i2pd_qt/android/res/values-rs/strings.xml b/qt/i2pd_qt/android/res/values-rs/strings.xml deleted file mode 100644 index 3194ce90..00000000 --- a/qt/i2pd_qt/android/res/values-rs/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Ministro servise nije pronađen. Aplikacija ne može biti pokrenuta. - Ova aplikacija zahteva Ministro servis. Želite li da ga instalirate? - Vaša aplikacija je naišla na fatalnu grešku i ne može nastaviti sa radom. - diff --git a/qt/i2pd_qt/android/res/values-ru/strings.xml b/qt/i2pd_qt/android/res/values-ru/strings.xml deleted file mode 100644 index d3cee80f..00000000 --- a/qt/i2pd_qt/android/res/values-ru/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - Сервис Ministro не найден.\nПриложение нельзя запустить. - Этому приложению необходим сервис Ministro. Вы хотите его установить? - Ваше приложение столкнулось с фатальной ошибкой и не может более работать. - diff --git a/qt/i2pd_qt/android/res/values-zh-rCN/strings.xml b/qt/i2pd_qt/android/res/values-zh-rCN/strings.xml deleted file mode 100644 index 2eb12698..00000000 --- a/qt/i2pd_qt/android/res/values-zh-rCN/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - 无法找到Ministro服务。\n应用程序无法启动。 - 此应用程序需要Ministro服务。您想安装它吗? - 您的应用程序遇到一个致命错误导致它无法继续。 - diff --git a/qt/i2pd_qt/android/res/values-zh-rTW/strings.xml b/qt/i2pd_qt/android/res/values-zh-rTW/strings.xml deleted file mode 100644 index f6e68efa..00000000 --- a/qt/i2pd_qt/android/res/values-zh-rTW/strings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - 無法找到Ministro服務。\n應用程序無法啟動。 - 此應用程序需要Ministro服務。您想安裝它嗎? - 您的應用程序遇到一個致命錯誤導致它無法繼續。 - diff --git a/qt/i2pd_qt/android/res/values/libs.xml b/qt/i2pd_qt/android/res/values/libs.xml deleted file mode 100644 index 4d68673c..00000000 --- a/qt/i2pd_qt/android/res/values/libs.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - https://download.qt-project.org/ministro/android/qt5/qt-5.4 - - - - - - - - - - - - - - - - - - - - diff --git a/qt/i2pd_qt/android/res/values/strings.xml b/qt/i2pd_qt/android/res/values/strings.xml deleted file mode 100644 index 713c7aa0..00000000 --- a/qt/i2pd_qt/android/res/values/strings.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - Can\'t find Ministro service.\nThe application can\'t start. - This application requires Ministro service. Would you like to install it? - Your application encountered a fatal error and cannot continue. - i2pd started - i2pd stopped - i2pd - diff --git a/qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistro.aidl b/qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistro.aidl deleted file mode 100644 index e23cb699..00000000 --- a/qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistro.aidl +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (c) 2011-2013, BogDan Vatra - Contact: http://www.qt.io/licensing/ - - Commercial License Usage - Licensees holding valid commercial Qt licenses may use this file in - accordance with the commercial license agreement provided with the - Software or, alternatively, in accordance with the terms contained in - a written agreement between you and The Qt Company. For licensing terms - and conditions see http://www.qt.io/terms-conditions. For further - information use the contact form at http://www.qt.io/contact-us. - - BSD License Usage - Alternatively, this file may be used under the BSD license as follows: - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -package org.kde.necessitas.ministro; - -import org.kde.necessitas.ministro.IMinistroCallback; - -interface IMinistro -{ -/** -* Check/download required libs to run the application -* -* param callback - interface used by Minsitro service to notify the client when the loader is ready -* param parameters -* parameters fields: -* * Key Name Key type Explanations -* "sources" StringArray Sources list from where Ministro will download the libs. Make sure you are using ONLY secure locations. -* "repository" String Overwrites the default Ministro repository. Possible values: default, stable, testing and unstable -* "required.modules" StringArray Required modules by your application -* "application.title" String Application name, used to show more information to user -* "qt.provider" String Qt libs provider, currently only "necessitas" is supported. -* "minimum.ministro.api" Integer Minimum Ministro API level, used to check if Ministro service compatible with your application. Current API Level is 3 ! -* "minimum.qt.version" Integer Minimim Qt version (e.g. 0x040800, which means Qt 4.8.0, check http://qt-project.org/doc/qt-4.8/qtglobal.html#QT_VERSION)! -*/ - void requestLoader(in IMinistroCallback callback, in Bundle parameters); -} diff --git a/qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl b/qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl deleted file mode 100644 index f19caa69..00000000 --- a/qt/i2pd_qt/android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright (c) 2011-2013, BogDan Vatra - Contact: http://www.qt.io/licensing/ - - Commercial License Usage - Licensees holding valid commercial Qt licenses may use this file in - accordance with the commercial license agreement provided with the - Software or, alternatively, in accordance with the terms contained in - a written agreement between you and The Qt Company. For licensing terms - and conditions see http://www.qt.io/terms-conditions. For further - information use the contact form at http://www.qt.io/contact-us. - - BSD License Usage - Alternatively, this file may be used under the BSD license as follows: - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package org.kde.necessitas.ministro; - -oneway interface IMinistroCallback { -/** -* This method is called by the Ministro service back into the application which -* implements this interface. -* -* param in - loaderParams -* loaderParams fields: -* * Key Name Key type Explanations -* * "error.code" Integer See below -* * "error.message" String Missing if no error, otherwise will contain the error message translated into phone language where available. -* * "dex.path" String The list of jar/apk files containing classes and resources, needed to be passed to application DexClassLoader -* * "lib.path" String The list of directories containing native libraries; may be missing, needed to be passed to application DexClassLoader -* * "loader.class.name" String Loader class name. -* -* "error.code" field possible errors: -* - 0 no error. -* - 1 incompatible Ministro version. Ministro needs to be upgraded. -* - 2 not all modules could be satisfy. -* - 3 invalid parameters -* - 4 invalid qt version -* - 5 download canceled -* -* The parameter contains additional fields which are used by the loader to start your application, so it must be passed to the loader. -*/ - - void loaderReady(in Bundle loaderParams); -} diff --git a/qt/i2pd_qt/android/src/org/purplei2p/i2pd/I2PDMainActivity.java b/qt/i2pd_qt/android/src/org/purplei2p/i2pd/I2PDMainActivity.java deleted file mode 100644 index aea50bf6..00000000 --- a/qt/i2pd_qt/android/src/org/purplei2p/i2pd/I2PDMainActivity.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.purplei2p.i2pd; - -import org.qtproject.qt5.android.bindings.QtActivity; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.Bundle; -import android.os.IBinder; - -public class I2PDMainActivity extends QtActivity -{ - - private static I2PDMainActivity instance; - - public I2PDMainActivity() {} - - /* (non-Javadoc) - * @see org.qtproject.qt5.android.bindings.QtActivity#onCreate(android.os.Bundle) - */ - @Override - public void onCreate(Bundle savedInstanceState) { - I2PDMainActivity.setInstance(this); - super.onCreate(savedInstanceState); - - //set the app be foreground (do not unload when RAM needed) - doBindService(); - } - - /* (non-Javadoc) - * @see org.qtproject.qt5.android.bindings.QtActivity#onDestroy() - */ - @Override - protected void onDestroy() { - I2PDMainActivity.setInstance(null); - doUnbindService(); - super.onDestroy(); - } - - public static I2PDMainActivity getInstance() { - return instance; - } - - private static void setInstance(I2PDMainActivity instance) { - I2PDMainActivity.instance = instance; - } - - - -// private LocalService mBoundService; - - private ServiceConnection mConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName className, IBinder service) { - // This is called when the connection with the service has been - // established, giving us the service object we can use to - // interact with the service. Because we have bound to a explicit - // service that we know is running in our own process, we can - // cast its IBinder to a concrete class and directly access it. -// mBoundService = ((LocalService.LocalBinder)service).getService(); - - // Tell the user about this for our demo. -// Toast.makeText(Binding.this, R.string.local_service_connected, -// Toast.LENGTH_SHORT).show(); - } - - public void onServiceDisconnected(ComponentName className) { - // This is called when the connection with the service has been - // unexpectedly disconnected -- that is, its process crashed. - // Because it is running in our same process, we should never - // see this happen. -// mBoundService = null; -// Toast.makeText(Binding.this, R.string.local_service_disconnected, -// Toast.LENGTH_SHORT).show(); - } - }; - - private boolean mIsBound; - - private void doBindService() { - // Establish a connection with the service. We use an explicit - // class name because we want a specific service implementation that - // we know will be running in our own process (and thus won't be - // supporting component replacement by other applications). - bindService(new Intent(this, - LocalService.class), mConnection, Context.BIND_AUTO_CREATE); - mIsBound = true; - } - - void doUnbindService() { - if (mIsBound) { - // Detach our existing connection. - unbindService(mConnection); - mIsBound = false; - } - } -} diff --git a/qt/i2pd_qt/android/src/org/purplei2p/i2pd/LocalService.java b/qt/i2pd_qt/android/src/org/purplei2p/i2pd/LocalService.java deleted file mode 100644 index e2901504..00000000 --- a/qt/i2pd_qt/android/src/org/purplei2p/i2pd/LocalService.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.purplei2p.i2pd; - -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Intent; -import android.os.Binder; -import android.os.IBinder; -import android.support.v4.app.NotificationCompat; -import android.util.Log; -import android.widget.Toast; - -public class LocalService extends Service { -// private NotificationManager mNM; - - // Unique Identification Number for the Notification. - // We use it on Notification start, and to cancel it. - private int NOTIFICATION = R.string.local_service_started; - - /** - * Class for clients to access. Because we know this service always - * runs in the same process as its clients, we don't need to deal with - * IPC. - */ - public class LocalBinder extends Binder { - LocalService getService() { - return LocalService.this; - } - } - - @Override - public void onCreate() { -// mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); - - // Display a notification about us starting. We put an icon in the status bar. - showNotification(); - - - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - Log.i("LocalService", "Received start id " + startId + ": " + intent); - return START_NOT_STICKY; - } - - @Override - public void onDestroy() { - // Cancel the persistent notification. - //mNM.cancel(NOTIFICATION); - stopForeground(true); - - // Tell the user we stopped. - Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show(); - } - - @Override - public IBinder onBind(Intent intent) { - return mBinder; - } - - // This is the object that receives interactions from clients. See - // RemoteService for a more complete example. - private final IBinder mBinder = new LocalBinder(); - - /** - * Show a notification while this service is running. - */ - private void showNotification() { - // In this sample, we'll use the same text for the ticker and the expanded notification - CharSequence text = getText(R.string.local_service_started); - - // The PendingIntent to launch our activity if the user selects this notification - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, - new Intent(this, I2PDMainActivity.class), 0); - - // Set the info for the views that show in the notification panel. - Notification notification = new NotificationCompat.Builder(this) - .setSmallIcon(R.drawable.itoopie_notification_icon) // the status icon - .setTicker(text) // the status text - .setWhen(System.currentTimeMillis()) // the time stamp - .setContentTitle(getText(R.string.local_service_label)) // the label of the entry - .setContentText(text) // the contents of the entry - .setContentIntent(contentIntent) // The intent to send when the entry is clicked - .build(); - - // Send the notification. - //mNM.notify(NOTIFICATION, notification); - startForeground(NOTIFICATION, notification); - } -} \ No newline at end of file diff --git a/qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtActivity.java b/qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtActivity.java deleted file mode 100644 index 9c607109..00000000 --- a/qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtActivity.java +++ /dev/null @@ -1,1621 +0,0 @@ -/* - Copyright (c) 2012-2013, BogDan Vatra - Contact: http://www.qt.io/licensing/ - - Commercial License Usage - Licensees holding valid commercial Qt licenses may use this file in - accordance with the commercial license agreement provided with the - Software or, alternatively, in accordance with the terms contained in - a written agreement between you and The Qt Company. For licensing terms - and conditions see http://www.qt.io/terms-conditions. For further - information use the contact form at http://www.qt.io/contact-us. - - BSD License Usage - Alternatively, this file may be used under the BSD license as follows: - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package org.qtproject.qt5.android.bindings; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.io.InputStream; -import java.io.FileOutputStream; -import java.io.FileInputStream; -import java.io.DataOutputStream; -import java.io.DataInputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; - -import org.kde.necessitas.ministro.IMinistro; -import org.kde.necessitas.ministro.IMinistroCallback; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.ComponentName; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.ServiceConnection; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageInfo; -import android.content.res.Configuration; -import android.content.res.Resources.Theme; -import android.content.res.AssetManager; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.drawable.ColorDrawable; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.IBinder; -import android.os.RemoteException; -import android.util.AttributeSet; -import android.util.Log; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.View; -import android.view.Window; -import android.view.WindowManager.LayoutParams; -import android.view.accessibility.AccessibilityEvent; -import dalvik.system.DexClassLoader; - -//@ANDROID-11 -import android.app.Fragment; -import android.view.ActionMode; -import android.view.ActionMode.Callback; -//@ANDROID-11 - - -public class QtActivity extends Activity -{ - private final static int MINISTRO_INSTALL_REQUEST_CODE = 0xf3ee; // request code used to know when Ministro installation is finished - private static final int MINISTRO_API_LEVEL = 5; // Ministro api level (check IMinistro.aidl file) - private static final int NECESSITAS_API_LEVEL = 2; // Necessitas api level used by platform plugin - private static final int QT_VERSION = 0x050100; // This app requires at least Qt version 5.1.0 - - private static final String ERROR_CODE_KEY = "error.code"; - private static final String ERROR_MESSAGE_KEY = "error.message"; - private static final String DEX_PATH_KEY = "dex.path"; - private static final String LIB_PATH_KEY = "lib.path"; - private static final String LOADER_CLASS_NAME_KEY = "loader.class.name"; - private static final String NATIVE_LIBRARIES_KEY = "native.libraries"; - private static final String ENVIRONMENT_VARIABLES_KEY = "environment.variables"; - private static final String APPLICATION_PARAMETERS_KEY = "application.parameters"; - private static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries"; - private static final String BUNDLED_IN_LIB_RESOURCE_ID_KEY = "android.app.bundled_in_lib_resource_id"; - private static final String BUNDLED_IN_ASSETS_RESOURCE_ID_KEY = "android.app.bundled_in_assets_resource_id"; - private static final String MAIN_LIBRARY_KEY = "main.library"; - private static final String STATIC_INIT_CLASSES_KEY = "static.init.classes"; - private static final String NECESSITAS_API_LEVEL_KEY = "necessitas.api.level"; - private static final String EXTRACT_STYLE_KEY = "extract.android.style"; - - /// Ministro server parameter keys - private static final String REQUIRED_MODULES_KEY = "required.modules"; - private static final String APPLICATION_TITLE_KEY = "application.title"; - private static final String MINIMUM_MINISTRO_API_KEY = "minimum.ministro.api"; - private static final String MINIMUM_QT_VERSION_KEY = "minimum.qt.version"; - private static final String SOURCES_KEY = "sources"; // needs MINISTRO_API_LEVEL >=3 !!! - // Use this key to specify any 3rd party sources urls - // Ministro will download these repositories into their - // own folders, check http://community.kde.org/Necessitas/Ministro - // for more details. - - private static final String REPOSITORY_KEY = "repository"; // use this key to overwrite the default ministro repsitory - private static final String ANDROID_THEMES_KEY = "android.themes"; // themes that your application uses - - - public String APPLICATION_PARAMETERS = null; // use this variable to pass any parameters to your application, - // the parameters must not contain any white spaces - // and must be separated with "\t" - // e.g "-param1\t-param2=value2\t-param3\tvalue3" - - public String ENVIRONMENT_VARIABLES = "QT_USE_ANDROID_NATIVE_STYLE=1\tQT_USE_ANDROID_NATIVE_DIALOGS=1\t"; - // use this variable to add any environment variables to your application. - // the env vars must be separated with "\t" - // e.g. "ENV_VAR1=1\tENV_VAR2=2\t" - // Currently the following vars are used by the android plugin: - // * QT_USE_ANDROID_NATIVE_STYLE - 1 to use the android widget style if available. - // * QT_USE_ANDROID_NATIVE_DIALOGS -1 to use the android native dialogs. - - public String[] QT_ANDROID_THEMES = null; // A list with all themes that your application want to use. - // The name of the theme must be the same with any theme from - // http://developer.android.com/reference/android/R.style.html - // The most used themes are: - // * "Theme" - (fallback) check http://developer.android.com/reference/android/R.style.html#Theme - // * "Theme_Black" - check http://developer.android.com/reference/android/R.style.html#Theme_Black - // * "Theme_Light" - (default for API <=10) check http://developer.android.com/reference/android/R.style.html#Theme_Light - // * "Theme_Holo" - check http://developer.android.com/reference/android/R.style.html#Theme_Holo - // * "Theme_Holo_Light" - (default for API 11-13) check http://developer.android.com/reference/android/R.style.html#Theme_Holo_Light - // * "Theme_DeviceDefault" - check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault - // * "Theme_DeviceDefault_Light" - (default for API 14+) check http://developer.android.com/reference/android/R.style.html#Theme_DeviceDefault_Light - - public String QT_ANDROID_DEFAULT_THEME = null; // sets the default theme. - - private static final int INCOMPATIBLE_MINISTRO_VERSION = 1; // Incompatible Ministro version. Ministro needs to be upgraded. - private static final int BUFFER_SIZE = 1024; - - private ActivityInfo m_activityInfo = null; // activity info object, used to access the libs and the strings - private DexClassLoader m_classLoader = null; // loader object - private String[] m_sources = {"https://download.qt-project.org/ministro/android/qt5/qt-5.2"}; // Make sure you are using ONLY secure locations - private String m_repository = "default"; // Overwrites the default Ministro repository - // Possible values: - // * default - Ministro default repository set with "Ministro configuration tool". - // By default the stable version is used. Only this or stable repositories should - // be used in production. - // * stable - stable repository, only this and default repositories should be used - // in production. - // * testing - testing repository, DO NOT use this repository in production, - // this repository is used to push a new release, and should be used to test your application. - // * unstable - unstable repository, DO NOT use this repository in production, - // this repository is used to push Qt snapshots. - private String[] m_qtLibs = null; // required qt libs - private int m_displayDensity = -1; - - public QtActivity() - { - if (Build.VERSION.SDK_INT <= 10) { - QT_ANDROID_THEMES = new String[] {"Theme_Light"}; - QT_ANDROID_DEFAULT_THEME = "Theme_Light"; - } - else if ((Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT <= 13) || Build.VERSION.SDK_INT >= 21){ - QT_ANDROID_THEMES = new String[] {"Theme_Holo_Light"}; - QT_ANDROID_DEFAULT_THEME = "Theme_Holo_Light"; - } else { - QT_ANDROID_THEMES = new String[] {"Theme_DeviceDefault_Light"}; - QT_ANDROID_DEFAULT_THEME = "Theme_DeviceDefault_Light"; - } - } - - // this function is used to load and start the loader - private void loadApplication(Bundle loaderParams) - { - try { - final int errorCode = loaderParams.getInt(ERROR_CODE_KEY); - if (errorCode != 0) { - if (errorCode == INCOMPATIBLE_MINISTRO_VERSION) { - downloadUpgradeMinistro(loaderParams.getString(ERROR_MESSAGE_KEY)); - return; - } - - // fatal error, show the error and quit - AlertDialog errorDialog = new AlertDialog.Builder(QtActivity.this).create(); - errorDialog.setMessage(loaderParams.getString(ERROR_MESSAGE_KEY)); - errorDialog.setButton(getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - finish(); - } - }); - errorDialog.show(); - return; - } - - // add all bundled Qt libs to loader params - ArrayList libs = new ArrayList(); - if ( m_activityInfo.metaData.containsKey("android.app.bundled_libs_resource_id") ) - libs.addAll(Arrays.asList(getResources().getStringArray(m_activityInfo.metaData.getInt("android.app.bundled_libs_resource_id")))); - - String libName = null; - if ( m_activityInfo.metaData.containsKey("android.app.lib_name") ) { - libName = m_activityInfo.metaData.getString("android.app.lib_name"); - loaderParams.putString(MAIN_LIBRARY_KEY, libName); //main library contains main() function - } - - loaderParams.putStringArrayList(BUNDLED_LIBRARIES_KEY, libs); - loaderParams.putInt(NECESSITAS_API_LEVEL_KEY, NECESSITAS_API_LEVEL); - - // load and start QtLoader class - m_classLoader = new DexClassLoader(loaderParams.getString(DEX_PATH_KEY), // .jar/.apk files - getDir("outdex", Context.MODE_PRIVATE).getAbsolutePath(), // directory where optimized DEX files should be written. - loaderParams.containsKey(LIB_PATH_KEY) ? loaderParams.getString(LIB_PATH_KEY) : null, // libs folder (if exists) - getClassLoader()); // parent loader - - @SuppressWarnings("rawtypes") - Class loaderClass = m_classLoader.loadClass(loaderParams.getString(LOADER_CLASS_NAME_KEY)); // load QtLoader class - Object qtLoader = loaderClass.newInstance(); // create an instance - Method prepareAppMethod = qtLoader.getClass().getMethod("loadApplication", - Activity.class, - ClassLoader.class, - Bundle.class); - if (!(Boolean)prepareAppMethod.invoke(qtLoader, this, m_classLoader, loaderParams)) - throw new Exception(""); - - QtApplication.setQtActivityDelegate(qtLoader); - - // now load the application library so it's accessible from this class loader - if (libName != null) - System.loadLibrary(libName); - - Method startAppMethod=qtLoader.getClass().getMethod("startApplication"); - if (!(Boolean)startAppMethod.invoke(qtLoader)) - throw new Exception(""); - - } catch (Exception e) { - e.printStackTrace(); - AlertDialog errorDialog = new AlertDialog.Builder(QtActivity.this).create(); - if (m_activityInfo.metaData.containsKey("android.app.fatal_error_msg")) - errorDialog.setMessage(m_activityInfo.metaData.getString("android.app.fatal_error_msg")); - else - errorDialog.setMessage("Fatal error, your application can't be started."); - - errorDialog.setButton(getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - finish(); - } - }); - errorDialog.show(); - } - } - - private ServiceConnection m_ministroConnection=new ServiceConnection() { - private IMinistro m_service = null; - @Override - public void onServiceConnected(ComponentName name, IBinder service) - { - m_service = IMinistro.Stub.asInterface(service); - try { - if (m_service != null) { - Bundle parameters = new Bundle(); - parameters.putStringArray(REQUIRED_MODULES_KEY, m_qtLibs); - parameters.putString(APPLICATION_TITLE_KEY, (String)QtActivity.this.getTitle()); - parameters.putInt(MINIMUM_MINISTRO_API_KEY, MINISTRO_API_LEVEL); - parameters.putInt(MINIMUM_QT_VERSION_KEY, QT_VERSION); - parameters.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES); - if (APPLICATION_PARAMETERS != null) - parameters.putString(APPLICATION_PARAMETERS_KEY, APPLICATION_PARAMETERS); - parameters.putStringArray(SOURCES_KEY, m_sources); - parameters.putString(REPOSITORY_KEY, m_repository); - if (QT_ANDROID_THEMES != null) - parameters.putStringArray(ANDROID_THEMES_KEY, QT_ANDROID_THEMES); - m_service.requestLoader(m_ministroCallback, parameters); - } - } catch (RemoteException e) { - e.printStackTrace(); - } - } - - private IMinistroCallback m_ministroCallback = new IMinistroCallback.Stub() { - // this function is called back by Ministro. - @Override - public void loaderReady(final Bundle loaderParams) throws RemoteException { - runOnUiThread(new Runnable() { - @Override - public void run() { - unbindService(m_ministroConnection); - loadApplication(loaderParams); - } - }); - } - }; - - @Override - public void onServiceDisconnected(ComponentName name) { - m_service = null; - } - }; - - private void downloadUpgradeMinistro(String msg) - { - AlertDialog.Builder downloadDialog = new AlertDialog.Builder(this); - downloadDialog.setMessage(msg); - downloadDialog.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - try { - Uri uri = Uri.parse("market://search?q=pname:org.kde.necessitas.ministro"); - Intent intent = new Intent(Intent.ACTION_VIEW, uri); - startActivityForResult(intent, MINISTRO_INSTALL_REQUEST_CODE); - } catch (Exception e) { - e.printStackTrace(); - ministroNotFound(); - } - } - }); - - downloadDialog.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - QtActivity.this.finish(); - } - }); - downloadDialog.show(); - } - - private void ministroNotFound() - { - AlertDialog errorDialog = new AlertDialog.Builder(QtActivity.this).create(); - - if (m_activityInfo.metaData.containsKey("android.app.ministro_not_found_msg")) - errorDialog.setMessage(m_activityInfo.metaData.getString("android.app.ministro_not_found_msg")); - else - errorDialog.setMessage("Can't find Ministro service.\nThe application can't start."); - - errorDialog.setButton(getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - finish(); - } - }); - errorDialog.show(); - } - - static private void copyFile(InputStream inputStream, OutputStream outputStream) - throws IOException - { - byte[] buffer = new byte[BUFFER_SIZE]; - - int count; - while ((count = inputStream.read(buffer)) > 0) - outputStream.write(buffer, 0, count); - } - - - private void copyAsset(String source, String destination) - throws IOException - { - // Already exists, we don't have to do anything - File destinationFile = new File(destination); - if (destinationFile.exists()) - return; - - File parentDirectory = destinationFile.getParentFile(); - if (!parentDirectory.exists()) - parentDirectory.mkdirs(); - - destinationFile.createNewFile(); - - AssetManager assetsManager = getAssets(); - InputStream inputStream = assetsManager.open(source); - OutputStream outputStream = new FileOutputStream(destinationFile); - copyFile(inputStream, outputStream); - - inputStream.close(); - outputStream.close(); - } - - private static void createBundledBinary(String source, String destination) - throws IOException - { - // Already exists, we don't have to do anything - File destinationFile = new File(destination); - if (destinationFile.exists()) - return; - - File parentDirectory = destinationFile.getParentFile(); - if (!parentDirectory.exists()) - parentDirectory.mkdirs(); - - destinationFile.createNewFile(); - - InputStream inputStream = new FileInputStream(source); - OutputStream outputStream = new FileOutputStream(destinationFile); - copyFile(inputStream, outputStream); - - inputStream.close(); - outputStream.close(); - } - - private boolean cleanCacheIfNecessary(String pluginsPrefix, long packageVersion) - { - File versionFile = new File(pluginsPrefix + "cache.version"); - - long cacheVersion = 0; - if (versionFile.exists() && versionFile.canRead()) { - try { - DataInputStream inputStream = new DataInputStream(new FileInputStream(versionFile)); - cacheVersion = inputStream.readLong(); - inputStream.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - if (cacheVersion != packageVersion) { - deleteRecursively(new File(pluginsPrefix)); - return true; - } else { - return false; - } - } - - private void extractBundledPluginsAndImports(String pluginsPrefix) - throws IOException - { - ArrayList libs = new ArrayList(); - - String libsDir = getApplicationInfo().nativeLibraryDir + "/"; - - long packageVersion = -1; - try { - PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0); - packageVersion = packageInfo.lastUpdateTime; - } catch (Exception e) { - e.printStackTrace(); - } - - if (!cleanCacheIfNecessary(pluginsPrefix, packageVersion)) - return; - - { - File versionFile = new File(pluginsPrefix + "cache.version"); - - File parentDirectory = versionFile.getParentFile(); - if (!parentDirectory.exists()) - parentDirectory.mkdirs(); - - versionFile.createNewFile(); - - DataOutputStream outputStream = new DataOutputStream(new FileOutputStream(versionFile)); - outputStream.writeLong(packageVersion); - outputStream.close(); - } - - { - String key = BUNDLED_IN_LIB_RESOURCE_ID_KEY; - java.util.Set keys = m_activityInfo.metaData.keySet(); - if (m_activityInfo.metaData.containsKey(key)) { - String[] list = getResources().getStringArray(m_activityInfo.metaData.getInt(key)); - - for (String bundledImportBinary : list) { - String[] split = bundledImportBinary.split(":"); - String sourceFileName = libsDir + split[0]; - String destinationFileName = pluginsPrefix + split[1]; - createBundledBinary(sourceFileName, destinationFileName); - } - } - } - - { - String key = BUNDLED_IN_ASSETS_RESOURCE_ID_KEY; - if (m_activityInfo.metaData.containsKey(key)) { - String[] list = getResources().getStringArray(m_activityInfo.metaData.getInt(key)); - - for (String fileName : list) { - String[] split = fileName.split(":"); - String sourceFileName = split[0]; - String destinationFileName = pluginsPrefix + split[1]; - copyAsset(sourceFileName, destinationFileName); - } - } - - } - } - - private void deleteRecursively(File directory) - { - File[] files = directory.listFiles(); - if (files != null) { - for (File file : files) { - if (file.isDirectory()) - deleteRecursively(file); - else - file.delete(); - } - - directory.delete(); - } - } - - private void cleanOldCacheIfNecessary(String oldLocalPrefix, String localPrefix) - { - File newCache = new File(localPrefix); - if (!newCache.exists()) { - { - File oldPluginsCache = new File(oldLocalPrefix + "plugins/"); - if (oldPluginsCache.exists() && oldPluginsCache.isDirectory()) - deleteRecursively(oldPluginsCache); - } - - { - File oldImportsCache = new File(oldLocalPrefix + "imports/"); - if (oldImportsCache.exists() && oldImportsCache.isDirectory()) - deleteRecursively(oldImportsCache); - } - - { - File oldQmlCache = new File(oldLocalPrefix + "qml/"); - if (oldQmlCache.exists() && oldQmlCache.isDirectory()) - deleteRecursively(oldQmlCache); - } - } - } - - private void startApp(final boolean firstStart) - { - try { - if (m_activityInfo.metaData.containsKey("android.app.qt_sources_resource_id")) { - int resourceId = m_activityInfo.metaData.getInt("android.app.qt_sources_resource_id"); - m_sources = getResources().getStringArray(resourceId); - } - - if (m_activityInfo.metaData.containsKey("android.app.repository")) - m_repository = m_activityInfo.metaData.getString("android.app.repository"); - - if (m_activityInfo.metaData.containsKey("android.app.qt_libs_resource_id")) { - int resourceId = m_activityInfo.metaData.getInt("android.app.qt_libs_resource_id"); - m_qtLibs = getResources().getStringArray(resourceId); - } - - if (m_activityInfo.metaData.containsKey("android.app.use_local_qt_libs") - && m_activityInfo.metaData.getInt("android.app.use_local_qt_libs") == 1) { - ArrayList libraryList = new ArrayList(); - - - String localPrefix = "/data/local/tmp/qt/"; - if (m_activityInfo.metaData.containsKey("android.app.libs_prefix")) - localPrefix = m_activityInfo.metaData.getString("android.app.libs_prefix"); - - String pluginsPrefix = localPrefix; - - boolean bundlingQtLibs = false; - if (m_activityInfo.metaData.containsKey("android.app.bundle_local_qt_libs") - && m_activityInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) { - localPrefix = getApplicationInfo().dataDir + "/"; - pluginsPrefix = localPrefix + "qt-reserved-files/"; - cleanOldCacheIfNecessary(localPrefix, pluginsPrefix); - extractBundledPluginsAndImports(pluginsPrefix); - bundlingQtLibs = true; - } - - if (m_qtLibs != null) { - for (int i=0;i 0) { - if (lib.startsWith("lib/")) - libraryList.add(localPrefix + lib); - else - libraryList.add(pluginsPrefix + lib); - } - } - } - - - String dexPaths = new String(); - String pathSeparator = System.getProperty("path.separator", ":"); - if (!bundlingQtLibs && m_activityInfo.metaData.containsKey("android.app.load_local_jars")) { - String[] jarFiles = m_activityInfo.metaData.getString("android.app.load_local_jars").split(":"); - for (String jar:jarFiles) { - if (jar.length() > 0) { - if (dexPaths.length() > 0) - dexPaths += pathSeparator; - dexPaths += localPrefix + jar; - } - } - } - - Bundle loaderParams = new Bundle(); - loaderParams.putInt(ERROR_CODE_KEY, 0); - loaderParams.putString(DEX_PATH_KEY, dexPaths); - loaderParams.putString(LOADER_CLASS_NAME_KEY, "org.qtproject.qt5.android.QtActivityDelegate"); - if (m_activityInfo.metaData.containsKey("android.app.static_init_classes")) { - loaderParams.putStringArray(STATIC_INIT_CLASSES_KEY, - m_activityInfo.metaData.getString("android.app.static_init_classes").split(":")); - } - loaderParams.putStringArrayList(NATIVE_LIBRARIES_KEY, libraryList); - - - String themePath = getApplicationInfo().dataDir + "/qt-reserved-files/android-style/"; - String stylePath = themePath + m_displayDensity + "/"; - if (!(new File(stylePath)).exists()) - loaderParams.putString(EXTRACT_STYLE_KEY, stylePath); - ENVIRONMENT_VARIABLES += "\tMINISTRO_ANDROID_STYLE_PATH=" + stylePath - + "\tQT_ANDROID_THEMES_ROOT_PATH=" + themePath; - - loaderParams.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES - + "\tQML2_IMPORT_PATH=" + pluginsPrefix + "/qml" - + "\tQML_IMPORT_PATH=" + pluginsPrefix + "/imports" - + "\tQT_PLUGIN_PATH=" + pluginsPrefix + "/plugins"); - - if (APPLICATION_PARAMETERS != null) { - loaderParams.putString(APPLICATION_PARAMETERS_KEY, APPLICATION_PARAMETERS); - } else { - Intent intent = getIntent(); - if (intent != null) { - String parameters = intent.getStringExtra("applicationArguments"); - if (parameters != null) - loaderParams.putString(APPLICATION_PARAMETERS_KEY, parameters.replace(' ', '\t')); - } - } - - loadApplication(loaderParams); - return; - } - - try { - if (!bindService(new Intent(org.kde.necessitas.ministro.IMinistro.class.getCanonicalName()), - m_ministroConnection, - Context.BIND_AUTO_CREATE)) { - throw new SecurityException(""); - } - } catch (Exception e) { - if (firstStart) { - String msg = "This application requires Ministro service. Would you like to install it?"; - if (m_activityInfo.metaData.containsKey("android.app.ministro_needed_msg")) - msg = m_activityInfo.metaData.getString("android.app.ministro_needed_msg"); - downloadUpgradeMinistro(msg); - } else { - ministroNotFound(); - } - } - } catch (Exception e) { - Log.e(QtApplication.QtTAG, "Can't create main activity", e); - } - } - - - - /////////////////////////// forward all notifications //////////////////////////// - /////////////////////////// Super class calls //////////////////////////////////// - /////////////// PLEASE DO NOT CHANGE THE FOLLOWING CODE ////////////////////////// - ////////////////////////////////////////////////////////////////////////////////// - - @Override - public boolean dispatchKeyEvent(KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.dispatchKeyEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchKeyEvent, event); - else - return super.dispatchKeyEvent(event); - } - public boolean super_dispatchKeyEvent(KeyEvent event) - { - return super.dispatchKeyEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.dispatchPopulateAccessibilityEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchPopulateAccessibilityEvent, event); - else - return super.dispatchPopulateAccessibilityEvent(event); - } - public boolean super_dispatchPopulateAccessibilityEvent(AccessibilityEvent event) - { - return super_dispatchPopulateAccessibilityEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) - { - if (QtApplication.m_delegateObject != null && QtApplication.dispatchTouchEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchTouchEvent, ev); - else - return super.dispatchTouchEvent(ev); - } - public boolean super_dispatchTouchEvent(MotionEvent event) - { - return super.dispatchTouchEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public boolean dispatchTrackballEvent(MotionEvent ev) - { - if (QtApplication.m_delegateObject != null && QtApplication.dispatchTrackballEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchTrackballEvent, ev); - else - return super.dispatchTrackballEvent(ev); - } - public boolean super_dispatchTrackballEvent(MotionEvent event) - { - return super.dispatchTrackballEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) - { - - if (QtApplication.m_delegateObject != null && QtApplication.onActivityResult != null) { - QtApplication.invokeDelegateMethod(QtApplication.onActivityResult, requestCode, resultCode, data); - return; - } - if (requestCode == MINISTRO_INSTALL_REQUEST_CODE) - startApp(false); - super.onActivityResult(requestCode, resultCode, data); - } - public void super_onActivityResult(int requestCode, int resultCode, Intent data) - { - super.onActivityResult(requestCode, resultCode, data); - } - //--------------------------------------------------------------------------- - - @Override - protected void onApplyThemeResource(Theme theme, int resid, boolean first) - { - if (!QtApplication.invokeDelegate(theme, resid, first).invoked) - super.onApplyThemeResource(theme, resid, first); - } - public void super_onApplyThemeResource(Theme theme, int resid, boolean first) - { - super.onApplyThemeResource(theme, resid, first); - } - //--------------------------------------------------------------------------- - - - @Override - protected void onChildTitleChanged(Activity childActivity, CharSequence title) - { - if (!QtApplication.invokeDelegate(childActivity, title).invoked) - super.onChildTitleChanged(childActivity, title); - } - public void super_onChildTitleChanged(Activity childActivity, CharSequence title) - { - super.onChildTitleChanged(childActivity, title); - } - //--------------------------------------------------------------------------- - - @Override - public void onConfigurationChanged(Configuration newConfig) - { - if (!QtApplication.invokeDelegate(newConfig).invoked) - super.onConfigurationChanged(newConfig); - } - public void super_onConfigurationChanged(Configuration newConfig) - { - super.onConfigurationChanged(newConfig); - } - //--------------------------------------------------------------------------- - - @Override - public void onContentChanged() - { - if (!QtApplication.invokeDelegate().invoked) - super.onContentChanged(); - } - public void super_onContentChanged() - { - super.onContentChanged(); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onContextItemSelected(MenuItem item) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(item); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onContextItemSelected(item); - } - public boolean super_onContextItemSelected(MenuItem item) - { - return super.onContextItemSelected(item); - } - //--------------------------------------------------------------------------- - - @Override - public void onContextMenuClosed(Menu menu) - { - if (!QtApplication.invokeDelegate(menu).invoked) - super.onContextMenuClosed(menu); - } - public void super_onContextMenuClosed(Menu menu) - { - super.onContextMenuClosed(menu); - } - //--------------------------------------------------------------------------- - - @Override - public void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - - try { - m_activityInfo = getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA); - for (Field f : Class.forName("android.R$style").getDeclaredFields()) { - if (f.getInt(null) == m_activityInfo.getThemeResource()) { - QT_ANDROID_THEMES = new String[] {f.getName()}; - QT_ANDROID_DEFAULT_THEME = f.getName(); - } - } - } catch (Exception e) { - e.printStackTrace(); - finish(); - return; - } - - try { - setTheme(Class.forName("android.R$style").getDeclaredField(QT_ANDROID_DEFAULT_THEME).getInt(null)); - } catch (Exception e) { - e.printStackTrace(); - } - - if (Build.VERSION.SDK_INT > 10) { - try { - requestWindowFeature(Window.class.getField("FEATURE_ACTION_BAR").getInt(null)); - } catch (Exception e) { - e.printStackTrace(); - } - } else { - requestWindowFeature(Window.FEATURE_NO_TITLE); - } - - if (QtApplication.m_delegateObject != null && QtApplication.onCreate != null) { - QtApplication.invokeDelegateMethod(QtApplication.onCreate, savedInstanceState); - return; - } - - m_displayDensity = getResources().getDisplayMetrics().densityDpi; - - ENVIRONMENT_VARIABLES += "\tQT_ANDROID_THEME=" + QT_ANDROID_DEFAULT_THEME - + "/\tQT_ANDROID_THEME_DISPLAY_DPI=" + m_displayDensity + "\t"; - - if (null == getLastNonConfigurationInstance()) { - // if splash screen is defined, then show it - if (m_activityInfo.metaData.containsKey("android.app.splash_screen_drawable")) - getWindow().setBackgroundDrawableResource(m_activityInfo.metaData.getInt("android.app.splash_screen_drawable")); - else - getWindow().setBackgroundDrawable(new ColorDrawable(0xff000000)); - - if (m_activityInfo.metaData.containsKey("android.app.background_running") - && m_activityInfo.metaData.getBoolean("android.app.background_running")) { - ENVIRONMENT_VARIABLES += "QT_BLOCK_EVENT_LOOPS_WHEN_SUSPENDED=0\t"; - } else { - ENVIRONMENT_VARIABLES += "QT_BLOCK_EVENT_LOOPS_WHEN_SUSPENDED=1\t"; - } - - if (m_activityInfo.metaData.containsKey("android.app.auto_screen_scale_factor") - && m_activityInfo.metaData.getBoolean("android.app.auto_screen_scale_factor")) { - ENVIRONMENT_VARIABLES += "QT_AUTO_SCREEN_SCALE_FACTOR=1\t"; - } - - startApp(true); - } - } - //--------------------------------------------------------------------------- - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) - { - if (!QtApplication.invokeDelegate(menu, v, menuInfo).invoked) - super.onCreateContextMenu(menu, v, menuInfo); - } - public void super_onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) - { - super.onCreateContextMenu(menu, v, menuInfo); - } - //--------------------------------------------------------------------------- - - @Override - public CharSequence onCreateDescription() - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(); - if (res.invoked) - return (CharSequence)res.methodReturns; - else - return super.onCreateDescription(); - } - public CharSequence super_onCreateDescription() - { - return super.onCreateDescription(); - } - //--------------------------------------------------------------------------- - - @Override - protected Dialog onCreateDialog(int id) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(id); - if (res.invoked) - return (Dialog)res.methodReturns; - else - return super.onCreateDialog(id); - } - public Dialog super_onCreateDialog(int id) - { - return super.onCreateDialog(id); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onCreateOptionsMenu(Menu menu) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(menu); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onCreateOptionsMenu(menu); - } - public boolean super_onCreateOptionsMenu(Menu menu) - { - return super.onCreateOptionsMenu(menu); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onCreatePanelMenu(int featureId, Menu menu) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId, menu); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onCreatePanelMenu(featureId, menu); - } - public boolean super_onCreatePanelMenu(int featureId, Menu menu) - { - return super.onCreatePanelMenu(featureId, menu); - } - //--------------------------------------------------------------------------- - - - @Override - public View onCreatePanelView(int featureId) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId); - if (res.invoked) - return (View)res.methodReturns; - else - return super.onCreatePanelView(featureId); - } - public View super_onCreatePanelView(int featureId) - { - return super.onCreatePanelView(featureId); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onCreateThumbnail(Bitmap outBitmap, Canvas canvas) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(outBitmap, canvas); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onCreateThumbnail(outBitmap, canvas); - } - public boolean super_onCreateThumbnail(Bitmap outBitmap, Canvas canvas) - { - return super.onCreateThumbnail(outBitmap, canvas); - } - //--------------------------------------------------------------------------- - - @Override - public View onCreateView(String name, Context context, AttributeSet attrs) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(name, context, attrs); - if (res.invoked) - return (View)res.methodReturns; - else - return super.onCreateView(name, context, attrs); - } - public View super_onCreateView(String name, Context context, AttributeSet attrs) - { - return super.onCreateView(name, context, attrs); - } - //--------------------------------------------------------------------------- - - @Override - protected void onDestroy() - { - super.onDestroy(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onKeyDown != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyDown, keyCode, event); - else - return super.onKeyDown(keyCode, event); - } - public boolean super_onKeyDown(int keyCode, KeyEvent event) - { - return super.onKeyDown(keyCode, event); - } - //--------------------------------------------------------------------------- - - - @Override - public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onKeyMultiple != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyMultiple, keyCode, repeatCount, event); - else - return super.onKeyMultiple(keyCode, repeatCount, event); - } - public boolean super_onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) - { - return super.onKeyMultiple(keyCode, repeatCount, event); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onKeyDown != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyUp, keyCode, event); - else - return super.onKeyUp(keyCode, event); - } - public boolean super_onKeyUp(int keyCode, KeyEvent event) - { - return super.onKeyUp(keyCode, event); - } - //--------------------------------------------------------------------------- - - @Override - public void onLowMemory() - { - if (!QtApplication.invokeDelegate().invoked) - super.onLowMemory(); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onMenuItemSelected(int featureId, MenuItem item) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId, item); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onMenuItemSelected(featureId, item); - } - public boolean super_onMenuItemSelected(int featureId, MenuItem item) - { - return super.onMenuItemSelected(featureId, item); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onMenuOpened(int featureId, Menu menu) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId, menu); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onMenuOpened(featureId, menu); - } - public boolean super_onMenuOpened(int featureId, Menu menu) - { - return super.onMenuOpened(featureId, menu); - } - //--------------------------------------------------------------------------- - - @Override - protected void onNewIntent(Intent intent) - { - if (!QtApplication.invokeDelegate(intent).invoked) - super.onNewIntent(intent); - } - public void super_onNewIntent(Intent intent) - { - super.onNewIntent(intent); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onOptionsItemSelected(MenuItem item) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(item); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onOptionsItemSelected(item); - } - public boolean super_onOptionsItemSelected(MenuItem item) - { - return super.onOptionsItemSelected(item); - } - //--------------------------------------------------------------------------- - - @Override - public void onOptionsMenuClosed(Menu menu) - { - if (!QtApplication.invokeDelegate(menu).invoked) - super.onOptionsMenuClosed(menu); - } - public void super_onOptionsMenuClosed(Menu menu) - { - super.onOptionsMenuClosed(menu); - } - //--------------------------------------------------------------------------- - - @Override - public void onPanelClosed(int featureId, Menu menu) - { - if (!QtApplication.invokeDelegate(featureId, menu).invoked) - super.onPanelClosed(featureId, menu); - } - public void super_onPanelClosed(int featureId, Menu menu) - { - super.onPanelClosed(featureId, menu); - } - //--------------------------------------------------------------------------- - - @Override - protected void onPause() - { - super.onPause(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onPostCreate(Bundle savedInstanceState) - { - super.onPostCreate(savedInstanceState); - QtApplication.invokeDelegate(savedInstanceState); - } - //--------------------------------------------------------------------------- - - @Override - protected void onPostResume() - { - super.onPostResume(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onPrepareDialog(int id, Dialog dialog) - { - if (!QtApplication.invokeDelegate(id, dialog).invoked) - super.onPrepareDialog(id, dialog); - } - public void super_onPrepareDialog(int id, Dialog dialog) - { - super.onPrepareDialog(id, dialog); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onPrepareOptionsMenu(Menu menu) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(menu); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onPrepareOptionsMenu(menu); - } - public boolean super_onPrepareOptionsMenu(Menu menu) - { - return super.onPrepareOptionsMenu(menu); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onPreparePanel(int featureId, View view, Menu menu) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(featureId, view, menu); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onPreparePanel(featureId, view, menu); - } - public boolean super_onPreparePanel(int featureId, View view, Menu menu) - { - return super.onPreparePanel(featureId, view, menu); - } - //--------------------------------------------------------------------------- - - @Override - protected void onRestart() - { - super.onRestart(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) - { - if (!QtApplication.invokeDelegate(savedInstanceState).invoked) - super.onRestoreInstanceState(savedInstanceState); - } - public void super_onRestoreInstanceState(Bundle savedInstanceState) - { - super.onRestoreInstanceState(savedInstanceState); - } - //--------------------------------------------------------------------------- - - @Override - protected void onResume() - { - super.onResume(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - public Object onRetainNonConfigurationInstance() - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(); - if (res.invoked) - return res.methodReturns; - else - return super.onRetainNonConfigurationInstance(); - } - public Object super_onRetainNonConfigurationInstance() - { - return super.onRetainNonConfigurationInstance(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onSaveInstanceState(Bundle outState) - { - if (!QtApplication.invokeDelegate(outState).invoked) - super.onSaveInstanceState(outState); - } - public void super_onSaveInstanceState(Bundle outState) - { - super.onSaveInstanceState(outState); - - } - //--------------------------------------------------------------------------- - - @Override - public boolean onSearchRequested() - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(); - if (res.invoked) - return (Boolean)res.methodReturns; - else - return super.onSearchRequested(); - } - public boolean super_onSearchRequested() - { - return super.onSearchRequested(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onStart() - { - super.onStart(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onStop() - { - super.onStop(); - QtApplication.invokeDelegate(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onTitleChanged(CharSequence title, int color) - { - if (!QtApplication.invokeDelegate(title, color).invoked) - super.onTitleChanged(title, color); - } - public void super_onTitleChanged(CharSequence title, int color) - { - super.onTitleChanged(title, color); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onTouchEvent(MotionEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onTouchEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onTouchEvent, event); - else - return super.onTouchEvent(event); - } - public boolean super_onTouchEvent(MotionEvent event) - { - return super.onTouchEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onTrackballEvent(MotionEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onTrackballEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onTrackballEvent, event); - else - return super.onTrackballEvent(event); - } - public boolean super_onTrackballEvent(MotionEvent event) - { - return super.onTrackballEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public void onUserInteraction() - { - if (!QtApplication.invokeDelegate().invoked) - super.onUserInteraction(); - } - public void super_onUserInteraction() - { - super.onUserInteraction(); - } - //--------------------------------------------------------------------------- - - @Override - protected void onUserLeaveHint() - { - if (!QtApplication.invokeDelegate().invoked) - super.onUserLeaveHint(); - } - public void super_onUserLeaveHint() - { - super.onUserLeaveHint(); - } - //--------------------------------------------------------------------------- - - @Override - public void onWindowAttributesChanged(LayoutParams params) - { - if (!QtApplication.invokeDelegate(params).invoked) - super.onWindowAttributesChanged(params); - } - public void super_onWindowAttributesChanged(LayoutParams params) - { - super.onWindowAttributesChanged(params); - } - //--------------------------------------------------------------------------- - - @Override - public void onWindowFocusChanged(boolean hasFocus) - { - if (!QtApplication.invokeDelegate(hasFocus).invoked) - super.onWindowFocusChanged(hasFocus); - } - public void super_onWindowFocusChanged(boolean hasFocus) - { - super.onWindowFocusChanged(hasFocus); - } - //--------------------------------------------------------------------------- - - //////////////// Activity API 5 ///////////// -//@ANDROID-5 - @Override - public void onAttachedToWindow() - { - if (!QtApplication.invokeDelegate().invoked) - super.onAttachedToWindow(); - } - public void super_onAttachedToWindow() - { - super.onAttachedToWindow(); - } - //--------------------------------------------------------------------------- - - @Override - public void onBackPressed() - { - if (!QtApplication.invokeDelegate().invoked) - super.onBackPressed(); - } - public void super_onBackPressed() - { - super.onBackPressed(); - } - //--------------------------------------------------------------------------- - - @Override - public void onDetachedFromWindow() - { - if (!QtApplication.invokeDelegate().invoked) - super.onDetachedFromWindow(); - } - public void super_onDetachedFromWindow() - { - super.onDetachedFromWindow(); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onKeyLongPress(int keyCode, KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onKeyLongPress != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyLongPress, keyCode, event); - else - return super.onKeyLongPress(keyCode, event); - } - public boolean super_onKeyLongPress(int keyCode, KeyEvent event) - { - return super.onKeyLongPress(keyCode, event); - } - //--------------------------------------------------------------------------- -//@ANDROID-5 - -//////////////// Activity API 8 ///////////// -//@ANDROID-8 -@Override - protected Dialog onCreateDialog(int id, Bundle args) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(id, args); - if (res.invoked) - return (Dialog)res.methodReturns; - else - return super.onCreateDialog(id, args); - } - public Dialog super_onCreateDialog(int id, Bundle args) - { - return super.onCreateDialog(id, args); - } - //--------------------------------------------------------------------------- - - @Override - protected void onPrepareDialog(int id, Dialog dialog, Bundle args) - { - if (!QtApplication.invokeDelegate(id, dialog, args).invoked) - super.onPrepareDialog(id, dialog, args); - } - public void super_onPrepareDialog(int id, Dialog dialog, Bundle args) - { - super.onPrepareDialog(id, dialog, args); - } - //--------------------------------------------------------------------------- -//@ANDROID-8 - //////////////// Activity API 11 ///////////// - -//@ANDROID-11 - @Override - public boolean dispatchKeyShortcutEvent(KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.dispatchKeyShortcutEvent != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchKeyShortcutEvent, event); - else - return super.dispatchKeyShortcutEvent(event); - } - public boolean super_dispatchKeyShortcutEvent(KeyEvent event) - { - return super.dispatchKeyShortcutEvent(event); - } - //--------------------------------------------------------------------------- - - @Override - public void onActionModeFinished(ActionMode mode) - { - if (!QtApplication.invokeDelegate(mode).invoked) - super.onActionModeFinished(mode); - } - public void super_onActionModeFinished(ActionMode mode) - { - super.onActionModeFinished(mode); - } - //--------------------------------------------------------------------------- - - @Override - public void onActionModeStarted(ActionMode mode) - { - if (!QtApplication.invokeDelegate(mode).invoked) - super.onActionModeStarted(mode); - } - public void super_onActionModeStarted(ActionMode mode) - { - super.onActionModeStarted(mode); - } - //--------------------------------------------------------------------------- - - @Override - public void onAttachFragment(Fragment fragment) - { - if (!QtApplication.invokeDelegate(fragment).invoked) - super.onAttachFragment(fragment); - } - public void super_onAttachFragment(Fragment fragment) - { - super.onAttachFragment(fragment); - } - //--------------------------------------------------------------------------- - - @Override - public View onCreateView(View parent, String name, Context context, AttributeSet attrs) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(parent, name, context, attrs); - if (res.invoked) - return (View)res.methodReturns; - else - return super.onCreateView(parent, name, context, attrs); - } - public View super_onCreateView(View parent, String name, Context context, - AttributeSet attrs) { - return super.onCreateView(parent, name, context, attrs); - } - //--------------------------------------------------------------------------- - - @Override - public boolean onKeyShortcut(int keyCode, KeyEvent event) - { - if (QtApplication.m_delegateObject != null && QtApplication.onKeyShortcut != null) - return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onKeyShortcut, keyCode,event); - else - return super.onKeyShortcut(keyCode, event); - } - public boolean super_onKeyShortcut(int keyCode, KeyEvent event) - { - return super.onKeyShortcut(keyCode, event); - } - //--------------------------------------------------------------------------- - - @Override - public ActionMode onWindowStartingActionMode(Callback callback) - { - QtApplication.InvokeResult res = QtApplication.invokeDelegate(callback); - if (res.invoked) - return (ActionMode)res.methodReturns; - else - return super.onWindowStartingActionMode(callback); - } - public ActionMode super_onWindowStartingActionMode(Callback callback) - { - return super.onWindowStartingActionMode(callback); - } - //--------------------------------------------------------------------------- -//@ANDROID-11 - //////////////// Activity API 12 ///////////// - -////@ANDROID-12 -// @Override -// public boolean dispatchGenericMotionEvent(MotionEvent ev) -// { -// if (QtApplication.m_delegateObject != null && QtApplication.dispatchGenericMotionEvent != null) -// return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.dispatchGenericMotionEvent, ev); -// else -// return super.dispatchGenericMotionEvent(ev); -// } -// public boolean super_dispatchGenericMotionEvent(MotionEvent event) -// { -// return super.dispatchGenericMotionEvent(event); -// } -// //--------------------------------------------------------------------------- -// -// @Override -// public boolean onGenericMotionEvent(MotionEvent event) -// { -// if (QtApplication.m_delegateObject != null && QtApplication.onGenericMotionEvent != null) -// return (Boolean) QtApplication.invokeDelegateMethod(QtApplication.onGenericMotionEvent, event); -// else -// return super.onGenericMotionEvent(event); -// } -// public boolean super_onGenericMotionEvent(MotionEvent event) -// { -// return super.onGenericMotionEvent(event); -// } -// //--------------------------------------------------------------------------- -////@ANDROID-12 - -} diff --git a/qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtApplication.java b/qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtApplication.java deleted file mode 100644 index c78aeb7f..00000000 --- a/qt/i2pd_qt/android/src/org/qtproject/qt5/android/bindings/QtApplication.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - Copyright (c) 2012-2013, BogDan Vatra - Contact: http://www.qt.io/licensing/ - - Commercial License Usage - Licensees holding valid commercial Qt licenses may use this file in - accordance with the commercial license agreement provided with the - Software or, alternatively, in accordance with the terms contained in - a written agreement between you and The Qt Company. For licensing terms - and conditions see http://www.qt.io/terms-conditions. For further - information use the contact form at http://www.qt.io/contact-us. - - BSD License Usage - Alternatively, this file may be used under the BSD license as follows: - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -package org.qtproject.qt5.android.bindings; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; - -import android.app.Application; - -public class QtApplication extends Application -{ - public final static String QtTAG = "Qt"; - public static Object m_delegateObject = null; - public static HashMap> m_delegateMethods= new HashMap>(); - public static Method dispatchKeyEvent = null; - public static Method dispatchPopulateAccessibilityEvent = null; - public static Method dispatchTouchEvent = null; - public static Method dispatchTrackballEvent = null; - public static Method onKeyDown = null; - public static Method onKeyMultiple = null; - public static Method onKeyUp = null; - public static Method onTouchEvent = null; - public static Method onTrackballEvent = null; - public static Method onActivityResult = null; - public static Method onCreate = null; - public static Method onKeyLongPress = null; - public static Method dispatchKeyShortcutEvent = null; - public static Method onKeyShortcut = null; - public static Method dispatchGenericMotionEvent = null; - public static Method onGenericMotionEvent = null; - - public static void setQtActivityDelegate(Object listener) - { - QtApplication.m_delegateObject = listener; - - ArrayList delegateMethods = new ArrayList(); - for (Method m : listener.getClass().getMethods()) { - if (m.getDeclaringClass().getName().startsWith("org.qtproject.qt5.android")) - delegateMethods.add(m); - } - - ArrayList applicationFields = new ArrayList(); - for (Field f : QtApplication.class.getFields()) { - if (f.getDeclaringClass().getName().equals(QtApplication.class.getName())) - applicationFields.add(f); - } - - for (Method delegateMethod : delegateMethods) { - try { - QtActivity.class.getDeclaredMethod(delegateMethod.getName(), delegateMethod.getParameterTypes()); - if (QtApplication.m_delegateMethods.containsKey(delegateMethod.getName())) { - QtApplication.m_delegateMethods.get(delegateMethod.getName()).add(delegateMethod); - } else { - ArrayList delegateSet = new ArrayList(); - delegateSet.add(delegateMethod); - QtApplication.m_delegateMethods.put(delegateMethod.getName(), delegateSet); - } - for (Field applicationField:applicationFields) { - if (applicationField.getName().equals(delegateMethod.getName())) { - try { - applicationField.set(null, delegateMethod); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } catch (Exception e) { - } - } - } - - @Override - public void onTerminate() { - if (m_delegateObject != null && m_delegateMethods.containsKey("onTerminate")) - invokeDelegateMethod(m_delegateMethods.get("onTerminate").get(0)); - super.onTerminate(); - } - - public static class InvokeResult - { - public boolean invoked = false; - public Object methodReturns = null; - } - - private static int stackDeep=-1; - public static InvokeResult invokeDelegate(Object... args) - { - InvokeResult result = new InvokeResult(); - if (m_delegateObject == null) - return result; - StackTraceElement[] elements = Thread.currentThread().getStackTrace(); - if (-1 == stackDeep) { - String activityClassName = QtActivity.class.getCanonicalName(); - for (int it=0;it - - - -

- OpenSSL под Android в Qt - -

Запись от Wyn размещена 18.01.2016 в 18:22
Метки android, openssl, qt

Мини-руководство по тому, как быстро скомпилировать OpenSSL для Android и связать его с проектом Qt.
-Для Linux.

-Вначале действия полностью идентичны "расово-верному" руководству по компилянию OpenSSL для Android:
-Качаем исходники openssl нужной версии с их сайта, качаем setenv-android.sh(все ссылки на закачку выше по ссылке).
-Ложим их в одну папку. Запускаем консоль, переходим в ней в эту самую папку.
-Далее:
BashВыделить код
1
-2
-3
-
$ rm -rf openssl-1.0.1g/   # удаляем исходники(вместо версии 1.0.1g - подставляем свою), если они уже были распакованы
-$ tar xzf openssl-1.0.1g.tar.gz    # распаковываем исходники в подпапку
-$ chmod a+x setenv-android.sh    # разрешаем setenv-android.sh исполняться
Редактируем setenv-android.sh, настраивая там _ANDROID_EABI, _ANDROID_ARCH, _ANDROID_API на нужные значения.
-Дальше возвращаемся в консоль:
BashВыделить код
1
-2
-3
-4
-5
-6
-7
-8
-9
-10
-11
-
$ export ANDROID_NDK_ROOT=путь_до_ANDROID_NDK # указываем путь до Android NDK для setenv-android.sh
-$ . ./setenv-android.sh # запускаем скрипт, чтобы он нам в окружение проставил необходимые далее переменные
-$ cd openssl-1.0.1g/
-$ perl -pi -e 's/install: all install_docs install_sw/install: install_docs install_sw/g' Makefile.org
-# конфигурируем
-$ ./config shared no-ssl2 no-ssl3 no-comp no-hw no-engine --openssldir=/usr/local/ssl/$ANDROID_API
-# собираем
-$ make depend
-$ make all
-# устанавливаем
-$ sudo -E make install CC=$ANDROID_TOOLCHAIN/arm-linux-androideabi-gcc RANLIB=$ANDROID_TOOLCHAIN/arm-linux-androideabi-ranlib
И тут начинается интересное. Андроид не принимает versioned shared object (это *.so.x и подобные). Казалось бы 2016 год, космические корабли уже давно бороздят просторы Большого театра, но вот те на.

-Однако, есть обходной приём - нужно заменить *.so.x.x.x на *_x_x_x.so. Простым переименованием файлов данную проблему здесь, разумеется, не решить. Нужно лезть внутрь и переименовывать soname и внутренние ссылки на другие versioned shared object. В интернете есть много способов по подобному переименованию. Большинство из них обещают райскую жизнь с rpl, забывая упомянуть, что утилита уже давно отпета и закопана на большинстве дистрибутивов. Или хитро-хитро редактируют makefile, что в итоге на место левой руки собирается правая нога. В целом множество путей из разряда "как потратить много времени на полную фигню".

-В итоге предлагаю решить данную проблему методом топора:
-Качаем hex-редактор, если ещё нет(в моём случае таковым оказался Okteta). Запускаем его из под рута(kdesu okteta), открываем в нём файлы openssldir/lib/libcrypto.so.1.0.0. Заменяем(ctrl+r) в нём символы ".so.1.0.0" на char "_1_0_0.so". Проделываем тоже самое с libssl.so.1.0.0. Всё, теперь осталось только переименовать сами файлы(в libcrypto_1_0_0.so и libssl_1_0_0.so) и поправить ссылки libssl.so и libcrypto.so, чтобы они вели на них.

-Чтобы подключить и использовать данную библиотеку в проекте нужно добавить в .pro:
BashВыделить код
1
-2
-3
-4
-5
-
android: {
-    INCLUDEPATH += /usr/local/ssl/android-21/include
-    LIBS += -L/usr/local/ssl/android-21/lib
-}
-LIBS += -lcrypto
А затем в настройках проекта, в Buld/Build Steps/Bulild Android Apk добавить libcrypto_1_0_0.so и libssl_1_0_0.so в список Additional Libraries.

-На этом всё. - -
-

Original: http://www.cyberforum.ru/blogs/748276/blog4086.html

- - diff --git a/qt/i2pd_qt/i2pd_qt.pro b/qt/i2pd_qt/i2pd_qt.pro index 879efc95..e24a3963 100644 --- a/qt/i2pd_qt/i2pd_qt.pro +++ b/qt/i2pd_qt/i2pd_qt.pro @@ -7,23 +7,6 @@ TEMPLATE = app QMAKE_CXXFLAGS *= -std=c++11 -ggdb DEFINES += USE_UPNP -# change to your own path, where you will store all needed libraries with 'git clone' commands below. -MAIN_PATH = /path/to/libraries - -# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git -# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git -# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git -# git clone https://github.com/PurpleI2P/android-ifaddrs.git -BOOST_PATH = $$MAIN_PATH/Boost-for-Android-Prebuilt -OPENSSL_PATH = $$MAIN_PATH/OpenSSL-for-Android-Prebuilt -MINIUPNP_PATH = $$MAIN_PATH/MiniUPnP-for-Android-Prebuilt -IFADDRS_PATH = $$MAIN_PATH/android-ifaddrs - -# Steps in Android SDK manager: -# 1) Check Extras/Google Support Library https://developer.android.com/topic/libraries/support-library/setup.html -# 2) Check API 11 -# Finally, click Install. - SOURCES += DaemonQT.cpp mainwindow.cpp \ ../../libi2pd/api.cpp \ ../../libi2pd/Base.cpp \ @@ -218,63 +201,6 @@ macx { LIBS += $$UPNPROOT/lib/libminiupnpc.a } -android { - message("Using Android settings") - DEFINES += ANDROID=1 - DEFINES += __ANDROID__ - - CONFIG += mobility - - MOBILITY = - - INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \ - $$OPENSSL_PATH/openssl-1.0.2/include \ - $$MINIUPNP_PATH/miniupnp-2.0/include \ - $$IFADDRS_PATH - DISTFILES += android/AndroidManifest.xml - - ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android - - SOURCES += $$IFADDRS_PATH/ifaddrs.c - HEADERS += $$IFADDRS_PATH/ifaddrs.h - - equals(ANDROID_TARGET_ARCH, armeabi-v7a){ - DEFINES += ANDROID_ARM7A - # http://stackoverflow.com/a/30235934/529442 - LIBS += -L$$BOOST_PATH/boost_1_53_0/armeabi-v7a/lib \ - -lboost_system-gcc-mt-1_53 -lboost_date_time-gcc-mt-1_53 \ - -lboost_filesystem-gcc-mt-1_53 -lboost_program_options-gcc-mt-1_53 \ - -L$$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/ -lcrypto -lssl \ - -L$$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/ -lminiupnpc - - PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \ - $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl.a - DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include - - ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto_1_0_0.so \ - $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libssl_1_0_0.so \ - $$MINIUPNP_PATH/miniupnp-2.0/armeabi-v7a/lib/libminiupnpc.so - } - - equals(ANDROID_TARGET_ARCH, x86){ - # http://stackoverflow.com/a/30235934/529442 - LIBS += -L$$BOOST_PATH/boost_1_53_0/x86/lib \ - -lboost_system-gcc-mt-1_53 -lboost_date_time-gcc-mt-1_53 \ - -lboost_filesystem-gcc-mt-1_53 -lboost_program_options-gcc-mt-1_53 \ - -L$$OPENSSL_PATH/openssl-1.0.2/x86/lib/ -lcrypto -lssl \ - -L$$MINIUPNP_PATH/miniupnp-2.0/x86/lib/ -lminiupnpc - - PRE_TARGETDEPS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto.a \ - $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl.a - - DEPENDPATH += $$OPENSSL_PATH/openssl-1.0.2/include - - ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libcrypto_1_0_0.so \ - $$OPENSSL_PATH/openssl-1.0.2/x86/lib/libssl_1_0_0.so \ - $$MINIUPNP_PATH/miniupnp-2.0/x86/lib/libminiupnpc.so - } -} - linux:!android { message("Using Linux settings") LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread -lminiupnpc