diff --git a/android/service/android_api_skeleton.cpp b/android/service/android_api_skeleton.cpp index 29fc40a..9bab40a 100644 --- a/android/service/android_api_skeleton.cpp +++ b/android/service/android_api_skeleton.cpp @@ -73,10 +73,13 @@ void AndroidApiSkeleton::launch_application(anbox::protobuf::bridge::LaunchAppli std::vector argv = { "/system/bin/am", "start", - // Launch any application always in the freeform stack - "--stack", "2", }; + if (request->has_stack()) { + argv.push_back("--stack"); + argv.push_back(std::to_string(request->stack())); + } + if (request->has_launch_bounds()) { argv.push_back("--launch-bounds"); std::stringstream launch_bounds; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f447a74..9a8fe0a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -185,12 +185,14 @@ set(SOURCES anbox/ubuntu/audio_sink.cpp anbox/dbus/interface.h + anbox/dbus/codecs.h anbox/dbus/skeleton/service.cpp anbox/dbus/skeleton/application_manager.cpp anbox/dbus/stub/application_manager.cpp anbox/application/launcher_storage.cpp anbox/application/database.cpp + anbox/application/manager.h anbox/cmds/version.cpp anbox/cmds/session_manager.cpp diff --git a/src/anbox/application/manager.h b/src/anbox/application/manager.h new file mode 100644 index 0000000..b05593b --- /dev/null +++ b/src/anbox/application/manager.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#ifndef ANBOX_APPLICATION_MANAGER_H_ +#define ANBOX_APPLICATION_MANAGER_H_ + +#include "anbox/android/intent.h" +#include "anbox/do_not_copy_or_move.h" +#include "anbox/graphics/rect.h" +#include "anbox/wm/stack.h" + +#include + +#include + +namespace anbox { +namespace application { +class Manager : public DoNotCopyOrMove { + public: + virtual void launch(const android::Intent &intent, + const graphics::Rect &launch_bounds = graphics::Rect::Invalid, + const wm::Stack::Id &stack = wm::Stack::Id::Default) = 0; + + virtual core::Property& ready() = 0; +}; + +class RestrictedManager : public Manager { + public: + RestrictedManager( + const std::shared_ptr &other, + const wm::Stack::Id &launch_stack = wm::Stack::Id::Invalid) : + other_(other), + launch_stack_(launch_stack) {} + + virtual ~RestrictedManager() {} + + void launch(const android::Intent &intent, + const graphics::Rect &launch_bounds = graphics::Rect::Invalid, + const wm::Stack::Id &stack = wm::Stack::Id::Default) override { + auto selected_stack = stack; + // If we have a static launch stack set use that one instead of + // the one the caller gave us. + if (launch_stack_ != wm::Stack::Id::Invalid) + selected_stack = launch_stack_; + other_->launch(intent, launch_bounds, selected_stack); + } + + core::Property& ready() override { return other_->ready(); } + + private: + std::shared_ptr other_; + wm::Stack::Id launch_stack_; +}; +} // namespace application +} // namespace anbox + +#endif diff --git a/src/anbox/application_manager.h b/src/anbox/application_manager.h deleted file mode 100644 index 0a21a29..0000000 --- a/src/anbox/application_manager.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2016 Simon Fels - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 3, as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - * - */ - -#ifndef ANBOX_APPLICATION_MANAGER_H_ -#define ANBOX_APPLICATION_MANAGER_H_ - -#include "anbox/android/intent.h" -#include "anbox/do_not_copy_or_move.h" -#include "anbox/graphics/rect.h" - -#include - -#include - -namespace anbox { -class ApplicationManager : public DoNotCopyOrMove { - public: - virtual void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) = 0; - virtual core::Property& ready() = 0; -}; -} // namespace anbox - -#endif diff --git a/src/anbox/bridge/android_api_stub.cpp b/src/anbox/bridge/android_api_stub.cpp index 2a471d5..4762b15 100644 --- a/src/anbox/bridge/android_api_stub.cpp +++ b/src/anbox/bridge/android_api_stub.cpp @@ -20,6 +20,7 @@ #include "anbox/logger.h" #include "anbox/rpc/channel.h" #include "anbox/utils.h" +#include "anbox/wm/stack.h" #include "anbox_bridge.pb.h" #include "anbox_rpc.pb.h" @@ -46,7 +47,8 @@ void AndroidApiStub::ensure_rpc_channel() { } void AndroidApiStub::launch(const android::Intent &intent, - const graphics::Rect &launch_bounds) { + const graphics::Rect &launch_bounds, + const wm::Stack::Id &stack) { ensure_rpc_channel(); auto c = std::make_shared>(); @@ -57,6 +59,20 @@ void AndroidApiStub::launch(const android::Intent &intent, launch_wait_handle_.expect_result(); } + switch (stack) { + case wm::Stack::Id::Default: + message.set_stack(::anbox::protobuf::bridge::LaunchApplication_Stack_DEFAULT); + break; + case wm::Stack::Id::Fullscreen: + message.set_stack(::anbox::protobuf::bridge::LaunchApplication_Stack_FULLSCREEN); + break; + case wm::Stack::Id::Freeform: + message.set_stack(::anbox::protobuf::bridge::LaunchApplication_Stack_FREEFORM); + break; + default: + break; + } + if (launch_bounds != graphics::Rect::Invalid) { auto rect = message.mutable_launch_bounds(); rect->set_left(launch_bounds_.left()); diff --git a/src/anbox/bridge/android_api_stub.h b/src/anbox/bridge/android_api_stub.h index 0bb6a5c..d95fd7b 100644 --- a/src/anbox/bridge/android_api_stub.h +++ b/src/anbox/bridge/android_api_stub.h @@ -18,7 +18,7 @@ #ifndef ANBOX_BRIDGE_ANDROID_API_STUB_H_ #define ANBOX_BRIDGE_ANDROID_API_STUB_H_ -#include "anbox/application_manager.h" +#include "anbox/application/manager.h" #include "anbox/common/wait_handle.h" #include "anbox/graphics/rect.h" @@ -35,7 +35,7 @@ namespace rpc { class Channel; } // namespace rpc namespace bridge { -class AndroidApiStub : public anbox::ApplicationManager { +class AndroidApiStub : public anbox::application::Manager { public: AndroidApiStub(); ~AndroidApiStub(); @@ -48,7 +48,10 @@ class AndroidApiStub : public anbox::ApplicationManager { void resize_task(const std::int32_t &id, const anbox::graphics::Rect &rect, const std::int32_t &resize_mode); - void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) override; + void launch(const android::Intent &intent, + const graphics::Rect &launch_bounds = graphics::Rect::Invalid, + const wm::Stack::Id &stack = wm::Stack::Id::Default) override; + core::Property& ready() override; private: diff --git a/src/anbox/cli.h b/src/anbox/cli.h index f1831ce..e398919 100644 --- a/src/anbox/cli.h +++ b/src/anbox/cli.h @@ -73,7 +73,7 @@ std::ostream& operator<<(std::ostream& out, // We are imposing size constraints to ensure a consistent CLI layout. typedef SizeConstrainedString<20> Name; typedef SizeConstrainedString<60> Usage; -typedef SizeConstrainedString<80> Description; +typedef SizeConstrainedString<100> Description; /// @brief Flag models an input parameter to a command. class Flag : public DoNotCopyOrMove { diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index 2a3671a..a73e2b6 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -50,10 +50,12 @@ anbox::cmds::Launch::Launch() flag(cli::make_flag(cli::Name{"package"}, cli::Description{"Package the intent should go to"}, intent_.package)); - flag(cli::make_flag( - cli::Name{"component"}, - cli::Description{"Component of a package the intent should go"}, - intent_.component)); + flag(cli::make_flag(cli::Name{"component"}, + cli::Description{"Component of a package the intent should go"}, + intent_.component)); + flag(cli::make_flag(cli::Name{"stack"}, + cli::Description{"Which window stack the activity should be started on. Possible: default, fullscreen, freeform"}, + stack_)); action([this](const cli::Command::Context&) { auto trap = core::posix::trap_signals_for_process({core::posix::Signal::sig_term, core::posix::Signal::sig_int}); @@ -82,7 +84,7 @@ anbox::cmds::Launch::Launch() dispatcher->dispatch([&]() { if (stub->ready()) { try { - stub->launch(intent_); + stub->launch(intent_, graphics::Rect::Invalid, stack_); success = true; } catch (std::exception &err) { ERROR("err %s", err.what()); @@ -97,7 +99,7 @@ anbox::cmds::Launch::Launch() if (!ready) return; try { - stub->launch(intent_); + stub->launch(intent_, graphics::Rect::Invalid, stack_); success = true; } catch (std::exception &err) { ERROR("Failed to launch activity: %s", err.what()); diff --git a/src/anbox/cmds/launch.h b/src/anbox/cmds/launch.h index 8ee4537..b7a6dfe 100644 --- a/src/anbox/cmds/launch.h +++ b/src/anbox/cmds/launch.h @@ -23,6 +23,7 @@ #include #include "anbox/android/intent.h" +#include "anbox/wm/stack.h" #include "anbox/cli.h" namespace anbox { @@ -33,6 +34,7 @@ class Launch : public cli::CommandWithFlagsAndAction { private: android::Intent intent_; + wm::Stack::Id stack_; }; } // namespace cmds } // namespace anbox diff --git a/src/anbox/cmds/session_manager.cpp b/src/anbox/cmds/session_manager.cpp index d6ceac8..888113d 100644 --- a/src/anbox/cmds/session_manager.cpp +++ b/src/anbox/cmds/session_manager.cpp @@ -145,6 +145,15 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) auto android_api_stub = std::make_shared(); + auto app_manager = std::static_pointer_cast(android_api_stub); + if (!single_window_) { + // When we're not running single window mode we need to restrict ourself to + // only launch applications in freeform mode as otherwise the window tracking + // doesn't work. + app_manager = std::make_shared( + android_api_stub, wm::Stack::Id::Freeform); + } + auto display_frame = graphics::Rect::Invalid; if (single_window_) display_frame = window_size_; @@ -219,7 +228,7 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) auto bus = bus_factory_(); bus->install_executor(core::dbus::asio::make_executor(bus, rt->service())); - auto skeleton = anbox::dbus::skeleton::Service::create_for_bus(bus, android_api_stub); + auto skeleton = anbox::dbus::skeleton::Service::create_for_bus(bus, app_manager); rt->start(); trap->run(); diff --git a/src/anbox/dbus/codecs.h b/src/anbox/dbus/codecs.h new file mode 100644 index 0000000..4a8459e --- /dev/null +++ b/src/anbox/dbus/codecs.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2017 Simon Fels + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + */ + +#ifndef ANBOX_DBUS_CODECS_H_ +#define ANBOX_DBUS_CODECS_H_ + +#include "anbox/wm/stack.h" + +#include + +#include + +namespace core { +namespace dbus { +template<> +struct Codec { + inline static void encode_argument(Message::Writer &out, const anbox::wm::Stack::Id &stack) { + std::stringstream ss; + ss << stack; + auto s = ss.str(); + out.push_stringn(s.c_str(), s.length()); + } + + inline static void decode_argument(Message::Reader &in, anbox::wm::Stack::Id &stack) { + std::stringstream ss; + ss << in.pop_string(); + ss >> stack; + } +}; +} // namespace dbus +} // namespace core + +#endif diff --git a/src/anbox/dbus/skeleton/application_manager.cpp b/src/anbox/dbus/skeleton/application_manager.cpp index 31ec7dc..e021a2d 100644 --- a/src/anbox/dbus/skeleton/application_manager.cpp +++ b/src/anbox/dbus/skeleton/application_manager.cpp @@ -18,6 +18,7 @@ #include "anbox/dbus/skeleton/application_manager.h" #include "anbox/android/intent.h" #include "anbox/dbus/interface.h" +#include "anbox/dbus/codecs.h" #include "anbox/logger.h" #include @@ -27,7 +28,7 @@ namespace dbus { namespace skeleton { ApplicationManager::ApplicationManager( const core::dbus::Bus::Ptr &bus, const core::dbus::Object::Ptr &object, - const std::shared_ptr &impl) + const std::shared_ptr &impl) : bus_(bus), object_(object), impl_(impl), properties_{ object_->get_property() }, signals_{ object_->get_signal() } { @@ -51,10 +52,13 @@ ApplicationManager::ApplicationManager( reader >> bottom; graphics::Rect launch_bounds{left, top, right, bottom}; + wm::Stack::Id stack = wm::Stack::Id::Default; + reader >> stack; + core::dbus::Message::Ptr reply; try { - launch(intent, launch_bounds); + launch(intent, launch_bounds, stack); reply = core::dbus::Message::make_method_return(msg); } catch (std::exception const &err) { reply = core::dbus::Message::make_error(msg, "org.anbox.Error.Failed", @@ -88,8 +92,10 @@ void ApplicationManager::on_property_value_changed(const typename Property::Valu dict, the_empty_list_of_invalidated_properties)); } -void ApplicationManager::launch(const android::Intent &intent, const graphics::Rect &launch_bounds) { - impl_->launch(intent, launch_bounds); +void ApplicationManager::launch(const android::Intent &intent, + const graphics::Rect &launch_bounds, + const wm::Stack::Id &stack) { + impl_->launch(intent, launch_bounds, stack); } core::Property& ApplicationManager::ready() { diff --git a/src/anbox/dbus/skeleton/application_manager.h b/src/anbox/dbus/skeleton/application_manager.h index c72f40b..8900815 100644 --- a/src/anbox/dbus/skeleton/application_manager.h +++ b/src/anbox/dbus/skeleton/application_manager.h @@ -18,7 +18,7 @@ #ifndef ANBOX_DBUS_SKELETON_APPLICATION_MANAGER_H_ #define ANBOX_DBUS_SKELETON_APPLICATION_MANAGER_H_ -#include "anbox/application_manager.h" +#include "anbox/application/manager.h" #include #include @@ -30,14 +30,17 @@ namespace anbox { namespace dbus { namespace skeleton { -class ApplicationManager : public anbox::ApplicationManager { +class ApplicationManager : public anbox::application::Manager { public: ApplicationManager(const core::dbus::Bus::Ptr &bus, const core::dbus::Object::Ptr &object, - const std::shared_ptr &impl); + const std::shared_ptr &impl); ~ApplicationManager(); - void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) override; + void launch(const android::Intent &intent, + const graphics::Rect &launch_bounds = graphics::Rect::Invalid, + const wm::Stack::Id &stack = wm::Stack::Id::Default) override; + core::Property& ready() override; private: @@ -47,7 +50,7 @@ class ApplicationManager : public anbox::ApplicationManager { core::dbus::Bus::Ptr bus_; core::dbus::Service::Ptr service_; core::dbus::Object::Ptr object_; - std::shared_ptr impl_; + std::shared_ptr impl_; struct { std::shared_ptr> ready; } properties_; diff --git a/src/anbox/dbus/skeleton/service.cpp b/src/anbox/dbus/skeleton/service.cpp index 75e0580..40910c1 100644 --- a/src/anbox/dbus/skeleton/service.cpp +++ b/src/anbox/dbus/skeleton/service.cpp @@ -24,7 +24,7 @@ namespace dbus { namespace skeleton { std::shared_ptr Service::create_for_bus( const core::dbus::Bus::Ptr &bus, - const std::shared_ptr &application_manager) { + const std::shared_ptr &application_manager) { auto service = core::dbus::Service::add_service( bus, anbox::dbus::interface::Service::name()); auto object = @@ -35,7 +35,7 @@ std::shared_ptr Service::create_for_bus( Service::Service( const core::dbus::Bus::Ptr &bus, const core::dbus::Service::Ptr &service, const core::dbus::Object::Ptr &object, - const std::shared_ptr &application_manager) + const std::shared_ptr &application_manager) : bus_(bus), service_(service), object_(object), diff --git a/src/anbox/dbus/skeleton/service.h b/src/anbox/dbus/skeleton/service.h index c169861..46fe8ee 100644 --- a/src/anbox/dbus/skeleton/service.h +++ b/src/anbox/dbus/skeleton/service.h @@ -18,7 +18,7 @@ #ifndef ANBOX_DBUS_SKELETON_SERVICE_H_ #define ANBOX_DBUS_SKELETON_SERVICE_H_ -#include "anbox/application_manager.h" +#include "anbox/application/manager.h" #include "anbox/do_not_copy_or_move.h" #include @@ -33,19 +33,19 @@ class Service : public DoNotCopyOrMove { public: static std::shared_ptr create_for_bus( const core::dbus::Bus::Ptr &bus, - const std::shared_ptr &application_manager); + const std::shared_ptr &application_manager); Service( const core::dbus::Bus::Ptr &bus, const core::dbus::Service::Ptr &service, const core::dbus::Object::Ptr &object, - const std::shared_ptr &application_manager); + const std::shared_ptr &application_manager); ~Service(); private: core::dbus::Bus::Ptr bus_; core::dbus::Service::Ptr service_; core::dbus::Object::Ptr object_; - std::shared_ptr application_manager_; + std::shared_ptr application_manager_; }; } // namespace skeleton } // namespace dbus diff --git a/src/anbox/dbus/stub/application_manager.cpp b/src/anbox/dbus/stub/application_manager.cpp index ec4b21e..e11176f 100644 --- a/src/anbox/dbus/stub/application_manager.cpp +++ b/src/anbox/dbus/stub/application_manager.cpp @@ -17,6 +17,7 @@ #include "anbox/dbus/stub/application_manager.h" #include "anbox/dbus/interface.h" +#include "anbox/dbus/codecs.h" #include "anbox/logger.h" namespace anbox { @@ -41,13 +42,15 @@ ApplicationManager::ApplicationManager(const core::dbus::Bus::Ptr &bus, ApplicationManager::~ApplicationManager() {} -void ApplicationManager::launch(const android::Intent &intent, const graphics::Rect &launch_bounds) { +void ApplicationManager::launch(const android::Intent &intent, + const graphics::Rect &launch_bounds, + const wm::Stack::Id &stack) { auto result = object_->invoke_method_synchronously< anbox::dbus::interface::ApplicationManager::Methods::Launch, anbox::dbus::interface::ApplicationManager::Methods::Launch::ResultType>( intent.action, intent.uri, intent.type, intent.flags, intent.package, intent.component, launch_bounds.left(), launch_bounds.top(), - launch_bounds.right(), launch_bounds.bottom()); + launch_bounds.right(), launch_bounds.bottom(), stack); if (result.is_error()) throw std::runtime_error(result.error().print()); } diff --git a/src/anbox/dbus/stub/application_manager.h b/src/anbox/dbus/stub/application_manager.h index bb44358..f70a93b 100644 --- a/src/anbox/dbus/stub/application_manager.h +++ b/src/anbox/dbus/stub/application_manager.h @@ -18,7 +18,7 @@ #ifndef ANBOX_DBUS_SKELETON_APPLICATION_MANAGER_H_ #define ANBOX_DBUS_SKELETON_APPLICATION_MANAGER_H_ -#include "anbox/application_manager.h" +#include "anbox/application/manager.h" #include #include @@ -29,7 +29,7 @@ namespace anbox { namespace dbus { namespace stub { -class ApplicationManager : public anbox::ApplicationManager { +class ApplicationManager : public anbox::application::Manager { public: static std::shared_ptr create_for_bus( const core::dbus::Bus::Ptr &bus); @@ -39,7 +39,10 @@ class ApplicationManager : public anbox::ApplicationManager { const core::dbus::Object::Ptr &object); ~ApplicationManager(); - void launch(const android::Intent &intent, const graphics::Rect &launch_bounds = graphics::Rect::Invalid) override; + void launch(const android::Intent &intent, + const graphics::Rect &launch_bounds = graphics::Rect::Invalid, + const wm::Stack::Id &stack = wm::Stack::Id::Default) override; + core::Property& ready() override; private: diff --git a/src/anbox/protobuf/anbox_bridge.proto b/src/anbox/protobuf/anbox_bridge.proto index 11bde22..993ae5e 100644 --- a/src/anbox/protobuf/anbox_bridge.proto +++ b/src/anbox/protobuf/anbox_bridge.proto @@ -34,6 +34,12 @@ message Notification { message LaunchApplication { required Intent intent = 1; optional Rect launch_bounds = 2; + enum Stack { + DEFAULT = 0; + FULLSCREEN = 1; + FREEFORM = 2; + } + optional Stack stack = 3 [default = DEFAULT]; } message SetFocusedTask { diff --git a/src/anbox/wm/multi_window_manager.cpp b/src/anbox/wm/multi_window_manager.cpp index 76c049d..0b45ad5 100644 --- a/src/anbox/wm/multi_window_manager.cpp +++ b/src/anbox/wm/multi_window_manager.cpp @@ -44,7 +44,7 @@ void MultiWindowManager::apply_window_state_update(const WindowState::List &upda for (const auto &window : updated) { // Ignore all windows which are not part of the freeform task stack - if (window.stack() != Stack::Freeform) continue; + if (window.stack() != Stack::Id::Freeform) continue; // And also those which don't have a surface mapped at the moment if (!window.has_surface()) continue; diff --git a/src/anbox/wm/stack.cpp b/src/anbox/wm/stack.cpp index 009a860..800850d 100644 --- a/src/anbox/wm/stack.cpp +++ b/src/anbox/wm/stack.cpp @@ -19,9 +19,33 @@ namespace anbox { namespace wm { -Stack::Id Stack::Invalid = -1; -Stack::Id Stack::Default = 0; -Stack::Id Stack::Fullscreen = 1; -Stack::Id Stack::Freeform = 2; +std::ostream &operator<<(std::ostream &out, const Stack::Id &stack) { + switch (stack) { + case anbox::wm::Stack::Id::Default: + out << "default"; + break; + case anbox::wm::Stack::Id::Fullscreen: + out << "fullscreen"; + break; + case anbox::wm::Stack::Id::Freeform: + out << "freeform"; + break; + default: + break; + } + return out; +} + +std::istream& operator>>(std::istream& in, Stack::Id &stack) { + std::string s; + in >> s; + if (s == "default") + stack = anbox::wm::Stack::Id::Default; + else if (s == "fullscreen") + stack = anbox::wm::Stack::Id::Fullscreen; + else if (s == "freeform") + stack = anbox::wm::Stack::Id::Freeform; + return in; +} } // namespace wm } // namespace anbox diff --git a/src/anbox/wm/stack.h b/src/anbox/wm/stack.h index 092b29d..6716317 100644 --- a/src/anbox/wm/stack.h +++ b/src/anbox/wm/stack.h @@ -18,23 +18,28 @@ #ifndef ANBOX_WM_STACK_H_ #define ANBOX_WM_STACK_H_ -#include +#include namespace anbox { namespace wm { class Stack { public: - typedef std::int32_t Id; - - static Id Invalid; - static Id Default; - static Id Fullscreen; - static Id Freeform; + enum class Id { + Invalid = -1, + Default = 0, + Fullscreen = 1, + Freeform = 2, + }; Stack() = delete; Stack(const Stack&) = delete; }; + +std::ostream& operator<<(std::ostream &out, Stack::Id const &stack); +std::istream& operator>>(std::istream &in, Stack::Id &stack); } // namespace wm } // namespace anbox + + #endif diff --git a/src/anbox/wm/window_state.cpp b/src/anbox/wm/window_state.cpp index d5b1494..e35b83c 100644 --- a/src/anbox/wm/window_state.cpp +++ b/src/anbox/wm/window_state.cpp @@ -25,7 +25,7 @@ WindowState::WindowState() frame_(graphics::Rect::Invalid), package_name_(""), task_(Task::Invalid), - stack_(Stack::Invalid) {} + stack_(Stack::Id::Invalid) {} WindowState::WindowState(const Display::Id &display, bool has_surface, const graphics::Rect &frame, diff --git a/tests/anbox/graphics/layer_composer_tests.cpp b/tests/anbox/graphics/layer_composer_tests.cpp index 7a4b427..c99801b 100644 --- a/tests/anbox/graphics/layer_composer_tests.cpp +++ b/tests/anbox/graphics/layer_composer_tests.cpp @@ -55,7 +55,7 @@ TEST(LayerComposer, FindsNoSuitableWindowForLayer) { graphics::Rect{0, 0, 1024, 768}, "org.anbox.test.1", wm::Task::Id{1}, - wm::Stack::Freeform, + wm::Stack::Id::Freeform, }; wm->apply_window_state_update({single_window}, {}); @@ -89,7 +89,7 @@ TEST(LayerComposer, MapsLayersToWindows) { graphics::Rect{0, 0, 1024, 768}, "org.anbox.foo", wm::Task::Id{1}, - wm::Stack::Freeform, + wm::Stack::Id::Freeform, }; auto second_window = wm::WindowState{ @@ -98,7 +98,7 @@ TEST(LayerComposer, MapsLayersToWindows) { graphics::Rect{300, 400, 1324, 1168}, "org.anbox.bar", wm::Task::Id{2}, - wm::Stack::Freeform, + wm::Stack::Id::Freeform, }; wm->apply_window_state_update({first_window, second_window}, {}); @@ -149,7 +149,7 @@ TEST(LayerComposer, WindowPartiallyOffscreen) { graphics::Rect{-100, -100, 924, 668}, "org.anbox.foo", wm::Task::Id{1}, - wm::Stack::Freeform, + wm::Stack::Id::Freeform, }; wm->apply_window_state_update({window}, {}); @@ -194,7 +194,7 @@ TEST(LayerComposer, PopupShouldNotCauseWindowLayerOffset) { graphics::Rect{1120, 270, 2144, 1038}, "org.anbox.foo", wm::Task::Id{3}, - wm::Stack::Freeform, + wm::Stack::Id::Freeform, }; wm->apply_window_state_update({window}, {});