Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/storage/StorageNotifierService.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "StorageNotifierService.h"
8
#include "mozilla/ClearOnShutdown.h"
9
#include "mozilla/StaticPtr.h"
10
11
namespace mozilla {
12
namespace dom {
13
14
namespace {
15
16
// This boolean is used to avoid the creation of the service after been
17
// distroyed on shutdown.
18
bool gStorageShuttingDown = false;
19
20
StaticRefPtr<StorageNotifierService> gStorageNotifierService;
21
22
} // anonymous
23
24
/* static */ StorageNotifierService*
25
StorageNotifierService::GetOrCreate()
26
0
{
27
0
  MOZ_ASSERT(NS_IsMainThread());
28
0
  if (!gStorageNotifierService && !gStorageShuttingDown) {
29
0
    gStorageNotifierService = new StorageNotifierService();
30
0
    ClearOnShutdown(&gStorageNotifierService);
31
0
  }
32
0
33
0
  return gStorageNotifierService;
34
0
}
35
36
StorageNotifierService::StorageNotifierService()
37
0
{
38
0
  MOZ_ASSERT(NS_IsMainThread());
39
0
  MOZ_ASSERT(!gStorageNotifierService);
40
0
}
41
42
StorageNotifierService::~StorageNotifierService()
43
0
{
44
0
  MOZ_ASSERT(NS_IsMainThread());
45
0
  MOZ_ASSERT(!gStorageNotifierService);
46
0
  gStorageShuttingDown = true;
47
0
}
48
49
/* static */ void
50
StorageNotifierService::Broadcast(StorageEvent* aEvent,
51
                                  const char16_t* aStorageType,
52
                                  bool aPrivateBrowsing,
53
                                  bool aImmediateDispatch)
54
0
{
55
0
  MOZ_ASSERT(NS_IsMainThread());
56
0
57
0
  RefPtr<StorageNotifierService> service = gStorageNotifierService;
58
0
  if (!service) {
59
0
    return;
60
0
  }
61
0
62
0
  RefPtr<StorageEvent> event = aEvent;
63
0
64
0
  nsTObserverArray<RefPtr<StorageNotificationObserver>>::ForwardIterator
65
0
    iter(service->mObservers);
66
0
67
0
  while (iter.HasMore()) {
68
0
    RefPtr<StorageNotificationObserver> observer = iter.GetNext();
69
0
70
0
    // Enforce that the source storage area's private browsing state matches
71
0
    // this window's state.  These flag checks and their maintenance independent
72
0
    // from the principal's OriginAttributes matter because chrome docshells
73
0
    // that are part of private browsing windows can be private browsing without
74
0
    // having their OriginAttributes set (because they have the system
75
0
    // principal).
76
0
    if (aPrivateBrowsing != observer->IsPrivateBrowsing()) {
77
0
      continue;
78
0
    }
79
0
80
0
    // No reasons to continue if the principal of the event doesn't match with
81
0
    // the window's one.
82
0
    if (!StorageUtils::PrincipalsEqual(aEvent->GetPrincipal(),
83
0
                                       observer->GetPrincipal())) {
84
0
      continue;
85
0
    }
86
0
87
0
    RefPtr<Runnable> r = NS_NewRunnableFunction(
88
0
      "StorageNotifierService::Broadcast",
89
0
      [observer, event, aStorageType, aPrivateBrowsing] () {
90
0
        observer->ObserveStorageNotification(event, aStorageType,
91
0
                                             aPrivateBrowsing);
92
0
      });
93
0
94
0
    if (aImmediateDispatch) {
95
0
      r->Run();
96
0
    } else {
97
0
      nsCOMPtr<nsIEventTarget> et = observer->GetEventTarget();
98
0
      if (et) {
99
0
        et->Dispatch(r.forget());
100
0
      }
101
0
    }
102
0
  }
103
0
}
104
105
void
106
StorageNotifierService::Register(StorageNotificationObserver* aObserver)
107
0
{
108
0
  MOZ_ASSERT(NS_IsMainThread());
109
0
  MOZ_ASSERT(aObserver);
110
0
  MOZ_ASSERT(!mObservers.Contains(aObserver));
111
0
112
0
  mObservers.AppendElement(aObserver);
113
0
}
114
115
void
116
StorageNotifierService::Unregister(StorageNotificationObserver* aObserver)
117
0
{
118
0
  MOZ_ASSERT(NS_IsMainThread());
119
0
  MOZ_ASSERT(aObserver);
120
0
121
0
  // No assertion about mObservers containing aObserver because window calls
122
0
  // this method multiple times.
123
0
124
0
  mObservers.RemoveElement(aObserver);
125
0
}
126
127
} // namespace dom
128
} // namespace mozilla