summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.cc
blob: b78c173ef0e29387408892908312299ae060ffee (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
// Copyright 2019 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 "third_party/blink/renderer/core/loader/worker_resource_timing_notifier_impl.h"

#include <memory>
#include "third_party/blink/renderer/core/loader/cross_thread_resource_timing_info_copier.h"
#include "third_party/blink/renderer/core/timing/dom_window_performance.h"
#include "third_party/blink/renderer/core/timing/performance.h"
#include "third_party/blink/renderer/core/timing/worker_global_scope_performance.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"

namespace blink {

namespace {

Performance* GetPerformance(ExecutionContext& execution_context) {
  DCHECK(execution_context.IsContextThread());
  if (execution_context.IsDocument()) {
    DCHECK(execution_context.ExecutingWindow());
    return DOMWindowPerformance::performance(
        *execution_context.ExecutingWindow());
  }
  if (execution_context.IsWorkerGlobalScope()) {
    return WorkerGlobalScopePerformance::performance(
        To<WorkerGlobalScope>(execution_context));
  }
  NOTREACHED() << "Unexpected execution context, it should be either Document "
                  "or WorkerGlobalScope";
  return nullptr;
}

}  // namespace

// static
WorkerResourceTimingNotifierImpl*
WorkerResourceTimingNotifierImpl::CreateForInsideResourceFetcher(
    ExecutionContext& execution_context) {
  auto* notifier = MakeGarbageCollected<WorkerResourceTimingNotifierImpl>(
      execution_context.GetTaskRunner(TaskType::kPerformanceTimeline));
  notifier->inside_execution_context_ = &execution_context;
  return notifier;
}

// static
WorkerResourceTimingNotifierImpl*
WorkerResourceTimingNotifierImpl::CreateForOutsideResourceFetcher(
    ExecutionContext& execution_context) {
  auto* notifier = MakeGarbageCollected<WorkerResourceTimingNotifierImpl>(
      execution_context.GetTaskRunner(TaskType::kPerformanceTimeline));
  notifier->outside_execution_context_ = &execution_context;
  return notifier;
}

WorkerResourceTimingNotifierImpl::WorkerResourceTimingNotifierImpl(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
    : task_runner_(std::move(task_runner)) {
  DCHECK(task_runner_);
}

void WorkerResourceTimingNotifierImpl::AddResourceTiming(
    mojom::blink::ResourceTimingInfoPtr info,
    const AtomicString& initiator_type,
    mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
        worker_timing_receiver) {
  if (task_runner_->RunsTasksInCurrentSequence()) {
    DCHECK(inside_execution_context_);
    if (inside_execution_context_->IsContextDestroyed())
      return;
    DCHECK(inside_execution_context_->IsContextThread());
    GetPerformance(*inside_execution_context_)
        ->AddResourceTiming(std::move(info), initiator_type,
                            std::move(worker_timing_receiver));
  } else {
    PostCrossThreadTask(
        *task_runner_, FROM_HERE,
        CrossThreadBindOnce(
            &WorkerResourceTimingNotifierImpl::AddCrossThreadResourceTiming,
            WrapCrossThreadWeakPersistent(this), std::move(info),
            initiator_type.GetString(), std::move(worker_timing_receiver)));
  }
}

void WorkerResourceTimingNotifierImpl::AddCrossThreadResourceTiming(
    mojom::blink::ResourceTimingInfoPtr info,
    const String& initiator_type,
    mojo::PendingReceiver<mojom::blink::WorkerTimingContainer>
        worker_timing_receiver) {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());
  if (!outside_execution_context_ ||
      outside_execution_context_->IsContextDestroyed())
    return;
  DCHECK(outside_execution_context_->IsContextThread());
  GetPerformance(*outside_execution_context_)
      ->AddResourceTiming(std::move(info), AtomicString(initiator_type),
                          std::move(worker_timing_receiver));
}

void WorkerResourceTimingNotifierImpl::Trace(Visitor* visitor) {
  visitor->Trace(inside_execution_context_);
  WorkerResourceTimingNotifier::Trace(visitor);
}

}  // namespace blink