From e8618fdfd7721d4dc25c8bd84ed3c558557a8d9b Mon Sep 17 00:00:00 2001 From: DC* Date: Sun, 12 Jul 2020 01:56:32 -0300 Subject: [PATCH] Respect settings to stop the node when on battery or on data - Using ConnectivityManager to check for changes on network - Using Receivers for Power connection changes - Update Fred with workaround for restarting the node --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 17 +---- .../java/org/freenetproject/mobile/App.java | 11 ++++ .../receivers/PowerConnectionReceiver.java | 14 ++--- .../mobile/receivers/WifiReceiver.java | 32 ---------- .../mobile/services/node/Manager.java | 62 ++++++++----------- .../mobile/services/node/Runner.java | 9 +-- .../mobile/services/node/Service.java | 57 +++++++---------- .../mobile/ui/main/activity/MainFragment.java | 1 - app/src/main/res/values-de/strings.xml | 6 +- app/src/main/res/values-es/strings.xml | 4 +- app/src/main/res/values-fr/strings.xml | 4 +- app/src/main/res/values-pt/strings.xml | 4 +- app/src/main/res/values/strings.xml | 4 +- app/src/main/res/xml/root_preferences.xml | 11 ---- 15 files changed, 82 insertions(+), 156 deletions(-) create mode 100644 app/src/main/java/org/freenetproject/mobile/App.java delete mode 100644 app/src/main/java/org/freenetproject/mobile/receivers/WifiReceiver.java diff --git a/app/build.gradle b/app/build.gradle index 6a4df6f..e969921 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -76,7 +76,7 @@ dependencies { implementation 'com.github.desyncr:onion-common:0.0.1-SNAPSHOT' implementation 'com.github.desyncr:onion-fec:0.0.1-SNAPSHOT' implementation 'com.github.desyncr:freenet-ext:0.60.0-SNAPSHOT' - implementation 'com.github.desyncr:fred:build01485-39-gce6ac' + implementation 'com.github.desyncr:fred:build01485-38-g83761' implementation 'androidx.preference:preference:1.1.1' testImplementation 'junit:junit:4.12' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0bbbb0d..d20d9ed 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,6 +11,7 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/org/freenetproject/mobile/App.java b/app/src/main/java/org/freenetproject/mobile/App.java new file mode 100644 index 0000000..4e1d2cb --- /dev/null +++ b/app/src/main/java/org/freenetproject/mobile/App.java @@ -0,0 +1,11 @@ +package org.freenetproject.mobile; + +import android.app.Application; + +public class App extends Application { + @Override + public void onCreate() { + super.onCreate(); + } + +} diff --git a/app/src/main/java/org/freenetproject/mobile/receivers/PowerConnectionReceiver.java b/app/src/main/java/org/freenetproject/mobile/receivers/PowerConnectionReceiver.java index f8a0634..7c13619 100644 --- a/app/src/main/java/org/freenetproject/mobile/receivers/PowerConnectionReceiver.java +++ b/app/src/main/java/org/freenetproject/mobile/receivers/PowerConnectionReceiver.java @@ -19,18 +19,12 @@ public void onReceive(Context context, Intent intent) { // only if configured to manage start/stop switch(Objects.requireNonNull(intent.getAction())){ case Intent.ACTION_POWER_CONNECTED: - Log.d("Freenet", "Power connected"); - if (Manager.getInstance().isPaused()) { - Log.i("Freenet", "Resuming service"); - Manager.getInstance().resumeService(context); - } + Log.i("Freenet", "Resuming service from power change"); + Manager.getInstance().resumeService(context); break; case Intent.ACTION_POWER_DISCONNECTED: - Log.d("Freenet", "Power disconnected"); - if (Manager.getInstance().isRunning()) { - Log.i("Freenet", "Pausing service"); - Manager.getInstance().pauseService(context); - } + Log.i("Freenet", "Pausing service from power change"); + Manager.getInstance().pauseService(context); break; } } diff --git a/app/src/main/java/org/freenetproject/mobile/receivers/WifiReceiver.java b/app/src/main/java/org/freenetproject/mobile/receivers/WifiReceiver.java deleted file mode 100644 index 42b9cf7..0000000 --- a/app/src/main/java/org/freenetproject/mobile/receivers/WifiReceiver.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.freenetproject.mobile.receivers; - -import android.annotation.SuppressLint; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.util.Log; - -import org.freenetproject.mobile.services.node.Manager; - -/** - * This receiver is only available for android < 21 - */ -public class WifiReceiver extends BroadcastReceiver { - @SuppressLint("UnsafeProtectedBroadcastReceiver") - @Override - public void onReceive(Context context, Intent intent) { - Log.d("Freenet", "Network change detected"); - ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE ); - NetworkInfo activeNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); - boolean isConnected = activeNetInfo != null && activeNetInfo.isConnectedOrConnecting(); - if (isConnected) { - Log.i("Freenet", "Resuming service"); - Manager.getInstance().resumeService(context); - } else { - Log.i("Freenet", "Pausing service"); - Manager.getInstance().pauseService(context); - } - } -} diff --git a/app/src/main/java/org/freenetproject/mobile/services/node/Manager.java b/app/src/main/java/org/freenetproject/mobile/services/node/Manager.java index faddb1c..6275ab0 100644 --- a/app/src/main/java/org/freenetproject/mobile/services/node/Manager.java +++ b/app/src/main/java/org/freenetproject/mobile/services/node/Manager.java @@ -46,26 +46,9 @@ public static Manager getInstance() { } public void init(Status value, Context context) { - if (value == Manager.Status.ERROR) { - new Thread(() -> { - reset(context); - status.postValue(Status.STOPPED); - }).start(); - status.setValue(Status.STOPPED); - return; - } - status.setValue(value); } - public void reset(Context context) { - try { - stopService(context); - } catch (Exception e) { - Log.e("Freenet", "Error stopping service: " + e.getMessage()); - } - } - public LiveData getStatus() { return status; } @@ -97,8 +80,7 @@ public int startService(Context context) { } } - int ret = resumeService(context); - + int ret = startNode(); if (ret == 0) { Intent serviceIntent = new Intent(context, Service.class); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -107,12 +89,32 @@ public int startService(Context context) { context.startService(serviceIntent); } } else { - Log.e("Freenet", "Error starting freenet"); + Log.e("Freenet", "Error starting freenet (" + ret + ")"); + status.postValue(Status.ERROR); } return 0; } + private int startNode() { + status.postValue(Status.STARTING_UP); + int ret = -1; + try { + ret = runner.start(new String[]{Installer.getInstance().getFreenetIniPath()}); + if (ret == 0) { + status.postValue(Status.STARTED); + } else if (ret == -1) { + // Already running + status.postValue(Status.STARTED); + } else { + status.postValue(Status.ERROR); + } + } catch (Exception e) { + status.postValue(Status.ERROR); + } + return ret; + } + /** * Stops the service through the Runner class. Also stops the Services.Node.Service. * @@ -171,25 +173,11 @@ public int pauseService(Context context) { * @return */ public int resumeService(Context context) { - if (isPaused()) { - return -1; + if (!isPaused()) { + return -2; } - status.postValue(Status.STARTING_UP); - int ret = -1; - try { - ret = runner.start(new String[]{Installer.getInstance().getFreenetIniPath()}); - if (ret == 0) { - status.postValue(Status.STARTED); - } else if (ret == -1) { - // Already running - status.postValue(Status.STARTED); - } else { - status.postValue(Status.ERROR); - } - } catch (Exception e) { - status.postValue(Status.ERROR); - } + int ret = startNode(); return ret; } diff --git a/app/src/main/java/org/freenetproject/mobile/services/node/Runner.java b/app/src/main/java/org/freenetproject/mobile/services/node/Runner.java index 4cc4ff6..8a7b555 100644 --- a/app/src/main/java/org/freenetproject/mobile/services/node/Runner.java +++ b/app/src/main/java/org/freenetproject/mobile/services/node/Runner.java @@ -1,11 +1,11 @@ package org.freenetproject.mobile.services.node; import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.tanukisoftware.wrapper.WrapperManager; import java.security.Security; import freenet.node.NodeStarter; +import freenet.node.SemiOrderedShutdownHook; /** * Small wrapper around NodeStarter and WrapperManager to start and stop the node. Also is responsible @@ -46,7 +46,7 @@ public synchronized int start(String[] args) { if (DEBUG) { Thread.sleep(DEBUG_START_DELAY); } else { - NodeStarter.main(args); + NodeStarter.start_osgi(args); } isRunning = true; } catch (IllegalStateException | InterruptedException e) { @@ -73,13 +73,14 @@ public synchronized int stop() { Thread.sleep(DEBUG_STOP_DELAY); } else { NodeStarter.stop_osgi(0); + SemiOrderedShutdownHook.get().run(); } } catch (NullPointerException e){ // Node was already stopped - isRunning = false; } catch (Exception e) { - isRunning = false; return -2; + }finally { + isRunning = false; } return 0; diff --git a/app/src/main/java/org/freenetproject/mobile/services/node/Service.java b/app/src/main/java/org/freenetproject/mobile/services/node/Service.java index a88b7c3..4b134a9 100644 --- a/app/src/main/java/org/freenetproject/mobile/services/node/Service.java +++ b/app/src/main/java/org/freenetproject/mobile/services/node/Service.java @@ -3,69 +3,63 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkRequest; -import android.net.wifi.WifiManager; -import android.os.Build; import android.os.IBinder; import android.util.Log; +import androidx.preference.PreferenceManager; + import org.freenetproject.mobile.receivers.PowerConnectionReceiver; -import org.freenetproject.mobile.receivers.WifiReceiver; import org.freenetproject.mobile.ui.notification.Notification; public class Service extends android.app.Service { - PowerConnectionReceiver pcr = new PowerConnectionReceiver(); - WifiReceiver wr = new WifiReceiver(); + PowerConnectionReceiver powerConnectionReceiver = new PowerConnectionReceiver(); ConnectivityManager connectivityManager; ConnectivityManager.NetworkCallback networkCallback; @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("Freenet", "Called service onStartCommand"); + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + Boolean preserveBattery = sharedPreferences.getBoolean("preserve_battery", true); + Boolean preserveData = sharedPreferences.getBoolean("preserve_data",true); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - // Register power connection receiver + // Register power connection receiver + if (preserveBattery) { IntentFilter powerConnectedFilter = new IntentFilter(); powerConnectedFilter.addAction(Intent.ACTION_POWER_CONNECTED); powerConnectedFilter.addAction(Intent.ACTION_POWER_DISCONNECTED); - registerReceiver(pcr, powerConnectedFilter); + registerReceiver(powerConnectionReceiver, powerConnectedFilter); + } - // register network callback + // Register network callback + if (preserveData) { Context context = getApplicationContext(); NetworkRequest networkRequest = new NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) .build(); - connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); + connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); networkCallback = new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { - Log.i("Freenet", "onAvailable"); - if (Manager.getInstance().isPaused()) { - Log.d("Freenet", "Resuming service"); - Manager.getInstance().resumeService(context); - } + Log.d("Freenet", "Resuming service from network change"); + Manager.getInstance().resumeService(context); } + @Override public void onLost(Network network) { - Log.i("Freenet", "onLost"); - if (Manager.getInstance().isRunning()) { - Log.d("Freenet", "Pausing service"); - Manager.getInstance().pauseService(context); - } + Log.d("Freenet", "Pausing service from network change"); + Manager.getInstance().pauseService(context); } }; connectivityManager.registerNetworkCallback(networkRequest, networkCallback); - } else { - // Register wifi changed intent, only available on Android < O - IntentFilter wifiFilter = new IntentFilter(); - wifiFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - registerReceiver(wr, wifiFilter); } startForeground(1, Notification.show(this)); @@ -77,15 +71,12 @@ public void onLost(Network network) { @Override public void onDestroy() { Log.i("Freenet", "Stopping service"); + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + Boolean preserveBattery = sharedPreferences.getBoolean("preserve_battery", true); + Boolean preserveData = sharedPreferences.getBoolean("preserve_data",true); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - unregisterReceiver(pcr); - connectivityManager.unregisterNetworkCallback(networkCallback); - } - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { - unregisterReceiver(wr); - } + if (preserveBattery) unregisterReceiver(powerConnectionReceiver); + if (preserveData) connectivityManager.unregisterNetworkCallback(networkCallback); Notification.remove(getApplicationContext()); stopForeground(true); diff --git a/app/src/main/java/org/freenetproject/mobile/ui/main/activity/MainFragment.java b/app/src/main/java/org/freenetproject/mobile/ui/main/activity/MainFragment.java index b9a809b..d06bf5e 100644 --- a/app/src/main/java/org/freenetproject/mobile/ui/main/activity/MainFragment.java +++ b/app/src/main/java/org/freenetproject/mobile/ui/main/activity/MainFragment.java @@ -57,7 +57,6 @@ private void updateControls(Manager m, View view) { controlButton.setOnClickListener(view1 -> { // HACK: Disable toggle button automatic check on click controlButton.setChecked(!controlButton.isChecked()); - new Thread(() -> { // Return right aways if for some reason it is still working (either // starting up or stopping). diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 419d4fd..273c173 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -16,10 +16,10 @@ Batterie- und Datennutzung Freenet Web Daten erhalten - Freenet nutzt Netzwerkdaten intensiv. Wenn diese Option aktiviert ist, wird Freenet nur ausgeführt, wenn eine Verbindung zu Wifi besteht. - Batterie schonen - Freenet kann dazu führen, dass sich der Akku schnell entlädt. Wenn diese Option aktiviert ist, läuft Freenet nur beim Aufladen. + Freenet nutzt Netzwerkdaten intensiv. Wenn diese Option aktiviert ist, wird Freenet nur ausgeführt, wenn eine Verbindung zu Wifi besteht. Der Knoten muss neu gestartet werden, um diese Einstellung zu aktivieren. + Freenet kann dazu führen, dass sich der Akku schnell entlädt. Wenn diese Option aktiviert ist, läuft Freenet nur beim Aufladen. Der Knoten muss neu gestartet werden, um diese Einstellung zu aktivieren. Zugriff auf Freenet vom PC aus Greifen Sie von einem PC oder Tablet auf Freenet zu, das auf Ihrem Telefon ausgeführt wird. Das Gerät muss sich im selben Netzwerk befinden. Freenet ist angehalten. + Batterie schonen \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index a41edbd..ba38234 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -16,9 +16,9 @@ Uso de batería y datos Freenet Web Preservar datos - Freenet hace un uso intensivo de los datos de la red. Con esta opción habilitada, Freenet se ejecutará solo cuando esté conectado a Wifi. + Freenet hace un uso intensivo de los datos de la red. Con esta opción habilitada, Freenet se ejecutará solo cuando esté conectado a Wifi. El nodo debe reiniciarse para activar esta configuración. Conservar la batería - Freenet puede hacer que la batería se descargue rápidamente. Con esta opción habilitada, Freenet solo se ejecutará cuando se cargue. + Freenet puede hacer que la batería se descargue rápidamente. Con esta opción habilitada, Freenet solo se ejecutará cuando se cargue. El nodo debe reiniciarse para activar esta configuración. Acceda a Freenet desde la PC Acceda a Freenet en su teléfono desde una PC o tableta. El dispositivo debe estar en la misma red. Freenet está pausado. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index c716004..47fbd54 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -16,9 +16,9 @@ Utilisation de la batterie et des données Freenet Web Conserver les données - Freenet utilise intensivement les données du réseau. Avec cette option activée, Freenet ne fonctionnera que lorsqu\'il sera connecté au Wifi. + Freenet utilise intensivement les données du réseau. Avec cette option activée, Freenet ne fonctionnera que lorsqu\'il sera connecté au Wifi. Le nœud doit être redémarré pour activer ce paramètre. Préserver la batterie - Freenet peut provoquer une décharge rapide de la batterie. Avec cette option activée, Freenet ne fonctionnera que lors du chargement. + Freenet peut provoquer une décharge rapide de la batterie. Avec cette option activée, Freenet ne fonctionnera que lors du chargement. Le nœud doit être redémarré pour activer ce paramètre. Accéder à Freenet depuis un PC Accédez à Freenet en cours d\'exécution sur votre téléphone depuis un PC ou une tablette. L\'appareil doit être sur le même réseau. Freenet est en pause. diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 79ab6f3..a0d6824 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -16,9 +16,9 @@ Bateria e uso de dados Freenet Web Preservar dados - A Freenet faz um uso intensivo dos dados da rede. Com esta opção ativada, o Freenet será executado apenas quando conectado ao Wifi. + A Freenet faz um uso intensivo dos dados da rede. Com esta opção ativada, o Freenet será executado apenas quando conectado ao Wifi. O nó deve ser reiniciado para ativar esta configuração. Preservar bateria - O Freenet pode fazer com que a bateria descarregue rapidamente. Com esta opção ativada, o Freenet funcionará apenas durante o carregamento. + O Freenet pode fazer com que a bateria descarregue rapidamente. Com esta opção ativada, o Freenet funcionará apenas durante o carregamento. O nó deve ser reiniciado para ativar esta configuração. Acesse o Freenet a partir do PC Acesse o Freenet em execução no seu telefone a partir de um PC ou tablet. O dispositivo deve estar na mesma rede. Freenet está em pausa. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c363484..8692112 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -18,9 +18,9 @@ Freenet Web Preserve data - Freenet makes an intensive use of network data. With this option enabled Freenet will run only when connected to Wifi. + Freenet makes an intensive use of network data. With this option enabled Freenet will run only when connected to Wifi.\n\nThe node must be restarted to activate this setting. Preserve battery - Freenet may cause the battery to discharge quickly. With this option enabled Freenet will run only when charging. + Freenet may cause the battery to discharge quickly. With this option enabled Freenet will run only when charging.\n\nThe node must be restarted to activate this setting. Access Freenet from PC Access Freenet running on your phone from a PC or Tablet. The device must be on the same network. diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index d458c1c..b795b31 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -18,15 +18,4 @@ - - - - - - \ No newline at end of file