Bug 1288821 - Convert callObserver/removeObserver to native method; r=snorp

Combine the callObserver and removeObserver methods used for notifying
alert listeners into the native method
GeckoAppShell.notifyAlertListener. Keep track of the listener and the
alert cookie on the native side so that we don't need
GeckoAppShell.ALERT_COOKIES anymore.
This commit is contained in:
Jim Chen 2016-08-04 09:17:54 -04:00
parent 535fa2c33f
commit 52c109b436
4 changed files with 70 additions and 16 deletions

View File

@ -179,8 +179,6 @@ public class GeckoAppShell
return CRASH_HANDLER;
}
private static final Map<String, String> ALERT_COOKIES = new ConcurrentHashMap<String, String>();
private static volatile boolean locationHighAccuracyEnabled;
// Accessed by NotificationHelper. This should be encapsulated.
@ -1028,6 +1026,9 @@ public class GeckoAppShell
PendingIntent.FLAG_UPDATE_CURRENT);
}
@WrapForJNI
private static native void notifyAlertListener(String name, String topic);
@WrapForJNI
public static void showAlertNotification(String imageUrl, String alertTitle, String alertText,
String alertCookie, String alertName, String host,
@ -1042,8 +1043,7 @@ public class GeckoAppShell
notificationID, "persistent-notification-close", persistentData);
} else {
ALERT_COOKIES.put(alertName, alertCookie);
callObserver(alertName, "alertshow", alertCookie);
notifyAlertListener(alertName, "alertshow");
// The intent to launch when the user clicks the expanded notification
final Intent notificationIntent = new Intent(GeckoApp.ACTION_ALERT_CALLBACK);
@ -1072,13 +1072,7 @@ public class GeckoAppShell
@WrapForJNI
public static void closeNotification(String alertName) {
final String alertCookie = ALERT_COOKIES.get(alertName);
if (alertCookie != null) {
callObserver(alertName, "alertfinished", alertCookie);
ALERT_COOKIES.remove(alertName);
}
removeObserver(alertName);
notifyAlertListener(alertName, "alertfinished");
final int notificationID = alertName.hashCode();
notificationClient.remove(notificationID);
@ -1088,7 +1082,7 @@ public class GeckoAppShell
final int notificationID = alertName.hashCode();
if (GeckoApp.ACTION_ALERT_CALLBACK.equals(action)) {
callObserver(alertName, "alertclickcallback", alertCookie);
notifyAlertListener(alertName, "alertclickcallback");
if (notificationClient.isOngoing(notificationID)) {
// When clicked, keep the notification if it displays progress

View File

@ -6,13 +6,14 @@
#include "AndroidAlerts.h"
#include "GeneratedJNIWrappers.h"
#include "nsAlertsUtils.h"
#include "nsAppShell.h"
namespace mozilla {
namespace widget {
NS_IMPL_ISUPPORTS(AndroidAlerts, nsIAlertsService)
StaticAutoPtr<AndroidAlerts::AlertInfoMap> AndroidAlerts::sAlertInfoMap;
NS_IMETHODIMP
AndroidAlerts::ShowAlertNotification(const nsAString & aImageUrl,
const nsAString & aAlertTitle,
@ -76,8 +77,11 @@ AndroidAlerts::ShowPersistentNotification(const nsAString& aPersistentData,
nsAlertsUtils::GetSourceHostPort(principal, host);
if (aPersistentData.IsEmpty() && aAlertListener) {
// This will remove any observers already registered for this id
nsAppShell::PostEvent(AndroidGeckoEvent::MakeAddObserver(name, aAlertListener));
if (!sAlertInfoMap) {
sAlertInfoMap = new AlertInfoMap();
}
// This will remove any observers already registered for this name.
sAlertInfoMap->Put(name, new AlertInfo{aAlertListener, cookie});
}
java::GeckoAppShell::ShowAlertNotification(
@ -91,9 +95,33 @@ NS_IMETHODIMP
AndroidAlerts::CloseAlert(const nsAString& aAlertName,
nsIPrincipal* aPrincipal)
{
// We delete the entry in sAlertInfoMap later, when CloseNotification calls
// NotifyListener.
java::GeckoAppShell::CloseNotification(aAlertName);
return NS_OK;
}
void
AndroidAlerts::NotifyListener(const nsAString& aName, const char* aTopic)
{
if (!sAlertInfoMap) {
return;
}
const auto pAlertInfo = sAlertInfoMap->Get(aName);
if (!pAlertInfo) {
return;
}
if (pAlertInfo->listener) {
pAlertInfo->listener->Observe(
nullptr, aTopic, pAlertInfo->cookie.get());
}
if (NS_LITERAL_CSTRING("alertfinished").Equals(aTopic)) {
sAlertInfoMap->Remove(aName);
}
}
} // namespace widget
} // namespace mozilla

View File

@ -6,7 +6,13 @@
#ifndef mozilla_widget_AndroidAlerts_h__
#define mozilla_widget_AndroidAlerts_h__
#include "nsClassHashtable.h"
#include "nsCOMPtr.h"
#include "nsHashKeys.h"
#include "nsIAlertsService.h"
#include "nsIObserver.h"
#include "mozilla/StaticPtr.h"
namespace mozilla {
namespace widget {
@ -19,8 +25,22 @@ public:
AndroidAlerts() {}
static void NotifyListener(const nsAString& aName, const char* aTopic);
protected:
virtual ~AndroidAlerts() {}
virtual ~AndroidAlerts()
{
sAlertInfoMap = nullptr;
}
struct AlertInfo
{
nsCOMPtr<nsIObserver> listener;
nsString cookie;
};
using AlertInfoMap = nsClassHashtable<nsStringHashKey, AlertInfo>;
static StaticAutoPtr<AlertInfoMap> sAlertInfoMap;
};
} // namespace widget

View File

@ -53,6 +53,7 @@
#include "mozilla/Logging.h"
#endif
#include "AndroidAlerts.h"
#include "ANRReporter.h"
#include "GeckoNetworkManager.h"
#include "GeckoScreenOrientation.h"
@ -322,6 +323,17 @@ public:
}
#endif
}
static void NotifyAlertListener(jni::String::Param aName,
jni::String::Param aTopic)
{
if (!aName || !aTopic) {
return;
}
AndroidAlerts::NotifyListener(
aName->ToString(), aTopic->ToCString().get());
}
};
nsAppShell::nsAppShell()