Bug 946344 - Remove GeckoEventResponder. r=mfinkle,blassey,kats

This commit is contained in:
Wes Johnston
2014-02-11 09:16:00 -08:00
parent 08b06cf66a
commit c89afdba0a
47 changed files with 269 additions and 503 deletions

View File

@@ -11,7 +11,9 @@
#include "ImageContainer.h"
#include "ImageTypes.h"
#include "prmem.h"
#include "nsContentUtils.h"
#include "nsIFilePicker.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
@@ -164,18 +166,38 @@ MediaEngineDefaultVideoSource::Snapshot(uint32_t aDuration, nsIDOMFile** aFile)
#ifndef MOZ_WIDGET_ANDROID
return NS_ERROR_NOT_IMPLEMENTED;
#else
if (!AndroidBridge::Bridge()) {
return NS_ERROR_UNEXPECTED;
nsAutoString filePath;
nsCOMPtr<nsIFilePicker> filePicker = do_CreateInstance("@mozilla.org/filepicker;1");
if (!filePicker)
return NS_ERROR_FAILURE;
nsXPIDLString title;
nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES, "Browse", title);
int16_t mode = static_cast<int16_t>(nsIFilePicker::modeOpen);
nsresult rv = filePicker->Init(nullptr, title, mode);
NS_ENSURE_SUCCESS(rv, rv);
filePicker->AppendFilters(nsIFilePicker::filterImages);
// XXX - This API should be made async
PRInt16 dialogReturn;
rv = filePicker->Show(&dialogReturn);
NS_ENSURE_SUCCESS(rv, rv);
if (dialogReturn == nsIFilePicker::returnCancel) {
*aFile = nullptr;
return NS_OK;
}
nsAutoString filePath;
AndroidBridge::Bridge()->ShowFilePickerForMimeType(filePath, NS_LITERAL_STRING("image/*"));
nsCOMPtr<nsIFile> localFile;
filePicker->GetFile(getter_AddRefs(localFile));
nsCOMPtr<nsIFile> file;
nsresult rv = NS_NewLocalFile(filePath, false, getter_AddRefs(file));
NS_ENSURE_SUCCESS(rv, rv);
if (!localFile) {
*aFile = nullptr;
return NS_OK;
}
NS_ADDREF(*aFile = new nsDOMFileFile(file));
nsCOMPtr<nsIDOMFile> domFile = new nsDOMFileFile(localFile);
domFile.forget(aFile);
return NS_OK;
#endif
}

View File

