Bug 1055144 - Implement sendRequestForResult. r=wesj

sendRequestForResult is a promise-based API for messaging Java. It
replaces the callback version of sendMessageToJava.
This commit is contained in:
Brian Nicholson 2014-09-02 15:53:29 -07:00
Родитель 61a925c055
Коммит b6dddfb90c
5 изменённых файлов: 31 добавлений и 32 удалений

Просмотреть файл

@ -27,7 +27,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
public final class EventDispatcher {
private static final String LOGTAG = "GeckoEventDispatcher";
private static final String GUID = "__guid__";
private static final String STATUS_CANCEL = "cancel";
private static final String STATUS_ERROR = "error";
private static final String STATUS_SUCCESS = "success";
@ -200,10 +199,9 @@ public final class EventDispatcher {
if (listeners == null || listeners.size() == 0) {
Log.w(LOGTAG, "No listeners for " + type);
// If there are no listeners, cancel the callback to prevent Gecko-side observers
// from being leaked.
// If there are no listeners, dispatch an error.
if (callback != null) {
callback.sendCancel();
callback.sendError("No listeners for request");
}
return;
}
@ -258,10 +256,6 @@ public final class EventDispatcher {
sendResponse(STATUS_ERROR, response);
}
public void sendCancel() {
sendResponse(STATUS_CANCEL, null);
}
private void sendResponse(final String status, final Object response) {
if (sent) {
throw new IllegalStateException("Callback has already been executed for type=" +

Просмотреть файл

@ -68,7 +68,6 @@ public class testEventDispatcher extends UITest
js.syncCall("send_test_message", NATIVE_EVENT);
js.syncCall("send_message_for_response", NATIVE_RESPONSE_EVENT, "success");
js.syncCall("send_message_for_response", NATIVE_RESPONSE_EVENT, "error");
js.syncCall("send_message_for_response", NATIVE_RESPONSE_EVENT, "cancel");
js.syncCall("send_test_message", NATIVE_EXCEPTION_EVENT);
js.syncCall("finish_test");
}
@ -149,8 +148,6 @@ public class testEventDispatcher extends UITest
callback.sendSuccess(response);
} else if ("error".equals(response)) {
callback.sendError(response);
} else if ("cancel".equals(response)) {
callback.sendCancel();
} else {
fFail("Response type should be valid: " + response);
}

Просмотреть файл

@ -26,9 +26,4 @@ public interface EventCallback {
* JSONObject#put(String, Object).
*/
public void sendError(Object response);
/**
* Cancels the request, preventing any Gecko-side callbacks from being executed.
*/
public void sendCancel();
}

Просмотреть файл

@ -18,7 +18,13 @@ XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
function sendMessageToJava(aMessage, aCallback) {
Cu.reportError("sendMessageToJava is deprecated. Use Messaging API instead.");
Messaging.sendRequest(aMessage, aCallback);
if (aCallback) {
Messaging.sendRequestForResult(aMessage)
.then(result => aCallback(result, null),
error => aCallback(null, error));
} else {
Messaging.sendRequest(aMessage);
}
}
let Messaging = {
@ -71,35 +77,42 @@ let Messaging = {
* Sends a request to Java.
*
* @param aMessage Message to send; must be an object with a "type" property
* @param aCallback Callback function, required if this request expects a response.
*/
sendRequest: function (aMessage, aCallback) {
if (aCallback) {
sendRequest: function (aMessage) {
Services.androidBridge.handleGeckoMessage(aMessage);
},
/**
* Sends a request to Java, returning a Promise that resolves to the response.
*
* @param aMessage Message to send; must be an object with a "type" property
* @returns A Promise resolving to the response
*/
sendRequestForResult: function (aMessage) {
return new Promise((resolve, reject) => {
let id = uuidgen.generateUUID().toString();
let obs = {
observe: function(aSubject, aTopic, aData) {
observe: function (aSubject, aTopic, aData) {
let data = JSON.parse(aData);
if (data.__guid__ != id) {
return;
}
Services.obs.removeObserver(obs, aMessage.type + ":Response", false);
Services.obs.removeObserver(obs, aMessage.type + ":Response");
if (data.status === "cancel") {
// No Java-side listeners handled our callback.
return;
if (data.status === "success") {
resolve(data.response);
} else {
reject(data.response);
}
aCallback(data.status === "success" ? data.response : null,
data.status === "error" ? data.response : null);
}
}
};
aMessage.__guid__ = id;
Services.obs.addObserver(obs, aMessage.type + ":Response", false);
}
return Services.androidBridge.handleGeckoMessage(aMessage);
this.sendRequest(aMessage);
});
},
};

2
testing/mochitest/roboextender/bootstrap.js поставляемый
Просмотреть файл

@ -29,7 +29,7 @@ var windowListener = {
height: XPCNativeWrapper.unwrap(e.target).documentElement.scrollHeight,
cheight: XPCNativeWrapper.unwrap(e.target).documentElement.clientHeight,
};
let retVal = _sendMessageToJava(message);
_sendMessageToJava(message);
});
}
}, false);