mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-02-02 02:44:15 +00:00
[android] update strings, menus, add reloading tunnels item
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
parent
4e37df26a3
commit
95fa835191
2
android/.gitignore
vendored
2
android/.gitignore
vendored
@ -4,6 +4,7 @@ bin
|
|||||||
libs
|
libs
|
||||||
log*
|
log*
|
||||||
obj
|
obj
|
||||||
|
.cxx
|
||||||
.gradle
|
.gradle
|
||||||
.idea
|
.idea
|
||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
@ -14,3 +15,4 @@ android.iml
|
|||||||
build
|
build
|
||||||
*.iml
|
*.iml
|
||||||
*.local
|
*.local
|
||||||
|
*.jks
|
||||||
|
@ -17,8 +17,9 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@android:style/Theme.Holo.Light.DarkActionBar"
|
android:theme="@android:style/Theme.Holo.Light.DarkActionBar"
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
>
|
>
|
||||||
|
|
||||||
<receiver android:name=".NetworkStateChangeReceiver">
|
<receiver android:name=".NetworkStateChangeReceiver">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
|
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
|
||||||
@ -30,10 +31,10 @@
|
|||||||
android:label="@string/app_name">
|
android:label="@string/app_name">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".I2PDActivity"
|
android:name=".I2PDActivity"
|
||||||
android:label="@string/app_name" />
|
android:label="@string/app_name" />
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "org_purplei2p_i2pd_I2PD_JNI.h"
|
#include "org_purplei2p_i2pd_I2PD_JNI.h"
|
||||||
#include "DaemonAndroid.h"
|
#include "DaemonAndroid.h"
|
||||||
#include "RouterContext.h"
|
#include "RouterContext.h"
|
||||||
|
#include "ClientContext.h"
|
||||||
#include "Transports.h"
|
#include "Transports.h"
|
||||||
|
|
||||||
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
|
JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith
|
||||||
@ -61,6 +62,11 @@ JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels
|
|||||||
i2p::context.SetAcceptsTunnels (true);
|
i2p::context.SetAcceptsTunnels (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs
|
||||||
|
(JNIEnv *env, jclass clazz) {
|
||||||
|
i2p::client::context.ReloadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
|
||||||
(JNIEnv *env, jclass clazz, jboolean isConnected) {
|
(JNIEnv *env, jclass clazz, jboolean isConnected) {
|
||||||
bool isConnectedBool = (bool) isConnected;
|
bool isConnectedBool = (bool) isConnected;
|
||||||
|
@ -27,6 +27,9 @@ JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels
|
|||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startAcceptingTunnels
|
||||||
(JNIEnv *, jclass);
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_reloadTunnelsConfigs
|
||||||
|
(JNIEnv *, jclass);
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
|
JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged
|
||||||
(JNIEnv * env, jclass clazz, jboolean isConnected);
|
(JNIEnv * env, jclass clazz, jboolean isConnected);
|
||||||
|
|
||||||
|
@ -15,13 +15,12 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="@dimen/horizontal_page_margin"
|
android:layout_marginBottom="@dimen/horizontal_page_margin"
|
||||||
android:visibility="gone"
|
android:visibility="gone" />
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/button_request_write_ext_storage_perms"
|
android:id="@+id/button_request_write_ext_storage_perms"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Retry requesting the SD card write permissions"
|
android:text="@string/retryPermRequest"
|
||||||
android:visibility="gone"/>
|
android:visibility="gone" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -15,13 +15,11 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="@dimen/horizontal_page_margin"
|
android:layout_marginBottom="@dimen/horizontal_page_margin"
|
||||||
android:text="SD card write access is required to write the keys and other files to the I2PD folder on SD card."
|
android:text="@string/permRequired" />
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/button_ok"
|
android:id="@+id/button_ok"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="OK"
|
android:text="@string/ok" />
|
||||||
/>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -5,9 +5,8 @@
|
|||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
tools:context=".I2PDActivity">
|
tools:context=".I2PDActivity">
|
||||||
|
|
||||||
<WebView
|
<WebView
|
||||||
android:id="@+id/webview1"
|
android:id="@+id/webview1"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"/>
|
android:layout_height="fill_parent" />
|
||||||
|
</LinearLayout>
|
||||||
</LinearLayout>
|
|
||||||
|
@ -3,23 +3,29 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context=".I2PDActivity">
|
tools:context=".I2PDActivity">
|
||||||
<group android:id="@+id/group_i2pd_control" >
|
|
||||||
|
<group android:id="@+id/group_various">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_stop"
|
android:id="@+id/action_battery_otimizations"
|
||||||
android:orderInCategory="99"
|
android:title="@string/menu_item_battery_optimizations_str" />
|
||||||
android:title="@string/action_stop" />
|
</group>
|
||||||
|
|
||||||
|
<group android:id="@+id/group_i2pd_control">
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_start_webview"
|
||||||
|
android:orderInCategory="96"
|
||||||
|
android:title="@string/action_start_webview" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_reload_tunnels_config"
|
||||||
|
android:orderInCategory="97"
|
||||||
|
android:title="@string/action_reload_tunnels_config" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_graceful_stop"
|
android:id="@+id/action_graceful_stop"
|
||||||
android:orderInCategory="98"
|
android:orderInCategory="98"
|
||||||
android:title="@string/action_graceful_stop" />
|
android:title="@string/action_graceful_stop" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_start_webview"
|
android:id="@+id/action_stop"
|
||||||
android:orderInCategory="97"
|
android:orderInCategory="99"
|
||||||
android:title="@string/action_start_webview" />
|
android:title="@string/action_stop" />
|
||||||
</group>
|
|
||||||
<group android:id="@+id/group_various" >
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_battery_otimizations"
|
|
||||||
android:title="@string/menu_item_battery_optimizations_str" />
|
|
||||||
</group>
|
</group>
|
||||||
</menu>
|
</menu>
|
||||||
|
@ -1,28 +1,40 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">i2pd</string>
|
<string name="app_name">i2pd</string>
|
||||||
|
|
||||||
<string name="action_stop">Остановить</string>
|
<string name="action_stop">Остановить</string>
|
||||||
<string name="action_graceful_stop">Корректная остановка</string>
|
<string name="action_graceful_stop">Корректная остановка</string>
|
||||||
<string name="action_cancel_graceful_stop">Отменить корректную остановку</string>
|
<string name="action_cancel_graceful_stop">Отменить корректную остановку</string>
|
||||||
|
<string name="action_reload_tunnels_config">Перезагрузить туннели</string>
|
||||||
|
<string name="action_start_webview">Открыть Веб Консоль</string>
|
||||||
|
|
||||||
<string name="graceful_stop_is_already_in_progress">Корректная остановка уже запущена</string>
|
<string name="graceful_stop_is_already_in_progress">Корректная остановка уже запущена</string>
|
||||||
<string name="graceful_stop_is_in_progress">Корректная остановка запущена</string>
|
<string name="graceful_stop_is_in_progress">Корректная остановка запущена</string>
|
||||||
|
<string name="gracefulShutdownInProgress">Корректная остановка запущена</string>
|
||||||
|
|
||||||
<string name="already_stopped">Уже остановлено</string>
|
<string name="already_stopped">Уже остановлено</string>
|
||||||
<string name="uninitialized">Приложение инициализируется</string>
|
<string name="uninitialized">Приложение инициализируется</string>
|
||||||
<string name="starting">Приложение запускается</string>
|
<string name="starting">Приложение запускается</string>
|
||||||
<string name="jniLibraryLoaded">Загружены JNI библиотеки</string>
|
<string name="jniLibraryLoaded">Загружены JNI библиотеки</string>
|
||||||
<string name="startedOkay">Приложение запущено</string>
|
<string name="startedOkay">Приложение запущено</string>
|
||||||
<string name="startFailed">Запуск не удался</string>
|
<string name="startFailed">Запуск не удался</string>
|
||||||
<string name="gracefulShutdownInProgress">Корректная остановка запущена</string>
|
|
||||||
<string name="stopped">Приложение было остановлено</string>
|
<string name="stopped">Приложение было остановлено</string>
|
||||||
<string name="remaining">осталось</string>
|
<string name="remaining">осталось</string>
|
||||||
|
|
||||||
<string name="title_activity_i2_pdperms_asker_prompt">Запрос</string>
|
<string name="title_activity_i2_pdperms_asker_prompt">Запрос</string>
|
||||||
<string name="permDenied">Права для записи на SD карту отклонены, вам необходимо предоставить их для продолжения</string>
|
<string name="permDenied">Права для записи на SD карту отклонены, вам необходимо предоставить их для продолжения</string>
|
||||||
|
<string name="permRequired">Права на запись на SD карту необходимы для записи ключей и других файлов в папку I2PD на внутренней памяти.</string>
|
||||||
|
<string name="retryPermRequest">Повторить запрос прав на запись на SD карту</string>
|
||||||
|
|
||||||
<string name="menu_item_battery_optimizations_str">Оптимизации аккумулятора</string>
|
<string name="menu_item_battery_optimizations_str">Оптимизации аккумулятора</string>
|
||||||
<string name="battery_optimizations_enabled">Оптимизации аккумулятора включены</string>
|
<string name="battery_optimizations_enabled">Оптимизации аккумулятора включены</string>
|
||||||
<string name="device_does_not_support_disabling_battery_optimizations">Ваша версия Андроид не поддерживает отключение оптимизаций аккумулятора</string>
|
|
||||||
<string name="battery_optimizations_enabled_explained">Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\nРекомендуется отключить эти оптимизации.</string>
|
<string name="battery_optimizations_enabled_explained">Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\nРекомендуется отключить эти оптимизации.</string>
|
||||||
<string name="battery_optimizations_enabled_dialog" >Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\n\nВам сейчас будет предложено разрешить отключение этих оптимизаций.</string>
|
<string name="battery_optimizations_enabled_dialog">Ваша операционная система осуществляет оптимизации расхода аккумулятора, которые могут приводить к выгрузке I2PD из памяти и прекращению его работы с целью сэкономить заряд аккумулятора.\n\nВам сейчас будет предложено разрешить отключение этих оптимизаций.</string>
|
||||||
<string name="continue_str">Продолжить</string>
|
<string name="continue_str">Продолжить</string>
|
||||||
|
<string name="device_does_not_support_disabling_battery_optimizations">Ваша версия Андроид не поддерживает отключение оптимизаций аккумулятора</string>
|
||||||
<string name="os_version_does_not_support_battery_optimizations_show_os_dialog_api">Ваша версия Андроид не поддерживает показ диалога об оптимизациях аккумулятора для приложений.</string>
|
<string name="os_version_does_not_support_battery_optimizations_show_os_dialog_api">Ваша версия Андроид не поддерживает показ диалога об оптимизациях аккумулятора для приложений.</string>
|
||||||
|
|
||||||
<string name="shutdown_canceled">Плановая остановка отменена</string>
|
<string name="shutdown_canceled">Плановая остановка отменена</string>
|
||||||
|
|
||||||
|
<string name="tunnels_reloading">Перезагрузка конфигурации туннелей...</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,29 +1,41 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
|
||||||
<string name="app_name">i2pd</string>
|
<string name="app_name">i2pd</string>
|
||||||
|
|
||||||
<string name="action_stop">Stop</string>
|
<string name="action_stop">Stop</string>
|
||||||
<string name="action_graceful_stop">Graceful Stop</string>
|
<string name="action_graceful_stop">Graceful Stop</string>
|
||||||
<string name="action_cancel_graceful_stop">Cancel Graceful Stop</string>
|
<string name="action_cancel_graceful_stop">Cancel Graceful Stop</string>
|
||||||
|
<string name="action_reload_tunnels_config">Reload tunnels</string>
|
||||||
|
<string name="action_start_webview">Open Web Console</string>
|
||||||
|
|
||||||
<string name="graceful_stop_is_already_in_progress">Graceful stop is already in progress</string>
|
<string name="graceful_stop_is_already_in_progress">Graceful stop is already in progress</string>
|
||||||
<string name="graceful_stop_is_in_progress">Graceful stop is in progress</string>
|
<string name="graceful_stop_is_in_progress">Graceful stop is in progress</string>
|
||||||
|
<string name="gracefulShutdownInProgress">Graceful shutdown in progress</string>
|
||||||
|
|
||||||
<string name="already_stopped">Already stopped</string>
|
<string name="already_stopped">Already stopped</string>
|
||||||
<string name="uninitialized">Application initializing</string>
|
<string name="uninitialized">Application initializing</string>
|
||||||
<string name="starting">Application starting</string>
|
<string name="starting">Application starting</string>
|
||||||
<string name="jniLibraryLoaded">Loaded JNI libraries</string>
|
<string name="jniLibraryLoaded">Loaded JNI libraries</string>
|
||||||
<string name="startedOkay">Application Started</string>
|
<string name="startedOkay">Application Started</string>
|
||||||
<string name="startFailed">Start failed</string>
|
<string name="startFailed">Start failed</string>
|
||||||
<string name="gracefulShutdownInProgress">Graceful shutdown in progress</string>
|
|
||||||
<string name="stopped">Application stopped</string>
|
<string name="stopped">Application stopped</string>
|
||||||
<string name="remaining">remaining</string>
|
<string name="remaining">remaining</string>
|
||||||
|
<string name="ok">OK</string>
|
||||||
|
|
||||||
<string name="title_activity_i2_pdperms_asker_prompt">Prompt</string>
|
<string name="title_activity_i2_pdperms_asker_prompt">Prompt</string>
|
||||||
<string name="permDenied">SD card write permission denied, you need to allow this to continue</string>
|
<string name="permDenied">SD card write permission denied, you need to allow this to continue</string>
|
||||||
|
<string name="permRequired">SD card write access is required to write the keys and other files to the I2PD folder on SD card.</string>
|
||||||
|
<string name="retryPermRequest">Retry requesting the SD card write permissions</string>
|
||||||
|
|
||||||
|
<string name="menu_item_battery_optimizations_str">Battery Optimizations</string>
|
||||||
<string name="battery_optimizations_enabled">Battery optimizations enabled</string>
|
<string name="battery_optimizations_enabled">Battery optimizations enabled</string>
|
||||||
<string name="battery_optimizations_enabled_explained">Your Android is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\nIt is recommended to allow disabling those battery optimizations.</string>
|
<string name="battery_optimizations_enabled_explained">Your Android is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\nIt is recommended to allow disabling those battery optimizations.</string>
|
||||||
<string name="battery_optimizations_enabled_dialog" >Your Android is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\n\nYou will now be asked to allow to disable those.</string>
|
<string name="battery_optimizations_enabled_dialog">Your Android is doing some heavy battery optimizations on I2PD that might lead to daemon closing with no other reason.\n\nYou will now be asked to allow to disable those.</string>
|
||||||
<string name="continue_str">Continue</string>
|
<string name="continue_str">Continue</string>
|
||||||
<string name="device_does_not_support_disabling_battery_optimizations">Your Android version does not support opting out of battery optimizations</string>
|
<string name="device_does_not_support_disabling_battery_optimizations">Your Android version does not support opting out of battery optimizations</string>
|
||||||
<string name="menu_item_battery_optimizations_str">Battery Optimizations</string>
|
|
||||||
<string name="os_version_does_not_support_battery_optimizations_show_os_dialog_api">Your Android OS version does not support showing the dialog for battery optimizations for applications.</string>
|
<string name="os_version_does_not_support_battery_optimizations_show_os_dialog_api">Your Android OS version does not support showing the dialog for battery optimizations for applications.</string>
|
||||||
|
|
||||||
<string name="shutdown_canceled">Planned shutdown canceled</string>
|
<string name="shutdown_canceled">Planned shutdown canceled</string>
|
||||||
<string name="action_start_webview">Start webview</string>
|
|
||||||
|
<string name="tunnels_reloading">Reloading tunnels config...</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -10,36 +10,61 @@ import org.purplei2p.i2pd.R;
|
|||||||
public class DaemonSingleton {
|
public class DaemonSingleton {
|
||||||
private static final String TAG = "i2pd";
|
private static final String TAG = "i2pd";
|
||||||
private static final DaemonSingleton instance = new DaemonSingleton();
|
private static final DaemonSingleton instance = new DaemonSingleton();
|
||||||
public interface StateUpdateListener { void daemonStateUpdate(); }
|
|
||||||
|
public interface StateUpdateListener {
|
||||||
|
void daemonStateUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
private final Set<StateUpdateListener> stateUpdateListeners = new HashSet<>();
|
private final Set<StateUpdateListener> stateUpdateListeners = new HashSet<>();
|
||||||
|
|
||||||
public static DaemonSingleton getInstance() { return instance; }
|
public static DaemonSingleton getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
public synchronized void addStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.add(listener); }
|
public synchronized void addStateChangeListener(StateUpdateListener listener) {
|
||||||
public synchronized void removeStateChangeListener(StateUpdateListener listener) { stateUpdateListeners.remove(listener); }
|
stateUpdateListeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void removeStateChangeListener(StateUpdateListener listener) {
|
||||||
|
stateUpdateListeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized void setState(State newState) {
|
private synchronized void setState(State newState) {
|
||||||
if(newState==null)throw new NullPointerException();
|
if (newState == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
|
||||||
State oldState = state;
|
State oldState = state;
|
||||||
if(oldState==null)throw new NullPointerException();
|
|
||||||
if(oldState.equals(newState))return;
|
if (oldState == null)
|
||||||
state=newState;
|
throw new NullPointerException();
|
||||||
|
|
||||||
|
if (oldState.equals(newState))
|
||||||
|
return;
|
||||||
|
|
||||||
|
state = newState;
|
||||||
fireStateUpdate1();
|
fireStateUpdate1();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void stopAcceptingTunnels() {
|
public synchronized void stopAcceptingTunnels() {
|
||||||
if(isStartedOkay()){
|
if (isStartedOkay()) {
|
||||||
setState(State.gracefulShutdownInProgress);
|
setState(State.gracefulShutdownInProgress);
|
||||||
I2PD_JNI.stopAcceptingTunnels();
|
I2PD_JNI.stopAcceptingTunnels();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void startAcceptingTunnels() {
|
public synchronized void startAcceptingTunnels() {
|
||||||
if(isStartedOkay()){
|
if (isStartedOkay()) {
|
||||||
setState(State.startedOkay);
|
setState(State.startedOkay);
|
||||||
I2PD_JNI.startAcceptingTunnels();
|
I2PD_JNI.startAcceptingTunnels();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized void reloadTunnelsConfigs() {
|
||||||
|
if (isStartedOkay()) {
|
||||||
|
I2PD_JNI.reloadTunnelsConfigs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private volatile boolean startedOkay;
|
private volatile boolean startedOkay;
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
@ -64,11 +89,13 @@ public class DaemonSingleton {
|
|||||||
|
|
||||||
private volatile State state = State.uninitialized;
|
private volatile State state = State.uninitialized;
|
||||||
|
|
||||||
public State getState() { return state; }
|
public State getState() {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
setState(State.starting);
|
setState(State.starting);
|
||||||
new Thread(new Runnable(){
|
new Thread(new Runnable() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -76,7 +103,7 @@ public class DaemonSingleton {
|
|||||||
I2PD_JNI.loadLibraries();
|
I2PD_JNI.loadLibraries();
|
||||||
setState(State.jniLibraryLoaded);
|
setState(State.jniLibraryLoaded);
|
||||||
} catch (Throwable tr) {
|
} catch (Throwable tr) {
|
||||||
lastThrowable=tr;
|
lastThrowable = tr;
|
||||||
setState(State.startFailed);
|
setState(State.startFailed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -84,25 +111,27 @@ public class DaemonSingleton {
|
|||||||
synchronized (DaemonSingleton.this) {
|
synchronized (DaemonSingleton.this) {
|
||||||
I2PD_JNI.setDataDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd");
|
I2PD_JNI.setDataDir(Environment.getExternalStorageDirectory().getAbsolutePath() + "/i2pd");
|
||||||
daemonStartResult = I2PD_JNI.startDaemon();
|
daemonStartResult = I2PD_JNI.startDaemon();
|
||||||
if("ok".equals(daemonStartResult)){
|
if ("ok".equals(daemonStartResult)) {
|
||||||
setState(State.startedOkay);
|
setState(State.startedOkay);
|
||||||
setStartedOkay(true);
|
setStartedOkay(true);
|
||||||
}else setState(State.startFailed);
|
} else
|
||||||
|
setState(State.startFailed);
|
||||||
}
|
}
|
||||||
} catch (Throwable tr) {
|
} catch (Throwable tr) {
|
||||||
lastThrowable=tr;
|
lastThrowable = tr;
|
||||||
setState(State.startFailed);
|
setState(State.startFailed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}, "i2pdDaemonStart").start();
|
}, "i2pdDaemonStart").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Throwable lastThrowable;
|
private Throwable lastThrowable;
|
||||||
private String daemonStartResult="N/A";
|
private String daemonStartResult = "N/A";
|
||||||
|
|
||||||
private void fireStateUpdate1() {
|
private void fireStateUpdate1() {
|
||||||
Log.i(TAG, "daemon state change: "+state);
|
Log.i(TAG, "daemon state change: " + state);
|
||||||
for(StateUpdateListener listener : stateUpdateListeners) {
|
for (StateUpdateListener listener : stateUpdateListeners) {
|
||||||
try {
|
try {
|
||||||
listener.daemonStateUpdate();
|
listener.daemonStateUpdate();
|
||||||
} catch (Throwable tr) {
|
} catch (Throwable tr) {
|
||||||
@ -134,8 +163,13 @@ public class DaemonSingleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void stopDaemon() {
|
public synchronized void stopDaemon() {
|
||||||
if(isStartedOkay()){
|
if (isStartedOkay()) {
|
||||||
try {I2PD_JNI.stopDaemon();}catch(Throwable tr){Log.e(TAG, "", tr);}
|
try {
|
||||||
|
I2PD_JNI.stopDaemon();
|
||||||
|
} catch(Throwable tr) {
|
||||||
|
Log.e(TAG, "", tr);
|
||||||
|
}
|
||||||
|
|
||||||
setStartedOkay(false);
|
setStartedOkay(false);
|
||||||
setState(State.stopped);
|
setState(State.stopped);
|
||||||
}
|
}
|
||||||
|
@ -68,42 +68,41 @@ public class I2PDActivity extends Activity {
|
|||||||
|
|
||||||
private static final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
private static final DaemonSingleton daemon = DaemonSingleton.getInstance();
|
||||||
|
|
||||||
private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener =
|
private final DaemonSingleton.StateUpdateListener daemonStateUpdatedListener = new DaemonSingleton.StateUpdateListener() {
|
||||||
new DaemonSingleton.StateUpdateListener() {
|
|
||||||
@Override
|
@Override
|
||||||
public void daemonStateUpdate()
|
public void daemonStateUpdate() {
|
||||||
{
|
|
||||||
processAssets();
|
processAssets();
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
try {
|
try {
|
||||||
if(textView==null) return;
|
if (textView==null)
|
||||||
Throwable tr = daemon.getLastThrowable();
|
return;
|
||||||
if(tr!=null) {
|
Throwable tr = daemon.getLastThrowable();
|
||||||
textView.setText(throwableToString(tr));
|
if (tr!=null) {
|
||||||
return;
|
textView.setText(throwableToString(tr));
|
||||||
}
|
return;
|
||||||
DaemonSingleton.State state = daemon.getState();
|
}
|
||||||
String startResultStr = DaemonSingleton.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : "";
|
DaemonSingleton.State state = daemon.getState();
|
||||||
String graceStr = DaemonSingleton.State.gracefulShutdownInProgress.equals(state) ? String.format(": %s %s", formatGraceTimeRemaining(), getText(R.string.remaining)) : "";
|
String startResultStr = DaemonSingleton.State.startFailed.equals(state) ? String.format(": %s", daemon.getDaemonStartResult()) : "";
|
||||||
textView.setText(String.format("%s%s%s", getText(state.getStatusStringResourceId()), startResultStr, graceStr));
|
String graceStr = DaemonSingleton.State.gracefulShutdownInProgress.equals(state) ? String.format(": %s %s", formatGraceTimeRemaining(), getText(R.string.remaining)) : "";
|
||||||
} catch (Throwable tr) {
|
textView.setText(String.format("%s%s%s", getText(state.getStatusStringResourceId()), startResultStr, graceStr));
|
||||||
Log.e(TAG,"error ignored",tr);
|
} catch (Throwable tr) {
|
||||||
}
|
Log.e(TAG,"error ignored",tr);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
private static volatile long graceStartedMillis;
|
private static volatile long graceStartedMillis;
|
||||||
private static final Object graceStartedMillis_LOCK=new Object();
|
private static final Object graceStartedMillis_LOCK = new Object();
|
||||||
private Menu optionsMenu;
|
private Menu optionsMenu;
|
||||||
|
|
||||||
private static String formatGraceTimeRemaining() {
|
private static String formatGraceTimeRemaining() {
|
||||||
long remainingSeconds;
|
long remainingSeconds;
|
||||||
synchronized (graceStartedMillis_LOCK){
|
synchronized (graceStartedMillis_LOCK) {
|
||||||
remainingSeconds=Math.round(Math.max(0,graceStartedMillis+GRACEFUL_DELAY_MILLIS-System.currentTimeMillis())/1000.0D);
|
remainingSeconds = Math.round(Math.max(0, graceStartedMillis + GRACEFUL_DELAY_MILLIS - System.currentTimeMillis()) / 1000.0D);
|
||||||
}
|
}
|
||||||
long remainingMinutes=(long)Math.floor(remainingSeconds/60.0D);
|
long remainingMinutes = (long)Math.floor(remainingSeconds / 60.0D);
|
||||||
long remSec=remainingSeconds-remainingMinutes*60;
|
long remSec = remainingSeconds - remainingMinutes * 60;
|
||||||
return remainingMinutes+":"+(remSec/10)+remSec%10;
|
return remainingMinutes + ":" + (remSec / 10) + remSec % 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -117,10 +116,8 @@ public class I2PDActivity extends Activity {
|
|||||||
daemonStateUpdatedListener.daemonStateUpdate();
|
daemonStateUpdatedListener.daemonStateUpdate();
|
||||||
|
|
||||||
// request permissions
|
// request permissions
|
||||||
if (Build.VERSION.SDK_INT >= 23)
|
if (Build.VERSION.SDK_INT >= 23) {
|
||||||
{
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
|
|
||||||
{
|
|
||||||
ActivityCompat.requestPermissions(this,
|
ActivityCompat.requestPermissions(this,
|
||||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||||
MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
|
MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
|
||||||
@ -131,7 +128,7 @@ public class I2PDActivity extends Activity {
|
|||||||
doBindService();
|
doBindService();
|
||||||
|
|
||||||
final Timer gracefulQuitTimer = getGracefulQuitTimer();
|
final Timer gracefulQuitTimer = getGracefulQuitTimer();
|
||||||
if(gracefulQuitTimer!=null){
|
if (gracefulQuitTimer!=null) {
|
||||||
long gracefulStopAtMillis;
|
long gracefulStopAtMillis;
|
||||||
synchronized (graceStartedMillis_LOCK) {
|
synchronized (graceStartedMillis_LOCK) {
|
||||||
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS;
|
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS;
|
||||||
@ -148,9 +145,9 @@ public class I2PDActivity extends Activity {
|
|||||||
textView = null;
|
textView = null;
|
||||||
daemon.removeStateChangeListener(daemonStateUpdatedListener);
|
daemon.removeStateChangeListener(daemonStateUpdatedListener);
|
||||||
//cancelGracefulStop0();
|
//cancelGracefulStop0();
|
||||||
try{
|
try {
|
||||||
doUnbindService();
|
doUnbindService();
|
||||||
}catch(Throwable tr){
|
} catch(Throwable tr) {
|
||||||
Log.e(TAG, "", tr);
|
Log.e(TAG, "", tr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,20 +155,20 @@ public class I2PDActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
|
||||||
{
|
{
|
||||||
if (requestCode == MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE) {
|
if (requestCode == MY_PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE) {
|
||||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
||||||
Log.e(TAG, "WR_EXT_STORAGE perm granted");
|
Log.e(TAG, "WR_EXT_STORAGE perm granted");
|
||||||
else {
|
else {
|
||||||
Log.e(TAG, "WR_EXT_STORAGE perm declined, stopping i2pd");
|
Log.e(TAG, "WR_EXT_STORAGE perm declined, stopping i2pd");
|
||||||
i2pdStop();
|
i2pdStop();
|
||||||
//TODO must work w/o this perm, ask orignal
|
//TODO must work w/o this perm, ask orignal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelGracefulStop0() {
|
private void cancelGracefulStop0() {
|
||||||
Timer gracefulQuitTimer = getGracefulQuitTimer();
|
Timer gracefulQuitTimer = getGracefulQuitTimer();
|
||||||
if(gracefulQuitTimer!=null) {
|
if (gracefulQuitTimer != null) {
|
||||||
gracefulQuitTimer.cancel();
|
gracefulQuitTimer.cancel();
|
||||||
setGracefulQuitTimer(null);
|
setGracefulQuitTimer(null);
|
||||||
}
|
}
|
||||||
@ -216,7 +213,8 @@ public class I2PDActivity extends Activity {
|
|||||||
|
|
||||||
private void doBindService() {
|
private void doBindService() {
|
||||||
synchronized (I2PDActivity.class) {
|
synchronized (I2PDActivity.class) {
|
||||||
if (mIsBound) return;
|
if (mIsBound)
|
||||||
|
return;
|
||||||
// Establish a connection with the service. We use an explicit
|
// Establish a connection with the service. We use an explicit
|
||||||
// class name because we want a specific service implementation that
|
// class name because we want a specific service implementation that
|
||||||
// we know will be running in our own process (and thus won't be
|
// we know will be running in our own process (and thus won't be
|
||||||
@ -256,10 +254,11 @@ public class I2PDActivity extends Activity {
|
|||||||
// as you specify a parent activity in AndroidManifest.xml.
|
// as you specify a parent activity in AndroidManifest.xml.
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
|
|
||||||
switch(id){
|
switch(id) {
|
||||||
case R.id.action_stop:
|
case R.id.action_stop:
|
||||||
i2pdStop();
|
i2pdStop();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.action_graceful_stop:
|
case R.id.action_graceful_stop:
|
||||||
synchronized (graceStartedMillis_LOCK) {
|
synchronized (graceStartedMillis_LOCK) {
|
||||||
if (getGracefulQuitTimer() != null)
|
if (getGracefulQuitTimer() != null)
|
||||||
@ -268,9 +267,15 @@ public class I2PDActivity extends Activity {
|
|||||||
i2pdGracefulStop();
|
i2pdGracefulStop();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.action_battery_otimizations:
|
case R.id.action_battery_otimizations:
|
||||||
onActionBatteryOptimizations();
|
onActionBatteryOptimizations();
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case R.id.action_reload_tunnels_config:
|
||||||
|
onReloadTunnelsConfig();
|
||||||
|
return true;
|
||||||
|
|
||||||
case R.id.action_start_webview:
|
case R.id.action_start_webview:
|
||||||
setContentView(R.layout.webview);
|
setContentView(R.layout.webview);
|
||||||
this.webView = (WebView) findViewById(R.id.webview1);
|
this.webView = (WebView) findViewById(R.id.webview1);
|
||||||
@ -291,100 +296,100 @@ public class I2PDActivity extends Activity {
|
|||||||
try {
|
try {
|
||||||
startActivity(new Intent(ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS));
|
startActivity(new Intent(ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS));
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (ActivityNotFoundException e) {
|
||||||
Log.e(TAG,"BATT_OPTIM_DIALOG_ActvtNotFound", e);
|
Log.e(TAG, "BATT_OPTIM_DIALOG_ActvtNotFound", e);
|
||||||
Toast.makeText(this, R.string.os_version_does_not_support_battery_optimizations_show_os_dialog_api, Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, R.string.os_version_does_not_support_battery_optimizations_show_os_dialog_api, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onReloadTunnelsConfig() {
|
||||||
|
Log.d(TAG, "reloading tunnels");
|
||||||
|
daemon.reloadTunnelsConfigs();
|
||||||
|
Toast.makeText(this, R.string.tunnels_reloading, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
private void i2pdStop() {
|
private void i2pdStop() {
|
||||||
cancelGracefulStop0();
|
cancelGracefulStop0();
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
Log.d(TAG, "stopping");
|
Log.d(TAG, "stopping");
|
||||||
try {
|
try {
|
||||||
daemon.stopDaemon();
|
daemon.stopDaemon();
|
||||||
} catch (Throwable tr) {
|
} catch (Throwable tr) {
|
||||||
Log.e(TAG, "", tr);
|
Log.e(TAG, "", tr);
|
||||||
}
|
}
|
||||||
quit(); //TODO make menu items for starting i2pd. On my Android, I need to reboot the OS to restart i2pd.
|
quit(); //TODO make menu items for starting i2pd. On my Android, I need to reboot the OS to restart i2pd.
|
||||||
},"stop").start();
|
}, "stop").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static volatile Timer gracefulQuitTimer;
|
private static volatile Timer gracefulQuitTimer;
|
||||||
|
|
||||||
private void i2pdGracefulStop() {
|
private void i2pdGracefulStop() {
|
||||||
if(daemon.getState()==DaemonSingleton.State.stopped){
|
if (daemon.getState() == DaemonSingleton.State.stopped) {
|
||||||
Toast.makeText(this, R.string.already_stopped,
|
Toast.makeText(this, R.string.already_stopped, Toast.LENGTH_SHORT).show();
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(getGracefulQuitTimer()!=null){
|
if (getGracefulQuitTimer() != null) {
|
||||||
Toast.makeText(this, R.string.graceful_stop_is_already_in_progress,
|
Toast.makeText(this, R.string.graceful_stop_is_already_in_progress, Toast.LENGTH_SHORT).show();
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Toast.makeText(this, R.string.graceful_stop_is_in_progress,
|
Toast.makeText(this, R.string.graceful_stop_is_in_progress, Toast.LENGTH_SHORT).show();
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
Log.d(TAG, "grac stopping");
|
Log.d(TAG, "graceful stopping");
|
||||||
if(daemon.isStartedOkay()) {
|
if (daemon.isStartedOkay()) {
|
||||||
daemon.stopAcceptingTunnels();
|
daemon.stopAcceptingTunnels();
|
||||||
long gracefulStopAtMillis;
|
long gracefulStopAtMillis;
|
||||||
synchronized (graceStartedMillis_LOCK) {
|
synchronized (graceStartedMillis_LOCK) {
|
||||||
graceStartedMillis = System.currentTimeMillis();
|
graceStartedMillis = System.currentTimeMillis();
|
||||||
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS;
|
gracefulStopAtMillis = graceStartedMillis + GRACEFUL_DELAY_MILLIS;
|
||||||
}
|
}
|
||||||
rescheduleGraceStop(null,gracefulStopAtMillis);
|
rescheduleGraceStop(null, gracefulStopAtMillis);
|
||||||
} else {
|
} else
|
||||||
i2pdStop();
|
i2pdStop();
|
||||||
}
|
} catch(Throwable tr) {
|
||||||
} catch(Throwable tr) {
|
Log.e(TAG, "", tr);
|
||||||
Log.e(TAG,"",tr);
|
}
|
||||||
}
|
}, "gracInit").start();
|
||||||
},"gracInit").start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelGracefulStop()
|
private void cancelGracefulStop()
|
||||||
{
|
{
|
||||||
cancelGracefulStop0();
|
cancelGracefulStop0();
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try
|
try {
|
||||||
{
|
Log.d(TAG, "canceling graceful stop");
|
||||||
Log.d(TAG, "canceling grac stop");
|
if (daemon.isStartedOkay()) {
|
||||||
if(daemon.isStartedOkay()) {
|
|
||||||
daemon.startAcceptingTunnels();
|
daemon.startAcceptingTunnels();
|
||||||
runOnUiThread(() -> Toast.makeText(this, R.string.shutdown_canceled, Toast.LENGTH_SHORT).show());
|
runOnUiThread(() -> Toast.makeText(this, R.string.shutdown_canceled, Toast.LENGTH_SHORT).show());
|
||||||
}
|
} else
|
||||||
else
|
i2pdStop();
|
||||||
i2pdStop();
|
} catch(Throwable tr) {
|
||||||
}
|
Log.e(TAG, "", tr);
|
||||||
catch(Throwable tr)
|
}
|
||||||
{
|
}, "gracCancel").start();
|
||||||
Log.e(TAG,"",tr);
|
|
||||||
}
|
|
||||||
},"gracCancel").start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rescheduleGraceStop(Timer gracefulQuitTimerOld, long gracefulStopAtMillis) {
|
private void rescheduleGraceStop(Timer gracefulQuitTimerOld, long gracefulStopAtMillis) {
|
||||||
if(gracefulQuitTimerOld!=null)gracefulQuitTimerOld.cancel();
|
if (gracefulQuitTimerOld != null)
|
||||||
|
gracefulQuitTimerOld.cancel();
|
||||||
|
|
||||||
final Timer gracefulQuitTimer = new Timer(true);
|
final Timer gracefulQuitTimer = new Timer(true);
|
||||||
setGracefulQuitTimer(gracefulQuitTimer);
|
setGracefulQuitTimer(gracefulQuitTimer);
|
||||||
gracefulQuitTimer.schedule(new TimerTask(){
|
gracefulQuitTimer.schedule(new TimerTask() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
i2pdStop();
|
i2pdStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
}, Math.max(0,gracefulStopAtMillis-System.currentTimeMillis()));
|
}, Math.max(0, gracefulStopAtMillis - System.currentTimeMillis()));
|
||||||
final TimerTask tickerTask = new TimerTask() {
|
final TimerTask tickerTask = new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
daemonStateUpdatedListener.daemonStateUpdate();
|
daemonStateUpdatedListener.daemonStateUpdate();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
gracefulQuitTimer.scheduleAtFixedRate(tickerTask,0/*start delay*/,1000/*millis period*/);
|
gracefulQuitTimer.scheduleAtFixedRate(tickerTask, 0/*start delay*/, 1000/*millis period*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Timer getGracefulQuitTimer() {
|
private static Timer getGracefulQuitTimer() {
|
||||||
@ -454,9 +459,9 @@ public class I2PDActivity extends Activity {
|
|||||||
*/
|
*/
|
||||||
private void copyFileAsset(String path) {
|
private void copyFileAsset(String path) {
|
||||||
File file = new File(i2pdpath, path);
|
File file = new File(i2pdpath, path);
|
||||||
if(!file.exists()) {
|
if (!file.exists()) {
|
||||||
try {
|
try {
|
||||||
try (InputStream in = getAssets().open(path) ) {
|
try (InputStream in = getAssets().open(path)) {
|
||||||
try (OutputStream out = new FileOutputStream(file)) {
|
try (OutputStream out = new FileOutputStream(file)) {
|
||||||
byte[] buffer = new byte[1024];
|
byte[] buffer = new byte[1024];
|
||||||
int read = in.read(buffer);
|
int read = in.read(buffer);
|
||||||
@ -475,97 +480,102 @@ public class I2PDActivity extends Activity {
|
|||||||
private void deleteRecursive(File fileOrDirectory) {
|
private void deleteRecursive(File fileOrDirectory) {
|
||||||
if (fileOrDirectory.isDirectory()) {
|
if (fileOrDirectory.isDirectory()) {
|
||||||
File[] files = fileOrDirectory.listFiles();
|
File[] files = fileOrDirectory.listFiles();
|
||||||
if(files!=null) {
|
if (files!=null) {
|
||||||
for (File child : files) {
|
for (File child : files) {
|
||||||
deleteRecursive(child);
|
deleteRecursive(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
boolean deleteResult = fileOrDirectory.delete();
|
boolean deleteResult = fileOrDirectory.delete();
|
||||||
if(!deleteResult)Log.e(TAG, "fileOrDirectory.delete() returned "+deleteResult+", absolute path='"+fileOrDirectory.getAbsolutePath()+"'");
|
if (!deleteResult)
|
||||||
|
Log.e(TAG, "fileOrDirectory.delete() returned " + deleteResult + ", absolute path='" + fileOrDirectory.getAbsolutePath() + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processAssets() {
|
private void processAssets() {
|
||||||
if (!assetsCopied) try {
|
if (!assetsCopied) {
|
||||||
assetsCopied = true; // prevent from running on every state update
|
|
||||||
|
|
||||||
File holderFile = new File(i2pdpath, "assets.ready");
|
|
||||||
String versionName = BuildConfig.VERSION_NAME; // here will be app version, like 2.XX.XX
|
|
||||||
StringBuilder text = new StringBuilder();
|
|
||||||
|
|
||||||
if (holderFile.exists()) {
|
|
||||||
try { // if holder file exists, read assets version string
|
|
||||||
FileReader fileReader = new FileReader(holderFile);
|
|
||||||
|
|
||||||
try {
|
|
||||||
BufferedReader br = new BufferedReader(fileReader);
|
|
||||||
|
|
||||||
try {
|
|
||||||
String line;
|
|
||||||
|
|
||||||
while ((line = br.readLine()) != null) {
|
|
||||||
text.append(line);
|
|
||||||
}
|
|
||||||
}finally {
|
|
||||||
try{
|
|
||||||
br.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
try{
|
|
||||||
fileReader.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if version differs from current app version or null, try to delete certificates folder
|
|
||||||
if (!text.toString().contains(versionName)) try {
|
|
||||||
boolean deleteResult = holderFile.delete();
|
|
||||||
if(!deleteResult)Log.e(TAG, "holderFile.delete() returned "+deleteResult+", absolute path='"+holderFile.getAbsolutePath()+"'");
|
|
||||||
File certPath = new File(i2pdpath, "certificates");
|
|
||||||
deleteRecursive(certPath);
|
|
||||||
}
|
|
||||||
catch (Throwable tr) {
|
|
||||||
Log.e(TAG, "", tr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy assets. If processed file exists, it won't be overwritten
|
|
||||||
copyAsset("addressbook");
|
|
||||||
copyAsset("certificates");
|
|
||||||
copyAsset("tunnels.d");
|
|
||||||
copyAsset("i2pd.conf");
|
|
||||||
copyAsset("subscriptions.txt");
|
|
||||||
copyAsset("tunnels.conf");
|
|
||||||
|
|
||||||
// update holder file about successful copying
|
|
||||||
FileWriter writer = new FileWriter(holderFile);
|
|
||||||
try {
|
try {
|
||||||
writer.append(versionName);
|
assetsCopied = true; // prevent from running on every state update
|
||||||
} finally {
|
|
||||||
try{
|
File holderFile = new File(i2pdpath, "assets.ready");
|
||||||
writer.close();
|
String versionName = BuildConfig.VERSION_NAME; // here will be app version, like 2.XX.XX
|
||||||
}catch (IOException e){
|
StringBuilder text = new StringBuilder();
|
||||||
Log.e(TAG,"on writer close", e);
|
|
||||||
}
|
if (holderFile.exists()) {
|
||||||
}
|
try { // if holder file exists, read assets version string
|
||||||
}
|
FileReader fileReader = new FileReader(holderFile);
|
||||||
catch (Throwable tr)
|
|
||||||
{
|
try {
|
||||||
Log.e(TAG,"on assets copying", tr);
|
BufferedReader br = new BufferedReader(fileReader);
|
||||||
|
|
||||||
|
try {
|
||||||
|
String line;
|
||||||
|
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
text.append(line);
|
||||||
|
}
|
||||||
|
}finally {
|
||||||
|
try {
|
||||||
|
br.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
fileReader.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if version differs from current app version or null, try to delete certificates folder
|
||||||
|
if (!text.toString().contains(versionName))
|
||||||
|
try {
|
||||||
|
boolean deleteResult = holderFile.delete();
|
||||||
|
if (!deleteResult)
|
||||||
|
Log.e(TAG, "holderFile.delete() returned " + deleteResult + ", absolute path='" + holderFile.getAbsolutePath() + "'");
|
||||||
|
File certPath = new File(i2pdpath, "certificates");
|
||||||
|
deleteRecursive(certPath);
|
||||||
|
}
|
||||||
|
catch (Throwable tr) {
|
||||||
|
Log.e(TAG, "", tr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy assets. If processed file exists, it won't be overwritten
|
||||||
|
copyAsset("addressbook");
|
||||||
|
copyAsset("certificates");
|
||||||
|
copyAsset("tunnels.d");
|
||||||
|
copyAsset("i2pd.conf");
|
||||||
|
copyAsset("subscriptions.txt");
|
||||||
|
copyAsset("tunnels.conf");
|
||||||
|
|
||||||
|
// update holder file about successful copying
|
||||||
|
FileWriter writer = new FileWriter(holderFile);
|
||||||
|
try {
|
||||||
|
writer.append(versionName);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
writer.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG,"on writer close", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Throwable tr)
|
||||||
|
{
|
||||||
|
Log.e(TAG,"on assets copying", tr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("BatteryLife")
|
@SuppressLint("BatteryLife")
|
||||||
private void openBatteryOptimizationDialogIfNeeded() {
|
private void openBatteryOptimizationDialogIfNeeded() {
|
||||||
boolean questionEnabled = getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true);
|
boolean questionEnabled = getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true);
|
||||||
Log.i(TAG,"BATT_OPTIM_questionEnabled=="+questionEnabled);
|
Log.i(TAG, "BATT_OPTIM_questionEnabled==" + questionEnabled);
|
||||||
if (!isKnownIgnoringBatteryOptimizations()
|
if (!isKnownIgnoringBatteryOptimizations()
|
||||||
&& android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M
|
&& android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M
|
||||||
&& questionEnabled) {
|
&& questionEnabled) {
|
||||||
@ -576,7 +586,7 @@ public class I2PDActivity extends Activity {
|
|||||||
try {
|
try {
|
||||||
startActivity(new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, Uri.parse(PACKAGE_URI_SCHEME + getPackageName())));
|
startActivity(new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS, Uri.parse(PACKAGE_URI_SCHEME + getPackageName())));
|
||||||
} catch (ActivityNotFoundException e) {
|
} catch (ActivityNotFoundException e) {
|
||||||
Log.e(TAG,"BATT_OPTIM_ActvtNotFound", e);
|
Log.e(TAG, "BATT_OPTIM_ActvtNotFound", e);
|
||||||
Toast.makeText(this, R.string.device_does_not_support_disabling_battery_optimizations, Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, R.string.device_does_not_support_disabling_battery_optimizations, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -595,14 +605,14 @@ public class I2PDActivity extends Activity {
|
|||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
final PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
|
final PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
|
||||||
if (pm == null) {
|
if (pm == null) {
|
||||||
Log.i(TAG, "BATT_OPTIM: POWER_SERVICE==null");
|
Log.i(TAG, "BATT_OPTIM: POWER_SERVICE==null");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
boolean ignoring = pm.isIgnoringBatteryOptimizations(getPackageName());
|
boolean ignoring = pm.isIgnoringBatteryOptimizations(getPackageName());
|
||||||
Log.i(TAG, "BATT_OPTIM: ignoring==" + ignoring);
|
Log.i(TAG, "BATT_OPTIM: ignoring==" + ignoring);
|
||||||
return ignoring;
|
return ignoring;
|
||||||
} else {
|
} else {
|
||||||
Log.i(TAG, "BATT_OPTIM: old sdk version=="+Build.VERSION.SDK_INT);
|
Log.i(TAG, "BATT_OPTIM: old sdk version==" + Build.VERSION.SDK_INT);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -626,12 +636,12 @@ public class I2PDActivity extends Activity {
|
|||||||
//moveTaskToBack(true);
|
//moveTaskToBack(true);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
}catch (Throwable tr) {
|
} catch (Throwable tr) {
|
||||||
Log.e(TAG, "", tr);
|
Log.e(TAG, "", tr);
|
||||||
}
|
}
|
||||||
try{
|
try {
|
||||||
daemon.stopDaemon();
|
daemon.stopDaemon();
|
||||||
}catch (Throwable tr) {
|
} catch (Throwable tr) {
|
||||||
Log.e(TAG, "", tr);
|
Log.e(TAG, "", tr);
|
||||||
}
|
}
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
|
@ -16,6 +16,8 @@ public class I2PD_JNI {
|
|||||||
|
|
||||||
public static native void startAcceptingTunnels();
|
public static native void startAcceptingTunnels();
|
||||||
|
|
||||||
|
public static native void reloadTunnelsConfigs();
|
||||||
|
|
||||||
public static native void onNetworkStateChanged(boolean isConnected);
|
public static native void onNetworkStateChanged(boolean isConnected);
|
||||||
|
|
||||||
public static native void setDataDir(String jdataDir);
|
public static native void setDataDir(String jdataDir);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user