void
nsDOMDesktopNotification::Init()
{
  nsRefPtr<nsDesktopNotificationRequest> request = new nsDesktopNotificationRequest(this);

  // if we are in the content process, then remote it to the parent.
  if (XRE_GetProcessType() == GeckoProcessType_Content) {

    // if for some reason mOwner is null, just silently
    // bail.  The user will not see a notification, and that
    // is fine.
    if (!GetOwner())
      return;

    // because owner implements nsITabChild, we can assume that it is
    // the one and only TabChild for this docshell.
    TabChild* child = GetTabChildFrom(GetOwner()->GetDocShell());

    // Retain a reference so the object isn't deleted without IPDL's knowledge.
    // Corresponding release occurs in DeallocPContentPermissionRequest.
    nsRefPtr<nsDesktopNotificationRequest> copy = request;

    child->SendPContentPermissionRequestConstructor(copy.forget().get(),
                                                    NS_LITERAL_CSTRING("desktop-notification"),
                                                    NS_LITERAL_CSTRING("unused"),
                                                    IPC::Principal(mPrincipal));

    request->Sendprompt();
    return;
  }

  // otherwise, dispatch it
  NS_DispatchToMainThread(request);
}
nsDOMDesktopNotification::nsDOMDesktopNotification(const nsAString & title,
                                                   const nsAString & description,
                                                   const nsAString & iconURL,
                                                   nsPIDOMWindow *aWindow,
                                                   nsIScriptContext* aScriptContext,
                                                   nsIURI* uri)
  : mTitle(title)
  , mDescription(description)
  , mIconURL(iconURL)
  , mURI(uri)
  , mAllow(PR_FALSE)
  , mShowHasBeenCalled(PR_FALSE)
{
  mOwner = aWindow;
  mScriptContext = aScriptContext;

  if (nsContentUtils::GetBoolPref("notification.disabled", PR_FALSE))
    return;

  // If we are in testing mode (running mochitests, for example)
  // and we are suppose to allow requests, then just post an allow event.
  if (nsContentUtils::GetBoolPref("notification.prompt.testing", PR_FALSE) &&
      nsContentUtils::GetBoolPref("notification.prompt.testing.allow", PR_TRUE)) {
    mAllow = PR_TRUE;
    return;
  }

  nsRefPtr<nsDesktopNotificationRequest> request = new nsDesktopNotificationRequest(this);

  // if we are in the content process, then remote it to the parent.
  if (XRE_GetProcessType() == GeckoProcessType_Content) {

    // if for some reason mOwner is null, just silently
    // bail.  The user will not see a notification, and that
    // is fine.
    if (!mOwner)
      return;

    // because owner implements nsITabChild, we can assume that it is
    // the one and only TabChild for this docshell.
    TabChild* child = GetTabChildFrom(mOwner->GetDocShell());
    
    // Retain a reference so the object isn't deleted without IPDL's knowledge.
    // Corresponding release occurs in DeallocPContentPermissionRequest.
    request->AddRef();

    nsCString type = NS_LITERAL_CSTRING("desktop-notification");
    child->SendPContentPermissionRequestConstructor(request, type, IPC::URI(mURI));
    
    request->Sendprompt();
    return;
  }

  // otherwise, dispatch it
  NS_DispatchToMainThread(request);

}
nsDOMDesktopNotification::nsDOMDesktopNotification(const nsAString & title,
                                                   const nsAString & description,
                                                   const nsAString & iconURL,
                                                   nsPIDOMWindow *aWindow,
                                                   nsIPrincipal* principal)
  : mTitle(title)
  , mDescription(description)
  , mIconURL(iconURL)
  , mPrincipal(principal)
  , mAllow(false)
  , mShowHasBeenCalled(false)
{
  BindToOwner(aWindow);
  if (Preferences::GetBool("notification.disabled", false)) {
    return;
  }

  // If we are in testing mode (running mochitests, for example)
  // and we are suppose to allow requests, then just post an allow event.
  if (Preferences::GetBool("notification.prompt.testing", false) &&
      Preferences::GetBool("notification.prompt.testing.allow", true)) {
    mAllow = true;
    return;
  }

  nsRefPtr<nsDesktopNotificationRequest> request = new nsDesktopNotificationRequest(this);

  // if we are in the content process, then remote it to the parent.
  if (XRE_GetProcessType() == GeckoProcessType_Content) {

    // if for some reason mOwner is null, just silently
    // bail.  The user will not see a notification, and that
    // is fine.
    if (!GetOwner())
      return;

    // because owner implements nsITabChild, we can assume that it is
    // the one and only TabChild for this docshell.
    TabChild* child = GetTabChildFrom(GetOwner()->GetDocShell());

    // Retain a reference so the object isn't deleted without IPDL's knowledge.
    // Corresponding release occurs in DeallocPContentPermissionRequest.
    nsRefPtr<nsDesktopNotificationRequest> copy = request;

    nsCString type = NS_LITERAL_CSTRING("desktop-notification");
    child->SendPContentPermissionRequestConstructor(copy.forget().get(), type, IPC::Principal(mPrincipal));

    request->Sendprompt();
    return;
  }

  // otherwise, dispatch it
  NS_DispatchToMainThread(request);

}
/* static */ nsresult
nsContentPermissionUtils::AskPermission(nsIContentPermissionRequest* aRequest, nsPIDOMWindow* aWindow)
{
  MOZ_ASSERT(!aWindow || aWindow->IsInnerWindow());
  NS_ENSURE_STATE(aWindow && aWindow->IsCurrentInnerWindow());

  // for content process
  if (XRE_GetProcessType() == GeckoProcessType_Content) {

    nsRefPtr<RemotePermissionRequest> req =
      new RemotePermissionRequest(aRequest, aWindow);

    MOZ_ASSERT(NS_IsMainThread()); // IPC can only be execute on main thread.

    TabChild* child = TabChild::GetFrom(aWindow->GetDocShell());
    NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);

    nsCOMPtr<nsIArray> typeArray;
    nsresult rv = aRequest->GetTypes(getter_AddRefs(typeArray));
    NS_ENSURE_SUCCESS(rv, rv);

    nsTArray<PermissionRequest> permArray;
    ConvertArrayToPermissionRequest(typeArray, permArray);

    nsCOMPtr<nsIPrincipal> principal;
    rv = aRequest->GetPrincipal(getter_AddRefs(principal));
    NS_ENSURE_SUCCESS(rv, rv);

    req->IPDLAddRef();
    child->SendPContentPermissionRequestConstructor(req,
                                                    permArray,
                                                    IPC::Principal(principal));

    req->Sendprompt();
    return NS_OK;
  }

  // for chrome process
  nsCOMPtr<nsIContentPermissionPrompt> prompt =
    do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
  if (prompt) {
    prompt->Prompt(aRequest);
  }
  return NS_OK;
}