1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/desktop_notification_handler.h"
6
7#include "chrome/browser/notifications/desktop_notification_service.h"
8#include "chrome/browser/notifications/desktop_notification_service_factory.h"
9#include "chrome/browser/profiles/profile.h"
10#include "chrome/common/url_constants.h"
11#include "content/browser/renderer_host/render_process_host.h"
12#include "content/browser/renderer_host/render_view_host.h"
13#include "content/browser/renderer_host/render_view_host_delegate.h"
14#include "content/common/desktop_notification_messages.h"
15
16DesktopNotificationHandler::DesktopNotificationHandler(
17    RenderViewHost* render_view_host)
18  : RenderViewHostObserver(render_view_host) {
19}
20
21DesktopNotificationHandler::~DesktopNotificationHandler() {
22}
23
24bool DesktopNotificationHandler::OnMessageReceived(
25    const IPC::Message& message) {
26  bool handled = true;
27
28  IPC_BEGIN_MESSAGE_MAP(DesktopNotificationHandler, message)
29    IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_Show, OnShow)
30    IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_Cancel, OnCancel)
31    IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_RequestPermission,
32                        OnRequestPermission)
33    IPC_MESSAGE_UNHANDLED(handled = false)
34  IPC_END_MESSAGE_MAP()
35
36  return handled;
37}
38
39void DesktopNotificationHandler::OnShow(
40    const DesktopNotificationHostMsg_Show_Params& params) {
41  // Disallow HTML notifications from unwanted schemes.  javascript:
42  // in particular allows unwanted cross-domain access.
43  GURL url = params.contents_url;
44  if (params.is_html &&
45      !url.SchemeIs(chrome::kHttpScheme) &&
46      !url.SchemeIs(chrome::kHttpsScheme) &&
47      !url.SchemeIs(chrome::kExtensionScheme) &&
48      !url.SchemeIs(chrome::kDataScheme)) {
49    return;
50  }
51
52  RenderProcessHost* process = render_view_host()->process();
53  DesktopNotificationService* service =
54      DesktopNotificationServiceFactory::GetForProfile(process->profile());
55
56  service->ShowDesktopNotification(
57    params,
58    process->id(),
59    routing_id(),
60    DesktopNotificationService::PageNotification);
61}
62
63void DesktopNotificationHandler::OnCancel(int notification_id) {
64  RenderProcessHost* process = render_view_host()->process();
65  DesktopNotificationService* service =
66      DesktopNotificationServiceFactory::GetForProfile(process->profile());
67
68  service->CancelDesktopNotification(
69      process->id(),
70      routing_id(),
71      notification_id);
72}
73
74void DesktopNotificationHandler::OnRequestPermission(
75    const GURL& source_origin, int callback_context) {
76  if (render_view_host()->delegate()->RequestDesktopNotificationPermission(
77          source_origin, callback_context)) {
78    return;
79  }
80
81  RenderProcessHost* process = render_view_host()->process();
82  DesktopNotificationService* service =
83      DesktopNotificationServiceFactory::GetForProfile(process->profile());
84  service->RequestPermission(
85      source_origin, process->id(), routing_id(), callback_context, NULL);
86}
87