OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 #ifndef COMPONENTS_MUS_PUBLIC_CPP_LIB_IN_FLIGHT_CHANGE_H_ | |
6 #define COMPONENTS_MUS_PUBLIC_CPP_LIB_IN_FLIGHT_CHANGE_H_ | |
7 | |
8 #include <stdint.h> | |
9 | |
10 #include <memory> | |
11 #include <string> | |
12 #include <vector> | |
13 | |
14 #include "base/macros.h" | |
15 #include "base/memory/ptr_util.h" | |
16 #include "components/mus/public/cpp/window_observer.h" | |
17 #include "mojo/public/cpp/bindings/array.h" | |
18 #include "ui/gfx/geometry/rect.h" | |
19 | |
20 namespace mus { | |
21 | |
22 namespace mojom { | |
23 enum class Cursor : int32_t; | |
24 } | |
25 | |
26 class Window; | |
27 class WindowTreeClient; | |
28 | |
29 enum class ChangeType { | |
30 ADD_CHILD, | |
31 ADD_TRANSIENT_WINDOW, | |
32 BOUNDS, | |
33 CAPTURE, | |
34 DELETE_WINDOW, | |
35 FOCUS, | |
36 NEW_WINDOW, | |
37 NEW_TOP_LEVEL_WINDOW, | |
38 OPACITY, | |
39 PREDEFINED_CURSOR, | |
40 PROPERTY, | |
41 REMOVE_CHILD, | |
42 REMOVE_TRANSIENT_WINDOW_FROM_PARENT, | |
43 REORDER, | |
44 SET_MODAL, | |
45 VISIBLE, | |
46 }; | |
47 | |
48 // InFlightChange is used to track function calls to the server and take the | |
49 // appropriate action when the call fails, or the same property changes while | |
50 // waiting for the response. When a function is called on the server an | |
51 // InFlightChange is created. The function call is complete when | |
52 // OnChangeCompleted() is received from the server. The following may occur | |
53 // while waiting for a response: | |
54 // . A new value is encountered from the server. For example, the bounds of | |
55 // a window is locally changed and while waiting for the ack | |
56 // OnWindowBoundsChanged() is received. | |
57 // When this happens SetRevertValueFrom() is invoked on the InFlightChange. | |
58 // The expectation is SetRevertValueFrom() takes the value to revert from the | |
59 // supplied change. | |
60 // . While waiting for the ack the property is again modified locally. When | |
61 // this happens a new InFlightChange is created. Once the ack for the first | |
62 // call is received, and the server rejected the change ChangeFailed() is | |
63 // invoked on the first change followed by SetRevertValueFrom() on the second | |
64 // InFlightChange. This allows the new change to update the value to revert | |
65 // should the second call fail. | |
66 // . If the server responds that the call failed and there is not another | |
67 // InFlightChange for the same window outstanding, then ChangeFailed() is | |
68 // invoked followed by Revert(). The expectation is Revert() sets the | |
69 // appropriate value back on the Window. | |
70 // | |
71 // In general there are two classes of changes: | |
72 // 1. We are the only side allowed to make the change. | |
73 // 2. The change can also be applied by another client. For example, the | |
74 // window manager may change the bounds as well as the local client. | |
75 // | |
76 // For (1) use CrashInFlightChange. As the name implies this change CHECKs that | |
77 // the change succeeded. Use the following pattern for this. This code goes | |
78 // where the change is sent to the server (in WindowTreeClient): | |
79 // const uint32_t change_id = | |
80 // ScheduleInFlightChange(base::WrapUnique(new CrashInFlightChange( | |
81 // window, ChangeType::REORDER))); | |
82 // | |
83 // For (2) use the same pattern as (1), but in the on change callback from the | |
84 // server (e.g. OnWindowBoundsChanged()) add the following: | |
85 // // value_from_server is the value supplied from the server. It corresponds | |
86 // // to the value of the property at the time the server processed the | |
87 // // change. If the local change fails, this is the value reverted to. | |
88 // InFlightBoundsChange new_change(window, value_from_server); | |
89 // if (ApplyServerChangeToExistingInFlightChange(new_change)) { | |
90 // // There was an in flight change for the same property. The in flight | |
91 // // change takes the value to revert from |new_change|. | |
92 // return; | |
93 // } | |
94 // | |
95 // // else case is no flight in change and the new value can be applied | |
96 // // immediately. | |
97 // WindowPrivate(window).LocalSetValue(new_value_from_server); | |
98 // | |
99 class InFlightChange { | |
100 public: | |
101 InFlightChange(Window* window, ChangeType type); | |
102 virtual ~InFlightChange(); | |
103 | |
104 // NOTE: for properties not associated with any window window is null. | |
105 Window* window() { return window_; } | |
106 const Window* window() const { return window_; } | |
107 ChangeType change_type() const { return change_type_; } | |
108 | |
109 // Returns true if the two changes are considered the same. This is only | |
110 // invoked if the window id and ChangeType match. | |
111 virtual bool Matches(const InFlightChange& change) const; | |
112 | |
113 // Called in two cases: | |
114 // . When the corresponding property on the server changes. In this case | |
115 // |change| corresponds to the value from the server. | |
116 // . When |change| unsuccesfully completes. | |
117 virtual void SetRevertValueFrom(const InFlightChange& change) = 0; | |
118 | |
119 // The change failed. Normally you need not take any action here as Revert() | |
120 // is called as appropriate. | |
121 virtual void ChangeFailed(); | |
122 | |
123 // The change failed and there is no pending change of the same type | |
124 // outstanding, revert the value. | |
125 virtual void Revert() = 0; | |
126 | |
127 private: | |
128 Window* window_; | |
129 const ChangeType change_type_; | |
130 }; | |
131 | |
132 class InFlightBoundsChange : public InFlightChange { | |
133 public: | |
134 InFlightBoundsChange(Window* window, const gfx::Rect& revert_bounds); | |
135 | |
136 // InFlightChange: | |
137 void SetRevertValueFrom(const InFlightChange& change) override; | |
138 void Revert() override; | |
139 | |
140 private: | |
141 gfx::Rect revert_bounds_; | |
142 | |
143 DISALLOW_COPY_AND_ASSIGN(InFlightBoundsChange); | |
144 }; | |
145 | |
146 // Inflight change that crashes on failure. This is useful for changes that are | |
147 // expected to always complete. | |
148 class CrashInFlightChange : public InFlightChange { | |
149 public: | |
150 CrashInFlightChange(Window* window, ChangeType type); | |
151 ~CrashInFlightChange() override; | |
152 | |
153 // InFlightChange: | |
154 void SetRevertValueFrom(const InFlightChange& change) override; | |
155 void ChangeFailed() override; | |
156 void Revert() override; | |
157 | |
158 private: | |
159 DISALLOW_COPY_AND_ASSIGN(CrashInFlightChange); | |
160 }; | |
161 | |
162 // Use this class for properties that are specific to the client, and not a | |
163 // particular window. For example, only a single window can have focus, so focus | |
164 // is specific to the client. | |
165 // | |
166 // This does not implement InFlightChange::Revert, subclasses must implement | |
167 // that to update the WindowTreeClient. | |
168 class InFlightWindowTreeClientChange : public InFlightChange, | |
169 public WindowObserver { | |
170 public: | |
171 InFlightWindowTreeClientChange(WindowTreeClient* client, | |
172 Window* revert_value, | |
173 ChangeType type); | |
174 ~InFlightWindowTreeClientChange() override; | |
175 | |
176 // InFlightChange: | |
177 void SetRevertValueFrom(const InFlightChange& change) override; | |
178 | |
179 protected: | |
180 WindowTreeClient* client() { return client_; } | |
181 Window* revert_window() { return revert_window_; } | |
182 | |
183 private: | |
184 void SetRevertWindow(Window* window); | |
185 | |
186 // WindowObserver: | |
187 void OnWindowDestroying(Window* window) override; | |
188 | |
189 WindowTreeClient* client_; | |
190 Window* revert_window_; | |
191 | |
192 DISALLOW_COPY_AND_ASSIGN(InFlightWindowTreeClientChange); | |
193 }; | |
194 | |
195 class InFlightCaptureChange : public InFlightWindowTreeClientChange { | |
196 public: | |
197 InFlightCaptureChange(WindowTreeClient* client, Window* revert_value); | |
198 ~InFlightCaptureChange() override; | |
199 | |
200 // InFlightChange: | |
201 void Revert() override; | |
202 | |
203 private: | |
204 DISALLOW_COPY_AND_ASSIGN(InFlightCaptureChange); | |
205 }; | |
206 | |
207 class InFlightFocusChange : public InFlightWindowTreeClientChange { | |
208 public: | |
209 InFlightFocusChange(WindowTreeClient* client, Window* revert_value); | |
210 ~InFlightFocusChange() override; | |
211 | |
212 // InFlightChange: | |
213 void Revert() override; | |
214 | |
215 private: | |
216 DISALLOW_COPY_AND_ASSIGN(InFlightFocusChange); | |
217 }; | |
218 | |
219 class InFlightPropertyChange : public InFlightChange { | |
220 public: | |
221 InFlightPropertyChange(Window* window, | |
222 const std::string& property_name, | |
223 const mojo::Array<uint8_t>& revert_value); | |
224 ~InFlightPropertyChange() override; | |
225 | |
226 // InFlightChange: | |
227 bool Matches(const InFlightChange& change) const override; | |
228 void SetRevertValueFrom(const InFlightChange& change) override; | |
229 void Revert() override; | |
230 | |
231 private: | |
232 const std::string property_name_; | |
233 mojo::Array<uint8_t> revert_value_; | |
234 | |
235 DISALLOW_COPY_AND_ASSIGN(InFlightPropertyChange); | |
236 }; | |
237 | |
238 class InFlightPredefinedCursorChange : public InFlightChange { | |
239 public: | |
240 InFlightPredefinedCursorChange(Window* window, mojom::Cursor revert_value); | |
241 ~InFlightPredefinedCursorChange() override; | |
242 | |
243 // InFlightChange: | |
244 void SetRevertValueFrom(const InFlightChange& change) override; | |
245 void Revert() override; | |
246 | |
247 private: | |
248 mojom::Cursor revert_cursor_; | |
249 | |
250 DISALLOW_COPY_AND_ASSIGN(InFlightPredefinedCursorChange); | |
251 }; | |
252 | |
253 class InFlightVisibleChange : public InFlightChange { | |
254 public: | |
255 InFlightVisibleChange(Window* window, const bool revert_value); | |
256 ~InFlightVisibleChange() override; | |
257 | |
258 // InFlightChange: | |
259 void SetRevertValueFrom(const InFlightChange& change) override; | |
260 void Revert() override; | |
261 | |
262 private: | |
263 bool revert_visible_; | |
264 | |
265 DISALLOW_COPY_AND_ASSIGN(InFlightVisibleChange); | |
266 }; | |
267 | |
268 class InFlightOpacityChange : public InFlightChange { | |
269 public: | |
270 InFlightOpacityChange(Window* window, float revert_value); | |
271 ~InFlightOpacityChange() override; | |
272 | |
273 // InFlightChange: | |
274 void SetRevertValueFrom(const InFlightChange& change) override; | |
275 void Revert() override; | |
276 | |
277 private: | |
278 float revert_opacity_; | |
279 | |
280 DISALLOW_COPY_AND_ASSIGN(InFlightOpacityChange); | |
281 }; | |
282 | |
283 class InFlightSetModalChange : public InFlightChange { | |
284 public: | |
285 explicit InFlightSetModalChange(Window* window); | |
286 ~InFlightSetModalChange() override; | |
287 | |
288 // InFlightChange: | |
289 void SetRevertValueFrom(const InFlightChange& change) override; | |
290 void Revert() override; | |
291 | |
292 private: | |
293 DISALLOW_COPY_AND_ASSIGN(InFlightSetModalChange); | |
294 }; | |
295 | |
296 } // namespace mus | |
297 | |
298 #endif // COMPONENTS_MUS_PUBLIC_CPP_LIB_IN_FLIGHT_CHANGE_H_ | |
OLD | NEW |