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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
content / test / fuzzer / controller_presentation_service_delegate_for_fuzzing.h [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_TEST_FUZZER_CONTROLLER_PRESENTATION_SERVICE_DELEGATE_FOR_FUZZING_H_
#define CONTENT_TEST_FUZZER_CONTROLLER_PRESENTATION_SERVICE_DELEGATE_FOR_FUZZING_H_
#include <map>
#include <memory>
#include <string>
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/presentation_screen_availability_listener.h"
#include "content/public/browser/presentation_service_delegate.h"
#include "content/test/fuzzer/controller_presentation_service_delegate_for_fuzzing.pb.h"
#include "media/base/flinging_controller.h"
#include "third_party/blink/public/mojom/presentation/presentation.mojom.h"
// Fake for the `ControllerPresentationServiceDelegate` interface
//
// This fake is limited to do callback, observer and listener behaviours,
// according to a set of actions specified by a protobuf.
// So it is not suitable for tests. It is designed for a fuzzer.
//
// Usage: call the component as expected as the delegate interface.
// To run the callables provided, use `NextAction`,
// provide a protobuf of the `Action` message - there lists the possible calls.
// This will instruct the fake to run the callbacks accordingly.
//
// The callables are run on the UI thread, as the delegate interface is expected
// to be called on the UI thread.
// In the case of MojoLPM fuzzers, `NextAction` should be called on the fuzzer
// thread.
class ControllerPresentationServiceDelegateForFuzzing
: public content::ControllerPresentationServiceDelegate {
public:
ControllerPresentationServiceDelegateForFuzzing();
~ControllerPresentationServiceDelegateForFuzzing() override;
// Used to run one callable.
// These are set by using this as implementation of the delegate interface.
// The callable is specified by the `action`, as defined in assocciated proto.
//
// All calls must be run on the same sequence
// (for MojoLPM fuzzers, it should be the fuzzer thread)
void NextAction(
const content::fuzzing::
controller_presentation_service_delegate_for_fuzzing::proto::Action&
action);
// ControllerPresentationServiceDelegate implementation
void AddObserver(int render_process_id,
int render_frame_id,
Observer* observer) override;
void RemoveObserver(int render_process_id, int render_frame_id) override;
void Reset(int render_process_id, int render_frame_id) override;
bool AddScreenAvailabilityListener(
int render_process_id,
int render_frame_id,
content::PresentationScreenAvailabilityListener* listener) override;
void RemoveScreenAvailabilityListener(
int render_process_id,
int render_frame_id,
content::PresentationScreenAvailabilityListener* listener) override;
void SetDefaultPresentationUrls(
const content::PresentationRequest& request,
content::DefaultPresentationConnectionCallback callback) override;
void StartPresentation(
const content::PresentationRequest& request,
content::PresentationConnectionCallback success_cb,
content::PresentationConnectionErrorCallback error_cb) override;
void ReconnectPresentation(
const content::PresentationRequest& request,
const std::string& presentation_id,
content::PresentationConnectionCallback success_cb,
content::PresentationConnectionErrorCallback error_cb) override;
void CloseConnection(int render_process_id,
int render_frame_id,
const std::string& presentation_id) override;
void Terminate(int render_process_id,
int render_frame_id,
const std::string& presentation_id) override;
std::unique_ptr<media::FlingingController> GetFlingingController(
int render_process_id,
int render_frame_id,
const std::string& presentation_id) override;
void ListenForConnectionStateChange(
int render_process_id,
int render_frame_id,
const blink::mojom::PresentationInfo& connection,
const content::PresentationConnectionStateChangedCallback&
state_changed_cb) override;
private:
using Action = content::fuzzing::
controller_presentation_service_delegate_for_fuzzing::proto::Action;
// Use to invoke the callbacks & registered callables
// For each, we have two member functions, where the first calls the second.
// The first is prefixed by `Handle`, which takes the raw protobuf datatype,
// and is run on the same thread as `NextAction` (for MojoLPM: fuzzer thread).
// The second is prefixed by `Call` which invokes the call with the converted
// datatype, and is run on the UI thread.
void HandleListenersGetAvailabilityUrl(
const mojolpm::url::mojom::Url& proto_url);
void CallListenersGetAvailabilityUrl(GURL url);
void HandleListenersOnScreenAvailabilityChanged(
const mojolpm::url::mojom::Url& proto_url,
const mojolpm::blink::mojom::ScreenAvailability&
proto_screen_availability);
void CallListenersOnScreenAvailabilityChanged(
GURL url,
blink::mojom::ScreenAvailability screen_availability);
void HandleSetDefaultPresentationUrls(
const mojolpm::blink::mojom::PresentationConnectionResult& proto_result);
void CallSetDefaultPresentationUrls(
blink::mojom::PresentationConnectionResultPtr result_ptr);
void HandleStartPresentationSuccess(
const mojolpm::blink::mojom::PresentationConnectionResult& proto_result);
void CallStartPresentationSuccess(
blink::mojom::PresentationConnectionResultPtr result_ptr);
void HandleStartPresentationError(
const mojolpm::blink::mojom::PresentationError& proto_error);
void CallStartPresentationError(blink::mojom::PresentationErrorPtr error_ptr);
void HandleReconnectPresentationSuccess(
const mojolpm::blink::mojom::PresentationConnectionResult& proto_result);
void CallReconnectPresentationSuccess(
blink::mojom::PresentationConnectionResultPtr result_ptr);
void HandleReconnectPresentationError(
const mojolpm::blink::mojom::PresentationError& proto_error);
void CallReconnectPresentationError(
blink::mojom::PresentationErrorPtr error_ptr);
void HandleListenForConnectionStateChangeStateChanged(
const mojolpm::blink::mojom::PresentationConnectionState&
proto_connection_state);
void CallListenForConnectionStateChangeStateChanged(
blink::mojom::PresentationConnectionState connection_state);
base::WeakPtr<ControllerPresentationServiceDelegateForFuzzing> GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
// We store all callbacks as single callables; not queued nor out of order,
// as this mimics the real delegate as closely as possible
std::map<content::GlobalRenderFrameHostId,
content::PresentationServiceDelegate::Observer*>
observers_;
std::map<GURL, content::PresentationScreenAvailabilityListener*> listeners_;
content::DefaultPresentationConnectionCallback
set_default_presentation_urls_callback_;
content::PresentationConnectionCallback start_presentation_success_cb_;
content::PresentationConnectionErrorCallback start_presentation_error_cb_;
content::PresentationConnectionCallback reconnect_presentation_success_cb_;
content::PresentationConnectionErrorCallback reconnect_presentation_error_cb_;
content::PresentationConnectionStateChangedCallback
listen_for_connection_state_change_state_changed_cb_;
SEQUENCE_CHECKER(sequence_checker_);
// `PostTask`ing the calls onto the UI thread is not guaranteed to outlive
// `this`. So a weak pointer is necessary for those calls.
base::WeakPtrFactory<ControllerPresentationServiceDelegateForFuzzing>
weak_factory_{this};
};
#endif // CONTENT_TEST_FUZZER_CONTROLLER_PRESENTATION_SERVICE_DELEGATE_FOR_FUZZING_H_