bug 882196 - Android crash in nsXPCWrappedJS::AddRef, remove nsAppShell::NotifyObservers r=kats

This commit is contained in:
Brad Lassey 2013-06-17 17:09:09 -04:00
parent bf0cb53536
commit c08786522e
10 changed files with 64 additions and 102 deletions

View File

@ -171,12 +171,10 @@ public class GeckoAppShell
// public static native void setSurfaceView(GeckoSurfaceView sv);
public static native void setLayerClient(GeckoLayerClient client);
public static native void onResume();
public static native void onLowMemory();
public static void callObserver(String observerKey, String topic, String data) {
sendEventToGecko(GeckoEvent.createCallObserverEvent(observerKey, topic, data));
}
public static native void removeObserver(String observerKey);
public static native void onChangeNetworkLinkStatus(String status);
public static native Message getNextMessageFromQueue(MessageQueue queue);
public static native void onSurfaceTextureFrameAvailable(Object surfaceTexture, int id);

View File

@ -76,7 +76,7 @@ public class GeckoConnectivityReceiver extends BroadcastReceiver {
}
if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) {
GeckoAppShell.onChangeNetworkLinkStatus(status);
GeckoAppShell.sendEventToGecko(GeckoEvent.createNetworkLinkChangeEvent(status));
}
}
}

View File

