Bug 1219855, Part 1 - Make `nsXULAlerts` implement `nsIAlertsService`. r=MattN,wchen

--HG--
extra : commitid : IXcGploxKLn
extra : rebase_source : b289323b92409c857a370e3a2fe44d772b0ebadb
This commit is contained in:
Kit Cambridge 2015-12-31 13:27:09 -07:00
Родитель c91f84cfbf
Коммит 7bf3de48ab
7 изменённых файлов: 184 добавлений и 89 удалений

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

@ -4,6 +4,8 @@
#include "mozilla/AlertNotification.h"
#include "nsAlertsUtils.h"
namespace mozilla {
NS_IMPL_CYCLE_COLLECTION(AlertNotification, mPrincipal)
@ -122,4 +124,18 @@ AlertNotification::GetInPrivateBrowsing(bool* aInPrivateBrowsing)
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetActionable(bool* aActionable)
{
*aActionable = nsAlertsUtils::IsActionablePrincipal(mPrincipal);
return NS_OK;
}
NS_IMETHODIMP
AlertNotification::GetSource(nsAString& aSource)
{
nsAlertsUtils::GetSourceHostPort(mPrincipal, aSource);
return NS_OK;
}
} // namespace mozilla

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

@ -28,7 +28,8 @@ using mozilla::dom::ContentChild;
NS_IMPL_ISUPPORTS(nsAlertsService, nsIAlertsService, nsIAlertsDoNotDisturb, nsIAlertsProgressListener)
nsAlertsService::nsAlertsService()
nsAlertsService::nsAlertsService() :
mXULAlerts(nsXULAlerts::GetInstance())
{
}
@ -104,6 +105,7 @@ NS_IMETHODIMP nsAlertsService::ShowAlert(nsIAlertNotification * aAlert,
return NS_OK;
}
#ifdef MOZ_WIDGET_ANDROID
nsAutoString imageUrl;
rv = aAlert->GetImageURL(imageUrl);
NS_ENSURE_SUCCESS(rv, rv);
@ -124,7 +126,6 @@ NS_IMETHODIMP nsAlertsService::ShowAlert(nsIAlertNotification * aAlert,
rv = aAlert->GetPrincipal(getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
#ifdef MOZ_WIDGET_ANDROID
mozilla::AndroidBridge::Bridge()->ShowAlertNotification(imageUrl, title, text, cookie,
aAlertListener, name, principal);
return NS_OK;
@ -144,26 +145,8 @@ NS_IMETHODIMP nsAlertsService::ShowAlert(nsIAlertNotification * aAlert,
return NS_OK;
}
bool textClickable;
rv = aAlert->GetTextClickable(&textClickable);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString bidi;
rv = aAlert->GetDir(bidi);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString lang;
rv = aAlert->GetLang(lang);
NS_ENSURE_SUCCESS(rv, rv);
bool inPrivateBrowsing;
rv = aAlert->GetInPrivateBrowsing(&inPrivateBrowsing);
NS_ENSURE_SUCCESS(rv, rv);
// Use XUL notifications as a fallback if above methods have failed.
rv = mXULAlerts.ShowAlertNotification(imageUrl, title, text, textClickable,
cookie, aAlertListener, name,
bidi, lang, principal, inPrivateBrowsing);
rv = mXULAlerts->ShowAlert(aAlert, aAlertListener);
return rv;
#endif // !MOZ_WIDGET_ANDROID
}
@ -188,7 +171,7 @@ NS_IMETHODIMP nsAlertsService::CloseAlert(const nsAString& aAlertName,
return sysAlerts->CloseAlert(aAlertName, nullptr);
}
return mXULAlerts.CloseAlert(aAlertName);
return mXULAlerts->CloseAlert(aAlertName, aPrincipal);
#endif // !MOZ_WIDGET_ANDROID
}
@ -209,7 +192,8 @@ NS_IMETHODIMP nsAlertsService::GetManualDoNotDisturb(bool* aRetVal)
return alertsDND->GetManualDoNotDisturb(aRetVal);
}
return mXULAlerts.GetManualDoNotDisturb(aRetVal);
nsCOMPtr<nsIAlertsDoNotDisturb> xulDND(do_QueryInterface(mXULAlerts));
return xulDND ? xulDND->GetManualDoNotDisturb(aRetVal) : NS_ERROR_FAILURE;
#endif
}
@ -228,7 +212,11 @@ NS_IMETHODIMP nsAlertsService::SetManualDoNotDisturb(bool aDoNotDisturb)
}
rv = alertsDND->SetManualDoNotDisturb(aDoNotDisturb);
} else {
rv = mXULAlerts.SetManualDoNotDisturb(aDoNotDisturb);
nsCOMPtr<nsIAlertsDoNotDisturb> xulDND(do_QueryInterface(mXULAlerts));
if (!xulDND) {
return NS_ERROR_FAILURE;
}
rv = xulDND->SetManualDoNotDisturb(aDoNotDisturb);
}
Telemetry::Accumulate(Telemetry::ALERTS_SERVICE_DND_ENABLED, 1);

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

