Add latch to ensure application messenger is set.

There are two ways that messages can reach the StatusService,
application events (which are handled via `handleEvent`) and
signal events (which are handled via `signalEvent`).

If a signal event fires before an application event, it still
uses handleEvent logic, and handleEvent will try to reply to
the message. If the `applicationMessenger` isn't set, the reply
fails and the react native app is never told that the status
node is running, which is why the app gets no messages.

I've added a CountDownLatch, forcing the event handler to wait
for the applicationMessenger to be set before replying to any
messages.

Tested by injecting a long wait into `handleMessage` and observing
the same failure we see in SauceLabs runs.
This commit is contained in:
angusiguess 2017-10-09 13:20:45 -03:00 committed by Roman Volosovskyi
parent 61a6167998
commit 49429c1c28
1 changed files with 10 additions and 1 deletions

View File

@ -5,6 +5,7 @@ import android.content.Intent;
import android.os.*;
import android.support.annotation.Nullable;
import android.util.Log;
import java.util.concurrent.CountDownLatch;
import java.lang.ref.WeakReference;
@ -37,6 +38,8 @@ public class StatusService extends Service {
}
}
private static CountDownLatch applicationMessengerIsSet = new CountDownLatch(1);
private final Messenger serviceMessenger = new Messenger(new IncomingHandler(this));
private static Messenger applicationMessenger = null;
@ -44,6 +47,7 @@ public class StatusService extends Service {
private boolean handleMessage(Message message) {
Log.d(TAG, "Received service message." + message.toString());
applicationMessenger = message.replyTo;
applicationMessengerIsSet.countDown();
return true;
}
@ -56,7 +60,12 @@ public class StatusService extends Service {
Message replyMessage = Message.obtain(null, 0, 0, 0, null);
replyMessage.setData(replyData);
sendReply(applicationMessenger, replyMessage);
try {
applicationMessengerIsSet.await();
sendReply(applicationMessenger, replyMessage);
} catch(InterruptedException e) {
Log.d(TAG, "Interrupted during event signalling.");
}
}
@Nullable