@ -63,7 +63,9 @@ public class GeckoEvent {
COMPOSITOR_RESUME(30),
NATIVE_GESTURE_EVENT(31),
IME_KEY_EVENT(32),
CALL_OBSERVER(33);
CALL_OBSERVER(33),
LOW_MEMORY(34),
NETWORK_LINK_CHANGE(35);
public final int value;
@ -667,6 +669,18 @@ public class GeckoEvent {
return event;
}
public static GeckoEvent createLowMemoryEvent(int level) {
GeckoEvent event = new GeckoEvent(NativeGeckoEvent.LOW_MEMORY);
event.mMetaState = level;
return event;
}
public static GeckoEvent createNetworkLinkChangeEvent(String status) {
GeckoEvent event = new GeckoEvent(NativeGeckoEvent.NETWORK_LINK_CHANGE);
event.mCharacters = status;
return event;
}
public void setAckNeeded(boolean ackNeeded) {
mAckNeeded = ackNeeded;
}

View File

@ -39,6 +39,7 @@ class MemoryMonitor extends BroadcastReceiver {
private static final String ACTION_MEMORY_DUMP = "org.mozilla.gecko.MEMORY_DUMP";
private static final String ACTION_FORCE_PRESSURE = "org.mozilla.gecko.FORCE_MEMORY_PRESSURE";
// Memory pressue levels, keep in sync with those in AndroidJavaWrappers.h
private static final int MEMORY_PRESSURE_NONE = 0;
private static final int MEMORY_PRESSURE_CLEANUP = 1;
private static final int MEMORY_PRESSURE_LOW = 2;
@ -148,8 +149,9 @@ class MemoryMonitor extends BroadcastReceiver {
// TODO hook in memory-reduction stuff for different levels here
if (level >= MEMORY_PRESSURE_MEDIUM) {
//Only send medium or higher events because that's all that is used right now
if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) {
GeckoAppShell.onLowMemory();
GeckoAppShell.sendEventToGecko(GeckoEvent.createLowMemoryEvent(level));
}
Favicons.getInstance().clearMemCache();

View File

@ -58,25 +58,6 @@ Java_org_mozilla_gecko_GeckoAppShell_onResume(JNIEnv * arg0, jclass arg1) {
#ifdef JNI_STUBS
typedef void (*Java_org_mozilla_gecko_GeckoAppShell_onLowMemory_t)(JNIEnv *, jclass);
static Java_org_mozilla_gecko_GeckoAppShell_onLowMemory_t f_Java_org_mozilla_gecko_GeckoAppShell_onLowMemory;
extern "C" NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_onLowMemory(JNIEnv * arg0, jclass arg1) {
if (!f_Java_org_mozilla_gecko_GeckoAppShell_onLowMemory) {
arg0->ThrowNew(arg0->FindClass("java/lang/UnsupportedOperationException"),
"JNI Function called before it was loaded");
return ;
}
f_Java_org_mozilla_gecko_GeckoAppShell_onLowMemory(arg0, arg1);
}
#endif
#ifdef JNI_BINDINGS
xul_dlsym("Java_org_mozilla_gecko_GeckoAppShell_onLowMemory", &f_Java_org_mozilla_gecko_GeckoAppShell_onLowMemory);
#endif
#ifdef JNI_STUBS
typedef void (*Java_org_mozilla_gecko_GeckoAppShell_removeObserver_t)(JNIEnv *, jclass, jstring);
static Java_org_mozilla_gecko_GeckoAppShell_removeObserver_t f_Java_org_mozilla_gecko_GeckoAppShell_removeObserver;
extern "C" NS_EXPORT void JNICALL
@ -96,25 +77,6 @@ Java_org_mozilla_gecko_GeckoAppShell_removeObserver(JNIEnv * arg0, jclass arg1,
#ifdef JNI_STUBS
typedef void (*Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus_t)(JNIEnv *, jclass, jstring);
static Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus_t f_Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus;
extern "C" NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus(JNIEnv * arg0, jclass arg1, jstring arg2) {
if (!f_Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus) {
arg0->ThrowNew(arg0->FindClass("java/lang/UnsupportedOperationException"),
"JNI Function called before it was loaded");
return ;
}
f_Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus(arg0, arg1, arg2);
}
#endif
#ifdef JNI_BINDINGS
xul_dlsym("Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus", &f_Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus);
#endif
#ifdef JNI_STUBS
typedef jobject (*Java_org_mozilla_gecko_GeckoAppShell_getNextMessageFromQueue_t)(JNIEnv *, jclass, jobject);
static Java_org_mozilla_gecko_GeckoAppShell_getNextMessageFromQueue_t f_Java_org_mozilla_gecko_GeckoAppShell_getNextMessageFromQueue;
extern "C" NS_EXPORT jobject JNICALL

View File

@ -22,7 +22,6 @@
#include <android/log.h>
#include "nsIObserverService.h"
#include "mozilla/Services.h"
#include "nsINetworkLinkService.h"
#ifdef MOZ_CRASHREPORTER
#include "nsICrashReporter.h"
@ -84,16 +83,6 @@ Java_org_mozilla_gecko_GeckoAppShell_setLayerClient(JNIEnv *jenv, jclass, jobjec
AndroidBridge::Bridge()->SetLayerClient(jenv, obj);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_onLowMemory(JNIEnv *jenv, jclass jc)
{
if (nsAppShell::gAppShell) {
nsAppShell::gAppShell->NotifyObservers(nullptr,
"memory-pressure",
NS_LITERAL_STRING("low-memory").get());
}
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_onResume(JNIEnv *jenv, jclass jc)
{
@ -115,19 +104,6 @@ Java_org_mozilla_gecko_GeckoAppShell_removeObserver(JNIEnv *jenv, jclass, jstrin
nsAppShell::gAppShell->RemoveObserver(sObserverKey);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_onChangeNetworkLinkStatus(JNIEnv *jenv, jclass, jstring jStatus)
{
if (!nsAppShell::gAppShell)
return;
nsJNIString sStatus(jStatus, jenv);
nsAppShell::gAppShell->NotifyObservers(nullptr,
NS_NETWORK_LINK_TOPIC,
sStatus.get());
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_reportJavaCrash(JNIEnv *jenv, jclass, jstring jStackTrace)
{

View File

@ -690,6 +690,16 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
break;
}
case LOW_MEMORY: {
mMetaState = jenv->GetIntField(jobj, jMetaStateField);
break;
}
case NETWORK_LINK_CHANGE: {
ReadCharactersField(jenv);
break;
}
default:
break;
}

View File

@ -707,9 +707,20 @@ public:
NATIVE_GESTURE_EVENT = 31,
IME_KEY_EVENT = 32,
CALL_OBSERVER = 33,
LOW_MEMORY = 34,
NETWORK_LINK_CHANGE = 35,
dummy_java_enum_list_end
};
enum {
// Memory pressue levels, keep in sync with those in MemoryMonitor.java
MEMORY_PRESSURE_NONE = 0,
MEMORY_PRESSURE_CLEANUP = 1,
MEMORY_PRESSURE_LOW = 2,
MEMORY_PRESSURE_MEDIUM = 3,
MEMORY_PRESSURE_HIGH = 4
};
enum {
// Internal Gecko events
IME_FLUSH_CHANGES = -2,

View File

@ -25,6 +25,7 @@
#include "nsIDOMWakeLockListener.h"
#include "nsIPowerManagerService.h"
#include "nsFrameManager.h"
#include "nsINetworkLinkService.h"
#include "mozilla/Services.h"
#include "mozilla/unused.h"
@ -522,6 +523,29 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
CallObserver(curEvent->Characters(), curEvent->CharactersExtra(), curEvent->Data());
break;
case AndroidGeckoEvent::LOW_MEMORY:
// TODO hook in memory-reduction stuff for different levels here
if (curEvent->MetaState() >= AndroidGeckoEvent::MEMORY_PRESSURE_MEDIUM) {
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (os) {
os->NotifyObservers(nullptr,
"memory-pressure",
NS_LITERAL_STRING("low-memory").get());
}
}
break;
case AndroidGeckoEvent::NETWORK_LINK_CHANGE:
{
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (os) {
os->NotifyObservers(nullptr,
NS_NETWORK_LINK_TOPIC,
nsString(curEvent->Characters()).get());
}
break;
}
case AndroidGeckoEvent::NOOP:
break;
@ -736,40 +760,6 @@ nsAppShell::RemoveObserver(const nsAString &aObserverKey)
mObserversHash.Remove(aObserverKey);
}
// NotifyObservers support. NotifyObservers only works on main thread.
class NotifyObserversCaller : public nsRunnable {
public:
NotifyObserversCaller(nsISupports *aSupports,
const char *aTopic, const PRUnichar *aData) :
mSupports(aSupports), mTopic(aTopic), mData(aData) {
}
NS_IMETHOD Run() {
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (os)
os->NotifyObservers(mSupports, mTopic.get(), mData.get());
return NS_OK;
}
private:
nsCOMPtr<nsISupports> mSupports;
nsCString mTopic;
nsString mData;
};
void
nsAppShell::NotifyObservers(nsISupports *aSupports,
const char *aTopic,
const PRUnichar *aData)
{
// This isn't main thread, so post this to main thread
nsCOMPtr<nsIRunnable> caller =
new NotifyObserversCaller(aSupports, aTopic, aData);
NS_DispatchToMainThread(caller);
}
// Used by IPC code
namespace mozilla {

View File

@ -49,7 +49,6 @@ public:
nsresult AddObserver(const nsAString &aObserverKey, nsIObserver *aObserver);
void CallObserver(const nsAString &aObserverKey, const nsAString &aTopic, const nsAString &aData);
void RemoveObserver(const nsAString &aObserverKey);
void NotifyObservers(nsISupports *aSupports, const char *aTopic, const PRUnichar *aData);
void ResendLastResizeEvent(nsWindow* aDest);
void SetBrowserApp(nsIAndroidBrowserApp* aBrowserApp) {