refactor: use ReactiveX

Change-Id: I9a58c8fa08ed0df63acb3efb2d4b5b47015382c5
diff --git a/ring-android/libringclient/src/main/java/cx/ring/call/CallPresenter.java b/ring-android/libringclient/src/main/java/cx/ring/call/CallPresenter.java
index 692f49f..ecaaf7d 100644
--- a/ring-android/libringclient/src/main/java/cx/ring/call/CallPresenter.java
+++ b/ring-android/libringclient/src/main/java/cx/ring/call/CallPresenter.java
@@ -2,6 +2,7 @@
  *  Copyright (C) 2004-2018 Savoir-faire Linux Inc.
  *
  *  Author: Hadrien De Sousa <hadrien.desousa@savoirfairelinux.com>
+ *  Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -24,35 +25,30 @@
 import java.util.concurrent.TimeUnit;
 
 import javax.inject.Inject;
+import javax.inject.Named;
 
-import cx.ring.facades.ConversationFacade;
 import cx.ring.model.CallContact;
 import cx.ring.model.Conference;
-import cx.ring.model.ServiceEvent;
 import cx.ring.model.SipCall;
 import cx.ring.mvp.RootPresenter;
 import cx.ring.services.AccountService;
 import cx.ring.services.CallService;
 import cx.ring.services.ContactService;
 import cx.ring.services.HardwareService;
-import cx.ring.services.HistoryService;
 import cx.ring.services.NotificationService;
 import cx.ring.utils.Log;
-import cx.ring.utils.Observable;
-import cx.ring.utils.Observer;
 import cx.ring.utils.StringUtils;
+import io.reactivex.Scheduler;
 
