summaryrefslogtreecommitdiffstats
path: root/content/child/notifications/pending_notifications_tracker.cc
blob: 588af7552e3d26983581af1316e1a652cd66894d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/child/notifications/pending_notifications_tracker.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/thread_task_runner_handle.h"
#include "content/child/notifications/notification_image_loader.h"
#include "content/public/common/notification_resources.h"
#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationData.h"
#include "third_party/skia/include/core/SkBitmap.h"

namespace content {

// Stores the information associated with a pending notification.
struct PendingNotificationsTracker::PendingNotification {
  PendingNotification(
      const scoped_refptr<NotificationImageLoader>& image_loader,
      const NotificationResourcesFetchedCallback& callback)
      : image_loader(image_loader), callback(callback) {}

  scoped_refptr<NotificationImageLoader> image_loader;
  NotificationResourcesFetchedCallback callback;
};

PendingNotificationsTracker::PendingNotificationsTracker(
    scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner)
    : main_thread_task_runner_(main_thread_task_runner), weak_factory_(this) {}

PendingNotificationsTracker::~PendingNotificationsTracker() {}

void PendingNotificationsTracker::FetchPageNotificationResources(
    const blink::WebNotificationData& notification_data,
    blink::WebNotificationDelegate* delegate,
    const NotificationResourcesFetchedCallback& callback) {
  delegate_to_pending_id_map_[delegate] = FetchNotificationResources(
      notification_data, callback,
      new NotificationImageLoader(
          base::Bind(&PendingNotificationsTracker::DidFetchPageNotification,
                     weak_factory_.GetWeakPtr(), delegate),
          base::ThreadTaskRunnerHandle::Get()));
}

void PendingNotificationsTracker::FetchPersistentNotificationResources(
    const blink::WebNotificationData& notification_data,
    const NotificationResourcesFetchedCallback& callback) {
  FetchNotificationResources(
      notification_data, callback,
      new NotificationImageLoader(
          base::Bind(
              &PendingNotificationsTracker::DidFetchPersistentNotification,
              weak_factory_.GetWeakPtr()),
          base::ThreadTaskRunnerHandle::Get()));
}

bool PendingNotificationsTracker::CancelPageNotificationFetches(
    blink::WebNotificationDelegate* delegate) {
  auto iter = delegate_to_pending_id_map_.find(delegate);
  if (iter == delegate_to_pending_id_map_.end())
    return false;

  pending_notifications_.Remove(iter->second);
  delegate_to_pending_id_map_.erase(iter);

  return true;
}

void PendingNotificationsTracker::DidFetchPageNotification(
    blink::WebNotificationDelegate* delegate,
    int notification_id,
    const SkBitmap& icon) {
  PendingNotification* pending_notification =
      pending_notifications_.Lookup(notification_id);
  DCHECK(pending_notification);

  NotificationResources notification_resources;
  notification_resources.notification_icon = icon;
  pending_notification->callback.Run(notification_resources);

  delegate_to_pending_id_map_.erase(delegate);
  pending_notifications_.Remove(notification_id);
}

void PendingNotificationsTracker::DidFetchPersistentNotification(
    int notification_id, const SkBitmap& icon) {
  PendingNotification* pending_notification =
      pending_notifications_.Lookup(notification_id);
  DCHECK(pending_notification);

  NotificationResources notification_resources;
  notification_resources.notification_icon = icon;
  pending_notification->callback.Run(notification_resources);

  pending_notifications_.Remove(notification_id);
}

int PendingNotificationsTracker::FetchNotificationResources(
    const blink::WebNotificationData& notification_data,
    const NotificationResourcesFetchedCallback& callback,
    const scoped_refptr<NotificationImageLoader>& image_loader) {
  int notification_id = pending_notifications_.Add(
      new PendingNotification(image_loader, callback));

  main_thread_task_runner_->PostTask(
      FROM_HERE,
      base::Bind(&NotificationImageLoader::StartOnMainThread, image_loader,
                 notification_id, GURL(notification_data.icon)));

  return notification_id;
}

}  // namespace content