@@ -238,82 +238,6 @@ public class ActivityHandlerHelper implements GeckoEventListener {
});
}
private Intent getFilePickerIntent(Context context, String aMimeType) {
ArrayList<Intent> intents = new ArrayList<Intent>();
final Prompt.PromptListItem[] items =
getItemsAndIntentsForFilePicker(context, aMimeType, intents);
if (intents.size() == 0) {
Log.i(LOGTAG, "no activities for the file picker!");
return null;
}
if (intents.size() == 1) {
return intents.get(0);
}
final PromptService ps = GeckoAppShell.getGeckoInterface().getPromptService();
final String title = getFilePickerTitle(context, aMimeType);
// Runnable has to be called to show an intent-like
// context menu UI using the PromptService.
ThreadUtils.postToUiThread(new Runnable() {
@Override public void run() {
ps.show(title, "", items, false, null);
}
});
String promptServiceResult = ps.getResponse(null);
int itemId = -1;
try {
itemId = new JSONObject(promptServiceResult).getInt("button");
if (itemId == -1) {
return null;
}
} catch (JSONException e) {
Log.e(LOGTAG, "result from promptservice was invalid: ", e);
return null;
}
return intents.get(itemId);
}
boolean showFilePicker(Activity parentActivity, String aMimeType, ActivityResultHandler handler) {
Intent intent = getFilePickerIntent(parentActivity, aMimeType);
if (intent == null) {
return false;
}
parentActivity.startActivityForResult(intent, mActivityResultHandlerMap.put(handler));
return true;
}
String showFilePicker(Activity parentActivity, String aMimeType) {
Intent intent = getFilePickerIntent(parentActivity, aMimeType);
if (intent == null) {
return "";
}
if (intent.getAction().equals(MediaStore.ACTION_IMAGE_CAPTURE)) {
parentActivity.startActivityForResult(intent, mActivityResultHandlerMap.put(mCameraImageResultHandler));
} else if (intent.getAction().equals(MediaStore.ACTION_VIDEO_CAPTURE)) {
parentActivity.startActivityForResult(intent, mActivityResultHandlerMap.put(mCameraVideoResultHandler));
} else if (intent.getAction().equals(Intent.ACTION_GET_CONTENT)) {
parentActivity.startActivityForResult(intent, mActivityResultHandlerMap.put(mFilePickerResultHandlerSync));
} else {
Log.e(LOGTAG, "We should not get an intent with another action!");
return "";
}
String filePickerResult;
while (null == (filePickerResult = mFilePickerResult.poll())) {
GeckoAppShell.processNextNativeEvent(true);
}
return filePickerResult;
}
/* Allows the user to pick an activity to load files from using a list prompt. Then opens the activity and
* sends the file returned to the passed in handler. If a null handler is passed in, will still
* pick and launch the file picker, but will throw away the result.

View File

@@ -31,7 +31,7 @@ import org.mozilla.gecko.prompts.Prompt;
import org.mozilla.gecko.toolbar.AutocompleteHandler;
import org.mozilla.gecko.toolbar.BrowserToolbar;
import org.mozilla.gecko.util.Clipboard;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.GamepadUtils;
import org.mozilla.gecko.util.HardwareUtils;
import org.mozilla.gecko.util.MenuUtils;

View File

@@ -6,7 +6,7 @@ package org.mozilla.gecko;
import org.mozilla.gecko.gfx.Layer;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.ThreadUtils;

View File

@@ -2,7 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.util;
package org.mozilla.gecko;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.util.GeckoEventListener;
import org.json.JSONObject;
@@ -14,6 +18,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
public final class EventDispatcher {
private static final String LOGTAG = "GeckoEventDispatcher";
private static final String GUID = "__guid__";
private final Map<String, CopyOnWriteArrayList<GeckoEventListener>> mEventListeners
= new HashMap<String, CopyOnWriteArrayList<GeckoEventListener>>();
@@ -52,18 +57,16 @@ public final class EventDispatcher {
}
}
public String dispatchEvent(String message) {
public void dispatchEvent(String message) {
try {
JSONObject json = new JSONObject(message);
return dispatchEvent(json);
dispatchEvent(json);
} catch (Exception e) {
Log.e(LOGTAG, "dispatchEvent: malformed JSON.", e);
}
return "";
}
public String dispatchEvent(JSONObject json) {
public void dispatchEvent(JSONObject json) {
// {
// "type": "value",
// "event_specific": "value",
@@ -87,29 +90,29 @@ public final class EventDispatcher {
if (listeners == null || listeners.size() == 0) {
Log.d(LOGTAG, "dispatchEvent: no listeners registered for event '" + type + "'");
return "";
return;
}
String response = null;
for (GeckoEventListener listener : listeners) {
listener.handleMessage(type, json);
if (listener instanceof GeckoEventResponder) {
String newResponse = ((GeckoEventResponder)listener).getResponse(json);
if (response != null && newResponse != null) {
Log.e(LOGTAG, "Received two responses for message of type " + type);
}
response = newResponse;
}
}
if (response != null)
return response;
} catch (Exception e) {
Log.e(LOGTAG, "handleGeckoMessage throws " + e, e);
}
return "";
}
public static void sendResponse(JSONObject message, JSONObject response) {
try {
response.put(GUID, message.getString(GUID));
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(message.getString("type") + ":Return", response.toString()));
} catch(Exception ex) { }
}
public static void sendError(JSONObject message, JSONObject error) {
try {
error.put(GUID, message.getString(GUID));
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(message.getString("type") + ":Error", error.toString()));
} catch(Exception ex) { }
}
}

View File

@@ -23,9 +23,7 @@ import org.mozilla.gecko.preferences.GeckoPreferences;
import org.mozilla.gecko.updater.UpdateService;
import org.mozilla.gecko.updater.UpdateServiceHelper;
import org.mozilla.gecko.util.ActivityResultHandler;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.GeckoEventResponder;
import org.mozilla.gecko.util.HardwareUtils;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.UiAsyncTask;
@@ -134,7 +132,6 @@ public abstract class GeckoApp
ContextGetter,
GeckoAppShell.GeckoInterface,
GeckoEventListener,
GeckoEventResponder,
GeckoMenu.Callback,
GeckoMenu.MenuPresenter,
LocationListener,
@@ -187,7 +184,6 @@ public abstract class GeckoApp
protected GeckoProfile mProfile;
public static int mOrientation;
protected boolean mIsRestoringActivity;
private String mCurrentResponse = "";
private ContactService mContactService;
private PromptService mPromptService;
@@ -685,7 +681,7 @@ public abstract class GeckoApp
}
JSONObject handlersJSON = new JSONObject();
handlersJSON.put("apps", new JSONArray(appList));
mCurrentResponse = handlersJSON.toString();
EventDispatcher.sendResponse(message, handlersJSON);
} else if (event.equals("Intent:Open")) {
GeckoAppShell.openUriExternal(message.optString("url"),
message.optString("mime"), message.optString("packageName"),
@@ -693,7 +689,9 @@ public abstract class GeckoApp
} else if (event.equals("Locale:Set")) {
setLocale(message.getString("locale"));
} else if (event.equals("NativeApp:IsDebuggable")) {
mCurrentResponse = getIsDebuggable() ? "true" : "false";
JSONObject ret = new JSONObject();
ret.put("isDebuggable", getIsDebuggable() ? "true" : "false");
EventDispatcher.sendResponse(message, ret);
} else if (event.equals("SystemUI:Visibility")) {
setSystemUiVisible(message.getBoolean("visible"));
}
@@ -702,12 +700,6 @@ public abstract class GeckoApp
}
}
public String getResponse(JSONObject origMessage) {
String res = mCurrentResponse;
mCurrentResponse = "";
return res;
}
void onStatePurged() { }
/**

View File

@@ -18,7 +18,6 @@ import org.mozilla.gecko.mozglue.JNITarget;
import org.mozilla.gecko.mozglue.RobocopTarget;
import org.mozilla.gecko.prompts.PromptService;
import org.mozilla.gecko.util.ActivityResultHandler;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.HardwareUtils;
import org.mozilla.gecko.util.ProxySelector;
@@ -1427,20 +1426,6 @@ public class GeckoAppShell
getGeckoInterface().setFullScreen(fullscreen);
}
@WrapElementForJNI(stubName = "ShowFilePickerForExtensionsWrapper")
public static String showFilePickerForExtensions(String aExtensions) {
if (getGeckoInterface() != null)
return sActivityHelper.showFilePicker(getGeckoInterface().getActivity(), getMimeTypeFromExtensions(aExtensions));
return "";
}
@WrapElementForJNI(stubName = "ShowFilePickerForMimeTypeWrapper")
public static String showFilePickerForMimeType(String aMimeType) {
if (getGeckoInterface() != null)
return sActivityHelper.showFilePicker(getGeckoInterface().getActivity(), aMimeType);
return "";
}
@WrapElementForJNI
public static void performHapticFeedback(boolean aIsLongPress) {
// Don't perform haptic feedback if a vibration is currently playing,
@@ -2345,8 +2330,8 @@ public class GeckoAppShell
}
@WrapElementForJNI(stubName = "HandleGeckoMessageWrapper")
public static String handleGeckoMessage(String message) {
return sEventDispatcher.dispatchEvent(message);
public static void handleGeckoMessage(String message) {
sEventDispatcher.dispatchEvent(message);
}
@WrapElementForJNI
@@ -2630,17 +2615,6 @@ public class GeckoAppShell
return true;
}
static native void notifyFilePickerResult(String filePath, long id);
@WrapElementForJNI(stubName = "ShowFilePickerAsyncWrapper")
public static void showFilePickerAsync(String aMimeType, final long id) {
sActivityHelper.showFilePickerAsync(getGeckoInterface().getActivity(), aMimeType, new ActivityHandlerHelper.FileResultHandler() {
public void gotFile(String filename) {
GeckoAppShell.notifyFilePickerResult(filename, id);
}
});
}
@WrapElementForJNI
public static void notifyWakeLockChanged(String topic, String state) {
if (getGeckoInterface() != null)

View File

@@ -5,9 +5,7 @@
package org.mozilla.gecko;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.GeckoEventResponder;
import org.json.JSONException;
import org.json.JSONObject;
@@ -140,7 +138,7 @@ class JavaAddonManager implements GeckoEventListener {
}
}
private static class CallbackWrapper implements GeckoEventResponder {
private static class CallbackWrapper implements GeckoEventListener {
private final Handler.Callback mDelegate;
private Bundle mBundle;
@@ -184,16 +182,14 @@ class JavaAddonManager implements GeckoEventListener {
Message msg = new Message();
msg.setData(mBundle);
mDelegate.handleMessage(msg);
JSONObject obj = new JSONObject();
obj.put("response", mBundle.getString("response"));
EventDispatcher.sendResponse(json, obj);
mBundle = null;
} catch (Exception e) {
Log.e(LOGTAG, "Caught exception thrown from wrapped addon message handler", e);
}
}
@Override
public String getResponse(JSONObject origMessage) {
String response = mBundle.getString("response");
mBundle = null;
return response;
}
}
}

View File

@@ -6,7 +6,7 @@
package org.mozilla.gecko;
import org.mozilla.gecko.background.common.GlobalConstants;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.GeckoEventListener;
import org.json.JSONException;

View File

@@ -5,8 +5,8 @@
package org.mozilla.gecko;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.util.GeckoEventResponder;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.GeckoEventListener;
import org.json.JSONArray;
import org.json.JSONException;
@@ -24,14 +24,12 @@ import java.util.HashMap;
* Helper class to get, set, and observe Android Shared Preferences.
*/
public final class SharedPreferencesHelper
implements GeckoEventResponder
implements GeckoEventListener
{
public static final String LOGTAG = "GeckoAndSharedPrefs";
protected final Context mContext;
protected String mResponse;
// mListeners is not synchronized because it is only updated in
// handleObserve, which is called from Gecko serially.
protected final Map<String, SharedPreferences.OnSharedPreferenceChangeListener> mListeners;
@@ -117,7 +115,7 @@ public final class SharedPreferencesHelper
* must include a String name, and a String type in ["bool", "int",
* "string"].
*/
private String handleGet(JSONObject message) throws JSONException {
private JSONArray handleGet(JSONObject message) throws JSONException {
if (!message.has("branch")) {
Log.e(LOGTAG, "No branch specified for SharedPreference:Get; aborting.");
return null;
@@ -156,7 +154,7 @@ public final class SharedPreferencesHelper
jsonValues.put(jsonValue);
}
return jsonValues.toString();
return jsonValues;
}
private static class ChangeListener
@@ -225,8 +223,6 @@ public final class SharedPreferencesHelper
public void handleMessage(String event, JSONObject message) {
// Everything here is synchronous and serial, so we need not worry about
// overwriting an in-progress response.
mResponse = null;
try {
if (event.equals("SharedPreferences:Set")) {
if (Log.isLoggable(LOGTAG, Log.VERBOSE)) {
@@ -237,9 +233,9 @@ public final class SharedPreferencesHelper
if (Log.isLoggable(LOGTAG, Log.VERBOSE)) {
Log.v(LOGTAG, "Got SharedPreferences:Get message.");
}
// Synchronous and serial, so we are the only consumer of
// mResponse and can write to it freely.
mResponse = handleGet(message);
JSONObject obj = new JSONObject();
obj.put("values", handleGet(message));
EventDispatcher.sendResponse(message, obj);
} else if (event.equals("SharedPreferences:Observe")) {
if (Log.isLoggable(LOGTAG, Log.VERBOSE)) {
Log.v(LOGTAG, "Got SharedPreferences:Observe message.");
@@ -254,9 +250,4 @@ public final class SharedPreferencesHelper
return;
}
}
@Override
public String getResponse(JSONObject origMessage) {
return mResponse;
}
}

View File

@@ -10,7 +10,7 @@ import org.mozilla.gecko.gfx.Layer;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.menu.GeckoMenu;
import org.mozilla.gecko.menu.GeckoMenuItem;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.FloatUtils;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.ThreadUtils;

View File

@@ -12,7 +12,7 @@ import org.mozilla.gecko.Tabs;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.mozglue.RobocopTarget;
import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.FloatUtils;
import android.content.Context;

View File

@@ -11,7 +11,7 @@ import org.mozilla.gecko.PrefsHelper;
import org.mozilla.gecko.Tab;
import org.mozilla.gecko.Tabs;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.FloatUtils;
import org.mozilla.gecko.util.GamepadUtils;
import org.mozilla.gecko.util.GeckoEventListener;

View File

@@ -16,7 +16,7 @@ import org.mozilla.gecko.TouchEventInterceptor;
import org.mozilla.gecko.ZoomConstraints;
import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import org.mozilla.gecko.mozglue.RobocopTarget;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.EventDispatcher;
import android.content.Context;
import android.graphics.Bitmap;

View File

@@ -8,7 +8,7 @@ package org.mozilla.gecko.gfx;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.GeckoThread;
import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.GeckoEventListener;
import org.json.JSONObject;

View File

@@ -6,7 +6,7 @@
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.EventDispatcher;
import android.graphics.PointF;
import android.view.KeyEvent;

View File

@@ -7,7 +7,7 @@ package org.mozilla.gecko.gfx;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.GeckoEventListener;
import org.json.JSONException;

View File

@@ -26,7 +26,7 @@ import org.mozilla.gecko.background.healthreport.HealthReportStorage.Measurement
import org.mozilla.gecko.background.healthreport.HealthReportStorage.MeasurementFields.FieldSpec;
import org.mozilla.gecko.background.healthreport.ProfileInformationCache;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.ThreadUtils;

View File

@@ -41,12 +41,10 @@ gujar.sources += [
'util/ActivityResultHandler.java',
'util/ActivityResultHandlerMap.java',
'util/Clipboard.java',
'util/EventDispatcher.java',
'util/FloatUtils.java',
'util/GamepadUtils.java',
'util/GeckoBackgroundThread.java',
'util/GeckoEventListener.java',
'util/GeckoEventResponder.java',
'util/GeckoJarReader.java',
'util/HardwareUtils.java',
'util/INIParser.java',
@@ -125,6 +123,7 @@ gbjar.sources += [
'Distribution.java',
'DoorHangerPopup.java',
'EditBookmarkDialog.java',
'EventDispatcher.java',
'favicons/cache/FaviconCache.java',
'favicons/cache/FaviconCacheElement.java',
'favicons/cache/FaviconsForURL.java',

View File

@@ -5,7 +5,6 @@
package org.mozilla.gecko.prompts;
import org.mozilla.gecko.util.GeckoEventResponder;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.widget.DateTimePicker;
@@ -54,7 +53,6 @@ import android.widget.TimePicker;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
public class Prompt implements OnClickListener, OnCancelListener, OnItemClickListener {
@@ -66,7 +64,6 @@ public class Prompt implements OnClickListener, OnCancelListener, OnItemClickLis
private AlertDialog mDialog;
private final LayoutInflater mInflater;
private ConcurrentLinkedQueue<String> mPromptQueue;
private final Context mContext;
private PromptCallback mCallback;
private String mGuid;
@@ -80,16 +77,9 @@ public class Prompt implements OnClickListener, OnCancelListener, OnItemClickLis
private static int mInputPaddingSize;
private static int mMinRowSize;
public Prompt(Context context, ConcurrentLinkedQueue<String> queue) {
this(context);
mCallback = null;
mPromptQueue = queue;
}
public Prompt(Context context, PromptCallback callback) {
this(context);
mCallback = callback;
mPromptQueue = null;
}
private Prompt(Context context) {
@@ -415,10 +405,6 @@ public class Prompt implements OnClickListener, OnCancelListener, OnItemClickLis
aReturn.put("guid", mGuid);
} catch(JSONException ex) { }
if (mPromptQueue != null) {
mPromptQueue.offer(aReturn.toString());
}
// poke the Gecko thread in case it's waiting for new events
GeckoAppShell.sendEventToGecko(GeckoEvent.createNoOpEvent());

View File

@@ -5,7 +5,6 @@
package org.mozilla.gecko.prompts;
import org.mozilla.gecko.util.GeckoEventResponder;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.widget.AllCapsTextView;
import org.mozilla.gecko.widget.DateTimePicker;

View File

@@ -5,27 +5,28 @@
package org.mozilla.gecko.prompts;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.util.GeckoEventResponder;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.GeckoEventListener;
import org.json.JSONObject;
import org.json.JSONException;
import android.content.Context;
import android.util.Log;
import java.util.concurrent.ConcurrentLinkedQueue;
public class PromptService implements GeckoEventResponder {
public class PromptService implements GeckoEventListener {
private static final String LOGTAG = "GeckoPromptService";
private final ConcurrentLinkedQueue<String> mPromptQueue;
private final Context mContext;
public PromptService(Context context) {
GeckoAppShell.getEventDispatcher().registerEventListener("Prompt:Show", this);
GeckoAppShell.getEventDispatcher().registerEventListener("Prompt:ShowTop", this);
mPromptQueue = new ConcurrentLinkedQueue<String>();
mContext = context;
}
@@ -41,11 +42,7 @@ public class PromptService implements GeckoEventResponder {
@Override
public void run() {
Prompt p;
if (callback != null) {
p = new Prompt(mContext, callback);
} else {
p = new Prompt(mContext, mPromptQueue);
}
p = new Prompt(mContext, callback);
p.show(aTitle, aText, aMenuList, aMultipleSelection);
}
});
@@ -58,35 +55,18 @@ public class PromptService implements GeckoEventResponder {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
boolean isAsync = message.optBoolean("async");
Prompt p;
if (isAsync) {
p = new Prompt(mContext, new Prompt.PromptCallback() {
public void onPromptFinished(String jsonResult) {
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Prompt:Reply", jsonResult));
p = new Prompt(mContext, new Prompt.PromptCallback() {
public void onPromptFinished(String jsonResult) {
try {
EventDispatcher.sendResponse(message, new JSONObject(jsonResult));
} catch(JSONException ex) {
Log.i(LOGTAG, "Error building json response", ex);
}
});
} else {
p = new Prompt(mContext, mPromptQueue);
}
}
});
p.show(message);
}
});
}
// GeckoEventResponder implementation
@Override
public String getResponse(final JSONObject origMessage) {
if (origMessage.optBoolean("async")) {
return "";
}
// we only handle one kind of message in handleMessage, and this is the
// response we provide for that message
String result;
while (null == (result = mPromptQueue.poll())) {
GeckoAppShell.processNextNativeEvent(true);
}
return result;
}
}

View File

@@ -4,13 +4,10 @@
<meta name="viewport" content="initial-scale=1.0"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript">
Components.utils.import("resource://gre/modules/Messaging.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/Home.jsm");
function sendMessageToJava(msg) {
return Services.androidBridge.handleGeckoMessage(JSON.stringify(msg));
}
const TEXT = "The quick brown fox jumps over the lazy dog.";
function start() {

View File

@@ -1,16 +0,0 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* ***** BEGIN LICENSE BLOCK *****
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* ***** END LICENSE BLOCK ***** */
package org.mozilla.gecko.util;
import org.json.JSONObject;
public interface GeckoEventResponder extends GeckoEventListener {
String getResponse(JSONObject response);
}

View File

@@ -11,9 +11,8 @@ import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.favicons.decoders.FaviconDecoder;
import org.mozilla.gecko.gfx.BitmapUtils;
import org.mozilla.gecko.util.ActivityResultHandler;
import org.mozilla.gecko.util.EventDispatcher;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.util.GeckoEventListener;
import org.mozilla.gecko.util.GeckoEventResponder;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.WebappAllocator;
@@ -38,14 +37,13 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class EventListener implements GeckoEventListener, GeckoEventResponder {
public class EventListener implements GeckoEventListener {
private static final String LOGTAG = "GeckoWebappEventListener";
private EventListener() { }
private static EventListener mEventListener;
private String mCurrentResponse = "";
private static EventListener getEventListener() {
if (mEventListener == null) {
@@ -110,23 +108,20 @@ public class EventListener implements GeckoEventListener, GeckoEventResponder {
String manifestURL = message.getString("manifestURL");
String origin = message.getString("origin");
// preInstallWebapp will return a File object pointing to the profile directory of the webapp
mCurrentResponse = preInstallWebapp(name, manifestURL, origin).toString();
JSONObject obj = new JSONObject();
obj.put("profile", preInstallWebapp(name, manifestURL, origin).toString());
EventDispatcher.sendResponse(message, obj);
} else if (event.equals("WebApps:GetApkVersions")) {
mCurrentResponse = getApkVersions(GeckoAppShell.getGeckoInterface().getActivity(),
message.getJSONArray("packageNames")).toString();
JSONObject obj = new JSONObject();
obj.put("versions", getApkVersions(GeckoAppShell.getGeckoInterface().getActivity(),
message.getJSONArray("packageNames")).toString());
EventDispatcher.sendResponse(message, obj);
}
} catch (Exception e) {
Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
}
}
public String getResponse(JSONObject origMessage) {
String res = mCurrentResponse;
mCurrentResponse = "";
return res;
}
// Not used by MOZ_ANDROID_SYNTHAPKS.
public static File preInstallWebapp(String aTitle, String aURI, String aOrigin) {
int index = WebappAllocator.getInstance(GeckoAppShell.getContext()).findAndAllocateIndex(aOrigin, aTitle, (String) null);

View File

@@ -9,16 +9,13 @@ let Ci = Components.interfaces;
let Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Messaging.jsm");
document.addEventListener("DOMContentLoaded", init, false);
function dump(a) {
Services.console.logStringMessage(a);
}
function sendMessageToJava(aMessage) {
Services.androidBridge.handleGeckoMessage(JSON.stringify(aMessage));
}
function init() {
let anchors = document.querySelectorAll(".maybe-later");
for(let anchor of anchors) {

View File

@@ -9,6 +9,7 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Messaging.jsm");
Cu.import("resource://gre/modules/SharedPreferences.jsm");
// Name of Android SharedPreference controlling whether to upload
@@ -24,10 +25,6 @@ const WRAPPER_VERSION = 1;
const EVENT_HEALTH_REQUEST = "HealthReport:Request";
const EVENT_HEALTH_RESPONSE = "HealthReport:Response";
function sendMessageToJava(message) {
return Services.androidBridge.handleGeckoMessage(JSON.stringify(message));
}
// about:healthreport prefs are stored in Firefox's default Android
// SharedPreferences.
let sharedPrefs = new SharedPreferences();

View File

@@ -27,6 +27,9 @@ Cu.import("resource://gre/modules/accessibility/AccessFu.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "sendMessageToJava",
"resource://gre/modules/Messaging.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "DebuggerServer",
"resource://gre/modules/devtools/dbg-server.jsm");
@@ -169,10 +172,6 @@ function dump(a) {
Services.console.logStringMessage(a);
}
function sendMessageToJava(aMessage) {
return Services.androidBridge.handleGeckoMessage(JSON.stringify(aMessage));
}
function doChangeMaxLineBoxWidth(aWidth) {
gReflowPending = null;
let webNav = BrowserApp.selectedTab.window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation);
@@ -7138,18 +7137,20 @@ var WebappsUI = {
doInstall: function doInstall(aData) {
let jsonManifest = aData.isPackage ? aData.app.updateManifest : aData.app.manifest;
let manifest = new ManifestHelper(jsonManifest, aData.app.origin);
let showPrompt = true;
if (!showPrompt || Services.prompt.confirm(null, Strings.browser.GetStringFromName("webapps.installTitle"), manifest.name + "\n" + aData.app.origin)) {
if (Services.prompt.confirm(null, Strings.browser.GetStringFromName("webapps.installTitle"), manifest.name + "\n" + aData.app.origin)) {
// Get a profile for the app to be installed in. We'll download everything before creating the icons.
let origin = aData.app.origin;
let profilePath = sendMessageToJava({
type: "Webapps:Preinstall",
name: manifest.name,
manifestURL: aData.app.manifestURL,
origin: origin
});
if (profilePath) {
sendMessageToJava({
type: "Webapps:Preinstall",
name: manifest.name,
manifestURL: aData.app.manifestURL,
origin: origin
}, (data) => {
let profilePath = JSON.parse(data).profile;
if (!profilePath)
return;
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
file.initWithPath(profilePath);
@@ -8032,12 +8033,12 @@ var ExternalApps = {
},
updatePageAction: function updatePageAction(uri) {
let apps = HelperApps.getAppsForUri(uri);
if (apps.length > 0)
this._setUriForPageAction(uri, apps);
else
this._removePageAction();
HelperApps.getAppsForUri(uri, { filterHttp: true }, (apps) => {
if (apps.length > 0)
this._setUriForPageAction(uri, apps);
else
this._removePageAction();
});
},
_setUriForPageAction: function setUriForPageAction(uri, apps) {

View File

@@ -8,10 +8,7 @@ const Cc = Components.classes;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
function sendMessageToJava(aMessage) {
return Services.androidBridge.handleGeckoMessage(JSON.stringify(aMessage));
}
Cu.import("resource://gre/modules/Messaging.jsm");
function ContentDispatchChooser() {}

View File

@@ -65,11 +65,6 @@ PaymentUI.prototype = {
return this.bundle = Services.strings.createBundle("chrome://browser/locale/payments.properties");
},
sendMessageToJava: function(aMsg) {
let data = Services.androidBridge.handleGeckoMessage(JSON.stringify(aMsg));
return JSON.parse(data);
},
confirmPaymentRequest: function confirmPaymentRequest(aRequestId,
aRequests,
aSuccessCb,

View File

@@ -805,11 +805,6 @@ let PromptUtils = {
return hostname;
},
sendMessageToJava: function(aMsg) {
let data = Services.androidBridge.handleGeckoMessage(JSON.stringify(aMsg));
return JSON.parse(data);
},
fireDialogEvent: function(aDomWin, aEventName) {
// accessing the document object can throw if this window no longer exists. See bug 789888.
try {

View File

@@ -17,9 +17,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "sendMessageToJava", "resource://gre/modules/Messaging.jsm");
function dump(a) {
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(a);
Services.console.logStringMessage(a);
}
// -----------------------------------------------------------------------
@@ -63,11 +64,6 @@ SessionStore.prototype = {
OS.File.remove(this._sessionFileBackup.path);
},
_sendMessageToJava: function (aMsg) {
let data = Services.androidBridge.handleGeckoMessage(JSON.stringify(aMsg));
return JSON.parse(data);
},
observe: function ss_observe(aSubject, aTopic, aData) {
let self = this;
let observerService = Services.obs;
@@ -132,7 +128,7 @@ SessionStore.prototype = {
}
// Let Java know we're done restoring tabs so tabs added after this can be animated
this._sendMessageToJava({
sendMessageToJava({
type: "Session:RestoreEnd"
});
}.bind(this)
@@ -415,7 +411,7 @@ SessionStore.prototype = {
// If we have private data, send it to Java; otherwise, send null to
// indicate that there is no private data
this._sendMessageToJava({
sendMessageToJava({
type: "PrivateBrowsing:Data",
session: (privateData.windows[0].tabs.length > 0) ? JSON.stringify(privateData) : null
});

View File

@@ -8,6 +8,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Prompt.jsm");
Cu.import("resource://gre/modules/Messaging.jsm");
XPCOMUtils.defineLazyGetter(this, "ContentAreaUtils", function() {
let ContentAreaUtils = {};
@@ -70,29 +71,43 @@ var HelperApps = {
return results;
},
getAppsForUri: function getAppsForUri(uri, flags = { filterHttp: true }) {
getAppsForUri: function getAppsForUri(uri, flags = { filterHttp: true }, callback) {
flags.filterHttp = "filterHttp" in flags ? flags.filterHttp : true;
// Query for apps that can/can't handle the mimetype
let msg = this._getMessage("Intent:GetHandlers", uri, flags);
let data = this._sendMessage(msg);
if (!data)
return [];
let parseData = (d) => {
let apps = []
let apps = this._parseApps(data.apps);
if (!d)
return apps;
if (flags.filterHttp) {
apps = apps.filter(function(app) {
return app.name && !this.defaultHttpHandlers[app.name];
}, this);
apps = this._parseApps(d.apps);
if (flags.filterHttp) {
apps = apps.filter(function(app) {
return app.name && !this.defaultHttpHandlers[app.name];
}, this);
}
return apps;
};
if (!callback) {
let data = this._sendMessageSync(msg);
if (!data)
return [];
return parseData(JSON.parse(data));
} else {
sendMessageToJava(msg, function(data) {
callback(parseData(JSON.parse(data)));
});
}
return apps;
},
launchUri: function launchUri(uri) {
let msg = this._getMessage("Intent:Open", uri);
this._sendMessage(msg);
sendMessageToJava(msg);
},
_parseApps: function _parseApps(appInfo) {
@@ -132,11 +147,19 @@ var HelperApps = {
className: app.activityName
});
this._sendMessage(msg);
sendMessageToJava(msg);
},
_sendMessage: function(msg) {
let res = Services.androidBridge.handleGeckoMessage(JSON.stringify(msg));
return JSON.parse(res);
_sendMessageSync: function(msg) {
let res = null;
sendMessageToJava(msg, function(data) {
res = data;
});
let thread = Services.tm.currentThread;
while (res == null)
thread.processNextEvent(true);
return res;
},
};

View File

@@ -11,6 +11,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/SharedPreferences.jsm");
Cu.import("resource://gre/modules/Messaging.jsm");
// See bug 915424
function resolveGeckoURI(aURI) {
@@ -27,10 +28,6 @@ function resolveGeckoURI(aURI) {
return aURI;
}
function sendMessageToJava(message) {
return Services.androidBridge.handleGeckoMessage(JSON.stringify(message));
}
function BannerMessage(options) {
let uuidgen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
this.id = uuidgen.generateUUID().toString();

View File

@@ -0,0 +1,41 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
this.EXPORTED_SYMBOLS = ["sendMessageToJava"];
XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
"@mozilla.org/uuid-generator;1",
"nsIUUIDGenerator");
function sendMessageToJava(aMessage, aCallback) {
if (aCallback) {
let id = uuidgen.generateUUID().toString();
let obs = {
observe: function(aSubject, aTopic, aData) {
let data = JSON.parse(aData);
if (data.__guid__ != id) {
return;
}
Services.obs.removeObserver(obs, aMessage.type + ":Return", false);
Services.obs.removeObserver(obs, aMessage.type + ":Error", false);
aCallback(aTopic == aMessage.type + ":Return" ? aData : null,
aTopic == aMessage.type + ":Error" ? aData : null)
}
}
aMessage.__guid__ = id;
Services.obs.addObserver(obs, aMessage.type + ":Return", false);
Services.obs.addObserver(obs, aMessage.type + ":Error", false);
}
return Services.androidBridge.handleGeckoMessage(JSON.stringify(aMessage));
}

View File

@@ -10,10 +10,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
// For adding observers.
Cu.import("resource://gre/modules/Services.jsm");
function sendMessageToJava(message) {
return Services.androidBridge.handleGeckoMessage(JSON.stringify(message));
}
Cu.import("resource://gre/modules/Messaging.jsm");
let _callbackId = 1;

View File

@@ -7,6 +7,7 @@ let Cc = Components.classes;
let Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/Messaging.jsm");
this.EXPORTED_SYMBOLS = ["Prompt"];
@@ -36,8 +37,6 @@ function Prompt(aOptions) {
this.msg.hint = aOptions.hint;
let idService = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
this.guid = idService.generateUUID().toString();
this.msg.guid = this.guid;
}
Prompt.prototype = {
@@ -152,24 +151,20 @@ Prompt.prototype = {
show: function(callback) {
this.callback = callback;
log("Sending message");
Services.obs.addObserver(this, "Prompt:Reply", false);
Services.obs.addObserver(this, "Prompt:Return", false);
this._innerShow();
},
_innerShow: function() {
Services.androidBridge.handleGeckoMessage(JSON.stringify(this.msg));
},
sendMessageToJava(this.msg, (aData) => {
log("observe " + aData);
let data = JSON.parse(aData);
observe: function(aSubject, aTopic, aData) {
log("observe " + aData);
let data = JSON.parse(aData);
if (data.guid != this.guid)
return;
Services.obs.removeObserver(this, "Prompt:Return", false);
Services.obs.removeObserver(this, "Prompt:Reply", false);
if (this.callback)
this.callback(data);
if (this.callback)
this.callback(data);
});
},
_setListItems: function(aItems) {

View File

@@ -11,15 +11,12 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/LoadContextInfo.jsm");
Cu.import("resource://gre/modules/FormHistory.jsm");
Cu.import("resource://gre/modules/Messaging.jsm");
function dump(a) {
Services.console.logStringMessage(a);
}
function sendMessageToJava(aMessage) {
return Services.androidBridge.handleGeckoMessage(JSON.stringify(aMessage));
}
this.EXPORTED_SYMBOLS = ["Sanitizer"];
let downloads = {

View File

@@ -11,10 +11,7 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
// For adding observers.
Cu.import("resource://gre/modules/Services.jsm");
function sendMessageToJava(message) {
return Services.androidBridge.handleGeckoMessage(JSON.stringify(message));
}
Cu.import("resource://gre/modules/Messaging.jsm");
/**
* Create an interface to an Android SharedPreferences branch.
@@ -62,13 +59,21 @@ SharedPreferences.prototype = Object.freeze({
this._setOne(prefName, value, "int");
},
_get: function _get(prefs) {
let values = sendMessageToJava({
_get: function _get(prefs, callback) {
let result = null;
sendMessageToJava({
type: "SharedPreferences:Get",
preferences: prefs,
branch: this._branch,
}, (data) => {
result = JSON.parse(data).values;
});
return JSON.parse(values);
let thread = Services.tm.currentThread;
while (result == null)
thread.processNextEvent(true);
return result;
},
_getOne: function _getOne(prefName, type) {

View File

@@ -284,10 +284,9 @@ this.WebappManager = {
}
// Map APK names to APK versions.
let apkNameToVersion = JSON.parse(sendMessageToJava({
type: "Webapps:GetApkVersions",
packageNames: installedApps.map(app => app.packageName).filter(packageName => !!packageName)
}));
let apkNameToVersion = yield this._getAPKVersions(installedApps.map(app =>
app.packageName).filter(packageName => !!packageName)
);
// Map manifest URLs to APK versions, which is what the service needs
// in order to tell us which apps are outdated; and also map them to app
@@ -336,6 +335,17 @@ this.WebappManager = {
}
}).bind(this)); },
_getAPKVersions: function(packageNames) {
let deferred = Promise.defer();
sendMessageToJava({
type: "Webapps:GetApkVersions",
packageNames: packageNames
}, data => deferred.resolve(JSON.parse(data).versions));
return deferred.promise;
},
_getInstalledApps: function() {
let deferred = Promise.defer();
DOMApplicationRegistry.getAll(apps => deferred.resolve(apps));

View File

@@ -11,6 +11,7 @@ EXTRA_JS_MODULES += [
'HomeProvider.jsm',
'JNI.jsm',
'LightweightThemeConsumer.jsm',
'Messaging.jsm',
'Notifications.jsm',
'OrderedBroadcast.jsm',
'Prompt.jsm',

View File

@@ -305,25 +305,6 @@ Java_org_mozilla_gecko_GeckoAppShell_cameraCallbackBridge(JNIEnv * arg0, jclass
#ifdef JNI_STUBS
typedef void (*Java_org_mozilla_gecko_GeckoAppShell_notifyFilePickerResult_t)(JNIEnv *, jclass, jstring, jlong);
static Java_org_mozilla_gecko_GeckoAppShell_notifyFilePickerResult_t f_Java_org_mozilla_gecko_GeckoAppShell_notifyFilePickerResult;
extern "C" NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_notifyFilePickerResult(JNIEnv * arg0, jclass arg1, jstring arg2, jlong arg3) {
if (!f_Java_org_mozilla_gecko_GeckoAppShell_notifyFilePickerResult) {
arg0->ThrowNew(arg0->FindClass("java/lang/UnsupportedOperationException"),
"JNI Function called before it was loaded");
return ;
}
f_Java_org_mozilla_gecko_GeckoAppShell_notifyFilePickerResult(arg0, arg1, arg2, arg3);
}
#endif
#ifdef JNI_BINDINGS
xul_dlsym("Java_org_mozilla_gecko_GeckoAppShell_notifyFilePickerResult", &f_Java_org_mozilla_gecko_GeckoAppShell_notifyFilePickerResult);
#endif
#ifdef JNI_STUBS
typedef jdouble (*Java_org_mozilla_gecko_GeckoJavaSampler_getProfilerTime_t)(JNIEnv *, jclass);
static Java_org_mozilla_gecko_GeckoJavaSampler_getProfilerTime_t f_Java_org_mozilla_gecko_GeckoJavaSampler_getProfilerTime;
extern "C" NS_EXPORT jdouble JNICALL

View File

@@ -42,8 +42,6 @@ using namespace mozilla;
using namespace mozilla::widget::android;
using namespace mozilla::gfx;
NS_IMPL_ISUPPORTS0(nsFilePickerCallback)
StaticRefPtr<AndroidBridge> AndroidBridge::sBridge;
static unsigned sJavaEnvThreadIndex = 0;
static jobject sGlobalContext = nullptr;
@@ -486,41 +484,6 @@ AndroidBridge::GetScreenDepth()
return sDepth;
}
void
AndroidBridge::ShowFilePickerForExtensions(nsAString& aFilePath, const nsAString& aExtensions)
{
JNIEnv *env = GetJNIEnv();
AutoLocalJNIFrame jniFrame(env, 1);
jstring jstr = GeckoAppShell::ShowFilePickerForExtensionsWrapper(aExtensions);
if (jstr == nullptr) {
return;
}
aFilePath.Assign(nsJNIString(jstr, env));
}
void
AndroidBridge::ShowFilePickerForMimeType(nsAString& aFilePath, const nsAString& aMimeType)
{
JNIEnv *env = GetJNIEnv();
AutoLocalJNIFrame jniFrame(env, 1);
jstring jstr = GeckoAppShell::ShowFilePickerForMimeTypeWrapper(aMimeType);
if (jstr == nullptr) {
return;
}
aFilePath.Assign(nsJNIString(jstr, env));
}
void
AndroidBridge::ShowFilePickerAsync(const nsAString& aMimeType, nsFilePickerCallback* callback)
{
callback->AddRef();
GeckoAppShell::ShowFilePickerAsyncWrapper(aMimeType, (int64_t) callback);
}
void
AndroidBridge::Vibrate(const nsTArray<uint32_t>& aPattern)
{
@@ -999,21 +962,14 @@ AndroidBridge::GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInf
}
void
AndroidBridge::HandleGeckoMessage(const nsAString &aMessage, nsAString &aRet)
AndroidBridge::HandleGeckoMessage(const nsAString &aMessage)
{
ALOG_BRIDGE("%s", __PRETTY_FUNCTION__);
JNIEnv *env = GetJNIEnv();
AutoLocalJNIFrame jniFrame(env, 1);
jstring returnMessage = GeckoAppShell::HandleGeckoMessageWrapper(aMessage);
if (!returnMessage)
return;
nsJNIString jniStr(returnMessage, env);
aRet.Assign(jniStr);
ALOG_BRIDGE("leaving %s", __PRETTY_FUNCTION__);
GeckoAppShell::HandleGeckoMessageWrapper(aMessage);
}
nsresult
@@ -1534,9 +1490,9 @@ nsAndroidBridge::~nsAndroidBridge()
}
/* void handleGeckoEvent (in AString message); */
NS_IMETHODIMP nsAndroidBridge::HandleGeckoMessage(const nsAString & message, nsAString &aRet)
NS_IMETHODIMP nsAndroidBridge::HandleGeckoMessage(const nsAString & message)
{
AndroidBridge::Bridge()->HandleGeckoMessage(message, aRet);
AndroidBridge::Bridge()->HandleGeckoMessage(message);
return NS_OK;
}

View File

@@ -282,7 +282,7 @@ public:
bool LockWindow(void *window, unsigned char **bits, int *width, int *height, int *format, int *stride);
bool UnlockWindow(void *window);
void HandleGeckoMessage(const nsAString& message, nsAString &aRet);
void HandleGeckoMessage(const nsAString& message);
bool InitCamera(const nsCString& contentType, uint32_t camera, uint32_t *width, uint32_t *height, uint32_t *fps);

View File

@@ -81,9 +81,6 @@ jmethodID GeckoAppShell::jSetFullScreen = 0;
jmethodID GeckoAppShell::jSetKeepScreenOn = 0;
jmethodID GeckoAppShell::jSetURITitle = 0;
jmethodID GeckoAppShell::jShowAlertNotificationWrapper = 0;
jmethodID GeckoAppShell::jShowFilePickerAsyncWrapper = 0;
jmethodID GeckoAppShell::jShowFilePickerForExtensionsWrapper = 0;
jmethodID GeckoAppShell::jShowFilePickerForMimeTypeWrapper = 0;
jmethodID GeckoAppShell::jShowInputMethodPicker = 0;
jmethodID GeckoAppShell::jUnlockProfile = 0;
jmethodID GeckoAppShell::jUnlockScreenOrientation = 0;
@@ -132,7 +129,7 @@ void GeckoAppShell::InitStubs(JNIEnv *jEnv) {
jGetScreenOrientationWrapper = getStaticMethod("getScreenOrientation", "()S");
jGetShowPasswordSetting = getStaticMethod("getShowPasswordSetting", "()Z");
jGetSystemColoursWrapper = getStaticMethod("getSystemColors", "()[I");
jHandleGeckoMessageWrapper = getStaticMethod("handleGeckoMessage", "(Ljava/lang/String;)Ljava/lang/String;");
jHandleGeckoMessageWrapper = getStaticMethod("handleGeckoMessage", "(Ljava/lang/String;)V");
jHandleUncaughtException = getStaticMethod("handleUncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
jHideProgressDialog = getStaticMethod("hideProgressDialog", "()V");
jInitCameraWrapper = getStaticMethod("initCamera", "(Ljava/lang/String;III)[I");
@@ -163,9 +160,6 @@ void GeckoAppShell::InitStubs(JNIEnv *jEnv) {
jSetKeepScreenOn = getStaticMethod("setKeepScreenOn", "(Z)V");
jSetURITitle = getStaticMethod("setUriTitle", "(Ljava/lang/String;Ljava/lang/String;)V");
jShowAlertNotificationWrapper = getStaticMethod("showAlertNotification", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
jShowFilePickerAsyncWrapper = getStaticMethod("showFilePickerAsync", "(Ljava/lang/String;J)V");
jShowFilePickerForExtensionsWrapper = getStaticMethod("showFilePickerForExtensions", "(Ljava/lang/String;)Ljava/lang/String;");
jShowFilePickerForMimeTypeWrapper = getStaticMethod("showFilePickerForMimeType", "(Ljava/lang/String;)Ljava/lang/String;");
jShowInputMethodPicker = getStaticMethod("showInputMethodPicker", "()V");
jUnlockProfile = getStaticMethod("unlockProfile", "()Z");
jUnlockScreenOrientation = getStaticMethod("unlockScreenOrientation", "()V");
@@ -703,19 +697,18 @@ jintArray GeckoAppShell::GetSystemColoursWrapper() {
return ret;
}
jstring GeckoAppShell::HandleGeckoMessageWrapper(const nsAString& a0) {
void GeckoAppShell::HandleGeckoMessageWrapper(const nsAString& a0) {
JNIEnv *env = AndroidBridge::GetJNIEnv();
if (env->PushLocalFrame(2) != 0) {
if (env->PushLocalFrame(1) != 0) {
AndroidBridge::HandleUncaughtException(env);
MOZ_ASSUME_UNREACHABLE("Exception should have caused crash.");
}
jstring j0 = AndroidBridge::NewJavaString(env, a0);
jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jHandleGeckoMessageWrapper, j0);
env->CallStaticVoidMethod(mGeckoAppShellClass, jHandleGeckoMessageWrapper, j0);
AndroidBridge::HandleUncaughtException(env);
jstring ret = static_cast<jstring>(env->PopLocalFrame(temp));
return ret;
env->PopLocalFrame(nullptr);
}
void GeckoAppShell::HandleUncaughtException(jobject a0, jthrowable a1) {
@@ -1136,50 +1129,6 @@ void GeckoAppShell::ShowAlertNotificationWrapper(const nsAString& a0, const nsAS
env->PopLocalFrame(nullptr);
}
void GeckoAppShell::ShowFilePickerAsyncWrapper(const nsAString& a0, int64_t a1) {
JNIEnv *env = AndroidBridge::GetJNIEnv();
if (env->PushLocalFrame(1) != 0) {
AndroidBridge::HandleUncaughtException(env);
MOZ_ASSUME_UNREACHABLE("Exception should have caused crash.");
}
jstring j0 = AndroidBridge::NewJavaString(env, a0);
env->CallStaticVoidMethod(mGeckoAppShellClass, jShowFilePickerAsyncWrapper, j0, a1);
AndroidBridge::HandleUncaughtException(env);
env->PopLocalFrame(nullptr);
}
jstring GeckoAppShell::ShowFilePickerForExtensionsWrapper(const nsAString& a0) {
JNIEnv *env = AndroidBridge::GetJNIEnv();
if (env->PushLocalFrame(2) != 0) {
AndroidBridge::HandleUncaughtException(env);
MOZ_ASSUME_UNREACHABLE("Exception should have caused crash.");
}
jstring j0 = AndroidBridge::NewJavaString(env, a0);
jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jShowFilePickerForExtensionsWrapper, j0);
AndroidBridge::HandleUncaughtException(env);
jstring ret = static_cast<jstring>(env->PopLocalFrame(temp));
return ret;
}
jstring GeckoAppShell::ShowFilePickerForMimeTypeWrapper(const nsAString& a0) {
JNIEnv *env = AndroidBridge::GetJNIEnv();
if (env->PushLocalFrame(2) != 0) {
AndroidBridge::HandleUncaughtException(env);
MOZ_ASSUME_UNREACHABLE("Exception should have caused crash.");
}
jstring j0 = AndroidBridge::NewJavaString(env, a0);
jobject temp = env->CallStaticObjectMethod(mGeckoAppShellClass, jShowFilePickerForMimeTypeWrapper, j0);
AndroidBridge::HandleUncaughtException(env);
jstring ret = static_cast<jstring>(env->PopLocalFrame(temp));
return ret;
}
void GeckoAppShell::ShowInputMethodPicker() {
JNIEnv *env = AndroidBridge::GetJNIEnv();
if (env->PushLocalFrame(0) != 0) {

View File

@@ -57,7 +57,7 @@ public:
static int16_t GetScreenOrientationWrapper();
static bool GetShowPasswordSetting();
static jintArray GetSystemColoursWrapper();
static jstring HandleGeckoMessageWrapper(const nsAString& a0);
static void HandleGeckoMessageWrapper(const nsAString& a0);
static void HandleUncaughtException(jobject a0, jthrowable a1);
static void HideProgressDialog();
static jintArray InitCameraWrapper(const nsAString& a0, int32_t a1, int32_t a2, int32_t a3);
@@ -88,9 +88,6 @@ public:
static void SetKeepScreenOn(bool a0);
static void SetURITitle(const nsAString& a0, const nsAString& a1);
static void ShowAlertNotificationWrapper(const nsAString& a0, const nsAString& a1, const nsAString& a2, const nsAString& a3, const nsAString& a4);
static void ShowFilePickerAsyncWrapper(const nsAString& a0, int64_t a1);
static jstring ShowFilePickerForExtensionsWrapper(const nsAString& a0);
static jstring ShowFilePickerForMimeTypeWrapper(const nsAString& a0);
static void ShowInputMethodPicker();
static bool UnlockProfile();
static void UnlockScreenOrientation();
@@ -169,9 +166,6 @@ protected:
static jmethodID jSetKeepScreenOn;
static jmethodID jSetURITitle;
static jmethodID jShowAlertNotificationWrapper;
static jmethodID jShowFilePickerAsyncWrapper;
static jmethodID jShowFilePickerForExtensionsWrapper;
static jmethodID jShowFilePickerForMimeTypeWrapper;
static jmethodID jShowInputMethodPicker;
static jmethodID jUnlockProfile;
static jmethodID jUnlockScreenOrientation;

View File

@@ -63,10 +63,10 @@ interface nsIAndroidDisplayport : nsISupports {
attribute float resolution;
};
[scriptable, uuid(5aa0cfa5-377c-4f5e-8dcf-59ebd9482d65)]
[scriptable, uuid(2af84552-4f74-480d-b637-ce2bcd7148fc)]
interface nsIAndroidBridge : nsISupports
{
AString handleGeckoMessage(in AString message);
void handleGeckoMessage(in AString message);
attribute nsIAndroidBrowserApp browserApp;
nsIAndroidDisplayport getDisplayPort(in boolean aPageSizeUpdate, in boolean isBrowserContentDisplayed, in int32_t tabId, in nsIAndroidViewport metrics);
void contentDocumentChanged();