summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.target15
-rw-r--r--cpus.c5
-rw-r--r--hw/vigs/vigs_gl_backend.c3
-rw-r--r--hw/yagl/yagl_process.c20
-rw-r--r--hw/yagl/yagl_process.h2
-rw-r--r--hw/yagl/yagl_thread.c11
-rw-r--r--include/sysemu/hax.h3
-rw-r--r--package/changelog30
-rw-r--r--package/pkginfo.manifest2
-rw-r--r--target-i386/hax-all.c181
-rw-r--r--target-i386/hax-darwin.c38
-rw-r--r--target-i386/hax-slot.c328
-rw-r--r--target-i386/hax-slot.h58
-rw-r--r--target-i386/hax-windows.c47
-rw-r--r--target-i386/monitor.c2
-rw-r--r--tizen/src/ecs/ecs.c109
-rw-r--r--tizen/src/ecs/ecs.h5
-rw-r--r--tizen/src/ecs/ecs_msg.c2
-rw-r--r--tizen/src/ecs/ecs_msg_device.c6
-rw-r--r--tizen/src/ecs/ecs_msg_injector.c4
-rw-r--r--tizen/src/emul_state.c33
-rw-r--r--tizen/src/emul_state.h2
-rw-r--r--tizen/src/emulator.c34
-rw-r--r--tizen/src/emulator_options.c7
-rw-r--r--tizen/src/hw/virtio/maru_virtio_sensor.c5
-rw-r--r--tizen/src/hw/virtio/maru_virtio_sensor.h2
-rw-r--r--tizen/src/hw/virtio/maru_virtio_tablet.c8
-rw-r--r--tizen/src/ui/displaybase.cpp32
-rw-r--r--tizen/src/ui/displayswwidget.cpp4
-rw-r--r--tizen/src/ui/input/keyboardshortcut.cpp5
-rw-r--r--tizen/src/ui/mainwindow.cpp83
-rw-r--r--tizen/src/ui/mainwindow.h12
-rw-r--r--tizen/src/ui/menu/aboutdialog.cpp10
-rw-r--r--tizen/src/ui/menu/contextmenu.cpp81
-rw-r--r--tizen/src/ui/menu/contextmenu.h4
-rw-r--r--tizen/src/ui/menu/detailedinfodialog.cpp15
-rw-r--r--tizen/src/ui/menu/screenshotdialog.cpp16
-rw-r--r--tizen/src/ui/menu/sdbhelper.cpp1
-rw-r--r--tizen/src/ui/menu/sdbhelperthread.cpp22
-rw-r--r--tizen/src/ui/menu/sdbhelperthread.h3
-rw-r--r--tizen/src/ui/movingwidget.cpp1
-rw-r--r--tizen/src/ui/qt5.c9
-rw-r--r--tizen/src/ui/qt5.h3
-rw-r--r--tizen/src/ui/qt5_supplement.cpp26
-rw-r--r--tizen/src/ui/qt5_supplement.h2
-rw-r--r--tizen/src/ui/resource/ui_strings.h1
-rw-r--r--tizen/src/ui/rotaryview.cpp2
-rw-r--r--tizen/src/ui/skinpainter.cpp7
-rw-r--r--tizen/src/util/Makefile.objs3
-rw-r--r--tizen/src/util/error_handler.c345
-rw-r--r--tizen/src/util/osutil-darwin.c4
-rw-r--r--tizen/src/util/osutil-linux.c4
-rw-r--r--tizen/src/util/osutil-win32.c179
-rw-r--r--tizen/src/util/osutil.c33
-rw-r--r--tizen/src/util/osutil.h6
-rw-r--r--version.rc4
-rw-r--r--vl.c14
57 files changed, 1344 insertions, 549 deletions
diff --git a/Makefile.target b/Makefile.target
index 8f35dae1e2..3456672830 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -149,13 +149,16 @@ obj-$(CONFIG_XEN_I386) += xen-hvm.o xen-mapcache.o
obj-$(call lnot,$(CONFIG_XEN)) += xen-common-stub.o
obj-$(call lnot,$(CONFIG_XEN_I386)) += xen-hvm-stub.o
-# HAX support
-ifdef CONFIG_WIN32
-obj-$(CONFIG_HAX) += target-i386/hax-all.o target-i386/hax-windows.o
-endif
-ifdef CONFIG_DARWIN
-obj-$(CONFIG_HAX) += target-i386/hax-all.o target-i386/hax-darwin.o
+# HAX support, only when targetting i386 or x86_64
+ifeq (y,$(CONFIG_HAX))
+ifneq (,$(filter i386 x86_64,$(TARGET_NAME)))
+obj-y += target-i386/hax-all.o target-i386/hax-slot.o
+obj-$(CONFIG_WIN32) += target-i386/hax-windows.o
+obj-$(CONFIG_DARWIN) += target-i386/hax-darwin.o
+else
+obj-y += hax-stub.o
endif
+endif # CONFIG_HAX
obj-$(call lnot,$(CONFIG_HAX)) += hax-stub.o
# Hardware support
diff --git a/cpus.c b/cpus.c
index 7c51e7e9d3..4d51e317a5 100644
--- a/cpus.c
+++ b/cpus.c
@@ -712,6 +712,11 @@ void cpu_synchronize_all_states(void)
CPU_FOREACH(cpu) {
cpu_synchronize_state(cpu);
+#ifdef CONFIG_HAX
+ if (hax_enabled() && hax_ug_platform()) {
+ hax_cpu_synchronize_state(cpu);
+ }
+#endif
}
}
diff --git a/hw/vigs/vigs_gl_backend.c b/hw/vigs/vigs_gl_backend.c
index 7fcd2c092f..94b95ff5c0 100644
--- a/hw/vigs/vigs_gl_backend.c
+++ b/hw/vigs/vigs_gl_backend.c
@@ -2938,6 +2938,9 @@ void vigs_gl_backend_cleanup(struct vigs_gl_backend *gl_backend)
if (gl_backend->dpy_tex) {
gl_backend->DeleteTextures(1, &gl_backend->dpy_tex);
}
+ if (gl_backend->dpy_fb) {
+ gl_backend->DeleteFramebuffers(1, &gl_backend->dpy_fb);
+ }
gl_backend->DeleteBuffers(1, &gl_backend->dpy_vbo);
gl_backend->DetachShader(gl_backend->dpy_scale_prog_id,
gl_backend->dpy_scale_prog_vs_id);
diff --git a/hw/yagl/yagl_process.c b/hw/yagl/yagl_process.c
index eb740315c2..1e6844f831 100644
--- a/hw/yagl/yagl_process.c
+++ b/hw/yagl/yagl_process.c
@@ -34,6 +34,7 @@
#include "yagl_stats.h"
#include "yagl_object_map.h"
#include "sysemu/kvm.h"
+#include "sysemu/hax.h"
struct yagl_process_state
*yagl_process_state_create(struct yagl_server_state *ss,
@@ -47,13 +48,20 @@ struct yagl_process_state
ps->object_map = yagl_object_map_create();
QLIST_INIT(&ps->threads);
-#ifdef CONFIG_KVM
- if (kvm_enabled()) {
- cpu_synchronize_state(current_cpu);
+#if defined (CONFIG_KVM) || defined (CONFIG_HAX)
+ if (kvm_enabled() || hax_enabled()) {
+ if (kvm_enabled()) {
+ cpu_synchronize_state(current_cpu);
+ } else {
+#ifdef CONFIG_HAX
+ hax_cpu_synchronize_state(current_cpu);
+#endif
+ }
+ CPUX86State *env = current_cpu->env_ptr;
memcpy(&ps->cr[0],
- &((CPUX86State *)current_cpu->env_ptr)->cr[0],
- sizeof(ps->cr));
- ps->hflags = ((CPUX86State *)current_cpu->env_ptr)->hflags;
+ &((CPUX86State *)current_cpu->env_ptr)->cr[0],
+ sizeof(ps->cr));
+ ps->hflags = env->hflags;
}
#endif
diff --git a/hw/yagl/yagl_process.h b/hw/yagl/yagl_process.h
index 4cbae5212c..bbf4568b58 100644
--- a/hw/yagl/yagl_process.h
+++ b/hw/yagl/yagl_process.h
@@ -55,7 +55,7 @@ struct yagl_process_state
QLIST_HEAD(, yagl_thread_state) threads;
-#ifdef CONFIG_KVM
+#if defined (CONFIG_KVM) || defined (CONFIG_HAX)
target_ulong cr[5];
uint32_t hflags;
#endif
diff --git a/hw/yagl/yagl_thread.c b/hw/yagl/yagl_thread.c
index 82a8d808dd..b965e32371 100644
--- a/hw/yagl/yagl_thread.c
+++ b/hw/yagl/yagl_thread.c
@@ -53,14 +53,15 @@ struct yagl_thread_work_item
uint32_t out_arrays_size;
};
-#ifdef CONFIG_KVM
+#if defined (CONFIG_KVM) || defined (CONFIG_HAX)
static __inline void yagl_cpu_synchronize_state(struct yagl_process_state *ps)
{
- if (kvm_enabled()) {
+ if (kvm_enabled() || hax_enabled()) {
+ CPUX86State *env = current_cpu->env_ptr;
memcpy(&((CPUX86State *)current_cpu->env_ptr)->cr[0],
- &ps->cr[0],
- sizeof(ps->cr));
- ((CPUX86State *)current_cpu->env_ptr)->hflags = ps->hflags;
+ &ps->cr[0],
+ sizeof(ps->cr));
+ env->hflags = ps->hflags;
}
}
#else
diff --git a/include/sysemu/hax.h b/include/sysemu/hax.h
index 58fb039e75..ac4cf7d3ad 100644
--- a/include/sysemu/hax.h
+++ b/include/sysemu/hax.h
@@ -44,8 +44,9 @@ int hax_vcpu_exec(CPUState *cpu);
int hax_smp_cpu_exec(CPUState *cpu);
void hax_cpu_synchronize_post_reset(CPUState *cpu);
void hax_cpu_synchronize_post_init(CPUState *cpu);
+void hax_cpu_synchronize_state(CPUState *cpu);
int hax_populate_ram(uint64_t va, uint32_t size);
-int hax_set_phys_mem(MemoryRegionSection *section);
+int hax_set_ram(uint64_t start_pa, uint32_t size, uint64_t host_va, int flags);
int hax_vcpu_emulation_mode(CPUState *cpu);
int hax_stop_emulation(CPUState *cpu);
int hax_stop_translate(CPUState *cpu);
diff --git a/package/changelog b/package/changelog
index 62caaf7bc5..21583477be 100644
--- a/package/changelog
+++ b/package/changelog
@@ -1,3 +1,33 @@
+* 2.6.10
+- modify VM lock
+== Munkyu Im <munkyu.im@samsung.com> 2016-11-08
+* 2.6.9
+- fix checking tap device
+== Munkyu Im <munkyu.im@samsung.com> 2016-10-25
+* 2.6.8
+- change QMatrix to QTransform
+- fix abnormal exit issue
+- remove Qt::AA_X11InitThreads attribute
+- modify backtrace feature for Windows
+== Sooyoung Ha <yoosah.ha@samsung.com> 2016-10-13
+* 2.6.7
+- display: Revert "display: move display functionality to Qt5 GUI" for AMD gpu issue
+- display: fix display rotation failure
+== Jinhyung Jo <jinhyung.jo@samsung.com> 2016-10-05
+* 2.6.6
+- adjust vm lock module
+- change version of about dialog
+- add surface option for AMD gpu driver
+==jihye kim<jihye424.kim@samsung.com> 2016-09-28
+* 2.6.5
+- temporarily remove shortcut info in mac
+- add missing "break" statement in skin
+== jihye kim <jihye424.kim@samsung.com> 2016-09-22
+* 2.6.4
+- fix transparency bug
+- separate cli vm searching
+- launch ecp using .app file in mac os
+== jihye kim <jihye424.kim@samsung.com> 2016-09-21
* 2.6.2
- tizen-kvm is moved to emulator-supplements package
== SeokYeon Hwang <syeon.hwang@samsung.com> 2016-03-22
diff --git a/package/pkginfo.manifest b/package/pkginfo.manifest
index b7b6b20495..c900929a76 100644
--- a/package/pkginfo.manifest
+++ b/package/pkginfo.manifest
@@ -1,4 +1,4 @@
-Version: 2.6.3
+Version: 2.6.10
Maintainer: SeokYeon Hwang <syeon.hwang@samsung.com>
Source: emulator
diff --git a/target-i386/hax-all.c b/target-i386/hax-all.c
index 916fcd47c1..10fec180a3 100644
--- a/target-i386/hax-all.c
+++ b/target-i386/hax-all.c
@@ -26,6 +26,7 @@
#include "strings.h"
#include "hax-i386.h"
+#include "hax-slot.h"
#include "hw/boards.h"
#include "sysemu/accel.h"
#include "exec/address-spaces.h"
@@ -371,7 +372,8 @@ struct hax_vm *hax_vm_create(struct hax_state *hax)
}
hax->vm = vm;
- dprint("End of VM create, id %d\n", vm->id);
+ hax_slot_init_registry();
+
return vm;
error:
@@ -384,6 +386,7 @@ int hax_vm_destroy(struct hax_vm *vm)
{
int i;
+ hax_slot_free_registry();
for (i = 0; i < HAX_MAX_VCPU; i++)
if (vm->vcpus[i])
{
@@ -396,6 +399,41 @@ int hax_vm_destroy(struct hax_vm *vm)
return 0;
}
+static void hax_set_phys_mem(MemoryRegionSection *section)
+{
+ MemoryRegion *mr = section->mr;
+ hwaddr start_pa = section->offset_within_address_space;
+ ram_addr_t size = int128_get64(section->size);
+ unsigned int delta;
+ void *host_ptr;
+ int flags;
+
+ /* We only care about RAM and ROM */
+ if (!memory_region_is_ram(mr)) {
+ return;
+ }
+
+ /* Adjust start_pa and size so that they are page-aligned. (Cf
+ * kvm_set_phys_mem() in kvm-all.c).
+ */
+ delta = TARGET_PAGE_SIZE - (start_pa & ~TARGET_PAGE_MASK);
+ delta &= ~TARGET_PAGE_MASK;
+ if (delta > size) {
+ return;
+ }
+ start_pa += delta;
+ size -= delta;
+ size &= TARGET_PAGE_MASK;
+ if (!size || start_pa & ~TARGET_PAGE_MASK) {
+ return;
+ }
+
+ host_ptr = memory_region_get_ram_ptr(mr) + section->offset_within_region
+ + delta;
+ flags = memory_region_is_rom(mr) ? 1 : 0;
+ hax_slot_register(start_pa, size, (uintptr_t) host_ptr, flags);
+}
+
static void
hax_region_add(MemoryListener *listener, MemoryRegionSection *section)
{
@@ -405,7 +443,7 @@ hax_region_add(MemoryListener *listener, MemoryRegionSection *section)
static void
hax_region_del(MemoryListener *listener, MemoryRegionSection *section)
{
- hax_set_phys_mem(section);
+ // Memory mappings will be removed at VM close.
}
@@ -417,11 +455,17 @@ hax_region_del(MemoryListener *listener, MemoryRegionSection *section)
static void hax_log_sync(MemoryListener *listener, MemoryRegionSection *section)
{
MemoryRegion *mr = section->mr;
+
+ if (!memory_region_is_ram(mr)) {
+ /* Skip MMIO regions */
+ return;
+ }
+
unsigned long c;
unsigned int len = ((int128_get64(section->size) / TARGET_PAGE_SIZE) + HOST_LONG_BITS - 1) /
HOST_LONG_BITS;
unsigned long bitmap[len];
- int i, j;
+ unsigned int i, j;
for (i = 0; i < len; i++) {
bitmap[i] = 1;
@@ -767,13 +811,6 @@ static int hax_vcpu_hax_exec(CPUArchState *env, int ug_platform)
break;
}
-#if 0
- if (cpu->hax_vcpu_dirty) {
- hax_vcpu_sync_state(env, 1);
- cpu->hax_vcpu_dirty = 0;
- }
-#endif
-
hax_vcpu_interrupt(env);
if (!ug_platform)
{
@@ -863,37 +900,52 @@ static int hax_vcpu_hax_exec(CPUArchState *env, int ug_platform)
return ret;
}
-#if 0
-static void do_hax_cpu_synchronize_state(void *_env)
+static void do_hax_cpu_synchronize_state(void *arg)
{
- CPUArchState *env = _env;
- CPUState *cpu = ENV_GET_CPU(env);
- if (!cpu->hax_vcpu_dirty) {
- hax_vcpu_sync_state(env, 0);
- cpu->hax_vcpu_dirty = 1;
- }
+ CPUState *cpu = arg;
+ CPUArchState *env = cpu->env_ptr;
+
+ hax_arch_get_registers(env);
+ cpu->hax_vcpu_dirty = true;
}
-static void hax_cpu_synchronize_state(CPUState *cpu)
+void hax_cpu_synchronize_state(CPUState *cpu)
{
- if (!cpu->hax_vcpu_dirty) {
- run_on_cpu(cpu, do_hax_cpu_synchronize_state, cpu);
- }
+ /* TODO: Do not sync if cpu->hax_vcpu_dirty is true. (Cf
+ * kvm_cpu_synchronize_state() in kvm-all.c)
+ * This would require that this flag be updated properly and consistently
+ * wherever a vCPU state sync between QEMU and HAX takes place. For now,
+ * just perform the sync regardless of hax_vcpu_dirty.
+ */
+ run_on_cpu(cpu, do_hax_cpu_synchronize_state, cpu);
}
-#endif
-void hax_cpu_synchronize_post_reset(CPUState *cpu)
+static void do_hax_cpu_synchronize_post_reset(void *arg)
{
- CPUArchState *env = (CPUArchState *)(cpu->env_ptr);
+ CPUState *cpu = arg;
+ CPUArchState *env = cpu->env_ptr;
+
hax_vcpu_sync_state(env, 1);
- cpu->hax_vcpu_dirty = 0;
+ cpu->hax_vcpu_dirty = false;
}
-void hax_cpu_synchronize_post_init(CPUState *cpu)
+void hax_cpu_synchronize_post_reset(CPUState * cpu)
{
- CPUArchState *env = (CPUArchState *)(cpu->env_ptr);
+ run_on_cpu(cpu, do_hax_cpu_synchronize_post_reset, cpu);
+}
+
+static void do_hax_cpu_synchronize_post_init(void *arg)
+{
+ CPUState *cpu = arg;
+ CPUArchState *env = cpu->env_ptr;
+
hax_vcpu_sync_state(env, 1);
- cpu->hax_vcpu_dirty = 0;
+ cpu->hax_vcpu_dirty = false;
+}
+
+void hax_cpu_synchronize_post_init(CPUState * cpu)
+{
+ run_on_cpu(cpu, do_hax_cpu_synchronize_post_init, cpu);
}
/*
@@ -1145,7 +1197,16 @@ static int hax_sync_vcpu_register(CPUArchState *env, int set)
hax_getput_reg(&regs._rdi, &env->regs[R_EDI], set);
hax_getput_reg(&regs._rsp, &env->regs[R_ESP], set);
hax_getput_reg(&regs._rbp, &env->regs[R_EBP], set);
-
+#ifdef TARGET_X86_64
+ hax_getput_reg(&regs._r8, &env->regs[8], set);
+ hax_getput_reg(&regs._r9, &env->regs[9], set);
+ hax_getput_reg(&regs._r10, &env->regs[10], set);
+ hax_getput_reg(&regs._r11, &env->regs[11], set);
+ hax_getput_reg(&regs._r12, &env->regs[12], set);
+ hax_getput_reg(&regs._r13, &env->regs[13], set);
+ hax_getput_reg(&regs._r14, &env->regs[14], set);
+ hax_getput_reg(&regs._r15, &env->regs[15], set);
+#endif
hax_getput_reg(&regs._rflags, &env->eflags, set);
hax_getput_reg(&regs._rip, &env->eip, set);
@@ -1173,8 +1234,14 @@ static int hax_sync_vcpu_register(CPUArchState *env, int set)
if (ret < 0)
return -1;
}
+
+ // it should be done after get_msrs, since it needs
+ // EFER synchonization
+#if 0
if (!set)
hax_setup_qemu_emulator(env);
+#endif
+
return 0;
}
@@ -1196,6 +1263,14 @@ static int hax_get_msrs(CPUArchState *env)
msrs[n++].entry = MSR_IA32_SYSENTER_ESP;
msrs[n++].entry = MSR_IA32_SYSENTER_EIP;
msrs[n++].entry = MSR_IA32_TSC;
+#ifdef TARGET_X86_64
+ msrs[n++].entry = MSR_EFER;
+ msrs[n++].entry = MSR_STAR;
+ msrs[n++].entry = MSR_LSTAR;
+ msrs[n++].entry = MSR_CSTAR;
+ msrs[n++].entry = MSR_FMASK;
+ msrs[n++].entry = MSR_KERNELGSBASE;
+#endif
md.nr_msr = n;
ret = hax_sync_msr(env, &md, 0);
if (ret < 0)
@@ -1215,6 +1290,26 @@ static int hax_get_msrs(CPUArchState *env)
case MSR_IA32_TSC:
env->tsc = msrs[i].value;
break;
+#ifdef TARGET_X86_64
+ case MSR_EFER:
+ env->efer = msrs[i].value;
+ break;
+ case MSR_STAR:
+ env->star = msrs[i].value;
+ break;
+ case MSR_LSTAR:
+ env->lstar = msrs[i].value;
+ break;
+ case MSR_CSTAR:
+ env->cstar = msrs[i].value;
+ break;
+ case MSR_FMASK:
+ env->fmask = msrs[i].value;
+ break;
+ case MSR_KERNELGSBASE:
+ env->kernelgsbase = msrs[i].value;
+ break;
+#endif
}
}
@@ -1233,6 +1328,14 @@ static int hax_set_msrs(CPUArchState *env)
hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
hax_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
hax_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
+#ifdef TARGET_X86_64
+ hax_msr_entry_set(&msrs[n++], MSR_EFER, env->efer);
+ hax_msr_entry_set(&msrs[n++], MSR_STAR, env->star);
+ hax_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
+ hax_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
+ hax_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask);
+ hax_msr_entry_set(&msrs[n++], MSR_KERNELGSBASE, env->kernelgsbase);
+#endif
md.nr_msr = n;
md.done = 0;
@@ -1255,9 +1358,13 @@ static int hax_get_fpu(CPUArchState *env)
for (i = 0; i < 8; ++i)
env->fptags[i] = !((fpu.ftw >> i) & 1);
memcpy(env->fpregs, fpu.st_mm, sizeof(env->fpregs));
+ for (i = 0; i < 8; ++i) {
+ memcpy(&env->xmm_regs[i], fpu.mmx_1[i], sizeof(fpu.mmx_1[i]));
+ }
+ for (i = 0; i < 8; ++i) {
+ memcpy(&env->xmm_regs[8 + i], fpu.mmx_2[i], sizeof(fpu.mmx_2[i]));
+ }
- memcpy(env->xmm_regs, fpu.mmx_1, sizeof(fpu.mmx_1));
- memcpy((ZMMReg *)(env->xmm_regs) + 8, fpu.mmx_2, sizeof(fpu.mmx_2));
env->mxcsr = fpu.mxcsr;
return 0;
@@ -1277,8 +1384,12 @@ static int hax_set_fpu(CPUArchState *env)
fpu.ftw |= (!env->fptags[i]) << i;
memcpy(fpu.st_mm, env->fpregs, sizeof (env->fpregs));
- memcpy(fpu.mmx_1, env->xmm_regs, sizeof (fpu.mmx_1));
- memcpy(fpu.mmx_2, (ZMMReg *)(env->xmm_regs) + 8, sizeof (fpu.mmx_2));
+ for (i = 0; i < 8; i++) {
+ memcpy(fpu.mmx_1[i], &env->xmm_regs[i], sizeof(fpu.mmx_1[i]));
+ }
+ for (i = 0; i < 8; i++) {
+ memcpy(fpu.mmx_2[i], &env->xmm_regs[i + 8], sizeof(fpu.mmx_2[i]));
+ }
fpu.mxcsr = env->mxcsr;
@@ -1301,6 +1412,8 @@ static int hax_arch_get_registers(CPUArchState *env)
if (ret < 0)
return ret;
+ hax_setup_qemu_emulator(env);
+
return 0;
}
diff --git a/target-i386/hax-darwin.c b/target-i386/hax-darwin.c
index b8dcbd40ab..be30d74af6 100644
--- a/target-i386/hax-darwin.c
+++ b/target-i386/hax-darwin.c
@@ -63,43 +63,23 @@ int hax_populate_ram(uint64_t va, uint32_t size)
return 0;
}
-int hax_set_phys_mem(MemoryRegionSection *section)
+int hax_set_ram(uint64_t start_pa, uint32_t size, uint64_t host_va, int flags)
{
- struct hax_set_ram_info info, *pinfo = &info;
- MemoryRegion *mr = section->mr;
- hwaddr start_addr = section->offset_within_address_space;
- ram_addr_t size = int128_get64(section->size);
+ struct hax_set_ram_info info;
int ret;
- /*We only care for the RAM and ROM*/
- if(!memory_region_is_ram(mr))
- return 0;
-
- if ( (start_addr & ~TARGET_PAGE_MASK) || (size & ~TARGET_PAGE_MASK))
- {
- dprint("set_phys_mem %llx %lx requires page aligned addr and size\n", start_addr, size);
- exit(1);
- return -1;
- }
-
- info.pa_start = start_addr;
+ info.pa_start = start_pa;
info.size = size;
- info.va = (uint64_t)(intptr_t)(memory_region_get_ram_ptr(mr) + section->offset_within_region);
- info.flags = memory_region_is_rom(mr) ? 1 : 0;
+ info.va = host_va;
+ info.flags = (uint8_t) flags;
- ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_SET_RAM, pinfo);
- if (ret < 0)
- {
- dprint("has set phys mem failed\n");
- exit(1);
+ ret = ioctl(hax_global.vm->fd, HAX_VM_IOCTL_SET_RAM, &info);
+ if (ret < 0) {
+ return -errno;
}
-
- return ret;
-
+ return 0;
}
-
-
int hax_capability(struct hax_state *hax, struct hax_capabilityinfo *cap)
{
int ret;
diff --git a/target-i386/hax-slot.c b/target-i386/hax-slot.c
new file mode 100644
index 0000000000..b0b3ed9dab
--- /dev/null
+++ b/target-i386/hax-slot.c
@@ -0,0 +1,328 @@
+/*
+** HAX memory slot operations
+**
+** Copyright (c) 2015-16 Intel Corporation
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** 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 General Public License for more details.
+*/
+
+#include "target-i386/hax-slot.h"
+#include "target-i386/hax-i386.h"
+#include "qemu/queue.h"
+
+//#define DEBUG_HAX_SLOT
+
+#ifdef DEBUG_HAX_SLOT
+#define DPRINTF(fmt, ...) \
+ do { fprintf(stdout, fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) \
+ do { } while (0)
+#endif
+
+/**
+ * HAXSlot: describes a guest physical memory region and its mapping
+ *
+ * @start_pa: a guest physical address marking the start of the region; must be
+ * page-aligned
+ * @end_pa: a guest physical address marking the end of the region; must be
+ * page-aligned
+ * @hva_pa_delta: the host virtual address to which guest physical address 0 is
+ * mapped; in other words, for any guest physical address within
+ * the region (start_pa <= pa < end_pa), the corresponding host
+ * virtual address is calculated by host_va = pa + hva_pa_delta
+ * @flags: parameters for the mapping; must be non-negative
+ * @entry: additional fields for linking #HAXSlot instances together
+ */
+typedef struct HAXSlot {
+ uint64_t start_pa;
+ uint64_t end_pa;
+ uint64_t hva_pa_delta;
+ int flags;
+ QTAILQ_ENTRY(HAXSlot) entry;
+} HAXSlot;
+
+/* A doubly-linked list (actually a tail queue) of all registered slots */
+static QTAILQ_HEAD(HAXSlotListHead, HAXSlot) slot_list =
+ QTAILQ_HEAD_INITIALIZER(slot_list);
+
+void hax_slot_init_registry(void)
+{
+ HAXSlot *initial_slot;
+
+ g_assert(QTAILQ_EMPTY(&slot_list));
+
+ initial_slot = (HAXSlot *) g_malloc0(sizeof(*initial_slot));
+ /* Implied: initial_slot->start_pa = 0; */
+ /* Ideally we want to set end_pa to 2^64, but that is too large for
+ * uint64_t. We don't need to support such a large guest physical address
+ * space anyway; (2^64 - TARGET_PAGE_SIZE) should be (more than) enough.
+ */
+ initial_slot->end_pa = TARGET_PAGE_MASK;
+ /* hva_pa_delta and flags are initialized with invalid values */
+ initial_slot->hva_pa_delta = ~TARGET_PAGE_MASK;
+ initial_slot->flags = -1;
+ QTAILQ_INSERT_TAIL(&slot_list, initial_slot, entry);
+}
+
+void hax_slot_free_registry(void)
+{
+ DPRINTF("%s: Deleting all registered slots\n", __func__);
+ while (!QTAILQ_EMPTY(&slot_list)) {
+ HAXSlot *slot = QTAILQ_FIRST(&slot_list);
+ QTAILQ_REMOVE(&slot_list, slot, entry);
+ g_free(slot);
+ }
+}
+
+/**
+ * hax_slot_dump: dumps a slot to stdout (for debugging)
+ *
+ * @slot: the slot to dump
+ */
+static void hax_slot_dump(HAXSlot *slot)
+{
+ DPRINTF("[ start_pa=0x%016" PRIx64 ", end_pa=0x%016" PRIx64
+ ", hva_pa_delta=0x%016" PRIx64 ", flags=%d ]\n", slot->start_pa,
+ slot->end_pa, slot->hva_pa_delta, slot->flags);
+}
+
+/**
+ * hax_slot_dump_list: dumps @slot_list to stdout (for debugging)
+ */
+static void hax_slot_dump_list(void)
+{
+#ifdef DEBUG_HAX_SLOT
+ HAXSlot *slot;
+ int i = 0;
+
+ DPRINTF("**** BEGIN HAX SLOT LIST DUMP ****\n");
+ QTAILQ_FOREACH(slot, &slot_list, entry) {
+ DPRINTF("Slot %d:\n\t", i++);
+ hax_slot_dump(slot);
+ }
+ DPRINTF("**** END HAX SLOT LIST DUMP ****\n");
+#endif
+}
+
+/**
+ * hax_slot_find: locates the slot containing a guest physical address
+ *
+ * Traverses @slot_list, starting from @start_slot, and returns the slot which
+ * contains @pa. There should be one and only one such slot, because:
+ *
+ * 1) @slot_list is initialized with a slot which covers all valid @pa values.
+ * This coverage stays unchanged as new slots are inserted into @slot_list.
+ * 2) @slot_list does not contain overlapping slots.
+ *
+ * @start_slot: the first slot from which @slot_list is traversed and searched;
+ * must not be %NULL
+ * @pa: the guest physical address to locate; must not be less than the lower
+ * bound of @start_slot
+ */
+static HAXSlot * hax_slot_find(HAXSlot *start_slot, uint64_t pa)
+{
+ HAXSlot *slot;
+
+ g_assert(start_slot);
+ g_assert(start_slot->start_pa <= pa);
+
+ slot = start_slot;
+ do {
+ if (slot->end_pa > pa) {
+ return slot;
+ }
+ slot = QTAILQ_NEXT(slot, entry);
+ } while (slot);
+
+ /* Should never reach here */
+ g_assert_not_reached();
+ return NULL;
+}
+
+/**
+ * hax_slot_split: splits a slot into two
+ *
+ * Shrinks @slot and creates a new slot from the vacated region. Returns the
+ * new slot.
+ *
+ * @slot: the slot to be split/shrinked
+ * @pa: the splitting point; must be page-aligned and within @slot
+ */
+static HAXSlot * hax_slot_split(HAXSlot *slot, uint64_t pa)
+{
+ HAXSlot *new_slot;
+
+ g_assert(slot);
+ g_assert(pa > slot->start_pa && pa < slot->end_pa);
+ g_assert(!(pa & ~TARGET_PAGE_MASK));
+
+ new_slot = (HAXSlot *) g_malloc0(sizeof(*new_slot));
+ new_slot->start_pa = pa;
+ new_slot->end_pa = slot->end_pa;
+ new_slot->hva_pa_delta = slot->hva_pa_delta;
+ new_slot->flags = slot->flags;
+
+ slot->end_pa = pa;
+ QTAILQ_INSERT_AFTER(&slot_list, slot, new_slot, entry);
+ return new_slot;
+}
+
+/**
+ * hax_slot_can_merge: tests if two slots are compatible
+ *
+ * Two slots are considered compatible if they share the same memory mapping
+ * attributes. Compatible slots can be merged if they overlap or are adjacent.
+ *
+ * Returns %true if @slot1 and @slot2 are compatible.
+ *
+ * @slot1: one of the slots to be tested; must not be %NULL
+ * @slot2: the other slot to be tested; must not be %NULL
+ */
+static bool hax_slot_can_merge(HAXSlot *slot1, HAXSlot *slot2)
+{
+ g_assert(slot1 && slot2);
+
+ return slot1->hva_pa_delta == slot2->hva_pa_delta
+ && slot1->flags == slot2->flags;
+}
+
+/**
+ * hax_slot_insert: inserts a slot into @slot_list, with the potential side
+ * effect of creating/updating memory mappings
+ *
+ * Causes memory mapping attributes of @slot to override those of overlapping
+ * slots (including partial slots) in @slot_list. For any slot whose mapping
+ * attributes have changed, performs an ioctl to enforce the new mapping.
+ *
+ * Aborts QEMU on error.
+ *
+ * @slot: the slot to be inserted
+ */
+static void hax_slot_insert(HAXSlot *slot)
+{
+ HAXSlot *low_slot, *high_slot;
+ HAXSlot *low_slot_prev, *high_slot_next;
+ HAXSlot *old_slot, *old_slot_next;
+
+ g_assert(!QTAILQ_EMPTY(&slot_list));
+
+ low_slot = hax_slot_find(QTAILQ_FIRST(&slot_list), slot->start_pa);
+ g_assert(low_slot);
+ low_slot_prev = QTAILQ_PREV(low_slot, HAXSlotListHead, entry);
+
+ /* Adjust slot and/or low_slot such that their lower bounds (start_pa)
+ * align.
+ */
+ if (hax_slot_can_merge(low_slot, slot)) {
+ slot->start_pa = low_slot->start_pa;
+ } else if (slot->start_pa == low_slot->start_pa && low_slot_prev
+ && hax_slot_can_merge(low_slot_prev, slot)) {
+ low_slot = low_slot_prev;
+ slot->start_pa = low_slot->start_pa;
+ } else if (slot->start_pa != low_slot->start_pa) {
+ /* low_slot->start_pa < slot->start_pa < low_slot->end_pa */
+ low_slot = hax_slot_split(low_slot, slot->start_pa);
+ g_assert(low_slot);
+ }
+ /* Now we have slot->start_pa == low_slot->start_pa */
+
+ high_slot = hax_slot_find(low_slot, slot->end_pa - 1);
+ g_assert(high_slot);
+ high_slot_next = QTAILQ_NEXT(high_slot, entry);
+
+ /* Adjust slot and/or high_slot such that their upper bounds (end_pa)
+ * align.
+ */
+ if (hax_slot_can_merge(slot, high_slot)) {
+ slot->end_pa = high_slot->end_pa;
+ } else if (slot->end_pa == high_slot->end_pa && high_slot_next
+ && hax_slot_can_merge(slot, high_slot_next)) {
+ high_slot = high_slot_next;
+ slot->end_pa = high_slot->end_pa;
+ } else if (slot->end_pa != high_slot->end_pa) {
+ /* high_slot->start_pa < slot->end_pa < high_slot->end_pa */
+ high_slot_next = hax_slot_split(high_slot, slot->end_pa);
+ g_assert(high_slot_next);
+ }
+ /* Now we have slot->end_pa == high_slot->end_pa */
+
+ /* We are ready for substitution: replace all slots between low_slot and
+ * high_slot (inclusive) with slot. */
+
+ /* Step 1: insert slot into the list, before low_slot */
+ QTAILQ_INSERT_BEFORE(low_slot, slot, entry);
+
+ /* Step 2: remove low_slot..high_slot, one by one */
+ for (old_slot = low_slot;
+ /* This condition always evaluates to 1. See:
+ * https://en.wikipedia.org/wiki/Comma_operator
+ */
+ old_slot_next = QTAILQ_NEXT(old_slot, entry), 1;
+ old_slot = old_slot_next) {
+ g_assert(old_slot);
+
+ QTAILQ_REMOVE(&slot_list, old_slot, entry);
+ if (!hax_slot_can_merge(slot, old_slot)) {
+ /* Mapping for guest memory region [old_slot->start_pa,
+ * old_slot->end_pa) has changed - must do ioctl. */
+ /* TODO: Further reduce the number of ioctl calls by preprocessing
+ * the low_slot..high_slot sublist and combining any two adjacent
+ * slots that are both incompatible with slot.
+ */
+ uint32_t size = old_slot->end_pa - old_slot->start_pa;
+ uint64_t host_va = old_slot->start_pa + slot->hva_pa_delta;
+ int err;
+
+ DPRINTF("%s: Doing ioctl (size=0x%08" PRIx32 ")\n", __func__, size);
+ /* Use the new host_va and flags */
+ err = hax_set_ram(old_slot->start_pa, size, host_va, slot->flags);
+ if (err) {
+ fprintf(stderr, "%s: Failed to set memory mapping (err=%d)\n",
+ __func__, err);
+ abort();
+ }
+ }
+ g_free(old_slot);
+
+ /* Exit the infinite loop following the removal of high_slot */
+ if (old_slot == high_slot) {
+ break;
+ }
+ }
+}
+
+void hax_slot_register(uint64_t start_pa, uint32_t size, uint64_t host_va,
+ int flags)
+{
+ uint64_t end_pa = start_pa + size;
+ HAXSlot *slot;
+
+ g_assert(!(start_pa & ~TARGET_PAGE_MASK));
+ g_assert(!(end_pa & ~TARGET_PAGE_MASK));
+ g_assert(start_pa < end_pa);
+ g_assert(host_va);
+ g_assert(flags >= 0);
+
+ slot = g_malloc0(sizeof(*slot));
+ slot->start_pa = start_pa;
+ slot->end_pa = end_pa;
+ slot->hva_pa_delta = host_va - start_pa;
+ slot->flags = flags;
+
+ DPRINTF("%s: Inserting slot:\n\t", __func__);
+ hax_slot_dump(slot);
+ hax_slot_dump_list();
+
+ hax_slot_insert(slot);
+
+ DPRINTF("%s: Done\n", __func__);
+ hax_slot_dump_list();
+}
diff --git a/target-i386/hax-slot.h b/target-i386/hax-slot.h
new file mode 100644
index 0000000000..d991c53d38
--- /dev/null
+++ b/target-i386/hax-slot.h
@@ -0,0 +1,58 @@
+/*
+** HAX memory slot operations
+**
+** Copyright (c) 2015-16 Intel Corporation
+**
+** This software is licensed under the terms of the GNU General Public
+** License version 2, as published by the Free Software Foundation, and
+** may be copied, distributed, and modified under those terms.
+**
+** 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 General Public License for more details.
+*/
+
+#ifndef _HAX_SLOT_H
+#define _HAX_SLOT_H
+
+#include <inttypes.h>
+
+/**
+ * hax_slot_init_registry: initializes the registry of memory slots.
+ *
+ * Should be called during HAX initialization, before any call to
+ * hax_slot_register().
+ */
+void hax_slot_init_registry(void);
+
+/**
+ * hax_slot_free_registry: destroys the registry of memory slots.
+ *
+ * Should be called during HAX cleanup to free up resources used by the
+ * registry of memory slots.
+ */
+void hax_slot_free_registry(void);
+
+/**
+ * hax_slot_register: registers a memory slot, updating HAX memory mappings if
+ * necessary.
+ *
+ * Must be called after hax_slot_init_registry(). Can be called multiple times
+ * to create new memory mappings or update existing ones. This function is smart
+ * enough to avoid asking the HAXM driver to do the same mapping twice for any
+ * guest physical page.
+ *
+ * Aborts QEMU on error.
+ *
+ * @start_pa: a guest physical address marking the start of the slot to
+ * register; must be page-aligned
+ * @size: size of the slot to register; must be page-aligned and positive
+ * @host_va: a host virtual address to which @start_pa should be mapped
+ * @flags: parameters for the mapping, passed verbatim to the HAXM driver if
+ * necessary; must be non-negative
+ */
+void hax_slot_register(uint64_t start_pa, uint32_t size, uint64_t host_va,
+ int flags);
+
+#endif
diff --git a/target-i386/hax-windows.c b/target-i386/hax-windows.c
index 5ff5916db5..f24a9e195e 100644
--- a/target-i386/hax-windows.c
+++ b/target-i386/hax-windows.c
@@ -90,48 +90,21 @@ int hax_populate_ram(uint64_t va, uint32_t size)
return 0;
}
-
-/*
- * much simpler than kvm, at least in first stage because:
- * We don't need consider the device pass-through, we don't need
- * consider the framebuffer, and we may even remove the bios at all
- */
-
-int hax_set_phys_mem(MemoryRegionSection *section)
+int hax_set_ram(uint64_t start_pa, uint32_t size, uint64_t host_va, int flags)
{
- struct hax_set_ram_info info, *pinfo = &info;
- MemoryRegion *mr = section->mr;
- hwaddr start_addr = section->offset_within_address_space;
- ram_addr_t size = int128_get64(section->size);
- HANDLE hDeviceVM;
+ struct hax_set_ram_info info;
+ HANDLE hDeviceVM = hax_global.vm->fd;
DWORD dSize = 0;
- int ret = 0;
-
- /* We only care for the RAM and ROM */
- if (!memory_region_is_ram(mr)) {
- return 0;
- }
-
- if ( (start_addr & ~TARGET_PAGE_MASK) || (size & ~TARGET_PAGE_MASK)) {
- dprint(
- "set_phys_mem %" PRIx64 " %" PRIxPTR " requires page aligned addr and size\n",
- start_addr, size);
- return -1;
- }
+ int ret;
- info.pa_start = start_addr;
+ info.pa_start = start_pa;
info.size = size;
- info.va = (uint64_t)(intptr_t)(memory_region_get_ram_ptr(mr) + section->offset_within_region);
- info.flags = memory_region_is_rom(mr) ? 1 : 0;
-
- hDeviceVM = hax_global.vm->fd;
+ info.va = host_va;
+ info.flags = (uint8_t) flags;
- ret = DeviceIoControl(hDeviceVM,
- HAX_VM_IOCTL_SET_RAM,
- pinfo, sizeof(*pinfo),
- NULL, 0,
- &dSize,
- (LPOVERLAPPED) NULL);
+ ret = DeviceIoControl(hDeviceVM, HAX_VM_IOCTL_SET_RAM,
+ &info, sizeof(info), NULL, 0, &dSize,
+ (LPOVERLAPPED) NULL);
if (!ret)
return -EFAULT;
diff --git a/target-i386/monitor.c b/target-i386/monitor.c
index fccfe40ab7..1f0e46cb7e 100644
--- a/target-i386/monitor.c
+++ b/target-i386/monitor.c
@@ -36,7 +36,7 @@ static void print_pte(Monitor *mon, hwaddr addr,
{
#ifdef TARGET_X86_64
if (addr & (1ULL << 47)) {
- addr |= -1LL << 48;
+ addr |= ~0ULL << 48;
}
#endif
monitor_printf(mon, TARGET_FMT_plx ": " TARGET_FMT_plx
diff --git a/tizen/src/ecs/ecs.c b/tizen/src/ecs/ecs.c
index c77b6c0a55..758579281c 100644
--- a/tizen/src/ecs/ecs.c
+++ b/tizen/src/ecs/ecs.c
@@ -51,6 +51,9 @@
#include "ecs.h"
#include "emul_state.h"
+#include "hw/virtio/maru_virtio_sensor.h"
+#include "hw/virtio/maru_virtio_nfc.h"
+
#include "debug_ch.h"
MULTI_DEBUG_CHANNEL(qemu, ecs);
@@ -77,6 +80,40 @@ static QemuThread ecs_thread_id;
static int suspend_state = 1;
+static char device_capabilities [16];
+
+enum ecs_check_cap_list {
+ CHECK_CAP_BATTERY = 0,
+ CHECK_CAP_LOCATION,
+ CHECK_CAP_NFC,
+ CHECK_CAP_TELEPHONY,
+ CHECK_CAP_ACCEL,
+ CHECK_CAP_GYRO,
+ CHECK_CAP_GEO,
+ CHECK_CAP_PROXI,
+ CHECK_CAP_LIGHT,
+ CHECK_CAP_PRESSURE,
+ CHECK_CAP_HEARTRATE,
+ CHECK_CAP_UV,
+ CHECK_CAP_PEDO
+};
+
+static int cap_device_list[] = {
+ 0x0001, // Battery
+ 0x0002, // Location
+ 0x0004, // NFC
+ 0x0008, // Telephony
+ 0x0010, // Accelerometer
+ 0x0020, // Gyroscope
+ 0x0040, // Magnetometer
+ 0x0080, // Proximity
+ 0x0100, // Light
+ 0x0200, // Pressure
+ 0x0400, // HeartRate
+ 0x0800, // Ultraviolet
+ 0x1000, // Pedometer
+};
+
void ecs_set_suspend_state(int state)
{
suspend_state = state;
@@ -87,6 +124,78 @@ int ecs_get_suspend_state(void)
return suspend_state;
}
+static void check_sensor_capability(int* capacity)
+{
+ int sensor_cap = get_sensor_capability();
+ if ((sensor_cap & sensor_cap_accel) == 0) {
+ *capacity &= ~cap_device_list[CHECK_CAP_ACCEL];
+ }
+ if ((sensor_cap & sensor_cap_geo) == 0) {
+ *capacity &= ~cap_device_list[CHECK_CAP_GEO];
+ }
+
+ if ((sensor_cap & sensor_cap_gyro) == 0) {
+ *capacity &= ~cap_device_list[CHECK_CAP_GYRO];
+ }
+
+ if ((sensor_cap & sensor_cap_proxi) == 0) {
+ *capacity &= ~cap_device_list[CHECK_CAP_PROXI];
+ }
+
+ if ((sensor_cap & sensor_cap_light) == 0) {
+ *capacity &= ~cap_device_list[CHECK_CAP_LIGHT];
+ }
+
+ if ((sensor_cap & sensor_cap_pressure) == 0) {
+ *capacity &= ~cap_device_list[CHECK_CAP_PRESSURE];
+ }
+
+ if ((sensor_cap & sensor_cap_uv) == 0) {
+ *capacity &= ~cap_device_list[CHECK_CAP_UV];
+ }
+
+ if ((sensor_cap & sensor_cap_hrm) == 0) {
+ *capacity &= ~cap_device_list[CHECK_CAP_HEARTRATE];
+ }
+
+ if ((sensor_cap & sensor_cap_pedo) == 0) {
+ *capacity &= ~cap_device_list[CHECK_CAP_PEDO];
+ }
+}
+
+extern VirtIONFC *vio_nfc;
+static void check_nfc_capability(int* capacity)
+{
+ if (!vio_nfc) {
+ *capacity &= ~cap_device_list[CHECK_CAP_NFC];
+ }
+}
+
+void ecs_set_device_capabilities(const char* cap)
+{
+ int capability = 0;
+
+ memset(device_capabilities, 0, sizeof(device_capabilities));
+
+ if (cap != NULL) {
+ capability = atoi(cap);
+ // check sensor capability
+ check_sensor_capability(&capability);
+ // check nfc capability
+ check_nfc_capability(&capability);
+
+ LOG_INFO("check_sensor_capability: %04x\n", capability);
+ snprintf(device_capabilities, sizeof(device_capabilities), "%d", capability);
+ }
+
+ make_send_device_ntf((char*)MSG_TYPE_CAP, MSG_GROUP_STATUS, 0, device_capabilities);
+}
+
+const char* ecs_get_device_capabilities(void)
+{
+ return device_capabilities;
+}
+
int ecs_write(int fd, const uint8_t *buf, int len)
{
int ret, remain;
diff --git a/tizen/src/ecs/ecs.h b/tizen/src/ecs/ecs.h
index 028c2f0675..3458dfaaa5 100644
--- a/tizen/src/ecs/ecs.h
+++ b/tizen/src/ecs/ecs.h
@@ -55,6 +55,7 @@
#define MSG_TYPE_HDS "hds"
#define MSG_TYPE_PACKAGE "package"
#define MSG_TYPE_SYSTEM "system"
+#define MSG_TYPE_CAP "cap"
#define MSG_GROUP_STATUS 15
@@ -95,4 +96,8 @@ int ecs_get_suspend_state(void);
void ecs_set_suspend_state(int state);
void ecs_suspend_lock_state(int state);
+/* Device capabilities check */
+const char* ecs_get_device_capabilities(void);
+void ecs_set_device_capabilities(const char* cap);
+
#endif /* __ECS_H__ */
diff --git a/tizen/src/ecs/ecs_msg.c b/tizen/src/ecs/ecs_msg.c
index 3eb314823a..305eb77051 100644
--- a/tizen/src/ecs/ecs_msg.c
+++ b/tizen/src/ecs/ecs_msg.c
@@ -197,6 +197,8 @@ void send_shutdown_request(int action)
if (!ret) {
LOG_SEVERE("fail to send evdi shutdown system call to emuld.\n");
}
+
+ ecs_set_device_capabilities(NULL);
}
bool ntf_to_injector(const char *data, const int len)
diff --git a/tizen/src/ecs/ecs_msg_device.c b/tizen/src/ecs/ecs_msg_device.c
index 3000478bde..4e7f5c1e84 100644
--- a/tizen/src/ecs/ecs_msg_device.c
+++ b/tizen/src/ecs/ecs_msg_device.c
@@ -431,14 +431,14 @@ bool msgproc_device_req(ECS_Client *ccli, ECS__DeviceReq *msg)
#endif
} else if (!strcmp(cmd, "input")) {
msgproc_device_req_input(ccli, msg, cmd);
- } else if (!strcmp(cmd, "vmname")) {
- const char *vmname = get_vm_name();
- msgproc_device_ans(ccli, cmd, true, vmname);
} else if (!strcmp(cmd, "vminfo")) {
gchar vminfo[128];
g_snprintf(vminfo, sizeof(vminfo) - 1, "%s %s %s",
get_vm_name(), get_profile_name(), get_platform_version());
msgproc_device_ans(ccli, cmd, true, vminfo);
+ } else if (!strcmp(cmd, MSG_TYPE_CAP)) {
+ const char* cap = ecs_get_device_capabilities();
+ make_send_device_ntf(cmd, MSG_GROUP_STATUS, 0, (char*)cap);
} else if (!strcmp(cmd, "nfc")) {
msgproc_device_req_nfc(ccli, msg);
} else if (!strcmp(cmd, "sdcard")) {
diff --git a/tizen/src/ecs/ecs_msg_injector.c b/tizen/src/ecs/ecs_msg_injector.c
index a65f70c044..c577ea3b9e 100644
--- a/tizen/src/ecs/ecs_msg_injector.c
+++ b/tizen/src/ecs/ecs_msg_injector.c
@@ -463,6 +463,10 @@ static bool injector_req_handle(char *cat, type_action action, const char *data)
LOG_WARNING("VirtFS is not enabled.\n");
return false;
#endif
+ } else if (!strcmp(cat, MSG_TYPE_CAP)) {
+ LOG_INFO("set capabilities: %s\n", data);
+ ecs_set_device_capabilities(data);
+ return true;
} else if (!strcmp(cat, MSG_TYPE_PACKAGE)) {
do_package(cat, action, data);
return true;
diff --git a/tizen/src/emul_state.c b/tizen/src/emul_state.c
index 8e6b7ea7c0..5ecf70dca7 100644
--- a/tizen/src/emul_state.c
+++ b/tizen/src/emul_state.c
@@ -311,38 +311,38 @@ const char *get_kernel_file(void)
return qemu_opt_get(qemu_get_machine_opts(), "kernel");
}
-// http proxy
-static const char *http_proxy_addr = NULL;
+// https proxy
+static const char *https_proxy_addr = NULL;
-const char *get_http_proxy_addr(void)
+const char *get_https_proxy_addr(void)
{
- if (http_proxy_addr) {
- return http_proxy_addr;
+ if (https_proxy_addr) {
+ return https_proxy_addr;
}
const char *kernel_cmdline =
qemu_opt_get(qemu_get_machine_opts(), "append");
// kernel cmdline always contains proxy information
- char *buf = g_strstr_len(kernel_cmdline, -1, "http_proxy=");
+ char *buf = g_strstr_len(kernel_cmdline, -1, "https_proxy=");
if (buf) {
char **token = g_strsplit_set(buf, "= ", 3);
if (token[0] && token[1] && g_strcmp0(token[1], "")) {
- http_proxy_addr = g_strdup(token[1]);
+ https_proxy_addr = g_strdup(token[1]);
g_strfreev(token);
- LOG_INFO("HTTP proxy address: %s\n", http_proxy_addr);
+ LOG_INFO("HTTPS proxy address: %s\n", https_proxy_addr);
- return http_proxy_addr;
+ return https_proxy_addr;
}
g_strfreev(token);
}
- http_proxy_addr = g_strdup("");
+ https_proxy_addr = g_strdup("");
- LOG_INFO("HTTP proxy address is not set.\n");
+ LOG_INFO("HTTPS proxy address is not set.\n");
- return http_proxy_addr;
+ return https_proxy_addr;
}
// vm_name
@@ -549,10 +549,7 @@ bool is_netclient_tap_attached(void)
NET_CLIENT_DRIVER_NIC,
MAX_QUEUE_NUM);
for (i = 0; i < queues; ++i) {
- if (ncs[i]->info->type == NET_CLIENT_DRIVER_TAP &&
- (ncs[i]->peer->info->type == NET_CLIENT_DRIVER_NIC ||
- // for legacy -net option.
- ncs[i]->peer->info->type == NET_CLIENT_DRIVER_HUBPORT)) {
+ if (ncs[i]->info->type == NET_CLIENT_DRIVER_TAP) {
return true;
}
}
@@ -742,8 +739,8 @@ static void emul_state_notify_exit(Notifier *notifier, void *data)
g_free((void *)swap_image_file);
swap_image_file = NULL;
- g_free((void *)http_proxy_addr);
- http_proxy_addr = NULL;
+ g_free((void *)https_proxy_addr);
+ https_proxy_addr = NULL;
g_free((void *)vm_name);
vm_name = NULL;
diff --git a/tizen/src/emul_state.h b/tizen/src/emul_state.h
index b360e88332..91a427a952 100644
--- a/tizen/src/emul_state.h
+++ b/tizen/src/emul_state.h
@@ -128,7 +128,7 @@ const char *get_drive_image_file(void);
const char *get_drive_image_ver(void);
const char *get_swap_image_file(void);
const char *get_kernel_file(void);
-const char *get_http_proxy_addr(void);
+const char *get_https_proxy_addr(void);
const char *get_vm_name(void);
const char *get_profile_name(void);
const char *get_platform_version(void);
diff --git a/tizen/src/emulator.c b/tizen/src/emulator.c
index b1d6bab6c8..b63d020518 100644
--- a/tizen/src/emulator.c
+++ b/tizen/src/emulator.c
@@ -47,7 +47,10 @@
#include "ecs/ecs.h"
#include "util/device_hotplug.h"
#include "util/exported_strings.h"
-
+#ifdef CONFIG_WIN32
+#include <windows.h>
+#include <sddl.h>
+#endif
#ifdef CONFIG_QT
#include <qt5_supplement.h>
#endif
@@ -240,7 +243,6 @@ const char *prepare_maru(const char * const kernel_cmdline)
void prepare_maru_after_device_init(void)
{
- make_vm_lock_os();
init_device_hotplug();
start_ecs();
@@ -283,7 +285,10 @@ static int emulator_main(int argc, char *argv[], char **envp)
set_variable(argv[optind - 1], argv[optind], true);
break;
case 'c':
- launch_conf_file = g_strdup(optarg);
+ if (optind == 3) {
+ // "--conf" should be a first argument
+ launch_conf_file = g_strdup(optarg);
+ }
break;
case 'q':
c = -1;
@@ -295,8 +300,12 @@ static int emulator_main(int argc, char *argv[], char **envp)
}
if (!launch_conf_file && qemu_arg_index == 0) {
- fprintf(stderr, "Usage: %s {-c|--conf} conf_file ...\n",
- basename(argv[0]));
+ char *executable = basename(argv[0]);
+ fprintf(stderr, "Usage: %s {-c|--conf} conf_file [--<key> <value>]...\n"
+ " %*s [{-q|--qemu} <QEMU_ARGS>...]\n",
+ executable, (int)strlen(executable), "");
+ fprintf(stderr, " %s {-q|--qemu} <QEMU_ARGS>...\n",
+ executable);
return -1;
}
@@ -308,6 +317,12 @@ static int emulator_main(int argc, char *argv[], char **envp)
set_bin_path_os(_qemu_argv[0]);
if (launch_conf_file) {
+ if (!g_file_test(launch_conf_file, G_FILE_TEST_EXISTS)) {
+ fprintf(stderr, "conf_file(%s) does not exist.\n", launch_conf_file);
+ return -1;
+ }
+
+ make_vm_lock_os(g_path_get_dirname(launch_conf_file));
if (!load_conf(launch_conf_file)) {
return -1;
}
@@ -346,6 +361,15 @@ int main(int argc, char *argv[], char **envp)
init_error_handler();
return emulator_main(argc, argv, envp);
}
+#elif defined (CONFIG_WIN32)
+int main(int argc, char *argv[])
+{
+ if (!check_integrity_level_and_respawn()) {
+ init_error_handler();
+ return emulator_main(argc, argv, NULL);
+ }
+ return 0;
+}
#else
int main(int argc, char *argv[])
{
diff --git a/tizen/src/emulator_options.c b/tizen/src/emulator_options.c
index 209bbabd94..03ea020bb5 100644
--- a/tizen/src/emulator_options.c
+++ b/tizen/src/emulator_options.c
@@ -220,7 +220,12 @@ bool load_conf(const char * const conf)
assert(!!conf);
filename = g_strdup(conf);
- file = fopen(filename, "r");
+ if(!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) {
+ fprintf(stderr,
+ "Profile configuration file [%s] is invalid.\n", filename);
+ return false;
+ }
+ file = g_fopen(filename, "r");
if (!file) {
fprintf(stderr,
"Profile configuration file [%s] is not found.\n", filename);
diff --git a/tizen/src/hw/virtio/maru_virtio_sensor.c b/tizen/src/hw/virtio/maru_virtio_sensor.c
index b6522ac4b8..94d892d619 100644
--- a/tizen/src/hw/virtio/maru_virtio_sensor.c
+++ b/tizen/src/hw/virtio/maru_virtio_sensor.c
@@ -726,6 +726,11 @@ static void parse_sensor_capability(char *lists)
LOG_INFO("sensor device capabilty enabled with %02x\n", sensor_capability);
}
+int get_sensor_capability(void)
+{
+ return sensor_capability;
+}
+
static void virtio_sensor_realize(DeviceState *dev, Error **errp)
{
LOG_INFO("initialize virtio-sensor device\n");
diff --git a/tizen/src/hw/virtio/maru_virtio_sensor.h b/tizen/src/hw/virtio/maru_virtio_sensor.h
index 1c0a743934..1cb5b19de9 100644
--- a/tizen/src/hw/virtio/maru_virtio_sensor.h
+++ b/tizen/src/hw/virtio/maru_virtio_sensor.h
@@ -143,6 +143,8 @@ typedef struct VirtIOSENSOR {
char *sensors;
} VirtIOSENSOR;
+int get_sensor_capability(void);
+
void req_sensor_data(enum sensor_types type, enum request_cmd req, char *data, int len);
#define get_sensor_accel() \
diff --git a/tizen/src/hw/virtio/maru_virtio_tablet.c b/tizen/src/hw/virtio/maru_virtio_tablet.c
index 9a564ba502..5bab39cc95 100644
--- a/tizen/src/hw/virtio/maru_virtio_tablet.c
+++ b/tizen/src/hw/virtio/maru_virtio_tablet.c
@@ -148,9 +148,7 @@ static void maru_tablet_bh(void *opaque)
qemu_mutex_unlock(&vt->mutex);
/* Get a queue buffer which is written by guest side. */
- do {
- elem = virtqueue_pop(vt->vq, sizeof(VirtQueueElement));
- } while (elem);
+ elem = virtqueue_pop(vt->vq, sizeof(VirtQueueElement));
qemu_mutex_lock(&vt->mutex);
while (!QTAILQ_EMPTY(&events_queue)) {
@@ -160,10 +158,10 @@ static void maru_tablet_bh(void *opaque)
/* copy event into virtio buffer */
len = iov_from_buf(elem->in_sg, elem->in_num, push_len,
&(event_entry->tablet), sizeof(EmulTabletEvent));
- if(len != sizeof(EmulTabletEvent)) {
+ if (len != sizeof(EmulTabletEvent)) {
LOG_WARNING("len != sizeof(EmulTabletEvent).\n");
LOG_WARNING("len: %zu, sizeof(EmulTabletEvent): %zu\n",
- len, sizeof(EmulTabletEvent));
+ len, sizeof(EmulTabletEvent));
}
push_len += sizeof(EmulTabletEvent);
diff --git a/tizen/src/ui/displaybase.cpp b/tizen/src/ui/displaybase.cpp
index 80b8b9b9e1..1daff0677c 100644
--- a/tizen/src/ui/displaybase.cpp
+++ b/tizen/src/ui/displaybase.cpp
@@ -110,21 +110,22 @@ void DisplayBase::showOffGuideImg()
{
offGuideShown = true;
- offGuide = new QLabel(win);
- offGuide->setAttribute(Qt::WA_DeleteOnClose);
- offGuide->setStyleSheet(
- "background-color: black; border-style: none;");
- offGuide->setAlignment(Qt::AlignCenter);
-
- offGuide->setGeometry(getGeometry());
- offGuide->setPixmap(offGuideImg.scaled(
- getGeometry().width(), getGeometry().height(),
- Qt::KeepAspectRatio, Qt::SmoothTransformation));
-
- if (maskImage.size() != QSize(0, 0)) {
- offGuide->setMask(maskImage.scaled(
- maskImage.width() * scaleFactor,
- maskImage.height() * scaleFactor).mask());
+ if (!offGuide) {
+ offGuide = new QLabel(win);
+ offGuide->setStyleSheet(
+ "background-color: black; border-style: none;");
+ offGuide->setAlignment(Qt::AlignCenter);
+
+ offGuide->setGeometry(getGeometry());
+ offGuide->setPixmap(offGuideImg.scaled(
+ getGeometry().width(), getGeometry().height(),
+ Qt::KeepAspectRatio, Qt::SmoothTransformation));
+
+ if (maskImage.size() != QSize(0, 0)) {
+ offGuide->setMask(maskImage.scaled(
+ maskImage.width() * scaleFactor,
+ maskImage.height() * scaleFactor).mask());
+ }
}
offGuide->show();
@@ -134,7 +135,6 @@ void DisplayBase::hideOffGuideImg()
{
if (offGuide != NULL) {
offGuide->close();
- offGuide = NULL;
}
offGuideShown = false;
diff --git a/tizen/src/ui/displayswwidget.cpp b/tizen/src/ui/displayswwidget.cpp
index 3880f7deb1..ec149a5c9f 100644
--- a/tizen/src/ui/displayswwidget.cpp
+++ b/tizen/src/ui/displayswwidget.cpp
@@ -40,11 +40,11 @@ DisplaySWWidget::DisplaySWWidget(QWidget *parent,
DisplayType *displayForm, QSize resolution, qreal scaleFactor) :
QLabel(parent), DisplayBase(displayForm, resolution, scaleFactor, this)
{
- /* fill the screen with black surface */
+ /* fill the screen with black(with full alpha) surface */
QPixmap initImage(
displayForm->getRect().width() * scaleFactor,
displayForm->getRect().height() * scaleFactor);
- initImage.fill(Qt::black);
+ initImage.fill(QColor(0, 0, 0, 255));
setPixmap(initImage);
/* to be enable to drop events */
setAcceptDrops(true);
diff --git a/tizen/src/ui/input/keyboardshortcut.cpp b/tizen/src/ui/input/keyboardshortcut.cpp
index c14f2cfdb6..a5f598c8a3 100644
--- a/tizen/src/ui/input/keyboardshortcut.cpp
+++ b/tizen/src/ui/input/keyboardshortcut.cpp
@@ -87,11 +87,10 @@ void KeyboardShortcut::registerHwKeyShortcuts(QList<HardwareKey *> &list)
void KeyboardShortcut::cancelHwKeyShortcuts(QList<HardwareKey *> &list)
{
for (int index = 0; index < list.count(); index++) {
- delete hwKeyShortcutMap.value(list.at(index));
- hwKeyShortcutMap.remove(list.at(index));
+ delete hwKeyShortcutMap.take(list.at(index));
}
- qDebug() << hwKeyShortcutMap.count() << "shortcuts have been registered";
+ qDebug() << hwKeyShortcutMap.count() << "shortcuts have been unregistered";
}
void KeyboardShortcut::slotHwKeyShortcut(int keycode)
diff --git a/tizen/src/ui/mainwindow.cpp b/tizen/src/ui/mainwindow.cpp
index 8667059807..54f441d46b 100644
--- a/tizen/src/ui/mainwindow.cpp
+++ b/tizen/src/ui/mainwindow.cpp
@@ -67,6 +67,8 @@ MainWindow::MainWindow(UiInformation *uiInfo, QWidget *parent) :
this->captureRequestData = NULL;
this->movingWidget = NULL;
+ this->isMovingMode = false;
+
/* windowing */
setWindowTitle(EMULATOR_TITLE);
setWindowIcon(QIcon(":/icons/emulator_icon.ico"));
@@ -97,7 +99,7 @@ MainWindow::MainWindow(UiInformation *uiInfo, QWidget *parent) :
}
/* display */
- updateDisplayMatrix();
+ updateDisplayTransform();
display = createDisplay(uiInfo->getMainFormDpyType());
/* set HW Key shortcut */
@@ -211,9 +213,9 @@ UIState *MainWindow::getUiState()
return uiInfo->getUiState();
}
-const QMatrix &MainWindow::getDisplayMatrix()
+const QTransform &MainWindow::getDisplayTransform()
{
- return dpyMatrix;
+ return dpyTransform;
}
MainView *MainWindow::getMainView()
@@ -412,12 +414,12 @@ void MainWindow::setMask(const QRegion &region)
}
}
-void MainWindow::updateDisplayMatrix()
+void MainWindow::updateDisplayTransform()
{
- dpyMatrix.reset();
- dpyMatrix.scale(
+ dpyTransform.reset();
+ dpyTransform.scale(
getUiState()->getScaleFactor(), getUiState()->getScaleFactor());
- dpyMatrix.rotate(uiInfo->getMainFormDpyType()->getAngle());
+ dpyTransform.rotate(uiInfo->getMainFormDpyType()->getAngle());
}
void MainWindow::switchForm(int index)
@@ -436,7 +438,7 @@ void MainWindow::switchForm(int index)
/* register new HW key shortcuts */
keyboardShortcut->registerHwKeyShortcuts(uiInfo->getMainForm()->getKeyList());
- updateDisplayMatrix();
+ updateDisplayTransform();
if (getDockingCon() != NULL) {
getDockingCon()->updateGeometry();
@@ -467,7 +469,7 @@ void MainWindow::scaleForm(int scale)
/* scale changing */
getUiState()->setScalePct(scale);
- updateDisplayMatrix();
+ updateDisplayTransform();
if (getDockingCon() != NULL) {
getDockingCon()->updateGeometry();
@@ -518,9 +520,12 @@ void MainWindow::processCaptured(bool captured, void *pixels,
if (captured) {
qDebug("save captured image: %p", pixels);
-
- QImage image = QImage((uchar *)pixels, width, height, QImage::Format_RGB32);
- QPixmap pixmap = QPixmap::fromImage(image); /* deep copy the data */
+ // pixels's format is ARGB32
+ QImage image =
+ QImage((uchar *)pixels, width, height, QImage::Format_ARGB32);
+ // deep copy from image & set all alpha channel value to 0xFF
+ QPixmap pixmap =
+ QPixmap::fromImage(image.convertToFormat(QImage::Format_RGB32));
QMetaObject::invokeMethod(popupMenu, "slotShowScreenshot",
Qt::QueuedConnection, Q_ARG(QPixmap, pixmap));
@@ -528,6 +533,8 @@ void MainWindow::processCaptured(bool captured, void *pixels,
qDebug("save blank image");
QPixmap pixmap(uiInfo->getResolution().width(), uiInfo->getResolution().height());
+ // fill the uninitialized buffer of the pixmap with 0xFF000000
+ pixmap.fill(QColor(0, 0, 0, 255));
QMetaObject::invokeMethod(popupMenu, "slotShowScreenshot",
Qt::QueuedConnection, Q_ARG(QPixmap, pixmap));
}
@@ -556,12 +563,17 @@ void MainWindow::turnOnMovingMode()
{
qDebug("enter the moving mode");
+ if (isMovingMode) {
+ return;
+ }
+
getDisplay()->turnOnMovingMode();
- if (isMovingMode() == false) {
+ if (movingWidget == NULL) {
movingWidget = new MovingWidget(this);
}
+ isMovingMode = true;
movingWidget->show();
}
@@ -569,17 +581,14 @@ void MainWindow::turnOffMovingMode()
{
qDebug("leave the moving mode");
- getDisplay()->turnOffMovingMode();
-
- if (isMovingMode() == true) {
- movingWidget->close();
- movingWidget = NULL;
+ if (!isMovingMode) {
+ return;
}
-}
-bool MainWindow::isMovingMode()
-{
- return (movingWidget != NULL);
+ getDisplay()->turnOffMovingMode();
+
+ movingWidget->close();
+ isMovingMode = false;
}
/* override */
@@ -599,17 +608,29 @@ void MainWindow::closeEvent(QCloseEvent *event)
}
}
-MainWindow::~MainWindow()
+QMessageBox *MainWindow::showMsgBox(
+ QMessageBox::Icon iconType, const QString &text,
+ QMessageBox::StandardButtons buttons,
+ QMessageBox::StandardButton defaultButton)
{
- qDebug("destroy main window");
+ qWarning() << text;
- if (popupMenu) {
- delete popupMenu;
- popupMenu = NULL;
+ QMessageBox *msgBox = new QMessageBox(iconType,
+ EMULATOR_TITLE, text, buttons, this);
+ if (defaultButton != QMessageBox::NoButton) {
+ msgBox->setDefaultButton(defaultButton);
}
+ msgBox->setAttribute(Qt::WA_DeleteOnClose);
+ msgBox->show(); /* non-blocking */
- if (rotary != NULL) {
- delete rotary;
- rotary = NULL;
- }
+#ifdef CONFIG_LINUX
+ popupMenu->slotOnTop(getUiState()->isOnTop());
+#endif
+
+ return msgBox;
+}
+
+MainWindow::~MainWindow()
+{
+ qDebug("destroy main window");
}
diff --git a/tizen/src/ui/mainwindow.h b/tizen/src/ui/mainwindow.h
index 183aeb337c..cd90e7395f 100644
--- a/tizen/src/ui/mainwindow.h
+++ b/tizen/src/ui/mainwindow.h
@@ -53,19 +53,24 @@ class MainWindow : public QWidget
Q_OBJECT
public:
+ bool isMovingMode;
+
explicit MainWindow(UiInformation *uiInfo, QWidget *parent = 0);
~MainWindow();
UiInformation *getUiInfo(void);
UIState *getUiState(void);
- const QMatrix &getDisplayMatrix();
+ const QTransform &getDisplayTransform();
MainView *getMainView();
ContextMenu *getPopupMenu();
DisplayBase *getDisplay();
KeyboardShortcut *getKeyboardShortcut();
QLabel *getScreenWidget();
+ QMessageBox *showMsgBox(QMessageBox::Icon iconType, const QString &text,
+ QMessageBox::StandardButtons buttons = QMessageBox::NoButton,
+ QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
- void updateDisplayMatrix();
+ void updateDisplayTransform();
void switchForm(int angle);
void scaleForm(int scale);
void capture(void);
@@ -84,7 +89,6 @@ public:
void turnOnMovingMode();
void turnOffMovingMode();
- bool isMovingMode();
public slots:
void slotContextMenu(const QPoint &pos);
@@ -105,7 +109,7 @@ private:
UiInformation *uiInfo;
/* windowing */
- QMatrix dpyMatrix;
+ QTransform dpyTransform;
QGraphicsScene *mainScene;
MainView *mainView;
DisplayBase *display;
diff --git a/tizen/src/ui/menu/aboutdialog.cpp b/tizen/src/ui/menu/aboutdialog.cpp
index 491eef6ed2..b956dd83ad 100644
--- a/tizen/src/ui/menu/aboutdialog.cpp
+++ b/tizen/src/ui/menu/aboutdialog.cpp
@@ -30,12 +30,17 @@
#include "aboutdialog.h"
#include "resource/ui_strings.h"
#include "build_info.h"
+#include "mainwindow.h"
+#include "emul_state.h"
AboutDialog::AboutDialog(QWidget *parent) :
QDialog(parent, Qt::Dialog | Qt::WindowStaysOnTopHint)
{
setWindowTitle(ABOUT_TITLE);
+ // remove ? button
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
QVBoxLayout *baseLayout = new QVBoxLayout(this);
baseLayout->setMargin(0);
baseLayout->setSpacing(5);
@@ -56,6 +61,9 @@ AboutDialog::AboutDialog(QWidget *parent) :
}
upsideLayout->addWidget(imageLabel);
+ /* Emulator platform version*/
+ QString platformVersion = QString(get_platform_version()).section('-', 1).trimmed();
+
/* SDK version */
QString versionFilePath = QDir(QCoreApplication::applicationDirPath() +
QDir::separator() + SDK_ROOT_PATH + SDK_VERSION_FILE).absolutePath();
@@ -90,7 +98,7 @@ AboutDialog::AboutDialog(QWidget *parent) :
*/
QString aboutText =
- "<b>" + QString(EMULATOR_TITLE) + " for " + EMULATOR_BUILD_VER + "</b><p>" +
+ "<b>" + QString(EMULATOR_TITLE) + " for " + platformVersion + "</b><p>" +
ABOUT_SDK_VERSION_TEXT + " : " + sdkVer + "<br>" +
ABOUT_PKG_VERSION_TEXT + " : " + pkgVer + "<br>" +
/* "Snapshot : " + SnapshotName + "<br>" + */
diff --git a/tizen/src/ui/menu/contextmenu.cpp b/tizen/src/ui/menu/contextmenu.cpp
index cf60abdc21..0c0c348f9d 100644
--- a/tizen/src/ui/menu/contextmenu.cpp
+++ b/tizen/src/ui/menu/contextmenu.cpp
@@ -925,12 +925,12 @@ void ContextMenu::slotShell()
QFileInfo sdbFileInfo(sdbPath);
if (sdbFileInfo.exists() == false) {
- showMsgBox(QMessageBox::Warning, MSG_SDB_NOT_EXIST + sdbPath);
+ parent->showMsgBox(QMessageBox::Warning, MSG_SDB_NOT_EXIST + sdbPath);
return;
}
if (!is_sdb_daemon_initialized()) {
- showMsgBox(QMessageBox::Warning, MSG_SDB_NOT_READY);
+ parent->showMsgBox(QMessageBox::Warning, MSG_SDB_NOT_READY);
return;
}
@@ -941,21 +941,19 @@ void ContextMenu::slotShell()
void ContextMenu::launchControlPanel(QString& command,
QStringList& arguments)
{
- QString httpProxyAddr;
- QString httpProxyPort;
- const char *http_proxy_addr = get_http_proxy_addr();
- if (http_proxy_addr) {
- char **proxy = g_strsplit(http_proxy_addr, ":", 2);
+ const char *https_proxy_addr = get_https_proxy_addr();
+ if (https_proxy_addr) {
+ char **proxy = g_strsplit(https_proxy_addr, ":", 2);
if (proxy[0] && proxy[1]) {
- httpProxyAddr = "-Dhttp.proxyHost=" + QString(proxy[0]);
- httpProxyPort = "-Dhttp.proxyPort=" + QString(proxy[1]);
+ QString httpsProxyAddr = "-Dhttps.proxyHost=" + QString(proxy[0]);
+ QString httpsProxyPort = "-Dhttps.proxyPort=" + QString(proxy[1]);
+ if (httpsProxyAddr != NULL && httpsProxyPort != NULL) {
+ arguments << httpsProxyAddr << httpsProxyPort;
+ }
}
g_strfreev(proxy);
}
- if (httpProxyAddr != NULL && httpProxyPort != NULL) {
- arguments << httpProxyAddr << httpProxyPort;
- }
QString loggingCommand = QString("launching ecp: \"" + command + "\"");
@@ -973,7 +971,7 @@ void ContextMenu::launchControlPanel(QString& command,
try {
QProcess::startDetached(command, arguments, workingDir);
} catch (QString &error) {
- showMsgBox(QMessageBox::Warning, MSG_INVALID_ECP_OPEN + error);
+ parent->showMsgBox(QMessageBox::Warning, MSG_INVALID_ECP_OPEN + error);
return;
}
#else
@@ -999,7 +997,7 @@ void ContextMenu::launchControlPanel(QString& command,
QString error = QString::number(GetLastError());
qWarning() << qPrintable(QString("error occured during launching \
ECP: ") + error);
- showMsgBox(QMessageBox::Warning, MSG_INVALID_ECP_OPEN + error);
+ parent->showMsgBox(QMessageBox::Warning, MSG_INVALID_ECP_OPEN + error);
}
CloseHandle(pinfo.hThread);
@@ -1015,18 +1013,28 @@ void ContextMenu::slotControlPanel()
QStringList arguments;
// check for new ECP
-#ifndef CONFIG_WIN32
- QString newCommand = QDir(QCoreApplication::applicationDirPath() +
+#if defined(CONFIG_WIN32)
+ QString ecpCommand = QDir(QCoreApplication::applicationDirPath() +
+ QDir::separator() + SDK_EMULATOR_TOOLS_BIN_PATH +
+ SDK_ECP_FILE + ".cmd").absolutePath();
+#elif defined(CONFIG_LINUX)
+ QString ecpCommand = QDir(QCoreApplication::applicationDirPath() +
QDir::separator() + SDK_EMULATOR_TOOLS_BIN_PATH +
SDK_ECP_FILE).absolutePath();
#else
- QString newCommand = QDir(QCoreApplication::applicationDirPath() +
+ QString ecpCommand = QDir(QCoreApplication::applicationDirPath() +
QDir::separator() + SDK_EMULATOR_TOOLS_BIN_PATH +
- SDK_ECP_FILE + ".cmd").absolutePath();
+ SDK_ECP_FILE + ".app").absolutePath();
+#endif
+ if (QFileInfo(ecpCommand).exists()) {
+#if defined(CONFIG_DARWIN)
+ // In mac os x, launch .app using "open" command
+ // ex : open emulator-control-panel.app --args vm_name=... platform_version=...
+ command = "open";
+ arguments << ecpCommand << "--args";
+#else
+ command = ecpCommand;
#endif
- if (QFileInfo(newCommand).exists()) {
- command = newCommand;
-
QString vmNameOpt = "vm_name=" + parent->getUiInfo()->getVmName();
QString platformVersionOpt = "platform_version=" +
QString::fromLocal8Bit(get_platform_version());
@@ -1061,7 +1069,7 @@ void ContextMenu::slotControlPanel()
command = QString::fromLocal8Bit(path);
} else {
// can not enter here...
- showMsgBox(QMessageBox::Warning, MSG_INVALID_JAVA_PATH);
+ parent->showMsgBox(QMessageBox::Warning, MSG_INVALID_JAVA_PATH);
return;
}
@@ -1088,7 +1096,7 @@ void ContextMenu::slotControlPanel()
}
// we can not launch ControlPanel
- showMsgBox(QMessageBox::Warning, MSG_ECP_NOT_EXIST);
+ parent->showMsgBox(QMessageBox::Warning, MSG_ECP_NOT_EXIST);
return;
}
@@ -1204,37 +1212,10 @@ QSignalMapper *ContextMenu::getControllerMapper()
return controllerMapper;
}
-QMessageBox *ContextMenu::showMsgBox(
- QMessageBox::Icon iconType, const QString &text,
- QMessageBox::StandardButtons buttons,
- QMessageBox::StandardButton defaultButton)
-{
- qWarning() << text;
-
- QMessageBox *msgBox = new QMessageBox(iconType,
- EMULATOR_TITLE, text, buttons, parent);
- if (defaultButton != QMessageBox::NoButton) {
- msgBox->setDefaultButton(defaultButton);
- }
- msgBox->setAttribute(Qt::WA_DeleteOnClose);
- msgBox->show(); /* non-blocking */
-
-#ifdef CONFIG_LINUX
- slotOnTop(parent->getUiState()->isOnTop());
-#endif
-
- return msgBox;
-}
-
ContextMenu::~ContextMenu()
{
qDebug("destroy menu");
- if (infoDialog) {
- delete infoDialog;
- infoDialog = NULL;
- }
-
delete sdbHelper;
longPressTimer->stop();
diff --git a/tizen/src/ui/menu/contextmenu.h b/tizen/src/ui/menu/contextmenu.h
index 88370a483d..f8518de322 100644
--- a/tizen/src/ui/menu/contextmenu.h
+++ b/tizen/src/ui/menu/contextmenu.h
@@ -128,10 +128,6 @@ private:
const QString &text, QShortcut *shortcut, const char *slot);
void attachShortcut(QAction *action, QShortcut *shortcut, const char *slot);
- QMessageBox *showMsgBox(QMessageBox::Icon iconType, const QString &text,
- QMessageBox::StandardButtons buttons = QMessageBox::NoButton,
- QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
-
MainWindow *parent;
QString vmName;
DetailedInfoDialog *infoDialog;
diff --git a/tizen/src/ui/menu/detailedinfodialog.cpp b/tizen/src/ui/menu/detailedinfodialog.cpp
index 7f404902fa..cbf6640552 100644
--- a/tizen/src/ui/menu/detailedinfodialog.cpp
+++ b/tizen/src/ui/menu/detailedinfodialog.cpp
@@ -34,6 +34,7 @@
#include "resource/ui_strings.h"
#include "mainwindow.h"
#include "menu/advancedmenuitem.h"
+#include "emul_state.h"
extern "C" {
int get_display_pixel_density(void);
@@ -54,6 +55,9 @@ DetailedInfoDialog::DetailedInfoDialog(QWidget *parent) :
win = ((MainWindow *)parent);
keyboardShortcut = win->getKeyboardShortcut();
+ // remove ? button
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
setWindowTitle(DETAILED_INFO_TITLE);
setMinimumWidth(DIALOG_MIN_WIDTH);
setMinimumHeight(DIALOG_MIN_HEIGHT);
@@ -73,8 +77,10 @@ DetailedInfoDialog::DetailedInfoDialog(QWidget *parent) :
/* VM information table */
vmInfoTable = createVmInfoTable();
tabWidget->addTab(vmInfoTable, tr(DETAILED_INFO_VMTAB_TITLE));
-
+// FIXME: temporarily remove shortcut dialog in DARWIN
+#ifndef CONFIG_DARWIN
/* shortcut information table */
+
QTabWidget *shortcutTab = new QTabWidget(tabWidget);
menuShortcutTable = createShortcutInfoTable();
@@ -83,6 +89,8 @@ DetailedInfoDialog::DetailedInfoDialog(QWidget *parent) :
shortcutTab->addTab(keyShortcutTable, "HW Key");
tabWidget->addTab(shortcutTab, DETAILED_INFO_SHORTCUTTAB_TITLE);
+#endif
+
}
upsideLayout->addWidget(tabWidget);
@@ -195,7 +203,7 @@ QTableWidget *DetailedInfoDialog::createVmInfoTable()
}
QString pkgVer = QString(pkginfo_version).section(':', 1).trimmed();
- insertTableRow(vmInfo, QString(DETAILED_INFO_EMUL_VER), QString(EMULATOR_BUILD_VER) +
+ insertTableRow(vmInfo, QString(DETAILED_INFO_EMUL_VER), QString(get_platform_version()).section('-', 1).trimmed() +
" Release on " + sdkVer + " SDK (" + pkgVer + ")");
/* add double click event listener */
@@ -319,7 +327,10 @@ void DetailedInfoDialog::insertHwKeyShortcutInfo(
/* override */
void DetailedInfoDialog::showEvent(QShowEvent *event)
{
+// FIXME: temporarily remove shortcut dialog in DARWIN
+#ifndef CONFIG_DARWIN
updateShortcutTableItems();
+#endif
if ((windowState() & Qt::WindowMaximized) == 0) {
tabWidget->setCurrentIndex(0);
diff --git a/tizen/src/ui/menu/screenshotdialog.cpp b/tizen/src/ui/menu/screenshotdialog.cpp
index b41798c905..42505d07ae 100644
--- a/tizen/src/ui/menu/screenshotdialog.cpp
+++ b/tizen/src/ui/menu/screenshotdialog.cpp
@@ -231,14 +231,12 @@ void ScreenShotDialog::updateRatio(int level)
void ScreenShotDialog::updateScreenShot(QPixmap &shotData)
{
- /* scaling */
- QPixmap shotImage = shotData.scaled(shotData.size() * ratio,
- Qt::KeepAspectRatio, Qt::FastTransformation);
-
- /* rotate */
- QMatrix matrix;
- matrix.rotate(getDisplayAngle());
- shotImage = shotImage.transformed(matrix);
+ /* scaling & rotate */
+ QTransform transform;
+ QPixmap shotImage =
+ shotData.transformed(
+ transform.scale(ratio, ratio).rotate(getDisplayAngle()),
+ Qt::SmoothTransformation);
/* update */
scene->setSceneRect(0, 0, shotImage.width(), shotImage.height());
@@ -277,6 +275,4 @@ void ScreenShotDialog::showEvent(QShowEvent *event)
ScreenShotDialog::~ScreenShotDialog()
{
qDebug("destroy screenshot dialog");
-
- win->getPopupMenu()->screenshotDialog = NULL;
}
diff --git a/tizen/src/ui/menu/sdbhelper.cpp b/tizen/src/ui/menu/sdbhelper.cpp
index 742966ffb2..c1da058892 100644
--- a/tizen/src/ui/menu/sdbhelper.cpp
+++ b/tizen/src/ui/menu/sdbhelper.cpp
@@ -30,6 +30,7 @@
#include "config-host.h"
#include "mainwindow.h"
+#include "displaybase.h"
#include "sdbhelper.h"
#include "sdbhelperthread.h"
#include "resource/ui_strings.h"
diff --git a/tizen/src/ui/menu/sdbhelperthread.cpp b/tizen/src/ui/menu/sdbhelperthread.cpp
index 2c0389ec6f..dec4171205 100644
--- a/tizen/src/ui/menu/sdbhelperthread.cpp
+++ b/tizen/src/ui/menu/sdbhelperthread.cpp
@@ -28,6 +28,7 @@
*/
#include "sdbhelperthread.h"
+#include "mainwindow.h"
#include "sdbhelper.h"
#include "displaybase.h"
#include "resource/ui_strings.h"
@@ -82,24 +83,5 @@ void SdbHelperThread::handleErrorOccured(QString errString, int exitCode)
{
qDebug() << "exitcode: " << exitCode;
//FIXME: (sdb) cannot returns exit code like "no space left"
- showMsgBox(QMessageBox::Warning, MSG_SDB_FAILED_PROCESSING + errString);
-}
-
-QMessageBox *SdbHelperThread::showMsgBox(
- QMessageBox::Icon iconType, const QString &text,
- QMessageBox::StandardButtons buttons,
- QMessageBox::StandardButton defaultButton)
-{
- qWarning() << text;
-
- QMessageBox *msgBox = new QMessageBox(iconType,
- EMULATOR_TITLE, text, buttons, (QWidget *)parent->getMainWindow());
- if (defaultButton != QMessageBox::NoButton) {
- msgBox->setDefaultButton(defaultButton);
- }
- msgBox->setAttribute(Qt::WA_DeleteOnClose);
- msgBox->setModal(false);
- msgBox->show(); /* non-blocking */
-
- return msgBox;
+ ((MainWindow *)parent->getMainWindow())->showMsgBox(QMessageBox::Warning, MSG_SDB_FAILED_PROCESSING + errString);
}
diff --git a/tizen/src/ui/menu/sdbhelperthread.h b/tizen/src/ui/menu/sdbhelperthread.h
index 5cdfcfc389..162ce1813a 100644
--- a/tizen/src/ui/menu/sdbhelperthread.h
+++ b/tizen/src/ui/menu/sdbhelperthread.h
@@ -53,9 +53,6 @@ private:
int command;
QString errorMsg;
QString outMsg;
- QMessageBox *showMsgBox(QMessageBox::Icon iconType, const QString &text,
- QMessageBox::StandardButtons buttons = QMessageBox::NoButton,
- QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
signals:
void errorOccured(QString errString, int exitCode);
diff --git a/tizen/src/ui/movingwidget.cpp b/tizen/src/ui/movingwidget.cpp
index e3daff486a..669da8fe36 100644
--- a/tizen/src/ui/movingwidget.cpp
+++ b/tizen/src/ui/movingwidget.cpp
@@ -43,7 +43,6 @@ MovingWidget::MovingWidget(QWidget *parent) : QWidget(parent)
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_TranslucentBackground);
- setAttribute(Qt::WA_DeleteOnClose);
resize(win->size());
qDebug() << "moving widget size:" << win->size();
diff --git a/tizen/src/ui/qt5.c b/tizen/src/ui/qt5.c
index cb934524d5..0b19be65bd 100644
--- a/tizen/src/ui/qt5.c
+++ b/tizen/src/ui/qt5.c
@@ -156,7 +156,8 @@ void maru_early_qt5_display_init(bool isOnscreen)
}
}
-static void maru_qt5_display_fini(void)
+// should be called before exit main()
+void maru_qt5_display_fini(void)
{
if (qt5_console) {
g_free(qt5_console);
@@ -177,6 +178,11 @@ int get_display_pixel_density(void)
return pixel_density_dpi;
}
+void maru_qt5_set_force_legacy(bool isLegacy)
+{
+ qt5_set_force_legacy(isLegacy);
+}
+
void maru_qt5_display_init(DisplayState *ds, int full_screen)
{
int i;
@@ -207,7 +213,6 @@ void maru_qt5_display_init(DisplayState *ds, int full_screen)
if (full_screen) {
/* TODO */
}
- atexit(maru_qt5_display_fini);
/* TODO
mouse_mode_notifier.notify = qt2_mouse_mode_change;
diff --git a/tizen/src/ui/qt5.h b/tizen/src/ui/qt5.h
index 64f2d4042a..226ea3759d 100644
--- a/tizen/src/ui/qt5.h
+++ b/tizen/src/ui/qt5.h
@@ -36,8 +36,11 @@
void maru_early_qt5_display_init(bool isOnscreen);
void maru_qt5_display_init(DisplayState *ds, int full_screen);
+void maru_qt5_display_fini(void);
void set_display_pixel_density(int dpi);
int get_display_pixel_density(void);
+void maru_qt5_set_force_legacy(bool isLegacy);
+
#endif // __QT5_H__
diff --git a/tizen/src/ui/qt5_supplement.cpp b/tizen/src/ui/qt5_supplement.cpp
index 639b9dac74..81202fe124 100644
--- a/tizen/src/ui/qt5_supplement.cpp
+++ b/tizen/src/ui/qt5_supplement.cpp
@@ -54,6 +54,7 @@ bool is_display_off(void);
//using namespace std;
bool qt5IsOnscreen;
QApplication *qt5App = NULL;
+bool isForceLegacy;
static int argc = 0;
static char *argv[0];
@@ -181,6 +182,7 @@ static void qMessageOutput(QtMsgType type, const QMessageLogContext &context,
case QtCriticalMsg:
case QtFatalMsg:
typeChar = 'S';
+ break;
default:
qFatal("invalid message type");
break;
@@ -442,23 +444,17 @@ void qt5_destroy()
uiInfo = NULL;
}
+void qt5_set_force_legacy(bool isLegacy)
+{
+ isForceLegacy = isLegacy;
+}
+
void qt5_early_prepare(bool isOnscreen)
{
qt5IsOnscreen = isOnscreen;
Q_INIT_RESOURCE(resource);
-#ifdef CONFIG_LINUX
- /* QGLWidget threading: Note that under X11 it is necessary to set the
- * Qt::AA_X11InitThreads application attribute to make the X11 library
- * and GLX calls thread safe, otherwise the above scenarios will fail. */
-
- /* Calls XInitThreads() as part of the QApplication construction in order
- * to make Xlib calls thread-safe. This attribute must be set before
- * QApplication is constructed. */
- QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
-#endif
-
qt5App = new QApplication(argc, argv);
/* add the path in the application's main() function, right after the
@@ -482,11 +478,11 @@ void qt5_prepare(void)
void qt5_update_internal(void *data, int width, int height)
{
- QImage image((uchar *)data, width, height, QImage::Format_RGB32);
+ QImage image((uchar *)data, width, height, QImage::Format_ARGB32);
- mainwindow->getScreenWidget()->setPixmap(
- QPixmap::fromImage(image.transformed(
- mainwindow->getDisplayMatrix(), Qt::SmoothTransformation)));
+ mainwindow->getScreenWidget()->setPixmap(QPixmap::fromImage(
+ image.convertToFormat(QImage::Format_RGB32).transformed(
+ mainwindow->getDisplayTransform(), Qt::SmoothTransformation)));
}
void qt5_switch_internal(void)
diff --git a/tizen/src/ui/qt5_supplement.h b/tizen/src/ui/qt5_supplement.h
index 836af47ce9..dbdcd06be2 100644
--- a/tizen/src/ui/qt5_supplement.h
+++ b/tizen/src/ui/qt5_supplement.h
@@ -46,6 +46,8 @@ void qt5_switch_internal(void);
void qt5_refresh_internal(void);
const char* qt5_get_version(void);
+
+void qt5_set_force_legacy(bool isLegacy);
#ifdef __cplusplus
}
#endif
diff --git a/tizen/src/ui/resource/ui_strings.h b/tizen/src/ui/resource/ui_strings.h
index 65566ffcf8..3a5c3afa5c 100644
--- a/tizen/src/ui/resource/ui_strings.h
+++ b/tizen/src/ui/resource/ui_strings.h
@@ -33,7 +33,6 @@
#define UI_STRINGS_H
#define EMULATOR_TITLE "Tizen Emulator"
-#define EMULATOR_BUILD_VER "3.0"
#define SDK_OFFICIAL_NAME "Tizen SDK"
#define SDK_OFFICIAL_URL "https://developer.tizen.org"
diff --git a/tizen/src/ui/rotaryview.cpp b/tizen/src/ui/rotaryview.cpp
index 3297f3fc34..fdb6816d7f 100644
--- a/tizen/src/ui/rotaryview.cpp
+++ b/tizen/src/ui/rotaryview.cpp
@@ -193,6 +193,4 @@ RotaryView::~RotaryView()
qDebug("destroy rotary view");
timer->stop();
-
- scene()->clear();
}
diff --git a/tizen/src/ui/skinpainter.cpp b/tizen/src/ui/skinpainter.cpp
index 0dac529d34..2c2bb3d3dc 100644
--- a/tizen/src/ui/skinpainter.cpp
+++ b/tizen/src/ui/skinpainter.cpp
@@ -88,12 +88,11 @@ void SkinPainter::drawSkin(QString patchPath, QSize center, int degree,
painter.drawEllipse(tagLeftTop, COLOR_TAG_SIZE, COLOR_TAG_SIZE);
/* rotate */
- QMatrix matrix;
- matrix.rotate(degree);
- skin = new QPixmap(image.transformed(matrix));
+ QTransform transform;
+ skin = new QPixmap(image.transformed(transform.rotate(degree)));
centeralRect = QRect(
- centeralRect0.topLeft(), matrix.mapRect(centeralRect0).size());
+ centeralRect0.topLeft(), transform.mapRect(centeralRect0).size());
}
QImage SkinPainter::getSkinImage() const
diff --git a/tizen/src/util/Makefile.objs b/tizen/src/util/Makefile.objs
index a4a2969fcc..a322caf7d7 100644
--- a/tizen/src/util/Makefile.objs
+++ b/tizen/src/util/Makefile.objs
@@ -30,6 +30,9 @@ obj-y += qt5_error_report.o
# error handler
obj-y += error_handler.o
+ifdef CONFIG_WIN32
+LIBS += -ldbghelp
+endif
# debug channel
obj-y += new_debug_ch.o
diff --git a/tizen/src/util/error_handler.c b/tizen/src/util/error_handler.c
index 1f91e8df85..959594e83c 100644
--- a/tizen/src/util/error_handler.c
+++ b/tizen/src/util/error_handler.c
@@ -4,6 +4,7 @@
* Copyright (C) 2015 Samsung Electronics Co., Ltd. All rights reserved.
*
* Contact:
+ * Jinhyung Jo <jinhyung.jo@samsung.com>
* SeokYeon Hwang <syeon.hwang@samsung.com>
* GiWoong Kim <giwoong.kim@samsung.com>
*
@@ -37,6 +38,7 @@
#ifdef CONFIG_WIN32
#include <windows.h>
+#include <dbghelp.h>
#else
#include <execinfo.h>
#endif
@@ -47,244 +49,229 @@
#include "emulator_common.h"
#include "emulator.h"
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(qemu, backtrace);
-
#ifdef CONFIG_QT
#include "qt5_error_report.h"
#endif
-#if defined(CONFIG_WIN32)
-static LPTOP_LEVEL_EXCEPTION_FILTER prevExceptionFilter;
-#elif defined(CONFIG_LINUX)
-static pthread_spinlock_t siglock;
-#endif
+#include "new_debug_ch.h"
-bool print_backtrace_at_normal_exit_enabled = false;
+DECLARE_DEBUG_CHANNEL(backtrace);
-/* Print 'backtrace' */
-#ifdef _WIN32
-struct frame_layout {
- void *pNext;
- void *pReturnAddr;
-};
+bool print_backtrace_at_normal_exit_enabled;
-static char *get_filename_from_path(char *path_buf)
+void enable_print_backtrace_at_normal_exit(void)
{
- char *ret_slash;
- char *ret_rslash;
-
- ret_slash = strrchr(path_buf, '/');
- ret_rslash = strrchr(path_buf, '\\');
-
- if (ret_slash || ret_rslash) {
- if (ret_slash > ret_rslash) {
- return ret_slash + 1;
- } else{
- return ret_rslash + 1;
- }
- }
-
- return path_buf;
+ print_backtrace_at_normal_exit_enabled = true;
}
+#ifdef CONFIG_WIN32
+static LPTOP_LEVEL_EXCEPTION_FILTER prevExceptionFilter;
-static HMODULE get_module_handle(void *dwAddress)
-{
- MEMORY_BASIC_INFORMATION Buffer;
- return VirtualQuery((LPCVOID) dwAddress, &Buffer, sizeof(Buffer))
- ? (HMODULE) Buffer.AllocationBase : (HMODULE) 0;
-}
-#endif
-
-static void dump_backtrace(void *ptr, int depth)
+/* The MSDN says as followed in "Updated Platform Support" page,
+ (https://msdn.microsoft.com/en-us/library/windows/desktop/
+ ms681408(v=vs.85).aspx)
+ "Where necessary, the DbgHelp library has been widened to support both 32-
+ and 64-bit Windows. The original function and structure definitions are
+ still in DbgHelp.h, but there are also updated versions of these
+ definitions that are compatible with 64-bit Windows. If you use the updated
+ functions in your code, it can be compiled for both 32- and 64-bit Windows.
+ Your code will also be more efficient, since the original functions simply
+ call the updated functions to perform the work."
+ However, using the updated functinos does not work on the Windows 32-bit.
+ IMHO, in the MinGW cross compile environment rather than the Visual Studio
+ it does not compile correctly.
+ Thus, use explicitly.
+*/
+static void dump_backtrace(void *ptr)
{
-#ifdef _WIN32
- int nCount;
- void *pTopFrame;
- struct frame_layout currentFrame;
- struct frame_layout *pCurrentFrame;
-
- char module_buf[1024];
- HMODULE hModule;
-
- PCONTEXT pContext = ptr;
- if (!pContext) {
- __asm__ __volatile__ ("movl %%ebp, %0" : "=m" (pTopFrame));
- } else {
#ifdef _WIN64
- pTopFrame = (void *)((PCONTEXT)pContext)->Rbp;
+ STACKFRAME64 frame;
#else
- pTopFrame = (void *)((PCONTEXT)pContext)->Ebp;
+ STACKFRAME frame;
#endif
+ int i;
+ DWORD image;
+ CONTEXT context;
+ HANDLE hProcess = GetCurrentProcess();
+ HANDLE hThread = GetCurrentThread();
+
+ if (!ptr) {
+ ZeroMemory(&context, sizeof(CONTEXT));
+ context.ContextFlags = CONTEXT_FULL;
+ RtlCaptureContext(&context);
+ } else {
+ CopyMemory(&context, ptr, sizeof(CONTEXT));
}
- if (pTopFrame == NULL) {
- INFO("ebp is null, skip this for now\n");
- return ;
- }
-
- nCount = 0;
- currentFrame.pNext = ((struct frame_layout *)pTopFrame)->pNext;
- currentFrame.pReturnAddr = ((struct frame_layout *)pTopFrame)->pReturnAddr;
- pCurrentFrame = (struct frame_layout *)pTopFrame;
+ SymInitialize(hProcess, NULL, TRUE);
- ERR("\nBacktrace Dump Start :\n");
- if (pContext) {
- memset(module_buf, 0, sizeof(module_buf));
#ifdef _WIN64
- hModule = get_module_handle((void *)((PCONTEXT)pContext)->Rip);
+ ZeroMemory(&frame, sizeof(STACKFRAME64));
+ image = IMAGE_FILE_MACHINE_AMD64;
+ frame.AddrPC.Offset = context.Rip;
+ frame.AddrPC.Mode = AddrModeFlat;
+ frame.AddrFrame.Offset = context.Rbp;
+ frame.AddrFrame.Mode = AddrModeFlat;
+ frame.AddrStack.Offset = context.Rsp;
+ frame.AddrStack.Mode = AddrModeFlat;
#else
- hModule = get_module_handle((void *)((PCONTEXT)pContext)->Eip);
+ ZeroMemory(&frame, sizeof(STACKFRAME));
+ image = IMAGE_FILE_MACHINE_I386;
+ frame.AddrPC.Offset = context.Eip;
+ frame.AddrPC.Mode = AddrModeFlat;
+ frame.AddrFrame.Offset = context.Ebp;
+ frame.AddrFrame.Mode = AddrModeFlat;
+ frame.AddrStack.Offset = context.Esp;
+ frame.AddrStack.Mode = AddrModeFlat;
#endif
- if (hModule) {
- if (!GetModuleFileNameA(hModule, module_buf, sizeof(module_buf))) {
- memset(module_buf, 0, sizeof(module_buf));
- }
- }
+
+ i = 0;
+ while (1) {
#ifdef _WIN64
- ERR("[%02d]Addr = 0x%p : %s\n", nCount, ((PCONTEXT)pContext)->Rip, get_filename_from_path(module_buf));
+ BOOL result = StackWalk64(image, hProcess, hThread,
+ &frame, &context, NULL,
+ SymFunctionTableAccess64,
+ SymGetModuleBase64, NULL);
#else
- ERR("[%02d]Addr = 0x%p : %s\n", nCount, ((PCONTEXT)pContext)->Eip, get_filename_from_path(module_buf));
+ BOOL result = StackWalk(image, hProcess, hThread,
+ &frame, &context, NULL,
+ SymFunctionTableAccess,
+ SymGetModuleBase, NULL);
#endif
- nCount++;
- }
-
- while (1) {
- if (((void *)pCurrentFrame < pTopFrame)
- || ((void *)pCurrentFrame >= (void *)0xC0000000)) {
+ if (!result) {
break;
}
-
- memset(module_buf, 0, sizeof(module_buf));
- hModule = get_module_handle(currentFrame.pReturnAddr);
- if (hModule) {
- if (!GetModuleFileNameA(hModule, module_buf, sizeof(module_buf))) {
- memset(module_buf, 0, sizeof(module_buf));
- }
- }
- ERR("[%02d]Addr = 0x%p : %s\n", nCount, currentFrame.pReturnAddr, get_filename_from_path(module_buf));
-
- if (!ReadProcessMemory(GetCurrentProcess(), currentFrame.pNext,
- (void *)&currentFrame, sizeof(struct frame_layout), NULL)) {
- break;
- }
- pCurrentFrame = (struct frame_layout *)pCurrentFrame->pNext;
-
- if (depth) {
- if (!--depth) {
- break;
+ TCHAR buffer[sizeof(SYMBOL_INFO) + (MAX_SYM_NAME - 1) * sizeof(TCHAR)];
+ PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
+ pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
+ pSymbol->MaxNameLen = MAX_SYM_NAME;
+ DWORD64 displacement = 0;
+ TCHAR pFileName[MAX_PATH] = {0, };
+#ifdef _WIN64
+ DWORD64 dwBase = SymGetModuleBase64(hProcess, frame.AddrPC.Offset);
+#else
+ DWORD dwBase = SymGetModuleBase(hProcess, frame.AddrPC.Offset);
+#endif
+ if (dwBase) {
+ HMODULE hModule = (HMODULE)((DWORD_PTR)dwBase);
+ if (!GetModuleFileNameA(hModule, pFileName, MAX_PATH)) {
+ snprintf(pFileName, MAX_PATH, "Unknown Module");
}
}
- nCount++;
- }
+ /* TODO: take the symbols for the static functions
+ without import .pdb */
+ if (SymFromAddr(hProcess,
+ frame.AddrPC.Offset,
+ &displacement, pSymbol)) {
+#ifdef _WIN64
+ LOG_INFO("#%04d 0x%016I64x in %s from %s\n",
#else
- void *trace[1024];
- int ndepth = backtrace(trace, 1024);
- ERR("Backtrace depth is %d.\n", ndepth);
-
- backtrace_symbols_fd(trace, ndepth, fileno(stderr));
+ LOG_INFO("#%04d 0x%08x in %s from %s\n",
+#endif
+ i, frame.AddrPC.Offset, pSymbol->Name, pFileName);
+ } else {
+#ifdef _WIN64
+ LOG_INFO("#%04d 0x%016I64x in ???????? from %s\n",
+#else
+ LOG_INFO("#%04d 0x%08x in ???????? from %s\n",
#endif
+ i, frame.AddrPC.Offset, pFileName);
+ }
+ i++;
+ }
+ SymCleanup(hProcess);
}
-static void handle_error_at_exit(void)
+static WINAPI LONG
+maru_unhandled_exception_filter(LPEXCEPTION_POINTERS pException)
{
- if (print_backtrace_at_normal_exit_enabled) {
- INFO("Stack backtrace for tracing...\n");
- INFO("This is not an error.\n");
- dump_backtrace(NULL, 0);
- }
-}
+#ifdef _WIN64
+ LOG_SEVERE("Exception occurred: Code[0x%x], Address[0x%016I64x]\n",
+#else
+ LOG_SEVERE("Exception occurred: Code[0x%x], Address[0x%08x]\n",
+#endif
+ pException->ExceptionRecord->ExceptionCode,
+ pException->ExceptionRecord->ExceptionAddress);
-void enable_print_backtrace_at_normal_exit(void) {
- print_backtrace_at_normal_exit_enabled = true;
-}
+ dump_backtrace(pException->ContextRecord);
-#ifdef CONFIG_WIN32
-static WINAPI LONG maru_unhandled_exception_filter(LPEXCEPTION_POINTERS pExceptionInfo){
- char module_buf[1024];
+ return EXCEPTION_CONTINUE_SEARCH;
+}
- // print system information again
- print_system_info();
+static void register_exception_handler(void)
+{
+ prevExceptionFilter =
+ SetUnhandledExceptionFilter(maru_unhandled_exception_filter);
+}
- DWORD dwException = pExceptionInfo->ExceptionRecord->ExceptionCode;
- ERR("%d\n ", (int)dwException);
+#else /* END FOR WINDOWS, START FOR LINUX & DARWIN */
- PEXCEPTION_RECORD pExceptionRecord;
- HMODULE hModule;
- PCONTEXT pContext;
+/* prevent an interrupt by another signal */
+QemuMutex siglock;
+/* uses in case SIGSEGV */
+struct sigaction old_sa;
- pExceptionRecord = pExceptionInfo->ExceptionRecord;
+/* Print 'backtrace' */
+static void dump_backtrace(void *ptr)
+{
+ int i;
+ void *trace[1024];
+ int ndepth = backtrace(trace, 1024);
+ char **syms = backtrace_symbols(trace, ndepth);
- memset(module_buf, 0, sizeof(module_buf));
- hModule = get_module_handle(pExceptionRecord->ExceptionAddress);
- if(hModule){
- if(!GetModuleFileNameA(hModule, module_buf, sizeof(module_buf))){
- memset(module_buf, 0, sizeof(module_buf));
- }
+ LOG_INFO("Backtrace depth is %d\n", ndepth);
+ for (i = 0; i < ndepth; i++) {
+ LOG_INFO("#%04d %s\n", i, syms[i]);
}
-
- ERR("Exception [%X] occured at %s:0x%08x\n",
- pExceptionRecord->ExceptionCode,
- get_filename_from_path(module_buf),
- pExceptionRecord->ExceptionAddress
- );
-
- pContext = pExceptionInfo->ContextRecord;
- dump_backtrace(pContext, 0);
- _exit(0);
- //return EXCEPTION_CONTINUE_SEARCH;
+ free(syms);
}
-#endif
-#ifdef CONFIG_LINUX
static void maru_sighandler(int sig)
{
- ERR("Got signal %d\n", sig);
- // print system information again
- print_system_info();
-
- pthread_spin_lock(&siglock);
- dump_backtrace(NULL, 0);
- pthread_spin_unlock(&siglock);
- _exit(0);
+ LOG_SEVERE("Got signal: %d(%s)\n", sig, strsignal(sig));
+
+ qemu_mutex_lock(&siglock);
+ dump_backtrace(NULL);
+ qemu_mutex_unlock(&siglock);
+ qemu_mutex_destroy(&siglock);
+ if (sig == SIGSEGV) {
+ sigaction(SIGSEGV, &old_sa, NULL);
+ raise(SIGSEGV);
+ }
}
-#endif
-
-#ifndef CONFIG_DARWIN
static void register_exception_handler(void)
{
- #ifdef CONFIG_WIN32
- prevExceptionFilter = SetUnhandledExceptionFilter(maru_unhandled_exception_filter);
- #else // LINUX
void *trace[1];
struct sigaction sa;
- // make dummy call to explicitly load glibc library
+ /* make dummy call to explicitly load glibc library */
backtrace(trace, 1);
- pthread_spin_init(&siglock,0);
- sa.sa_handler = (void*) maru_sighandler;
+ qemu_mutex_init(&siglock);
+ sa.sa_handler = maru_sighandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
- sigaction(SIGSEGV, &sa, NULL);
+ /* store previous signal action */
+ sigaction(SIGSEGV, &sa, &old_sa);
sigaction(SIGBUS, &sa, NULL);
sigaction(SIGILL, &sa, NULL);
sigaction(SIGFPE, &sa, NULL);
sigaction(SIGABRT, &sa, NULL);
- // main thread only
+ /* main thread only */
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
- #endif
}
-#else // CONFIG_DARWIN
-static void register_exception_handler(void)
+#endif /* END FOR LINUX & DARWIN */
+
+static void handle_error_at_exit(void)
{
- // TODO: Exception handling on darwin
+ if (print_backtrace_at_normal_exit_enabled) {
+ LOG_INFO("Stack backtrace for tracing...\n");
+ LOG_INFO("This is not an error\n");
+ dump_backtrace(NULL);
+ }
}
-#endif
#define MAX_MESSAGE_LEN 2048
static size_t message_len;
@@ -296,9 +283,9 @@ static void report(const char *fmt, va_list ap)
message_len = g_strlcat(message, new_message, MAX_MESSAGE_LEN);
g_free(new_message);
- // We are wating for '\n'
+ /* We are waiting for '\n' */
if (message[message_len - 1] == '\n') {
-#if defined(CONFIG_QT)
+#ifdef CONFIG_QT
start_qt5_msgbox(CRITICAL_ICON, message);
#endif
@@ -307,10 +294,12 @@ static void report(const char *fmt, va_list ap)
}
}
-static ErrorReporter error_reporter =
- { .report = report };
+static ErrorReporter error_reporter = {
+ .report = report
+};
-void init_error_handler(void) {
+void init_error_handler(void)
+{
register_exception_handler();
add_error_reporter(&error_reporter);
diff --git a/tizen/src/util/osutil-darwin.c b/tizen/src/util/osutil-darwin.c
index b27ed7ca24..c797ca8df0 100644
--- a/tizen/src/util/osutil-darwin.c
+++ b/tizen/src/util/osutil-darwin.c
@@ -47,8 +47,8 @@
#include "new_debug_ch.h"
DECLARE_DEBUG_CHANNEL(osutil);
-void make_vm_lock_os(void) {
- make_vm_lock_posix();
+void make_vm_lock_os(gchar *vms_path) {
+ make_vm_lock_posix(vms_path);
}
void set_bin_path_os(char const *const exec_argv)
diff --git a/tizen/src/util/osutil-linux.c b/tizen/src/util/osutil-linux.c
index 8e432f990b..c46e46123f 100644
--- a/tizen/src/util/osutil-linux.c
+++ b/tizen/src/util/osutil-linux.c
@@ -50,8 +50,8 @@
#include "new_debug_ch.h"
DECLARE_DEBUG_CHANNEL(osutil);
-void make_vm_lock_os(void) {
- make_vm_lock_posix();
+void make_vm_lock_os(gchar *vms_path) {
+ make_vm_lock_posix(vms_path);
}
void set_bin_path_os(char const *const exec_argv)
diff --git a/tizen/src/util/osutil-win32.c b/tizen/src/util/osutil-win32.c
index a76edfc2e6..48220da10c 100644
--- a/tizen/src/util/osutil-win32.c
+++ b/tizen/src/util/osutil-win32.c
@@ -83,29 +83,36 @@ image file and kernel log file are aleady opened with exclusive write
lock by pre-executed emulator. But it is still useful for
emulator-manager.
*/
-void make_vm_lock_os(void)
+void make_vm_lock_os(gchar *vms_path)
{
+
g_assert(lock_file == INVALID_HANDLE_VALUE);
g_assert(lock_filename == NULL);
- lock_filename = g_strdup_printf("%s.lock", get_drive_image_file());
+ lock_filename = g_strdup_printf("%s\\%s", vms_path, VMLOCK_FILE);
if (g_mkdir_with_parents(g_path_get_dirname(lock_filename), 0777)) {
LOG_WARNING("Can not create directory for lock file: %ld\n",
GetLastError());
+ // do not create the lock file.
+ g_free(lock_filename);
+ lock_filename = NULL;
+ return;
}
lock_file = CreateFile(lock_filename,
- GENERIC_READ | GENERIC_WRITE,
- 0, // No share
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
- NULL);
+ GENERIC_READ | GENERIC_WRITE,
+ 0, // No share
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
+ NULL);
if (lock_file == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
// On Windows, the file opened by CreateFile has exclusive lock
// naturally unless FILE_SHARE_* attribute is set.
if (error == ERROR_SHARING_VIOLATION) {
+ g_free(lock_filename);
+ lock_filename = NULL;
error_report("Can not execute this VM. "
"The same VM may be running now.");
exit(1);
@@ -201,12 +208,12 @@ bool make_sdcard_lock_os(char *sdcard)
fname = g_strdup_printf("%s.lck", sdcard);
h = CreateFile(fname,
- GENERIC_READ,
- 0, // No share
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
- NULL);
+ GENERIC_READ,
+ 0, // No share
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
+ NULL);
if (h == INVALID_HANDLE_VALUE) {
LOG_WARNING("Failed to CreateFile a sdcard lock file: %d\n",
@@ -277,11 +284,11 @@ void get_java_path_win32(const char **java_path)
/* Opens above key to query the current version */
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- strKey,
- 0,
- KEY_QUERY_VALUE |
- MY_KEY_WOW64_64KEY,
- &hKey);
+ strKey,
+ 0,
+ KEY_QUERY_VALUE |
+ MY_KEY_WOW64_64KEY,
+ &hKey);
if (res != ERROR_SUCCESS) {
LOG_WARNING("Java Runtime Environment key not found\n");
goto javahome_not_found;
@@ -289,11 +296,11 @@ void get_java_path_win32(const char **java_path)
/* Queries for the current version */
res = RegQueryValueEx(hKey,
- "CurrentVersion",
- NULL,
- NULL,
- (LPBYTE)strVersion,
- &dwBufLen);
+ "CurrentVersion",
+ NULL,
+ NULL,
+ (LPBYTE)strVersion,
+ &dwBufLen);
RegCloseKey(hKey);
if (res != ERROR_SUCCESS) {
LOG_WARNING("JRE CurrentVersion not found\n");
@@ -306,11 +313,11 @@ void get_java_path_win32(const char **java_path)
/* Opens above key to query the JavaHome */
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- strKey,
- 0,
- KEY_QUERY_VALUE |
- MY_KEY_WOW64_64KEY,
- &hKey);
+ strKey,
+ 0,
+ KEY_QUERY_VALUE |
+ MY_KEY_WOW64_64KEY,
+ &hKey);
if (res == ERROR_SUCCESS) {
/* Queries for the JavaHome */
dwBufLen = PATH_MAX;
@@ -336,3 +343,117 @@ javahome_not_found:
*java_path = current_java_path;
}
+
+bool check_integrity_level_and_respawn(void)
+{
+ BOOL bResult = false;
+ HANDLE hToken = NULL;
+ HANDLE hNewToken = NULL;
+ PSID pIntegritySid = NULL;
+ TOKEN_MANDATORY_LABEL TIL = { { 0, }, };
+ PTOKEN_MANDATORY_LABEL pTIL = NULL;
+ PROCESS_INFORMATION ProcInfo = { 0, };
+ STARTUPINFO StartupInfo = { 0, };
+ SID_IDENTIFIER_AUTHORITY
+ MLAuthority = { SECURITY_MANDATORY_LABEL_AUTHORITY };
+ DWORD dwIntegrityLevel, dwSize = 0;
+
+ if(!OpenProcessToken(GetCurrentProcess(),
+ TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_QUERY |
+ TOKEN_ASSIGN_PRIMARY, &hToken)) {
+ LOG_WARNING("OpenProcessToken Error %lu\n", GetLastError());
+ goto CleanExit;
+ }
+
+ if (!GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize)) {
+ DWORD dwResult = GetLastError();
+ if (dwResult != ERROR_INSUFFICIENT_BUFFER) {
+ LOG_WARNING("GetTokenInformation Error %lu\n", dwResult);
+ goto CleanExit;
+ }
+ }
+
+ pTIL = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwSize);
+ if (!pTIL) {
+ LOG_WARNING("LocalAlloc Error %lu\n", GetLastError());
+ goto CleanExit;
+ }
+
+ if (!GetTokenInformation(hToken, TokenIntegrityLevel, pTIL,
+ dwSize, &dwSize)) {
+ LOG_WARNING("GetTokenInformation Error %lu\n", GetLastError());
+ goto CleanExit;
+ }
+
+ dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid,
+ (DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid) - 1));
+
+ if (dwIntegrityLevel >= SECURITY_MANDATORY_MEDIUM_RID &&
+ dwIntegrityLevel < SECURITY_MANDATORY_HIGH_RID) {
+ // We have medium integrity level. So keep going on.
+ goto CleanExit;
+ }
+
+ LOG_INFO("Running with elevated integrity level. Try to respawn.\n");
+
+ if (!DuplicateTokenEx(hToken, 0, NULL, SecurityImpersonation,
+ TokenPrimary, &hNewToken)) {
+ LOG_WARNING("DuplicateTokenEx Error %lu\n", GetLastError());
+ goto CleanExit;
+ }
+
+ if (!AllocateAndInitializeSid(&MLAuthority, 1, SECURITY_MANDATORY_MEDIUM_RID,
+ 0, 0, 0, 0, 0, 0, 0, &pIntegritySid)) {
+ LOG_WARNING("AllocateAndInitializeSid Error %lu\n", GetLastError());
+ goto CleanExit;
+ }
+
+ TIL.Label.Attributes = SE_GROUP_INTEGRITY;
+ TIL.Label.Sid = pIntegritySid;
+
+ if (!SetTokenInformation(hNewToken,
+ TokenIntegrityLevel,
+ &TIL,
+ sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid))) {
+ LOG_WARNING("SetTokenInformation Error %lu\n", GetLastError());
+ goto CleanExit;
+ }
+
+ if (!CreateProcessAsUser(hNewToken, 0, GetCommandLine(),
+ NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcInfo)) {
+ LOG_WARNING( "CreateProcessAsUser Error %lu\n", GetLastError());
+ goto CleanExit;
+ }
+
+ LOG_INFO("Respawning success. Waiting for child process.\n");
+ bResult = true;
+ WaitForSingleObject(ProcInfo.hProcess, INFINITE);
+
+CleanExit:
+ if (ProcInfo.hProcess != NULL) {
+ CloseHandle(ProcInfo.hProcess);
+ }
+
+ if (ProcInfo.hThread != NULL) {
+ CloseHandle(ProcInfo.hThread);
+ }
+
+ if (pIntegritySid != NULL) {
+ LocalFree(pIntegritySid);
+ }
+
+ if (hNewToken != NULL) {
+ CloseHandle(hNewToken);
+ }
+
+ if (hToken != NULL) {
+ CloseHandle(hToken);
+ }
+
+ if (pTIL != NULL) {
+ LocalFree(pTIL);
+ }
+
+ return bResult;
+}
+
diff --git a/tizen/src/util/osutil.c b/tizen/src/util/osutil.c
index 099e1780b7..540579381b 100644
--- a/tizen/src/util/osutil.c
+++ b/tizen/src/util/osutil.c
@@ -46,6 +46,7 @@ DECLARE_DEBUG_CHANNEL(osutil)
static int lock_file = -1;
+static gchar *lock_filename = NULL;
static struct flock _lock = {
.l_type = F_WRLCK,
.l_start = 0,
@@ -101,6 +102,7 @@ static bool fd_checklock(int fd)
static void remove_vm_lock_posix(void)
{
+ int error = 0;
if (lock_file == -1) {
return;
}
@@ -110,6 +112,16 @@ static void remove_vm_lock_posix(void)
}
close(lock_file);
+ if (lock_filename != NULL) {
+ if (unlink(lock_filename) == -1) {
+ error = errno;
+ LOG_WARNING("Failed to unlink lock file(%d): %s\n",
+ error, strerror(error));
+ }
+ g_free(lock_filename);
+ lock_filename = NULL;
+ }
+
lock_file = -1;
}
@@ -120,20 +132,22 @@ static void notify_remove_lock(Notifier *notifier, void *data)
static Notifier remove_lock = { .notify = notify_remove_lock };
-void make_vm_lock_posix(void)
+void make_vm_lock_posix(gchar *vms_path)
{
- const char *image_file = get_drive_image_file();
int error = 0;
+ lock_filename = g_strdup_printf("%s/%s", vms_path, VMLOCK_FILE);
- g_assert(lock_file == -1);
- g_assert(image_file != NULL);
+ g_assert(lock_filename != NULL);
retry:
- lock_file = open(image_file, O_RDWR);
+ lock_file = open(lock_filename, O_RDWR|O_CREAT, 0666);
if (lock_file == -1) {
error = errno;
- LOG_WARNING("Failed to open image file for lock: %s\n",
- strerror(error));
+ LOG_WARNING("Failed to open file for lock(%d): %s\n",
+ error, strerror(error));
+ // do not create the lock file.
+ g_free(lock_filename);
+ lock_filename = NULL;
return;
}
@@ -152,10 +166,7 @@ retry:
exit(1);
}
- LOG_WARNING("Failed to lock image file: %s\n", strerror(error));
- close(lock_file);
- lock_file = -1;
- return;
+ LOG_WARNING("Failed to lock file: %s\n", strerror(error));
}
emulator_add_exit_notifier(&remove_lock);
diff --git a/tizen/src/util/osutil.h b/tizen/src/util/osutil.h
index 8e9d2ac519..d478155f28 100644
--- a/tizen/src/util/osutil.h
+++ b/tizen/src/util/osutil.h
@@ -42,20 +42,22 @@
#define ERR_NODEV 4 /* ACT_SDCARD_DETACH_FAIL. No sdcard attached. */
#define ERR_BUSY 5 /* ACT_SDCARD_ATTACH_FAIL. Already sdcard attached. */
#define ERR_NOENT 6 /* ACT_SDCARD_NO_ATTACH_FOUND. Other sdcard attached. */
+#define VMLOCK_FILE "vm.lock"
extern const char *pac_tempfile;
-void make_vm_lock_os(void);
+void make_vm_lock_os(gchar *vms_path);
bool make_sdcard_lock_os(char *sdcard);
int remove_sdcard_lock_os(char *sdcard);
#ifndef CONFIG_WIN32
-void make_vm_lock_posix(void);
+void make_vm_lock_posix(gchar *dirname);
bool make_sdcard_lock_posix(char *sdcard);
int remove_sdcard_lock_posix(char *sdcard);
#else
void get_java_path_win32(const char **java_path);
+bool check_integrity_level_and_respawn(void);
#endif
void set_bin_path_os(char const *const);
diff --git a/version.rc b/version.rc
index c7922d5200..86455bb873 100644
--- a/version.rc
+++ b/version.rc
@@ -14,7 +14,11 @@ FILESUBTYPE VFT2_UNKNOWN
BLOCK "040904E4"
{
VALUE "CompanyName", "http://www.qemu-project.org"
+#ifdef CONFIG_MARU
+ VALUE "FileDescription", "Tizen Emulator"
+#else
VALUE "FileDescription", "QEMU machine emulators and tools"
+#endif
VALUE "FileVersion", QEMU_VERSION
VALUE "LegalCopyright", "Copyright various authors. Released under the GNU General Public License."
VALUE "LegalTrademarks", "QEMU is a trademark of Fabrice Bellard."
diff --git a/vl.c b/vl.c
index e85078aa4a..4eee2b97ce 100644
--- a/vl.c
+++ b/vl.c
@@ -2261,6 +2261,9 @@ static DisplayType select_display(const char *p)
}
set_display_pixel_density(dpi);
nextopt = endptr;
+ } else if (strstart(opts, ",forcelegacy", &nextopt)) {
+ opts = nextopt;
+ //maru_qt5_set_force_legacy(true);
} else {
invalid_maru_qt_args:
error_report(FAILED_TO_DISPLAY_PARSING);
@@ -4847,5 +4850,16 @@ int main(int argc, char **argv, char **envp)
monitor_cleanup();
qemu_chr_cleanup();
+#if defined(CONFIG_MARU) && defined(CONFIG_QT)
+ switch (display_type) {
+ case DT_MARU_QT_ONSCREEN:
+ case DT_MARU_QT_OFFSCREEN:
+ maru_qt5_display_fini();
+ break;
+ default:
+ break;
+ }
+#endif
+
return 0;
}