mirror of
https://github.com/apache/cordova-android.git
synced 2025-02-26 03:53:09 +08:00
Backport CordovaBridge from 4.0.x -> master
This commit is contained in:
parent
d8a19b5565
commit
cc860804f6
@ -669,7 +669,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
|
|||||||
@Deprecated // Call method on appView directly.
|
@Deprecated // Call method on appView directly.
|
||||||
public void sendJavascript(String statement) {
|
public void sendJavascript(String statement) {
|
||||||
if (this.appView != null) {
|
if (this.appView != null) {
|
||||||
this.appView.jsMessageQueue.addJavaScript(statement);
|
this.appView.bridge.getMessageQueue().addJavaScript(statement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
185
framework/src/org/apache/cordova/CordovaBridge.java
Normal file
185
framework/src/org/apache/cordova/CordovaBridge.java
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import org.apache.cordova.PluginManager;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains APIs that the JS can call. All functions in here should also have
|
||||||
|
* an equivalent entry in CordovaChromeClient.java, and be added to
|
||||||
|
* cordova-js/lib/android/plugin/android/promptbasednativeapi.js
|
||||||
|
*/
|
||||||
|
public class CordovaBridge {
|
||||||
|
private static final String LOG_TAG = "CordovaBridge";
|
||||||
|
private PluginManager pluginManager;
|
||||||
|
private NativeToJsMessageQueue jsMessageQueue;
|
||||||
|
private volatile int bridgeSecret = -1; // written by UI thread, read by JS thread.
|
||||||
|
private String loadedUrl;
|
||||||
|
|
||||||
|
public CordovaBridge(PluginManager pluginManager, NativeToJsMessageQueue jsMessageQueue) {
|
||||||
|
this.pluginManager = pluginManager;
|
||||||
|
this.jsMessageQueue = jsMessageQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final boolean checkBridgeEnabled(String action) {
|
||||||
|
if (!jsMessageQueue.isBridgeEnabled()) {
|
||||||
|
if (bridgeSecret == -1) {
|
||||||
|
Log.d(LOG_TAG, action + " call made before bridge was enabled.");
|
||||||
|
} else {
|
||||||
|
Log.d(LOG_TAG, "Ignoring " + action + " from previous page load.");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String jsExec(int bridgeSecret, String service, String action, String callbackId, String arguments) throws JSONException, IllegalAccessException {
|
||||||
|
if (!checkBridgeEnabled("exec()")) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
verifySecret(bridgeSecret);
|
||||||
|
// If the arguments weren't received, send a message back to JS. It will switch bridge modes and try again. See CB-2666.
|
||||||
|
// We send a message meant specifically for this case. It starts with "@" so no other message can be encoded into the same string.
|
||||||
|
if (arguments == null) {
|
||||||
|
return "@Null arguments.";
|
||||||
|
}
|
||||||
|
|
||||||
|
jsMessageQueue.setPaused(true);
|
||||||
|
try {
|
||||||
|
// Tell the resourceApi what thread the JS is running on.
|
||||||
|
CordovaResourceApi.jsThread = Thread.currentThread();
|
||||||
|
|
||||||
|
pluginManager.exec(service, action, callbackId, arguments);
|
||||||
|
String ret = "";
|
||||||
|
if (!NativeToJsMessageQueue.DISABLE_EXEC_CHAINING) {
|
||||||
|
ret = jsMessageQueue.popAndEncode(false);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return "";
|
||||||
|
} finally {
|
||||||
|
jsMessageQueue.setPaused(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void jsSetNativeToJsBridgeMode(int bridgeSecret, int value) throws IllegalAccessException {
|
||||||
|
verifySecret(bridgeSecret);
|
||||||
|
jsMessageQueue.setBridgeMode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String jsRetrieveJsMessages(int bridgeSecret, boolean fromOnlineEvent) throws IllegalAccessException {
|
||||||
|
if (!checkBridgeEnabled("retrieveJsMessages()")) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
verifySecret(bridgeSecret);
|
||||||
|
return jsMessageQueue.popAndEncode(fromOnlineEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifySecret(int value) throws IllegalAccessException {
|
||||||
|
if (bridgeSecret < 0 || value != bridgeSecret) {
|
||||||
|
throw new IllegalAccessException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called on page transitions */
|
||||||
|
void clearBridgeSecret() {
|
||||||
|
bridgeSecret = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called by cordova.js to initialize the bridge. */
|
||||||
|
int generateBridgeSecret() {
|
||||||
|
bridgeSecret = (int)(Math.random() * Integer.MAX_VALUE);
|
||||||
|
return bridgeSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset(String loadedUrl) {
|
||||||
|
jsMessageQueue.reset();
|
||||||
|
clearBridgeSecret();
|
||||||
|
this.loadedUrl = loadedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String promptOnJsPrompt(String origin, String message, String defaultValue) {
|
||||||
|
if (defaultValue != null && defaultValue.length() > 3 && defaultValue.startsWith("gap:")) {
|
||||||
|
JSONArray array;
|
||||||
|
try {
|
||||||
|
array = new JSONArray(defaultValue.substring(4));
|
||||||
|
int bridgeSecret = array.getInt(0);
|
||||||
|
String service = array.getString(1);
|
||||||
|
String action = array.getString(2);
|
||||||
|
String callbackId = array.getString(3);
|
||||||
|
String r = jsExec(bridgeSecret, service, action, callbackId, message);
|
||||||
|
return r == null ? "" : r;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// Sets the native->JS bridge mode.
|
||||||
|
else if (defaultValue != null && defaultValue.startsWith("gap_bridge_mode:")) {
|
||||||
|
try {
|
||||||
|
int bridgeSecret = Integer.parseInt(defaultValue.substring(16));
|
||||||
|
jsSetNativeToJsBridgeMode(bridgeSecret, Integer.parseInt(message));
|
||||||
|
} catch (NumberFormatException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// Polling for JavaScript messages
|
||||||
|
else if (defaultValue != null && defaultValue.startsWith("gap_poll:")) {
|
||||||
|
int bridgeSecret = Integer.parseInt(defaultValue.substring(9));
|
||||||
|
try {
|
||||||
|
String r = jsRetrieveJsMessages(bridgeSecret, "1".equals(message));
|
||||||
|
return r == null ? "" : r;
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else if (defaultValue != null && defaultValue.startsWith("gap_init:")) {
|
||||||
|
// Protect against random iframes being able to talk through the bridge.
|
||||||
|
// Trust only file URLs and the start URL's domain.
|
||||||
|
// The extra origin.startsWith("http") is to protect against iframes with data: having "" as origin.
|
||||||
|
if (origin.startsWith("file:") || (origin.startsWith("http") && loadedUrl.startsWith(origin))) {
|
||||||
|
// Enable the bridge
|
||||||
|
int bridgeMode = Integer.parseInt(defaultValue.substring(9));
|
||||||
|
jsMessageQueue.setBridgeMode(bridgeMode);
|
||||||
|
// Tell JS the bridge secret.
|
||||||
|
int secret = generateBridgeSecret();
|
||||||
|
return ""+secret;
|
||||||
|
} else {
|
||||||
|
Log.e(LOG_TAG, "gap_init called from restricted origin: " + origin);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeToJsMessageQueue getMessageQueue() {
|
||||||
|
return jsMessageQueue;
|
||||||
|
}
|
||||||
|
}
|
@ -20,15 +20,12 @@ package org.apache.cordova;
|
|||||||
|
|
||||||
import org.apache.cordova.CordovaInterface;
|
import org.apache.cordova.CordovaInterface;
|
||||||
import org.apache.cordova.LOG;
|
import org.apache.cordova.LOG;
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -60,7 +57,6 @@ import android.widget.RelativeLayout;
|
|||||||
public class CordovaChromeClient extends WebChromeClient {
|
public class CordovaChromeClient extends WebChromeClient {
|
||||||
|
|
||||||
public static final int FILECHOOSER_RESULTCODE = 5173;
|
public static final int FILECHOOSER_RESULTCODE = 5173;
|
||||||
private static final String LOG_TAG = "CordovaChromeClient";
|
|
||||||
private String TAG = "CordovaLog";
|
private String TAG = "CordovaLog";
|
||||||
private long MAX_QUOTA = 100 * 1024 * 1024;
|
private long MAX_QUOTA = 100 * 1024 * 1024;
|
||||||
protected CordovaInterface cordova;
|
protected CordovaInterface cordova;
|
||||||
@ -193,67 +189,9 @@ public class CordovaChromeClient extends WebChromeClient {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onJsPrompt(WebView view, String origin, String message, String defaultValue, JsPromptResult result) {
|
public boolean onJsPrompt(WebView view, String origin, String message, String defaultValue, JsPromptResult result) {
|
||||||
// Unlike the @JavascriptInterface bridge, this method is always called on the UI thread.
|
// Unlike the @JavascriptInterface bridge, this method is always called on the UI thread.
|
||||||
if (defaultValue != null && defaultValue.length() > 3 && defaultValue.startsWith("gap:")) {
|
String handledRet = appView.bridge.promptOnJsPrompt(origin, message, defaultValue);
|
||||||
JSONArray array;
|
if (handledRet != null) {
|
||||||
try {
|
result.confirm(handledRet);
|
||||||
array = new JSONArray(defaultValue.substring(4));
|
|
||||||
int bridgeSecret = array.getInt(0);
|
|
||||||
String service = array.getString(1);
|
|
||||||
String action = array.getString(2);
|
|
||||||
String callbackId = array.getString(3);
|
|
||||||
String r = appView.exposedJsApi.exec(bridgeSecret, service, action, callbackId, message);
|
|
||||||
result.confirm(r == null ? "" : r);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
result.cancel();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
result.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets the native->JS bridge mode.
|
|
||||||
else if (defaultValue != null && defaultValue.startsWith("gap_bridge_mode:")) {
|
|
||||||
try {
|
|
||||||
int bridgeSecret = Integer.parseInt(defaultValue.substring(16));
|
|
||||||
appView.exposedJsApi.setNativeToJsBridgeMode(bridgeSecret, Integer.parseInt(message));
|
|
||||||
result.cancel();
|
|
||||||
} catch (NumberFormatException e){
|
|
||||||
e.printStackTrace();
|
|
||||||
result.cancel();
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
result.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Polling for JavaScript messages
|
|
||||||
else if (defaultValue != null && defaultValue.startsWith("gap_poll:")) {
|
|
||||||
int bridgeSecret = Integer.parseInt(defaultValue.substring(9));
|
|
||||||
try {
|
|
||||||
String r = appView.exposedJsApi.retrieveJsMessages(bridgeSecret, "1".equals(message));
|
|
||||||
result.confirm(r == null ? "" : r);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
result.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (defaultValue != null && defaultValue.startsWith("gap_init:")) {
|
|
||||||
// Protect against random iframes being able to talk through the bridge.
|
|
||||||
// Trust only file URLs and the start URL's domain.
|
|
||||||
// The extra origin.startsWith("http") is to protect against iframes with data: having "" as origin.
|
|
||||||
if (origin.startsWith("file:") || (origin.startsWith("http") && appView.loadedUrl.startsWith(origin))) {
|
|
||||||
// Enable the bridge
|
|
||||||
int bridgeMode = Integer.parseInt(defaultValue.substring(9));
|
|
||||||
appView.jsMessageQueue.setBridgeMode(bridgeMode);
|
|
||||||
// Tell JS the bridge secret.
|
|
||||||
int secret = appView.exposedJsApi.generateBridgeSecret();
|
|
||||||
result.confirm(""+secret);
|
|
||||||
} else {
|
|
||||||
Log.e(LOG_TAG, "gap_init called from restricted origin: " + origin);
|
|
||||||
result.cancel();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Returning false would also show a dialog, but the default one shows the origin (ugly).
|
// Returning false would also show a dialog, but the default one shows the origin (ugly).
|
||||||
final JsPromptResult res = result;
|
final JsPromptResult res = result;
|
||||||
|
@ -81,8 +81,7 @@ public class CordovaWebView extends WebView {
|
|||||||
|
|
||||||
private long lastMenuEventTime = 0;
|
private long lastMenuEventTime = 0;
|
||||||
|
|
||||||
NativeToJsMessageQueue jsMessageQueue;
|
CordovaBridge bridge;
|
||||||
ExposedJsApi exposedJsApi;
|
|
||||||
|
|
||||||
/** custom view created by the browser (a video player for example) */
|
/** custom view created by the browser (a video player for example) */
|
||||||
private View mCustomView;
|
private View mCustomView;
|
||||||
@ -149,8 +148,7 @@ public class CordovaWebView extends WebView {
|
|||||||
super.setWebViewClient(webViewClient);
|
super.setWebViewClient(webViewClient);
|
||||||
|
|
||||||
pluginManager = new PluginManager(this, this.cordova, pluginEntries);
|
pluginManager = new PluginManager(this, this.cordova, pluginEntries);
|
||||||
jsMessageQueue = new NativeToJsMessageQueue(this, cordova);
|
bridge = new CordovaBridge(pluginManager, new NativeToJsMessageQueue(this, cordova));
|
||||||
exposedJsApi = new ExposedJsApi(pluginManager, jsMessageQueue);
|
|
||||||
resourceApi = new CordovaResourceApi(this.getContext(), pluginManager);
|
resourceApi = new CordovaResourceApi(this.getContext(), pluginManager);
|
||||||
|
|
||||||
pluginManager.addService("App", "org.apache.cordova.App");
|
pluginManager.addService("App", "org.apache.cordova.App");
|
||||||
@ -300,7 +298,7 @@ public class CordovaWebView extends WebView {
|
|||||||
// use the prompt bridge instead.
|
// use the prompt bridge instead.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.addJavascriptInterface(exposedJsApi, "_cordovaNative");
|
this.addJavascriptInterface(new ExposedJsApi(bridge), "_cordovaNative");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -497,7 +495,7 @@ public class CordovaWebView extends WebView {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void sendJavascript(String statement) {
|
public void sendJavascript(String statement) {
|
||||||
this.jsMessageQueue.addJavaScript(statement);
|
this.bridge.getMessageQueue().addJavaScript(statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -508,7 +506,7 @@ public class CordovaWebView extends WebView {
|
|||||||
* @param callbackId
|
* @param callbackId
|
||||||
*/
|
*/
|
||||||
public void sendPluginResult(PluginResult result, String callbackId) {
|
public void sendPluginResult(PluginResult result, String callbackId) {
|
||||||
this.jsMessageQueue.addPluginResult(result, callbackId);
|
this.bridge.getMessageQueue().addPluginResult(result, callbackId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -141,8 +141,7 @@ public class CordovaWebViewClient extends WebViewClient {
|
|||||||
isCurrentlyLoading = true;
|
isCurrentlyLoading = true;
|
||||||
LOG.d(TAG, "onPageStarted(" + url + ")");
|
LOG.d(TAG, "onPageStarted(" + url + ")");
|
||||||
// Flush stale messages.
|
// Flush stale messages.
|
||||||
this.appView.jsMessageQueue.reset();
|
this.appView.bridge.reset(url);
|
||||||
this.appView.exposedJsApi.clearBridgeSecret();
|
|
||||||
|
|
||||||
// Broadcast message that page has loaded
|
// Broadcast message that page has loaded
|
||||||
this.appView.postMessage("onPageStarted", url);
|
this.appView.postMessage("onPageStarted", url);
|
||||||
|
@ -20,7 +20,6 @@ package org.apache.cordova;
|
|||||||
|
|
||||||
import android.webkit.JavascriptInterface;
|
import android.webkit.JavascriptInterface;
|
||||||
|
|
||||||
import org.apache.cordova.PluginManager;
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,69 +29,24 @@ import org.json.JSONException;
|
|||||||
*/
|
*/
|
||||||
/* package */ class ExposedJsApi {
|
/* package */ class ExposedJsApi {
|
||||||
|
|
||||||
private PluginManager pluginManager;
|
private CordovaBridge bridge;
|
||||||
private NativeToJsMessageQueue jsMessageQueue;
|
|
||||||
private volatile int bridgeSecret = -1; // written by UI thread, read by JS thread.
|
|
||||||
|
|
||||||
public ExposedJsApi(PluginManager pluginManager, NativeToJsMessageQueue jsMessageQueue) {
|
public ExposedJsApi(CordovaBridge bridge) {
|
||||||
this.pluginManager = pluginManager;
|
this.bridge = bridge;
|
||||||
this.jsMessageQueue = jsMessageQueue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
public String exec(int bridgeSecret, String service, String action, String callbackId, String arguments) throws JSONException, IllegalAccessException {
|
public String exec(int bridgeSecret, String service, String action, String callbackId, String arguments) throws JSONException, IllegalAccessException {
|
||||||
verifySecret(bridgeSecret);
|
return bridge.jsExec(bridgeSecret, service, action, callbackId, arguments);
|
||||||
// If the arguments weren't received, send a message back to JS. It will switch bridge modes and try again. See CB-2666.
|
|
||||||
// We send a message meant specifically for this case. It starts with "@" so no other message can be encoded into the same string.
|
|
||||||
if (arguments == null) {
|
|
||||||
return "@Null arguments.";
|
|
||||||
}
|
|
||||||
|
|
||||||
jsMessageQueue.setPaused(true);
|
|
||||||
try {
|
|
||||||
// Tell the resourceApi what thread the JS is running on.
|
|
||||||
CordovaResourceApi.jsThread = Thread.currentThread();
|
|
||||||
|
|
||||||
pluginManager.exec(service, action, callbackId, arguments);
|
|
||||||
String ret = "";
|
|
||||||
if (!NativeToJsMessageQueue.DISABLE_EXEC_CHAINING) {
|
|
||||||
ret = jsMessageQueue.popAndEncode(false);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return "";
|
|
||||||
} finally {
|
|
||||||
jsMessageQueue.setPaused(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
public void setNativeToJsBridgeMode(int bridgeSecret, int value) throws IllegalAccessException {
|
public void setNativeToJsBridgeMode(int bridgeSecret, int value) throws IllegalAccessException {
|
||||||
verifySecret(bridgeSecret);
|
bridge.jsSetNativeToJsBridgeMode(bridgeSecret, value);
|
||||||
jsMessageQueue.setBridgeMode(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
public String retrieveJsMessages(int bridgeSecret, boolean fromOnlineEvent) throws IllegalAccessException {
|
public String retrieveJsMessages(int bridgeSecret, boolean fromOnlineEvent) throws IllegalAccessException {
|
||||||
verifySecret(bridgeSecret);
|
return bridge.jsRetrieveJsMessages(bridgeSecret, fromOnlineEvent);
|
||||||
return jsMessageQueue.popAndEncode(fromOnlineEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void verifySecret(int value) throws IllegalAccessException {
|
|
||||||
if (bridgeSecret < 0 || value != bridgeSecret) {
|
|
||||||
throw new IllegalAccessException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Called on page transitions */
|
|
||||||
void clearBridgeSecret() {
|
|
||||||
bridgeSecret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Called by cordova.js to initialize the bridge. */
|
|
||||||
int generateBridgeSecret() {
|
|
||||||
bridgeSecret = (int)(Math.random() * Integer.MAX_VALUE);
|
|
||||||
return bridgeSecret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,11 @@ public class NativeToJsMessageQueue {
|
|||||||
registeredListeners[3] = new PrivateApiBridgeMode();
|
registeredListeners[3] = new PrivateApiBridgeMode();
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isBridgeEnabled() {
|
||||||
|
return activeBridgeMode != null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the bridge mode.
|
* Changes the bridge mode.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user