// Copyright 2014 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 "components/mus/ws/test_change_tracker.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "components/mus/public/cpp/util.h" #include "mojo/common/common_type_converters.h" using mojo::Array; using mojo::String; namespace mus { namespace ws { std::string WindowIdToString(Id id) { return (id == 0) ? "null" : base::StringPrintf("%d,%d", HiWord(id), LoWord(id)); } namespace { std::string RectToString(const mojo::Rect& rect) { return base::StringPrintf("%d,%d %dx%d", rect.x, rect.y, rect.width, rect.height); } std::string DirectionToString(mojom::OrderDirection direction) { return direction == mojom::ORDER_DIRECTION_ABOVE ? "above" : "below"; } std::string ChangeToDescription1(const Change& change) { switch (change.type) { case CHANGE_TYPE_EMBED: return "OnEmbed"; case CHANGE_TYPE_EMBEDDED_APP_DISCONNECTED: return base::StringPrintf("OnEmbeddedAppDisconnected window=%s", WindowIdToString(change.window_id).c_str()); case CHANGE_TYPE_UNEMBED: return "OnUnembed"; case CHANGE_TYPE_NODE_BOUNDS_CHANGED: return base::StringPrintf( "BoundsChanged window=%s old_bounds=%s new_bounds=%s", WindowIdToString(change.window_id).c_str(), RectToString(change.bounds).c_str(), RectToString(change.bounds2).c_str()); case CHANGE_TYPE_NODE_VIEWPORT_METRICS_CHANGED: // TODO(sky): Not implemented. return "ViewportMetricsChanged"; case CHANGE_TYPE_NODE_HIERARCHY_CHANGED: return base::StringPrintf( "HierarchyChanged window=%s new_parent=%s old_parent=%s", WindowIdToString(change.window_id).c_str(), WindowIdToString(change.window_id2).c_str(), WindowIdToString(change.window_id3).c_str()); case CHANGE_TYPE_NODE_REORDERED: return base::StringPrintf("Reordered window=%s relative=%s direction=%s", WindowIdToString(change.window_id).c_str(), WindowIdToString(change.window_id2).c_str(), DirectionToString(change.direction).c_str()); case CHANGE_TYPE_NODE_DELETED: return base::StringPrintf("WindowDeleted window=%s", WindowIdToString(change.window_id).c_str()); case CHANGE_TYPE_NODE_VISIBILITY_CHANGED: return base::StringPrintf("VisibilityChanged window=%s visible=%s", WindowIdToString(change.window_id).c_str(), change.bool_value ? "true" : "false"); case CHANGE_TYPE_NODE_DRAWN_STATE_CHANGED: return base::StringPrintf("DrawnStateChanged window=%s drawn=%s", WindowIdToString(change.window_id).c_str(), change.bool_value ? "true" : "false"); case CHANGE_TYPE_INPUT_EVENT: return base::StringPrintf("InputEvent window=%s event_action=%d", WindowIdToString(change.window_id).c_str(), change.event_action); case CHANGE_TYPE_PROPERTY_CHANGED: return base::StringPrintf("PropertyChanged window=%s key=%s value=%s", WindowIdToString(change.window_id).c_str(), change.property_key.c_str(), change.property_value.c_str()); case CHANGE_TYPE_DELEGATE_EMBED: return base::StringPrintf("DelegateEmbed url=%s", change.embed_url.data()); case CHANGE_TYPE_FOCUSED: return base::StringPrintf("Focused id=%s", WindowIdToString(change.window_id).c_str()); } return std::string(); } } // namespace std::vector ChangesToDescription1( const std::vector& changes) { std::vector strings(changes.size()); for (size_t i = 0; i < changes.size(); ++i) strings[i] = ChangeToDescription1(changes[i]); return strings; } std::string SingleChangeToDescription(const std::vector& changes) { std::string result; for (auto& change : changes) { if (!result.empty()) result += "\n"; result += ChangeToDescription1(change); } return result; } std::string SingleWindowDescription(const std::vector& windows) { if (windows.size() != 1u) return "more than one changes and expected only one"; return windows[0].ToString(); } std::string ChangeWindowDescription(const std::vector& changes) { if (changes.size() != 1) return std::string(); std::vector window_strings(changes[0].windows.size()); for (size_t i = 0; i < changes[0].windows.size(); ++i) window_strings[i] = "[" + changes[0].windows[i].ToString() + "]"; return base::JoinString(window_strings, ","); } TestWindow WindowDataToTestWindow(const mojom::WindowDataPtr& data) { TestWindow window; window.parent_id = data->parent_id; window.window_id = data->window_id; window.visible = data->visible; window.drawn = data->drawn; window.properties = data->properties.To>>(); return window; } void WindowDatasToTestWindows(const Array& data, std::vector* test_windows) { for (size_t i = 0; i < data.size(); ++i) test_windows->push_back(WindowDataToTestWindow(data[i])); } Change::Change() : type(CHANGE_TYPE_EMBED), connection_id(0), window_id(0), window_id2(0), window_id3(0), event_action(0), direction(mojom::ORDER_DIRECTION_ABOVE), bool_value(false) {} Change::~Change() {} TestChangeTracker::TestChangeTracker() : delegate_(NULL) {} TestChangeTracker::~TestChangeTracker() {} void TestChangeTracker::OnEmbed(ConnectionSpecificId connection_id, mojom::WindowDataPtr root) { Change change; change.type = CHANGE_TYPE_EMBED; change.connection_id = connection_id; change.windows.push_back(WindowDataToTestWindow(root)); AddChange(change); } void TestChangeTracker::OnEmbeddedAppDisconnected(Id window_id) { Change change; change.type = CHANGE_TYPE_EMBEDDED_APP_DISCONNECTED; change.window_id = window_id; AddChange(change); } void TestChangeTracker::OnWindowBoundsChanged(Id window_id, mojo::RectPtr old_bounds, mojo::RectPtr new_bounds) { Change change; change.type = CHANGE_TYPE_NODE_BOUNDS_CHANGED; change.window_id = window_id; change.bounds.x = old_bounds->x; change.bounds.y = old_bounds->y; change.bounds.width = old_bounds->width; change.bounds.height = old_bounds->height; change.bounds2.x = new_bounds->x; change.bounds2.y = new_bounds->y; change.bounds2.width = new_bounds->width; change.bounds2.height = new_bounds->height; AddChange(change); } void TestChangeTracker::OnUnembed() { Change change; change.type = CHANGE_TYPE_UNEMBED; AddChange(change); } void TestChangeTracker::OnWindowViewportMetricsChanged( mojom::ViewportMetricsPtr old_metrics, mojom::ViewportMetricsPtr new_metrics) { Change change; change.type = CHANGE_TYPE_NODE_VIEWPORT_METRICS_CHANGED; // NOT IMPLEMENTED AddChange(change); } void TestChangeTracker::OnWindowHierarchyChanged( Id window_id, Id new_parent_id, Id old_parent_id, Array windows) { Change change; change.type = CHANGE_TYPE_NODE_HIERARCHY_CHANGED; change.window_id = window_id; change.window_id2 = new_parent_id; change.window_id3 = old_parent_id; WindowDatasToTestWindows(windows, &change.windows); AddChange(change); } void TestChangeTracker::OnWindowReordered(Id window_id, Id relative_window_id, mojom::OrderDirection direction) { Change change; change.type = CHANGE_TYPE_NODE_REORDERED; change.window_id = window_id; change.window_id2 = relative_window_id; change.direction = direction; AddChange(change); } void TestChangeTracker::OnWindowDeleted(Id window_id) { Change change; change.type = CHANGE_TYPE_NODE_DELETED; change.window_id = window_id; AddChange(change); } void TestChangeTracker::OnWindowVisibilityChanged(Id window_id, bool visible) { Change change; change.type = CHANGE_TYPE_NODE_VISIBILITY_CHANGED; change.window_id = window_id; change.bool_value = visible; AddChange(change); } void TestChangeTracker::OnWindowDrawnStateChanged(Id window_id, bool drawn) { Change change; change.type = CHANGE_TYPE_NODE_DRAWN_STATE_CHANGED; change.window_id = window_id; change.bool_value = drawn; AddChange(change); } void TestChangeTracker::OnWindowInputEvent(Id window_id, mojom::EventPtr event) { Change change; change.type = CHANGE_TYPE_INPUT_EVENT; change.window_id = window_id; change.event_action = event->action; AddChange(change); } void TestChangeTracker::OnWindowSharedPropertyChanged(Id window_id, String name, Array data) { Change change; change.type = CHANGE_TYPE_PROPERTY_CHANGED; change.window_id = window_id; change.property_key = name; if (data.is_null()) change.property_value = "NULL"; else change.property_value = data.To(); AddChange(change); } void TestChangeTracker::OnWindowFocused(Id window_id) { Change change; change.type = CHANGE_TYPE_FOCUSED; change.window_id = window_id; AddChange(change); } void TestChangeTracker::DelegateEmbed(const String& url) { Change change; change.type = CHANGE_TYPE_DELEGATE_EMBED; change.embed_url = url; AddChange(change); } void TestChangeTracker::AddChange(const Change& change) { changes_.push_back(change); if (delegate_) delegate_->OnChangeAdded(); } TestWindow::TestWindow() {} TestWindow::~TestWindow() {} std::string TestWindow::ToString() const { return base::StringPrintf("window=%s parent=%s", WindowIdToString(window_id).c_str(), WindowIdToString(parent_id).c_str()); } std::string TestWindow::ToString2() const { return base::StringPrintf( "window=%s parent=%s visible=%s drawn=%s", WindowIdToString(window_id).c_str(), WindowIdToString(parent_id).c_str(), visible ? "true" : "false", drawn ? "true" : "false"); } } // namespace ws } // namespace mus