Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle event registration and removal #66

Merged
merged 1 commit into from
Feb 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.walmartlabs.electrode.reactnative.bridge;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.walmartlabs.electrode.reactnative.bridge.helpers.Logger;

import org.junit.Before;
import org.junit.Test;

import java.util.UUID;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertNull;

public class BridgeHolderTests extends BaseBridgeTestCase {

@Before
public void setUp() {
Logger.overrideLogLevel(Logger.LogLevel.DEBUG);
}

@Test
public void testRequestHandlerQueuing() {
String KEY_HANDLER = "requestHandler";

ElectrodeBridgeRequestHandler<ElectrodeBridgeRequest, Object> requestHandler1 = new ElectrodeBridgeRequestHandler<ElectrodeBridgeRequest, Object>() {
@Override
public void onRequest(@Nullable ElectrodeBridgeRequest payload, @NonNull ElectrodeBridgeResponseListener<Object> responseListener) {

}
};

UUID requestHandler1Uuid = ElectrodeBridgeHolder.registerRequestHandler(KEY_HANDLER, requestHandler1);
assertEquals(1, ElectrodeBridgeHolder.mQueuedRequestHandlersRegistration.size());
assertTrue(ElectrodeBridgeHolder.mQueuedRequestHandlersRegistration.containsKey(KEY_HANDLER));
assertNotNull(ElectrodeBridgeHolder.mQueuedRequestHandlersRegistration.get(KEY_HANDLER));
assertEquals(requestHandler1, ElectrodeBridgeHolder.mQueuedRequestHandlersRegistration.get(KEY_HANDLER).getRequestHandler());


ElectrodeBridgeRequestHandler<ElectrodeBridgeRequest, Object> requestHandler2 = new ElectrodeBridgeRequestHandler<ElectrodeBridgeRequest, Object>() {
@Override
public void onRequest(@Nullable ElectrodeBridgeRequest payload, @NonNull ElectrodeBridgeResponseListener<Object> responseListener) {

}
};

//Add second request handler, this should replace the first one.
UUID requestHandler2Uuid = ElectrodeBridgeHolder.registerRequestHandler(KEY_HANDLER, requestHandler2);
assertEquals(1, ElectrodeBridgeHolder.mQueuedRequestHandlersRegistration.size());
assertTrue(ElectrodeBridgeHolder.mQueuedRequestHandlersRegistration.containsKey(KEY_HANDLER));
assertNotNull(ElectrodeBridgeHolder.mQueuedRequestHandlersRegistration.get(KEY_HANDLER));
assertEquals(requestHandler2, ElectrodeBridgeHolder.mQueuedRequestHandlersRegistration.get(KEY_HANDLER).getRequestHandler());


//Try removing the first request handler which is already replaced by second
assertNull(ElectrodeBridgeHolder.unregisterRequestHandler(requestHandler1Uuid));

//Remove the second request handler
assertEquals(requestHandler2, ElectrodeBridgeHolder.unregisterRequestHandler(requestHandler2Uuid));
assertEquals(0, ElectrodeBridgeHolder.mQueuedRequestHandlersRegistration.size());
assertFalse(ElectrodeBridgeHolder.mQueuedRequestHandlersRegistration.containsKey(KEY_HANDLER));
}

@Test
public void testEventListenerQueuing() {
String KEY_LISTENER = "eventListener";
ElectrodeBridgeEventListener<ElectrodeBridgeEvent> eventListener1 = new ElectrodeBridgeEventListener<ElectrodeBridgeEvent>() {
@Override
public void onEvent(@Nullable ElectrodeBridgeEvent eventPayload) {

}
};

UUID eventListener1Uuid = ElectrodeBridgeHolder.addEventListener(KEY_LISTENER, eventListener1);

assertEquals(1, ElectrodeBridgeHolder.mQueuedEventListenersRegistration.size());
assertTrue(ElectrodeBridgeHolder.mQueuedEventListenersRegistration.containsKey(KEY_LISTENER));
assertNotNull(ElectrodeBridgeHolder.mQueuedEventListenersRegistration.get(KEY_LISTENER));
assertEquals(1, ElectrodeBridgeHolder.mQueuedEventListenersRegistration.get(KEY_LISTENER).size());
assertEquals(eventListener1, ElectrodeBridgeHolder.mQueuedEventListenersRegistration.get(KEY_LISTENER).get(0).getEventListener());


//Add the second listener
ElectrodeBridgeEventListener<ElectrodeBridgeEvent> eventListener2 = new ElectrodeBridgeEventListener<ElectrodeBridgeEvent>() {
@Override
public void onEvent(@Nullable ElectrodeBridgeEvent eventPayload) {
}
};

UUID eventListener2Uuid = ElectrodeBridgeHolder.addEventListener(KEY_LISTENER, eventListener2);
assertEquals(1, ElectrodeBridgeHolder.mQueuedEventListenersRegistration.size());
assertTrue(ElectrodeBridgeHolder.mQueuedEventListenersRegistration.containsKey(KEY_LISTENER));
assertNotNull(ElectrodeBridgeHolder.mQueuedEventListenersRegistration.get(KEY_LISTENER));
assertEquals(2, ElectrodeBridgeHolder.mQueuedEventListenersRegistration.get(KEY_LISTENER).size());
assertEquals(eventListener1, ElectrodeBridgeHolder.mQueuedEventListenersRegistration.get(KEY_LISTENER).get(0).getEventListener());
assertEquals(eventListener2, ElectrodeBridgeHolder.mQueuedEventListenersRegistration.get(KEY_LISTENER).get(1).getEventListener());

//Remove one listener
assertEquals(eventListener2, ElectrodeBridgeHolder.removeEventListener(eventListener2Uuid));
assertEquals(1, ElectrodeBridgeHolder.mQueuedEventListenersRegistration.size());
assertTrue(ElectrodeBridgeHolder.mQueuedEventListenersRegistration.containsKey(KEY_LISTENER));
assertNotNull(ElectrodeBridgeHolder.mQueuedEventListenersRegistration.get(KEY_LISTENER));
assertEquals(1, ElectrodeBridgeHolder.mQueuedEventListenersRegistration.get(KEY_LISTENER).size());
assertEquals(eventListener1, ElectrodeBridgeHolder.mQueuedEventListenersRegistration.get(KEY_LISTENER).get(0).getEventListener());

//Remove all listeners
assertEquals(eventListener1, ElectrodeBridgeHolder.removeEventListener(eventListener1Uuid));
assertEquals(0, ElectrodeBridgeHolder.mQueuedEventListenersRegistration.size());
assertFalse(ElectrodeBridgeHolder.mQueuedEventListenersRegistration.containsKey(KEY_LISTENER));
assertNull(ElectrodeBridgeHolder.mQueuedEventListenersRegistration.get(KEY_LISTENER));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.walmartlabs.electrode.reactnative.bridge;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.walmartlabs.electrode.reactnative.bridge.helpers.Logger;

Expand Down Expand Up @@ -48,10 +49,10 @@ public final class ElectrodeBridgeHolder {
// This solution does not really scale in the sense that if the user sends a 1000 requests
// upon native app start, it can become problematic. But I don't see why a user would do that
// unless it's a bug in its app
private static final HashMap<String, RequestHandlerPlaceholder> mQueuedRequestHandlersRegistration = new HashMap<>();
private static final HashMap<String, EventListenerPlaceholder> mQueuedEventListenersRegistration = new HashMap<>();
private static final HashMap<ElectrodeBridgeRequest, ElectrodeBridgeResponseListener<ElectrodeBridgeResponse>> mQueuedRequests = new HashMap<>();
private static final List<ElectrodeBridgeEvent> mQueuedEvents = new ArrayList<>();
static final HashMap<String, RequestHandlerPlaceholder> mQueuedRequestHandlersRegistration = new HashMap<>();
static final HashMap<String, List<EventListenerPlaceholder>> mQueuedEventListenersRegistration = new HashMap<>();
static final HashMap<ElectrodeBridgeRequest, ElectrodeBridgeResponseListener<ElectrodeBridgeResponse>> mQueuedRequests = new HashMap<>();
static final List<ElectrodeBridgeEvent> mQueuedEvents = new ArrayList<>();

static {
ElectrodeBridgeTransceiver.registerReactNativeReadyListener(new ElectrodeBridgeTransceiver.ReactNativeReadyListener() {
Expand Down Expand Up @@ -135,7 +136,12 @@ public static UUID addEventListener(@NonNull String name,
UUID eventUUID = UUID.randomUUID();
if (!isReactNativeReady) {
Logger.d(TAG, "Queuing event handler registration for event(name=%s). Will register once react native initialization is complete.", name);
mQueuedEventListenersRegistration.put(name, new EventListenerPlaceholder(eventUUID, eventListener));
List<EventListenerPlaceholder> placeholderList = mQueuedEventListenersRegistration.get(name);
if (placeholderList == null) {
placeholderList = new ArrayList<>();
mQueuedEventListenersRegistration.put(name, placeholderList);
}
placeholderList.add(new EventListenerPlaceholder(eventUUID, eventListener));
return eventUUID;
}

Expand All @@ -153,8 +159,32 @@ public static void addConstantsProvider(@NonNull ConstantsProvider constantsProv
* @param eventListenerUuid {@link UUID}
* @return
*/
@Nullable
public static ElectrodeBridgeEventListener<ElectrodeBridgeEvent> removeEventListener(@NonNull UUID eventListenerUuid) {
return electrodeNativeBridge.removeEventListener(eventListenerUuid);
if (!isReactNativeReady) {
ElectrodeBridgeEventListener<ElectrodeBridgeEvent> eventListener = null;
synchronized (mQueuedEventListenersRegistration) {
String key = null;
for (Map.Entry<String, List<EventListenerPlaceholder>> entry : mQueuedEventListenersRegistration.entrySet()) {
List<EventListenerPlaceholder> placeholderList = entry.getValue();
for (EventListenerPlaceholder placeholder : placeholderList) {
if (eventListenerUuid == placeholder.getUUID()) {
key = entry.getKey();
eventListener = placeholder.getEventListener();
placeholderList.remove(placeholder);
break;
}
}
if (placeholderList.size() == 0) {
mQueuedEventListenersRegistration.remove(key);
break;
}
}
}
return eventListener;
} else {
return electrodeNativeBridge.removeEventListener(eventListenerUuid);
}
}

/**
Expand All @@ -164,7 +194,20 @@ public static ElectrodeBridgeEventListener<ElectrodeBridgeEvent> removeEventList
* @return registerRequestHandler unregistered
*/
public static ElectrodeBridgeRequestHandler<ElectrodeBridgeRequest, Object> unregisterRequestHandler(@NonNull UUID requestHandlerUuid) {
return electrodeNativeBridge.unregisterRequestHandler(requestHandlerUuid);
if (!isReactNativeReady) {
ElectrodeBridgeRequestHandler<ElectrodeBridgeRequest, Object> requestHandler = null;
synchronized (mQueuedRequestHandlersRegistration) {
for (Map.Entry<String, RequestHandlerPlaceholder> entry : mQueuedRequestHandlersRegistration.entrySet()) {
if (entry.getValue().getUUID() == requestHandlerUuid) {
requestHandler = entry.getValue().getRequestHandler();
mQueuedRequestHandlersRegistration.remove(entry.getKey());
}
}
}
return requestHandler;
} else {
return electrodeNativeBridge.unregisterRequestHandler(requestHandlerUuid);
}
}

private static void registerQueuedRequestHandlers() {
Expand All @@ -178,11 +221,15 @@ private static void registerQueuedRequestHandlers() {
}

private static void registerQueuedEventListeners() {
for (Map.Entry<String, EventListenerPlaceholder> entry : mQueuedEventListenersRegistration.entrySet()) {
electrodeNativeBridge.addEventListener(
entry.getKey(),
entry.getValue().getEventListener(),
entry.getValue().getUUID());
for (Map.Entry<String, List<EventListenerPlaceholder>> entry : mQueuedEventListenersRegistration.entrySet()) {
List<EventListenerPlaceholder> placeholderList = entry.getValue();
for (EventListenerPlaceholder placeholder : placeholderList) {
electrodeNativeBridge.addEventListener(
entry.getKey(),
placeholder.getEventListener(),
placeholder.getUUID());
}

}
mQueuedEventListenersRegistration.clear();
}
Expand Down