@ -43,7 +43,7 @@ protected:
virtual ~nsAlertsService();
bool ShouldShowAlert();
nsXULAlerts mXULAlerts;
nsCOMPtr<nsIAlertsService> mXULAlerts;
};
#endif /* nsAlertsService_h__ */

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

@ -12,7 +12,7 @@ interface nsIPrincipal;
#define ALERT_NOTIFICATION_CONTRACTID "@mozilla.org/alert-notification;1"
%}
[scriptable, uuid(b26b4a67-81b0-4270-8311-1e00a097ef92)]
[scriptable, uuid(9e87fc34-8dbb-4b14-a724-b27be6822ec8)]
interface nsIAlertNotification : nsISupports
{
/** Initializes an alert notification. */
@ -81,8 +81,7 @@ interface nsIAlertNotification : nsISupports
/**
* The principal of the page that created the alert. Used for IPC security
* checks, and to determine whether the alert should show the source string
* and action buttons.
* checks, and to determine whether the alert is actionable.
*/
readonly attribute nsIPrincipal principal;
@ -91,6 +90,19 @@ interface nsIAlertNotification : nsISupports
* in private browsing mode.
*/
readonly attribute boolean inPrivateBrowsing;
/**
* Indicates whether this alert should show the source string and action
* buttons. False for system alerts (which can omit the principal), or
* expanded, system, and null principals.
*/
readonly attribute boolean actionable;
/**
* The host and port of the originating page, or an empty string if the alert
* is not actionable.
*/
readonly attribute AString source;
};
[scriptable, uuid(f7a36392-d98b-4141-a7d7-4e46642684e3)]

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

