From cd5ba362c2d7cffce1d0ddd10497bdee8e6c6668 Mon Sep 17 00:00:00 2001 From: DC* Date: Sat, 1 May 2021 00:54:46 +0100 Subject: [PATCH 1/3] Upgrade to node-wrapper 1.1 Signed-off-by: DC* --- app/build.gradle | 4 +- .../mobile/services/node/Manager.java | 169 +++++++----------- .../mobile/ui/main/activity/MainFragment.java | 24 +-- 3 files changed, 85 insertions(+), 112 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 3196e78..bc05ea1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,7 @@ android { } defaultConfig { applicationId "org.freenetproject.mobile" - minSdkVersion 22 + minSdkVersion 26 targetSdkVersion 30 versionCode 303 versionName '0.3.2-beta' @@ -55,7 +55,7 @@ dependencies { implementation 'com.google.guava:guava:24.1-jre' // Freenet dependencies - implementation ('com.github.freenet-mobile:node-wrapper:0.6') { + implementation ('com.github.freenet-mobile:node-wrapper:1.1') { exclude group: 'org.freenetproject', module: 'freenet-ext' exclude group: 'net.java.dev.jna', module: 'jna' exclude group: 'net.java.dev.jna', module: 'jna-platform' 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 cf065b7..19e1085 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 @@ -2,8 +2,8 @@ import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.res.Resources; -import android.os.Build; import android.util.Log; import androidx.lifecycle.LiveData; @@ -11,48 +11,46 @@ import com.jakewharton.processphoenix.ProcessPhoenix; +import org.freenetproject.mobile.NodeController; +import org.freenetproject.mobile.NodeControllerImpl; import org.freenetproject.mobile.R; import org.freenetproject.mobile.ui.main.activity.MainActivity; -import java.io.FileNotFoundException; +import java.io.File; +import java.io.IOException; import java.util.HashMap; import java.util.Map; -import org.freenetproject.mobile.Runner; -import org.freenetproject.mobile.Installer; - /** * Class responsible for exposing data to the UI. It also exposes methods for the UI to interact with, * such as startService and stopService. */ public class Manager { - + public static final String CONTEXT_NETWORK = "network"; + public static final String CONTEXT_BATTERY = "battery"; private static Manager instance = null; - private final Runner runner = Runner.getInstance(); + private final Map contextRunFlag = new HashMap() {{ + put(CONTEXT_NETWORK, true); + put(CONTEXT_BATTERY, true); + }}; + // when adding a new state that has transitions be sure to update isTransitioning method public enum Status { STARTING_UP, STARTED, STOPPING, STOPPED, ERROR, - INSTALLING, PAUSED, - PAUSING // when adding a new state that has transitions be sure to update isTransitioning method + PAUSING } - public static final String CONTEXT_NETWORK = "network"; - public static final String CONTEXT_BATTERY = "battery"; + private NodeController nc; + private final MutableLiveData status = new MutableLiveData(); - private Map contextRunFlag = new HashMap() {{ - put(CONTEXT_NETWORK, true); - put(CONTEXT_BATTERY, true); - }}; - - private MutableLiveData status = new MutableLiveData(); private Manager() { status.postValue( - runner.isStarted() ? Status.STARTED : Status.STOPPED + nc != null && nc.isRunning() ? Status.STARTED : Status.STOPPED ); } @@ -77,92 +75,73 @@ public LiveData getStatus() { * Checks if the node is installed and install it otherwise. * * @param context Application context. - * @return */ - public int startService(Context context) { - if (!Installer.getInstance().isInstalled()) { - status.postValue(Status.INSTALLING); - try { - Resources res = context.getResources(); - Installer.getInstance().install( - context.getDir("data", Context.MODE_PRIVATE).getAbsolutePath(), - res.openRawResource(R.raw.seednodes), - res.openRawResource(R.raw.freenet), - res.openRawResource(R.raw.bookmarks), - res.getConfiguration().locale.getDisplayLanguage() - ); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - } + public void startService(Context context) throws IOException { + File path = context.getDir("data", Context.MODE_PRIVATE); - int ret = startNode(); - if (ret == 0) { - Intent serviceIntent = new Intent(context, Service.class); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - context.startForegroundService(serviceIntent); - } else { - context.startService(serviceIntent); - } - } else { - Log.e("Freenet", "Error starting freenet (" + ret + ")"); - status.postValue(Status.ERROR); + status.postValue(Status.STARTING_UP); + + nc = new NodeControllerImpl(path.toPath()); + + SharedPreferences prefs = context.getSharedPreferences( + context.getPackageName(), Context.MODE_PRIVATE + ); + + Resources res = context.getResources(); + // Setup first-run configuration + if (prefs.getBoolean("first-run", true)) { + nc.setConfig("seednodes.fref", res.openRawResource(R.raw.seednodes)); + nc.setConfig("bookmarks.dat", res.openRawResource(R.raw.bookmarks)); } - return 0; - } + nc.start(); - 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); + if (nc.isRunning()) { + + if (prefs.getBoolean("first-run", true)) { + // Setup first-run runtime configuration + nc.setConfig("node.l10n", res.getConfiguration().getLocales().get(0).toLanguageTag()); } - } catch (Exception e) { + + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean("first-run", false); + editor.apply(); + + Intent serviceIntent = new Intent(context, Service.class); + context.startForegroundService(serviceIntent); + status.postValue(Status.STARTED); + + } else { status.postValue(Status.ERROR); } - return ret; + } /** * Stops the service through the Runner class. Also stops the Services.Node.Service. * * @param context Application context. - * @return */ - public int stopService(Context context) { + public void stopService(Context context) { Intent serviceIntent = new Intent(context, Service.class); context.stopService(serviceIntent); try { - if (runner.stop() != 0) { - status.postValue(Status.ERROR); - } - + nc.shutdown(); status.postValue(Status.STOPPED); - } catch (Exception e) { status.postValue(Status.ERROR); } - return 0; } /** * Stop the node and restart the application. * - * @param context - * @return + * @param context Application context */ - public int restartService(Context context) { + public void restartService(Context context) { stopService(context); Log.i("Freenet", "Calling rebirth"); @@ -174,73 +153,64 @@ public int restartService(Context context) { ) ); - return 0; } /** * Pauses the node running on the device while maintaining the service running on foreground. * - * @param context - * @return + * @param context Application context + * @param serviceContext String description for the calling context */ - public int pauseService(Context context, String serviceContext) { + public void pauseService(Context context, String serviceContext) { if (isPaused()) { - return -1; + return; } contextRunFlag.put(serviceContext, false); status.postValue(Status.PAUSING); try { - if (runner.pause() == 0) { - status.postValue(Status.PAUSED); - } else { - status.postValue(Status.ERROR); - - } + nc.pause(); + status.postValue(Status.PAUSED); } catch (Exception e) { status.postValue(Status.ERROR); } - return 0; } /** * Starts up or resume a service. * - * @param context - * @return + * @param context Application context + * @param serviceContext String description for the calling context */ - public int resumeService(Context context, String serviceContext) { + public void resumeService(Context context, String serviceContext) { if (!isPaused()) { - return -2; + return; } contextRunFlag.put(serviceContext, true); for (Boolean value : contextRunFlag.values()) { - if (!value) - return -3; // a given context has flagged not to run + if (!value) { + return; // a given context has flagged not to run + } } status.postValue(Status.STARTING_UP); try { - if (runner.resume() == 0) { - status.postValue(Status.STARTED); - } else { - status.postValue(Status.ERROR); - } + nc.resume(); + status.postValue(Status.STARTED); } catch (Exception e) { status.postValue(Status.ERROR); } - return 0; } - public Boolean resetService(Context context) { + public void resetService(Context context) { Intent serviceIntent = new Intent(context, Service.class); context.stopService(serviceIntent); try { - runner.stop(); + nc.shutdown(); } catch (Exception e) { Log.e("Freenet", "Error stopping node: " + e.getMessage()); } @@ -253,7 +223,6 @@ public Boolean resetService(Context context) { MainActivity.class ) ); - return true; } public Boolean isStopped() { 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 5a41f44..775dc10 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 @@ -14,8 +14,6 @@ import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; -import com.google.common.collect.ImmutableMap; - import org.freenetproject.mobile.BuildConfig; import org.freenetproject.mobile.R; import org.freenetproject.mobile.services.node.Manager; @@ -24,18 +22,20 @@ import org.freenetproject.mobile.ui.acknowledgement.activity.AcknowledgementActivity; import org.freenetproject.mobile.ui.acknowledgement.activity.AcknowledgementFragment; import org.freenetproject.mobile.ui.main.viewmodel.MainViewModel; -import org.freenetproject.mobile.ui.notification.Notification; import org.freenetproject.mobile.ui.settings.activity.SettingsActivity; +import java.util.HashMap; +import java.io.IOException; import java.util.Map; public class MainFragment extends Fragment { - static final Map STATUS_ACTION_MAP = ImmutableMap.builder() - .put(Manager.Status.STARTED.ordinal(), R.drawable.ic_baseline_power_settings_new_24) - .put(Manager.Status.PAUSED.ordinal(), R.drawable.ic_baseline_power_settings_new_24) - .put(Manager.Status.STOPPED.ordinal(), R.drawable.ic_baseline_play_circle_outline_24) - .put(Manager.Status.ERROR.ordinal(), R.drawable.ic_baseline_replay_24) - .build(); + static final Map STATUS_ACTION_MAP = new HashMap() {{ + put(Manager.Status.STOPPED.ordinal(), R.drawable.ic_baseline_info_24); + put(Manager.Status.STARTED.ordinal(), R.drawable.ic_baseline_power_settings_new_24); + put(Manager.Status.PAUSED.ordinal(), R.drawable.ic_baseline_power_settings_new_24); + put(Manager.Status.STOPPED.ordinal(), R.drawable.ic_baseline_play_circle_outline_24); + put(Manager.Status.ERROR.ordinal(), R.drawable.ic_baseline_replay_24); + }}; @Override public View onCreateView( @@ -80,7 +80,11 @@ private void updateControls(Manager m, View view) { // When running or paused the node can be shutdown,but it can not // be paused or started. if (m.isStopped()) { - m.startService(view.getContext()); + try { + m.startService(view.getContext()); + } catch (IOException e) { + // Should set an error message + } } else if (m.isRunning() || m.isPaused()) { m.restartService(view.getContext()); } else if (m.hasError()) { From 2f6edbf929bd1987f1e2fd7865ee30f9b464ca7a Mon Sep 17 00:00:00 2001 From: DC* Date: Sun, 2 May 2021 02:27:52 +0100 Subject: [PATCH 2/3] Upgrade to node-wrapper 2 Signed-off-by: DC* --- app/build.gradle | 2 +- .../freenetproject/mobile/services/node/Manager.java | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index bc05ea1..57c64e0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,7 +55,7 @@ dependencies { implementation 'com.google.guava:guava:24.1-jre' // Freenet dependencies - implementation ('com.github.freenet-mobile:node-wrapper:1.1') { + implementation ('com.github.freenet-mobile:node-wrapper:2.0') { exclude group: 'org.freenetproject', module: 'freenet-ext' exclude group: 'net.java.dev.jna', module: 'jna' exclude group: 'net.java.dev.jna', module: 'jna-platform' 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 19e1085..3f4da4e 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 @@ -20,6 +20,7 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.Objects; /** * Class responsible for exposing data to the UI. It also exposes methods for the UI to interact with, @@ -226,22 +227,23 @@ public void resetService(Context context) { } public Boolean isStopped() { - return status.getValue().equals(Status.STOPPED); + return Objects.equals(status.getValue(), Status.STOPPED); } public Boolean isPaused() { - return status.getValue().equals(Status.PAUSED); + return Objects.equals(status.getValue(), Status.PAUSED); } public Boolean isRunning() { - return status.getValue().equals(Status.STARTED); + return Objects.equals(status.getValue(), Status.STARTED); } public Boolean hasError() { - return status.getValue().equals(Status.ERROR); + return Objects.equals(status.getValue(), Status.ERROR); } public Boolean isTransitioning() { Status value = status.getValue(); + assert value != null; return !value.equals(Status.STARTED) && !value.equals(Status.STOPPED) && !value.equals(Status.PAUSED); From 48fdd69e7c699134ed142a37bd4e0d8ce4f32812 Mon Sep 17 00:00:00 2001 From: DC* Date: Thu, 12 Aug 2021 22:00:16 +0100 Subject: [PATCH 3/3] Update build.gradle --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index c26efc9..8ed7f26 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,8 +11,8 @@ android { applicationId "org.freenetproject.mobile" minSdkVersion 26 targetSdkVersion 30 - versionCode 305 - versionName '0.3.4-beta' + versionCode 400 + versionName '1.0.0-beta' testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true