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