mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	remove i2pd-qt android project (closes #1279)
This commit is contained in:
		
							parent
							
								
									d84c9ad611
								
							
						
					
					
						commit
						3f091f4748
					
				
					 37 changed files with 0 additions and 2516 deletions
				
			
		
							
								
								
									
										1
									
								
								qt/i2pd_qt/android/.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								qt/i2pd_qt/android/.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1 +0,0 @@
 | 
			
		|||
/gen/
 | 
			
		||||
| 
						 | 
				
			
			@ -1,64 +0,0 @@
 | 
			
		|||
<?xml version="1.0"?>
 | 
			
		||||
<manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.22.0" android:versionCode="1" android:installLocation="auto">
 | 
			
		||||
    <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/>
 | 
			
		||||
        <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
 | 
			
		||||
    <!-- <application android:hardwareAccelerated="true" -->
 | 
			
		||||
        <application android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="i2pd" android:icon="@drawable/icon">
 | 
			
		||||
        <!-- android:configChanges="screenSize|smallestScreenSize" are since api 13, "layoutDirection" since api 17 -->
 | 
			
		||||
        <activity android:configChanges="orientation|uiMode|screenLayout|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.purplei2p.i2pd.I2PDMainActivity" android:label="i2pd" android:screenOrientation="unspecified" android:launchMode="singleTop">
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="android.intent.action.MAIN"/>
 | 
			
		||||
                <category android:name="android.intent.category.LAUNCHER"/>
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
            <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
 | 
			
		||||
            <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
 | 
			
		||||
            <meta-data android:name="android.app.repository" android:value="default"/>
 | 
			
		||||
            <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
 | 
			
		||||
            <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
 | 
			
		||||
            <!-- Deploy Qt libs as part of package -->
 | 
			
		||||
            <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
 | 
			
		||||
            <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
 | 
			
		||||
            <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
 | 
			
		||||
            <!-- Run with local libs -->
 | 
			
		||||
            <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
 | 
			
		||||
            <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
 | 
			
		||||
            <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
 | 
			
		||||
            <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
 | 
			
		||||
            <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
 | 
			
		||||
            <!--  Messages maps -->
 | 
			
		||||
            <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
 | 
			
		||||
            <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
 | 
			
		||||
            <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
 | 
			
		||||
            <!--  Messages maps -->
 | 
			
		||||
 | 
			
		||||
            <!-- Splash screen -->
 | 
			
		||||
            <!--
 | 
			
		||||
            <meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/>
 | 
			
		||||
            -->
 | 
			
		||||
            <!-- Splash screen -->
 | 
			
		||||
 | 
			
		||||
            <!-- Background running -->
 | 
			
		||||
            <!-- Warning: changing this value to true may cause unexpected crashes if the
 | 
			
		||||
                          application still try to draw after
 | 
			
		||||
                          "applicationStateChanged(Qt::ApplicationSuspended)"
 | 
			
		||||
                          signal is sent! -->
 | 
			
		||||
            <meta-data android:name="android.app.background_running" android:value="false"/>
 | 
			
		||||
            <!-- Background running -->
 | 
			
		||||
 | 
			
		||||
            <!-- auto screen scale factor -->
 | 
			
		||||
            <meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
 | 
			
		||||
            <!-- auto screen scale factor -->
 | 
			
		||||
        </activity>
 | 
			
		||||
        <service android:enabled="true" android:name=".LocalService"/>
 | 
			
		||||
    </application>
 | 
			
		||||
 | 
			
		||||
    <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
 | 
			
		||||
         Remove the comment if you do not require these default permissions. -->
 | 
			
		||||
    <!-- %%INSERT_PERMISSIONS -->
 | 
			
		||||
 | 
			
		||||
    <!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
 | 
			
		||||
         Remove the comment if you do not require these default features. -->
 | 
			
		||||
    <!-- %%INSERT_FEATURES -->
 | 
			
		||||
 | 
			
		||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 | 
			
		||||
</manifest>
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 36 KiB  | 
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 1.9 KiB  | 
| 
						 | 
				
			
			@ -1,4 +0,0 @@
 | 
			
		|||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:layout_width="fill_parent"
 | 
			
		||||
    android:layout_height="fill_parent" />
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Ministro-Dienst wurde nicht gefunden.\nAnwendung kann nicht gestartet werden</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Diese Anwendung benötigt den Ministro-Dienst. Möchten Sie ihn installieren?</string>
 | 
			
		||||
    <string name="fatal_error_msg">In Ihrer Anwendung ist ein schwerwiegender Fehler aufgetreten, sie kann nicht fortgesetzt werden</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Δεν ήταν δυνατή η εύρεση της υπηρεσίας Ministro. Δεν είναι δυνατή η εκκίνηση της εφαρμογής.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Η εφαρμογή απαιτεί την υπηρεσία Ministro. Να εγκατασταθεί η υπηρεσία?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Παρουσιάστηκε ένα κρίσιμο σφάλμα και η εφαρμογή δεν μπορεί να συνεχίσει.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Servicio Ministro inesistente. Imposible ejecutar la aplicación.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Esta aplicación requiere el servicio Ministro. Instalarlo?</string>
 | 
			
		||||
    <string name="fatal_error_msg">La aplicación ha causado un error grave y no es posible continuar.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Ei suuda leida Ministro teenust.\nProgrammi ei saa käivitada.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">See programm vajab Ministro teenust.\nKas soovite paigaldada?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Programmiga juhtus fataalne viga.\nKahjuks ei saa jätkata.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">سرویس Ministro را پیدا نمیکند. برنامه نمیتواند آغاز شود.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">این نرمافزار به سرویس Ministro احتیاج دارد. آیا دوست دارید آن را نصب کنید؟</string>
 | 
			
		||||
    <string name="fatal_error_msg">خطایی اساسی در برنامهتان رخ داد و اجرای برنامه نمیتواند ادامه یابد.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Le service Ministro est introuvable.\nL\'application ne peut pas démarrer.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Cette application requiert le service Ministro. Voulez-vous l\'installer?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Votre application a rencontré une erreur fatale et ne peut pas continuer.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Layanan Ministro tidak bisa ditemukan.\nAplikasi tidak bisa dimulai.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Aplikasi ini membutuhkan layanan Ministro. Apakah Anda ingin menginstalnya?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Aplikasi Anda mengalami kesalahan fatal dan tidak dapat melanjutkan.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Servizio Ministro inesistente. Impossibile eseguire \nl\'applicazione.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Questa applicazione richiede il servizio Ministro.Installarlo?</string>
 | 
			
		||||
    <string name="fatal_error_msg">L\'applicazione ha provocato un errore grave e non puo\' continuare.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Ministroサービスが見つかりません。\nアプリケーションが起動できません。</string>
 | 
			
		||||
    <string name="ministro_needed_msg">このアプリケーションにはMinistroサービスが必要です。 インストールしてもよろしいですか?</string>
 | 
			
		||||
    <string name="fatal_error_msg">アプリケーションで致命的なエラーが発生したため続行できません。</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Tidak jumpa servis Ministro.\nAplikasi tidak boleh dimulakan.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Aplikasi ini memerlukan servis Ministro. Adakah anda ingin pasang servis itu?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Aplikasi anda menemui ralat muat dan tidak boleh diteruskan.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Kan ikke finne tjenesten Ministro. Applikasjonen kan ikke starte.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Denne applikasjonen krever tjenesten Ministro. Vil du installere denne?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Applikasjonen fikk en kritisk feil og kan ikke fortsette</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">De Ministro service is niet gevonden.\nDe applicatie kan niet starten.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Deze applicatie maakt gebruik van de Ministro service. Wilt u deze installeren?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Er is een fatale fout in de applicatie opgetreden. De applicatie kan niet verder gaan.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Usługa Ministro nie została znaleziona.\nAplikacja nie może zostać uruchomiona.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Aplikacja wymaga usługi Ministro. Czy chcesz ją zainstalować?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Wystąpił błąd krytyczny. Aplikacja zostanie zamknięta.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Não foi possível encontrar o serviço Ministro.\nA aplicação não pode iniciar.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Essa aplicação requer o serviço Ministro. Gostaria de instalá-lo?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Sua aplicação encontrou um erro fatal e não pode continuar.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Serviciul Ministro nu poate fi găsit.\nAplicaţia nu poate porni.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Această aplicaţie necesită serviciul Ministro.\nDoriţi să-l instalaţi?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Aplicaţia dumneavoastră a întâmpinat o eroare fatală şi nu poate continua.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Ministro servise nije pronađen. Aplikacija ne može biti pokrenuta.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Ova aplikacija zahteva Ministro servis. Želite li da ga instalirate?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Vaša aplikacija je naišla na fatalnu grešku i ne može nastaviti sa radom.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">Сервис Ministro не найден.\nПриложение нельзя запустить.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">Этому приложению необходим сервис Ministro. Вы хотите его установить?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Ваше приложение столкнулось с фатальной ошибкой и не может более работать.</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">无法找到Ministro服务。\n应用程序无法启动。</string>
 | 
			
		||||
    <string name="ministro_needed_msg">此应用程序需要Ministro服务。您想安装它吗?</string>
 | 
			
		||||
    <string name="fatal_error_msg">您的应用程序遇到一个致命错误导致它无法继续。</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="ministro_not_found_msg">無法找到Ministro服務。\n應用程序無法啟動。</string>
 | 
			
		||||
    <string name="ministro_needed_msg">此應用程序需要Ministro服務。您想安裝它嗎?</string>
 | 
			
		||||
    <string name="fatal_error_msg">您的應用程序遇到一個致命錯誤導致它無法繼續。</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,25 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <array name="qt_sources">
 | 
			
		||||
        <item>https://download.qt-project.org/ministro/android/qt5/qt-5.4</item>
 | 
			
		||||
    </array>
 | 
			
		||||
 | 
			
		||||
    <!-- The following is handled automatically by the deployment tool. It should
 | 
			
		||||
         not be edited manually. -->
 | 
			
		||||
 | 
			
		||||
    <array name="bundled_libs">
 | 
			
		||||
        <!-- %%INSERT_EXTRA_LIBS%% -->
 | 
			
		||||
    </array>
 | 
			
		||||
 | 
			
		||||
     <array name="qt_libs">
 | 
			
		||||
         <!-- %%INSERT_QT_LIBS%% -->
 | 
			
		||||
     </array>
 | 
			
		||||
 | 
			
		||||
    <array name="bundled_in_lib">
 | 
			
		||||
        <!-- %%INSERT_BUNDLED_IN_LIB%% -->
 | 
			
		||||
    </array>
 | 
			
		||||
    <array name="bundled_in_assets">
 | 
			
		||||
        <!-- %%INSERT_BUNDLED_IN_ASSETS%% -->
 | 
			
		||||
    </array>
 | 
			
		||||
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +0,0 @@
 | 
			
		|||
<?xml version='1.0' encoding='utf-8'?>
 | 
			
		||||
<resources>
 | 
			
		||||
    <!-- %%INSERT_STRINGS -->
 | 
			
		||||
    <string name="ministro_not_found_msg">Can\'t find Ministro service.\nThe application can\'t start.</string>
 | 
			
		||||
    <string name="ministro_needed_msg">This application requires Ministro service. Would you like to install it?</string>
 | 
			
		||||
    <string name="fatal_error_msg">Your application encountered a fatal error and cannot continue.</string>
 | 
			
		||||
    <string name="local_service_started">i2pd started</string>
 | 
			
		||||
    <string name="local_service_stopped">i2pd stopped</string>
 | 
			
		||||
    <string name="local_service_label">i2pd</string>
 | 
			
		||||
</resources>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,60 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
    Copyright (c) 2011-2013, BogDan Vatra <bogdan@kde.org>
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,65 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
    Copyright (c) 2011-2013, BogDan Vatra <bogdan@kde.org>
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,159 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
    Copyright (c) 2012-2013, BogDan Vatra <bogdan@kde.org>
 | 
			
		||||
    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<String, ArrayList<Method>> m_delegateMethods= new HashMap<String, ArrayList<Method>>();
 | 
			
		||||
    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<Method> delegateMethods = new ArrayList<Method>();
 | 
			
		||||
        for (Method m : listener.getClass().getMethods()) {
 | 
			
		||||
            if (m.getDeclaringClass().getName().startsWith("org.qtproject.qt5.android"))
 | 
			
		||||
                delegateMethods.add(m);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ArrayList<Field> applicationFields = new ArrayList<Field>();
 | 
			
		||||
        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<Method> delegateSet = new ArrayList<Method>();
 | 
			
		||||
                    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<elements.length;it++)
 | 
			
		||||
                if (elements[it].getClassName().equals(activityClassName)) {
 | 
			
		||||
                    stackDeep = it;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
        }
 | 
			
		||||
        final String methodName=elements[stackDeep].getMethodName();
 | 
			
		||||
        if (-1 == stackDeep || !m_delegateMethods.containsKey(methodName))
 | 
			
		||||
            return result;
 | 
			
		||||
 | 
			
		||||
        for (Method m : m_delegateMethods.get(methodName)) {
 | 
			
		||||
            if (m.getParameterTypes().length == args.length) {
 | 
			
		||||
                result.methodReturns = invokeDelegateMethod(m, args);
 | 
			
		||||
                result.invoked = true;
 | 
			
		||||
                return result;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Object invokeDelegateMethod(Method m, Object... args)
 | 
			
		||||
    {
 | 
			
		||||
        try {
 | 
			
		||||
            return m.invoke(m_delegateObject, args);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,59 +0,0 @@
 | 
			
		|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 | 
			
		||||
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="ru" class=" ya-page_js_yes"><head>
 | 
			
		||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 | 
			
		||||
 | 
			
		||||
<h1 id="blog_title" style="font-size:14pt; font-weight:normal; margin:0px">
 | 
			
		||||
			OpenSSL под Android в Qt
 | 
			
		||||
 | 
			
		||||
		</h1> <div class="smallfont shade"> <span class="shade">Запись от <a href="http://www.cyberforum.ru/blogs/748276/">Wyn</a> размещена 18.01.2016 в 18:22</span> </div> <script type="text/javascript" src="./patch_openssl_so_libs_files/blog_ajax_tag.js"></script> <div class="smallfont" id="blogtagcontainer_4086"> <span class="shade">Метки</span> <span id="blogtaglist_4086"><a href="http://www.cyberforum.ru/blog.php?tag=android&u=748276">android</a>, <a href="http://www.cyberforum.ru/blog.php?tag=openssl&u=748276">openssl</a>, <a href="http://www.cyberforum.ru/blog.php?tag=qt&u=748276">qt</a></span> </div> <div style="clear:both; margin-top:4px"></div> <hr size="1" style="color:#AAAAAA; background-color:#AAAAAA; margin-bottom:10px">  <div id="blog_message" style="margin-bottom:10px"><!-- google_ad_section_start --><!-- google_ad_section_start -->Мини-руководство по тому, как быстро скомпилировать OpenSSL для Android и связать его с проектом Qt.<br>
 | 
			
		||||
Для Linux.<br> <br>
 | 
			
		||||
Вначале действия полностью идентичны <a rel="nofollow" href="https://wiki.openssl.org/index.php/Android" target="_blank" title="https://wiki.openssl.org/index.php/Android">"расово-верному" руководству по компилянию OpenSSL для Android</a>:<br>
 | 
			
		||||
Качаем исходники openssl нужной версии с их сайта, качаем setenv-android.sh(все ссылки на закачку выше по ссылке).<br>
 | 
			
		||||
Ложим их в одну папку. Запускаем консоль, переходим в ней в эту самую папку.<br>
 | 
			
		||||
Далее:<br> <div style="margin: 5px 10px 5px 30px"><table class="bash"><thead><tr><td colspan="2" class="head">Bash<a href="http://www.cyberforum.ru/#" style="float: right; color: rgb(96, 96, 96); font-weight: normal;">Выделить код</a></td></tr></thead><tbody><tr class="li1"><td><div id="52254522" style="overflow: auto; width: 805px; height: 73px"><table><tbody><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
 | 
			
		||||
2
 | 
			
		||||
3
 | 
			
		||||
</pre></td><td class="de1"><pre class="de1">$ <span class="kw2">rm</span> <span class="re5">-rf</span> openssl-1.0.1g<span class="sy0">/</span>   <span class="co0"># удаляем исходники(вместо версии 1.0.1g - подставляем свою), если они уже были распакованы</span>
 | 
			
		||||
$ <span class="kw2">tar</span> xzf openssl-1.0.1g.tar.gz    <span class="co0"># распаковываем исходники в подпапку</span>
 | 
			
		||||
$ <span class="kw2">chmod</span> a+x setenv-android.sh    <span class="co0"># разрешаем setenv-android.sh исполняться</span></pre></td></tr></tbody></table></div></td></tr></tbody></table></div>Редактируем setenv-android.sh, настраивая там _ANDROID_EABI, _ANDROID_ARCH, _ANDROID_API на нужные значения.<br>
 | 
			
		||||
Дальше возвращаемся в консоль:<br> <div style="margin: 5px 10px 5px 30px"><table class="bash"><thead><tr><td colspan="2" class="head">Bash<a href="http://www.cyberforum.ru/#" style="float: right; color: rgb(96, 96, 96); font-weight: normal;">Выделить код</a></td></tr></thead><tbody><tr class="li1"><td><div id="701353202" style="overflow: auto; width: 805px; height: 201px"><table><tbody><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
 | 
			
		||||
2
 | 
			
		||||
3
 | 
			
		||||
4
 | 
			
		||||
5
 | 
			
		||||
6
 | 
			
		||||
7
 | 
			
		||||
8
 | 
			
		||||
9
 | 
			
		||||
10
 | 
			
		||||
11
 | 
			
		||||
</pre></td><td class="de1"><pre class="de1">$ <span class="kw3">export</span> <span class="re2">ANDROID_NDK_ROOT</span>=путь_до_ANDROID_NDK <span class="co0"># указываем путь до Android NDK для setenv-android.sh</span>
 | 
			
		||||
$ . .<span class="sy0">/</span>setenv-android.sh <span class="co0"># запускаем скрипт, чтобы он нам в окружение проставил необходимые далее переменные</span>
 | 
			
		||||
$ <span class="kw3">cd</span> openssl-1.0.1g<span class="sy0">/</span>
 | 
			
		||||
$ <span class="kw2">perl</span> <span class="re5">-pi</span> <span class="re5">-e</span> <span class="st_h">'s/install: all install_docs install_sw/install: install_docs install_sw/g'</span> Makefile.org
 | 
			
		||||
<span class="co0"># конфигурируем</span>
 | 
			
		||||
$ .<span class="sy0">/</span>config shared no-ssl2 no-ssl3 no-comp no-hw no-engine <span class="re5">--openssldir</span>=<span class="sy0">/</span>usr<span class="sy0">/</span>local<span class="sy0">/</span>ssl<span class="sy0">/</span><span class="re1">$ANDROID_API</span>
 | 
			
		||||
<span class="co0"># собираем</span>
 | 
			
		||||
$ <span class="kw2">make</span> depend
 | 
			
		||||
$ <span class="kw2">make</span> all
 | 
			
		||||
<span class="co0"># устанавливаем</span>
 | 
			
		||||
$ <span class="kw2">sudo</span> <span class="re5">-E</span> <span class="kw2">make</span> <span class="kw2">install</span> <span class="re2">CC</span>=<span class="re1">$ANDROID_TOOLCHAIN</span><span class="sy0">/</span>arm-linux-androideabi-gcc <span class="re2">RANLIB</span>=<span class="re1">$ANDROID_TOOLCHAIN</span><span class="sy0">/</span>arm-linux-androideabi-ranlib</pre></td></tr></tbody></table></div></td></tr></tbody></table></div>И тут начинается интересное. Андроид не принимает versioned shared object (это *.so.x и подобные). Казалось бы 2016 год, космические корабли уже давно бороздят просторы Большого театра, но вот те на. <br> <br>
 | 
			
		||||
Однако, есть обходной приём - нужно заменить *.so.x.x.x на *_x_x_x.so. Простым переименованием файлов данную проблему здесь, разумеется, не решить. Нужно лезть внутрь и переименовывать soname и внутренние ссылки на другие versioned shared object. В интернете есть много способов по подобному переименованию. Большинство из них обещают райскую жизнь с rpl, забывая упомянуть, что утилита уже давно отпета и закопана на большинстве дистрибутивов. Или хитро-хитро редактируют makefile, что в итоге на место левой руки собирается правая нога. В целом множество путей из разряда "как потратить много времени на полную фигню". <br> <br>
 | 
			
		||||
В итоге предлагаю решить данную проблему методом топора:<br>
 | 
			
		||||
Качаем 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, чтобы они вели на них.<br> <br>
 | 
			
		||||
Чтобы подключить и использовать данную библиотеку в проекте нужно добавить в .pro:<br> <div style="margin: 5px 10px 5px 30px"><table class="bash"><thead><tr><td colspan="2" class="head">Bash<a href="http://www.cyberforum.ru/#" style="float: right; color: rgb(96, 96, 96); font-weight: normal;">Выделить код</a></td></tr></thead><tbody><tr class="li1"><td><div id="304166412" style="overflow: auto; width: 805px; height: 105px"><table><tbody><tr class="li1"><td class="ln" style="padding: 0px 10px 0px 5px;"><pre class="de1">1
 | 
			
		||||
2
 | 
			
		||||
3
 | 
			
		||||
4
 | 
			
		||||
5
 | 
			
		||||
</pre></td><td class="de1"><pre class="de1">android: <span class="br0">{</span>
 | 
			
		||||
    INCLUDEPATH += <span class="sy0">/</span>usr<span class="sy0">/</span>local<span class="sy0">/</span>ssl<span class="sy0">/</span>android-<span class="nu0">21</span><span class="sy0">/</span>include
 | 
			
		||||
    LIBS += -L<span class="sy0">/</span>usr<span class="sy0">/</span>local<span class="sy0">/</span>ssl<span class="sy0">/</span>android-<span class="nu0">21</span><span class="sy0">/</span>lib
 | 
			
		||||
<span class="br0">}</span>
 | 
			
		||||
LIBS += <span class="re5">-lcrypto</span></pre></td></tr></tbody></table></div></td></tr></tbody></table></div>А затем в настройках проекта, в Buld/Build Steps/Bulild Android Apk добавить libcrypto_1_0_0.so и libssl_1_0_0.so в список Additional Libraries.<br> <br>
 | 
			
		||||
На этом всё.
 | 
			
		||||
 | 
			
		||||
<br>
 | 
			
		||||
<p><small>Original: http://www.cyberforum.ru/blogs/748276/blog4086.html</small></p>
 | 
			
		||||
 | 
			
		||||
</body></html>
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue