blob: 8083def1bc4f36dfd0a3e8b2ab521ea4bf47cb15 [file] [log] [blame]
Devlin Cronin1fc76f32021-09-15 01:39:341// Copyright 2021 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 "extensions/browser/extension_host_test_helper.h"
6
7#include "base/containers/contains.h"
8#include "base/run_loop.h"
9#include "extensions/browser/extension_host.h"
10
11namespace extensions {
12
13ExtensionHostTestHelper::ExtensionHostTestHelper(
14 content::BrowserContext* browser_context)
15 : ExtensionHostTestHelper(browser_context, ExtensionId()) {}
16
17ExtensionHostTestHelper::ExtensionHostTestHelper(
18 content::BrowserContext* browser_context,
19 ExtensionId extension_id)
20 : extension_id_(std::move(extension_id)) {
21 host_registry_observation_.Observe(
22 ExtensionHostRegistry::Get(browser_context));
23}
24
25ExtensionHostTestHelper::~ExtensionHostTestHelper() = default;
26
Devlin Cronin30eb24f2021-09-17 19:26:4327void ExtensionHostTestHelper::OnExtensionHostCreated(
28 content::BrowserContext* browser_context,
29 ExtensionHost* host) {
30 EventSeen(host, HostEvent::kCreated);
31}
32
Devlin Cronin58ac6f7752021-09-21 19:06:3733void ExtensionHostTestHelper::OnExtensionHostCompletedFirstLoad(
34 content::BrowserContext* browser_context,
35 ExtensionHost* host) {
36 EventSeen(host, HostEvent::kCompletedFirstLoad);
37}
38
Devlin Cronin1fc76f32021-09-15 01:39:3439void ExtensionHostTestHelper::OnExtensionHostDestroyed(
40 content::BrowserContext* browser_context,
41 ExtensionHost* host) {
42 EventSeen(host, HostEvent::kDestroyed);
43}
44
Devlin Cronin30eb24f2021-09-17 19:26:4345ExtensionHost* ExtensionHostTestHelper::WaitFor(HostEvent event) {
Devlin Cronin1fc76f32021-09-15 01:39:3446 DCHECK(!waiting_for_);
47
Devlin Cronin30eb24f2021-09-17 19:26:4348 auto iter = observed_events_.find(event);
49 if (iter != observed_events_.end()) {
50 // Note: This can be null if the host has been destroyed.
51 return iter->second;
52 }
Devlin Cronin1fc76f32021-09-15 01:39:3453
54 base::RunLoop run_loop;
55 // Note: We use QuitWhenIdle (instead of Quit) so that any other listeners of
56 // the relevant events get a chance to run first.
57 quit_loop_ = run_loop.QuitWhenIdleClosure();
58 waiting_for_ = event;
59 run_loop.Run();
Devlin Cronin30eb24f2021-09-17 19:26:4360
61 DCHECK(base::Contains(observed_events_, event));
62 // Note: This can still be null here if the corresponding ExtensionHost was
63 // destroyed. This is always true when waiting for
64 // OnExtensionHostDestroyed(), but can also happen if the ExtensionHost is
65 // destroyed while waiting for the run loop to idle.
66 return observed_events_[event];
Devlin Cronin1fc76f32021-09-15 01:39:3467}
68
69void ExtensionHostTestHelper::EventSeen(ExtensionHost* host, HostEvent event) {
70 // Check if the host matches our restrictions.
71 if (!extension_id_.empty() && host->extension_id() != extension_id_)
72 return;
73
Devlin Cronin30eb24f2021-09-17 19:26:4374 if (event == HostEvent::kDestroyed) {
75 // Clean up all old pointers to the ExtensionHost on its destruction.
76 for (auto& kv : observed_events_) {
77 if (kv.second == host)
78 kv.second = nullptr;
79 }
80
81 // Ensure we don't put a new pointer for the host into the map.
82 host = nullptr;
83 }
84
85 observed_events_[event] = host;
86
Devlin Cronin1fc76f32021-09-15 01:39:3487 if (waiting_for_ == event) {
88 DCHECK(quit_loop_);
89 waiting_for_.reset();
90 std::move(quit_loop_).Run();
91 }
92}
93
94} // namespace extensions