From 58a9c2935ceda13c737c11742446d0192668fc20 Mon Sep 17 00:00:00 2001 From: Adrian Tiberius Date: Thu, 16 Jun 2016 07:23:11 +0300 Subject: [PATCH] Moved geth to service --- android/app/src/main/AndroidManifest.xml | 5 + .../main/java/com/statusim/GethService.java | 149 ++++++++++++++++++ .../main/java/com/statusim/MainActivity.java | 110 +++++++++---- 3 files changed, 234 insertions(+), 30 deletions(-) create mode 100644 android/app/src/main/java/com/statusim/GethService.java diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d8e1a14016..42b5ee2517 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -22,6 +22,11 @@ + diff --git a/android/app/src/main/java/com/statusim/GethService.java b/android/app/src/main/java/com/statusim/GethService.java new file mode 100644 index 0000000000..7033cd303e --- /dev/null +++ b/android/app/src/main/java/com/statusim/GethService.java @@ -0,0 +1,149 @@ +package com.statusim; + +import android.app.Service; +import android.content.Intent; +import android.os.Handler; +import android.os.AsyncTask; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.Messenger; +import android.support.annotation.Nullable; +import android.util.Log; +import android.os.Environment; + +import java.lang.ref.WeakReference; + +import com.facebook.react.common.ApplicationHolder; +import com.github.ethereum.go_ethereum.cmd.Geth; + +import java.io.File; + +public class GethService extends Service { + + private static final String TAG = "GethService"; + + private static boolean isGethStarted = false; + private static boolean isGethInitialized = false; + private final Handler handler = new Handler(); + + static class IncomingHandler extends Handler { + + private final WeakReference service; + + IncomingHandler(GethService service) { + + this.service = new WeakReference(service); + } + + @Override + public void handleMessage(Message message) { + + GethService service = this.service.get(); + if (service != null) { + if (!service.handleMessage(message)) { + super.handleMessage(message); + } + } + } + } + + final Messenger serviceMessenger = new Messenger(new IncomingHandler(this)); + + protected class StartTask extends AsyncTask { + + public StartTask() { + } + + protected Void doInBackground(Void... args) { + startGeth(); + return null; + } + + protected void onPostExecute(Void results) { + onGethStarted(); + } + } + + protected void onGethStarted() { + Log.d(TAG, "Geth Service started"); + isGethStarted = true; + //Log.w("Geth", "adding peer"); + //Geth.run("--exec admin.addPeer(\"enode://e2f28126720452aa82f7d3083e49e6b3945502cb94d9750a15e27ee310eed6991618199f878e5fbc7dfa0e20f0af9554b41f491dc8f1dbae8f0f2d37a3a613aa@139.162.13.89:55555\") attach http://localhost:8545"); + } + + protected void startGeth() { + Log.d(TAG, "Starting background Geth Service"); + + File extStore = Environment.getExternalStorageDirectory(); + + final String dataFolder = extStore.exists() ? + extStore.getAbsolutePath() : + getApplicationInfo().dataDir; + + final Runnable addPeer = new Runnable() { + public void run() { + Log.w("Geth", "adding peer"); + Geth.run("--exec admin.addPeer(\"enode://e2f28126720452aa82f7d3083e49e6b3945502cb94d9750a15e27ee310eed6991618199f878e5fbc7dfa0e20f0af9554b41f491dc8f1dbae8f0f2d37a3a613aa@139.162.13.89:55555\") attach http://localhost:8545"); + } + }; + + new Thread(new Runnable() { + public void run() { + Geth.run("--shh --ipcdisable --nodiscover --rpc --rpcapi db,eth,net,web3,shh,admin --fast --datadir=" + dataFolder); + } + }).start(); + + handler.postDelayed(addPeer, 5000); + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return serviceMessenger.getBinder(); + } + + @Override + public void onCreate() { + super.onCreate(); + //SoLoader.init(this, /* native exopackage */ false); + /* + try { + ApplicationHolder.getApplication(); + } + catch (AssertionError err) { + ApplicationHolder.setApplication(getApplication()); + } +*/ + System.loadLibrary("gethraw"); + System.loadLibrary("geth"); + + if (!isGethInitialized) { + isGethInitialized = true; + new StartTask().execute(); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + //stop geth + isGethStarted = false; + isGethInitialized = false; + Log.d(TAG, "Geth Service stopped !"); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return Service.START_STICKY; + } + + protected boolean handleMessage(Message message) { + return false; + } + + public static boolean isRunning() + { + return isGethInitialized; + } +} diff --git a/android/app/src/main/java/com/statusim/MainActivity.java b/android/app/src/main/java/com/statusim/MainActivity.java index cf17707c29..85348bec41 100644 --- a/android/app/src/main/java/com/statusim/MainActivity.java +++ b/android/app/src/main/java/com/statusim/MainActivity.java @@ -7,17 +7,24 @@ import com.facebook.react.ReactPackage; import com.facebook.react.shell.MainReactPackage; import com.rt2zz.reactnativecontacts.ReactNativeContacts; import android.os.Bundle; -import android.os.Environment; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnCancelListener; -import com.github.ethereum.go_ethereum.cmd.Geth; +import android.content.ComponentName; +import android.content.ServiceConnection; +import android.content.Intent; +import android.content.Context; + import com.bitgo.randombytes.RandomBytesPackage; import com.BV.LinearGradient.LinearGradientPackage; import com.centaurwarchief.smslistener.SmsListener; -import android.os.Handler; + import android.util.Log; import java.util.Arrays; @@ -32,45 +39,70 @@ import io.realm.react.RealmReactPackage; public class MainActivity extends ReactActivity { - final Handler handler = new Handler(); + /** + * Incoming message handler. Calls to its binder are sequential! + */ + protected final IncomingHandler handler = new IncomingHandler(); + + /** Flag indicating if the service is bound. */ + protected boolean isBound; + + /** Sends messages to the service. */ + protected Messenger serviceMessenger = null; + + /** Receives messages from the service. */ + protected Messenger clientMessenger = new Messenger(handler); + + class IncomingHandler extends Handler { + + @Override + public void handleMessage(Message message) { + + boolean isClaimed = false; + System.out.println("!!!!!!!!!!!!!! Received Service Message !!!!!!!!!!!!!!"); + super.handleMessage(message); + } + } + + protected ServiceConnection serviceConnection = new ServiceConnection() { + + public void onServiceConnected(ComponentName className, IBinder service) { + + // This is called when the connection with the service has been + // established, giving us the object we can use to + // interact with the service. We are communicating with the + // service using a Messenger, so here we get a client-side + // representation of that from the raw IBinder object. + serviceMessenger = new Messenger(service); + isBound = true; + onConnected(); + } + + public void onServiceDisconnected(ComponentName className) { + + // This is called when the connection with the service has been + // unexpectedly disconnected -- that is, its process crashed. + serviceMessenger = null; + isBound = false; + System.out.println("!!!!!!!!!!!!!! Geth Service Disconnected !!!!!!!!!!!!!!"); + } + }; + + protected void onConnected() { + System.out.println("!!!!!!!!!!!!!! Geth Service Connected !!!!!!!!!!!!!!"); + } protected void startStatus() { // Required because of crazy APN settings redirecting localhost (found in GB) Properties properties = System.getProperties(); properties.setProperty("http.nonProxyHosts", "localhost|127.0.0.1"); properties.setProperty("https.nonProxyHosts", "localhost|127.0.0.1"); - - File extStore = Environment.getExternalStorageDirectory(); - - final String dataFolder = extStore.exists() ? - extStore.getAbsolutePath() : - getApplicationInfo().dataDir; - - // Launch! - final Runnable addPeer = new Runnable() { - public void run() { - Log.w("Geth", "adding peer"); - Geth.run("--exec admin.addPeer(\"enode://e2f28126720452aa82f7d3083e49e6b3945502cb94d9750a15e27ee310eed6991618199f878e5fbc7dfa0e20f0af9554b41f491dc8f1dbae8f0f2d37a3a613aa@139.162.13.89:55555\") attach http://localhost:8545"); - } - }; - new Thread(new Runnable() { - public void run() { - Geth.run("--shh --ipcdisable --nodiscover --rpc --rpcapi db,eth,net,web3,shh,admin --fast --datadir=" + dataFolder); - - } - }).start(); - handler.postDelayed(addPeer, 5000); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // Required for android-16 (???) - // Crash if put in startStatus() ? - System.loadLibrary("gethraw"); - System.loadLibrary("geth"); - if(!RootUtil.isDeviceRooted()) { startStatus(); } else { @@ -96,9 +128,27 @@ public class MainActivity extends ReactActivity { }).create(); dialog.show(); } + Intent intent = new Intent(this, GethService.class); + if (!GethService.isRunning()) { + startService(intent); + } + if (serviceConnection != null && GethService.isRunning()) { + bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); + } } + @Override + protected void onDestroy() { + super.onDestroy(); + try { + unbindService(serviceConnection); + } + catch (Throwable t) { + Log.e("MainActivity", "Failed to unbind from the geth service", t); + } + } + /** * Returns the name of the main component registered from JavaScript. * This is used to schedule rendering of the component.