From 81d166e4e60beba3bee6c6e45e1e2c79f5cb5749 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 21 Apr 2017 07:22:01 +0200 Subject: [PATCH 01/86] Add in-snap path to nvidia driver binaries to LD_LIBRARY_PATH --- scripts/snap-wrapper.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scripts/snap-wrapper.sh b/scripts/snap-wrapper.sh index 0122ad3..0ca2d83 100755 --- a/scripts/snap-wrapper.sh +++ b/scripts/snap-wrapper.sh @@ -29,6 +29,12 @@ export LIBGL_DRIVERS_PATH=$SNAP/usr/lib/$ARCH/dri # ensure the snappy gl libs win export LD_LIBRARY_PATH="$SNAP_LIBRARY_PATH:$LD_LIBRARY_PATH" +# Workaround in snapd for proprietary nVidia drivers mounts the drivers in +# /var/lib/snapd/lib/gl that needs to be in LD_LIBRARY_PATH +# Without that OpenGL using apps do not work with the nVidia drivers. +# Ref.: https://bugs.launchpad.net/snappy/+bug/1588192 +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/var/lib/snapd/lib/gl + # We set XDG_DATA_HOME to SNAP_USER_COMMON here as this will be the location we will # create all our application launchers in. The system application launcher will # be configured by our installer to look into this directory for available From df7ae21541a3315de99dbc5a769ed06f909e77a2 Mon Sep 17 00:00:00 2001 From: hub2git Date: Sat, 22 Apr 2017 19:53:14 -0700 Subject: [PATCH 02/86] Update ISSUE_TEMPLATE.md 1. A few people don't know what to do with line 6 (the line I changed). See, for example: https://github.com/anbox/anbox/issues/157 https://github.com/anbox/anbox/issues/159 https://github.com/anbox/anbox/issues/141 https://github.com/anbox/anbox/issues/132 2. Since [anbox system-info] prints the version number, we don't need to ask people to do [anbox version]. 3. Changed wordings of the other "section titles". --- .github/ISSUE_TEMPLATE.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 6c04d72..1881bb6 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,15 +1,16 @@ Make sure you are running the latest version of Anbox before reporting an issue. -Please also check that no similar bug is already reported. Have a look on the -list of open bugs at https://github.com/anbox/anbox/issues +Please also check that no similar bug is already reported. Have a look on the list of open bugs at https://github.com/anbox/anbox/issues -**Anbox release (`anbox version`) and system info (`anbox system-info`):** +** Please paste the result of `anbox system-info` below:** +``` +[please paste printout of `anbox system-info` here] +``` + +**Please describe your problem:** -**Description of the problem:** - - -**Expected:** +**What were you expecting?:** **Additional info:** From fd18da0d091cf7f3ace407b1650a37615ced8167 Mon Sep 17 00:00:00 2001 From: hub2git Date: Sat, 22 Apr 2017 20:04:30 -0700 Subject: [PATCH 03/86] From one newbie to other newbies... I'm a newbie. I reckon most people on github aren't. But in the off-chance that the rare newbie visits, I think it's good to have a simple statement about Anbox that a newbie could understand. Hence my suggested change. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6061a09..956f403 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Anbox -Anbox is container based approach to boot a full Android system on a -regular GNU Linux system like Ubuntu. +Anbox is container based approach to boot a full Android system on a regular GNU Linux system like Ubuntu. +In newbie terms: Anbox will let you run Android on your Linux without the slowness of virtualization. ## Overview From 2792942ca2ef0ee4c3398c10152ecd4aef56486f Mon Sep 17 00:00:00 2001 From: Jonathan Date: Sun, 23 Apr 2017 11:52:00 +0200 Subject: [PATCH 04/86] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6061a09..bf1132a 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ # Anbox -Anbox is container based approach to boot a full Android system on a -regular GNU Linux system like Ubuntu. +Anbox is container-based approach to boot a full Android system on a +regular GNU/Linux system like Ubuntu. ## Overview Anbox uses Linux namespaces (user, pid, uts, net, mount, ipc) to run a full Android system in a container and provide Android applications on -any GNU Linux based platform. +any GNU/Linux-based platform. The Android inside the container has no direct access to any hardware. All hardware access is going through the anbox daemon on the host. We're -reusing what Android implemented within the QEMU based emulator for Open -GL ES accelerated rendering. The Android system inside the container uses +reusing what Android implemented within the QEMU-based emulator for OpenGL +ES accelerated rendering. The Android system inside the container uses different pipes to communicate with the host system and sends all hardware access commands through these. @@ -170,7 +170,7 @@ Running Anbox from a local build requires a few more things you need to know about. Please have a look at the ["Runtime Setup"](docs/runtime-setup.md) documentation. -## documentation +## Documentation You will find additional documentation for Anbox in the *docs* subdirectory of the project source. @@ -187,7 +187,7 @@ If you have found an issue with Anbox, please [file a bug](https://github.com/an ## Get in Touch If you want to get in contact with the developers please feel free to join the -*#anbox* IRC channel on [FreeNode](https://freenode.net/). +*#anbox* IRC channel on [Freenode](https://freenode.net/). ## Copyright and Licensing @@ -195,5 +195,5 @@ Anbox reuses code from other projects like the Android QEMU emulator. These projects are available in the external/ subdirectory with the licensing terms included. -The anbox source itself, if not stated differently in the relevant source files, +The Anbox source itself, if not stated differently in the relevant source files, is licensed under the terms of the GPLv3 license. From 978e13d19a893831d859bf68a5984993ba279973 Mon Sep 17 00:00:00 2001 From: hub2git Date: Sun, 23 Apr 2017 12:46:14 -0700 Subject: [PATCH 05/86] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf1132a..e1c0e6c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Anbox -Anbox is container-based approach to boot a full Android system on a +Anbox is a container-based approach to boot a full Android system on a regular GNU/Linux system like Ubuntu. ## Overview From cf87aec563843e2f6e8d7ba98c2ac613e8aaf2e0 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 26 Apr 2017 08:25:29 +0200 Subject: [PATCH 06/86] Install additional dbus-user-session package This gives us all necessary things like DISPLAY or XAUTHORITY within the environment for a service started by systemd --user --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 8696f8e..c5fc412 100644 --- a/debian/control +++ b/debian/control @@ -10,7 +10,7 @@ Vcs-Git: https://github.com/anbox/anbox.git Package: anbox-common Architecture: all -Depends: ${misc:Depends} +Depends: ${misc:Depends} dbus-user-session Description: Common files necessary for Anbox . This package contains necessary things which can't be shipped From 6c782cffc188df7bd764f2e3519b9f71ceb83f7f Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 26 Apr 2017 08:26:25 +0200 Subject: [PATCH 07/86] Activate anbox service for the systemd user session --- debian/rules | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/rules b/debian/rules index b141034..85b38d1 100755 --- a/debian/rules +++ b/debian/rules @@ -28,8 +28,9 @@ override_dh_install: install -d $(CURDIR)/debian/tmp/etc/modules-load.d install -m 0644 kernel/anbox.conf $(CURDIR)/debian/tmp/etc/modules-load.d - install -d $(CURDIR)/debian/tmp/usr/lib/systemd/user/ + install -d $(CURDIR)/debian/tmp/usr/lib/systemd/user/default.target.wants install -m 0644 data/anbox.service $(CURDIR)/debian/tmp/usr/lib/systemd/user/ + ln -sf /usr/lib/systemd/user/anbox.service $(CURDIR)/debian/tmp/usr/lib/systemd/user/default.target.wants/anbox.service install -d $(CURDIR)/debian/tmp/usr/share/upstart/sessions/ install -m 0644 data/anbox.conf $(CURDIR)/debian/tmp/usr/share/upstart/sessions/ From c993eb3033b35974cb8539084af561b7ca325728 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 26 Apr 2017 08:31:49 +0200 Subject: [PATCH 08/86] debian: add missing comma in Depends: --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index c5fc412..9dfb528 100644 --- a/debian/control +++ b/debian/control @@ -10,7 +10,7 @@ Vcs-Git: https://github.com/anbox/anbox.git Package: anbox-common Architecture: all -Depends: ${misc:Depends} dbus-user-session +Depends: ${misc:Depends}, dbus-user-session Description: Common files necessary for Anbox . This package contains necessary things which can't be shipped From 7f41e1a90946cdc5914f09e6058673d5640bc151 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 26 Apr 2017 08:43:15 +0200 Subject: [PATCH 09/86] Always try to restart anbox session service when it crashes --- data/anbox.service.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/anbox.service.in b/data/anbox.service.in index 933b4d1..7cdd14f 100644 --- a/data/anbox.service.in +++ b/data/anbox.service.in @@ -2,7 +2,11 @@ Description=Anbox session manager [Service] +Type=simple ExecStart=@SNAP_MOUNT_DIR@/anbox session-manager +Restart=always +StartLimitIntervalSec=3 +StartLimitBurst=1 [Install] WantedBy=default.target From fd615c3989299cabb00d3afc9227aea65ae9953a Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 26 Apr 2017 19:31:17 +0200 Subject: [PATCH 10/86] Add kernel patches to add namespace support to binder --- ...generic-per-ipc-pointer-and-peripc_o.patch | 185 ++++++++ ...-namepsace-support-for-Android-binde.patch | 428 ++++++++++++++++++ 2 files changed, 613 insertions(+) create mode 100644 kernel/patches/0001-ipc-namespace-a-generic-per-ipc-pointer-and-peripc_o.patch create mode 100644 kernel/patches/0002-binder-implement-namepsace-support-for-Android-binde.patch diff --git a/kernel/patches/0001-ipc-namespace-a-generic-per-ipc-pointer-and-peripc_o.patch b/kernel/patches/0001-ipc-namespace-a-generic-per-ipc-pointer-and-peripc_o.patch new file mode 100644 index 0000000..0acd5e9 --- /dev/null +++ b/kernel/patches/0001-ipc-namespace-a-generic-per-ipc-pointer-and-peripc_o.patch @@ -0,0 +1,185 @@ +From 8f8ac2552c4a411cf1b8c6328409f861248e8d0d Mon Sep 17 00:00:00 2001 +From: Oren Laadan +Date: Sun, 22 Dec 2013 10:07:39 +0000 +Subject: [PATCH 1/2] ipc namespace: a generic per-ipc pointer and peripc_ops + +Add a void * pointer to struct ipc_namespace. The access rules are: +1. (un)register ops with (un)register_peripc_operations() +2. call ipc_assign_generic() to put private data on the ipc_namespace +3. call ipc_access_generic() to access the private data +4. do not change the pointer during the lifetime of ipc_namespace + +Modeled after generic net-ns pointers (commit dec827d), but simplified +to accommodate a single user for now (reduce code churn): +5. only one caller can register at a time +6. caller must register at boot time (not to be used by modules) + +Signed-off-by: Oren Laadan +Signed-off-by: Amir Goldstein +--- + include/linux/ipc_namespace.h | 29 +++++++++++++++++++++ + ipc/namespace.c | 9 +++++++ + ipc/util.c | 60 +++++++++++++++++++++++++++++++++++++++++++ + ipc/util.h | 3 +++ + 4 files changed, 101 insertions(+) + +diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h +index d6ad91f..535061a 100644 +--- a/include/linux/ipc_namespace.h ++++ b/include/linux/ipc_namespace.h +@@ -70,8 +70,37 @@ struct ipc_namespace { + struct user_namespace *user_ns; + + unsigned int proc_inum; ++ ++ /* allow others to piggyback on ipc_namesspaces */ ++ void *gen; /* for others' private stuff */ + }; + ++/* ++ * To access to the per-ipc generic data: ++ * 1. (un)register ops with (un)register_peripc_operations() ++ * 2. call ipc_assign_generic() to put private data on the ipc_namespace ++ * 3. call ipc_access_generic() to access the private data ++ * 4. do not change the pointer during the lifetime of ipc_namespace ++ * ++ * Modeled after generic net-ns pointers (commit dec827d), simplified for ++ * a single user case for now: ++ * 5. only one caller can register at a time ++ * 6. caller must register at boot time (not to be used by modules) ++ */ ++struct peripc_operations { ++ int (*init)(struct ipc_namespace *); ++ void (*exit)(struct ipc_namespace *); ++}; ++ ++static inline void ipc_assign_generic(struct ipc_namespace *ns, void *data) ++{ ns->gen = data; } ++ ++static inline void *ipc_access_generic(struct ipc_namespace *ns) ++{ return ns->gen; } ++ ++extern int register_peripc_ops(struct peripc_operations *ops); ++extern void unregister_peripc_ops(struct peripc_operations *ops); ++ + extern struct ipc_namespace init_ipc_ns; + extern atomic_t nr_ipc_ns; + +diff --git a/ipc/namespace.c b/ipc/namespace.c +index aba9a58..575aeae 100644 +--- a/ipc/namespace.c ++++ b/ipc/namespace.c +@@ -33,9 +33,17 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns, + } + + atomic_set(&ns->count, 1); ++ ++ err = init_peripc_ns(ns); ++ if (err) { ++ kfree(ns); ++ return ERR_PTR(err); ++ } ++ + err = mq_init_ns(ns); + if (err) { + proc_free_inum(ns->proc_inum); ++ exit_peripc_ns(ns); + kfree(ns); + return ERR_PTR(err); + } +@@ -111,6 +119,7 @@ static void free_ipc_ns(struct ipc_namespace *ns) + sem_exit_ns(ns); + msg_exit_ns(ns); + shm_exit_ns(ns); ++ exit_peripc_ns(ns); + atomic_dec(&nr_ipc_ns); + + /* +diff --git a/ipc/util.c b/ipc/util.c +index 7353425..533f8f9 100644 +--- a/ipc/util.c ++++ b/ipc/util.c +@@ -71,6 +71,66 @@ struct ipc_proc_iface { + int (*show)(struct seq_file *, void *); + }; + ++/* allow others to piggyback on ipc_namespace */ ++static DEFINE_MUTEX(peripc_mutex); ++static struct peripc_operations *peripc_ops; ++ ++/* ++ * peripc_operations is a simplified pernet_operations: ++ * - allow only one entity to register ++ * - allow to register only at boot time (no modules) ++ * (these assumptions make the code much simpler) ++ */ ++ ++static int init_peripc_count; ++ ++/* caller hold peripc_mutex */ ++int init_peripc_ns(struct ipc_namespace *ns) ++{ ++ int ret = 0; ++ ++ if (peripc_ops && peripc_ops->init) ++ ret = peripc_ops->init(ns); ++ if (ret == 0) ++ init_peripc_count++; ++ return ret; ++} ++ ++/* caller hold peripc_mutex */ ++void exit_peripc_ns(struct ipc_namespace *ns) ++{ ++ if (peripc_ops && peripc_ops->exit) ++ peripc_ops->exit(ns); ++ init_peripc_count--; ++} ++ ++int register_peripc_ops(struct peripc_operations *ops) ++{ ++ int ret = -EBUSY; ++ ++ mutex_lock(&peripc_mutex); ++ /* must be first register, and only init ipc_namespace exists */ ++ if (peripc_ops == NULL && init_peripc_count == 0) { ++ peripc_ops = ops; ++ ret = init_peripc_ns(&init_ipc_ns); ++ if (ret < 0) ++ peripc_ops = NULL; ++ } ++ mutex_unlock(&peripc_mutex); ++ return ret; ++} ++ ++void unregister_peripc_ops(struct peripc_operations *ops) ++{ ++ mutex_lock(&peripc_mutex); ++ /* sanity: be same as registered, and no other ipc ns (beyond init) */ ++ BUG_ON(peripc_ops != ops); ++ BUG_ON(init_peripc_count != 1); ++ if (ops->exit) ++ exit_peripc_ns(&init_ipc_ns); ++ peripc_ops = NULL; ++ mutex_unlock(&peripc_mutex); ++} + static void ipc_memory_notifier(struct work_struct *work) + { + ipcns_notify(IPCNS_MEMCHANGED); +diff --git a/ipc/util.h b/ipc/util.h +index 59d78aa..daee0be 100644 +--- a/ipc/util.h ++++ b/ipc/util.h +@@ -47,6 +47,9 @@ static inline void msg_exit_ns(struct ipc_namespace *ns) { } + static inline void shm_exit_ns(struct ipc_namespace *ns) { } + #endif + ++int init_peripc_ns(struct ipc_namespace *ns); ++void exit_peripc_ns(struct ipc_namespace *ns); ++ + struct ipc_rcu { + struct rcu_head rcu; + atomic_t refcount; +-- +2.7.4 + diff --git a/kernel/patches/0002-binder-implement-namepsace-support-for-Android-binde.patch b/kernel/patches/0002-binder-implement-namepsace-support-for-Android-binde.patch new file mode 100644 index 0000000..74595a0 --- /dev/null +++ b/kernel/patches/0002-binder-implement-namepsace-support-for-Android-binde.patch @@ -0,0 +1,428 @@ +From fcd9d70190dd7e6536878a6379122f06e3b90919 Mon Sep 17 00:00:00 2001 +From: Oren Laadan +Date: Sun, 22 Dec 2013 10:07:40 +0000 +Subject: [PATCH 2/2] binder: implement namepsace support for Android binder + driver + +Add namespaces support for the Android binder driver. +As binder is an IPC mechanism, tie its namespace to IPC_NS. + +In binder, the first process to call BINDER_SET_CONTEXT_MGR ioctl +becomes the manager with context 0, and thereafter IPC is realized +through binder handles obtained from this manager. + +For namespaces, associate a separate binder state with each namespace +so each namespace has its own context manager. Binder users within a +namespace interact only with the context manager there. This suffices +because binder does not allow IPC not via the context manager. + +Currently, statistics remain global, except for the list of processes +that hold an open binder device (reported per namespace). + +Signed-off-by: Oren Laadan +Acked-by: Amir Goldstein +--- + drivers/android/Kconfig | 1 + + drivers/android/binder.c | 172 ++++++++++++++++++++++++++++++++++++++--------- + 2 files changed, 143 insertions(+), 30 deletions(-) + +diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig +index bdfc6c6..739063d 100644 +--- a/drivers/android/Kconfig ++++ b/drivers/android/Kconfig +@@ -10,6 +10,7 @@ if ANDROID + config ANDROID_BINDER_IPC + bool "Android Binder IPC Driver" + depends on MMU ++ select SYSVIPC + default n + ---help--- + Binder is used in Android for both communication between processes, +diff --git a/drivers/android/binder.c b/drivers/android/binder.c +index fee479d..2a63e9b 100644 +--- a/drivers/android/binder.c ++++ b/drivers/android/binder.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -47,19 +48,98 @@ + #include + #include "binder_trace.h" + ++/* ++ * Using a private context manager for each binder namespace is sufficient ++ * to isolate between namespaces, because in binder all IPC must be realized ++ * via hanldes obtained from the context manager. ++ * ++ * TODO: currently, most debugfs data is not tracked per binder namespaces. ++ * Except for "procs" which are properly virtualized, everything else is ++ * global, including stats, logs, and dead nodes. ++ */ ++struct binder_namespace { ++ struct kref kref; ++ ++ struct binder_node *context_mgr_node; ++ kuid_t context_mgr_uid; ++ int last_id; ++ ++ struct hlist_head procs; ++}; ++ ++static struct binder_namespace *create_binder_ns(void) ++{ ++ struct binder_namespace *binder_ns; ++ ++ binder_ns = kzalloc(sizeof(struct binder_namespace), GFP_KERNEL); ++ if (binder_ns) { ++ kref_init(&binder_ns->kref); ++ binder_ns->context_mgr_uid = INVALID_UID; ++ INIT_HLIST_HEAD(&binder_ns->procs); ++ } ++ return binder_ns; ++} ++ ++static void free_binder_ns(struct kref *kref) ++{ ++ kfree(container_of(kref, struct binder_namespace, kref)); ++} ++ ++static void get_binder_ns(struct binder_namespace *binder_ns) ++{ ++ kref_get(&binder_ns->kref); ++} ++ ++static void put_binder_ns(struct binder_namespace *binder_ns) ++{ ++ kref_put(&binder_ns->kref, free_binder_ns); ++} ++ ++/* ++ * Binder is an IPC mechanism, so tie its namespace to IPC_NS ++ * using the generic data pointer and per-ipc operations. ++ */ ++static struct binder_namespace *current_binder_ns(void) ++{ ++ return ipc_access_generic(current->nsproxy->ipc_ns); ++} ++ ++int binder_init_ns(struct ipc_namespace *ipcns) ++{ ++ struct binder_namespace *binder_ns; ++ int ret = -ENOMEM; ++ ++ binder_ns = create_binder_ns(); ++ if (binder_ns) { ++ ipc_assign_generic(ipcns, binder_ns); ++ ret = 0; ++ } ++ return ret; ++} ++ ++void binder_exit_ns(struct ipc_namespace *ipcns) ++{ ++ struct binder_namespace *binder_ns; ++ ++ binder_ns = ipc_access_generic(ipcns); ++ if (binder_ns) ++ put_binder_ns(binder_ns); ++} ++ ++struct peripc_operations binder_peripc_ops = { ++ .init = binder_init_ns, ++ .exit = binder_exit_ns, ++}; ++ + static DEFINE_RT_MUTEX(binder_main_lock); + static DEFINE_MUTEX(binder_deferred_lock); + static DEFINE_MUTEX(binder_mmap_lock); + +-static HLIST_HEAD(binder_procs); + static HLIST_HEAD(binder_deferred_list); + static HLIST_HEAD(binder_dead_nodes); + + static struct dentry *binder_debugfs_dir_entry_root; + static struct dentry *binder_debugfs_dir_entry_proc; +-static struct binder_node *binder_context_mgr_node; +-static kuid_t binder_context_mgr_uid = INVALID_UID; +-static int binder_last_id; + static struct workqueue_struct *binder_deferred_workqueue; + + #define BINDER_DEBUG_ENTRY(name) \ +@@ -327,6 +407,8 @@ struct binder_proc { + int ready_threads; + long default_priority; + struct dentry *debugfs_entry; ++ ++ struct binder_namespace *binder_ns; + }; + + enum { +@@ -910,7 +992,7 @@ static struct binder_node *binder_new_node(struct binder_proc *proc, + binder_stats_created(BINDER_STAT_NODE); + rb_link_node(&node->rb_node, parent, p); + rb_insert_color(&node->rb_node, &proc->nodes); +- node->debug_id = ++binder_last_id; ++ node->debug_id = ++proc->binder_ns->last_id; + node->proc = proc; + node->ptr = ptr; + node->cookie = cookie; +@@ -931,7 +1013,7 @@ static int binder_inc_node(struct binder_node *node, int strong, int internal, + if (internal) { + if (target_list == NULL && + node->internal_strong_refs == 0 && +- !(node == binder_context_mgr_node && ++ !(node == node->proc->binder_ns->context_mgr_node && + node->has_strong_ref)) { + pr_err("invalid inc strong node for %d\n", + node->debug_id); +@@ -1045,13 +1127,13 @@ static struct binder_ref *binder_get_ref_for_node(struct binder_proc *proc, + if (new_ref == NULL) + return NULL; + binder_stats_created(BINDER_STAT_REF); +- new_ref->debug_id = ++binder_last_id; ++ new_ref->debug_id = ++proc->binder_ns->last_id; + new_ref->proc = proc; + new_ref->node = node; + rb_link_node(&new_ref->rb_node_node, parent, p); + rb_insert_color(&new_ref->rb_node_node, &proc->refs_by_node); + +- new_ref->desc = (node == binder_context_mgr_node) ? 0 : 1; ++ new_ref->desc = (node == proc->binder_ns->context_mgr_node) ? 0 : 1; + for (n = rb_first(&proc->refs_by_desc); n != NULL; n = rb_next(n)) { + ref = rb_entry(n, struct binder_ref, rb_node_desc); + if (ref->desc > new_ref->desc) +@@ -1391,7 +1473,7 @@ static void binder_transaction(struct binder_proc *proc, + } + target_node = ref->node; + } else { +- target_node = binder_context_mgr_node; ++ target_node = proc->binder_ns->context_mgr_node; + if (target_node == NULL) { + return_error = BR_DEAD_REPLY; + goto err_no_context_mgr_node; +@@ -1452,7 +1534,7 @@ static void binder_transaction(struct binder_proc *proc, + } + binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE); + +- t->debug_id = ++binder_last_id; ++ t->debug_id = ++proc->binder_ns->last_id; + e->debug_id = t->debug_id; + + if (reply) +@@ -1787,10 +1869,10 @@ static int binder_thread_write(struct binder_proc *proc, + if (get_user(target, (uint32_t __user *)ptr)) + return -EFAULT; + ptr += sizeof(uint32_t); +- if (target == 0 && binder_context_mgr_node && ++ if (target == 0 && proc->binder_ns->context_mgr_node && + (cmd == BC_INCREFS || cmd == BC_ACQUIRE)) { + ref = binder_get_ref_for_node(proc, +- binder_context_mgr_node); ++ proc->binder_ns->context_mgr_node); + if (ref->desc != target) { + binder_user_error("%d:%d tried to acquire reference to desc 0, got %d instead\n", + proc->pid, thread->pid, +@@ -2696,9 +2778,10 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp) + { + int ret = 0; + struct binder_proc *proc = filp->private_data; ++ struct binder_namespace *binder_ns = proc->binder_ns; + kuid_t curr_euid = current_euid(); + +- if (binder_context_mgr_node != NULL) { ++ if (binder_ns->context_mgr_node != NULL) { + pr_err("BINDER_SET_CONTEXT_MGR already set\n"); + ret = -EBUSY; + goto out; +@@ -2706,27 +2789,27 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp) + ret = security_binder_set_context_mgr(proc->tsk); + if (ret < 0) + goto out; +- if (uid_valid(binder_context_mgr_uid)) { +- if (!uid_eq(binder_context_mgr_uid, curr_euid)) { ++ if (uid_valid(binder_ns->context_mgr_uid)) { ++ if (!uid_eq(binder_ns->context_mgr_uid, curr_euid)) { + pr_err("BINDER_SET_CONTEXT_MGR bad uid %d != %d\n", + from_kuid(&init_user_ns, curr_euid), + from_kuid(&init_user_ns, +- binder_context_mgr_uid)); ++ binder_ns->context_mgr_uid)); + ret = -EPERM; + goto out; + } + } else { +- binder_context_mgr_uid = curr_euid; ++ binder_ns->context_mgr_uid = curr_euid; + } +- binder_context_mgr_node = binder_new_node(proc, 0, 0); +- if (binder_context_mgr_node == NULL) { ++ binder_ns->context_mgr_node = binder_new_node(proc, 0, 0); ++ if (binder_ns->context_mgr_node == NULL) { + ret = -ENOMEM; + goto out; + } +- binder_context_mgr_node->local_weak_refs++; +- binder_context_mgr_node->local_strong_refs++; +- binder_context_mgr_node->has_strong_ref = 1; +- binder_context_mgr_node->has_weak_ref = 1; ++ binder_ns->context_mgr_node->local_weak_refs++; ++ binder_ns->context_mgr_node->local_strong_refs++; ++ binder_ns->context_mgr_node->has_strong_ref = 1; ++ binder_ns->context_mgr_node->has_weak_ref = 1; + out: + return ret; + } +@@ -2947,10 +3030,15 @@ err_bad_arg: + static int binder_open(struct inode *nodp, struct file *filp) + { + struct binder_proc *proc; ++ struct binder_namespace *binder_ns; + + binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n", + current->group_leader->pid, current->pid); + ++ binder_ns = current_binder_ns(); ++ if (binder_ns == NULL) ++ return -ENOMEM; ++ + proc = kzalloc(sizeof(*proc), GFP_KERNEL); + if (proc == NULL) + return -ENOMEM; +@@ -2960,10 +3048,13 @@ static int binder_open(struct inode *nodp, struct file *filp) + init_waitqueue_head(&proc->wait); + proc->default_priority = task_nice(current); + ++ proc->binder_ns = binder_ns; ++ get_binder_ns(binder_ns); ++ + binder_lock(__func__); + + binder_stats_created(BINDER_STAT_PROC); +- hlist_add_head(&proc->proc_node, &binder_procs); ++ hlist_add_head(&proc->proc_node, &binder_ns->procs); + proc->pid = current->group_leader->pid; + INIT_LIST_HEAD(&proc->delivered_death); + filp->private_data = proc; +@@ -3067,6 +3158,7 @@ static int binder_node_release(struct binder_node *node, int refs) + + static void binder_deferred_release(struct binder_proc *proc) + { ++ struct binder_namespace *binder_ns = proc->binder_ns; + struct binder_transaction *t; + struct rb_node *n; + int threads, nodes, incoming_refs, outgoing_refs, buffers, +@@ -3077,11 +3169,12 @@ static void binder_deferred_release(struct binder_proc *proc) + + hlist_del(&proc->proc_node); + +- if (binder_context_mgr_node && binder_context_mgr_node->proc == proc) { ++ if (binder_ns->context_mgr_node && ++ binder_ns->context_mgr_node->proc == proc) { + binder_debug(BINDER_DEBUG_DEAD_BINDER, + "%s: %d context_mgr_node gone\n", + __func__, proc->pid); +- binder_context_mgr_node = NULL; ++ binder_ns->context_mgr_node = NULL; + } + + threads = 0; +@@ -3160,6 +3253,7 @@ static void binder_deferred_release(struct binder_proc *proc) + vfree(proc->buffer); + } + ++ put_binder_ns(proc->binder_ns); + put_task_struct(proc->tsk); + + binder_debug(BINDER_DEBUG_OPEN_CLOSE, +@@ -3540,10 +3634,14 @@ static void print_binder_proc_stats(struct seq_file *m, + + static int binder_state_show(struct seq_file *m, void *unused) + { ++ struct binder_namespace *binder_ns = current_binder_ns(); + struct binder_proc *proc; + struct binder_node *node; + int do_lock = !binder_debug_no_lock; + ++ if (binder_ns == NULL) ++ return 0; ++ + if (do_lock) + binder_lock(__func__); + +@@ -3554,7 +3652,7 @@ static int binder_state_show(struct seq_file *m, void *unused) + hlist_for_each_entry(node, &binder_dead_nodes, dead_node) + print_binder_node(m, node); + +- hlist_for_each_entry(proc, &binder_procs, proc_node) ++ hlist_for_each_entry(proc, &binder_ns->procs, proc_node) + print_binder_proc(m, proc, 1); + if (do_lock) + binder_unlock(__func__); +@@ -3563,9 +3661,13 @@ static int binder_state_show(struct seq_file *m, void *unused) + + static int binder_stats_show(struct seq_file *m, void *unused) + { ++ struct binder_namespace *binder_ns = current_binder_ns(); + struct binder_proc *proc; + int do_lock = !binder_debug_no_lock; + ++ if (binder_ns == NULL) ++ return 0; ++ + if (do_lock) + binder_lock(__func__); + +@@ -3573,7 +3675,7 @@ static int binder_stats_show(struct seq_file *m, void *unused) + + print_binder_stats(m, "", &binder_stats); + +- hlist_for_each_entry(proc, &binder_procs, proc_node) ++ hlist_for_each_entry(proc, &binder_ns->procs, proc_node) + print_binder_proc_stats(m, proc); + if (do_lock) + binder_unlock(__func__); +@@ -3582,14 +3684,18 @@ static int binder_stats_show(struct seq_file *m, void *unused) + + static int binder_transactions_show(struct seq_file *m, void *unused) + { ++ struct binder_namespace *binder_ns = current_binder_ns(); + struct binder_proc *proc; + int do_lock = !binder_debug_no_lock; + ++ if (binder_ns == NULL) ++ return 0; ++ + if (do_lock) + binder_lock(__func__); + + seq_puts(m, "binder transactions:\n"); +- hlist_for_each_entry(proc, &binder_procs, proc_node) ++ hlist_for_each_entry(proc, &binder_ns->procs, proc_node) + print_binder_proc(m, proc, 0); + if (do_lock) + binder_unlock(__func__); +@@ -3661,9 +3767,15 @@ static int __init binder_init(void) + { + int ret; + ++ ret = register_peripc_ops(&binder_peripc_ops); ++ if (ret < 0) ++ return ret; ++ + binder_deferred_workqueue = create_singlethread_workqueue("binder"); +- if (!binder_deferred_workqueue) ++ if (!binder_deferred_workqueue) { ++ unregister_peripc_ops(&binder_peripc_ops); + return -ENOMEM; ++ } + + binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL); + if (binder_debugfs_dir_entry_root) +-- +2.7.4 + From 08aa37e9eb216bbb0a5d15c57925dcbf1f61a4b0 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 26 Apr 2017 19:57:15 +0200 Subject: [PATCH 11/86] Import helper cmake script to find GMock and GTest on more modern systems Taken from https://code.launchpad.net/~cmake-extras/cmake-extras/trunk --- cmake/FindGMock.cmake | 92 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 cmake/FindGMock.cmake diff --git a/cmake/FindGMock.cmake b/cmake/FindGMock.cmake new file mode 100644 index 0000000..2078030 --- /dev/null +++ b/cmake/FindGMock.cmake @@ -0,0 +1,92 @@ +# Copyright (C) 2014 Canonical Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser 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 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 . + +# Build with system gmock and embedded gtest +# +# Usage: +# +# find_package(GMock) +# +# ... +# +# target_link_libraries( +# my-target +# ${GTEST_BOTH_LIBRARIES} +# ) +# +# NOTE: Due to the way this package finder is implemented, do not attempt +# to find the GMock package more than once. + +find_package(Threads) + +if (EXISTS "/usr/src/googletest") + # As of version 1.8.0 + set(GMOCK_SOURCE_DIR "/usr/src/googletest/googlemock" CACHE PATH "gmock source directory") + set(GMOCK_INCLUDE_DIRS "${GMOCK_SOURCE_DIR}/include" CACHE PATH "gmock source include directory") + set(GTEST_INCLUDE_DIRS "/usr/src/googletest/googletest/include" CACHE PATH "gtest source include directory") +else() + set(GMOCK_SOURCE_DIR "/usr/src/gmock" CACHE PATH "gmock source directory") + set(GMOCK_INCLUDE_DIRS "/usr/include" CACHE PATH "gmock source include directory") + set(GTEST_INCLUDE_DIRS "/usr/include" CACHE PATH "gtest source include directory") +endif() + +# We add -g so we get debug info for the gtest stack frames with gdb. +# The warnings are suppressed so we get a noise-free build for gtest and gmock if the caller +# has these warnings enabled. +set(findgmock_cxx_flags "${CMAKE_CXX_FLAGS} -g -Wno-old-style-cast -Wno-missing-field-initializers -Wno-ctor-dtor-privacy -Wno-switch-default") + +set(findgmock_bin_dir "${CMAKE_CURRENT_BINARY_DIR}/gmock") +set(findgmock_gtest_lib "${findgmock_bin_dir}/gtest/libgtest.a") +set(findgmock_gtest_main_lib "${findgmock_bin_dir}/gtest/libgtest_main.a") +set(findgmock_gmock_lib "${findgmock_bin_dir}/libgmock.a") +set(findgmock_gmock_main_lib "${findgmock_bin_dir}/libgmock_main.a") + +include(ExternalProject) +ExternalProject_Add(GMock SOURCE_DIR "${GMOCK_SOURCE_DIR}" + BINARY_DIR "${findgmock_bin_dir}" + BUILD_BYPRODUCTS "${findgmock_gtest_lib}" + "${findgmock_gtest_main_lib}" + "${findgmock_gmock_lib}" + "${findgmock_gmock_main_lib}" + INSTALL_COMMAND "" + CMAKE_ARGS "-DCMAKE_CXX_FLAGS=${findgmock_cxx_flags}") + +add_library(gtest INTERFACE) +target_include_directories(gtest INTERFACE ${GTEST_INCLUDE_DIRS}) +target_link_libraries(gtest INTERFACE ${findgmock_gtest_lib} ${CMAKE_THREAD_LIBS_INIT}) +add_dependencies(gtest GMock) + +add_library(gtest_main INTERFACE) +target_include_directories(gtest_main INTERFACE ${GTEST_INCLUDE_DIRS}) +target_link_libraries(gtest_main INTERFACE ${findgmock_gtest_main_lib} gtest) + +add_library(gmock INTERFACE) +target_include_directories(gmock INTERFACE ${GMOCK_INCLUDE_DIRS}) +target_link_libraries(gmock INTERFACE ${findgmock_gmock_lib} gtest) + +add_library(gmock_main INTERFACE) +target_include_directories(gmock_main INTERFACE ${GMOCK_INCLUDE_DIRS}) +target_link_libraries(gmock_main INTERFACE ${findgmock_gmock_main_lib} gmock) + +set(GTEST_LIBRARIES gtest) +set(GTEST_MAIN_LIBRARIES gtest_main) +set(GMOCK_LIBRARIES gmock gmock_main) +set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES}) + +unset(findgmock_cxx_flags) +unset(findgmock_bin_dir) +unset(findgmock_gtest_lib) +unset(findgmock_gtest_main_lib) +unset(findgmock_gmock_lib) +unset(findgmock_gmock_main_lib) From 525d37b9dbd98f40c8848c3a03b50ce9fd5adfa4 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 26 Apr 2017 08:35:13 +0200 Subject: [PATCH 12/86] Build debs also during our travis job --- scripts/clean-build.sh | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/scripts/clean-build.sh b/scripts/clean-build.sh index b2de311..ad1b332 100755 --- a/scripts/clean-build.sh +++ b/scripts/clean-build.sh @@ -40,14 +40,24 @@ apt-get clean cd /anbox -# In cases where anbox comes directly from a checked out Android -# build environment we miss some symlinks which are present on -# the host and don't have a valid git repository in that case. -git clean -fdx . || true -git reset --hard || true +cleanup() { + # In cases where anbox comes directly from a checked out Android + # build environment we miss some symlinks which are present on + # the host and don't have a valid git repository in that case. + git clean -fdx . || true + git reset --hard || true +} + +cleanup mkdir build || rm -rf build/* cd build cmake .. make -j10 make test + +cleanup + +apt-get install -y build-essential curl devscripts gdebi-core +apt-get install -y $(gdebi --quiet --apt-line ./debian/control) +debuild -us -uc From 06a8b728cdbe4c6569a3dcca31bfb984b164abb8 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 26 Apr 2017 08:47:49 +0200 Subject: [PATCH 13/86] Install additional needed build dependencies --- scripts/clean-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/clean-build.sh b/scripts/clean-build.sh index ad1b332..0c0f612 100755 --- a/scripts/clean-build.sh +++ b/scripts/clean-build.sh @@ -58,6 +58,6 @@ make test cleanup -apt-get install -y build-essential curl devscripts gdebi-core +apt-get install -y build-essential curl devscripts gdebi-core dkms dh-systemd apt-get install -y $(gdebi --quiet --apt-line ./debian/control) debuild -us -uc From 73ecb78bc6c93872c73e0564712c28850b556e9b Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 27 Apr 2017 06:44:50 +0200 Subject: [PATCH 14/86] scripts: cleanup git tree only when one exists --- scripts/clean-build.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/clean-build.sh b/scripts/clean-build.sh index 0c0f612..d7219d7 100755 --- a/scripts/clean-build.sh +++ b/scripts/clean-build.sh @@ -44,8 +44,10 @@ cleanup() { # In cases where anbox comes directly from a checked out Android # build environment we miss some symlinks which are present on # the host and don't have a valid git repository in that case. - git clean -fdx . || true - git reset --hard || true + if [ -d .git ] ; then + git clean -fdx . + git reset --hard + fi } cleanup From 615ecc570a61e2f22b594f161ced6860fb960c5f Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sat, 29 Apr 2017 11:24:43 +0200 Subject: [PATCH 15/86] debian: add missing anbox.service symlink to package --- debian/anbox-common.install | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/anbox-common.install b/debian/anbox-common.install index 4700a8e..bf67a97 100644 --- a/debian/anbox-common.install +++ b/debian/anbox-common.install @@ -1,3 +1,4 @@ etc/X11/Xsession.d/68anbox usr/share/upstart/sessions/anbox.conf usr/lib/systemd/user/anbox.service +usr/lib/systemd/user/default.target.wants/anbox.service From 067ed5ec4b6f4cb7017e650bd9b63fd361e9a43d Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sat, 29 Apr 2017 12:07:57 +0200 Subject: [PATCH 16/86] debian: update changelog --- debian/changelog | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/debian/changelog b/debian/changelog index eccc558..a7152a9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +anbox (6) artful; urgency=medium + + * Add anbox-common package which ships any additional files needed for + anbox but can't be installed with a snap as of today. + + -- Simon Fels Sat, 29 Apr 2017 12:06:56 +0200 + anbox (5) zesty; urgency=medium * Rework packaging to also ship things we installed through the snap From fe0dba3b82805b6f76c921e507b3719615394958 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sat, 29 Apr 2017 12:14:02 +0200 Subject: [PATCH 17/86] Bump snap version to 2 --- snapcraft.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snapcraft.yaml b/snapcraft.yaml index 0318ead..12cf904 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,5 +1,5 @@ name: anbox -version: 1-dev +version: 2 summary: Android in a Box description: | Runtime for Android applications which runs a full Android system From 3abcc023b7ed00d62c2fe472785172bf96ebbcfb Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 2 May 2017 18:10:16 +0200 Subject: [PATCH 18/86] Close connection when adbd connection is closed This will ensure the message processor is correctly terminated and a new connection is established when the adb server process on the host opens a connection to us again. --- src/anbox/qemu/adb_message_processor.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/anbox/qemu/adb_message_processor.cpp b/src/anbox/qemu/adb_message_processor.cpp index f41b9de..9fe9575 100644 --- a/src/anbox/qemu/adb_message_processor.cpp +++ b/src/anbox/qemu/adb_message_processor.cpp @@ -156,7 +156,8 @@ void AdbMessageProcessor::on_host_read_size( const boost::system::error_code &error, std::size_t bytes_read) { if (error) { state_ = closed_by_host; - BOOST_THROW_EXCEPTION(std::runtime_error(error.message())); + messenger_->close(); + return; } messenger_->send(reinterpret_cast(host_buffer_.data()), bytes_read); From bcdbdbac6ac7a9675011783717ecee1839702b03 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 2 May 2017 07:21:47 +0200 Subject: [PATCH 19/86] external: prevent a child process from killing a process on cleanup --- .../include/core/posix/child_process.h | 6 ++++++ .../process-cpp-minimal/src/core/posix/child_process.cpp | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/external/process-cpp-minimal/include/core/posix/child_process.h b/external/process-cpp-minimal/include/core/posix/child_process.h index d6b3b31..fde7977 100644 --- a/external/process-cpp-minimal/include/core/posix/child_process.h +++ b/external/process-cpp-minimal/include/core/posix/child_process.h @@ -114,6 +114,12 @@ public: */ wait::Result wait_for(const wait::Flags& flags); + /** + * @brief Mark the child process to not to be killed when the ChildProcess + * instance goes away. + */ + void dont_kill_on_cleanup(); + #ifndef ANDROID /** * @brief Access this process's stderr. diff --git a/external/process-cpp-minimal/src/core/posix/child_process.cpp b/external/process-cpp-minimal/src/core/posix/child_process.cpp index b121b89..ad16571 100644 --- a/external/process-cpp-minimal/src/core/posix/child_process.cpp +++ b/external/process-cpp-minimal/src/core/posix/child_process.cpp @@ -303,7 +303,7 @@ struct ChildProcess::Private ~Private() { // Check if we are in the original parent process. - if (original_parent_pid == getpid()) + if (original_parent_pid == getpid() && !dont_kill_on_cleanup) { // If so, check if we are considering a valid pid here. // If so, we kill the original child. @@ -333,6 +333,8 @@ struct ChildProcess::Private // is called from the child process. pid_t original_parent_pid; pid_t original_child_pid; + + bool dont_kill_on_cleanup = false; }; ChildProcess ChildProcess::invalid() @@ -395,6 +397,11 @@ wait::Result ChildProcess::wait_for(const wait::Flags& flags) return result; } +void ChildProcess::dont_kill_on_cleanup() +{ + d->dont_kill_on_cleanup = true; +} + #ifndef ANDROID std::istream& ChildProcess::cerr() { From 83bf973d98de9efd38cc42f9043b808a583bb616 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 2 May 2017 07:22:13 +0200 Subject: [PATCH 20/86] dbus: stub: don't register an object but retrieve the already registered one --- src/anbox/dbus/skeleton/service.cpp | 6 ++---- src/anbox/dbus/stub/application_manager.cpp | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/anbox/dbus/skeleton/service.cpp b/src/anbox/dbus/skeleton/service.cpp index 40910c1..8f309c2 100644 --- a/src/anbox/dbus/skeleton/service.cpp +++ b/src/anbox/dbus/skeleton/service.cpp @@ -25,10 +25,8 @@ namespace skeleton { std::shared_ptr Service::create_for_bus( const core::dbus::Bus::Ptr &bus, const std::shared_ptr &application_manager) { - auto service = core::dbus::Service::add_service( - bus, anbox::dbus::interface::Service::name()); - auto object = - service->add_object_for_path(anbox::dbus::interface::Service::path()); + auto service = core::dbus::Service::add_service(bus, anbox::dbus::interface::Service::name()); + auto object = service->add_object_for_path(anbox::dbus::interface::Service::path()); return std::make_shared(bus, service, object, application_manager); } diff --git a/src/anbox/dbus/stub/application_manager.cpp b/src/anbox/dbus/stub/application_manager.cpp index e11176f..743d73e 100644 --- a/src/anbox/dbus/stub/application_manager.cpp +++ b/src/anbox/dbus/stub/application_manager.cpp @@ -25,7 +25,7 @@ namespace dbus { namespace stub { std::shared_ptr ApplicationManager::create_for_bus(const core::dbus::Bus::Ptr &bus) { auto service = core::dbus::Service::use_service_or_throw_if_not_available(bus, anbox::dbus::interface::Service::name()); - auto object = service->add_object_for_path(anbox::dbus::interface::Service::path()); + auto object = service->object_for_path(anbox::dbus::interface::Service::path()); return std::make_shared(bus, service, object); } From d2eae3a832ce9c3e4f5218f73cfdcd1c1e33dc05 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 2 May 2017 07:23:18 +0200 Subject: [PATCH 21/86] cmds/launch: start session manager if not already running --- src/anbox/cmds/launch.cpp | 48 +++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index a73e2b6..f4e8202 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -26,12 +26,16 @@ #include +#include "core/posix/exec.h" +#include "core/posix/fork.h" #include "core/posix/signal.h" namespace fs = boost::filesystem; namespace { const boost::posix_time::seconds max_wait_timeout{30}; +const unsigned int max_restart_attempts{3}; +const std::chrono::seconds restart_interval{1}; } anbox::cmds::Launch::Launch() @@ -69,11 +73,47 @@ anbox::cmds::Launch::Launch() auto bus = std::make_shared(core::dbus::WellKnownBus::session); bus->install_executor(core::dbus::asio::make_executor(bus, rt->service())); + // Instead of relying on the user session init system to start our + // session manager process we also attempt to start it on 0our own + // if not already running. This will help to mitigate problems with + // a crashing or a not yet started session manager instance. std::shared_ptr stub; - try { - stub = dbus::stub::ApplicationManager::create_for_bus(bus); - } catch (...) { - ERROR("Anbox session manager service isn't running!"); + for (auto n = 0; n < max_restart_attempts; n++) { + try { + stub = dbus::stub::ApplicationManager::create_for_bus(bus); + } catch (std::exception &err) { + WARNING("Anbox session manager service isn't running, trying to start it."); + + std::vector args = {"session-manager"}; + + std::map env; + core::posix::this_process::env::for_each([&](const std::string &name, const std::string &value) { + env.insert({name, value}); + }); + + const auto exe_path = utils::process_get_exe_path(::getpid()); + + try { + const auto flags = core::posix::StandardStream::stdout | core::posix::StandardStream::stderr; + auto child = core::posix::fork([&]() { + auto grandchild = core::posix::exec(exe_path, args, env, flags); + grandchild.dont_kill_on_cleanup(); + return core::posix::exit::Status::success; + }, flags); + child.wait_for(core::posix::wait::Flags::untraced); + + DEBUG("Started session manager, will now try to connect .."); + } + catch (...) { + ERROR("Failed to start session manager instance"); + } + } + + std::this_thread::sleep_for(restart_interval); + } + + if (!stub) { + ERROR("Couldn't get a connection with the session manager"); return EXIT_FAILURE; } From 855a391a5bf579f647fa47d8d5d7c9223528edaa Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 2 May 2017 08:13:33 +0200 Subject: [PATCH 22/86] android: only print intent information when available --- src/anbox/android/intent.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/anbox/android/intent.cpp b/src/anbox/android/intent.cpp index aa40f2c..8344dc0 100644 --- a/src/anbox/android/intent.cpp +++ b/src/anbox/android/intent.cpp @@ -22,16 +22,25 @@ namespace anbox { namespace android { std::ostream &operator<<(std::ostream &out, const Intent &intent) { - out << "[" - << "action=" << intent.action << " " - << "uri=" << intent.uri << " " - << "type=" << intent.type << " " - << "flags=" << intent.flags << " " - << "package=" << intent.package << " " - << "component=" << intent.component << " " - << "categories=[ "; - for (const auto &category : intent.categories) out << category << " "; - out << "]]"; + out << "["; + if (intent.action.length() > 0) + out << " " << "action=" << intent.action << " "; + if (intent.uri.length() > 0) + out << " " << "uri=" << intent.uri << " "; + if (intent.type.length() > 0) + out << " " << "type=" << intent.type << " "; + if (intent.flags > 0) + out << " " << "flags=" << intent.flags << " "; + if (intent.package.length() > 0) + out << " " << "package=" << intent.package << " "; + if (intent.component.length() > 0) + out << "component=" << intent.component << " "; + if (intent.categories.size() > 0) { + out << "categories=[ "; + for (const auto &category : intent.categories) out << category << " "; + out << "] "; + } + out << "]"; return out; } } // namespace android From c44e2a84d84a60c257af8e768ad28e2916e2fc83 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 2 May 2017 19:48:17 +0200 Subject: [PATCH 23/86] Add simple splash screen implementation --- src/CMakeLists.txt | 2 + src/anbox/ui/splash_screen.cpp | 85 ++++++++++++++++++++++++++++++++++ src/anbox/ui/splash_screen.h | 42 +++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 src/anbox/ui/splash_screen.cpp create mode 100644 src/anbox/ui/splash_screen.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5675ccb..6dac24c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -203,6 +203,8 @@ set(SOURCES anbox/utils/environment_file.cpp + anbox/ui/splash_screen.cpp + anbox/do_not_copy_or_move.h anbox/optional.h anbox/defer_action.h) diff --git a/src/anbox/ui/splash_screen.cpp b/src/anbox/ui/splash_screen.cpp new file mode 100644 index 0000000..fc94dba --- /dev/null +++ b/src/anbox/ui/splash_screen.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2017 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 . + * + */ + +#include "anbox/ui/splash_screen.h" +#include "anbox/utils.h" + +#include + +namespace anbox { +namespace ui { +SplashScreen::SplashScreen() { + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) { + const auto message = utils::string_format("Failed to initialize SDL: %s", SDL_GetError()); + BOOST_THROW_EXCEPTION(std::runtime_error(message)); + } + + const auto width = 1024, height = 768; + window_ = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS); + if (!window_) { + const auto message = utils::string_format("Failed to create window: %s", SDL_GetError()); + BOOST_THROW_EXCEPTION(std::runtime_error(message)); + } + + auto surface = SDL_GetWindowSurface(window_); + SDL_FillRect(surface, nullptr, SDL_MapRGB(surface->format, 0xee, 0xee, 0xee)); + SDL_UpdateWindowSurface(window_); + + auto renderer = SDL_CreateRenderer(window_, -1, SDL_RENDERER_ACCELERATED); + auto img = IMG_LoadTexture(renderer, "/snap/anbox/current/snap/gui/icon.png"); + + const auto tex_width = 128, tex_height = 128; + SDL_Rect r{(width - tex_width) / 2, (height - tex_height) / 2, 128, 128}; + + SDL_SetRenderDrawColor(renderer, 0xee, 0xee, 0xee, 0xff); + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, img, nullptr, &r); + SDL_RenderPresent(renderer); + + SDL_ShowWindow(window_); + + event_thread_ = std::thread(&SplashScreen::process_events, this); +} + +SplashScreen::~SplashScreen() { + if (event_thread_running_) { + event_thread_running_ = false; + if (event_thread_.joinable()) + event_thread_.join(); + } + + if (window_) + SDL_DestroyWindow(window_); +} + +void SplashScreen::process_events() { + event_thread_running_ = true; + while (event_thread_running_) { + SDL_Event event; + while (SDL_WaitEventTimeout(&event, 100)) { + switch (event.type) { + case SDL_QUIT: + break; + default: + break; + } + } + } +} +} // namespace ui +} // namespace anbox diff --git a/src/anbox/ui/splash_screen.h b/src/anbox/ui/splash_screen.h new file mode 100644 index 0000000..bee6f6d --- /dev/null +++ b/src/anbox/ui/splash_screen.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2017 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_UI_SPLASH_SCREEN_H_ +#define ANBOX_UI_SPLASH_SCREEN_H_ + +#include + +#include + +namespace anbox { +namespace ui { +class SplashScreen { + public: + SplashScreen(); + ~SplashScreen(); + + private: + void process_events(); + + std::thread event_thread_; + bool event_thread_running_; + SDL_Window *window_; +}; +} // namespace ui +} // namespace anbox + +#endif From ee105c396300b1ba7ae12c9499ad13089d3b5d14 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 07:57:00 +0200 Subject: [PATCH 24/86] Hook splash screen into our launcher --- src/anbox/cmds/launch.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index f4e8202..b484817 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -19,6 +19,7 @@ #include "anbox/common/wait_handle.h" #include "anbox/dbus/stub/application_manager.h" #include "anbox/common/dispatcher.h" +#include "anbox/ui/splash_screen.h" #include "anbox/runtime.h" #include "anbox/logger.h" @@ -73,6 +74,8 @@ anbox::cmds::Launch::Launch() auto bus = std::make_shared(core::dbus::WellKnownBus::session); bus->install_executor(core::dbus::asio::make_executor(bus, rt->service())); + std::shared_ptr ss; + // Instead of relying on the user session init system to start our // session manager process we also attempt to start it on 0our own // if not already running. This will help to mitigate problems with @@ -84,6 +87,12 @@ anbox::cmds::Launch::Launch() } catch (std::exception &err) { WARNING("Anbox session manager service isn't running, trying to start it."); + // Give us a splash screen as long as we're trying to connect + // with the session manager so the user knows something is + // happening after he started Anbox. + if (!ss) + ss = std::make_shared(); + std::vector args = {"session-manager"}; std::map env; @@ -129,6 +138,7 @@ anbox::cmds::Launch::Launch() } catch (std::exception &err) { ERROR("err %s", err.what()); } + ss.reset(); trap->stop(); return; } @@ -145,6 +155,7 @@ anbox::cmds::Launch::Launch() ERROR("Failed to launch activity: %s", err.what()); success = false; } + ss.reset(); trap->stop(); }); }); From bcb00e31afbbd6eec00fd2c2a16c703b41aad8f0 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 07:57:33 +0200 Subject: [PATCH 25/86] Add necessary dependency on SDL2 image --- CMakeLists.txt | 1 + src/CMakeLists.txt | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 957664b..bf489a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ find_package(GLESv2 REQUIRED) find_package(Protobuf REQUIRED) pkg_check_modules(SDL2 sdl2 REQUIRED) +pkg_check_modules(SDL2_IMAGE SDL2_image REQUIRED) pkg_check_modules(DBUS_CPP dbus-cpp REQUIRED) pkg_check_modules(DBUS dbus-1 REQUIRED) pkg_check_modules(LXC lxc REQUIRED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6dac24c..f8017a4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ include_directories( ${DBUS_CPP_INCLUDE_DIRS} ${DBUS_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS} + ${SDL2_IMAGE_INCLUDE_DIRS} ${LXC_INCLUDE_DIRS} ${MIRCLIENT_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} @@ -217,6 +218,8 @@ target_link_libraries(anbox-core ${DBUS_CPP_LIBRARIES} ${SDL2_LDFLAGS} ${SDL2_LIBRARIES} + ${SDL2_IMAGE_LDFLAGS} + ${SDL2_IMAGE_LIBRARIES} ${LXC_LDFLAGS} ${LXC_LIBRARIES} ${MIRCLIENT_LDFLAGS} From f4df33efe4219db2114204e19105d7818f363944 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 07:57:54 +0200 Subject: [PATCH 26/86] Improve launch and splash screen interactions --- src/anbox/cmds/launch.cpp | 55 +++++++++++++++++++++------------------ src/anbox/cmds/launch.h | 3 +++ 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index b484817..66de05e 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -34,9 +34,20 @@ namespace fs = boost::filesystem; namespace { -const boost::posix_time::seconds max_wait_timeout{30}; -const unsigned int max_restart_attempts{3}; -const std::chrono::seconds restart_interval{1}; +const boost::posix_time::seconds max_wait_timeout{240}; +const int max_restart_attempts{3}; +const std::chrono::seconds restart_interval{5}; +} + +bool anbox::cmds::Launch::try_launch_activity(const std::shared_ptr &stub) { + try { + DEBUG("Sending launch intent %s to Android ..", intent_); + stub->launch(intent_, graphics::Rect::Invalid, stack_); + } catch (std::exception &err) { + ERROR("Failed to launch activity: %s", err.what()); + return false; + } + return true; } anbox::cmds::Launch::Launch() @@ -77,13 +88,14 @@ anbox::cmds::Launch::Launch() std::shared_ptr ss; // Instead of relying on the user session init system to start our - // session manager process we also attempt to start it on 0our own + // session manager process we also attempt to start it on our own // if not already running. This will help to mitigate problems with // a crashing or a not yet started session manager instance. std::shared_ptr stub; for (auto n = 0; n < max_restart_attempts; n++) { try { stub = dbus::stub::ApplicationManager::create_for_bus(bus); + break; } catch (std::exception &err) { WARNING("Anbox session manager service isn't running, trying to start it."); @@ -101,9 +113,13 @@ anbox::cmds::Launch::Launch() }); const auto exe_path = utils::process_get_exe_path(::getpid()); + if (!fs::exists(exe_path)) { + ERROR("Can't find correct anbox executable to run. Found %s but does not exist", exe_path); + return EXIT_FAILURE; + } try { - const auto flags = core::posix::StandardStream::stdout | core::posix::StandardStream::stderr; + const auto flags = core::posix::StandardStream::empty; // core::posix::StandardStream::stdout | core::posix::StandardStream::stderr; auto child = core::posix::fork([&]() { auto grandchild = core::posix::exec(exe_path, args, env, flags); grandchild.dont_kill_on_cleanup(); @@ -116,9 +132,9 @@ anbox::cmds::Launch::Launch() catch (...) { ERROR("Failed to start session manager instance"); } - } - std::this_thread::sleep_for(restart_interval); + std::this_thread::sleep_for(restart_interval); + } } if (!stub) { @@ -126,36 +142,23 @@ anbox::cmds::Launch::Launch() return EXIT_FAILURE; } - auto dispatcher = anbox::common::create_dispatcher_for_runtime(rt); - bool success = false; - + auto dispatcher = anbox::common::create_dispatcher_for_runtime(rt); dispatcher->dispatch([&]() { if (stub->ready()) { - try { - stub->launch(intent_, graphics::Rect::Invalid, stack_); - success = true; - } catch (std::exception &err) { - ERROR("err %s", err.what()); - } ss.reset(); + success = try_launch_activity(stub); trap->stop(); return; } - DEBUG("Android hasn't fully booted yet. Waiting a bit.."); + DEBUG("Android hasn't fully booted yet. Waiting a bit .."); stub->ready().changed().connect([&](bool ready) { if (!ready) return; - try { - stub->launch(intent_, graphics::Rect::Invalid, stack_); - success = true; - } catch (std::exception &err) { - ERROR("Failed to launch activity: %s", err.what()); - success = false; - } ss.reset(); + success = try_launch_activity(stub); trap->stop(); }); }); @@ -163,8 +166,8 @@ anbox::cmds::Launch::Launch() boost::asio::deadline_timer timer(rt->service()); timer.expires_from_now(max_wait_timeout); timer.async_wait([&](const boost::system::error_code&) { - WARNING("Stop waiting as we're already waiting for too long. Something is wrong"); - WARNING("with your setup and the container may have failed to boot."); + WARNING("Stopped waiting as we're already waited for too long. Something"); + WARNING("is wrong with your setup or the container has failed to boot."); trap->stop(); }); diff --git a/src/anbox/cmds/launch.h b/src/anbox/cmds/launch.h index b7a6dfe..7fc71c9 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/dbus/stub/application_manager.h" #include "anbox/wm/stack.h" #include "anbox/cli.h" @@ -33,6 +34,8 @@ class Launch : public cli::CommandWithFlagsAndAction { Launch(); private: + bool try_launch_activity(const std::shared_ptr &stub); + android::Intent intent_; wm::Stack::Id stack_; }; From f0945502795c5a5e624f7c0206574cdd823aa2cb Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 08:20:31 +0200 Subject: [PATCH 27/86] Use correct resource path and check for errors on splash screen creation --- src/anbox/config.cpp | 8 ++++++++ src/anbox/config.h | 3 +++ src/anbox/ui/splash_screen.cpp | 14 +++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/anbox/config.cpp b/src/anbox/config.cpp index 7c0961e..d6be507 100644 --- a/src/anbox/config.cpp +++ b/src/anbox/config.cpp @@ -41,6 +41,10 @@ void anbox::SystemConfiguration::set_data_path(const std::string &path) { data_path = path; } +void anbox::SystemConfiguration::set_resource_path(const std::string &path) { + resource_path = path; +} + fs::path anbox::SystemConfiguration::data_dir() const { return data_path; } @@ -76,6 +80,10 @@ std::string anbox::SystemConfiguration::application_item_dir() const { return dir.string(); } +std::string anbox::SystemConfiguration::resource_dir() const { + return resource_path.string(); +} + anbox::SystemConfiguration& anbox::SystemConfiguration::instance() { static SystemConfiguration config; return config; diff --git a/src/anbox/config.h b/src/anbox/config.h index 91f72c6..e3417d8 100644 --- a/src/anbox/config.h +++ b/src/anbox/config.h @@ -31,6 +31,7 @@ class SystemConfiguration { virtual ~SystemConfiguration() = default; void set_data_path(const std::string &path); + void set_resource_path(const std::string &path); boost::filesystem::path data_dir() const; std::string rootfs_dir() const; @@ -40,11 +41,13 @@ class SystemConfiguration { std::string container_socket_path() const; std::string input_device_dir() const; std::string application_item_dir() const; + std::string resource_dir() const; protected: SystemConfiguration() = default; boost::filesystem::path data_path = "/var/lib/anbox"; + boost::filesystem::path resource_path = "/usr/share/anbox"; }; } // namespace anbox diff --git a/src/anbox/ui/splash_screen.cpp b/src/anbox/ui/splash_screen.cpp index fc94dba..c8c7f86 100644 --- a/src/anbox/ui/splash_screen.cpp +++ b/src/anbox/ui/splash_screen.cpp @@ -16,6 +16,7 @@ */ #include "anbox/ui/splash_screen.h" +#include "anbox/config.h" #include "anbox/utils.h" #include @@ -37,11 +38,22 @@ SplashScreen::SplashScreen() { } auto surface = SDL_GetWindowSurface(window_); + if (!surface) + BOOST_THROW_EXCEPTION(std::runtime_error("Could not retrieve surface for our window")); + SDL_FillRect(surface, nullptr, SDL_MapRGB(surface->format, 0xee, 0xee, 0xee)); SDL_UpdateWindowSurface(window_); auto renderer = SDL_CreateRenderer(window_, -1, SDL_RENDERER_ACCELERATED); - auto img = IMG_LoadTexture(renderer, "/snap/anbox/current/snap/gui/icon.png"); + if (!renderer) + BOOST_THROW_EXCEPTION(std::runtime_error("Could not create renderer")); + + const auto icon_path = utils::string_format("%s/ui/icon.png", SystemConfiguration::instance().resource_dir()); + auto img = IMG_LoadTexture(renderer, icon_path.c_str()); + if (!img) { + const auto msg = utils::string_format("Failed to create texture from %s", icon_path); + BOOST_THROW_EXCEPTION(std::runtime_error(msg)); + } const auto tex_width = 128, tex_height = 128; SDL_Rect r{(width - tex_width) / 2, (height - tex_height) / 2, 128, 128}; From f838e759d843613e014775d3f8b15af7af7b428e Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 08:25:12 +0200 Subject: [PATCH 28/86] Install necessary resource files --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf489a7..7be7fdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,3 +104,6 @@ if (NOT "${HOST_CMAKE_C_COMPILER}" STREQUAL "") message(STATUS "Host C compiler: ${HOST_CMAKE_C_COMPILER}") message(STATUS "Host C compiler: ${HOST_CMAKE_CXX_COMPILER}") endif() + +install(FILES snap/gui/icon.png DESTINATION share/anbox/ui) + From 48758d8955473df351cd91822f9606c3175e29f7 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 08:25:33 +0200 Subject: [PATCH 29/86] Set correct resource path when starting from within a snap --- src/anbox/cmds/launch.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index 66de05e..f309491 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -20,6 +20,7 @@ #include "anbox/dbus/stub/application_manager.h" #include "anbox/common/dispatcher.h" #include "anbox/ui/splash_screen.h" +#include "anbox/config.h" #include "anbox/runtime.h" #include "anbox/logger.h" @@ -85,6 +86,12 @@ anbox::cmds::Launch::Launch() auto bus = std::make_shared(core::dbus::WellKnownBus::session); bus->install_executor(core::dbus::asio::make_executor(bus, rt->service())); + const auto snap_path = utils::get_env_value("SNAP"); + if (!snap_path.empty()) { + const auto resource_path = utils::string_format("%s/share/anbox", snap_path); + SystemConfiguration::instance().set_resource_path(resource_path) + } + std::shared_ptr ss; // Instead of relying on the user session init system to start our From 817f80d6bdb2dcc2c341014b6ba9d46cbc4d04ce Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 08:28:56 +0200 Subject: [PATCH 30/86] Add missing build dependency on libsdl2-image-dev --- snapcraft.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/snapcraft.yaml b/snapcraft.yaml index 12cf904..dfd0660 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -111,6 +111,7 @@ parts: - libprotobuf-dev - libproperties-cpp-dev - libsdl2-dev + - libsdl2-image-dev - pkg-config - protobuf-compiler stage-packages: From 7432fb15b3e6a6ca1bb5c05ea7ca4e0e81f9bbe0 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 May 2017 09:15:43 +0100 Subject: [PATCH 31/86] docs: build-android.md: Add missing step to initialise the build env Setting up the build environment is a required step. Without it, the subsequent step `lunch` will not be available. Signed-off-by: Lee Jones --- docs/build-android.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/build-android.md b/docs/build-android.md index 7f4b76e..3789155 100644 --- a/docs/build-android.md +++ b/docs/build-android.md @@ -33,8 +33,15 @@ This will take quite some time depending on the speed of your internet connectio ## Build Android -When all sources are successfully downloaded you can start building Android -itself. Initialize the build by +When all sources are successfully downloaded you can start building Android itself. + +Firstly initialize the environment with the ```envsetup.sh``` script. + +``` +$ . build/envsetup.sh +``` + +Then initialize the build using ```lunch```. ``` $ lunch anbox_desktop_x86_64-userdebug From 15067054c8657c8e4492518347d80107fd3cfe02 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 May 2017 16:30:44 +0100 Subject: [PATCH 32/86] rpc: connection_creator: Fix formatting error Warning currently prints out: [WW 2017-05-03 15:15:30] [connection_creator.cpp:47@create_connection_for] A second client tried to connect. Denied request as we already have oneand only allow a single client ^ Due to the way in which the code is formatted, we end up missing fudging the words 'one' and 'and'. Also the 3rd line in the source file seems somewhat superfluous. Let's fix that too. Signed-off-by: Lee Jones --- src/anbox/rpc/connection_creator.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/anbox/rpc/connection_creator.cpp b/src/anbox/rpc/connection_creator.cpp index 2989675..0ac1fd9 100644 --- a/src/anbox/rpc/connection_creator.cpp +++ b/src/anbox/rpc/connection_creator.cpp @@ -43,8 +43,7 @@ void ConnectionCreator::create_connection_for( socket->close(); WARNING( "A second client tried to connect. Denied request as we already have " - "one" - "and only allow a single client"); + "one and only allow a single client"); return; } From f61a7f91d694b5be88f51c81589408baff3f1299 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 20:47:40 +0200 Subject: [PATCH 33/86] Use a full screen loading image which includes some text --- CMakeLists.txt | 2 +- data/ui/loading-screen.png | Bin 0 -> 13724 bytes snapcraft.yaml | 1 + src/anbox/cmds/launch.cpp | 4 ++-- src/anbox/ui/splash_screen.cpp | 8 +++----- 5 files changed, 7 insertions(+), 8 deletions(-) create mode 100644 data/ui/loading-screen.png diff --git a/CMakeLists.txt b/CMakeLists.txt index 7be7fdb..02064fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,5 +105,5 @@ if (NOT "${HOST_CMAKE_C_COMPILER}" STREQUAL "") message(STATUS "Host C compiler: ${HOST_CMAKE_CXX_COMPILER}") endif() -install(FILES snap/gui/icon.png DESTINATION share/anbox/ui) +install(FILES data/ui/loading-screen.png DESTINATION share/anbox/ui) diff --git a/data/ui/loading-screen.png b/data/ui/loading-screen.png new file mode 100644 index 0000000000000000000000000000000000000000..267836181738c1cc4d05732af9e84d0bac877908 GIT binary patch literal 13724 zcmeHtXH*ki+wLd|k4iD9geEA6Ac6s@O0!TDP>d3gP(>-ykt!hs^-)>?3j$I#h(Krp zhMoi!h$s+2deuaw6C))+Lh?;~&pKCOzRPu8_q`|K(nSlAozgo2 z01!EU&h#<>Y|{V$0pK4&@J#Rd3?1+w=x$|U3h?-!=ft8X;F%pk=Nv)+VAmf0{}v!C zM-n_K6ng%Gnb5cG0^-LsQ)q?|@RU@j+11dqf&Ts;0inRzTOQX!J#HL`xEbnwz~cOc zOZIm}p#X3IIB$B|HgaTs9F_S!4E>c&t;9E?7KNc(D2}IkytkcJI&^EL(MsGpJ+dz( z&2Q|GO*Pdx+pkad$-a=sEab4g^MsHnzm;8UM+*C_%I zz=w-1{6p^^&>}$W@-|`caKLDb0C+fO(*llvzxr#9zp?Q*9sYvDUp)NF4u1*pzbg-< zFKz+8+gnPlp$01O_&a1F;Fh=saNxz|k9RAPs6~);z}Z+xL`ej@-v$#t_TNVL@jB zV}BIgecC|vUW9A;?}m$+NNADYm~5qCuwzdB%@FPEuI+FC0Y02=0b&nX9wA0Dzt3B9 zOjyxc#>~%XO(Mqiji8h6WxFBj=St_F&raKyq}_|G?3pN%?HyESkB}w@@v14Vb;jHd zEt`Z0V;*)$TW8-&cPF$)6F3kDims9SZ-AhG!{}{eV@`(E5jLDLe~gUS;`sifBDrxQ zJL42og-0lFNrSK9?rDRf+;dj04P#;^U3N$Fh_|hrc!`7U9WuIR1wFgL`F4aTZaHx0 zvSp`Ec2$Ju;bZLI7nq+($_2IWp0Ag1N8?U2^t>;be4LUFjqGm;S=!5Wvqc2+o;1;l z0@p+5bDt$Ncz(f^01y9--2zx#4TN;WM=~Zc>T)AXH&EjbAfEcB*prI1ulwg)Vun81 z;*e}^`skEpQyFf*CU?cT&MZy5%To(ko*rlm=)VIoLI0hl*F(;9MJ}_%LM|R@Yx8z; zBQ<>e!&~B&6SDFv4;j_G9MC=$m}ydED67Id>;4wt$Ul-m(6*IIG;_v64m<1_(zb>7 zEe8!B2=aPFXbvc3Nk_4ZzA9u1ba_Vqe!*x5&GrVV4iNxSG(d5h@;snLrLa{m!dUY+ zE_WP_{k;Ld{Jxmc5XydADbw6cc_FqugvR@rm4 zQe(G?w!re^pY?HUzaIxu8%}-*`8Cu@n!qUX=U3wo)2CvL-Lx(8&R21s6m*j$J^YNl z4`7BKtO|rXiF^=`^Vvde8?F7wncww)FL}MFv@uMF-2qJz8139(U-G4;iOk)Sm_JtB(E7GeV$AIucQ8QTM-EL6XeH&z<0X1 zIB+hYoax?mmf4%K)A8_OIxA-Ru0H#wO{!-p;cEk-nSQsck$nUrgesW@RSeh+ksme0s_EeX-_vIO*l!%>0~dOx+x^u%8U90qa@7fwN~aatJj{% z7)$V$UNFqd@dPi6H1R^b1Uj}Cbxh%8jgF;SW;+BinVpg8t4qI7MAWE=>Y7tjpiwUB zpXhGl&Sv^qzj3YmxL{_Eoc>a`7r^Rhfnf1$F&8H4c`8POsbHCaPmKJPz+mMyaUbio zm)gX5zOnR;5h}zC_pD+QdwtAG-;ga!d4%!G#e7Fiy+N#=afGppsi~p%W@KNukrW(x z6f<cRZeQlsB5+ZjWKw)6@3kNkAYN z=9j<}%&kqHOn%JTonpKy4)0z&j5SBJHH_v-nKZAg>3e({7}7o=1%aSEz36$l2DEG& zL%Dp+^c@wrJI*e3u`@}}glER|s?1G=Mi>WSntv4Vl%ySXE#}Ae2Y04V2xEWmP2bkF z^*;caaO)qJnt?kpfu;D_GLxRf>M*P3<&P|iJ!XA@c~&`RHv}@c*~ycuoa8>L|8^&k zB4dMsb7-kK`zq0^N6r!{B9kP83eJW-?FlRTC^r?FM>^mVy?KXCpBLja70cHV_6J)g z3=s_6KmGK8DOQDU2RLpeuZoH`8S+5N!-j^2%xBLM(CpPV1IAiY{q4c!*+b(c zT)6TW6KRTna=fZ#`2gty!7jBJ0m;_0C^0{gcYJwWMw?#9dt|>q6 zRL@YO5)Og0Mem9YU%V{dlxH|SBk^N5Srmwz-607)>;s(*CW6DRfW4R9!vl^@gf6Z# z-`h-ve@JC^dKoDnJHgJ$%+8+ctS(l-i^K8jD=@yLrXIR#(N;?U4Htd_du9gp#EkFW z6_fsS(rcJfs;Yn=($j-7jClRbBHnb7*rzJp*_E}WI?fqRslC(Qnvjqs8`~rk`n!0| z*&m8l)TGEQ0NtF=Mi0cGaWI$VJar|{?5?%CDU#|$@M=Tc<`D0zJlUB0T||%47>NT z`xUf;@hxVd&3Z8Rhhxma!*eU~y+{%qE2)_t;9{=N08U9PZWjd3KZV3mJysH=&I-?3 zb$0KMPj%sJc(}3$c8{nZ*j0=$KVAwZgjZYrtmi=R}ku~w`_%WZ;D~xO~Pko;3bWZkhtYdEzSYdij}!tGL)E`=B?|< z^!3WCp`jM@ecL<7oLa}mrXM}OeZVs-WMRSnmrP~7Mpl;{4BvW-68ta&Y%9^<3kw61 zXWwH7?Q@@2xhX5*`bp8>r(7c26Gz8?ec~Pei7fZ7MOMY!y7iK}Sx07$!Ylg=TuSYt z$4v~D=GWSI!Tx!#aT$eF%v9SYZRM+!2>$=QF=)*KNFE zxQ4qm`5_;(OnB>5H1|?vDPFaEVzsk=sVYtpFJ71^8JT;Ir>T}Gc{cybq#d9k;dEvz zaQ%7OH!o+bEDXf4ev%XYDRtw8Higr;sE%;_=N)K{(E|ra#eNM(@=L=%}uLf@f*};vOaU)5PM&Der4N zDm^D|qgIhadw`VVpccFVH^;1NWUCnzJa1YyvxO8U+8qhzJTTls|5rpt0Y_LqAhbPM ziCQVA`CSB%gh?>B#cFE3YujCFeMSYn|9R^TB80sBh$lVAnoq`u9@D$|^hYhyNqFP# zhvWEuW0dl_J|74{brpfomfoY8?}H~%FNtuSHpL%sIpZw(ZOUWg{anw3*L@7L!;p>jSIqR|`$kR6Vo0))*O_z~FYKa;?c(-x(iV z{|mzhJ}u_x)Xn!S`PBRk2Jgh-xhKRaQSB*OT?_|Tzt%uaRey4YS;#Qj&D(foLs{-5 z72~9XydIN6dJ-f(p2Z&o)qVh9?Q72Ca+2z#^@E?oT$Hid;S|dfp_+joWIP(1A2s+=Mc)UVan3s4gkxJX!ME z;|$8tipJvs?1_62xO&JltErs%acI@G&E98{p5Tq67Ws)#qK5J9BSpeN&9m->3HU0P zl8c1ux%_?w8p}1U_v49ph7;{L>g%boU+wvhyI~vSQNu8bZF%jik+)UCsx{Wbo*Dl_ zP6)`00vCdP=JDPv@ZX7b0)m!IMP0M*pZl~pxBMhe&Z~SbMPcdJQ= z^jZb}a>e}g}F;P_u^MQG}7pK^KI9 z1N=~Kw@qmKhU0a7gZ@yI+03y>c=9hfHmej0Jj?_abp3g2tQ7Q~3nD#0 zt8>EYd}Ee}1N}VyW8$vRV>1U4?6(T;z$qj@s&s$n#N&xE=2GiX@jh>1H*FPV&l1)K z4;EPW*S&ZK0$Msa-T5@h@K3m+~Mb` zPt_Ec^#=m6rhJ)!H%;()J0kpE7`HhxmlCQtuW$}7KfGEGB zc|0Q~;p;%hsY$(&cb>ZOgYGgT{&#qNRg=Wo0V>-fA8!G&bvUIA6 zavZNJL49|XvwVq(!=LE`Vh#ECh^yjUW9&wBf3i85UxaOZduvn}HGEFV2{@(8-;MY^ zBban~Kn`Z!P;+jk`}{fWYXun1UU|sXfqRa0i_&yX?Q(c+=f$>Nz_|;2A!I8`A;?Kl7zJao zFQs39draX^YR^y3WJI;ujC^t3gNZp%PYGHWw+3rFq9a5dBvmaLlOR=LkAil*EIRb* zZuXrN?LLO^htl}9p9Nx-jcwzpCRywow*8m#nKG%-Fg(7=_%>l$^f3P_gNTD$z@EaS z$&vsAF1SJ5Z*~NchEMce+!#sB9$WhGK6o^OY_wLfUn0=Wvu04XGbqGMjo0Meedz70j`k;P zEE3{J8pD{gCfrkoBowP9gS2?hzI8E52eYHYhoayDv(*cS!ZQRZWDK6P-&$-+CyX0c)v)U?OL#@$}l-h^xM0y}m0^(Sd_0+7ts~ zgpFyruDqsY!pN74@g~i5D<&zMcNo{7I8?8R7m>l?!%_`f8EF19+8So=!2&!xXWpO! zX?oL4M`xer2_0T!xdgm&#oeMrJ!D4$7-ZM^VPq;Hlz4pBGLIMuS-2C;yJb&6niA!D zyh9btr`D0CM?h7V7`QmTuZXwGlOo?{Dg}?6w@Fn|LKe2pP@^vTZZA)b-k7 zr?p@OnngZpByqH>yQ?jOjJE0XC4e>L;_dmKwRIh85ov{TUqhy{V_dk^Ve2S*`qVda1i`pOAQ)9b1@cX+p#nFXlNWwZkp73mv)qd%MLZcaDAgS>a&DGMX(W+(%i1(+_X^!HHxm9N^TiUa8!7ufQ15_CpAT9K_LGs> zJ09%t^EE#vH~2AWE@gaCxQS9d5=(jmT^V~#+M_uOw>+wVg!DA{y>tnr-nx2$6>wnu z(+Nx84+Te(6wLLU`l2%8P1T4s=Nyh{gLoZe3${qVs%VYmTAjT1yeGc;8rtgucJWMR zZkQ%s)je}ByfmuLOMT(~k*H7C$~L4LcZCf|P?CJyY_Epbflwk#@ZmR*$d`YT&Bv-Y zZT3O-B*%-)o&5IPhLWg6ss}Ks?aBorBqIgnE&u4QK#_c=mFR$1c8@!3 zw=5J}y5i~UUWds8C+UWz}72-;w{$qP@Jqmqe@W}eW3z}+k29wWAcQU%`Ysl? za$nt~iGj={=9WDS2!#szcXzid8ibeCFF+TY>d;3ACl)S$x=Yo02*Q9#5TDROgk;n| zstRzC*A=*52guIBu8fT&--6l-bjSG_ZamzqZ=gIWf|HtBS-(Ku+_yVq6#(|G@!ti= z&rie;kXOz6+0p-brt^Guf}d=7QMSJI5f@#)d}C@D9~zJ(%?vW4HM4k4-nHp2dw-M2 zjR%dF+sI&-XxtGO-q>P6ViF=*tGgQlr@yR)i8f!T3W8{mQpjHzB z+4Yvnt{7MM&qjtH4-T;|3GjN?x8+L05eUwBXWms-3PvvQc8?U3=4EUkH%`zpj$!*V za|iAe`%m*fI~LHPehD8RrH<<>$cet}v`J*+IPdjv zK79pc`H4vDTDn<3Zy(VhGYzSZUy-4G>rE6JTmPZb7JA%{Oo*_o!QJ}K<0re zS#bIkOOU-~%|s7JrJZK^m;2=Ix@ZN0Fm8C)f+9=PDMT^z~bIjk@fp%|6o% z0DrLJk^?=Ybg>TmIt)Q@olF*33262PmS*gZ!Jz2Ot}2C@S0ojKQoxhYlccp z+!|?H>><7ceV!&x>67uDSbaW$8iKBFzc+zewfHxnH8aX{vHg z8fC#4IFVh$!+ab;V*CjoFnb>kAj!Hp1p;eRP|6vOX&;_^q|6H6y+{ z5Mx@?a7eoBgq_;)S-&L76|~Gsd`H6l!so*1yAROc{t<&ky&lF6ne5RdDjv%!Z4-fR z-pGmK?5K(vZ_Lcfnsq({LU;>=+i(-y$0EK3zW$?H2sU`JU>A6ZjKR#0*1=X6$7O12 zYM8&e_cMnX;{+V`Ls-0=_67%&}2wnF|RfTom0J@ z8M#vHMd@%%P44LE7a0a&>3 zOEkqwOso?E0s40$wowM`&b^8Zjt`@T>ACS8^Zok`@L)=Gfr1+~5Psb>Et=*_Kn7l; zdV(!&RbMCXCvO|IG#bGcmVE?T{6D)n;wAk)aLXAHykoiDo0D_q@z6LI-U7VoTd|2B z0Nm#De)J`EC&REQr#C=sGoLx`-O&MB#7;uPw}M;BGhp8t0DBH#ZUDf;JaD-H@KV_g z9RHhN4F>H5+zjW3suXJjC*|rUV^D^xL)YPzgY=hAE+&4lF)=z;|MhO<#8O@cS90Rl z13gpIR>GjmoQVpcAr6|Ny+twAP@ECNYPwEI*-xZob$O0qc$>kzO%}zK`@>ZfyVWL4 zW48*Z0Qm%~8Pt!kZ%f&4K>Pm0CMBP@o}UVB{<^&?W^*HQxyOQ@Vz3xbjajX^9xVG# z5O{3|E*^WwfYGd_pfJH*t)r9_<&B`CM{E77{6}l+*Jw$(hk&oehxyF_a6=dZ38p0| zixMxeZl$!5Q#12-FuMX{w746UypxNKa}`4kAzprC^_mw=HkTupvL|K1i5$c8<<~!0 z(D0=diH-pcO5u!&{ev#3g-eXOF{Q)fl*)#mSwkc=D*C5Zeu8pdq{2nx_3x4IWhQn{ z2Fca2VeS{d!(6g5-Ge5FUc`IQaIBz_gD`73A2P?@w+ z9@v(@Ih^0-k>M=iSnGG<5F1TJP1Jm)HbpQ}90Q3uq*X#?+dg|Ih;nXdZ_9%5@(Zyx zD0!{zY)p>5%WV%%*CgixgDPgc<`(_yo;>zKwr-n)S8hM5IZfQ&DcEc*hP^VIbW(!RyXuZjo&76<>h%W>j&`daSfdhXi1mx)Y1du)o9cI9Himx~7KF2C+VTR*w1 zRu9z&(;xe9c$ul`?fKTJMaAZGI`XkoV86J>Tbp)ANG`s#qEVG^(Ry&8*~k2_7Yv9P zbdG2IThyx_60L1$)yO|<*z zmin1j*|gQsz*I2P>*uRK(I^-W1>D{na12Za@A6Sk7?8cs*QVcDI4DtNf<3`%f991Z zg+R0sSramP6Oq@Wr_ahKx^5J@CdvfVU%S92a(;iJm(_G9Cd=rx_x0HtvKpw#u55y9 zQhdC@V*T~ug~p!eGBDAnb;Je#;Khci_E#6OY5aKSp8$i1H68(r9KWD9z8A7!Wpj+Q zMjL7j^Yt5V)QO=f$0!^lE?=J10D|@&2e&rcTW=QSN@Tdk+@2qA(px047wg%JP4uI# z>z0h($09Pit);G;vyWD9Pvu6mE1Rr$)KBH1+y^V1i3D8*1#t5$W4r>R+xp^7B$*o7 z4#v4VHP2|59GNwN0LUpcAU80(pR5bjQ=HE1p-+Afu8+v`PTc3^v|FmemRbVu4I1H-GP>ScF%q(l&EG=93U8VB3@?Opea87+T4H;SIWE)N=P5DdoP4yBCN9pDDylP6EAFg$ML zoa1C8t(GwIh`2NC{R5FIFKS*Sn0e`H+8eEVY}Q_ZO8TJ=|2d6*wFp2URRQCTg}egB zzYm6ohn1*di~;6A9Z9Fwe^dgT5z<2{yU}HGwd_|+Tq+YAWRyR9N7`>SQn5SzlzJy($dQsLT!V=A z?py=y`plY4BLGPI&5X>1H%t<-aeAWMh zP`;v)M~Ra!Y!Qg&IcG-V!e||ZANOCrd?8YKiT2G3{0F)-B>+ge_Af7o21|pkZKIfQ znSY>#j}4z-o@yco`hfZMo>;qu$wtqF$9|}D=%Xi~ zdV*v;1c2)^bFRFo=*>A-`L(gs&7ssbFh!;gZE1nGDjfnljE$f<= zN&$J;kUdOI*#&FXa9PS4Tn?Do3CQjTnG*nCPsZr{?=a+lopS$9_`j-X{+jpyPxJCH z2H|Rab*%AWGD_NDry?-4hp(Vp@>=+3SGV!a@>==NYwJc}1qJ}~JNU@qX5$8q0BWlM sIR3o^G{Rqt@dM&-z<@^hU(c7VMs2!kwyx*$_$EJZcG0xrjN9G+0r#_ifdBvi literal 0 HcmV?d00001 diff --git a/snapcraft.yaml b/snapcraft.yaml index dfd0660..7c4d150 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -124,4 +124,5 @@ parts: make test prime: - usr/bin/anbox + - usr/share/anbox - usr/lib/*-linux-*/ diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index f309491..16f71dd 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -88,8 +88,8 @@ anbox::cmds::Launch::Launch() const auto snap_path = utils::get_env_value("SNAP"); if (!snap_path.empty()) { - const auto resource_path = utils::string_format("%s/share/anbox", snap_path); - SystemConfiguration::instance().set_resource_path(resource_path) + const auto resource_path = utils::string_format("%s/usr/share/anbox", snap_path); + SystemConfiguration::instance().set_resource_path(resource_path); } std::shared_ptr ss; diff --git a/src/anbox/ui/splash_screen.cpp b/src/anbox/ui/splash_screen.cpp index c8c7f86..c4ca6cf 100644 --- a/src/anbox/ui/splash_screen.cpp +++ b/src/anbox/ui/splash_screen.cpp @@ -48,18 +48,16 @@ SplashScreen::SplashScreen() { if (!renderer) BOOST_THROW_EXCEPTION(std::runtime_error("Could not create renderer")); - const auto icon_path = utils::string_format("%s/ui/icon.png", SystemConfiguration::instance().resource_dir()); + const auto icon_path = utils::string_format("%s/ui/loading-screen.png", SystemConfiguration::instance().resource_dir()); auto img = IMG_LoadTexture(renderer, icon_path.c_str()); if (!img) { const auto msg = utils::string_format("Failed to create texture from %s", icon_path); BOOST_THROW_EXCEPTION(std::runtime_error(msg)); } - const auto tex_width = 128, tex_height = 128; - SDL_Rect r{(width - tex_width) / 2, (height - tex_height) / 2, 128, 128}; - - SDL_SetRenderDrawColor(renderer, 0xee, 0xee, 0xee, 0xff); SDL_RenderClear(renderer); + + SDL_Rect r{0, 0, 1024, 768}; SDL_RenderCopy(renderer, img, nullptr, &r); SDL_RenderPresent(renderer); From 352d774760fad55ef7b952481a5bff2dda782c05 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 20:48:15 +0200 Subject: [PATCH 34/86] Prefer empty check over length one --- src/anbox/android/intent.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/anbox/android/intent.cpp b/src/anbox/android/intent.cpp index 8344dc0..2fcd8f0 100644 --- a/src/anbox/android/intent.cpp +++ b/src/anbox/android/intent.cpp @@ -23,19 +23,19 @@ namespace anbox { namespace android { std::ostream &operator<<(std::ostream &out, const Intent &intent) { out << "["; - if (intent.action.length() > 0) + if (!intent.action.empty()) out << " " << "action=" << intent.action << " "; - if (intent.uri.length() > 0) + if (!intent.uri.empty()) out << " " << "uri=" << intent.uri << " "; - if (intent.type.length() > 0) + if (!intent.type.empty()) out << " " << "type=" << intent.type << " "; if (intent.flags > 0) out << " " << "flags=" << intent.flags << " "; - if (intent.package.length() > 0) + if (!intent.package.empty()) out << " " << "package=" << intent.package << " "; - if (intent.component.length() > 0) + if (!intent.component.empty()) out << "component=" << intent.component << " "; - if (intent.categories.size() > 0) { + if (!intent.categories.size() > 0) { out << "categories=[ "; for (const auto &category : intent.categories) out << category << " "; out << "] "; From 7fe8cfeb38ae9436153d5862b0234e1d65eb5fed Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 3 May 2017 21:09:30 +0200 Subject: [PATCH 35/86] Use already defined width and height variables --- src/anbox/ui/splash_screen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anbox/ui/splash_screen.cpp b/src/anbox/ui/splash_screen.cpp index c4ca6cf..d40ebf5 100644 --- a/src/anbox/ui/splash_screen.cpp +++ b/src/anbox/ui/splash_screen.cpp @@ -57,7 +57,7 @@ SplashScreen::SplashScreen() { SDL_RenderClear(renderer); - SDL_Rect r{0, 0, 1024, 768}; + SDL_Rect r{0, 0, width, height}; SDL_RenderCopy(renderer, img, nullptr, &r); SDL_RenderPresent(renderer); From ee4d0b9c49dab3ff651ac5a82320b46011e85361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Rosenkr=C3=A4nzer?= Date: Thu, 4 May 2017 15:44:37 +0200 Subject: [PATCH 36/86] Make sure helper libraries get built as static libs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure helper libraries get built as static libs regardless of the cmake version being used. This fixes issue 217. Signed-off-by: Bernhard Rosenkränzer --- external/android-emugl/host/libs/GLESv1_dec/CMakeLists.txt | 2 +- external/android-emugl/host/libs/GLESv2_dec/CMakeLists.txt | 2 +- .../android-emugl/host/libs/Translator/GLcommon/CMakeLists.txt | 2 +- .../android-emugl/host/libs/libOpenGLESDispatch/CMakeLists.txt | 2 +- .../android-emugl/host/libs/renderControl_dec/CMakeLists.txt | 2 +- external/android-emugl/shared/OpenglCodecCommon/CMakeLists.txt | 2 +- external/android-emugl/shared/emugl/common/CMakeLists.txt | 2 +- external/process-cpp-minimal/src/CMakeLists.txt | 2 ++ external/xdg/CMakeLists.txt | 2 +- src/CMakeLists.txt | 3 ++- 10 files changed, 12 insertions(+), 9 deletions(-) diff --git a/external/android-emugl/host/libs/GLESv1_dec/CMakeLists.txt b/external/android-emugl/host/libs/GLESv1_dec/CMakeLists.txt index e8d83e2..c0b79af 100644 --- a/external/android-emugl/host/libs/GLESv1_dec/CMakeLists.txt +++ b/external/android-emugl/host/libs/GLESv1_dec/CMakeLists.txt @@ -20,5 +20,5 @@ if ("${cmake_build_type_lower}" STREQUAL "trace") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENGL_DEBUG}") endif() -add_library(GLESv1_dec ${SOURCES} ${GENERATED_SOURCES}) +add_library(GLESv1_dec STATIC ${SOURCES} ${GENERATED_SOURCES}) target_link_libraries(GLESv1_dec OpenglCodecCommon) diff --git a/external/android-emugl/host/libs/GLESv2_dec/CMakeLists.txt b/external/android-emugl/host/libs/GLESv2_dec/CMakeLists.txt index 140d061..6bd78c5 100644 --- a/external/android-emugl/host/libs/GLESv2_dec/CMakeLists.txt +++ b/external/android-emugl/host/libs/GLESv2_dec/CMakeLists.txt @@ -20,5 +20,5 @@ if ("${cmake_build_type_lower}" STREQUAL "trace") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENGL_DEBUG}") endif() -add_library(GLESv2_dec ${SOURCES} ${GENERATED_SOURCES}) +add_library(GLESv2_dec STATIC ${SOURCES} ${GENERATED_SOURCES}) target_link_libraries(GLESv2_dec OpenglCodecCommon) diff --git a/external/android-emugl/host/libs/Translator/GLcommon/CMakeLists.txt b/external/android-emugl/host/libs/Translator/GLcommon/CMakeLists.txt index 79339f6..9f553f9 100644 --- a/external/android-emugl/host/libs/Translator/GLcommon/CMakeLists.txt +++ b/external/android-emugl/host/libs/Translator/GLcommon/CMakeLists.txt @@ -12,6 +12,6 @@ set(SOURCES objectNameManager.cpp FramebufferData.cpp) -add_library(GLcommon ${SOURCES}) +add_library(GLcommon STATIC ${SOURCES}) target_link_libraries(GLcommon emugl_common) diff --git a/external/android-emugl/host/libs/libOpenGLESDispatch/CMakeLists.txt b/external/android-emugl/host/libs/libOpenGLESDispatch/CMakeLists.txt index 715fa8b..c4bd232 100644 --- a/external/android-emugl/host/libs/libOpenGLESDispatch/CMakeLists.txt +++ b/external/android-emugl/host/libs/libOpenGLESDispatch/CMakeLists.txt @@ -3,7 +3,7 @@ set(SOURCES GLESv2Dispatch.cpp GLESv1Dispatch.cpp) -add_library(OpenGLESDispatch ${SOURCES} ${GENERATED_SOURCES}) +add_library(OpenGLESDispatch STATIC ${SOURCES} ${GENERATED_SOURCES}) target_link_libraries(OpenGLESDispatch emugl_common GLESv2_dec diff --git a/external/android-emugl/host/libs/renderControl_dec/CMakeLists.txt b/external/android-emugl/host/libs/renderControl_dec/CMakeLists.txt index cb67c5a..4b0786f 100644 --- a/external/android-emugl/host/libs/renderControl_dec/CMakeLists.txt +++ b/external/android-emugl/host/libs/renderControl_dec/CMakeLists.txt @@ -16,5 +16,5 @@ if ("${cmake_build_type_lower}" STREQUAL "trace") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENGL_DEBUG}") endif() -add_library(renderControl_dec ${GENERATED_SOURCES}) +add_library(renderControl_dec STATIC ${GENERATED_SOURCES}) target_link_libraries(renderControl_dec OpenglCodecCommon) diff --git a/external/android-emugl/shared/OpenglCodecCommon/CMakeLists.txt b/external/android-emugl/shared/OpenglCodecCommon/CMakeLists.txt index 67606d7..fe3db64 100644 --- a/external/android-emugl/shared/OpenglCodecCommon/CMakeLists.txt +++ b/external/android-emugl/shared/OpenglCodecCommon/CMakeLists.txt @@ -12,4 +12,4 @@ set(SOURCES Makefile ProtocolUtils.h) -add_library(OpenglCodecCommon ${SOURCES}) +add_library(OpenglCodecCommon STATIC ${SOURCES}) diff --git a/external/android-emugl/shared/emugl/common/CMakeLists.txt b/external/android-emugl/shared/emugl/common/CMakeLists.txt index ef8b6d2..09388c6 100644 --- a/external/android-emugl/shared/emugl/common/CMakeLists.txt +++ b/external/android-emugl/shared/emugl/common/CMakeLists.txt @@ -28,6 +28,6 @@ set(COMMON_SOURCES thread_unittest.cpp unique_integer_map.h) -add_library(emugl_common ${COMMON_SOURCES}) +add_library(emugl_common STATIC ${COMMON_SOURCES}) target_link_libraries(emugl_common dl pthread) diff --git a/external/process-cpp-minimal/src/CMakeLists.txt b/external/process-cpp-minimal/src/CMakeLists.txt index 8daf938..dec4659 100644 --- a/external/process-cpp-minimal/src/CMakeLists.txt +++ b/external/process-cpp-minimal/src/CMakeLists.txt @@ -15,6 +15,8 @@ # Authored by: Thomas Voss add_library( process-cpp + + STATIC core/posix/backtrace.h core/posix/backtrace.cpp diff --git a/external/xdg/CMakeLists.txt b/external/xdg/CMakeLists.txt index f19f69d..249da48 100644 --- a/external/xdg/CMakeLists.txt +++ b/external/xdg/CMakeLists.txt @@ -11,7 +11,7 @@ include_directories( ${Boost_INCLUDE_DIRS} ) -add_library(xdg xdg.cpp) +add_library(xdg STATIC xdg.cpp) set_property(TARGET xdg PROPERTY CXX_STANDARD 11) target_link_libraries(xdg ${Boost_LIBRARIES}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5675ccb..0229795 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,6 +41,7 @@ protobuf_generate_cpp( add_library(anbox-protobuf + STATIC ${GENERATED_PROTOBUF_BRIDGE_SRCS} ${GENERATED_PROTOBUF_BRIDGE_HDRS} ${GENERATED_PROTOBUF_RPC_SRCS} @@ -207,7 +208,7 @@ set(SOURCES anbox/optional.h anbox/defer_action.h) -add_library(anbox-core ${SOURCES}) +add_library(anbox-core STATIC ${SOURCES}) target_link_libraries(anbox-core ${Boost_LDFLAGS} ${Boost_LIBRARIES} From dfdad4aa6c626c7441e20e3b1fea359037afa65d Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 5 May 2017 07:05:25 +0200 Subject: [PATCH 37/86] Integrate review feedback --- src/anbox/cmds/launch.cpp | 15 +++++++++++---- src/anbox/config.cpp | 2 +- src/anbox/config.h | 2 +- src/anbox/ui/splash_screen.cpp | 7 +------ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index 16f71dd..afbd2ab 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -88,8 +88,8 @@ anbox::cmds::Launch::Launch() const auto snap_path = utils::get_env_value("SNAP"); if (!snap_path.empty()) { - const auto resource_path = utils::string_format("%s/usr/share/anbox", snap_path); - SystemConfiguration::instance().set_resource_path(resource_path); + const auto resource_path = fs::path(snap_path) / "usr" / "share" / "anbox"; + SystemConfiguration::instance().set_resource_path(resource_path.string()); } std::shared_ptr ss; @@ -126,12 +126,17 @@ anbox::cmds::Launch::Launch() } try { - const auto flags = core::posix::StandardStream::empty; // core::posix::StandardStream::stdout | core::posix::StandardStream::stderr; + const auto flags = core::posix::StandardStream::stdout | core::posix::StandardStream::stderr; auto child = core::posix::fork([&]() { auto grandchild = core::posix::exec(exe_path, args, env, flags); grandchild.dont_kill_on_cleanup(); return core::posix::exit::Status::success; }, flags); + + // We don't wait for the grandchild but the child as we use double forking + // here to break through the process hierarchy and make the grandchild a + // direct child of the init process so it keeps running on its own and + // indepent of our short living process here. child.wait_for(core::posix::wait::Flags::untraced); DEBUG("Started session manager, will now try to connect .."); @@ -173,8 +178,10 @@ anbox::cmds::Launch::Launch() boost::asio::deadline_timer timer(rt->service()); timer.expires_from_now(max_wait_timeout); timer.async_wait([&](const boost::system::error_code&) { - WARNING("Stopped waiting as we're already waited for too long. Something"); + WARNING("Stopped waiting as we've already waited for too long. Something"); WARNING("is wrong with your setup or the container has failed to boot."); + WARNING("If you think you found a bug please don't hesitate to file on"); + WARNING("at https://github.com/anbox/anbox/issues/new"); trap->stop(); }); diff --git a/src/anbox/config.cpp b/src/anbox/config.cpp index d6be507..a13aa43 100644 --- a/src/anbox/config.cpp +++ b/src/anbox/config.cpp @@ -41,7 +41,7 @@ void anbox::SystemConfiguration::set_data_path(const std::string &path) { data_path = path; } -void anbox::SystemConfiguration::set_resource_path(const std::string &path) { +void anbox::SystemConfiguration::set_resource_path(const fs::path &path) { resource_path = path; } diff --git a/src/anbox/config.h b/src/anbox/config.h index e3417d8..47a518e 100644 --- a/src/anbox/config.h +++ b/src/anbox/config.h @@ -31,7 +31,7 @@ class SystemConfiguration { virtual ~SystemConfiguration() = default; void set_data_path(const std::string &path); - void set_resource_path(const std::string &path); + void set_resource_path(const boost::filesystem &path); boost::filesystem::path data_dir() const; std::string rootfs_dir() const; diff --git a/src/anbox/ui/splash_screen.cpp b/src/anbox/ui/splash_screen.cpp index d40ebf5..b52c817 100644 --- a/src/anbox/ui/splash_screen.cpp +++ b/src/anbox/ui/splash_screen.cpp @@ -82,12 +82,7 @@ void SplashScreen::process_events() { while (event_thread_running_) { SDL_Event event; while (SDL_WaitEventTimeout(&event, 100)) { - switch (event.type) { - case SDL_QUIT: - break; - default: - break; - } + // Keep running until we're terminated } } } From 45ac3ecf6ade13dd796dea9f68e8211af9171e0f Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 5 May 2017 07:50:14 +0200 Subject: [PATCH 38/86] Set version we're building from snapcraft --- CMakeLists.txt | 11 +++++ snapcraft.yaml | 5 ++ src/CMakeLists.txt | 4 +- src/anbox/{version.cpp => build/version.h.in} | 25 +++++++--- src/anbox/cmds/system_info.cpp | 9 ++-- src/anbox/cmds/version.cpp | 7 ++- src/anbox/version.h | 46 ------------------- 7 files changed, 43 insertions(+), 64 deletions(-) rename src/anbox/{version.cpp => build/version.h.in} (55%) delete mode 100644 src/anbox/version.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 957664b..a3fe59e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,17 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -fPIC") set(ANBOX_TRANSLATOR_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/anbox/translators) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTRANSLATOR_INSTALL_DIR=\\\"${CMAKE_INSTALL_PREFIX}/${ANBOX_TRANSLATOR_INSTALL_DIR}\\\"") +if (NOT VERSION) + set(VERSION 2) + if ("${cmake_build_type_lower}" STREQUAL "release") + set(VERSION_SUFFIX "") + else() + set(VERSION_SUFFIX dev) + endif() +endif() +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/anbox/build/version.h.in + ${CMAKE_CURRENT_SOURCE_DIR}/src/anbox/build/version.h) + add_subdirectory(external) add_subdirectory(src) add_subdirectory(tests) diff --git a/snapcraft.yaml b/snapcraft.yaml index 12cf904..a32e30e 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,4 +1,8 @@ name: anbox +# NOTE: Always only use increasing numeric values here. This is +# passed down into cmake and assigned to an integer variable which +# can be used for version number comparision inside the code base +# to accomondate for any breaking changes. version: 2 summary: Android in a Box description: | @@ -84,6 +88,7 @@ parts: # FIXME: Anbox currently has some paths with hard coded prefixes. Once # that is fixed we can avoid using a prefix here. - -DCMAKE_INSTALL_PREFIX:PATH=/usr + - -DVERSION=$SNAPCRAFT_PROJECT_VERSION build-packages: - build-essential - cmake diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0229795..42f07bd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -57,11 +57,13 @@ set(SOURCES anbox/utils.cpp anbox/cli.cpp anbox/runtime.cpp - anbox/version.cpp anbox/daemon.cpp anbox/config.cpp anbox/not_reachable.cpp + anbox/build/version.cpp + anbox/build/version.h.in + anbox/android/intent.cpp anbox/common/fd.cpp diff --git a/src/anbox/version.cpp b/src/anbox/build/version.h.in similarity index 55% rename from src/anbox/version.cpp rename to src/anbox/build/version.h.in index 8759db7..da4a288 100644 --- a/src/anbox/version.cpp +++ b/src/anbox/build/version.h.in @@ -17,11 +17,22 @@ * */ -#include "anbox/version.h" +#ifndef ANBOX_VERSION_H_ +#define ANBOX_VERSION_H_ -void anbox::version(std::uint32_t& major, std::uint32_t& minor, - std::uint32_t& patch) { - major = anbox::build::version_major; - minor = anbox::build::version_minor; - patch = anbox::build::version_patch; -} +#include +#include + +namespace anbox { +namespace build { +/// @brief version_major marks the major version +static constexpr const std::uint32_t version_major{@VERSION@}; +/// @brief version_suffix is an additional suffix which can be amended to +/// the major version number to indicate a dev build for example. +static const std::string version_suffix{"@VERSION_SUFFIX@"}; +/// @brief version queries the version of Anbox +std::string version(); +} // namespace build +} // namespace anbox + +#endif // ANBOX_VERSION_H_ diff --git a/src/anbox/cmds/system_info.cpp b/src/anbox/cmds/system_info.cpp index 421f11c..d503cc0 100644 --- a/src/anbox/cmds/system_info.cpp +++ b/src/anbox/cmds/system_info.cpp @@ -19,9 +19,9 @@ #include "anbox/graphics/emugl/RenderApi.h" #include "anbox/graphics/emugl/DispatchTables.h" #include "anbox/utils/environment_file.h" -#include "anbox/version.h" #include "anbox/logger.h" -#include "anbox/version.h" + +#include "anbox/build/version.h" #include #include @@ -50,10 +50,7 @@ class SystemInformation { std::stringstream s; s << "version: " - << anbox::utils::string_format("%d.%d.%d", - anbox::build::version_major, - anbox::build::version_minor, - anbox::build::version_patch) + << anbox::build::version() << std::endl; s << "os:" << std::endl diff --git a/src/anbox/cmds/version.cpp b/src/anbox/cmds/version.cpp index c405e48..3ce15e1 100644 --- a/src/anbox/cmds/version.cpp +++ b/src/anbox/cmds/version.cpp @@ -18,16 +18,15 @@ */ #include "anbox/cmds/version.h" -#include "anbox/version.h" +#include "anbox/build/version.h" +#include "anbox/utils.h" anbox::cmds::Version::Version() : CommandWithFlagsAndAction{ cli::Name{"version"}, cli::Usage{"version"}, cli::Description{"print the version of the daemon"}} { action([](const cli::Command::Context& ctxt) { - std::uint32_t major, minor, patch; - anbox::version(major, minor, patch); - ctxt.cout << "anbox " << major << "." << minor << "." << patch << std::endl; + ctxt.cout << "anbox " << build::version() << std::endl; return 0; }); } diff --git a/src/anbox/version.h b/src/anbox/version.h deleted file mode 100644 index 11617ae..0000000 --- a/src/anbox/version.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2016 Canonical, Ltd. - * - * 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 . - * - * Authored by: Thomas Voß - * - */ - -#ifndef ANBOX_VERSION_H_ -#define ANBOX_VERSION_H_ - -#include - -namespace anbox { -namespace build { -/// @brief version_major marks the major version of the library. The constant is -/// meant to be used -/// by client code both at build and runtime, enabling version checks. -static constexpr const std::uint32_t version_major{0}; -/// @brief version_major marks the minor version of the library. The constant is -/// meant to be used -/// by client code both at build and runtime, enabling version checks. -static constexpr const std::uint32_t version_minor{1}; -/// @brief version_patch marks the major version of the library. The constant is -/// meant to be used -/// by client code both at build and runtime, enabling version checks. -static constexpr const std::uint32_t version_patch{0}; -} // namespace build - -/// @brief version queries the version of the library, placing the result in -/// major, minor and patch. -void version(std::uint32_t& major, std::uint32_t& minor, std::uint32_t& patch); -} // namespace build - -#endif // ANBOX_VERSION_H_ From 68dba196bab47e98d30c17d715bcb1f143bf4d3b Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 5 May 2017 07:53:43 +0200 Subject: [PATCH 39/86] Add libsdl2-image-dev as build dependency for travis --- scripts/clean-build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/clean-build.sh b/scripts/clean-build.sh index d7219d7..ab659bb 100755 --- a/scripts/clean-build.sh +++ b/scripts/clean-build.sh @@ -32,6 +32,7 @@ apt-get install -qq -y \ libproperties-cpp-dev \ libprotobuf-dev \ libsdl2-dev \ + libsdl2-image-dev \ lxc-dev \ pkg-config \ protobuf-compiler From 16831f100e9d4d9b99f4aeba20ccf48d4a243350 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 5 May 2017 08:09:52 +0200 Subject: [PATCH 40/86] Integrate review feedback --- CMakeLists.txt | 8 ++++---- src/anbox/build/version.h.in | 6 +++--- src/anbox/cmds/system_info.cpp | 2 +- src/anbox/cmds/version.cpp | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a3fe59e..8e75384 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,12 +94,12 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -fPIC") set(ANBOX_TRANSLATOR_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/anbox/translators) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTRANSLATOR_INSTALL_DIR=\\\"${CMAKE_INSTALL_PREFIX}/${ANBOX_TRANSLATOR_INSTALL_DIR}\\\"") -if (NOT VERSION) - set(VERSION 2) +if (NOT ANBOX_VERSION) + set(ANBOX_VERSION 2) if ("${cmake_build_type_lower}" STREQUAL "release") - set(VERSION_SUFFIX "") + set(ANBOX_VERSION_SUFFIX "") else() - set(VERSION_SUFFIX dev) + set(ANBOX_VERSION_SUFFIX dev) endif() endif() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/anbox/build/version.h.in diff --git a/src/anbox/build/version.h.in b/src/anbox/build/version.h.in index da4a288..e6dcbbd 100644 --- a/src/anbox/build/version.h.in +++ b/src/anbox/build/version.h.in @@ -26,12 +26,12 @@ namespace anbox { namespace build { /// @brief version_major marks the major version -static constexpr const std::uint32_t version_major{@VERSION@}; +static constexpr const std::uint32_t version_major{@ANBOX_VERSION@}; /// @brief version_suffix is an additional suffix which can be amended to /// the major version number to indicate a dev build for example. -static const std::string version_suffix{"@VERSION_SUFFIX@"}; +static constexpr const char *version_suffix{"@ANBOX_VERSION_SUFFIX@"}; /// @brief version queries the version of Anbox -std::string version(); +std::string print_version(); } // namespace build } // namespace anbox diff --git a/src/anbox/cmds/system_info.cpp b/src/anbox/cmds/system_info.cpp index d503cc0..ef90366 100644 --- a/src/anbox/cmds/system_info.cpp +++ b/src/anbox/cmds/system_info.cpp @@ -50,7 +50,7 @@ class SystemInformation { std::stringstream s; s << "version: " - << anbox::build::version() + << anbox::build::print_version() << std::endl; s << "os:" << std::endl diff --git a/src/anbox/cmds/version.cpp b/src/anbox/cmds/version.cpp index 3ce15e1..d8aef39 100644 --- a/src/anbox/cmds/version.cpp +++ b/src/anbox/cmds/version.cpp @@ -26,7 +26,7 @@ anbox::cmds::Version::Version() cli::Name{"version"}, cli::Usage{"version"}, cli::Description{"print the version of the daemon"}} { action([](const cli::Command::Context& ctxt) { - ctxt.cout << "anbox " << build::version() << std::endl; + ctxt.cout << "anbox " << build::print_version() << std::endl; return 0; }); } From 6c65da7a2ce0564e0a266773d8f80a8aa216da29 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 5 May 2017 08:15:34 +0200 Subject: [PATCH 41/86] Add missing version source file --- src/anbox/build/version.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/anbox/build/version.cpp diff --git a/src/anbox/build/version.cpp b/src/anbox/build/version.cpp new file mode 100644 index 0000000..38298c6 --- /dev/null +++ b/src/anbox/build/version.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 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 . + * + */ + +#include "anbox/build/version.h" +#include "anbox/utils.h" + +namespace anbox { +namespace build { +std::string print_version() { + static std::string v; + if (v.empty()) { + if (version_suffix.empty()) + v = utils::string_format("%d", version_major); + else + v = utils::string_format("%d-%s", version_major, version_suffix); + } + return v; +} +} // namespace build +} // namespace anbox From 7b737733bad72da1bf2d08b3c6271007699749e9 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 5 May 2017 18:36:58 +0200 Subject: [PATCH 42/86] Rework version string initialization --- src/anbox/build/version.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/anbox/build/version.cpp b/src/anbox/build/version.cpp index 38298c6..07576e9 100644 --- a/src/anbox/build/version.cpp +++ b/src/anbox/build/version.cpp @@ -18,16 +18,21 @@ #include "anbox/build/version.h" #include "anbox/utils.h" +#include + namespace anbox { namespace build { +static std::string init_version_string() { + std::string v; + if (!version_suffix || std::strlen(version_suffix) == 0) + v = utils::string_format("%d", version_major); + else + v = utils::string_format("%d-%s", version_major, version_suffix); + return v; +} + std::string print_version() { - static std::string v; - if (v.empty()) { - if (version_suffix.empty()) - v = utils::string_format("%d", version_major); - else - v = utils::string_format("%d-%s", version_major, version_suffix); - } + static const std::string v{init_version_string()}; return v; } } // namespace build From 189003ef953912a8a6c4d7f40335afac18502c49 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 5 May 2017 18:41:52 +0200 Subject: [PATCH 43/86] Correct exception handling --- src/anbox/cmds/launch.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index afbd2ab..f373c61 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -44,10 +44,14 @@ bool anbox::cmds::Launch::try_launch_activity(const std::shared_ptrlaunch(intent_, graphics::Rect::Invalid, stack_); - } catch (std::exception &err) { + } catch (const std::exception &err) { ERROR("Failed to launch activity: %s", err.what()); return false; + } catch (...) { + ERROR("Failed to launch activity"); + return false; } + return true; } From 8c1247c0a8fd57fb1e37f064bf4c0956f84d58b7 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 5 May 2017 18:45:52 +0200 Subject: [PATCH 44/86] Use boost::filesystem::path correctly --- src/anbox/cmds/launch.cpp | 2 +- src/anbox/config.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index f373c61..69830aa 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -93,7 +93,7 @@ anbox::cmds::Launch::Launch() const auto snap_path = utils::get_env_value("SNAP"); if (!snap_path.empty()) { const auto resource_path = fs::path(snap_path) / "usr" / "share" / "anbox"; - SystemConfiguration::instance().set_resource_path(resource_path.string()); + SystemConfiguration::instance().set_resource_path(resource_path); } std::shared_ptr ss; diff --git a/src/anbox/config.h b/src/anbox/config.h index 47a518e..0fce571 100644 --- a/src/anbox/config.h +++ b/src/anbox/config.h @@ -31,7 +31,7 @@ class SystemConfiguration { virtual ~SystemConfiguration() = default; void set_data_path(const std::string &path); - void set_resource_path(const boost::filesystem &path); + void set_resource_path(const boost::filesystem::path &path); boost::filesystem::path data_dir() const; std::string rootfs_dir() const; From dbcc5cfba02faa56604d7959e11010cbff5b22d2 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sun, 7 May 2017 11:46:59 +0200 Subject: [PATCH 45/86] Fix incorrect logical expression for intent check --- src/anbox/android/intent.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anbox/android/intent.cpp b/src/anbox/android/intent.cpp index 2fcd8f0..4f5e659 100644 --- a/src/anbox/android/intent.cpp +++ b/src/anbox/android/intent.cpp @@ -35,7 +35,7 @@ std::ostream &operator<<(std::ostream &out, const Intent &intent) { out << " " << "package=" << intent.package << " "; if (!intent.component.empty()) out << "component=" << intent.component << " "; - if (!intent.categories.size() > 0) { + if (intent.categories.size() > 0) { out << "categories=[ "; for (const auto &category : intent.categories) out << category << " "; out << "] "; From 8d4c9dadc42e530dedf7cae691e7539a4f8cd0a4 Mon Sep 17 00:00:00 2001 From: Matlink Date: Mon, 8 May 2017 10:16:38 +0200 Subject: [PATCH 46/86] Adding libsdl2-image-dev dependency --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8434312..3486b6b 100644 --- a/README.md +++ b/README.md @@ -130,8 +130,8 @@ $ sudo apt install build-essential cmake cmake-data debhelper dbus google-mock \ libboost-program-options-dev libboost-system-dev libboost-test-dev \ libboost-thread-dev libcap-dev libdbus-1-dev libdbus-cpp-dev libegl1-mesa-dev \ libgles2-mesa-dev libglib2.0-dev libglm-dev libgtest-dev liblxc1 \ - libproperties-cpp-dev libprotobuf-dev libsdl2-dev lxc-dev pkg-config \ - protobuf-compiler + libproperties-cpp-dev libprotobuf-dev libsdl2-dev libsdl2-image-dev lxc-dev \ + pkg-config protobuf-compiler ``` Afterwards you can build Anbox with From 41530325eca28154e10c092cf4d1cddad43b4aa2 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 9 May 2017 07:20:56 +0200 Subject: [PATCH 47/86] Read host os-release file when running inside the snap --- src/anbox/cmds/system_info.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/anbox/cmds/system_info.cpp b/src/anbox/cmds/system_info.cpp index ef90366..60f4bf9 100644 --- a/src/anbox/cmds/system_info.cpp +++ b/src/anbox/cmds/system_info.cpp @@ -34,6 +34,7 @@ namespace fs = boost::filesystem; namespace { constexpr const char *os_release_path{"/etc/os-release"}; +constexpr const char *host_os_release_path{"/var/lib/snapd/hostfs/etc/os-release"}; constexpr const char *proc_version_path{"/proc/version"}; constexpr const char *binder_path{"/dev/binder"}; constexpr const char *ashmem_path{"/dev/ashmem"}; @@ -94,14 +95,18 @@ class SystemInformation { private: void collect_os_info() { os_info_.snap_based = (getenv("SNAP") != nullptr); - if (fs::exists(os_release_path)) { + fs::path path = os_release_path; + // If we're running from within a snap the best we can do is to + // access the hostfs and read the os-release file from there. + if (os_info_.snap_based && fs::exists(host_os_release_path)) + path = host_os_release_path; + + // Double check that there aren't any permission errors when trying + // to access the file (e.g. because of snap confinement) + if (fs::exists(path)) { anbox::utils::EnvironmentFile os_release(os_release_path); os_info_.name = os_release.value("NAME"); os_info_.version = os_release.value("VERSION"); - } else if (os_info_.snap_based) { - // As we can't read /etc/os-release and we're snap-based this is the best we can guess - os_info_.name = "Ubuntu"; - os_info_.version = "16"; } } From a8045e0c8c70e246333050bb5897252d5388d926 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 9 May 2017 07:27:21 +0200 Subject: [PATCH 48/86] Print snap revision if running inside a snap --- src/anbox/cmds/system_info.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/anbox/cmds/system_info.cpp b/src/anbox/cmds/system_info.cpp index ef90366..ea53d3a 100644 --- a/src/anbox/cmds/system_info.cpp +++ b/src/anbox/cmds/system_info.cpp @@ -53,6 +53,12 @@ class SystemInformation { << anbox::build::print_version() << std::endl; + if (anbox::utils::is_env_set("SNAP_REVISION")) { + s << "snap-revision: " + << anbox::utils::get_env_value("SNAP_REVISION") + << std::endl; + } + s << "os:" << std::endl << " name: " << os_info_.name << std::endl << " version: " << os_info_.version << std::endl From 385bf94d51ebbdd5c6c96c475e81e15b7bc48253 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 9 May 2017 09:51:38 +0200 Subject: [PATCH 49/86] Integrate review feedback --- src/anbox/cmds/system_info.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/anbox/cmds/system_info.cpp b/src/anbox/cmds/system_info.cpp index 60f4bf9..9dd54c8 100644 --- a/src/anbox/cmds/system_info.cpp +++ b/src/anbox/cmds/system_info.cpp @@ -38,6 +38,8 @@ constexpr const char *host_os_release_path{"/var/lib/snapd/hostfs/etc/os-release constexpr const char *proc_version_path{"/proc/version"}; constexpr const char *binder_path{"/dev/binder"}; constexpr const char *ashmem_path{"/dev/ashmem"}; +constexpr const char *os_release_name{"NAME"}; +constexpr const char *os_release_version{"VERSION"}; class SystemInformation { public: @@ -94,7 +96,7 @@ class SystemInformation { private: void collect_os_info() { - os_info_.snap_based = (getenv("SNAP") != nullptr); + os_info_.snap_based = !anbox::utils::get_env_value("SNAP").empty(); fs::path path = os_release_path; // If we're running from within a snap the best we can do is to // access the hostfs and read the os-release file from there. @@ -104,9 +106,9 @@ class SystemInformation { // Double check that there aren't any permission errors when trying // to access the file (e.g. because of snap confinement) if (fs::exists(path)) { - anbox::utils::EnvironmentFile os_release(os_release_path); - os_info_.name = os_release.value("NAME"); - os_info_.version = os_release.value("VERSION"); + anbox::utils::EnvironmentFile os_release(path); + os_info_.name = os_release.value(os_release_name); + os_info_.version = os_release.value(os_release_version); } } From c5f1a2724bfa802d8b2b197c4d159aa9eb63f300 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 10 May 2017 19:05:33 +0200 Subject: [PATCH 50/86] Implement BinaryWriter class to allow writing binary data --- src/CMakeLists.txt | 1 + src/anbox/common/binary_writer.cpp | 106 +++++++++++++++++++++ src/anbox/common/binary_writer.h | 57 +++++++++++ tests/anbox/common/CMakeLists.txt | 1 + tests/anbox/common/binary_writer_tests.cpp | 100 +++++++++++++++++++ 5 files changed, 265 insertions(+) create mode 100644 src/anbox/common/binary_writer.cpp create mode 100644 src/anbox/common/binary_writer.h create mode 100644 tests/anbox/common/binary_writer_tests.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 43eb183..557558c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -79,6 +79,7 @@ set(SOURCES anbox/common/loop_device.cpp anbox/common/loop_device_allocator.cpp anbox/common/mount_entry.cpp + anbox/common/binary_writer.cpp anbox/testing/gtest_utils.h diff --git a/src/anbox/common/binary_writer.cpp b/src/anbox/common/binary_writer.cpp new file mode 100644 index 0000000..f6d4973 --- /dev/null +++ b/src/anbox/common/binary_writer.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2016 Thomas Voss + * 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 . + * + */ + +#include "anbox/common/binary_writer.h" + +#include +#include + +#include + +namespace { +bool is_little_endian() { + std::uint32_t v = 1; + return (*reinterpret_cast(&v) == 1); +} +} + +namespace anbox { +namespace common { + +BinaryWriter::BinaryWriter(std::vector::iterator begin, + std::vector::iterator end) : + begin_{begin}, current_{begin}, end_{end}, + byte_order_{is_little_endian() ? Order::Little : Order::Big} {} + +void BinaryWriter::set_byte_order(Order order) { + byte_order_ = order; +} + +void BinaryWriter::write_unsigned_short(std::uint16_t value) { + if (current_ + sizeof(value) > end_) + throw std::out_of_range{"Write buffer exhausted"}; + + std::uint16_t v = value; + switch (byte_order_) { + case Order::Big: + v = boost::endian::native_to_big(value); + break; + case Order::Little: + v = boost::endian::native_to_little(value); + break; + default: + break; + } + + *reinterpret_cast(&(*current_)) = v; + current_ += sizeof(v); +} + +void BinaryWriter::write_unsigned_long(std::uint32_t value) { + if (current_ + sizeof(value) > end_) + throw std::out_of_range{"Write buffer exhausted"}; + + std::uint32_t v = value; + switch (byte_order_) { + case Order::Big: + v = boost::endian::native_to_big(value); + break; + case Order::Little: + v = boost::endian::native_to_little(value); + break; + default: + break; + } + + *reinterpret_cast(&(*current_)) = v; + current_ += sizeof(v); +} + +void BinaryWriter::write_string(const char *s, std::size_t size) { + if (current_ + size > end_) + throw std::out_of_range{"Write buffer exhausted"}; + + memcpy(&(*current_), s, size); + current_ += size; +} + +void BinaryWriter::write_string_with_size(const std::string &str) { + write_string_with_size(str.c_str(), str.length()); +} + +void BinaryWriter::write_string_with_size(const char *s, std::size_t size) { + write_unsigned_short(size); + write_string(s, size); +} + +std::size_t BinaryWriter::bytes_written() const { + return current_ - begin_; +} +} // namespace common +} // namespace anbox diff --git a/src/anbox/common/binary_writer.h b/src/anbox/common/binary_writer.h new file mode 100644 index 0000000..f2aeefd --- /dev/null +++ b/src/anbox/common/binary_writer.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2016 Thomas Voss + * 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_COMMON_BINARY_WRITER_H_ +#define ANBOX_COMMON_BINARY_WRITER_H_ + +#include +#include +#include + +namespace anbox { +namespace common { +class BinaryWriter { + public: + enum class Order { + Big, + Little, + }; + + explicit BinaryWriter(std::vector::iterator begin_, + std::vector::iterator end_); + + void set_byte_order(Order order); + + void write_unsigned_short(std::uint16_t value); + void write_unsigned_long(std::uint32_t value); + void write_string(const char *s, std::size_t size); + void write_string_with_size(const std::string &str); + void write_string_with_size(const char *s, std::size_t size); + + std::size_t bytes_written() const; + + private: + std::vector::iterator begin_; + std::vector::iterator current_; + std::vector::iterator end_; + Order byte_order_; +}; +} // namespace common +} // namespace anbox + +#endif diff --git a/tests/anbox/common/CMakeLists.txt b/tests/anbox/common/CMakeLists.txt index 4d04ebe..facd443 100644 --- a/tests/anbox/common/CMakeLists.txt +++ b/tests/anbox/common/CMakeLists.txt @@ -2,3 +2,4 @@ ANBOX_ADD_TEST(message_channel_tests message_channel_tests.cpp) ANBOX_ADD_TEST(small_vector_tests small_vector_tests.cpp) ANBOX_ADD_TEST(type_traits_tests type_traits_tests.cpp) ANBOX_ADD_TEST(scope_ptr_tests scope_ptr_tests.cpp) +ANBOX_ADD_TEST(binary_writer_tests binary_writer_tests.cpp) diff --git a/tests/anbox/common/binary_writer_tests.cpp b/tests/anbox/common/binary_writer_tests.cpp new file mode 100644 index 0000000..4f12a23 --- /dev/null +++ b/tests/anbox/common/binary_writer_tests.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2017 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 . + * + */ + +#include "anbox/common/binary_writer.h" + +#include + +namespace ac = anbox::common; + +using namespace ::testing; + +TEST(BinaryWriter, WritesUnsignedLong) { + std::vector buffer; + buffer.resize(sizeof(std::uint32_t) * 2); + ac::BinaryWriter writer(buffer.begin(), buffer.end()); + + writer.write_unsigned_long(0x10); + writer.write_unsigned_long(0x3322); + + ASSERT_THAT(buffer, ElementsAre(0x10, 0x00, 0x00, 0x00, 0x22, 0x33, 0x00, 0x00)); +} + +TEST(BinaryWriter, WriteUnsignedLongFailsWithExhaustedError) { + std::vector buffer; + ac::BinaryWriter writer(buffer.begin(), buffer.end()); + EXPECT_THROW(writer.write_unsigned_long(0x11), std::out_of_range); +} + +TEST(BinaryWriter, WriteUnsignedLongWithChangedBinaryOrder) { + std::vector buffer; + buffer.resize(sizeof(std::uint32_t)); + ac::BinaryWriter writer(buffer.begin(), buffer.end()); + + writer.set_byte_order(ac::BinaryWriter::Order::Big); + writer.write_unsigned_long(0x11223344); + + ASSERT_THAT(buffer, ElementsAre(0x11, 0x22, 0x33, 0x44)); + + buffer.clear(); + buffer.resize(sizeof(std::uint32_t)); + + writer = ac::BinaryWriter(buffer.begin(), buffer.end()); + + writer.set_byte_order(ac::BinaryWriter::Order::Little); + writer.write_unsigned_long(0x11223344); + + ASSERT_THAT(buffer, ElementsAre(0x44, 0x33, 0x22, 0x11)); +} + +TEST(BinaryWriter, WriteUnsignedShort) { + std::vector buffer; + buffer.resize(sizeof(std::uint16_t) * 2); + ac::BinaryWriter writer(buffer.begin(), buffer.end()); + + writer.write_unsigned_short(0x10); + writer.write_unsigned_short(0x3322); + + ASSERT_THAT(buffer, ElementsAre(0x10, 0x00, 0x22, 0x33)); +} + +TEST(BinaryWriter, WriteUnsignedShortFailsWithExhaustedError) { + std::vector buffer; + ac::BinaryWriter writer(buffer.begin(), buffer.end()); + EXPECT_THROW(writer.write_unsigned_short(0x11), std::out_of_range); +} + +TEST(BinaryWriter, WriteUnsignedShortWithChangedBinaryOrder) { + std::vector buffer; + buffer.resize(sizeof(std::uint16_t)); + ac::BinaryWriter writer(buffer.begin(), buffer.end()); + + writer.set_byte_order(ac::BinaryWriter::Order::Big); + writer.write_unsigned_short(0x1122); + + ASSERT_THAT(buffer, ElementsAre(0x11, 0x22)); + + buffer.clear(); + buffer.resize(sizeof(std::uint16_t)); + + writer = ac::BinaryWriter(buffer.begin(), buffer.end()); + + writer.set_byte_order(ac::BinaryWriter::Order::Little); + writer.write_unsigned_short(0x1122); + + ASSERT_THAT(buffer, ElementsAre(0x22, 0x11)); +} From 5bc93f76fe2df1dd86dd0bc31c42b1c9922669a5 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 10 May 2017 19:06:12 +0200 Subject: [PATCH 51/86] Create static IP configuration for Android --- src/CMakeLists.txt | 1 + src/anbox/android/ip_config_builder.cpp | 108 ++++++++++++++++++++++++ src/anbox/android/ip_config_builder.h | 63 ++++++++++++++ src/anbox/container/lxc_container.cpp | 55 ++++++++++-- src/anbox/container/lxc_container.h | 1 + 5 files changed, 223 insertions(+), 5 deletions(-) create mode 100644 src/anbox/android/ip_config_builder.cpp create mode 100644 src/anbox/android/ip_config_builder.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 557558c..60817e4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -66,6 +66,7 @@ set(SOURCES anbox/build/version.h.in anbox/android/intent.cpp + anbox/android/ip_config_builder.cpp anbox/common/fd.cpp anbox/common/fd_sets.h diff --git a/src/anbox/android/ip_config_builder.cpp b/src/anbox/android/ip_config_builder.cpp new file mode 100644 index 0000000..fa10610 --- /dev/null +++ b/src/anbox/android/ip_config_builder.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2017 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 . + * + */ + +#include "anbox/android/ip_config_builder.h" + +#include + +#include +#include + +namespace { +constexpr const char *assignment_key{"ipAssignment"}; +constexpr const char *link_address_key{"linkAddress"}; +constexpr const char *gateway_key{"gateway"}; +constexpr const char *dns_key{"dns"}; +constexpr const char *id_key{"id"}; +constexpr const char *eos_key{"eos"}; +constexpr const char *assignment_static{"STATIC"}; +constexpr const char *assignment_dhcp{"DHCP"}; +constexpr const char *assignment_unknown{"UNKNOWN"}; + +namespace aa = anbox::android; +std::string assignment_to_string(const aa::IpConfigBuilder::Assignment &value) { + switch (value) { + case anbox::android::IpConfigBuilder::Assignment::Static: + return assignment_static; + break; + case anbox::android::IpConfigBuilder::Assignment::DHCP: + return assignment_dhcp; + break; + default: + break; + } + return assignment_unknown; +} +} + +namespace anbox { +namespace android { +std::size_t IpConfigBuilder::write(common::BinaryWriter &writer) { + writer.set_byte_order(common::BinaryWriter::Order::Big); + + writer.write_unsigned_long(static_cast(version_)); + + writer.write_string_with_size(assignment_key); + writer.write_string_with_size(assignment_to_string(assignment_)); + + writer.write_string_with_size(link_address_key); + writer.write_string_with_size(link_.address); + writer.write_unsigned_long(link_.prefix_length); + + writer.write_string_with_size(gateway_key); + writer.write_unsigned_long(0); + writer.write_unsigned_long(1); + writer.write_string_with_size(gateway_); + + writer.write_string_with_size(dns_key); + for (const auto &server : dns_servers_) + writer.write_string_with_size(server); + + writer.write_string_with_size(id_key); + writer.write_unsigned_long(id_); + + writer.write_string_with_size(eos_key); + + return writer.bytes_written(); +} + +void IpConfigBuilder::set_version(const Version &version) { + version_ = version; +} + +void IpConfigBuilder::set_assignment(const Assignment &assignment) { + assignment_ = assignment; +} + +void IpConfigBuilder::set_link_address(const std::string &address, uint32_t prefix_length) { + link_.address = address; + link_.prefix_length = prefix_length; +} + +void IpConfigBuilder::set_gateway(const std::string &gateway) { + gateway_ = gateway; +} + +void IpConfigBuilder::set_dns_servers(const std::vector &dns_servers) { + dns_servers_ = dns_servers; +} + +void IpConfigBuilder::set_id(uint32_t id) { + id_ = id; +} +} // namespace android +} // namespace anbox diff --git a/src/anbox/android/ip_config_builder.h b/src/anbox/android/ip_config_builder.h new file mode 100644 index 0000000..6ae0db0 --- /dev/null +++ b/src/anbox/android/ip_config_builder.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2017 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_ANDROID_IPCONFIGBUILDER_H_ +#define ANBOX_ANDROID_IPCONFIGBUILDER_H_ + +#include "anbox/common/binary_writer.h" + +#include +#include +#include + +namespace anbox { +namespace android { +struct IpConfigBuilder { + enum class Version : std::uint32_t { + Version1 = 1, + Version2 = 2, + }; + + enum class Assignment { + Static, + DHCP, + }; + + std::size_t write(common::BinaryWriter &writer); + + void set_version(const Version &version); + void set_assignment(const Assignment &assignment); + void set_link_address(const std::string &address, std::uint32_t prefix_length); + void set_gateway(const std::string &gateway); + void set_dns_servers(const std::vector &dns_servers); + void set_id(std::uint32_t id); + + private: + Version version_; + Assignment assignment_; + struct { + std::string address; + std::uint32_t prefix_length; + } link_; + std::string gateway_; + std::vector dns_servers_; + std::uint32_t id_; +}; +} // namespace android +} // namespace anbox + +#endif diff --git a/src/anbox/container/lxc_container.cpp b/src/anbox/container/lxc_container.cpp index 3faf842..b8c0cf8 100644 --- a/src/anbox/container/lxc_container.cpp +++ b/src/anbox/container/lxc_container.cpp @@ -15,6 +15,7 @@ * */ +#include "anbox/android/ip_config_builder.h" #include "anbox/container/lxc_container.h" #include "anbox/config.h" #include "anbox/logger.h" @@ -22,6 +23,7 @@ #include #include +#include #include #include @@ -76,6 +78,53 @@ void LxcContainer::setup_id_maps() { max_id - creds_.gid() - 1)); } +void LxcContainer::setup_network() { + if (!fs::exists("/sys/class/net/anbox0")) { + WARNING("Anbox bridge interface 'anbox0' doesn't exist. Network functionality will not be available"); + return; + } + + set_config_item("lxc.network.type", "veth"); + set_config_item("lxc.network.flags", "up"); + set_config_item("lxc.network.link", "anbox0"); + + // Instead of relying on DHCP we will give Android a static IP configuration + // for the virtual ethernet interface LXC creates for us. This will be bridged + // to the host and will allows us to have reliable network connectivity and + // not depend on any other system service. + // + // See http://androidxref.com/7.1.1_r6/xref/frameworks/base/core/java/android/net/IpConfiguration.java + // for more details of the IP configuration format used here. + + android::IpConfigBuilder ip_conf; + ip_conf.set_version(android::IpConfigBuilder::Version::Version2); + ip_conf.set_assignment(android::IpConfigBuilder::Assignment::Static); + ip_conf.set_link_address("192.168.250.2", 24); + ip_conf.set_gateway("192.168.250.1"); + ip_conf.set_dns_servers({"8.8.8.8"}); + ip_conf.set_id(0); + + std::vector buffer(512); + common::BinaryWriter writer(buffer.begin(), buffer.end()); + const auto size = ip_conf.write(writer); + + const auto ip_conf_dir = SystemConfiguration::instance().data_dir() / "data" / "misc" / "ethernet"; + if (!fs::exists(ip_conf_dir)) + fs::create_directories(ip_conf_dir); + + const auto ip_conf_path = ip_conf_dir / "ipconfig.txt"; + if (fs::exists(ip_conf_path)) + fs::remove(ip_conf_path); + + std::ofstream f(ip_conf_path.string(), std::ofstream::binary); + if (f.is_open()) { + f.write(reinterpret_cast(buffer.data()), size); + f.close(); + } else { + ERROR("Failed to write IP configuration. Network functionality will not be available."); + } +} + void LxcContainer::start(const Configuration &configuration) { if (getuid() != 0) BOOST_THROW_EXCEPTION(std::runtime_error("You have to start the container as root")); @@ -131,11 +180,7 @@ void LxcContainer::start(const Configuration &configuration) { const auto log_path = SystemConfiguration::instance().log_dir(); set_config_item("lxc.logfile", utils::string_format("%s/container.log", log_path).c_str()); - if (fs::exists("/sys/class/net/anboxbr0")) { - set_config_item("lxc.network.type", "veth"); - set_config_item("lxc.network.flags", "up"); - set_config_item("lxc.network.link", "anboxbr0"); - } + setup_network(); #if 0 // Android uses namespaces as well so we have to allow nested namespaces for LXC diff --git a/src/anbox/container/lxc_container.h b/src/anbox/container/lxc_container.h index 886a9d4..bc87760 100644 --- a/src/anbox/container/lxc_container.h +++ b/src/anbox/container/lxc_container.h @@ -39,6 +39,7 @@ class LxcContainer : public Container { private: void set_config_item(const std::string &key, const std::string &value); void setup_id_maps(); + void setup_network(); State state_; lxc_container *container_; From 54499f0135c85f346debe601772b42d9dfa1d1e9 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 10 May 2017 19:06:38 +0200 Subject: [PATCH 52/86] Simply bridge implementation to provide just a static configuration --- scripts/anbox-bridge.sh | 95 ++--------------------------------------- 1 file changed, 4 insertions(+), 91 deletions(-) diff --git a/scripts/anbox-bridge.sh b/scripts/anbox-bridge.sh index e6793b5..46f34b7 100755 --- a/scripts/anbox-bridge.sh +++ b/scripts/anbox-bridge.sh @@ -14,34 +14,21 @@ # limitations under the License. # Taken from https://github.com/lxc/lxd-pkg-ubuntu/blob/dpm-xenial/lxd-bridge/lxd-bridge +# but modified for the use within anbox. varrun="/run/anbox" -varlib="/var/lib/anbox" -BRIDGE="anboxbr0" +BRIDGE="anbox0" # IPv4 -IPV4_ADDR="10.0.6.1" +IPV4_ADDR="192.168.250.1" IPV4_NETMASK="255.255.255.0" -IPV4_NETWORK="10.0.6.1/24" -IPV4_DHCP_RANGE="10.0.6.2,10.0.6.254" -IPV4_DHCP_MAX="252" +IPV4_NETWORK="192.168.250.1/24" IPV4_NAT="true" -# IPv6 -IPV6_ADDR="fd9d:e4dc:4e00:9e98::1" -IPV6_MASK="64" -IPV6_NETWORK="fd9d:e4dc:4e00:9e98::1/64" -IPV6_NAT="true" -IPV6_PROXY="false" - use_iptables_lock="-w" iptables -w -L -n > /dev/null 2>&1 || use_iptables_lock="" -HAS_IPV6=false -[ -e "/proc/sys/net/ipv6/conf/default/disable_ipv6" ] && \ - [ "$(cat /proc/sys/net/ipv6/conf/default/disable_ipv6)" = "0" ] && HAS_IPV6=true - _netmask2cidr () { # Assumes there's no "255." after a non-255 byte in the mask local x=${1##*255.} @@ -88,11 +75,6 @@ start() { # set up the anbox network [ ! -d "/sys/class/net/${BRIDGE}" ] && ip link add dev "${BRIDGE}" type bridge - if [ "${HAS_IPV6}" = "true" ]; then - echo 0 > "/proc/sys/net/ipv6/conf/${BRIDGE}/autoconf" || true - echo 0 > "/proc/sys/net/ipv6/conf/${BRIDGE}/accept_dad" || true - fi - # if we are run from systemd on a system with selinux enabled, # the mkdir will create /run/anbox as init_var_run_t which dnsmasq # can't write its pid into, so we restorecon it (to var_run_t) @@ -103,13 +85,6 @@ start() { fi fi - if [ ! -d "${varlib}" ]; then - mkdir -p "${varlib}" - if which restorecon >/dev/null 2>&1; then - restorecon "${varlib}" - fi - fi - ifup "${BRIDGE}" "${IPV4_ADDR}" "${IPV4_NETMASK}" IPV4_ARG="" @@ -118,25 +93,6 @@ start() { if [ "${IPV4_NAT}" = "true" ]; then iptables "${use_iptables_lock}" -t nat -A POSTROUTING -s "${IPV4_NETWORK}" ! -d "${IPV4_NETWORK}" -j MASQUERADE -m comment --comment "managed by anbox-bridge" fi - IPV4_ARG="--listen-address ${IPV4_ADDR} --dhcp-range ${IPV4_DHCP_RANGE} --dhcp-lease-max=${IPV4_DHCP_MAX}" - fi - - IPV6_ARG="" - if [ "${HAS_IPV6}" = "true" ] && [ -n "${IPV6_ADDR}" ] && [ -n "${IPV6_MASK}" ] && [ -n "${IPV6_NETWORK}" ]; then - # IPv6 sysctls don't respect the "all" path... - for interface in /proc/sys/net/ipv6/conf/*; do - echo 2 > "${interface}/accept_ra" - done - - for interface in /proc/sys/net/ipv6/conf/*; do - echo 1 > "${interface}/forwarding" - done - - ip -6 addr add dev "${BRIDGE}" "${IPV6_ADDR}/${IPV6_MASK}" - if [ "${IPV6_NAT}" = "true" ]; then - ip6tables "${use_iptables_lock}" -t nat -A POSTROUTING -s "${IPV6_NETWORK}" ! -d "${IPV6_NETWORK}" -j MASQUERADE -m comment --comment "managed by anbox-bridge" - fi - IPV6_ARG="--dhcp-range=${IPV6_ADDR},ra-stateless,ra-names --listen-address ${IPV6_ADDR}" fi iptables "${use_iptables_lock}" -I INPUT -i "${BRIDGE}" -p udp --dport 67 -j ACCEPT -m comment --comment "managed by anbox-bridge" @@ -147,35 +103,6 @@ start() { iptables "${use_iptables_lock}" -I FORWARD -o "${BRIDGE}" -j ACCEPT -m comment --comment "managed by anbox-bridge" iptables "${use_iptables_lock}" -t mangle -A POSTROUTING -o "${BRIDGE}" -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill -m comment --comment "managed by anbox-bridge" - DOMAIN_ARG="" - if [ -n "${DOMAIN}" ]; then - DOMAIN_ARG="-s ${DOMAIN} -S /${DOMAIN}/" - fi - - CONFILE_ARG="" - if [ -n "${CONFILE}" ]; then - CONFILE_ARG="--conf-file=${CONFILE}" - fi - - # https://lists.linuxcontainers.org/pipermail/lxc-devel/2014-October/010561.html - for DNSMASQ_USER in anbox dnsmasq nobody - do - if getent passwd "${DNSMASQ_USER}" >/dev/null; then - break - fi - done - - if [ -n "${IPV4_ADDR}" ] || [ -n "${IPV6_ADDR}" ]; then - # shellcheck disable=SC2086 - dnsmasq ${CONFILE_ARG} ${DOMAIN_ARG} -u "${DNSMASQ_USER}" --strict-order --bind-interfaces --pid-file="${varrun}/dnsmasq.pid" --dhcp-no-override --except-interface=lo --interface="${BRIDGE}" --dhcp-leasefile="${varlib}/dnsmasq.${BRIDGE}.leases" --dhcp-authoritative ${IPV4_ARG} ${IPV6_ARG} || cleanup - fi - - if [ "${HAS_IPV6}" = "true" ] && [ "${IPV6_PROXY}" = "true" ]; then - PATH="${PATH}:$(dirname "${0}")" anbox-bridge-proxy --addr="[fe80::1%${BRIDGE}]:13128" & - PID=$! - echo "${PID}" > "${varrun}/proxy.pid" - fi - touch "${varrun}/network_up" FAILED=0 } @@ -197,20 +124,6 @@ stop() { iptables ${use_iptables_lock} -t nat -D POSTROUTING -s ${IPV4_NETWORK} ! -d ${IPV4_NETWORK} -j MASQUERADE -m comment --comment "managed by anbox-bridge" fi - if [ "${HAS_IPV6}" = "true" ] && [ -n "${IPV6_NETWORK}" ] && [ "${IPV6_NAT}" = "true" ]; then - ip6tables ${use_iptables_lock} -t nat -D POSTROUTING -s ${IPV6_NETWORK} ! -d ${IPV6_NETWORK} -j MASQUERADE -m comment --comment "managed by anbox-bridge" - fi - - if [ -e "${varrun}/dnsmasq.pid" ]; then - pid=$(cat "${varrun}/dnsmasq.pid" 2>/dev/null) && kill -9 "${pid}" - rm -f "${varrun}/dnsmasq.pid" - fi - - if [ -e "${varrun}/proxy.pid" ]; then - pid=$(cat "${varrun}/proxy.pid" 2>/dev/null) && kill -9 "${pid}" - rm -f "${varrun}/proxy.pid" - fi - # if ${BRIDGE} has attached interfaces, don't destroy the bridge ls /sys/class/net/${BRIDGE}/brif/* > /dev/null 2>&1 || ip link delete "${BRIDGE}" fi From 2fb4067da97453f12bb00d952e4bfa56041f500d Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 11 May 2017 07:07:47 +0200 Subject: [PATCH 53/86] Add more constants for various static configuration items --- src/anbox/android/ip_config_builder.cpp | 10 ++++++++-- src/anbox/container/lxc_container.cpp | 16 ++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/anbox/android/ip_config_builder.cpp b/src/anbox/android/ip_config_builder.cpp index fa10610..4efe4db 100644 --- a/src/anbox/android/ip_config_builder.cpp +++ b/src/anbox/android/ip_config_builder.cpp @@ -33,6 +33,9 @@ constexpr const char *assignment_static{"STATIC"}; constexpr const char *assignment_dhcp{"DHCP"}; constexpr const char *assignment_unknown{"UNKNOWN"}; +constexpr const std::uint32_t is_default_gateway{0}; +constexpr const std::uint32_t gateway_is_present{1}; + namespace aa = anbox::android; std::string assignment_to_string(const aa::IpConfigBuilder::Assignment &value) { switch (value) { @@ -54,6 +57,9 @@ namespace android { std::size_t IpConfigBuilder::write(common::BinaryWriter &writer) { writer.set_byte_order(common::BinaryWriter::Order::Big); + // See http://androidxref.com/7.1.1_r6/xref/frameworks/base/services/core/java/com/android/server/net/IpConfigStore.java + // for more details on the binary file format used here. + writer.write_unsigned_long(static_cast(version_)); writer.write_string_with_size(assignment_key); @@ -64,8 +70,8 @@ std::size_t IpConfigBuilder::write(common::BinaryWriter &writer) { writer.write_unsigned_long(link_.prefix_length); writer.write_string_with_size(gateway_key); - writer.write_unsigned_long(0); - writer.write_unsigned_long(1); + writer.write_unsigned_long(is_default_gateway); + writer.write_unsigned_long(gateway_is_present); writer.write_string_with_size(gateway_); writer.write_string_with_size(dns_key); diff --git a/src/anbox/container/lxc_container.cpp b/src/anbox/container/lxc_container.cpp index b8c0cf8..ee388a9 100644 --- a/src/anbox/container/lxc_container.cpp +++ b/src/anbox/container/lxc_container.cpp @@ -35,6 +35,13 @@ namespace fs = boost::filesystem; +namespace { +constexpr const char *default_container_ip_address{"192.168.250.2"}; +constexpr const std::uint32_t default_container_ip_prefix_length{24}; +constexpr const char *default_host_ip_address{"192.168.250.1"}; +constexpr const char *default_dns_server{"8.8.8.8"}; +} + namespace anbox { namespace container { LxcContainer::LxcContainer(bool privileged, const network::Credentials &creds) @@ -92,16 +99,13 @@ void LxcContainer::setup_network() { // for the virtual ethernet interface LXC creates for us. This will be bridged // to the host and will allows us to have reliable network connectivity and // not depend on any other system service. - // - // See http://androidxref.com/7.1.1_r6/xref/frameworks/base/core/java/android/net/IpConfiguration.java - // for more details of the IP configuration format used here. android::IpConfigBuilder ip_conf; ip_conf.set_version(android::IpConfigBuilder::Version::Version2); ip_conf.set_assignment(android::IpConfigBuilder::Assignment::Static); - ip_conf.set_link_address("192.168.250.2", 24); - ip_conf.set_gateway("192.168.250.1"); - ip_conf.set_dns_servers({"8.8.8.8"}); + ip_conf.set_link_address(default_container_ip_address, default_container_ip_prefix_length); + ip_conf.set_gateway(default_host_ip_address); + ip_conf.set_dns_servers({default_dns_server}); ip_conf.set_id(0); std::vector buffer(512); From e441f3d42b9d281c4dc48075ab319703e507921c Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 11 May 2017 07:42:01 +0200 Subject: [PATCH 54/86] Extend BinaryWriter test cases to cover all necessary things --- tests/anbox/common/binary_writer_tests.cpp | 30 ++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/anbox/common/binary_writer_tests.cpp b/tests/anbox/common/binary_writer_tests.cpp index 4f12a23..01495a3 100644 --- a/tests/anbox/common/binary_writer_tests.cpp +++ b/tests/anbox/common/binary_writer_tests.cpp @@ -31,6 +31,7 @@ TEST(BinaryWriter, WritesUnsignedLong) { writer.write_unsigned_long(0x10); writer.write_unsigned_long(0x3322); + ASSERT_EQ(writer.bytes_written(), 8); ASSERT_THAT(buffer, ElementsAre(0x10, 0x00, 0x00, 0x00, 0x22, 0x33, 0x00, 0x00)); } @@ -48,6 +49,7 @@ TEST(BinaryWriter, WriteUnsignedLongWithChangedBinaryOrder) { writer.set_byte_order(ac::BinaryWriter::Order::Big); writer.write_unsigned_long(0x11223344); + ASSERT_EQ(writer.bytes_written(), 4); ASSERT_THAT(buffer, ElementsAre(0x11, 0x22, 0x33, 0x44)); buffer.clear(); @@ -58,6 +60,7 @@ TEST(BinaryWriter, WriteUnsignedLongWithChangedBinaryOrder) { writer.set_byte_order(ac::BinaryWriter::Order::Little); writer.write_unsigned_long(0x11223344); + ASSERT_EQ(writer.bytes_written(), 4); ASSERT_THAT(buffer, ElementsAre(0x44, 0x33, 0x22, 0x11)); } @@ -69,6 +72,7 @@ TEST(BinaryWriter, WriteUnsignedShort) { writer.write_unsigned_short(0x10); writer.write_unsigned_short(0x3322); + ASSERT_EQ(writer.bytes_written(), 4); ASSERT_THAT(buffer, ElementsAre(0x10, 0x00, 0x22, 0x33)); } @@ -86,6 +90,7 @@ TEST(BinaryWriter, WriteUnsignedShortWithChangedBinaryOrder) { writer.set_byte_order(ac::BinaryWriter::Order::Big); writer.write_unsigned_short(0x1122); + ASSERT_EQ(writer.bytes_written(), 2); ASSERT_THAT(buffer, ElementsAre(0x11, 0x22)); buffer.clear(); @@ -96,5 +101,30 @@ TEST(BinaryWriter, WriteUnsignedShortWithChangedBinaryOrder) { writer.set_byte_order(ac::BinaryWriter::Order::Little); writer.write_unsigned_short(0x1122); + ASSERT_EQ(writer.bytes_written(), 2); ASSERT_THAT(buffer, ElementsAre(0x22, 0x11)); } + +TEST(BinaryWriter, WriteString) { + std::vector buffer; + buffer.resize(sizeof(std::uint8_t) * 4); + ac::BinaryWriter writer(buffer.begin(), buffer.end()); + + writer.write_string("test", 4); + + ASSERT_EQ(writer.bytes_written(), 4); + ASSERT_THAT(buffer, ElementsAre(0x74, 0x65, 0x73, 0x74)); +} + +TEST(BinaryWriter, WriteStringWithSize) { + std::vector buffer; + buffer.resize(sizeof(std::uint8_t) * 6); + ac::BinaryWriter writer(buffer.begin(), buffer.end()); + + writer.set_byte_order(ac::BinaryWriter::Order::Big); + + writer.write_string_with_size("test"); + + ASSERT_EQ(writer.bytes_written(), 6); + ASSERT_THAT(buffer, ElementsAre(0x00, 0x04, 0x74, 0x65, 0x73, 0x74)); +} From 7530bf9246f1b1d20001d0bc82c1c25de6e9858c Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 11 May 2017 07:44:10 +0200 Subject: [PATCH 55/86] Use class instead of struct for IpConfigBuilder --- src/anbox/android/ip_config_builder.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/anbox/android/ip_config_builder.h b/src/anbox/android/ip_config_builder.h index 6ae0db0..812da7c 100644 --- a/src/anbox/android/ip_config_builder.h +++ b/src/anbox/android/ip_config_builder.h @@ -26,7 +26,8 @@ namespace anbox { namespace android { -struct IpConfigBuilder { +class IpConfigBuilder { + public: enum class Version : std::uint32_t { Version1 = 1, Version2 = 2, @@ -37,6 +38,8 @@ struct IpConfigBuilder { DHCP, }; + IpConfigBuilder() = default; + std::size_t write(common::BinaryWriter &writer); void set_version(const Version &version); From 22fcbabb64c0f55e6ef64c14ee5de9b4965748ee Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 11 May 2017 07:45:24 +0200 Subject: [PATCH 56/86] Print warning if user starts container manager manually --- scripts/container-manager.sh | 3 ++- src/anbox/cmds/container_manager.cpp | 13 ++++++++++++- src/anbox/cmds/container_manager.h | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/scripts/container-manager.sh b/scripts/container-manager.sh index 993a150..440f7ea 100755 --- a/scripts/container-manager.sh +++ b/scripts/container-manager.sh @@ -37,7 +37,8 @@ start() { exec $AA_EXEC $SNAP/bin/anbox-wrapper.sh container-manager \ --data-path=$DATA_PATH \ - --android-image=$ANDROID_IMG + --android-image=$ANDROID_IMG \ + --daemon } stop() { diff --git a/src/anbox/cmds/container_manager.cpp b/src/anbox/cmds/container_manager.cpp index 4716303..dffd6dc 100644 --- a/src/anbox/cmds/container_manager.cpp +++ b/src/anbox/cmds/container_manager.cpp @@ -48,11 +48,22 @@ anbox::cmds::ContainerManager::ContainerManager() flag(cli::make_flag(cli::Name{"privileged"}, cli::Description{"Run Android container in privileged mode"}, privileged_)); + flag(cli::make_flag(cli::Name{"daemon"}, + cli::Description{"Mark service as being started as systemd daemon"}, + daemon_)); action([&](const cli::Command::Context&) { try { + if (!daemon_) { + WARNING("You are running the container manager manually which is most likely not"); + WARNING("what you want. The container manager is normally started by systemd or"); + WARNING("or another init system. If you still want to run the container-manager"); + WARNING("you can get rid of this warning by starting with the --daemon option."); + WARNING(""); + } + if (getuid() != 0) { - ERROR("You're not running the container-manager as root. Generally you don't"); + ERROR("You are not running the container-manager as root. Generally you don't"); ERROR("want to run the container-manager manually unless you're a developer"); ERROR("as it is started by the init system of your operating system."); return EXIT_FAILURE; diff --git a/src/anbox/cmds/container_manager.h b/src/anbox/cmds/container_manager.h index 4525756..679c802 100644 --- a/src/anbox/cmds/container_manager.h +++ b/src/anbox/cmds/container_manager.h @@ -42,6 +42,7 @@ class ContainerManager : public cli::CommandWithFlagsAndAction { std::shared_ptr android_img_loop_dev_; std::vector> mounts_; bool privileged_ = false; + bool daemon_ = false; }; } // namespace cmds } // namespace anbox From e60e020413aefd38388fc6eae15286ae13e80d88 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 11 May 2017 17:59:54 +0200 Subject: [PATCH 57/86] Remove double 'or' from warning message --- src/anbox/cmds/container_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anbox/cmds/container_manager.cpp b/src/anbox/cmds/container_manager.cpp index dffd6dc..593be7e 100644 --- a/src/anbox/cmds/container_manager.cpp +++ b/src/anbox/cmds/container_manager.cpp @@ -57,7 +57,7 @@ anbox::cmds::ContainerManager::ContainerManager() if (!daemon_) { WARNING("You are running the container manager manually which is most likely not"); WARNING("what you want. The container manager is normally started by systemd or"); - WARNING("or another init system. If you still want to run the container-manager"); + WARNING("another init system. If you still want to run the container-manager"); WARNING("you can get rid of this warning by starting with the --daemon option."); WARNING(""); } From e83cc1e5fda75322f62ddb510d56cde84aeea0b9 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 11 May 2017 18:00:06 +0200 Subject: [PATCH 58/86] Use geteuid instead of getuid --- src/anbox/cmds/container_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/anbox/cmds/container_manager.cpp b/src/anbox/cmds/container_manager.cpp index 593be7e..b64f002 100644 --- a/src/anbox/cmds/container_manager.cpp +++ b/src/anbox/cmds/container_manager.cpp @@ -62,7 +62,7 @@ anbox::cmds::ContainerManager::ContainerManager() WARNING(""); } - if (getuid() != 0) { + if (geteuid() != 0) { ERROR("You are not running the container-manager as root. Generally you don't"); ERROR("want to run the container-manager manually unless you're a developer"); ERROR("as it is started by the init system of your operating system."); From dd21e8fa1de0d8a200f63c4dc4e393eec5b5d725 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 11 May 2017 18:03:56 +0200 Subject: [PATCH 59/86] Make never change value static and const --- src/anbox/common/binary_writer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/anbox/common/binary_writer.cpp b/src/anbox/common/binary_writer.cpp index f6d4973..e9f16d9 100644 --- a/src/anbox/common/binary_writer.cpp +++ b/src/anbox/common/binary_writer.cpp @@ -25,8 +25,8 @@ namespace { bool is_little_endian() { - std::uint32_t v = 1; - return (*reinterpret_cast(&v) == 1); + static const std::uint32_t v = 1; + return (*reinterpret_cast(&v) == 1); } } From e73ea080c43948d46f6bccb153da6bea7ec6dc5c Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Thu, 11 May 2017 18:06:24 +0200 Subject: [PATCH 60/86] Rename write_unsigned_{long,short} to write_uint{16,32} --- src/anbox/android/ip_config_builder.cpp | 10 +++---- src/anbox/common/binary_writer.cpp | 6 ++-- src/anbox/common/binary_writer.h | 4 +-- tests/anbox/common/binary_writer_tests.cpp | 32 +++++++++++----------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/anbox/android/ip_config_builder.cpp b/src/anbox/android/ip_config_builder.cpp index 4efe4db..8ba13ce 100644 --- a/src/anbox/android/ip_config_builder.cpp +++ b/src/anbox/android/ip_config_builder.cpp @@ -60,18 +60,18 @@ std::size_t IpConfigBuilder::write(common::BinaryWriter &writer) { // See http://androidxref.com/7.1.1_r6/xref/frameworks/base/services/core/java/com/android/server/net/IpConfigStore.java // for more details on the binary file format used here. - writer.write_unsigned_long(static_cast(version_)); + writer.write_uint32(static_cast(version_)); writer.write_string_with_size(assignment_key); writer.write_string_with_size(assignment_to_string(assignment_)); writer.write_string_with_size(link_address_key); writer.write_string_with_size(link_.address); - writer.write_unsigned_long(link_.prefix_length); + writer.write_uint32(link_.prefix_length); writer.write_string_with_size(gateway_key); - writer.write_unsigned_long(is_default_gateway); - writer.write_unsigned_long(gateway_is_present); + writer.write_uint32(is_default_gateway); + writer.write_uint32(gateway_is_present); writer.write_string_with_size(gateway_); writer.write_string_with_size(dns_key); @@ -79,7 +79,7 @@ std::size_t IpConfigBuilder::write(common::BinaryWriter &writer) { writer.write_string_with_size(server); writer.write_string_with_size(id_key); - writer.write_unsigned_long(id_); + writer.write_uint32(id_); writer.write_string_with_size(eos_key); diff --git a/src/anbox/common/binary_writer.cpp b/src/anbox/common/binary_writer.cpp index e9f16d9..3202199 100644 --- a/src/anbox/common/binary_writer.cpp +++ b/src/anbox/common/binary_writer.cpp @@ -42,7 +42,7 @@ void BinaryWriter::set_byte_order(Order order) { byte_order_ = order; } -void BinaryWriter::write_unsigned_short(std::uint16_t value) { +void BinaryWriter::write_uint16(std::uint16_t value) { if (current_ + sizeof(value) > end_) throw std::out_of_range{"Write buffer exhausted"}; @@ -62,7 +62,7 @@ void BinaryWriter::write_unsigned_short(std::uint16_t value) { current_ += sizeof(v); } -void BinaryWriter::write_unsigned_long(std::uint32_t value) { +void BinaryWriter::write_uint32(std::uint32_t value) { if (current_ + sizeof(value) > end_) throw std::out_of_range{"Write buffer exhausted"}; @@ -95,7 +95,7 @@ void BinaryWriter::write_string_with_size(const std::string &str) { } void BinaryWriter::write_string_with_size(const char *s, std::size_t size) { - write_unsigned_short(size); + write_uint16(size); write_string(s, size); } diff --git a/src/anbox/common/binary_writer.h b/src/anbox/common/binary_writer.h index f2aeefd..23708c6 100644 --- a/src/anbox/common/binary_writer.h +++ b/src/anbox/common/binary_writer.h @@ -37,8 +37,8 @@ class BinaryWriter { void set_byte_order(Order order); - void write_unsigned_short(std::uint16_t value); - void write_unsigned_long(std::uint32_t value); + void write_uint16(std::uint16_t value); + void write_uint32(std::uint32_t value); void write_string(const char *s, std::size_t size); void write_string_with_size(const std::string &str); void write_string_with_size(const char *s, std::size_t size); diff --git a/tests/anbox/common/binary_writer_tests.cpp b/tests/anbox/common/binary_writer_tests.cpp index 01495a3..6bab562 100644 --- a/tests/anbox/common/binary_writer_tests.cpp +++ b/tests/anbox/common/binary_writer_tests.cpp @@ -23,31 +23,31 @@ namespace ac = anbox::common; using namespace ::testing; -TEST(BinaryWriter, WritesUnsignedLong) { +TEST(BinaryWriter, WriteUint32) { std::vector buffer; buffer.resize(sizeof(std::uint32_t) * 2); ac::BinaryWriter writer(buffer.begin(), buffer.end()); - writer.write_unsigned_long(0x10); - writer.write_unsigned_long(0x3322); + writer.write_uint32(0x10); + writer.write_uint32(0x3322); ASSERT_EQ(writer.bytes_written(), 8); ASSERT_THAT(buffer, ElementsAre(0x10, 0x00, 0x00, 0x00, 0x22, 0x33, 0x00, 0x00)); } -TEST(BinaryWriter, WriteUnsignedLongFailsWithExhaustedError) { +TEST(BinaryWriter, WriteUint32FailsWithExhaustedError) { std::vector buffer; ac::BinaryWriter writer(buffer.begin(), buffer.end()); - EXPECT_THROW(writer.write_unsigned_long(0x11), std::out_of_range); + EXPECT_THROW(writer.write_uint32(0x11), std::out_of_range); } -TEST(BinaryWriter, WriteUnsignedLongWithChangedBinaryOrder) { +TEST(BinaryWriter, WriteUint32WithChangedBinaryOrder) { std::vector buffer; buffer.resize(sizeof(std::uint32_t)); ac::BinaryWriter writer(buffer.begin(), buffer.end()); writer.set_byte_order(ac::BinaryWriter::Order::Big); - writer.write_unsigned_long(0x11223344); + writer.write_uint32(0x11223344); ASSERT_EQ(writer.bytes_written(), 4); ASSERT_THAT(buffer, ElementsAre(0x11, 0x22, 0x33, 0x44)); @@ -58,37 +58,37 @@ TEST(BinaryWriter, WriteUnsignedLongWithChangedBinaryOrder) { writer = ac::BinaryWriter(buffer.begin(), buffer.end()); writer.set_byte_order(ac::BinaryWriter::Order::Little); - writer.write_unsigned_long(0x11223344); + writer.write_uint32(0x11223344); ASSERT_EQ(writer.bytes_written(), 4); ASSERT_THAT(buffer, ElementsAre(0x44, 0x33, 0x22, 0x11)); } -TEST(BinaryWriter, WriteUnsignedShort) { +TEST(BinaryWriter, WriteUint16) { std::vector buffer; buffer.resize(sizeof(std::uint16_t) * 2); ac::BinaryWriter writer(buffer.begin(), buffer.end()); - writer.write_unsigned_short(0x10); - writer.write_unsigned_short(0x3322); + writer.write_uint16(0x10); + writer.write_uint16(0x3322); ASSERT_EQ(writer.bytes_written(), 4); ASSERT_THAT(buffer, ElementsAre(0x10, 0x00, 0x22, 0x33)); } -TEST(BinaryWriter, WriteUnsignedShortFailsWithExhaustedError) { +TEST(BinaryWriter, WriteUint16FailsWithExhaustedError) { std::vector buffer; ac::BinaryWriter writer(buffer.begin(), buffer.end()); - EXPECT_THROW(writer.write_unsigned_short(0x11), std::out_of_range); + EXPECT_THROW(writer.write_uint16(0x11), std::out_of_range); } -TEST(BinaryWriter, WriteUnsignedShortWithChangedBinaryOrder) { +TEST(BinaryWriter, WriteUint16WithChangedBinaryOrder) { std::vector buffer; buffer.resize(sizeof(std::uint16_t)); ac::BinaryWriter writer(buffer.begin(), buffer.end()); writer.set_byte_order(ac::BinaryWriter::Order::Big); - writer.write_unsigned_short(0x1122); + writer.write_uint16(0x1122); ASSERT_EQ(writer.bytes_written(), 2); ASSERT_THAT(buffer, ElementsAre(0x11, 0x22)); @@ -99,7 +99,7 @@ TEST(BinaryWriter, WriteUnsignedShortWithChangedBinaryOrder) { writer = ac::BinaryWriter(buffer.begin(), buffer.end()); writer.set_byte_order(ac::BinaryWriter::Order::Little); - writer.write_unsigned_short(0x1122); + writer.write_uint16(0x1122); ASSERT_EQ(writer.bytes_written(), 2); ASSERT_THAT(buffer, ElementsAre(0x22, 0x11)); From bf243a33e8414460c288befc8fc3626fd8c04594 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 12 May 2017 08:35:10 +0200 Subject: [PATCH 61/86] Make platform policy a weak_ptr inside our window managers to break cycle reference --- src/anbox/wm/multi_window_manager.cpp | 15 +++++++++++---- src/anbox/wm/multi_window_manager.h | 4 ++-- src/anbox/wm/single_window_manager.cpp | 12 ++++++++---- src/anbox/wm/single_window_manager.h | 4 ++-- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/anbox/wm/multi_window_manager.cpp b/src/anbox/wm/multi_window_manager.cpp index 83ab0b6..04806f3 100644 --- a/src/anbox/wm/multi_window_manager.cpp +++ b/src/anbox/wm/multi_window_manager.cpp @@ -25,7 +25,7 @@ namespace anbox { namespace wm { -MultiWindowManager::MultiWindowManager(const std::shared_ptr &policy, +MultiWindowManager::MultiWindowManager(const std::weak_ptr &policy, const std::shared_ptr &android_api_stub, const std::shared_ptr &app_db) : platform_policy_(policy), android_api_stub_(android_api_stub), app_db_(app_db) {} @@ -67,9 +67,16 @@ void MultiWindowManager::apply_window_state_update(const WindowState::List &upda if (app.valid()) title = app.name; - auto platform_window = platform_policy_->create_window(window.task(), window.frame(), title); - platform_window->attach(); - windows_.insert({window.task(), platform_window}); + if (auto p = platform_policy_.lock()) { + auto w = p->create_window(window.task(), window.frame(), title); + if (w) { + w->attach(); + windows_.insert({window.task(), w}); + } else { + // FIXME can we call this here safely or do we need to schedule the removal? + remove_task(window.task()); + } + } } // Send updates we collected per task down to the corresponding window diff --git a/src/anbox/wm/multi_window_manager.h b/src/anbox/wm/multi_window_manager.h index 4e2d7c4..845986c 100644 --- a/src/anbox/wm/multi_window_manager.h +++ b/src/anbox/wm/multi_window_manager.h @@ -37,7 +37,7 @@ class Policy; namespace wm { class MultiWindowManager : public Manager { public: - MultiWindowManager(const std::shared_ptr &policy, + MultiWindowManager(const std::weak_ptr &policy, const std::shared_ptr &android_api_stub, const std::shared_ptr &app_db); ~MultiWindowManager(); @@ -53,7 +53,7 @@ class MultiWindowManager : public Manager { private: std::mutex mutex_; - std::shared_ptr platform_policy_; + std::weak_ptr platform_policy_; std::shared_ptr android_api_stub_; std::shared_ptr app_db_; std::map> windows_; diff --git a/src/anbox/wm/single_window_manager.cpp b/src/anbox/wm/single_window_manager.cpp index 6adb43e..10dd8f9 100644 --- a/src/anbox/wm/single_window_manager.cpp +++ b/src/anbox/wm/single_window_manager.cpp @@ -26,7 +26,7 @@ namespace anbox { namespace wm { -SingleWindowManager::SingleWindowManager(const std::shared_ptr &policy, +SingleWindowManager::SingleWindowManager(const std::weak_ptr &policy, const graphics::Rect &window_size, const std::shared_ptr &app_db) : platform_policy_(policy), window_size_(window_size), app_db_(app_db) {} @@ -34,9 +34,13 @@ SingleWindowManager::SingleWindowManager(const std::shared_ptr SingleWindowManager::~SingleWindowManager() {} void SingleWindowManager::setup() { - window_ = platform_policy_->create_window(0, window_size_, "Anbox - Android in a Box"); - if (!window_->attach()) - WARNING("Failed to attach window to renderer"); + if (auto p = platform_policy_.lock()) { + window_ = p->create_window(0, window_size_, "Anbox - Android in a Box"); + if (!window_->attach()) + WARNING("Failed to attach window to renderer"); + } else { + throw std::runtime_error("Can't create window as we don't have a platform abstraction"); + } } void SingleWindowManager::apply_window_state_update(const WindowState::List &updated, const WindowState::List &removed) { diff --git a/src/anbox/wm/single_window_manager.h b/src/anbox/wm/single_window_manager.h index 6d0d2ca..7595776 100644 --- a/src/anbox/wm/single_window_manager.h +++ b/src/anbox/wm/single_window_manager.h @@ -35,7 +35,7 @@ namespace wm { class Window; class SingleWindowManager : public Manager { public: - SingleWindowManager(const std::shared_ptr &policy, + SingleWindowManager(const std::weak_ptr &policy, const graphics::Rect &window_size, const std::shared_ptr &app_db); ~SingleWindowManager(); @@ -52,7 +52,7 @@ class SingleWindowManager : public Manager { void remove_task(const Task::Id &task) override; private: - std::shared_ptr platform_policy_; + std::weak_ptr platform_policy_; graphics::Rect window_size_; std::shared_ptr app_db_; std::shared_ptr window_; From 583e191071fd5379e155b07c74d911a413875b3c Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 12 May 2017 08:36:03 +0200 Subject: [PATCH 62/86] Don't register platform policy as display manager but use a singleton instead --- src/anbox/cmds/session_manager.cpp | 2 -- src/anbox/graphics/emugl/DisplayManager.cpp | 30 ++++++++++---------- src/anbox/graphics/emugl/DisplayManager.h | 31 +++++++++++++-------- src/anbox/graphics/emugl/RenderControl.cpp | 8 +++--- src/anbox/ubuntu/platform_policy.cpp | 7 +---- src/anbox/ubuntu/platform_policy.h | 6 +--- 6 files changed, 40 insertions(+), 44 deletions(-) diff --git a/src/anbox/cmds/session_manager.cpp b/src/anbox/cmds/session_manager.cpp index 5c294d0..7637741 100644 --- a/src/anbox/cmds/session_manager.cpp +++ b/src/anbox/cmds/session_manager.cpp @@ -159,8 +159,6 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) display_frame = window_size_; auto policy = std::make_shared(input_manager, display_frame, single_window_); - // FIXME this needs to be removed and solved differently behind the scenes - registerDisplayManager(policy); auto app_db = std::make_shared(); diff --git a/src/anbox/graphics/emugl/DisplayManager.cpp b/src/anbox/graphics/emugl/DisplayManager.cpp index 0a624cd..91b842d 100644 --- a/src/anbox/graphics/emugl/DisplayManager.cpp +++ b/src/anbox/graphics/emugl/DisplayManager.cpp @@ -17,22 +17,22 @@ #include "DisplayManager.h" -namespace { -std::shared_ptr display_mgr; - -class NullDisplayManager : public DisplayManager { - public: - DisplayInfo display_info() const override { return {1280, 720}; } -}; +namespace anbox { +namespace graphics { +namespace emugl { +std::shared_ptr DisplayInfo::get() { + static auto info = std::make_shared(); + return info; } -DisplayManager::~DisplayManager() {} - -std::shared_ptr DisplayManager::get() { - if (!display_mgr) display_mgr = std::make_shared(); - return display_mgr; +void DisplayInfo::set_resolution(const std::uint32_t &vertical, const std::uint32_t horizontal) { + vertical_resolution_ = vertical; + horizontal_resolution_ = horizontal; } -void registerDisplayManager(const std::shared_ptr &mgr) { - display_mgr = mgr; -} +std::uint32_t DisplayInfo::vertical_resolution() const { return vertical_resolution_; } + +std::uint32_t DisplayInfo::horizontal_resolution() const { return horizontal_resolution_; } +} // namespace emugl +} // namespace graphics +} // namespace anbox diff --git a/src/anbox/graphics/emugl/DisplayManager.h b/src/anbox/graphics/emugl/DisplayManager.h index 857742f..fdba3cd 100644 --- a/src/anbox/graphics/emugl/DisplayManager.h +++ b/src/anbox/graphics/emugl/DisplayManager.h @@ -15,25 +15,32 @@ * */ -#ifndef DISPLAY_MANAGER_H_ -#define DISPLAY_MANAGER_H_ +#ifndef ANBOX_GRAPHICS_EMUGL_DISPLAY_INFO_H_ +#define ANBOX_GRAPHICS_EMUGL_DISPLAY_INFO_H_ +#include #include -class DisplayManager { +namespace anbox { +namespace graphics { +namespace emugl { +class DisplayInfo { public: - virtual ~DisplayManager(); + DisplayInfo() = default; - struct DisplayInfo { - int horizontal_resolution; - int vertical_resolution; - }; + static std::shared_ptr get(); - virtual DisplayInfo display_info() const = 0; + void set_resolution(const std::uint32_t &vertical, const std::uint32_t horizontal); - static std::shared_ptr get(); + std::uint32_t vertical_resolution() const; + std::uint32_t horizontal_resolution() const; + + private: + std::uint32_t vertical_resolution_ = 1280; + std::uint32_t horizontal_resolution_ = 720; }; - -void registerDisplayManager(const std::shared_ptr &mgr); +} // namespace emugl +} // namespace graphics +} // namespace anbox #endif diff --git a/src/anbox/graphics/emugl/RenderControl.cpp b/src/anbox/graphics/emugl/RenderControl.cpp index b479be0..85f8aef 100644 --- a/src/anbox/graphics/emugl/RenderControl.cpp +++ b/src/anbox/graphics/emugl/RenderControl.cpp @@ -169,10 +169,10 @@ static EGLint rcGetFBParam(EGLint param) { switch (param) { case FB_WIDTH: - ret = DisplayManager::get()->display_info().horizontal_resolution; + ret = static_cast(anbox::graphics::emugl::DisplayInfo::get()->horizontal_resolution()); break; case FB_HEIGHT: - ret = DisplayManager::get()->display_info().vertical_resolution; + ret = static_cast(anbox::graphics::emugl::DisplayInfo::get()->vertical_resolution()); break; case FB_XDPI: ret = 72; // XXX: should be implemented @@ -360,12 +360,12 @@ int rcGetNumDisplays() { int rcGetDisplayWidth(uint32_t display_id) { (void)display_id; - return DisplayManager::get()->display_info().horizontal_resolution; + return static_cast(anbox::graphics::emugl::DisplayInfo::get()->horizontal_resolution()); } int rcGetDisplayHeight(uint32_t display_id) { (void)display_id; - return DisplayManager::get()->display_info().vertical_resolution; + return static_cast(anbox::graphics::emugl::DisplayInfo::get()->vertical_resolution()); } int rcGetDisplayDpiX(uint32_t display_id) { diff --git a/src/anbox/ubuntu/platform_policy.cpp b/src/anbox/ubuntu/platform_policy.cpp index 6c88c1b..cea5551 100644 --- a/src/anbox/ubuntu/platform_policy.cpp +++ b/src/anbox/ubuntu/platform_policy.cpp @@ -68,8 +68,7 @@ PlatformPolicy::PlatformPolicy( window_size_immutable_ = true; } - display_info_.horizontal_resolution = display_frame.width(); - display_info_.vertical_resolution = display_frame.height(); + graphics::emugl::DisplayInfo::get()->set_resolution(display_frame.width(), display_frame.height()); pointer_ = input_manager->create_device(); pointer_->set_name("anbox-pointer"); @@ -285,10 +284,6 @@ void PlatformPolicy::window_resized(const Window::Id &id, } } -DisplayManager::DisplayInfo PlatformPolicy::display_info() const { - return display_info_; -} - void PlatformPolicy::set_clipboard_data(const ClipboardData &data) { if (data.text.empty()) return; diff --git a/src/anbox/ubuntu/platform_policy.h b/src/anbox/ubuntu/platform_policy.h index 9a09c0d..62d69f5 100644 --- a/src/anbox/ubuntu/platform_policy.h +++ b/src/anbox/ubuntu/platform_policy.h @@ -41,8 +41,7 @@ class Manager; namespace ubuntu { class PlatformPolicy : public std::enable_shared_from_this, public platform::Policy, - public Window::Observer, - public DisplayManager { + public Window::Observer { public: PlatformPolicy(const std::shared_ptr &input_manager, const graphics::Rect &static_display_frame = graphics::Rect::Invalid, @@ -61,8 +60,6 @@ class PlatformPolicy : public std::enable_shared_from_this, void window_resized(const Window::Id &id, const std::int32_t &width, const std::int32_t &height) override; - DisplayInfo display_info() const override; - void set_renderer(const std::shared_ptr &renderer); void set_window_manager(const std::shared_ptr &window_manager); @@ -89,7 +86,6 @@ class PlatformPolicy : public std::enable_shared_from_this, bool event_thread_running_; std::shared_ptr pointer_; std::shared_ptr keyboard_; - DisplayManager::DisplayInfo display_info_; bool window_size_immutable_ = false; bool single_window_ = false; }; From c0393a6713c8e49357821ed4c4f85e62a6101d42 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 8 May 2017 11:00:47 +0100 Subject: [PATCH 63/86] cmds: session_manager: Provide an option to use any container Normally Anbox will use the default container provided by the Anbox Container Manager, but some users may wish to run their own container. Here we're adding a --standalone flag which tells the Session Manager not to interact (configure/start) the Container Manager. This allows the user to utilise any other bespoke container of their choosing. For instance, this new feature was tested using a Docker container running the android.img provided by Anbox. Signed-off-by: Lee Jones --- src/anbox/cmds/session_manager.cpp | 29 +++++++++++++++++++---------- src/anbox/cmds/session_manager.h | 1 + 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/anbox/cmds/session_manager.cpp b/src/anbox/cmds/session_manager.cpp index 5c294d0..924eadf 100644 --- a/src/anbox/cmds/session_manager.cpp +++ b/src/anbox/cmds/session_manager.cpp @@ -106,6 +106,9 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) flag(cli::make_flag(cli::Name{"window-size"}, cli::Description{"Size of the window in single window mode, e.g. --window-size=1024,768"}, window_size_)); + flag(cli::make_flag(cli::Name{"standalone"}, + cli::Description{"Prevents the Container Manager from starting the default container (Experimental)"}, + standalone_)); action([this](const cli::Command::Context &) { auto trap = core::posix::trap_signals_for_process( @@ -136,10 +139,12 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) auto dispatcher = anbox::common::create_dispatcher_for_runtime(rt); container::Client container(rt); - container.register_terminate_handler([&]() { - WARNING("Lost connection to container manager, terminating."); - trap->stop(); - }); + if (!standalone_) { + container.register_terminate_handler([&]() { + WARNING("Lost connection to container manager, terminating."); + trap->stop(); + }); + } auto input_manager = std::make_shared(rt); @@ -213,7 +218,8 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) })); container::Configuration container_configuration; - container_configuration.bind_mounts = { + if (!standalone_) { + container_configuration.bind_mounts = { {qemu_pipe_connector->socket_file(), "/dev/qemu_pipe"}, {bridge_connector->socket_file(), "/dev/anbox_bridge"}, {audio_server->socket_file(), "/dev/anbox_audio"}, @@ -221,9 +227,10 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) {"/dev/binder", "/dev/binder"}, {"/dev/ashmem", "/dev/ashmem"}, {"/dev/fuse", "/dev/fuse"}, - }; + }; - dispatcher->dispatch([&]() { container.start(container_configuration); }); + dispatcher->dispatch([&]() { container.start(container_configuration); }); + } auto bus = bus_factory_(); bus->install_executor(core::dbus::asio::make_executor(bus, rt->service())); @@ -233,9 +240,11 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) rt->start(); trap->run(); - // Stop the container which should close all open connections we have on - // our side and should terminate all services. - container.stop(); + if (!standalone_) { + // Stop the container which should close all open connections we have on + // our side and should terminate all services. + container.stop(); + } rt->stop(); diff --git a/src/anbox/cmds/session_manager.h b/src/anbox/cmds/session_manager.h index 9ffb419..60c3d42 100644 --- a/src/anbox/cmds/session_manager.h +++ b/src/anbox/cmds/session_manager.h @@ -45,6 +45,7 @@ class SessionManager : public cli::CommandWithFlagsAndAction { graphics::GLRendererServer::Config::Driver gles_driver_; bool single_window_ = false; graphics::Rect window_size_; + bool standalone_ = false; }; } // namespace cmds } // namespace anbox From 157a2f9c1351e02ad369b3cee66d6ecab9f9be06 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 May 2017 11:47:24 +0100 Subject: [PATCH 64/86] cmds: session_manager: Introduce an Experimental Mode flag Some features which Anbox offer may be useful to users, but can not be officially supported. For example, the recently added Stand-Alone Mode can be utilised to make use of different types of independent containers where Anbox does not control the complete life cycle, but since these types of setups can be widely varying and complex, it would not be impossible to provide support. Thus, when running in these modes, it's important for the user to show knowledge that they are operating in an experimental way. This functionality provided by issuing the --experimental flag when starting the Session Manager. Signed-off-by: Lee Jones --- src/anbox/cmds/session_manager.cpp | 8 ++++++++ src/anbox/cmds/session_manager.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/anbox/cmds/session_manager.cpp b/src/anbox/cmds/session_manager.cpp index 924eadf..d0ce924 100644 --- a/src/anbox/cmds/session_manager.cpp +++ b/src/anbox/cmds/session_manager.cpp @@ -109,6 +109,9 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) flag(cli::make_flag(cli::Name{"standalone"}, cli::Description{"Prevents the Container Manager from starting the default container (Experimental)"}, standalone_)); + flag(cli::make_flag(cli::Name{"experimental"}, + cli::Description{"Allows users to use experimental features"}, + experimental_)); action([this](const cli::Command::Context &) { auto trap = core::posix::trap_signals_for_process( @@ -118,6 +121,11 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) trap->stop(); }); + if (standalone_ && !experimental_) { + ERROR("Experimental features selected, but --experimental flag not set"); + return EXIT_FAILURE; + } + if (!fs::exists("/dev/binder") || !fs::exists("/dev/ashmem")) { ERROR("Failed to start as either binder or ashmem kernel drivers are not loaded"); return EXIT_FAILURE; diff --git a/src/anbox/cmds/session_manager.h b/src/anbox/cmds/session_manager.h index 60c3d42..498f5a5 100644 --- a/src/anbox/cmds/session_manager.h +++ b/src/anbox/cmds/session_manager.h @@ -46,6 +46,7 @@ class SessionManager : public cli::CommandWithFlagsAndAction { bool single_window_ = false; graphics::Rect window_size_; bool standalone_ = false; + bool experimental_ = false; }; } // namespace cmds } // namespace anbox From e492cd1af8870cc7ef5ffdeea0dca69231f93c79 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 May 2017 14:00:36 +0100 Subject: [PATCH 65/86] cmds: session_manager: Handle the Container Client class using pointers We can now start the Session Manager in Stand Alone Mode. This means that the Container Manager is not required, since the assumption is that the user will provide their own container. The issue is that the container related calls are spread throughout the Session Manager's code base. So if we attempt to take an instance of the Container Client class in one if-ed out area, by the time we reach the next, it will be out of scope. One solution is to take the instance of the Container Client class globally, then only make use of it if it's required. This works great if the Container Manager is running in the background. However, since a connection is made to the Container Manager during the constructor, if the Container Manager is not running, the side-effect is the following error: Failed to connect to socket /run/anbox-container.socket: Connection refused To solve this problem we will use a global (actually private to the Session Manager) pointer which will always be in scope. It will only be initialised and used when required though. Signed-off-by: Lee Jones --- src/anbox/cmds/session_manager.cpp | 8 ++++---- src/anbox/cmds/session_manager.h | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/anbox/cmds/session_manager.cpp b/src/anbox/cmds/session_manager.cpp index d0ce924..5a46566 100644 --- a/src/anbox/cmds/session_manager.cpp +++ b/src/anbox/cmds/session_manager.cpp @@ -146,9 +146,9 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) auto rt = Runtime::create(); auto dispatcher = anbox::common::create_dispatcher_for_runtime(rt); - container::Client container(rt); if (!standalone_) { - container.register_terminate_handler([&]() { + container_ = std::make_shared(rt); + container_->register_terminate_handler([&]() { WARNING("Lost connection to container manager, terminating."); trap->stop(); }); @@ -237,7 +237,7 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) {"/dev/fuse", "/dev/fuse"}, }; - dispatcher->dispatch([&]() { container.start(container_configuration); }); + dispatcher->dispatch([&]() { container_->start(container_configuration); }); } auto bus = bus_factory_(); @@ -251,7 +251,7 @@ anbox::cmds::SessionManager::SessionManager(const BusFactory &bus_factory) if (!standalone_) { // Stop the container which should close all open connections we have on // our side and should terminate all services. - container.stop(); + container_->stop(); } rt->stop(); diff --git a/src/anbox/cmds/session_manager.h b/src/anbox/cmds/session_manager.h index 498f5a5..25185ac 100644 --- a/src/anbox/cmds/session_manager.h +++ b/src/anbox/cmds/session_manager.h @@ -30,6 +30,9 @@ #include "anbox/graphics/rect.h" namespace anbox { +namespace container { +class Client; +} // namespace container namespace cmds { class SessionManager : public cli::CommandWithFlagsAndAction { public: @@ -40,6 +43,7 @@ class SessionManager : public cli::CommandWithFlagsAndAction { SessionManager(const BusFactory& bus_factory = session_bus_factory()); private: + std::shared_ptr container_; BusFactory bus_factory_; std::string desktop_file_hint_; graphics::GLRendererServer::Config::Driver gles_driver_; From 14d77e9cc4a5203665a512a6485d9a416bfd43de Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 12 May 2017 18:46:25 +0200 Subject: [PATCH 66/86] User proper constants in our adb message processor --- src/anbox/qemu/adb_message_processor.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/anbox/qemu/adb_message_processor.cpp b/src/anbox/qemu/adb_message_processor.cpp index 9fe9575..350c549 100644 --- a/src/anbox/qemu/adb_message_processor.cpp +++ b/src/anbox/qemu/adb_message_processor.cpp @@ -27,10 +27,14 @@ namespace { const unsigned short default_adb_client_port{5037}; const unsigned short default_host_listen_port{6664}; +constexpr const char *loopback_address{"127.0.0.1"}; const std::string accept_command{"accept"}; const std::string ok_command{"ok"}; const std::string ko_command{"ko"}; const std::string start_command{"start"}; +// This timeount should be too high to not cause a too long wait time for the +// user until we connect to the adb host instance after it appeared and not +// too short to not put unnecessary burden on the CPU. const boost::posix_time::seconds default_adb_wait_time{1}; static std::mutex active_instance; } @@ -102,7 +106,7 @@ void AdbMessageProcessor::advance_state() { void AdbMessageProcessor::wait_for_host_connection() { if (!host_connector_) { host_connector_ = std::make_shared( - boost::asio::ip::address_v4::from_string("127.0.0.1"), + boost::asio::ip::address_v4::from_string(loopback_address), default_host_listen_port, runtime_, std::make_shared< network::DelegateConnectionCreator>( @@ -113,12 +117,9 @@ void AdbMessageProcessor::wait_for_host_connection() { // Notify the adb host instance so that it knows on which port our // proxy is waiting for incoming connections. auto messenger = std::make_shared( - boost::asio::ip::address_v4::from_string("127.0.0.1"), - default_adb_client_port, runtime_); - auto message = - utils::string_format("host:emulator:%d", default_host_listen_port); - auto handshake = - utils::string_format("%04x%s", message.size(), message.c_str()); + boost::asio::ip::address_v4::from_string(loopback_address), default_adb_client_port, runtime_); + auto message = utils::string_format("host:emulator:%d", default_host_listen_port); + auto handshake = utils::string_format("%04x%s", message.size(), message.c_str()); messenger->send(handshake.data(), handshake.size()); } catch (std::exception &) { // Try again later when the host adb service is maybe available From 183c02d2d0f7e5d61be551996ff20b2e2a6f7483 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Fri, 12 May 2017 18:46:49 +0200 Subject: [PATCH 67/86] Make adb message processor more robust in shutdown scenarios --- src/anbox/qemu/adb_message_processor.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/anbox/qemu/adb_message_processor.cpp b/src/anbox/qemu/adb_message_processor.cpp index 350c549..ef56773 100644 --- a/src/anbox/qemu/adb_message_processor.cpp +++ b/src/anbox/qemu/adb_message_processor.cpp @@ -16,10 +16,10 @@ */ #include "anbox/qemu/adb_message_processor.h" -#include "anbox/logger.h" #include "anbox/network/delegate_connection_creator.h" #include "anbox/network/delegate_message_processor.h" #include "anbox/network/tcp_socket_messenger.h" +#include "anbox/utils.h" #include #include @@ -54,7 +54,11 @@ AdbMessageProcessor::AdbMessageProcessor( AdbMessageProcessor::~AdbMessageProcessor() { state_ = closed_by_host; + + host_notify_timer_.cancel(); host_connector_.reset(); + + // Unlock our lock to bring down any waiting instance active_instance.unlock(); } @@ -68,6 +72,7 @@ void AdbMessageProcessor::advance_state() { active_instance.lock(); if (state_ == closed_by_host) { + host_notify_timer_.cancel(); host_connector_.reset(); return; } @@ -104,6 +109,9 @@ void AdbMessageProcessor::advance_state() { } void AdbMessageProcessor::wait_for_host_connection() { + if (state_ == closed_by_host || state_ == closed_by_container) + return; + if (!host_connector_) { host_connector_ = std::make_shared( boost::asio::ip::address_v4::from_string(loopback_address), @@ -121,11 +129,11 @@ void AdbMessageProcessor::wait_for_host_connection() { auto message = utils::string_format("host:emulator:%d", default_host_listen_port); auto handshake = utils::string_format("%04x%s", message.size(), message.c_str()); messenger->send(handshake.data(), handshake.size()); - } catch (std::exception &) { + } catch (...) { // Try again later when the host adb service is maybe available + host_notify_timer_.cancel(); host_notify_timer_.expires_from_now(default_adb_wait_time); - host_notify_timer_.async_wait( - [&](const boost::system::error_code &) { wait_for_host_connection(); }); + host_notify_timer_.async_wait([&](const boost::system::error_code &) { wait_for_host_connection(); }); } } @@ -153,11 +161,9 @@ void AdbMessageProcessor::read_next_host_message() { boost::asio::buffer(host_buffer_)); } -void AdbMessageProcessor::on_host_read_size( - const boost::system::error_code &error, std::size_t bytes_read) { +void AdbMessageProcessor::on_host_read_size(const boost::system::error_code &error, std::size_t bytes_read) { if (error) { state_ = closed_by_host; - messenger_->close(); return; } From 62ce199dbc54d0dca70839f15c3215b191248f61 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sun, 14 May 2017 12:53:48 +0200 Subject: [PATCH 68/86] Use std::unique_lock for mutex operations --- src/anbox/qemu/adb_message_processor.cpp | 11 +++++------ src/anbox/qemu/adb_message_processor.h | 5 +++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/anbox/qemu/adb_message_processor.cpp b/src/anbox/qemu/adb_message_processor.cpp index ef56773..ad2e792 100644 --- a/src/anbox/qemu/adb_message_processor.cpp +++ b/src/anbox/qemu/adb_message_processor.cpp @@ -36,13 +36,14 @@ const std::string start_command{"start"}; // user until we connect to the adb host instance after it appeared and not // too short to not put unnecessary burden on the CPU. const boost::posix_time::seconds default_adb_wait_time{1}; -static std::mutex active_instance; } using namespace std::placeholders; namespace anbox { namespace qemu { +std::mutex AdbMessageProcessor::active_instance_{}; + AdbMessageProcessor::AdbMessageProcessor( const std::shared_ptr &rt, const std::shared_ptr &messenger) @@ -50,16 +51,14 @@ AdbMessageProcessor::AdbMessageProcessor( state_(waiting_for_guest_accept_command), expected_command_(accept_command), messenger_(messenger), - host_notify_timer_(rt->service()) {} + host_notify_timer_(rt->service()), + lock_(active_instance_, std::defer_lock) {} AdbMessageProcessor::~AdbMessageProcessor() { state_ = closed_by_host; host_notify_timer_.cancel(); host_connector_.reset(); - - // Unlock our lock to bring down any waiting instance - active_instance.unlock(); } void AdbMessageProcessor::advance_state() { @@ -69,7 +68,7 @@ void AdbMessageProcessor::advance_state() { // running we don't have to do anything here until that one is done. // The container directly starts a second connection once the first // one is established but will not use it until the active one is closed. - active_instance.lock(); + lock_.lock(); if (state_ == closed_by_host) { host_notify_timer_.cancel(); diff --git a/src/anbox/qemu/adb_message_processor.h b/src/anbox/qemu/adb_message_processor.h index b98fa7a..a58925e 100644 --- a/src/anbox/qemu/adb_message_processor.h +++ b/src/anbox/qemu/adb_message_processor.h @@ -27,6 +27,8 @@ #include +#include + namespace anbox { namespace qemu { class AdbMessageProcessor : public network::MessageProcessor { @@ -66,6 +68,9 @@ class AdbMessageProcessor : public network::MessageProcessor { std::shared_ptr host_messenger_; std::array host_buffer_; boost::asio::deadline_timer host_notify_timer_; + std::unique_lock lock_; + + static std::mutex active_instance_; }; } // namespace graphics } // namespace anbox From 56ed59334ff6f5c474e52967d2cbdf03dbb9b160 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sun, 14 May 2017 12:59:08 +0200 Subject: [PATCH 69/86] Don't try to connect to host adb when timer is aborted --- src/anbox/qemu/adb_message_processor.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/anbox/qemu/adb_message_processor.cpp b/src/anbox/qemu/adb_message_processor.cpp index ad2e792..97135cb 100644 --- a/src/anbox/qemu/adb_message_processor.cpp +++ b/src/anbox/qemu/adb_message_processor.cpp @@ -132,7 +132,11 @@ void AdbMessageProcessor::wait_for_host_connection() { // Try again later when the host adb service is maybe available host_notify_timer_.cancel(); host_notify_timer_.expires_from_now(default_adb_wait_time); - host_notify_timer_.async_wait([&](const boost::system::error_code &) { wait_for_host_connection(); }); + host_notify_timer_.async_wait([this](const boost::system::error_code &err) { + if (err) + return; + wait_for_host_connection(); + }); } } @@ -156,8 +160,7 @@ void AdbMessageProcessor::on_host_connection(std::shared_ptrasync_receive_msg(callback, - boost::asio::buffer(host_buffer_)); + host_messenger_->async_receive_msg(callback, boost::asio::buffer(host_buffer_)); } void AdbMessageProcessor::on_host_read_size(const boost::system::error_code &error, std::size_t bytes_read) { From 4fde30b7b667ef0fc3cb8175eabb1547bae6598d Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sun, 14 May 2017 20:52:12 +0200 Subject: [PATCH 70/86] Correct emugl includes and move to std::{mutex,shared_ptr} where possible --- src/anbox/graphics/emugl/ColorBuffer.cpp | 21 +++-- src/anbox/graphics/emugl/ColorBuffer.h | 3 +- src/anbox/graphics/emugl/ReadBuffer.cpp | 7 +- src/anbox/graphics/emugl/ReadBuffer.h | 3 +- src/anbox/graphics/emugl/RenderApi.cpp | 13 ++-- src/anbox/graphics/emugl/RenderApi.h | 2 +- src/anbox/graphics/emugl/RenderContext.cpp | 3 +- src/anbox/graphics/emugl/RenderContext.h | 8 +- src/anbox/graphics/emugl/RenderControl.cpp | 20 ++--- src/anbox/graphics/emugl/RenderControl.h | 2 + src/anbox/graphics/emugl/RenderThread.cpp | 36 ++++----- src/anbox/graphics/emugl/RenderThread.h | 11 +-- src/anbox/graphics/emugl/RenderThreadInfo.cpp | 6 +- src/anbox/graphics/emugl/RenderThreadInfo.h | 12 ++- src/anbox/graphics/emugl/Renderable.cpp | 2 +- src/anbox/graphics/emugl/Renderer.cpp | 78 +++++++++++-------- src/anbox/graphics/emugl/Renderer.h | 17 ++-- src/anbox/graphics/emugl/RendererConfig.cpp | 7 +- src/anbox/graphics/emugl/TextureDraw.cpp | 8 +- src/anbox/graphics/emugl/TextureResize.cpp | 7 +- src/anbox/graphics/emugl/TextureResize.h | 1 + src/anbox/graphics/emugl/TimeUtils.cpp | 3 +- src/anbox/graphics/emugl/TimeUtils.h | 1 + src/anbox/graphics/emugl/WindowSurface.cpp | 13 ++-- src/anbox/graphics/emugl/WindowSurface.h | 8 +- .../graphics/opengles_message_processor.cpp | 4 +- .../graphics/opengles_message_processor.h | 11 ++- 27 files changed, 160 insertions(+), 147 deletions(-) diff --git a/src/anbox/graphics/emugl/ColorBuffer.cpp b/src/anbox/graphics/emugl/ColorBuffer.cpp index c1efb6e..9cace59 100644 --- a/src/anbox/graphics/emugl/ColorBuffer.cpp +++ b/src/anbox/graphics/emugl/ColorBuffer.cpp @@ -13,17 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "ColorBuffer.h" - -#include "DispatchTables.h" -#include "RenderThreadInfo.h" -#include "TextureDraw.h" -#include "TextureResize.h" - -#include "OpenGLESDispatch/EGLDispatch.h" +#include "anbox/graphics/emugl/ColorBuffer.h" +#include "anbox/graphics/emugl/DispatchTables.h" +#include "anbox/graphics/emugl/RenderThreadInfo.h" +#include "anbox/graphics/emugl/TextureDraw.h" +#include "anbox/graphics/emugl/TextureResize.h" #include "anbox/logger.h" +#include "external/android-emugl/host/include/OpenGLESDispatch/EGLDispatch.h" + #include namespace { @@ -251,7 +250,7 @@ void ColorBuffer::subUpdate(int x, int y, int width, int height, bool ColorBuffer::blitFromCurrentReadBuffer() { RenderThreadInfo* tInfo = RenderThreadInfo::get(); - if (!tInfo->currContext.Ptr()) { + if (!tInfo->currContext) { // no Current context return false; } @@ -312,7 +311,7 @@ bool ColorBuffer::bindToTexture() { return false; } RenderThreadInfo* tInfo = RenderThreadInfo::get(); - if (!tInfo->currContext.Ptr()) { + if (!tInfo->currContext) { return false; } if (tInfo->currContext->isGL2()) { @@ -328,7 +327,7 @@ bool ColorBuffer::bindToRenderbuffer() { return false; } RenderThreadInfo* tInfo = RenderThreadInfo::get(); - if (!tInfo->currContext.Ptr()) { + if (!tInfo->currContext) { return false; } if (tInfo->currContext->isGL2()) { diff --git a/src/anbox/graphics/emugl/ColorBuffer.h b/src/anbox/graphics/emugl/ColorBuffer.h index 793a671..19bf44c 100644 --- a/src/anbox/graphics/emugl/ColorBuffer.h +++ b/src/anbox/graphics/emugl/ColorBuffer.h @@ -19,7 +19,6 @@ #include #include #include -#include "emugl/common/smart_ptr.h" #include @@ -135,6 +134,6 @@ class ColorBuffer { TextureResize* m_resizer; }; -typedef emugl::SmartPtr ColorBufferPtr; +typedef std::shared_ptr ColorBufferPtr; #endif diff --git a/src/anbox/graphics/emugl/ReadBuffer.cpp b/src/anbox/graphics/emugl/ReadBuffer.cpp index 3ff151d..d7bff7b 100644 --- a/src/anbox/graphics/emugl/ReadBuffer.cpp +++ b/src/anbox/graphics/emugl/ReadBuffer.cpp @@ -13,13 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "ReadBuffer.h" + +#include "anbox/graphics/emugl/ReadBuffer.h" +#include "anbox/logger.h" + #include #include #include -#include "anbox/logger.h" - ReadBuffer::ReadBuffer(size_t bufsize) { m_size = bufsize; m_buf = static_cast(malloc(m_size * sizeof(unsigned char))); diff --git a/src/anbox/graphics/emugl/ReadBuffer.h b/src/anbox/graphics/emugl/ReadBuffer.h index 86a486f..68c7545 100644 --- a/src/anbox/graphics/emugl/ReadBuffer.h +++ b/src/anbox/graphics/emugl/ReadBuffer.h @@ -16,7 +16,7 @@ #ifndef _READ_BUFFER_H #define _READ_BUFFER_H -#include "IOStream.h" +#include "external/android-emugl/host/include/libOpenglRender/IOStream.h" class ReadBuffer { public: @@ -34,4 +34,5 @@ class ReadBuffer { size_t m_size; size_t m_validData; }; + #endif diff --git a/src/anbox/graphics/emugl/RenderApi.cpp b/src/anbox/graphics/emugl/RenderApi.cpp index dc07604..69fce23 100644 --- a/src/anbox/graphics/emugl/RenderApi.cpp +++ b/src/anbox/graphics/emugl/RenderApi.cpp @@ -14,15 +14,14 @@ * limitations under the License. */ -#include "RenderApi.h" +#include "anbox/graphics/emugl/RenderApi.h" +#include "anbox/graphics/emugl/DispatchTables.h" -#include "DispatchTables.h" +#include "external/android-emugl/host/include/OpenGLESDispatch/EGLDispatch.h" +#include "external/android-emugl/host/include/OpenGLESDispatch/GLESv1Dispatch.h" +#include "external/android-emugl/host/include/OpenGLESDispatch/GLESv2Dispatch.h" -#include "OpenGLESDispatch/EGLDispatch.h" -#include "OpenGLESDispatch/GLESv1Dispatch.h" -#include "OpenGLESDispatch/GLESv2Dispatch.h" - -#include "emugl/common/crash_reporter.h" +#include "external/android-emugl/shared/emugl/common/crash_reporter.h" #include diff --git a/src/anbox/graphics/emugl/RenderApi.h b/src/anbox/graphics/emugl/RenderApi.h index 65cab84..150fdd6 100644 --- a/src/anbox/graphics/emugl/RenderApi.h +++ b/src/anbox/graphics/emugl/RenderApi.h @@ -21,7 +21,7 @@ #include -#include "emugl/common/logging.h" +#include "external/android-emugl/shared/emugl/common/logging.h" typedef struct { logger_t coarse; diff --git a/src/anbox/graphics/emugl/RenderContext.cpp b/src/anbox/graphics/emugl/RenderContext.cpp index ef47143..2909a49 100644 --- a/src/anbox/graphics/emugl/RenderContext.cpp +++ b/src/anbox/graphics/emugl/RenderContext.cpp @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "RenderContext.h" + +#include "anbox/graphics/emugl/RenderContext.h" #include "OpenGLESDispatch/EGLDispatch.h" diff --git a/src/anbox/graphics/emugl/RenderContext.h b/src/anbox/graphics/emugl/RenderContext.h index fd2dccf..6e18a9b 100644 --- a/src/anbox/graphics/emugl/RenderContext.h +++ b/src/anbox/graphics/emugl/RenderContext.h @@ -13,14 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #ifndef _LIBRENDER_RENDER_CONTEXT_H #define _LIBRENDER_RENDER_CONTEXT_H -#include "GLDecoderContextData.h" -#include "emugl/common/smart_ptr.h" +#include "external/android-emugl/shared/OpenglCodecCommon/GLDecoderContextData.h" #include +#include + // A class used to model a guest EGLContext. This simply wraps a host // EGLContext, associated with an GLDecoderContextData instance that is // used to store copies of guest-side arrays. @@ -60,6 +62,6 @@ class RenderContext { GLDecoderContextData mContextData; }; -typedef emugl::SmartPtr RenderContextPtr; +typedef std::shared_ptr RenderContextPtr; #endif // _LIBRENDER_RENDER_CONTEXT_H diff --git a/src/anbox/graphics/emugl/RenderControl.cpp b/src/anbox/graphics/emugl/RenderControl.cpp index b479be0..094b46c 100644 --- a/src/anbox/graphics/emugl/RenderControl.cpp +++ b/src/anbox/graphics/emugl/RenderControl.cpp @@ -13,20 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "RenderControl.h" - -#include "ChecksumCalculatorThreadInfo.h" -#include "DispatchTables.h" -#include "DisplayManager.h" -#include "RenderThreadInfo.h" -#include "Renderer.h" -#include "RendererConfig.h" - -#include "OpenGLESDispatch/EGLDispatch.h" +#include "anbox/graphics/emugl/RenderControl.h" +#include "anbox/graphics/emugl/DispatchTables.h" +#include "anbox/graphics/emugl/DisplayManager.h" +#include "anbox/graphics/emugl/RenderThreadInfo.h" +#include "anbox/graphics/emugl/Renderer.h" +#include "anbox/graphics/emugl/RendererConfig.h" #include "anbox/graphics/layer_composer.h" #include "anbox/logger.h" +#include "external/android-emugl/shared/OpenglCodecCommon/ChecksumCalculatorThreadInfo.h" +#include "external/android-emugl/host/include/OpenGLESDispatch/EGLDispatch.h" + + #include #include diff --git a/src/anbox/graphics/emugl/RenderControl.h b/src/anbox/graphics/emugl/RenderControl.h index 82f1635..5495560 100644 --- a/src/anbox/graphics/emugl/RenderControl.h +++ b/src/anbox/graphics/emugl/RenderControl.h @@ -13,9 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #ifndef _RENDER_CONTROL_H #define _RENDER_CONTROL_H +// Generated with emugl at build time #include "renderControl_dec.h" #include diff --git a/src/anbox/graphics/emugl/RenderThread.cpp b/src/anbox/graphics/emugl/RenderThread.cpp index 9dbc569..7e6dff7 100644 --- a/src/anbox/graphics/emugl/RenderThread.cpp +++ b/src/anbox/graphics/emugl/RenderThread.cpp @@ -13,32 +13,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "RenderThread.h" - -#include "ReadBuffer.h" -#include "RenderControl.h" -#include "RenderThreadInfo.h" -#include "Renderer.h" -#include "TimeUtils.h" - -#include "../../../shared/OpenglCodecCommon/ChecksumCalculatorThreadInfo.h" -#include "OpenGLESDispatch/EGLDispatch.h" -#include "OpenGLESDispatch/GLESv1Dispatch.h" -#include "OpenGLESDispatch/GLESv2Dispatch.h" +#include "anbox/graphics/emugl/RenderThread.h" +#include "anbox/graphics/emugl/ReadBuffer.h" +#include "anbox/graphics/emugl/RenderControl.h" +#include "anbox/graphics/emugl/RenderThreadInfo.h" +#include "anbox/graphics/emugl/Renderer.h" +#include "anbox/graphics/emugl/TimeUtils.h" #include "anbox/logger.h" +#include "external/android-emugl/shared/OpenglCodecCommon/ChecksumCalculatorThreadInfo.h" +#include "external/android-emugl/host/include/OpenGLESDispatch/EGLDispatch.h" +#include "external/android-emugl/host/include/OpenGLESDispatch/GLESv1Dispatch.h" +#include "external/android-emugl/host/include/OpenGLESDispatch/GLESv2Dispatch.h" + #define STREAM_BUFFER_SIZE 4 * 1024 * 1024 -RenderThread::RenderThread(const std::shared_ptr &renderer, IOStream *stream, emugl::Mutex *lock) - : emugl::Thread(), renderer_(renderer), m_lock(lock), m_stream(stream) {} +RenderThread::RenderThread(const std::shared_ptr &renderer, IOStream *stream, std::mutex &m) + : emugl::Thread(), renderer_(renderer), m_lock(m), m_stream(stream) {} RenderThread::~RenderThread() { forceStop(); } -RenderThread *RenderThread::create(const std::shared_ptr &renderer, IOStream *stream, emugl::Mutex *lock) { - return new RenderThread(renderer, stream, lock); +RenderThread *RenderThread::create(const std::shared_ptr &renderer, IOStream *stream, std::mutex &m) { + return new RenderThread(renderer, stream, m); } void RenderThread::forceStop() { m_stream->forceStop(); } @@ -62,7 +61,8 @@ intptr_t RenderThread::main() { do { progress = false; - m_lock->lock(); + std::unique_lock l(m_lock); + size_t last = threadInfo.m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream); if (last > 0) { @@ -83,8 +83,6 @@ intptr_t RenderThread::main() { progress = true; } - m_lock->unlock(); - } while (progress); } diff --git a/src/anbox/graphics/emugl/RenderThread.h b/src/anbox/graphics/emugl/RenderThread.h index 5e6ae11..74cde6d 100644 --- a/src/anbox/graphics/emugl/RenderThread.h +++ b/src/anbox/graphics/emugl/RenderThread.h @@ -13,15 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #ifndef _LIB_OPENGL_RENDER_RENDER_THREAD_H #define _LIB_OPENGL_RENDER_RENDER_THREAD_H -#include "IOStream.h" +#include "external/android-emugl/host/include/libOpenglRender/IOStream.h" -#include "emugl/common/mutex.h" #include "emugl/common/thread.h" #include +#include class Renderer; @@ -36,7 +37,7 @@ class RenderThread : public emugl::Thread { // decoding operations between all threads. // TODO(digit): Why is this needed here? Shouldn't this be handled // by the decoders themselves or at a lower-level? - static RenderThread* create(const std::shared_ptr& renderer, IOStream* stream, emugl::Mutex* mutex); + static RenderThread* create(const std::shared_ptr& renderer, IOStream* stream, std::mutex &m); // Destructor. virtual ~RenderThread(); @@ -51,12 +52,12 @@ class RenderThread : public emugl::Thread { private: RenderThread(); // No default constructor - RenderThread(const std::shared_ptr& renderer, IOStream* stream, emugl::Mutex* mutex); + RenderThread(const std::shared_ptr& renderer, IOStream* stream, std::mutex &m); virtual intptr_t main(); std::shared_ptr renderer_; - emugl::Mutex* m_lock; + std::mutex &m_lock; IOStream* m_stream; }; diff --git a/src/anbox/graphics/emugl/RenderThreadInfo.cpp b/src/anbox/graphics/emugl/RenderThreadInfo.cpp index 500a0b4..bc87705 100644 --- a/src/anbox/graphics/emugl/RenderThreadInfo.cpp +++ b/src/anbox/graphics/emugl/RenderThreadInfo.cpp @@ -14,10 +14,10 @@ * limitations under the License. */ -#include "RenderThreadInfo.h" +#include "anbox/graphics/emugl/RenderThreadInfo.h" -#include "emugl/common/lazy_instance.h" -#include "emugl/common/thread_store.h" +#include "external/android-emugl/shared/emugl/common/lazy_instance.h" +#include "external/android-emugl/shared/emugl/common/thread_store.h" namespace { class ThreadInfoStore : public ::emugl::ThreadStore { diff --git a/src/anbox/graphics/emugl/RenderThreadInfo.h b/src/anbox/graphics/emugl/RenderThreadInfo.h index f246ae5..9440d61 100644 --- a/src/anbox/graphics/emugl/RenderThreadInfo.h +++ b/src/anbox/graphics/emugl/RenderThreadInfo.h @@ -13,13 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #ifndef _LIB_OPENGL_RENDER_THREAD_INFO_H #define _LIB_OPENGL_RENDER_THREAD_INFO_H -#include "GLESv1Decoder.h" -#include "GLESv2Decoder.h" -#include "RenderContext.h" -#include "WindowSurface.h" +#include "anbox/graphics/emugl/RenderContext.h" +#include "anbox/graphics/emugl/WindowSurface.h" + +#include "external/android-emugl/host/libs/GLESv1_dec/GLESv1Decoder.h" +#include "external/android-emugl/host/libs/GLESv2_dec/GLESv2Decoder.h" + +// Generated with emugl at build time #include "renderControl_dec.h" #include diff --git a/src/anbox/graphics/emugl/Renderable.cpp b/src/anbox/graphics/emugl/Renderable.cpp index e75d1a2..06e4273 100644 --- a/src/anbox/graphics/emugl/Renderable.cpp +++ b/src/anbox/graphics/emugl/Renderable.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "Renderable.h" +#include "anbox/graphics/emugl/Renderable.h" Renderable::Renderable(const std::string &name, const std::uint32_t &buffer, const anbox::graphics::Rect &screen_position, diff --git a/src/anbox/graphics/emugl/Renderer.cpp b/src/anbox/graphics/emugl/Renderer.cpp index f4e5a76..776de49 100644 --- a/src/anbox/graphics/emugl/Renderer.cpp +++ b/src/anbox/graphics/emugl/Renderer.cpp @@ -14,19 +14,18 @@ * limitations under the License. */ -#include "Renderer.h" - -#include "DispatchTables.h" -#include "RenderThreadInfo.h" -#include "TimeUtils.h" -#include "gles2_dec.h" - -#include "OpenGLESDispatch/EGLDispatch.h" - +#include "anbox/graphics/emugl/Renderer.h" +#include "anbox/graphics/emugl/DispatchTables.h" +#include "anbox/graphics/emugl/RenderThreadInfo.h" +#include "anbox/graphics/emugl/TimeUtils.h" #include "anbox/graphics/gl_extensions.h" - #include "anbox/logger.h" +#include "external/android-emugl/host/include/OpenGLESDispatch/EGLDispatch.h" + +// Generated with emugl at build time +#include "gles2_dec.h" + #include #include @@ -361,13 +360,14 @@ HandleType Renderer::genHandle() { HandleType Renderer::createColorBuffer(int p_width, int p_height, GLenum p_internalFormat) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); + HandleType ret = 0; ColorBufferPtr cb(ColorBuffer::create( getDisplay(), p_width, p_height, p_internalFormat, getCaps().has_eglimage_texture_2d, m_colorBufferHelper)); - if (cb.Ptr() != NULL) { + if (cb) { ret = genHandle(); m_colorbuffers[ret].cb = cb; m_colorbuffers[ret].refcount = 1; @@ -377,7 +377,8 @@ HandleType Renderer::createColorBuffer(int p_width, int p_height, HandleType Renderer::createRenderContext(int p_config, HandleType p_share, bool p_isGL2) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); + HandleType ret = 0; const RendererConfig *config = getConfigs()->get(p_config); @@ -394,11 +395,11 @@ HandleType Renderer::createRenderContext(int p_config, HandleType p_share, share = (*s).second; } EGLContext sharedContext = - share.Ptr() ? share->getEGLContext() : EGL_NO_CONTEXT; + share ? share->getEGLContext() : EGL_NO_CONTEXT; RenderContextPtr rctx(RenderContext::create( m_eglDisplay, config->getEglConfig(), sharedContext, p_isGL2)); - if (rctx.Ptr() != NULL) { + if (rctx) { ret = genHandle(); m_contexts[ret] = rctx; RenderThreadInfo *tinfo = RenderThreadInfo::get(); @@ -409,7 +410,7 @@ HandleType Renderer::createRenderContext(int p_config, HandleType p_share, HandleType Renderer::createWindowSurface(int p_config, int p_width, int p_height) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); HandleType ret = 0; @@ -420,7 +421,7 @@ HandleType Renderer::createWindowSurface(int p_config, int p_width, WindowSurfacePtr win(WindowSurface::create( getDisplay(), config->getEglConfig(), p_width, p_height)); - if (win.Ptr() != NULL) { + if (win) { ret = genHandle(); m_windows[ret] = std::pair(win, 0); RenderThreadInfo *tinfo = RenderThreadInfo::get(); @@ -431,7 +432,8 @@ HandleType Renderer::createWindowSurface(int p_config, int p_width, } void Renderer::drainRenderContext() { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); + RenderThreadInfo *tinfo = RenderThreadInfo::get(); if (tinfo->m_contextSet.empty()) return; for (std::set::iterator it = tinfo->m_contextSet.begin(); @@ -443,7 +445,8 @@ void Renderer::drainRenderContext() { } void Renderer::drainWindowSurface() { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); + RenderThreadInfo *tinfo = RenderThreadInfo::get(); if (tinfo->m_windowSet.empty()) return; for (std::set::iterator it = tinfo->m_windowSet.begin(); @@ -466,7 +469,8 @@ void Renderer::drainWindowSurface() { } void Renderer::DestroyRenderContext(HandleType p_context) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); + m_contexts.erase(p_context); RenderThreadInfo *tinfo = RenderThreadInfo::get(); if (tinfo->m_contextSet.empty()) return; @@ -474,7 +478,8 @@ void Renderer::DestroyRenderContext(HandleType p_context) { } void Renderer::DestroyWindowSurface(HandleType p_surface) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); + if (m_windows.find(p_surface) != m_windows.end()) { m_windows.erase(p_surface); RenderThreadInfo *tinfo = RenderThreadInfo::get(); @@ -484,7 +489,8 @@ void Renderer::DestroyWindowSurface(HandleType p_surface) { } int Renderer::openColorBuffer(HandleType p_colorbuffer) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); + ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); if (c == m_colorbuffers.end()) { // bad colorbuffer handle @@ -496,7 +502,8 @@ int Renderer::openColorBuffer(HandleType p_colorbuffer) { } void Renderer::closeColorBuffer(HandleType p_colorbuffer) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); + ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); if (c == m_colorbuffers.end()) { // This is harmless: it is normal for guest system to issue @@ -511,7 +518,7 @@ void Renderer::closeColorBuffer(HandleType p_colorbuffer) { } bool Renderer::flushWindowSurfaceColorBuffer(HandleType p_surface) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); WindowSurfaceMap::iterator w(m_windows.find(p_surface)); if (w == m_windows.end()) { @@ -521,7 +528,10 @@ bool Renderer::flushWindowSurfaceColorBuffer(HandleType p_surface) { return false; } - WindowSurface *surface = (*w).second.first.Ptr(); + auto surface = (*w).second.first; + if (!surface) + return false; + surface->flushColorBuffer(); return true; @@ -529,7 +539,7 @@ bool Renderer::flushWindowSurfaceColorBuffer(HandleType p_surface) { bool Renderer::setWindowSurfaceColorBuffer(HandleType p_surface, HandleType p_colorbuffer) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); WindowSurfaceMap::iterator w(m_windows.find(p_surface)); if (w == m_windows.end()) { @@ -553,7 +563,7 @@ bool Renderer::setWindowSurfaceColorBuffer(HandleType p_surface, void Renderer::readColorBuffer(HandleType p_colorbuffer, int x, int y, int width, int height, GLenum format, GLenum type, void *pixels) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); if (c == m_colorbuffers.end()) { @@ -567,7 +577,7 @@ void Renderer::readColorBuffer(HandleType p_colorbuffer, int x, int y, bool Renderer::updateColorBuffer(HandleType p_colorbuffer, int x, int y, int width, int height, GLenum format, GLenum type, void *pixels) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); if (c == m_colorbuffers.end()) { @@ -581,7 +591,7 @@ bool Renderer::updateColorBuffer(HandleType p_colorbuffer, int x, int y, } bool Renderer::bindColorBufferToTexture(HandleType p_colorbuffer) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); if (c == m_colorbuffers.end()) { @@ -593,7 +603,7 @@ bool Renderer::bindColorBufferToTexture(HandleType p_colorbuffer) { } bool Renderer::bindColorBufferToRenderbuffer(HandleType p_colorbuffer) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); ColorBufferMap::iterator c(m_colorbuffers.find(p_colorbuffer)); if (c == m_colorbuffers.end()) { @@ -606,7 +616,7 @@ bool Renderer::bindColorBufferToRenderbuffer(HandleType p_colorbuffer) { bool Renderer::bindContext(HandleType p_context, HandleType p_drawSurface, HandleType p_readSurface) { - emugl::Mutex::AutoLock mutex(m_lock); + std::unique_lock l(m_lock); WindowSurfacePtr draw(NULL), read(NULL); RenderContextPtr ctx(NULL); @@ -654,7 +664,7 @@ bool Renderer::bindContext(HandleType p_context, HandleType p_drawSurface, // RenderThreadInfo *tinfo = RenderThreadInfo::get(); WindowSurfacePtr bindDraw, bindRead; - if (draw.Ptr() == NULL && read.Ptr() == NULL) { + if (!draw && !read) { // Unbind the current read and draw surfaces from the context bindDraw = tinfo->currDrawSurf; bindRead = tinfo->currReadSurf; @@ -663,8 +673,8 @@ bool Renderer::bindContext(HandleType p_context, HandleType p_drawSurface, bindRead = read; } - if (bindDraw.Ptr() != NULL && bindRead.Ptr() != NULL) { - if (bindDraw.Ptr() != bindRead.Ptr()) { + if (bindDraw && bindRead) { + if (bindDraw != bindRead) { bindDraw->bind(ctx, WindowSurface::BIND_DRAW); bindRead->bind(ctx, WindowSurface::BIND_READ); } else { diff --git a/src/anbox/graphics/emugl/Renderer.h b/src/anbox/graphics/emugl/Renderer.h index 5258639..cfcc0b2 100644 --- a/src/anbox/graphics/emugl/Renderer.h +++ b/src/anbox/graphics/emugl/Renderer.h @@ -16,14 +16,12 @@ #ifndef _LIBRENDER_FRAMEBUFFER_H #define _LIBRENDER_FRAMEBUFFER_H -#include "ColorBuffer.h" -#include "RenderContext.h" -#include "RendererConfig.h" -#include "TextureDraw.h" -#include "WindowSurface.h" -#include "emugl/common/mutex.h" - -#include "Renderable.h" +#include "anbox/graphics/emugl/ColorBuffer.h" +#include "anbox/graphics/emugl/RenderContext.h" +#include "anbox/graphics/emugl/RendererConfig.h" +#include "anbox/graphics/emugl/TextureDraw.h" +#include "anbox/graphics/emugl/WindowSurface.h" +#include "anbox/graphics/emugl/Renderable.h" #include "anbox/graphics/primitives.h" #include "anbox/graphics/program_family.h" @@ -32,6 +30,7 @@ #include #include +#include #include @@ -257,7 +256,7 @@ class Renderer : public anbox::graphics::Renderer { private: static Renderer* s_renderer; static HandleType s_nextHandle; - emugl::Mutex m_lock; + std::mutex m_lock; RendererConfigList* m_configs; RendererCaps m_caps; EGLDisplay m_eglDisplay; diff --git a/src/anbox/graphics/emugl/RendererConfig.cpp b/src/anbox/graphics/emugl/RendererConfig.cpp index 83b044f..02b6b78 100644 --- a/src/anbox/graphics/emugl/RendererConfig.cpp +++ b/src/anbox/graphics/emugl/RendererConfig.cpp @@ -12,15 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "RendererConfig.h" +#include "anbox/graphics/emugl/RendererConfig.h" +#include "anbox/logger.h" -#include "OpenGLESDispatch/EGLDispatch.h" +#include "external/android-emugl/host/include/OpenGLESDispatch/EGLDispatch.h" #include #include -#include "anbox/logger.h" - namespace { const GLuint kConfigAttributes[] = { EGL_DEPTH_SIZE, // must be first - see getDepthSize() diff --git a/src/anbox/graphics/emugl/TextureDraw.cpp b/src/anbox/graphics/emugl/TextureDraw.cpp index bb421bd..2c052f9 100644 --- a/src/anbox/graphics/emugl/TextureDraw.cpp +++ b/src/anbox/graphics/emugl/TextureDraw.cpp @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "TextureDraw.h" - -#include "DispatchTables.h" +#include "anbox/graphics/emugl/TextureDraw.h" +#include "anbox/graphics/emugl/DispatchTables.h" +#include "anbox/logger.h" #include #include @@ -22,8 +22,6 @@ #include -#include "anbox/logger.h" - // M_PI isn't defined in C++ (when strict ISO compliance is enabled) #ifndef M_PI #define M_PI 3.14159265358979323846264338327 diff --git a/src/anbox/graphics/emugl/TextureResize.cpp b/src/anbox/graphics/emugl/TextureResize.cpp index 131be30..49407b1 100644 --- a/src/anbox/graphics/emugl/TextureResize.cpp +++ b/src/anbox/graphics/emugl/TextureResize.cpp @@ -13,17 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "TextureResize.h" -#include "DispatchTables.h" +#include "anbox/graphics/emugl/TextureResize.h" +#include "anbox/graphics/emugl/DispatchTables.h" +#include "anbox/logger.h" #include #include #include #include -#include "anbox/logger.h" - #define MAX_FACTOR_POWER 4 static const char kCommonShaderSource[] = diff --git a/src/anbox/graphics/emugl/TextureResize.h b/src/anbox/graphics/emugl/TextureResize.h index 8024761..fece99d 100644 --- a/src/anbox/graphics/emugl/TextureResize.h +++ b/src/anbox/graphics/emugl/TextureResize.h @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #ifndef _LIBRENDER_TEXTURERESIZE_H #define _LIBRENDER_TEXTURERESIZE_H diff --git a/src/anbox/graphics/emugl/TimeUtils.cpp b/src/anbox/graphics/emugl/TimeUtils.cpp index 854bb79..8e80cd4 100644 --- a/src/anbox/graphics/emugl/TimeUtils.cpp +++ b/src/anbox/graphics/emugl/TimeUtils.cpp @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "TimeUtils.h" + +#include "anbox/graphics/emugl/TimeUtils.h" #include #include diff --git a/src/anbox/graphics/emugl/TimeUtils.h b/src/anbox/graphics/emugl/TimeUtils.h index bc4fd1c..116e37a 100644 --- a/src/anbox/graphics/emugl/TimeUtils.h +++ b/src/anbox/graphics/emugl/TimeUtils.h @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #ifndef _TIME_UTILS_H #define _TIME_UTILS_H diff --git a/src/anbox/graphics/emugl/WindowSurface.cpp b/src/anbox/graphics/emugl/WindowSurface.cpp index 669ce6d..fd60aba 100644 --- a/src/anbox/graphics/emugl/WindowSurface.cpp +++ b/src/anbox/graphics/emugl/WindowSurface.cpp @@ -13,17 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "WindowSurface.h" -#include "RendererConfig.h" -#include "OpenGLESDispatch/EGLDispatch.h" +#include "anbox/graphics/emugl/WindowSurface.h" +#include "anbox/graphics/emugl/RendererConfig.h" +#include "anbox/logger.h" + +#include "external/android-emugl/host/include/OpenGLESDispatch/EGLDispatch.h" #include #include #include -#include "anbox/logger.h" WindowSurface::WindowSurface(EGLDisplay display, EGLConfig config) : mSurface(NULL), @@ -84,7 +85,7 @@ void WindowSurface::bind(RenderContextPtr p_ctx, BindType p_bindType) { } bool WindowSurface::flushColorBuffer() { - if (!mAttachedColorBuffer.Ptr()) { + if (!mAttachedColorBuffer) { return true; } if (!mWidth || !mHeight) { @@ -98,7 +99,7 @@ bool WindowSurface::flushColorBuffer() { return false; } - if (!mDrawContext.Ptr()) { + if (!mDrawContext) { ERROR("Draw context is NULL"); return false; } diff --git a/src/anbox/graphics/emugl/WindowSurface.h b/src/anbox/graphics/emugl/WindowSurface.h index 62c497d..4b35ddb 100644 --- a/src/anbox/graphics/emugl/WindowSurface.h +++ b/src/anbox/graphics/emugl/WindowSurface.h @@ -16,10 +16,8 @@ #ifndef _LIBRENDER_WINDOW_SURFACE_H #define _LIBRENDER_WINDOW_SURFACE_H -#include "ColorBuffer.h" -#include "RenderContext.h" - -#include "emugl/common/smart_ptr.h" +#include "anbox/graphics/emugl/ColorBuffer.h" +#include "anbox/graphics/emugl/RenderContext.h" #include #include @@ -94,6 +92,6 @@ class WindowSurface { EGLDisplay mDisplay; }; -typedef emugl::SmartPtr WindowSurfacePtr; +typedef std::shared_ptr WindowSurfacePtr; #endif // _LIBRENDER_WINDOW_SURFACE_H diff --git a/src/anbox/graphics/opengles_message_processor.cpp b/src/anbox/graphics/opengles_message_processor.cpp index bd06793..e54c205 100644 --- a/src/anbox/graphics/opengles_message_processor.cpp +++ b/src/anbox/graphics/opengles_message_processor.cpp @@ -29,7 +29,7 @@ namespace anbox { namespace graphics { -emugl::Mutex OpenGlesMessageProcessor::global_lock{}; +std::mutex OpenGlesMessageProcessor::global_lock{}; OpenGlesMessageProcessor::OpenGlesMessageProcessor( const std::shared_ptr &renderer, @@ -43,7 +43,7 @@ OpenGlesMessageProcessor::OpenGlesMessageProcessor( boost::asio::buffer(&client_flags, sizeof(unsigned int))); if (err) ERROR("%s", err.message()); - render_thread_.reset(RenderThread::create(renderer, stream_.get(), &global_lock)); + render_thread_.reset(RenderThread::create(renderer, stream_.get(), std::ref(global_lock))); if (!render_thread_->start()) BOOST_THROW_EXCEPTION( std::runtime_error("Failed to start renderer thread")); diff --git a/src/anbox/graphics/opengles_message_processor.h b/src/anbox/graphics/opengles_message_processor.h index 45f4c01..8f3bd7a 100644 --- a/src/anbox/graphics/opengles_message_processor.h +++ b/src/anbox/graphics/opengles_message_processor.h @@ -18,16 +18,15 @@ #ifndef ANBOX_GRAPHICS_OPENGLES_MESSAGE_PROCESSOR_H_ #define ANBOX_GRAPHICS_OPENGLES_MESSAGE_PROCESSOR_H_ -#include - -#include - #include "anbox/network/message_processor.h" #include "anbox/network/socket_connection.h" #include "anbox/network/socket_messenger.h" #include "anbox/runtime.h" -#include "external/android-emugl/shared/emugl/common/mutex.h" +#include + +#include +#include class IOStream; class RenderThread; @@ -45,7 +44,7 @@ class OpenGlesMessageProcessor : public network::MessageProcessor { bool process_data(const std::vector &data) override; private: - static emugl::Mutex global_lock; + static std::mutex global_lock; std::shared_ptr messenger_; std::shared_ptr stream_; From bae91aedbfe5de35812dee54714f13a55f54594d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AC=9D=E8=87=B4=E9=82=A6=20=28XIE=20Zhibang=29?= Date: Mon, 15 May 2017 16:57:50 +0800 Subject: [PATCH 71/86] Update build-android.md "anbox_desktop_armv7a_arm" is already renamed to "anbox_desktop_armv7a_neon". --- docs/build-android.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build-android.md b/docs/build-android.md index 3789155..cfd0a56 100644 --- a/docs/build-android.md +++ b/docs/build-android.md @@ -50,7 +50,7 @@ $ lunch anbox_desktop_x86_64-userdebug The complete list of supported build targets: * anbox_desktop_x86_64-userdebug - * anbox_desktop_armv7a_arm-userdebug + * anbox_desktop_armv7a_neon-userdebug * anbox_desktop_arm64-userdebug Now build everything with From b10f16428a88317f9552aeed8e354ec6a809a919 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Wed, 17 May 2017 11:08:10 +0200 Subject: [PATCH 72/86] Make dependency on properties-cpp explicit ...so its include files are found even in a non-default location --- CMakeLists.txt | 1 + src/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ade5b8..6d1dcf3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,7 @@ pkg_check_modules(SDL2_IMAGE SDL2_image REQUIRED) pkg_check_modules(DBUS_CPP dbus-cpp REQUIRED) pkg_check_modules(DBUS dbus-1 REQUIRED) pkg_check_modules(LXC lxc REQUIRED) +pkg_check_modules(PROPERTIES_CPP properties-cpp REQUIRED) pkg_check_modules(MIRCLIENT mirclient) if (MIRCLIENT_FOUND) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMIR_SUPPORT") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 60817e4..3fb6a7e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,7 @@ include_directories( ${DBUS_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS} + ${PROPERTIES_CPP_INCLUDE_DIRS} ${LXC_INCLUDE_DIRS} ${MIRCLIENT_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} From f26252d1fc2bb169c61687d6236adea169526b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernhard=20Rosenkr=C3=A4nzer?= Date: Thu, 18 May 2017 17:56:49 +0200 Subject: [PATCH 73/86] Fix build with clang MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes building anbox with clang 4.0 -- removes unused declarations, makes sure a template is visible at first instantiation, makes sure exception declarations match between headers and implementations Signed-off-by: Bernhard Rosenkränzer --- external/xdg/xdg.cpp | 1 - src/anbox/cmds/session_manager.cpp | 7 ++++++- src/anbox/graphics/emugl/ColorBuffer.cpp | 16 ---------------- src/anbox/graphics/emugl/TextureDraw.cpp | 9 +++------ src/anbox/graphics/emugl/TextureDraw.h | 3 --- src/anbox/network/published_socket_connector.cpp | 2 +- src/anbox/network/tcp_socket_connector.cpp | 2 +- src/anbox/qemu/pipe_connection_creator.cpp | 2 +- src/anbox/rpc/connection_creator.cpp | 2 +- src/anbox/runtime.cpp | 2 +- 10 files changed, 14 insertions(+), 32 deletions(-) diff --git a/external/xdg/xdg.cpp b/external/xdg/xdg.cpp index de9b043..d54fdfe 100644 --- a/external/xdg/xdg.cpp +++ b/external/xdg/xdg.cpp @@ -57,7 +57,6 @@ constexpr const char* xdg_data_dirs{"XDG_DATA_DIRS"}; constexpr const char* xdg_config_home{"XDG_CONFIG_HOME"}; constexpr const char* xdg_config_dirs{"XDG_CONFIG_DIRS"}; constexpr const char* xdg_cache_home{"XDG_CACHE_HOME"}; -constexpr const char* xdg_runtime_dir{"XDG_RUNTIME_DIR"}; } namespace impl diff --git a/src/anbox/cmds/session_manager.cpp b/src/anbox/cmds/session_manager.cpp index 5a46566..3834502 100644 --- a/src/anbox/cmds/session_manager.cpp +++ b/src/anbox/cmds/session_manager.cpp @@ -27,12 +27,17 @@ #include "anbox/bridge/android_api_stub.h" #include "anbox/bridge/platform_api_skeleton.h" #include "anbox/bridge/platform_message_processor.h" +#include "anbox/graphics/gl_renderer_server.h" + +namespace { +std::istream& operator>>(std::istream& in, anbox::graphics::GLRendererServer::Config::Driver& driver); +} + #include "anbox/cmds/session_manager.h" #include "anbox/common/dispatcher.h" #include "anbox/config.h" #include "anbox/container/client.h" #include "anbox/dbus/skeleton/service.h" -#include "anbox/graphics/gl_renderer_server.h" #include "anbox/input/manager.h" #include "anbox/logger.h" #include "anbox/network/published_socket_connector.h" diff --git a/src/anbox/graphics/emugl/ColorBuffer.cpp b/src/anbox/graphics/emugl/ColorBuffer.cpp index c1efb6e..4c478f3 100644 --- a/src/anbox/graphics/emugl/ColorBuffer.cpp +++ b/src/anbox/graphics/emugl/ColorBuffer.cpp @@ -35,22 +35,6 @@ inline void* SafePointerFromUInt(unsigned int handle) { return reinterpret_cast(static_cast(handle)); } -inline unsigned int SafeUIntFromPointer(const void* ptr) { -#if 1 - // Ignore the assert below to avoid crashing when running older - // system images, which might have buggy encoder libraries. Print - // an error message though. - if (reinterpret_cast(ptr) != static_cast(reinterpret_cast(ptr))) { - WARNING("Bad generic pointer %p", ptr); - } -#else - // Assertion error if the pointer contains a value that does not fit - // in an unsigned integer! - assert((uintptr_t)(ptr) == (unsigned int)(uintptr_t)(ptr)); -#endif - return static_cast(reinterpret_cast(ptr)); -} - // Lazily create and bind a framebuffer object to the current host context. // |fbo| is the address of the framebuffer object name. // |tex| is the name of a texture that is attached to the framebuffer object diff --git a/src/anbox/graphics/emugl/TextureDraw.cpp b/src/anbox/graphics/emugl/TextureDraw.cpp index bb421bd..5015420 100644 --- a/src/anbox/graphics/emugl/TextureDraw.cpp +++ b/src/anbox/graphics/emugl/TextureDraw.cpp @@ -97,16 +97,13 @@ const GLint kIndicesLen = sizeof(kIndices) / sizeof(kIndices[0]); } // namespace -TextureDraw::TextureDraw(EGLDisplay display) - : mDisplay(display), - mVertexShader(0), +TextureDraw::TextureDraw(EGLDisplay) + : mVertexShader(0), mFragmentShader(0), mProgram(0), mPositionSlot(-1), mInCoordSlot(-1), - mTextureSlot(-1), - mRotationSlot(-1), - mTranslationSlot(-1) { + mTextureSlot(-1) { // Create shaders and program. mVertexShader = createShader(GL_VERTEX_SHADER, kVertexShaderSource); mFragmentShader = createShader(GL_FRAGMENT_SHADER, kFragmentShaderSource); diff --git a/src/anbox/graphics/emugl/TextureDraw.h b/src/anbox/graphics/emugl/TextureDraw.h index 5f6ef96..10f796c 100644 --- a/src/anbox/graphics/emugl/TextureDraw.h +++ b/src/anbox/graphics/emugl/TextureDraw.h @@ -42,15 +42,12 @@ class TextureDraw { bool draw(GLuint texture); private: - EGLDisplay mDisplay; GLuint mVertexShader; GLuint mFragmentShader; GLuint mProgram; GLint mPositionSlot; GLint mInCoordSlot; GLint mTextureSlot; - GLint mRotationSlot; - GLint mTranslationSlot; GLuint mVertexBuffer; GLuint mIndexBuffer; }; diff --git a/src/anbox/network/published_socket_connector.cpp b/src/anbox/network/published_socket_connector.cpp index 5e1a9b6..50e8fc5 100644 --- a/src/anbox/network/published_socket_connector.cpp +++ b/src/anbox/network/published_socket_connector.cpp @@ -33,7 +33,7 @@ PublishedSocketConnector::PublishedSocketConnector( start_accept(); } -PublishedSocketConnector::~PublishedSocketConnector() {} +PublishedSocketConnector::~PublishedSocketConnector() noexcept {} void PublishedSocketConnector::start_accept() { auto socket = std::make_shared(runtime_->service()); diff --git a/src/anbox/network/tcp_socket_connector.cpp b/src/anbox/network/tcp_socket_connector.cpp index 00d33c2..63e8325 100644 --- a/src/anbox/network/tcp_socket_connector.cpp +++ b/src/anbox/network/tcp_socket_connector.cpp @@ -34,7 +34,7 @@ TcpSocketConnector::TcpSocketConnector( start_accept(); } -TcpSocketConnector::~TcpSocketConnector() { acceptor_.cancel(); } +TcpSocketConnector::~TcpSocketConnector() noexcept { acceptor_.cancel(); } void TcpSocketConnector::start_accept() { auto socket = diff --git a/src/anbox/qemu/pipe_connection_creator.cpp b/src/anbox/qemu/pipe_connection_creator.cpp index 78bb258..722b227 100644 --- a/src/anbox/qemu/pipe_connection_creator.cpp +++ b/src/anbox/qemu/pipe_connection_creator.cpp @@ -73,7 +73,7 @@ PipeConnectionCreator::PipeConnectionCreator(const std::shared_ptr &re std::make_shared>()) { } -PipeConnectionCreator::~PipeConnectionCreator() { +PipeConnectionCreator::~PipeConnectionCreator() noexcept { connections_->clear(); } diff --git a/src/anbox/rpc/connection_creator.cpp b/src/anbox/rpc/connection_creator.cpp index 0ac1fd9..2f3f864 100644 --- a/src/anbox/rpc/connection_creator.cpp +++ b/src/anbox/rpc/connection_creator.cpp @@ -34,7 +34,7 @@ ConnectionCreator::ConnectionCreator(const std::shared_ptr& rt, std::make_shared>()), message_processor_factory_(factory) {} -ConnectionCreator::~ConnectionCreator() {} +ConnectionCreator::~ConnectionCreator() noexcept {} void ConnectionCreator::create_connection_for( std::shared_ptr const& diff --git a/src/anbox/runtime.cpp b/src/anbox/runtime.cpp index 1be2d1c..cbfefa7 100644 --- a/src/anbox/runtime.cpp +++ b/src/anbox/runtime.cpp @@ -57,7 +57,7 @@ Runtime::Runtime(std::uint32_t pool_size) strand_{service_}, keep_alive_{service_} {} -Runtime::~Runtime() { +Runtime::~Runtime() noexcept(true) { try { stop(); } catch (...) { From 190d8690d3c9d0f1d09a3c1cfe06092f83c619ca Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 23 May 2017 08:29:41 +0200 Subject: [PATCH 74/86] If launched with debug severity allow our subprocess to write to stdout/stderr --- src/anbox/cmds/launch.cpp | 6 +++++- src/anbox/logger.cpp | 4 ++++ src/anbox/logger.h | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index 69830aa..1d8aa82 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -130,7 +130,11 @@ anbox::cmds::Launch::Launch() } try { - const auto flags = core::posix::StandardStream::stdout | core::posix::StandardStream::stderr; + auto flags = core::posix::StandardStream::stdout | core::posix::StandardStream::stderr; + // If we have logging enable in debug mode then we allow the child process + // to print to stdout/stderr too. + if (Log().GetSeverity() == Logger::Severity::kDebug) + flags = core::posix::StandardStream::empty; auto child = core::posix::fork([&]() { auto grandchild = core::posix::exec(exe_path, args, env, flags); grandchild.dont_kill_on_cleanup(); diff --git a/src/anbox/logger.cpp b/src/anbox/logger.cpp index f59803d..2e184d8 100644 --- a/src/anbox/logger.cpp +++ b/src/anbox/logger.cpp @@ -64,6 +64,10 @@ struct BoostLogLogger : public anbox::Logger { severity_ = severity; } + Severity GetSeverity() override { + return severity_; + } + void Log(Severity severity, const std::string& message, const boost::optional& loc) override { if (!initialized_) Init(); diff --git a/src/anbox/logger.h b/src/anbox/logger.h index 6e797b6..e9b06e4 100644 --- a/src/anbox/logger.h +++ b/src/anbox/logger.h @@ -51,6 +51,7 @@ class Logger : public DoNotCopyOrMove { bool SetSeverityFromString(const std::string &severity); virtual void SetSeverity(const Severity& severity) = 0; + virtual Severity GetSeverity() = 0; virtual void Log(Severity severity, const std::string& message, const boost::optional& location) = 0; From d03a32b014e488e97214f0bd528d9f8995fafb5f Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 23 May 2017 08:30:00 +0200 Subject: [PATCH 75/86] Create container data directory on startup if it doesn't exist --- src/anbox/cmds/container_manager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/anbox/cmds/container_manager.cpp b/src/anbox/cmds/container_manager.cpp index b64f002..a71f07b 100644 --- a/src/anbox/cmds/container_manager.cpp +++ b/src/anbox/cmds/container_manager.cpp @@ -79,6 +79,9 @@ anbox::cmds::ContainerManager::ContainerManager() if (!data_path_.empty()) SystemConfiguration::instance().set_data_path(data_path_); + if (!fs::exists(data_path_)) + fs::create_directories(data_path_); + if (!setup_mounts()) return EXIT_FAILURE; From c08b795494ff545e1406866a05566ab9c84a4379 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Tue, 23 May 2017 08:31:54 +0200 Subject: [PATCH 76/86] Assign current owner to the IP configuration dir If we don't assign the unprivileged user as owner the container will fail to start as the Android services wont be able to write anything into the created directory hierarchy. --- src/anbox/container/lxc_container.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/anbox/container/lxc_container.cpp b/src/anbox/container/lxc_container.cpp index ee388a9..485a6c2 100644 --- a/src/anbox/container/lxc_container.cpp +++ b/src/anbox/container/lxc_container.cpp @@ -36,6 +36,7 @@ namespace fs = boost::filesystem; namespace { +constexpr unsigned int unprivileged_user_id{100000}; constexpr const char *default_container_ip_address{"192.168.250.2"}; constexpr const std::uint32_t default_container_ip_prefix_length{24}; constexpr const char *default_host_ip_address{"192.168.250.1"}; @@ -58,8 +59,7 @@ LxcContainer::~LxcContainer() { } void LxcContainer::setup_id_maps() { - // FIXME make these id sets configurable - const auto base_id = 100000; + const auto base_id = unprivileged_user_id; const auto max_id = 65536; set_config_item("lxc.id_map", @@ -112,10 +112,22 @@ void LxcContainer::setup_network() { common::BinaryWriter writer(buffer.begin(), buffer.end()); const auto size = ip_conf.write(writer); - const auto ip_conf_dir = SystemConfiguration::instance().data_dir() / "data" / "misc" / "ethernet"; - if (!fs::exists(ip_conf_dir)) + const auto data_ethernet_path = fs::path("data") / "misc" / "ethernet"; + const auto ip_conf_dir = SystemConfiguration::instance().data_dir() / data_ethernet_path; + if (!fs::exists(ip_conf_dir)) { fs::create_directories(ip_conf_dir); + // We have to walk through the created directory hierachy now and + // ensure the permissions are set correctly. Otherwise the Android + // system will fail to boot as it isn't allowed to write anything + // into these directories. + for (auto iter = data_ethernet_path.begin(); iter != data_ethernet_path.end(); iter++) { + const auto path = SystemConfiguration::instance().data_dir() / *iter; + if (::chown(path.c_str(), unprivileged_user_id, unprivileged_user_id) < 0) + WARNING("Failed to set owner for path '%s'", path); + } + } + const auto ip_conf_path = ip_conf_dir / "ipconfig.txt"; if (fs::exists(ip_conf_path)) fs::remove(ip_conf_path); From bc4ce254d12cbdaf1e5ff8197b64ea7ded14c3ee Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sat, 27 May 2017 18:05:23 +0200 Subject: [PATCH 77/86] Migrate permissions of /data correctly for existing installations --- src/anbox/container/lxc_container.cpp | 34 ++++++++++++++++++++------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/anbox/container/lxc_container.cpp b/src/anbox/container/lxc_container.cpp index 485a6c2..a2e0705 100644 --- a/src/anbox/container/lxc_container.cpp +++ b/src/anbox/container/lxc_container.cpp @@ -32,6 +32,9 @@ #include #include #include +#include + +#include namespace fs = boost::filesystem; @@ -114,18 +117,31 @@ void LxcContainer::setup_network() { const auto data_ethernet_path = fs::path("data") / "misc" / "ethernet"; const auto ip_conf_dir = SystemConfiguration::instance().data_dir() / data_ethernet_path; - if (!fs::exists(ip_conf_dir)) { + if (!fs::exists(ip_conf_dir)) fs::create_directories(ip_conf_dir); - // We have to walk through the created directory hierachy now and - // ensure the permissions are set correctly. Otherwise the Android - // system will fail to boot as it isn't allowed to write anything - // into these directories. - for (auto iter = data_ethernet_path.begin(); iter != data_ethernet_path.end(); iter++) { - const auto path = SystemConfiguration::instance().data_dir() / *iter; - if (::chown(path.c_str(), unprivileged_user_id, unprivileged_user_id) < 0) - WARNING("Failed to set owner for path '%s'", path); + // We have to walk through the created directory hierachy now and + // ensure the permissions are set correctly. Otherwise the Android + // system will fail to boot as it isn't allowed to write anything + // into these directories. As previous versions of Anbox which were + // published to our users did this incorrectly we need to check on + // every startup if those directories are still owned by root and + // if they are we move them over to the unprivileged user. + auto path = SystemConfiguration::instance().data_dir(); + for (auto iter = data_ethernet_path.begin(); iter != data_ethernet_path.end(); iter++) { + path /= *iter; + + struct stat st; + if (stat(path.c_str(), &st) < 0) { + WARNING("Cannot retrieve permissions of path %s", path); + continue; } + + if (st.st_uid != 0 && st.st_gid != 0) + continue; + + if (::chown(path.c_str(), unprivileged_user_id, unprivileged_user_id) < 0) + WARNING("Failed to set owner for path '%s'", path); } const auto ip_conf_path = ip_conf_dir / "ipconfig.txt"; From 5e1e08b5ebe6546e1f54656bc58e44ec05fbe818 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sat, 27 May 2017 18:11:03 +0200 Subject: [PATCH 78/86] Correct incorrect vertical/horizontal to width/height assignment --- src/anbox/graphics/emugl/RenderControl.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/anbox/graphics/emugl/RenderControl.cpp b/src/anbox/graphics/emugl/RenderControl.cpp index b34e28f..26e9559 100644 --- a/src/anbox/graphics/emugl/RenderControl.cpp +++ b/src/anbox/graphics/emugl/RenderControl.cpp @@ -169,10 +169,10 @@ static EGLint rcGetFBParam(EGLint param) { switch (param) { case FB_WIDTH: - ret = static_cast(anbox::graphics::emugl::DisplayInfo::get()->horizontal_resolution()); + ret = static_cast(anbox::graphics::emugl::DisplayInfo::get()->vertical_resolution()); break; case FB_HEIGHT: - ret = static_cast(anbox::graphics::emugl::DisplayInfo::get()->vertical_resolution()); + ret = static_cast(anbox::graphics::emugl::DisplayInfo::get()->horizontal_resolution()); break; case FB_XDPI: ret = 72; // XXX: should be implemented @@ -360,12 +360,12 @@ int rcGetNumDisplays() { int rcGetDisplayWidth(uint32_t display_id) { (void)display_id; - return static_cast(anbox::graphics::emugl::DisplayInfo::get()->horizontal_resolution()); + return static_cast(anbox::graphics::emugl::DisplayInfo::get()->vertical_resolution()); } int rcGetDisplayHeight(uint32_t display_id) { (void)display_id; - return static_cast(anbox::graphics::emugl::DisplayInfo::get()->vertical_resolution()); + return static_cast(anbox::graphics::emugl::DisplayInfo::get()->horizontal_resolution()); } int rcGetDisplayDpiX(uint32_t display_id) { From 977999f721603d1be731132b0ae475db3b82181f Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sat, 27 May 2017 18:18:03 +0200 Subject: [PATCH 79/86] tests: add case for render control API to guarantee correct width/height --- tests/anbox/graphics/CMakeLists.txt | 1 + tests/anbox/graphics/render_control_tests.cpp | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tests/anbox/graphics/render_control_tests.cpp diff --git a/tests/anbox/graphics/CMakeLists.txt b/tests/anbox/graphics/CMakeLists.txt index 85b07c2..ce02330 100644 --- a/tests/anbox/graphics/CMakeLists.txt +++ b/tests/anbox/graphics/CMakeLists.txt @@ -1,3 +1,4 @@ ANBOX_ADD_TEST(buffer_queue_tests buffer_queue_tests.cpp) ANBOX_ADD_TEST(buffered_io_stream_tests buffered_io_stream_tests.cpp) ANBOX_ADD_TEST(layer_composer_tests layer_composer_tests.cpp) +ANBOX_ADD_TEST(render_control_tests render_control_tests.cpp) diff --git a/tests/anbox/graphics/render_control_tests.cpp b/tests/anbox/graphics/render_control_tests.cpp new file mode 100644 index 0000000..5a97f04 --- /dev/null +++ b/tests/anbox/graphics/render_control_tests.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2017 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 . + * + */ + +#include + +#include "anbox/graphics/emugl/DisplayManager.h" + +extern int rcGetDisplayWidth(uint32_t display_id); +extern int rcGetDisplayHeight(uint32_t display_id); + +TEST(RenderControl, WidthHeightAreCorrectlyAssigned) { + anbox::graphics::emugl::DisplayInfo::get()->set_resolution(640, 480); + ASSERT_EQ(rcGetDisplayWidth(0), 640); + ASSERT_EQ(rcGetDisplayHeight(0), 480); +} From 2a9a40155c52002d5c8240b1d22f7e45ba5c766c Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sat, 27 May 2017 18:37:29 +0200 Subject: [PATCH 80/86] Add snap and travis status in README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 3486b6b..d613855 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +[![Snap Status](https://build.snapcraft.io/badge/anbox/anbox.svg)](https://build.snapcraft.io/user/anbox/anbox) +[![Build Status](https://travis-ci.org/anbox/anbox.svg?branch=master)](https://travis-ci.org/anbox/anbox) + # Anbox Anbox is a container-based approach to boot a full Android system on a From c8621e4b9725fdac8ce25205f081225b15cbbc58 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sat, 27 May 2017 20:35:52 +0200 Subject: [PATCH 81/86] Bump snap version to 3 --- snapcraft.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snapcraft.yaml b/snapcraft.yaml index eebe70d..76abb6e 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -3,7 +3,7 @@ name: anbox # passed down into cmake and assigned to an integer variable which # can be used for version number comparision inside the code base # to accomondate for any breaking changes. -version: 2 +version: 3 summary: Android in a Box description: | Runtime for Android applications which runs a full Android system From 552d30cfb44437a67ab763d20173b2cb7fde8947 Mon Sep 17 00:00:00 2001 From: Eddie Ringle Date: Mon, 29 May 2017 18:58:39 -0500 Subject: [PATCH 82/86] Fix build with GCC 7.1 From the Porting to GCC 7[1] page: > Several C++ Standard Library headers have been changed to no longer include > the `` header. As such, C++ programs that used components defined > in `` without explicitly including that header will no longer > compile. > Previously components such as std::bind and std::function were > implicitly defined after including unrelated headers such as ``, > ``, ``, and ``. > Correct code should `#include ` to define them. [1]: https://gcc.gnu.org/gcc-7/porting_to.html Signed-off-by: Eddie Ringle --- src/anbox/bridge/platform_api_skeleton.h | 1 + src/anbox/qemu/at_parser.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/anbox/bridge/platform_api_skeleton.h b/src/anbox/bridge/platform_api_skeleton.h index 7a9891b..843416e 100644 --- a/src/anbox/bridge/platform_api_skeleton.h +++ b/src/anbox/bridge/platform_api_skeleton.h @@ -18,6 +18,7 @@ #ifndef ANBOX_BRIDGE_PLATFORM_SERVER_H_ #define ANBOX_BRIDGE_PLATFORM_SERVER_H_ +#include #include namespace google { diff --git a/src/anbox/qemu/at_parser.h b/src/anbox/qemu/at_parser.h index 3935376..def3881 100644 --- a/src/anbox/qemu/at_parser.h +++ b/src/anbox/qemu/at_parser.h @@ -18,6 +18,7 @@ #ifndef ANBOX_QEMU_AT_PARSER_H_ #define ANBOX_QEMU_AT_PARSER_H_ +#include #include #include #include From dc21069ae18d6eec321a74be0df33095ee1e0e4d Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Sat, 3 Jun 2017 14:02:04 +0200 Subject: [PATCH 83/86] Rework versioning to include git rev in snap version --- CMakeLists.txt | 11 +++++------ snapcraft.yaml | 10 ++++++---- src/anbox/build/version.cpp | 4 ++-- src/anbox/build/version.h.in | 4 ++-- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d1dcf3..c6432a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,12 +97,11 @@ set(ANBOX_TRANSLATOR_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/anbox/translators) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTRANSLATOR_INSTALL_DIR=\\\"${CMAKE_INSTALL_PREFIX}/${ANBOX_TRANSLATOR_INSTALL_DIR}\\\"") if (NOT ANBOX_VERSION) - set(ANBOX_VERSION 2) - if ("${cmake_build_type_lower}" STREQUAL "release") - set(ANBOX_VERSION_SUFFIX "") - else() - set(ANBOX_VERSION_SUFFIX dev) - endif() + exec_program("git" ${CMAKE_SOURCE_DIR} ARGS "rev-parse --short HEAD" OUTPUT_VARIABLE GIT_COMMIT_HASH) + set(ANBOX_VERSION "local-${GIT_COMMIT_HASH}") +endif() +if (ANBOX_VERSION_SUFFIX) + set(ANBOX_VERSION "${ANBOX_VERSION}-${ANBOX_VERSION_SUFFIX}") endif() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/anbox/build/version.h.in ${CMAKE_CURRENT_SOURCE_DIR}/src/anbox/build/version.h) diff --git a/snapcraft.yaml b/snapcraft.yaml index 76abb6e..2e23850 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,9 +1,11 @@ name: anbox -# NOTE: Always only use increasing numeric values here. This is -# passed down into cmake and assigned to an integer variable which -# can be used for version number comparision inside the code base -# to accomondate for any breaking changes. version: 3 +version-script: | + if [ "$SNAPCRAFT_GRADE" = "stable" ]; then + echo $SNAPCRAFT_PROJECT_VERSION + else + echo $SNAPCRAFT_PROJECT_VERSION-$(git rev-parse --short HEAD) + fi summary: Android in a Box description: | Runtime for Android applications which runs a full Android system diff --git a/src/anbox/build/version.cpp b/src/anbox/build/version.cpp index 07576e9..b63b804 100644 --- a/src/anbox/build/version.cpp +++ b/src/anbox/build/version.cpp @@ -25,9 +25,9 @@ namespace build { static std::string init_version_string() { std::string v; if (!version_suffix || std::strlen(version_suffix) == 0) - v = utils::string_format("%d", version_major); + v = utils::string_format("%s", version); else - v = utils::string_format("%d-%s", version_major, version_suffix); + v = utils::string_format("%s-%s", version, version_suffix); return v; } diff --git a/src/anbox/build/version.h.in b/src/anbox/build/version.h.in index e6dcbbd..fb7983a 100644 --- a/src/anbox/build/version.h.in +++ b/src/anbox/build/version.h.in @@ -25,8 +25,8 @@ namespace anbox { namespace build { -/// @brief version_major marks the major version -static constexpr const std::uint32_t version_major{@ANBOX_VERSION@}; +/// @brief version marks the version +static constexpr const char *version{"@ANBOX_VERSION@"}; /// @brief version_suffix is an additional suffix which can be amended to /// the major version number to indicate a dev build for example. static constexpr const char *version_suffix{"@ANBOX_VERSION_SUFFIX@"}; From 19110b824fc5110ac74494e294fb740a7a0ce38d Mon Sep 17 00:00:00 2001 From: Tomasz Maciej Nowak Date: Mon, 5 Jun 2017 15:08:54 +0200 Subject: [PATCH 84/86] dkms: fix modules build with more kernel versions The Makefile for ashmem and binder have this line: KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build so dkms will always build those modules against running kernel, even for other kernel version headers. With this commit dkms will always provide the necessary kernel version. Signed-off-by: Tomasz Maciej Nowak --- kernel/ashmem/dkms.conf | 2 +- kernel/binder/dkms.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/ashmem/dkms.conf b/kernel/ashmem/dkms.conf index bde1557..715fa57 100644 --- a/kernel/ashmem/dkms.conf +++ b/kernel/ashmem/dkms.conf @@ -1,7 +1,7 @@ PACKAGE_NAME="anbox-ashmem" PACKAGE_VERSION="1" CLEAN="make clean" -MAKE[0]="make all KVERSION=$kernelver" +MAKE[0]="make all KERNEL_SRC=/lib/modules/$kernelver/build" BUILT_MODULE_NAME[0]="ashmem_linux" DEST_MODULE_LOCATION[0]="/updates" AUTOINSTALL="yes" diff --git a/kernel/binder/dkms.conf b/kernel/binder/dkms.conf index 8484321..1b5fd7a 100644 --- a/kernel/binder/dkms.conf +++ b/kernel/binder/dkms.conf @@ -1,7 +1,7 @@ PACKAGE_NAME="anbox-binder" PACKAGE_VERSION="1" CLEAN="make clean" -MAKE[0]="make all KVERSION=$kernelver" +MAKE[0]="make all KERNEL_SRC=/lib/modules/$kernelver/build" BUILT_MODULE_NAME[0]="binder_linux" DEST_MODULE_LOCATION[0]="/updates" AUTOINSTALL="yes" From edd8960009e15787754d2fa271fb9e0bbfb6ca45 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 7 Jun 2017 07:25:34 +0200 Subject: [PATCH 85/86] Ensure that we have an valid intent before we launch it --- src/anbox/android/intent.cpp | 6 ++++++ src/anbox/android/intent.h | 2 ++ src/anbox/cmds/launch.cpp | 5 +++++ tests/anbox/CMakeLists.txt | 1 + tests/anbox/android/CMakeLists.txt | 1 + tests/anbox/android/intent_tests.cpp | 31 ++++++++++++++++++++++++++++ 6 files changed, 46 insertions(+) create mode 100644 tests/anbox/android/CMakeLists.txt create mode 100644 tests/anbox/android/intent_tests.cpp diff --git a/src/anbox/android/intent.cpp b/src/anbox/android/intent.cpp index 4f5e659..1b7b0e3 100644 --- a/src/anbox/android/intent.cpp +++ b/src/anbox/android/intent.cpp @@ -21,6 +21,12 @@ namespace anbox { namespace android { +bool Intent::valid() const { + // At the moment we only support component+package for intents + // (see android/service/android_api_skeleton.cpp for more details) + return !(component.empty() && package.empty()); +} + std::ostream &operator<<(std::ostream &out, const Intent &intent) { out << "["; if (!intent.action.empty()) diff --git a/src/anbox/android/intent.h b/src/anbox/android/intent.h index a628f8f..57f2add 100644 --- a/src/anbox/android/intent.h +++ b/src/anbox/android/intent.h @@ -31,6 +31,8 @@ struct Intent { std::string package; std::string component; std::vector categories; + + bool valid() const; }; std::ostream &operator<<(std::ostream &out, const Intent &intent); diff --git a/src/anbox/cmds/launch.cpp b/src/anbox/cmds/launch.cpp index 1d8aa82..3e0f885 100644 --- a/src/anbox/cmds/launch.cpp +++ b/src/anbox/cmds/launch.cpp @@ -79,6 +79,11 @@ anbox::cmds::Launch::Launch() stack_)); action([this](const cli::Command::Context&) { + if (!intent_.valid()) { + ERROR("The intent you provided is invalid. Please provide a correct launch intent."); + return EXIT_FAILURE; + } + auto trap = core::posix::trap_signals_for_process({core::posix::Signal::sig_term, core::posix::Signal::sig_int}); trap->signal_raised().connect([trap](const core::posix::Signal& signal) { INFO("Signal %i received. Good night.", static_cast(signal)); diff --git a/tests/anbox/CMakeLists.txt b/tests/anbox/CMakeLists.txt index 41692fa..ca13908 100644 --- a/tests/anbox/CMakeLists.txt +++ b/tests/anbox/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(android) add_subdirectory(support) add_subdirectory(common) add_subdirectory(graphics) diff --git a/tests/anbox/android/CMakeLists.txt b/tests/anbox/android/CMakeLists.txt new file mode 100644 index 0000000..9753aa8 --- /dev/null +++ b/tests/anbox/android/CMakeLists.txt @@ -0,0 +1 @@ +ANBOX_ADD_TEST(intent_tests intent_tests.cpp) diff --git a/tests/anbox/android/intent_tests.cpp b/tests/anbox/android/intent_tests.cpp new file mode 100644 index 0000000..395a69d --- /dev/null +++ b/tests/anbox/android/intent_tests.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2017 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 . + * + */ + +#include "anbox/android/intent.h" + +#include + +TEST(Intent, IsValid) { + anbox::android::Intent intent; + ASSERT_FALSE(intent.valid()); + intent.component = "foo"; + ASSERT_TRUE(intent.valid()); + intent.package = "bla"; + ASSERT_TRUE(intent.valid()); + intent.component = ""; + ASSERT_TRUE(intent.valid()); +} From 4ff35c2026c16b51437d76b45b1063e6fa15dbd2 Mon Sep 17 00:00:00 2001 From: Simon Fels Date: Wed, 7 Jun 2017 07:41:11 +0200 Subject: [PATCH 86/86] Pass snap version to correct cmake variable --- snapcraft.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snapcraft.yaml b/snapcraft.yaml index 2e23850..3ed6b2b 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -90,7 +90,7 @@ parts: # FIXME: Anbox currently has some paths with hard coded prefixes. Once # that is fixed we can avoid using a prefix here. - -DCMAKE_INSTALL_PREFIX:PATH=/usr - - -DVERSION=$SNAPCRAFT_PROJECT_VERSION + - -DANBOX_VERSION=$SNAPCRAFT_PROJECT_VERSION build-packages: - build-essential - cmake