From b4712175449256626a6fd78a75eb869df22cdd51 Mon Sep 17 00:00:00 2001 From: Igor Mandrigin Date: Fri, 25 Jan 2019 15:32:45 +0100 Subject: [PATCH] get rid of status service alltogether --- android/app/src/main/AndroidManifest.xml | 4 - .../ethereum/module/ConnectorHandler.java | 10 -- .../ethereum/module/ServiceConnector.java | 153 ------------------ .../status/ethereum/module/StatusModule.java | 81 ++-------- .../module/StatusNodeEventHandler.java | 5 + .../status/ethereum/module/StatusService.java | 111 ++++--------- .../chat/commands/impl/transactions.cljs | 2 - src/status_im/init/core.cljs | 10 +- src/status_im/native_module/core.cljs | 3 - src/status_im/native_module/impl/module.cljs | 86 +++------- src/status_im/signals/core.cljs | 5 - src/status_im/ui/screens/db.cljs | 5 +- src/status_im/utils/logging/core.cljs | 1 - 13 files changed, 80 insertions(+), 396 deletions(-) delete mode 100644 modules/react-native-status/android/src/main/java/im/status/ethereum/module/ConnectorHandler.java delete mode 100644 modules/react-native-status/android/src/main/java/im/status/ethereum/module/ServiceConnector.java create mode 100644 modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusNodeEventHandler.java diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 520e849b98ec..296f5adf0077 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -75,10 +75,6 @@ - diff --git a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/ConnectorHandler.java b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/ConnectorHandler.java deleted file mode 100644 index 3dbba9b6625f..000000000000 --- a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/ConnectorHandler.java +++ /dev/null @@ -1,10 +0,0 @@ -package im.status.ethereum.module; - - -import android.os.Message; - -public interface ConnectorHandler { - boolean handleMessage(Message message); - void onConnectorConnected(); - void onConnectorDisconnected(); -} diff --git a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/ServiceConnector.java b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/ServiceConnector.java deleted file mode 100644 index 43afd9011856..000000000000 --- a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/ServiceConnector.java +++ /dev/null @@ -1,153 +0,0 @@ -package im.status.ethereum.module; - - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.*; -import android.util.Log; - -import java.util.ArrayList; - -public class ServiceConnector { - - private static final String TAG = "ServiceConnector"; - /** Context of the activity from which this connector was launched */ - private Context context; - - /** The class of the service we want to connect to */ - private Class serviceClass; - - /** Flag indicating if the service is bound. */ - boolean isBound; - - /** Sends messages to the service. */ - Messenger serviceMessenger = null; - - /** Receives messages from the service. */ - Messenger clientMessenger = null; - - private ArrayList handlers = new ArrayList<>(); - - /** Handles incoming messages from service. */ - private class IncomingHandler extends Handler { - - IncomingHandler(HandlerThread thread) { - - super(thread.getLooper()); - } - - @Override - public void handleMessage(Message message) { - - boolean isClaimed = false; - //if (message.obj != null) { - // String identifier = ((Bundle) message.obj).getString("identifier"); - //if (identifier != null) { - - for (ConnectorHandler handler : handlers) { - // if (identifier.equals(handler.getID())) { - isClaimed = handler.handleMessage(message); - // } - } - // } - //} - if (!isClaimed) { - super.handleMessage(message); - } - } - } - - /** - * Class for interacting with the main interface of the service. - */ - private 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; - for (ConnectorHandler handler: handlers) { - handler.onConnectorConnected(); - } - } - - 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; - for (ConnectorHandler handler: handlers) { - handler.onConnectorDisconnected(); - } - } - }; - - ServiceConnector(Context context, Class serviceClass) { - this.context = context; - this.serviceClass = serviceClass; - // Handler thread to avoid running on the main UI thread - HandlerThread handlerThread = new HandlerThread("HandlerThread"); - handlerThread.start(); - // Incoming message handler. Calls to its binder are sequential! - IncomingHandler handler = new IncomingHandler(handlerThread); - clientMessenger = new Messenger(handler); - } - - /** Bind to the service */ - public boolean bindService() { - - if (serviceConnection != null) { - Intent intent = new Intent(context, serviceClass); - context.getApplicationContext().startService(intent); - return context.getApplicationContext().bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); - } else { - return false; - } - } - - /** Unbind from the service */ - public void unbindService() { - - if (isBound && serviceConnection != null) { - context.getApplicationContext().unbindService(serviceConnection); - isBound = false; -/* - Intent intent = new Intent(context, serviceClass); - context.getApplicationContext().stopService(intent); -*/ - } - } - - public void registerHandler(ConnectorHandler handler) { - - if (!handlers.contains(handler)) { - handlers.add(handler); - } - } - - public void removeHandler(ConnectorHandler handler) { - - handlers.remove(handler); - } - - public void sendMessage() { - - Message msg = Message.obtain(null, 0, 0, 0); - msg.replyTo = clientMessenger; - try { - Log.d(TAG, "Sending message to service: "); - serviceMessenger.send(msg); - } catch (RemoteException e) { - Log.e(TAG, "Exception sending message(" + msg.toString() + ") to service: ", e); - } - } -} diff --git a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java index adc8863f6a86..dfc5eb42c3a2 100644 --- a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java +++ b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusModule.java @@ -50,7 +50,7 @@ import javax.annotation.Nullable; -class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventListener, ConnectorHandler, LifecycleObserver { +class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventListener, StatusNodeEventHandler { private static final String TAG = "StatusModule"; private static final String logsZipFileName = "Status-debug-logs.zip"; @@ -60,7 +60,6 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL private final static int TESTNET_NETWORK_ID = 3; private static StatusModule module; - private ServiceConnector status = null; private ExecutorService executor = null; private boolean debug; private boolean devCluster; @@ -87,45 +86,12 @@ public String getName() { @Override public void onHostResume() { // Activity `onResume` module = this; - Activity currentActivity = getCurrentActivity(); - if (currentActivity == null) { - Log.d(TAG, "On host Activity doesn't exist"); - return; - } - - if (status == null) { - status = new ServiceConnector(currentActivity, StatusService.class); - status.registerHandler(this); - } - - safeStartAndBindService(); - } - - private void safeStartAndBindService() { - // If we bind StatusService too early on Android 9+, it will crash the app. - // This is a workaround, to listen to the app lifecycle, - // and to start the service only when the app is in foreground already. - Log.d(TAG, "[onHostResume] android 9+ delaying service binding."); - ProcessLifecycleOwner.get().getLifecycle().addObserver(this); - } - - @OnLifecycleEvent(Lifecycle.Event.ON_START) - void onEnterForeground() { - Log.d(TAG, "[onEnterForeground] the app is foreground now, binding service"); - doStartService(); - ProcessLifecycleOwner.get().getLifecycle().removeObserver(this); - } - - private void doStartService() { - status.bindService(); - signalEvent("{\"type\":\"module.initialized\"}"); + StatusService.INSTANCE.setSignalEventListener(this); } @Override public void onHostPause() { - if (status != null) { - status.unbindService(); - } + } @Override @@ -134,19 +100,18 @@ public void onHostDestroy() { } private boolean checkAvailability() { - - Activity currentActivity = getCurrentActivity(); - if (currentActivity == null) { - Log.d(TAG, "Activity doesn't exist"); - return false; + if (getCurrentActivity() != null) { + return true; } - return true; - } + Log.d(TAG, "Activity doesn't exist"); + return false; + } - void signalEvent(String jsonEvent) { - Log.d(TAG, "Signal event: " + jsonEvent); + @Override + public void handleEvent(String jsonEvent) { + Log.d(TAG, "[handleEvent] event: " + jsonEvent); WritableMap params = Arguments.createMap(); params.putString("jsonEvent", jsonEvent); this.getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("gethEvent", params); @@ -297,7 +262,6 @@ private void doStartNode(final String jsonConfigString) { else { Log.e(TAG, "StartNode failed: " + res); } - status.sendMessage(); } catch (JSONException e) { Log.e(TAG, "updateConfig failed: " + e.getMessage()); System.exit(1); @@ -388,6 +352,7 @@ public void moveToInternalStorage(Callback callback) { public void startNode(final String config) { Log.d(TAG, "startNode"); if (!checkAvailability()) { + Log.e(TAG, "[startNode] Activity doesn't exists, cannot start node"); return; } @@ -817,28 +782,6 @@ public void clearStorageAPIs() { } } - @Override - public boolean handleMessage(Message message) { - - Log.d(TAG, "Received message: " + message.toString()); - Bundle bundle = message.getData(); - - String event = bundle.getString("event"); - signalEvent(event); - - return true; - } - - @Override - public void onConnectorConnected() { - - } - - @Override - public void onConnectorDisconnected() { - - } - @ReactMethod public void callRPC(final String payload, final Callback callback) { Runnable r = new Runnable() { diff --git a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusNodeEventHandler.java b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusNodeEventHandler.java new file mode 100644 index 000000000000..1e29d63b1aa7 --- /dev/null +++ b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusNodeEventHandler.java @@ -0,0 +1,5 @@ +package im.status.ethereum.module; + +public interface StatusNodeEventHandler { + void handleEvent(String eventJson); +} diff --git a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusService.java b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusService.java index fec769145b0f..a9115090db0a 100644 --- a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusService.java +++ b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/StatusService.java @@ -9,98 +9,55 @@ import java.lang.ref.WeakReference; -public class StatusService extends Service { - private static final String TAG = "StatusService"; - - public StatusService() { - super(); - } - - private static class IncomingHandler extends Handler { - - private final WeakReference service; - - IncomingHandler(StatusService service) { +/** + * StatusService has nothing to do with Android services anymore. + * The name "StatusService" is kep to keep backward compatibility with status-go. + * Hopefully, it will be replaced when GoMobile + */ +public class StatusService { + static final StatusService INSTANCE = new StatusService(); - this.service = new WeakReference<>(service); - } + private static final String TAG = "StatusService"; - @Override - public void handleMessage(Message message) { + /** + * signalEvent is called by Statusgo JNI module to pass events from the node. + * @param jsonEvent + */ + public static void signalEvent(String jsonEvent) { + Log.d(TAG, "[signalEvent] event: " + jsonEvent); + StatusNodeEventHandler listener = StatusService.INSTANCE.getSignalEventListener(); - StatusService service = this.service.get(); - if (service != null) { - if (!service.handleMessage(message)) { - super.handleMessage(message); - } - } + if (listener == null) { + Log.w(TAG, "[signalEvent] no listener is set (module is missing?) ignoring event: " + jsonEvent); + return; } - } - - private static CountDownLatch applicationMessengerIsSet = new CountDownLatch(1); - private final Messenger serviceMessenger = new Messenger(new IncomingHandler(this)); - - private static Messenger applicationMessenger = null; - - private boolean handleMessage(Message message) { - Log.d(TAG, "Received service message." + message.toString()); - applicationMessenger = message.replyTo; - applicationMessengerIsSet.countDown(); - - return true; + Log.d(TAG, "[signalEvent] passing event to the listener: " + jsonEvent); + listener.handleEvent(jsonEvent); } - public static void signalEvent(String jsonEvent) { - - Log.d(TAG, "Signal event: " + jsonEvent); - Bundle replyData = new Bundle(); - replyData.putString("event", jsonEvent); + private StatusNodeEventHandler signalEventListener; - Message replyMessage = Message.obtain(null, 0, 0, 0, null); - replyMessage.setData(replyData); - try { - applicationMessengerIsSet.await(); - sendReply(applicationMessenger, replyMessage); - } catch(InterruptedException e) { - Log.d(TAG, "Interrupted during event signalling."); - } + void setSignalEventListener(StatusNodeEventHandler listener) { + Log.d(TAG, "[setSignalEventListener], setting listener to: " + this.safeClassName(listener)); + this.signalEventListener = listener; } - @Nullable - @Override - public IBinder onBind(Intent intent) { - return serviceMessenger.getBinder(); - } + private String safeClassName(Object object) { + if (object == null) { + return "null"; + } - @Override - public void onCreate() { - super.onCreate(); - Log.d(TAG, "Status Service created!"); - } + if (object.getClass() == null) { + return ""; + } - @Override - public void onDestroy() { - super.onDestroy(); - Log.d(TAG, "Status Service stopped!"); + return object.getClass().getCanonicalName(); } - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - return Service.START_STICKY; + private StatusNodeEventHandler getSignalEventListener() { + return this.signalEventListener; } - private static void sendReply(Messenger messenger, Message message) { - try { - boolean ex = false; - if (messenger != null) { - ex = true; - } - Log.d(TAG, "before sendReply " + ex); - messenger.send(message); - } catch (Exception e) { - Log.e(TAG, "Exception sending message id: " + message.what, e); - } - } } diff --git a/src/status_im/chat/commands/impl/transactions.cljs b/src/status_im/chat/commands/impl/transactions.cljs index 0860909d3ace..31242d4474aa 100644 --- a/src/status_im/chat/commands/impl/transactions.cljs +++ b/src/status_im/chat/commands/impl/transactions.cljs @@ -395,7 +395,6 @@ (defview request-preview [{:keys [message-id content outgoing timestamp timestamp-str group-chat]}] (letsubs [id->command [:chats/id->command] - status-initialized? [:get :status-module-initialized?] network [:network-name] prices [:prices]] (let [{:keys [amount asset fiat-amount currency answered?] request-network :network} (:params content) @@ -440,7 +439,6 @@ [react/text {:style (transactions-styles/command-request-button-text answered?)} (i18n/label (if answered? :command-button-sent :command-button-send))]]])]] (if (and (not network-mismatch?) - status-initialized? (not outgoing) (not answered?)) [react/touchable-highlight diff --git a/src/status_im/init/core.cljs b/src/status_im/init/core.cljs index 1fde99c652d4..e638d48831df 100644 --- a/src/status_im/init/core.cljs +++ b/src/status_im/init/core.cljs @@ -85,7 +85,7 @@ (fx/defn initialize-app-db "Initialize db to initial state" - [{{:keys [status-module-initialized? view-id hardwallet + [{{:keys [view-id hardwallet initial-props desktop/desktop network-status network peers-count peers-summary device-UUID push-notifications/stored] @@ -100,7 +100,6 @@ :network-status network-status :peers-count (or peers-count 0) :peers-summary (or peers-summary []) - :status-module-initialized? (or platform/ios? js/goog.DEBUG status-module-initialized?) :node/status status :network network :hardwallet hardwallet @@ -170,7 +169,7 @@ :keys [accounts/accounts accounts/create networks/networks network network-status peers-count peers-summary view-id navigation-stack desktop/desktop hardwallet - status-module-initialized? device-UUID semaphores accounts/login] + device-UUID semaphores accounts/login] :node/keys [status on-ready] :or {network (get app-db :network)}} db current-account (get accounts address) @@ -179,7 +178,6 @@ {:db (cond-> (assoc app-db :view-id view-id :navigation-stack navigation-stack - :status-module-initialized? (or platform/ios? js/goog.DEBUG status-module-initialized?) :node/status status :node/on-ready on-ready :accounts/create create @@ -247,10 +245,6 @@ :init/restore-native-settings restore-native-settings!) -(re-frame/reg-fx - :init/status-module-initialized - status/module-initialized!) - (re-frame/reg-fx :init/get-device-UUID (fn [] diff --git a/src/status_im/native_module/core.cljs b/src/status_im/native_module/core.cljs index 254586265645..7976a3fa2be5 100644 --- a/src/status_im/native_module/core.cljs +++ b/src/status_im/native_module/core.cljs @@ -48,9 +48,6 @@ (defn send-transaction [rpcParams password callback] (native-module/send-transaction rpcParams password callback)) -(defn module-initialized! [] - (native-module/module-initialized!)) - (defn notify-users [m callback] (native-module/notify-users m callback)) diff --git a/src/status_im/native_module/impl/module.cljs b/src/status_im/native_module/impl/module.cljs index e629ad62e001..6a11a7a833b5 100644 --- a/src/status_im/native_module/impl/module.cljs +++ b/src/status_im/native_module/impl/module.cljs @@ -11,39 +11,6 @@ [clojure.string :as string] [status-im.utils.platform :as platform])) -;; if StatusModule is not initialized better to store -;; calls and make them only when StatusModule is ready -;; this flag helps to handle this -(defonce module-initialized? (atom (or p/ios? js/goog.DEBUG p/desktop?))) - -;; array of calls to StatusModule -(defonce calls (atom [])) - -(defn module-initialized! [] - (reset! module-initialized? true)) - -(defn store-call [args] - (log/debug :store-call args) - (swap! calls conj args)) - -(defn call-module [f] - ;;(log/debug :call-module f) - (if @module-initialized? - (f) - (store-call f))) - -(defonce loop-started (atom false)) - -(when-not @loop-started - (go-loop [_ nil] - (reset! loop-started true) - (if (and (seq @calls) @module-initialized?) - (do (swap! calls (fn [calls] - (doseq [call calls] - (call)))) - (reset! loop-started false)) - (recur (async/