@ -5,12 +5,13 @@
#include "nsXULAlerts.h"
#include "nsAutoPtr.h"
#include "nsComponentManagerUtils.h"
#include "nsCOMPtr.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/dom/Notification.h"
#include "mozilla/unused.h"
#include "nsIServiceManager.h"
#include "nsAlertsUtils.h"
#include "nsISupportsArray.h"
#include "nsISupportsPrimitives.h"
#include "nsPIDOMWindow.h"
@ -21,6 +22,10 @@ using mozilla::dom::NotificationTelemetryService;
#define ALERT_CHROME_URL "chrome://global/content/alerts/alert.xul"
namespace {
StaticRefPtr<nsXULAlerts> gXULAlerts;
} // anonymous namespace
NS_IMPL_ISUPPORTS(nsXULAlertObserver, nsIObserver)
NS_IMETHODIMP
@ -43,16 +48,52 @@ nsXULAlertObserver::Observe(nsISupports* aSubject, const char* aTopic,
return rv;
}
nsresult
NS_IMPL_ISUPPORTS(nsXULAlerts, nsIAlertsService, nsIAlertsDoNotDisturb)
/* static */ already_AddRefed<nsXULAlerts>
nsXULAlerts::GetInstance()
{
if (!gXULAlerts) {
gXULAlerts = new nsXULAlerts();
ClearOnShutdown(&gXULAlerts);
}
RefPtr<nsXULAlerts> instance = gXULAlerts.get();
return instance.forget();
}
NS_IMETHODIMP
nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle,
const nsAString& aAlertText, bool aAlertTextClickable,
const nsAString& aAlertCookie, nsIObserver* aAlertListener,
const nsAString& aAlertName, const nsAString& aBidi,
const nsAString& aLang, nsIPrincipal* aPrincipal,
bool aInPrivateBrowsing)
const nsAString& aLang, const nsAString & aData,
nsIPrincipal* aPrincipal, bool aInPrivateBrowsing)
{
nsCOMPtr<nsIAlertNotification> alert =
do_CreateInstance(ALERT_NOTIFICATION_CONTRACTID);
NS_ENSURE_TRUE(alert, NS_ERROR_FAILURE);
nsresult rv = alert->Init(aAlertName, aImageUrl, aAlertTitle,
aAlertText, aAlertTextClickable,
aAlertCookie, aBidi, aLang, aData,
aPrincipal, aInPrivateBrowsing);
NS_ENSURE_SUCCESS(rv, rv);
return ShowAlert(alert, aAlertListener);
}
NS_IMETHODIMP
nsXULAlerts::ShowAlert(nsIAlertNotification* aAlert,
nsIObserver* aAlertListener)
{
bool inPrivateBrowsing;
nsresult rv = aAlert->GetInPrivateBrowsing(&inPrivateBrowsing);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString cookie;
rv = aAlert->GetCookie(cookie);
NS_ENSURE_SUCCESS(rv, rv);
if (mDoNotDisturb) {
if (!aInPrivateBrowsing) {
if (!inPrivateBrowsing) {
RefPtr<NotificationTelemetryService> telemetry =
NotificationTelemetryService::GetInstance();
if (telemetry) {
@ -60,51 +101,88 @@ nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString&
// libnotify backends will fire `alertshow` even if "do not disturb"
// is enabled. In that case, `NotificationObserver` will record the
// sender.
Unused << NS_WARN_IF(NS_FAILED(telemetry->RecordSender(aPrincipal)));
nsCOMPtr<nsIPrincipal> principal;
if (NS_SUCCEEDED(aAlert->GetPrincipal(getter_AddRefs(principal)))) {
Unused << NS_WARN_IF(NS_FAILED(telemetry->RecordSender(principal)));
}
}
}
if (aAlertListener)
aAlertListener->Observe(nullptr, "alertfinished", cookie.get());
return NS_OK;
}
nsAutoString name;
rv = aAlert->GetName(name);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString imageUrl;
rv = aAlert->GetImageURL(imageUrl);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString title;
rv = aAlert->GetTitle(title);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString text;
rv = aAlert->GetText(text);
NS_ENSURE_SUCCESS(rv, rv);
bool textClickable;
rv = aAlert->GetTextClickable(&textClickable);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString bidi;
rv = aAlert->GetDir(bidi);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString lang;
rv = aAlert->GetLang(lang);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString source;
rv = aAlert->GetSource(source);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
nsCOMPtr<nsISupportsArray> argsArray;
nsresult rv = NS_NewISupportsArray(getter_AddRefs(argsArray));
rv = NS_NewISupportsArray(getter_AddRefs(argsArray));
NS_ENSURE_SUCCESS(rv, rv);
// create scriptable versions of our strings that we can store in our nsISupportsArray....
nsCOMPtr<nsISupportsString> scriptableImageUrl (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableImageUrl, NS_ERROR_FAILURE);
scriptableImageUrl->SetData(aImageUrl);
scriptableImageUrl->SetData(imageUrl);
rv = argsArray->AppendElement(scriptableImageUrl);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> scriptableAlertTitle (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableAlertTitle, NS_ERROR_FAILURE);
scriptableAlertTitle->SetData(aAlertTitle);
scriptableAlertTitle->SetData(title);
rv = argsArray->AppendElement(scriptableAlertTitle);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> scriptableAlertText (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableAlertText, NS_ERROR_FAILURE);
scriptableAlertText->SetData(aAlertText);
scriptableAlertText->SetData(text);
rv = argsArray->AppendElement(scriptableAlertText);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsPRBool> scriptableIsClickable (do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID));
NS_ENSURE_TRUE(scriptableIsClickable, NS_ERROR_FAILURE);
scriptableIsClickable->SetData(aAlertTextClickable);
scriptableIsClickable->SetData(textClickable);
rv = argsArray->AppendElement(scriptableIsClickable);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> scriptableAlertCookie (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableAlertCookie, NS_ERROR_FAILURE);
scriptableAlertCookie->SetData(aAlertCookie);
scriptableAlertCookie->SetData(cookie);
rv = argsArray->AppendElement(scriptableAlertCookie);
NS_ENSURE_SUCCESS(rv, rv);
@ -121,14 +199,14 @@ nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString&
nsCOMPtr<nsISupportsString> scriptableBidi (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableBidi, NS_ERROR_FAILURE);
scriptableBidi->SetData(aBidi);
scriptableBidi->SetData(bidi);
rv = argsArray->AppendElement(scriptableBidi);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> scriptableLang (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableLang, NS_ERROR_FAILURE);
scriptableLang->SetData(aLang);
scriptableLang->SetData(lang);
rv = argsArray->AppendElement(scriptableLang);
NS_ENSURE_SUCCESS(rv, rv);
@ -137,7 +215,7 @@ nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString&
// it may take the same position.
nsCOMPtr<nsISupportsInterfacePointer> replacedWindow = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
NS_ENSURE_TRUE(replacedWindow, NS_ERROR_FAILURE);
nsIDOMWindow* previousAlert = mNamedWindows.GetWeak(aAlertName);
nsIDOMWindow* previousAlert = mNamedWindows.GetWeak(name);
replacedWindow->SetData(previousAlert);
replacedWindow->SetDataIID(&NS_GET_IID(nsIDOMWindow));
rv = argsArray->AppendElement(replacedWindow);
@ -147,7 +225,7 @@ nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString&
// mNamedWindows when it is closed.
nsCOMPtr<nsISupportsInterfacePointer> ifptr = do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
RefPtr<nsXULAlertObserver> alertObserver = new nsXULAlertObserver(this, aAlertName, aAlertListener);
RefPtr<nsXULAlertObserver> alertObserver = new nsXULAlertObserver(this, name, aAlertListener);
nsCOMPtr<nsISupports> iSupports(do_QueryInterface(alertObserver));
ifptr->SetData(iSupports);
ifptr->SetDataIID(&NS_GET_IID(nsIObserver));
@ -158,43 +236,42 @@ nsXULAlerts::ShowAlertNotification(const nsAString& aImageUrl, const nsAString&
// notification. It is empty for system alerts.
nsCOMPtr<nsISupportsString> scriptableAlertSource (do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
NS_ENSURE_TRUE(scriptableAlertSource, NS_ERROR_FAILURE);
nsAutoString source;
nsAlertsUtils::GetSourceHostPort(aPrincipal, source);
scriptableAlertSource->SetData(source);
rv = argsArray->AppendElement(scriptableAlertSource);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMWindow> newWindow;
nsAutoCString features("chrome,dialog=yes,titlebar=no,popup=yes");
if (aInPrivateBrowsing) {
if (inPrivateBrowsing) {
features.AppendLiteral(",private");
}
rv = wwatch->OpenWindow(0, ALERT_CHROME_URL, "_blank", features.get(),
argsArray, getter_AddRefs(newWindow));
NS_ENSURE_SUCCESS(rv, rv);
mNamedWindows.Put(aAlertName, newWindow);
mNamedWindows.Put(name, newWindow);
alertObserver->SetAlertWindow(newWindow);
return NS_OK;
}
nsresult
NS_IMETHODIMP
nsXULAlerts::SetManualDoNotDisturb(bool aDoNotDisturb)
{
mDoNotDisturb = aDoNotDisturb;
return NS_OK;
}
nsresult
NS_IMETHODIMP
nsXULAlerts::GetManualDoNotDisturb(bool* aRetVal)
{
*aRetVal = mDoNotDisturb;
return NS_OK;
}
nsresult
nsXULAlerts::CloseAlert(const nsAString& aAlertName)
NS_IMETHODIMP
nsXULAlerts::CloseAlert(const nsAString& aAlertName,
nsIPrincipal* aPrincipal)
{
nsIDOMWindow* alert = mNamedWindows.GetWeak(aAlertName);
nsCOMPtr<nsPIDOMWindow> domWindow = do_QueryInterface(alert);

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

@ -12,28 +12,24 @@
#include "nsIDOMWindow.h"
#include "nsIObserver.h"
class nsXULAlerts {
class nsXULAlerts : public nsIAlertsService,
public nsIAlertsDoNotDisturb
{
friend class nsXULAlertObserver;
public:
NS_DECL_NSIALERTSDONOTDISTURB
NS_DECL_NSIALERTSSERVICE
NS_DECL_ISUPPORTS
nsXULAlerts()
{
}
virtual ~nsXULAlerts() {}
nsresult ShowAlertNotification(const nsAString& aImageUrl, const nsAString& aAlertTitle,
const nsAString& aAlertText, bool aAlertTextClickable,
const nsAString& aAlertCookie, nsIObserver* aAlertListener,
const nsAString& aAlertName, const nsAString& aBidi,
const nsAString& aLang, nsIPrincipal* aPrincipal,
bool aInPrivateBrowsing);
nsresult CloseAlert(const nsAString& aAlertName);
nsresult GetManualDoNotDisturb(bool* aRetVal);
nsresult SetManualDoNotDisturb(bool aDoNotDisturb);
static already_AddRefed<nsXULAlerts> GetInstance();
protected:
virtual ~nsXULAlerts() {}
nsInterfaceHashtable<nsStringHashKey, nsIDOMWindow> mNamedWindows;
bool mDoNotDisturb = false;
};
@ -58,7 +54,7 @@ public:
protected:
virtual ~nsXULAlertObserver() {}
nsXULAlerts* mXULAlerts;
RefPtr<nsXULAlerts> mXULAlerts;
nsString mAlertName;
nsCOMPtr<nsIDOMWindow> mAlertWindow;
nsCOMPtr<nsIObserver> mObserver;

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

@ -18,7 +18,6 @@
#include "nsCOMPtr.h"
#include "nsIObserver.h"
#include "nsIContentPolicy.h"
#include "nsAlertsUtils.h"
#include "imgRequestProxy.h"
using namespace mozilla;
@ -269,11 +268,9 @@ OSXNotificationCenter::ShowAlert(nsIAlertNotification* aAlert,
NS_ENSURE_SUCCESS(rv, rv);
notification.title = nsCocoaUtils::ToNSString(title);
nsCOMPtr<nsIPrincipal> principal;
rv = aAlert->GetPrincipal(getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString hostPort;
nsAlertsUtils::GetSourceHostPort(principal, hostPort);
rv = aAlert->GetSource(hostPort);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIStringBundle> bundle;
nsCOMPtr<nsIStringBundleService> sbs = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
sbs->CreateBundle("chrome://alerts/locale/alert.properties", getter_AddRefs(bundle));
@ -297,7 +294,12 @@ OSXNotificationCenter::ShowAlert(nsIAlertNotification* aAlert,
notification.hasActionButton = NO;
// If this is not an application/extension alert, show additional actions dealing with permissions.
if (nsAlertsUtils::IsActionablePrincipal(principal)) {
bool isActionable;
if (NS_SUCCEEDED(aAlert->GetActionable(&isActionable)) && isActionable) {
nsCOMPtr<nsIStringBundle> bundle;
nsCOMPtr<nsIStringBundleService> sbs = do_GetService(NS_STRINGBUNDLE_CONTRACTID);
sbs->CreateBundle("chrome://alerts/locale/alert.properties", getter_AddRefs(bundle));
if (bundle) {
nsXPIDLString closeButtonTitle, actionButtonTitle, disableButtonTitle, settingsButtonTitle;
bundle->GetStringFromName(MOZ_UTF16("closeButton.title"),
@ -378,22 +380,26 @@ OSXNotificationCenter::ShowAlert(nsIAlertNotification* aAlert,
nsCOMPtr<nsIURI> imageUri;
NS_NewURI(getter_AddRefs(imageUri), imageUrl);
if (imageUri) {
rv = il->LoadImage(imageUri, nullptr, nullptr,
mozilla::net::RP_Default,
principal, nullptr,
this, nullptr,
inPrivateBrowsing ? nsIRequest::LOAD_ANONYMOUS :
nsIRequest::LOAD_NORMAL,
nullptr, nsIContentPolicy::TYPE_INTERNAL_IMAGE,
EmptyString(),
getter_AddRefs(osxni->mIconRequest));
nsCOMPtr<nsIPrincipal> principal;
rv = aAlert->GetPrincipal(getter_AddRefs(principal));
if (NS_SUCCEEDED(rv)) {
// Set a timer for six seconds. If we don't have an icon by the time this
// goes off then we go ahead without an icon.
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
osxni->mIconTimeoutTimer = timer;
timer->InitWithCallback(this, 6000, nsITimer::TYPE_ONE_SHOT);
return NS_OK;
rv = il->LoadImage(imageUri, nullptr, nullptr,
mozilla::net::RP_Default,
principal, nullptr,
this, nullptr,
inPrivateBrowsing ? nsIRequest::LOAD_ANONYMOUS :
nsIRequest::LOAD_NORMAL,
nullptr, nsIContentPolicy::TYPE_INTERNAL_IMAGE,
EmptyString(),
getter_AddRefs(osxni->mIconRequest));
if (NS_SUCCEEDED(rv)) {
// Set a timer for six seconds. If we don't have an icon by the time this
// goes off then we go ahead without an icon.
nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
osxni->mIconTimeoutTimer = timer;
timer->InitWithCallback(this, 6000, nsITimer::TYPE_ONE_SHOT);
return NS_OK;
}
}
}
}