-public class CallPresenter extends RootPresenter<CallView> implements Observer<ServiceEvent> {
+public class CallPresenter extends RootPresenter<CallView> {
 
     public final static String TAG = CallPresenter.class.getSimpleName();
 
-    protected AccountService mAccountService;
-    protected NotificationService mNotificationService;
-    protected HardwareService mHardwareService;
-    protected CallService mCallService;
-    protected ContactService mContactService;
-    protected HistoryService mHistoryService;
-    protected ConversationFacade mConversationFacade;
+    private AccountService mAccountService;
+    private NotificationService mNotificationService;
+    private HardwareService mHardwareService;
+    private CallService mCallService;
+    private ContactService mContactService;
 
     private SipCall mSipCall;
     private boolean mOnGoingCall = false;
@@ -67,29 +63,25 @@
     private Runnable timeRunnable = this::updateTime;
 
     @Inject
+    @Named("UiScheduler")
+    protected Scheduler mUiScheduler;
+
+    @Inject
     public CallPresenter(AccountService accountService,
                          NotificationService notificationService,
                          HardwareService hardwareService,
                          CallService callService,
-                         ContactService contactService,
-                         HistoryService historyService,
-                         ConversationFacade conversationFacade) {
-        this.mAccountService = accountService;
-        this.mNotificationService = notificationService;
-        this.mHardwareService = hardwareService;
-        this.mCallService = callService;
-        this.mContactService = contactService;
-        this.mHistoryService = historyService;
-        this.mConversationFacade = conversationFacade;
+                         ContactService contactService) {
+        mAccountService = accountService;
+        mNotificationService = notificationService;
+        mHardwareService = hardwareService;
+        mCallService = callService;
+        mContactService = contactService;
     }
 
     @Override
     public void unbindView() {
         super.unbindView();
-        mAccountService.removeObserver(this);
-        mCallService.removeObserver(this);
-        mHardwareService.removeObserver(this);
-
         if (!mAudioOnly) {
             mHardwareService.stopCapture();
         }
@@ -98,9 +90,16 @@
     @Override
     public void bindView(CallView view) {
         super.bindView(view);
-        mAccountService.addObserver(this);
-        mCallService.addObserver(this);
-        mHardwareService.addObserver(this);
+        mCompositeDisposable.add(mAccountService.getRegisteredNames()
+                .observeOn(mUiScheduler)
+                .subscribe(r -> {
+                    if (mSipCall != null && mSipCall.getContact() != null) {
+                        getView().updateContactBubble(mSipCall.getContact());
+                    }
+                }));
+        mCompositeDisposable.add(mHardwareService.getVideoEvents()
+                .observeOn(mUiScheduler)
+                .subscribe(this::onVideoEvent));
     }
 
     public void initOutGoing(String accountId, String contactRingId, boolean audioOnly) {
@@ -112,34 +111,31 @@
         if (mHardwareService.getCameraCount() == 0) {
             audioOnly = true;
         }
-
-        mSipCall = mConversationFacade.placeCall(accountId, StringUtils.toNumber(contactRingId), audioOnly);
-        if (mSipCall == null) {
-            Log.w(TAG, "initOutGoing: null Call");
-            finish();
-            return;
-        }
-
-        mAudioOnly = mSipCall.isAudioOnly();
-
-        getView().updateMenu();
-
-        confUpdate();
-        getContactDetails();
         getView().blockScreenRotation();
+
+        mCompositeDisposable.add(mCallService
+                .placeCallObservable(accountId, StringUtils.toNumber(contactRingId), audioOnly)
+                .observeOn(mUiScheduler)
+                .subscribe(call ->  {
+            mSipCall = call;
+            mAudioOnly = mSipCall.isAudioOnly();
+            getView().updateMenu();
+            confUpdate();
+            getContactDetails();
+        }));
     }
 
     public void initIncoming(String confId) {
-        mSipCall = mCallService.getCurrentCallForId(confId);
-        if (mSipCall == null) {
-            Log.w(TAG, "initIncoming: null Call");
-            finish();
-            return;
-        }
-        mAudioOnly = mSipCall.isAudioOnly();
-        confUpdate();
-        getContactDetails();
         getView().blockScreenRotation();
+        mCompositeDisposable.add(mCallService.getCallUpdates(confId)
+                .observeOn(mUiScheduler)
+                .subscribe(call -> {
+            mSipCall = call;
+            mAudioOnly = mSipCall.isAudioOnly();
+            getView().updateMenu();
+            confUpdate();
+            getContactDetails();
+        }));
     }
 
     public void prepareOptionMenu() {
@@ -157,7 +153,7 @@
                 || mSipCall.getContact().getIds().isEmpty()) {
             return;
         }
-        getView().goToConversation(mAccountService.getCurrentAccount().getAccountID(), mSipCall.getContact().getIds().get(0));
+        getView().goToConversation(mSipCall.getAccount(), mSipCall.getContact().getIds().get(0));
     }
 
     public void speakerClick() {
@@ -198,9 +194,10 @@
     }
 
     public void refuseCall() {
-        if (mSipCall != null) {
-            mCallService.refuse(mSipCall.getCallId());
-            mNotificationService.cancelCallNotification(mSipCall.getCallId().hashCode());
+        final SipCall call = mSipCall;
+        if (call != null) {
+            mCallService.refuse(call.getCallId());
+            mNotificationService.cancelCallNotification(call.getCallId().hashCode());
         }
         finish();
     }
@@ -254,15 +251,16 @@
         if (mSipCall == null) {
             return;
         }
+        CallView view = getView();
         mAudioOnly = mSipCall.isAudioOnly();
         if (mSipCall.isOnGoing()) {
             mOnGoingCall = true;
-            getView().initNormalStateDisplay(mAudioOnly);
-            getView().updateContactBubble(mSipCall.getContact());
-            getView().updateMenu();
+            view.initNormalStateDisplay(mAudioOnly);
+            view.updateContactBubble(mSipCall.getContact());
+            view.updateMenu();
             if (!mAudioOnly) {
                 mHardwareService.setPreviewSettings();
-                getView().displayVideoSurface(true);
+                view.displayVideoSurface(true);
             }
             if (executor == null || executor.isShutdown()) {
                 executor = Executors.newSingleThreadScheduledExecutor();
@@ -273,14 +271,14 @@
                 if (mAccountService.getAccount(mSipCall.getAccount()).isAutoanswerEnabled()) {
                     mCallService.accept(mSipCall.getCallId());
                 } else {
-                    getView().initIncomingCallDisplay();
-                    getView().updateContactBubble(mSipCall.getContact());
+                    view.initIncomingCallDisplay();
+                    view.updateContactBubble(mSipCall.getContact());
                 }
             } else {
                 mOnGoingCall = false;
-                getView().updateCallStatus(mSipCall.getCallState());
-                getView().initOutGoingCallDisplay();
-                getView().updateContactBubble(mSipCall.getContact());
+                view.updateCallStatus(mSipCall.getCallState());
+                view.initOutGoingCallDisplay();
+                view.updateContactBubble(mSipCall.getContact());
             }
         } else {
             finish();
@@ -327,56 +325,21 @@
         }
     }
 
-    @Override
-    public void update(Observable observable, ServiceEvent event) {
-        if (event == null) {
-            return;
-        }
+    private void onVideoEvent(HardwareService.VideoEvent event) {
+        Log.d(TAG, "VIDEO_EVENT: " + event.start + " " + event.callId);
+        previewHeight = event.w;
+        previewWidth = event.h;
 
-        if (observable instanceof CallService) {
-            switch (event.getEventType()) {
-                case CALL_STATE_CHANGED:
-                    SipCall call = event.getEventInput(ServiceEvent.EventInput.CALL, SipCall.class);
-                    int state = call.getCallState();
-
-                    Log.d(TAG, "CALL_STATE_CHANGED: " + call.getCallId() + " " + state);
-
-                    parseCall(call, state);
-                    confUpdate();
-                    break;
-            }
-        } else if (observable instanceof AccountService) {
-            switch (event.getEventType()) {
-                case REGISTERED_NAME_FOUND:
-                    if (mSipCall != null && mSipCall.getContact() != null) {
-                        getView().updateContactBubble(mSipCall.getContact());
-                    }
-                    break;
-            }
-        } else if (observable instanceof HardwareService) {
-            switch (event.getEventType()) {
-                case VIDEO_EVENT:
-                    boolean videoStart = event.getEventInput(ServiceEvent.EventInput.VIDEO_START, Boolean.class, false);
-                    String callId = event.getEventInput(ServiceEvent.EventInput.VIDEO_CALL, String.class);
-
-                    Log.d(TAG, "VIDEO_EVENT: " + videoStart + " " + callId);
-                    previewHeight = event.getEventInput(ServiceEvent.EventInput.VIDEO_WIDTH, Integer.class, 0);
-                    previewWidth = event.getEventInput(ServiceEvent.EventInput.VIDEO_HEIGHT, Integer.class, 0);
-
-                    if (videoStart) {
-                        getView().displayVideoSurface(true);
-                    } else if (mSipCall != null && callId != null && mSipCall.getCallId().equals(callId)) {
-                        boolean videoStarted = event.getEventInput(ServiceEvent.EventInput.VIDEO_STARTED, Boolean.class, false);
-                        getView().displayVideoSurface(videoStarted);
-                        if (videoStarted) {
-                            videoWidth = event.getEventInput(ServiceEvent.EventInput.VIDEO_WIDTH, Integer.class, 0);
-                            videoHeight = event.getEventInput(ServiceEvent.EventInput.VIDEO_HEIGHT, Integer.class, 0);
-                        }
-                    }
-                    getView().resetVideoSize(videoWidth, videoHeight, previewWidth, previewHeight);
-                    break;
+        if (event.start) {
+            getView().displayVideoSurface(true);
+        } else if (mSipCall != null && mSipCall.getCallId().equals(event.callId)) {
+            getView().displayVideoSurface(event.started);
+            if (event.started) {
+                videoWidth = event.w;
+                videoHeight = event.h;
             }
         }
+        getView().resetVideoSize(videoWidth, videoHeight, previewWidth, previewHeight);
     }
 
     public void positiveButtonClicked() {