#! /bin/sh
program=mcetorture
version=1.3.8

DBUS_PATH=/com/nokia/mce/request
DBUS_DEST=com.nokia.mce
DBUS_INTERFACE=$DBUS_DEST.request
DBUS_SEND=dbus-send
DBUS_SEND_FLAGS_REPLY='--system --type=method_call --print-reply'
DBUS_SEND_FLAGS='--system --type=method_call'

logfile=/media/mmc1/mcetorture.log
logball=/media/mmc1/dsmelog.tar
memfile=/media/mmc1/mcememlog
mcepid=$(pidof mce)

# FIXME
KEYBOARD_EVENT_FILE=/dev/input/event0
POWERBUTTON_EVENT_FILE=/dev/input/event1

x=0
tests=0
retval=

MCETOOL_FLAGS=

skipsystemui=0
oneshot=0
noleakcheck=0
noabort=0
actdeadui=
splashscreenui=
modechangeui=
powerkeymenuui=
devicelockui=
tklockui=
alarmui=
blank=
mceinfo=
unblank=
dim=
offline=
voip=
powerkeymenu=
tklock=
alarm=
led=
homeshort=
homelong=
powershort=
powerlong=
gconfbrightness=
gconftimeout=
gconfled=
eventerrors=
dbuserrors=

EVENT_TIMESTAMP="\110\147\230\105\137\026\013\000"
EVENT_KEY_TYPE="\001\000"
EVENT_POWER_KEY="\164\000"
EVENT_HOME_KEY="\077\000"
EVENT_ESC_KEY="\001\000"
EVENT_UP_KEY="\149\000"
EVENT_LEFT_KEY="\151\000"
EVENT_RIGHT_KEY="\152\000"
EVENT_DOWN_KEY="\154\000"
EVENT_SELECT_KEY="\140\000"
EVENT_TOO_SHORT_KEY="\042"
EVENT_TOO_LONG_KEY="\042\042\042"
EVENT_PRESS_VALUE="\001\000\000\000"
EVENT_RELEASE_VALUE="\000\000\000\000"

GCONF_DISPLAY_BRIGHTNESS_PATH=/system/osso/dsm/display/display_brightness
GCONF_DISPLAY_BLANK_TIMEOUT_PATH=/system/osso/dsm/display/display_blank_timeout
GCONF_DISPLAY_DIM_TIMEOUT_PATH=/system/osso/dsm/display/display_dim_timeout
GCONF_DISPLAY_ON_WITH_CHARGER_PATH=/system/osso/dsm/display/display_on_with_charger
GCONF_LED_PATTERN_ERROR_PATH=/system/osso/dsm/leds/PatternError
GCONF_BRIGHTNESS_MIN=1
GCONF_BRIGHTNESS_MAX=5

get_memstats()
{
	size=$(awk '/Size:/ { a += $2 } END { printf a }' /proc/$mcepid/smaps)
	rss=$(awk '/Rss:/ { a += $2 }' /proc/$mcepid/smaps)
	shared_clean=$(awk '/Shared_Clean:/ { a += $2 } END { printf a }' /proc/$mcepid/smaps)
	shared_dirty=$(awk '/Shared_Dirty:/ { a += $2 } END { printf a }' /proc/$mcepid/smaps)
	private_clean=$(awk '/Private_Clean:/ { a += $2 } END { printf a }' /proc/$mcepid/smaps)
	private_dirty=$(awk '/Private_Dirty/ { a += $2 } END { printf a }' /proc/$mcepid/smaps)

	# Make sure we don't get any unset values
	[ x"$size" = x"" ] && size=0
	[ x"$rss" = x"" ] && rss=0
	[ x"$shared_clean" = x"" ] && shared_clean=0
	[ x"$shared_dirty" = x"" ] && shared_dirty=0
	[ x"$private_clean" = x"" ] && private_clean=0
	[ x"$private_dirty" = x"" ] && private_dirty=0
}

leakcheck()
{
	if [ $noleakcheck -eq 1 ]; then
		return 0
	fi

	old_size=$size
	old_rss=$rss
	old_shared_clean=$shared_clean
	old_shared_dirty=$shared_dirty
	old_private_clean=$private_clean
	old_private_dirty=$private_dirty

	get_memstats

	if [ $size -gt $old_size ] ||
	   [ $rss -gt $old_rss ] ||
	   [ $shared_clean -gt $old_shared_clean ] ||
	   [ $shared_dirty -gt $old_shared_dirty ] ||
	   [ $private_clean -gt $old_private_clean ] ||
	   [ $private_dirty -gt $old_private_dirty ]; then
		printf "Aieeek, a leak!\n"
		cp /proc/$mcepid/smaps $memfile.after
		return 1
	fi

	return 0
}

abort()
{
	if [ $noabort -eq 1 ]; then
		return 0
	fi

	printf "Aborting: " > $logfile
	echo $1 >> $logfile
	echo iterations: $x >> $logfile
	echo testcases: $actdeadui $splashscreenui $modechangeui $powerkeymenuui $devicelockui $tklockui $alarmui $blank $mceinfo $unblank $dim $offline $voip $powerkeymenu $tklock $alarm $led $homeshort $homelong $powershort $powerlong $gconfbrightness $gconftimeouts $gconfled $eventerrors $dbuserrors >> $logfile
	cat /var/ftd-log/syslog >> $logfile
	tar cf $logball /var/lib/dsme
	exit 42
}

normal_exit()
{
	test_unblank
	exit 0
}

usage()
{
	printf "Usage: %s [OPTION]... [TEST]...\n" $program
	printf "Continuously run the specified tests;\n"
	printf "if no tests are listed, all tests are executed\n"
	printf "\n"
	printf "  --skip-systemui  skip tests that only tortures SystemUI\n"
	printf "  --no-leakcheck   disable leak-checking\n"
	printf "  --no-abort       do not abort on error\n"
	printf "  --session        use the session bus instead of the system bus for D-Bus\n"
	printf "  --one-shot       run the tests once, then exit\n"
	printf "  --help           display this help and exit\n"
	printf "  --version        output version information and exit\n"
	printf "\n"
	printf "Valid tests are:\n"
	printf "\n"
	printf "  actdead-ui(x)\n"
	printf "  splashscreen-ui(x)\n"
	printf "  modechange-ui(x)\n"
	printf "  powerkeymenu-ui(x)\n"
	printf "  devicelock-ui(x)\n"
	printf "  tklock-ui(x)\n"
	printf "  alarm-ui(x)\n"
	printf "  blank\n"
	printf "  mceinfo\n"
	printf "  unblank\n"
	printf "  dim\n"
	printf "  offline\n"
	printf "  voip\n"
	printf "  powerkeymenu\n"
	printf "  tklock\n"
	printf "  alarm\n"
	printf "  led\n"
	printf "  homeshort\n"
	printf "  homelong\n"
	printf "  powershort\n"
	printf "  powerlong(*)\n"
	printf "  gconf-brightness\n"
	printf "  gconf-timeouts\n"
	printf "  gconf-led\n"
	printf "  event-errors\n"
	printf "  dbus-errors\n"
	printf "\n"
	printf "(*) not included in the default set of test cases\n"
	printf "    since it would cause the device to reboot\n"
	printf "(x) this test case only tortures SystemUI\n"
}

version()
{
	printf "%s %s\n" $program $version
}

test_mceinfo()
{
	# just dump information
	mcetool $MCETOOL_FLAGS > /dev/null
}

# Only tortures SystemUI
test_actdead_ui()
{
	# open acting dead UI
	mcetool $MCETOOL_FLAGS --no-status --actdead=open > /dev/null
	# close acting dead UI
	mcetool $MCETOOL_FLAGS --no-status --actdead=close > /dev/null
}

# Only tortures SystemUI
test_splashscreen_ui()
{
	# open startup splashscreen
	mcetool $MCETOOL_FLAGS --no-status --splashscreen=startup > /dev/null
	# close startup splashscreen
	mcetool $MCETOOL_FLAGS --no-status --splashscreen=close > /dev/null
	# open shutdown splashscreen
	mcetool $MCETOOL_FLAGS --no-status --splashscreen=shutdown > /dev/null
	# close shutdown splashscreen
	mcetool $MCETOOL_FLAGS --no-status --splashscreen=close > /dev/null
	# open shutdown splashscreen in silent mode
	mcetool $MCETOOL_FLAGS --no-status --splashscreen=silent-shutdown > /dev/null
	# close shutdown splashscreen
	mcetool $MCETOOL_FLAGS --no-status --splashscreen=close > /dev/null
}

# Only tortures SystemUI
test_modechange_ui()
{
	# open modechange dialog in normal mode
	mcetool $MCETOOL_FLAGS --dont-block --no-status --modechange=normal > /dev/null
	# close modechange dialog
	mcetool $MCETOOL_FLAGS --no-status --modechange=close > /dev/null
	# open modechange dialog in flight mode
	mcetool $MCETOOL_FLAGS --dont-block --no-status --modechange=flight > /dev/null
	# close modechange dialog
	mcetool $MCETOOL_FLAGS --no-status --modechange=close > /dev/null
}

# Only tortures SystemUI
test_powerkeymenu_ui()
{
	# open powerkey menu in normal mode
	mcetool $MCETOOL_FLAGS --dont-block --no-status --powerkeymenu=normal > /dev/null
	# close powerkey menu
	mcetool $MCETOOL_FLAGS --no-status --powerkeymenu=close > /dev/null
	# open powerkey menu in flight mode
	mcetool $MCETOOL_FLAGS --dont-block --no-status --powerkeymenu=flight > /dev/null
	# close powerkey menu
	mcetool $MCETOOL_FLAGS --no-status --powerkeymenu=close > /dev/null
}

# Only tortures SystemUI
test_devicelock()
{
	# open device lock dialog
	mcetool $MCETOOL_FLAGS --dont-block --no-status --devicelock=normal > /dev/null
	# close device lock dialog
	mcetool $MCETOOL_FLAGS --no-status --devicelock=close > /dev/null
	# open device lock dialog in no-input mode
	mcetool $MCETOOL_FLAGS --dont-block --no-status --devicelock=noinput > /dev/null
	# close device lock dialog
	mcetool $MCETOOL_FLAGS --no-status --devicelock=close > /dev/null
	# open device lock dialog in confirm mode
	mcetool $MCETOOL_FLAGS --dont-block --no-status --devicelock=confirm > /dev/null
	# close device lock dialog
	mcetool $MCETOOL_FLAGS --no-status --devicelock=close > /dev/null
}

# Only tortures SystemUI
test_tklock_ui()
{
	# open tklock UI
	mcetool $MCETOOL_FLAGS --no-status --tklock=open > /dev/null
	# close tklock UI
	mcetool $MCETOOL_FLAGS --no-status --tklock=close > /dev/null
	# open tklock UI without infoprints
	mcetool $MCETOOL_FLAGS --no-status --tklock=silent-open > /dev/null
	# close tklock UI without infoprints
	mcetool $MCETOOL_FLAGS --no-status --tklock=silent-close > /dev/null
	# show tklock UI help infoprint
	mcetool $MCETOOL_FLAGS --no-status --tklock=help > /dev/null
	# close tklock UI
	mcetool $MCETOOL_FLAGS --no-status --tklock=close > /dev/null
}

# Only tortures SystemUI
test_alarm_ui()
{
	# open alarm UI
	mcetool $MCETOOL_FLAGS --dont-block --no-status --alarm=normal > /dev/null
	# close alarm UI
	mcetool $MCETOOL_FLAGS --no-status --alarm=close > /dev/null
	# open alarm UI with custom text, sound, and icon
	mcetool $MCETOOL_FLAGS --dont-block --no-status --alarm-text="This is a test" --alarm-icon=/usr/share/icons/hicolor/50x50/hildon/qgn_indi_KeypadLk_lock.png --alarm-sound=/usr/share/sounds/call-ringtone02.wav --alarm=normal > /dev/null
	# close alarm UI
	mcetool $MCETOOL_FLAGS --no-status --alarm=close > /dev/null
	# open alarm UI in no-snooze mode
	mcetool $MCETOOL_FLAGS --dont-block --no-status --alarm=nosnooze > /dev/null
	# close alarm UI
	mcetool $MCETOOL_FLAGS --no-status --alarm=close > /dev/null
	# open alarm UI in switch-on mode
	mcetool $MCETOOL_FLAGS --dont-block --no-status --alarm=switchon > /dev/null
	# close alarm UI
	mcetool $MCETOOL_FLAGS --no-status --alarm=close > /dev/null
}

test_blank()
{
	# blank screen
	mcetool $MCETOOL_FLAGS --no-status --blank-screen > /dev/null
}

test_dim()
{
	# blank screen
	mcetool $MCETOOL_FLAGS --no-status --blank-screen > /dev/null
}

test_unblank()
{
	# unblank screen and prevent blank
	mcetool $MCETOOL_FLAGS --no-status --unblank-screen > /dev/null
	mcetool $MCETOOL_FLAGS --no-status --blank-prevent > /dev/null
}

test_offline()
{
	# switch to flight mode
	mcetool $MCETOOL_FLAGS --no-status --set-mode=flight > /dev/null

	# switch to normal mode
	mcetool $MCETOOL_FLAGS --no-status --set-mode=normal > /dev/null
}

test_voip()
{
	# switch to voip mode
	mcetool $MCETOOL_FLAGS --no-status --set-mode=voip > /dev/null

	# switch to normal mode
	mcetool $MCETOOL_FLAGS --no-status --set-mode=normal > /dev/null
}

test_tklock()
{
	# lock tklock
	mcetool $MCETOOL_FLAGS --no-status --set-tklock-mode=locked > /dev/null
	# unlock tklock
	mcetool $MCETOOL_FLAGS --no-status --set-tklock-mode=unlocked > /dev/null
	# lock tklock and dim the screen
	mcetool $MCETOOL_FLAGS --no-status --set-tklock-mode=locked-dim > /dev/null
	# unlock tklock without infoprints
	mcetool $MCETOOL_FLAGS --no-status --set-tklock-mode=silent-unlocked > /dev/null
	# lock tklock without infoprints
	mcetool $MCETOOL_FLAGS --no-status --set-tklock-mode=silent-locked > /dev/null
	# unlock tklock
	mcetool $MCETOOL_FLAGS --no-status --set-tklock-mode=unlocked > /dev/null
	# lock tklock without infoprints and dim the screen
	mcetool $MCETOOL_FLAGS --no-status --set-tklock-mode=silent-locked-dim > /dev/null
	# unlock tklock without infoprints
	mcetool $MCETOOL_FLAGS --no-status --set-tklock-mode=silent-unlocked > /dev/null
}

test_alarm()
{
	# Set alarm mode to on
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.set_alarm_mode string:visible

	# Set alarm mode to snoozed
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.set_alarm_mode string:snoozed

	# Set alarm mode to snoozed
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.set_alarm_mode string:off
}

test_led()
{
	# Enable LED
	mcetool $MCETOOL_FLAGS --no-status --enable-led
	# Activate poweron LED pattern
	mcetool $MCETOOL_FLAGS --no-status --activate-led-pattern=PatternPowerOn
	# Activate error LED pattern
	mcetool $MCETOOL_FLAGS --no-status --activate-led-pattern=PatternError
	# Disable LED
	mcetool $MCETOOL_FLAGS --no-status --disable-led
	# Enable LED
	mcetool $MCETOOL_FLAGS --no-status --enable-led
	# Deactivate poweron LED pattern
	mcetool $MCETOOL_FLAGS --no-status --deactivate-led-pattern=PatternPowerOn
	# Deactivate error LED pattern
	mcetool $MCETOOL_FLAGS --no-status --deactivate-led-pattern=PatternError
	# Disable LED
	mcetool $MCETOOL_FLAGS --no-status --disable-led
}

inject_keyshort()
{
	printf $EVENT_TIMESTAMP$EVENT_KEY_TYPE$1$EVENT_PRESS_VALUE$EVENT_TIMESTAMP$EVENT_KEY_TYPE$1$EVENT_RELEASE_VALUE > $2
	sleep 1
}

inject_keylong()
{
	printf $EVENT_TIMESTAMP$EVENT_KEY_TYPE$1$EVENT_PRESS_VALUE > $2
	sleep 2
	printf $EVENT_TIMESTAMP$EVENT_KEY_TYPE$1$EVENT_RELEASE_VALUE > $2
	sleep 1
}

test_homeshort()
{
	# Inject a short [home] event into the keyboard event queue
	inject_keyshort $EVENT_HOME_KEY $KEYBOARD_EVENT_FILE
}

test_homelong()
{
	# Inject a long [home] event into the keyboard event queue
	inject_keylong $EVENT_HOME_KEY $KEYBOARD_EVENT_FILE
}

test_powershort()
{
	# Trigger a long [power] event
	mcetool $MCETOOL_FLAGS --no-status --powerkey-event=short
}

test_powerlong()
{
	# Trigger a long [power] event
	mcetool $MCETOOL_FLAGS --no-status --powerkey-event=long
}

test_powerkeymenu()
{
	# Inject a short [power] event into the powerbutton event queue
	inject_keyshort $EVENT_POWER_KEY $POWERBUTTON_EVENT_FILE

	# Inject a short [esc] event into the keyboard event queue
	inject_keyshort $EVENT_ESC_KEY $KEYBOARD_EVENT_FILE
}

gconf_set()
{
	keytype=$(gconftool-2 --get-type $1)

	if [ x"$keytype" != x"$2" ]; then
		abort "Got type $keytype for GConf key $1, expected $2"
	fi

	gconftool-2 --set --type=$2 $1 $3
	sleep 1
}

gconf_set_bool()
{
	gconf_set $1 bool $2
}

gconf_set_int()
{
	gconf_set $1 int $2
}

gconf_get()
{
	keytype=$(gconftool-2 --get-type $2)

	if [ x"$keytype" != x"$1" ]; then
		abort "Got type $keytype for GConf key $2, expected $1"
	fi

	retval=$(gconftool-2 --get $2)
}

gconf_get_bool()
{
	gconf_get bool $1
	# This looks stupid; it's just to allow altering
	# of the return value
	tmp=$retval
	retval=$tmp
}

gconf_get_int()
{
	gconf_get int $1
	# This looks stupid; it's just to allow altering
	# of the return value
	tmp=$retval
	retval=$tmp
}

test_gconf_brightness()
{
	# Save old brightness
	gconf_get_int $GCONF_DISPLAY_BRIGHTNESS_PATH
	old_brightness=$retval

	# Set maximum brightness
	gconf_set_int $GCONF_DISPLAY_BRIGHTNESS_PATH $GCONF_BRIGHTNESS_MAX

	# Set minimum brightness
	gconf_set_int $GCONF_DISPLAY_BRIGHTNESS_PATH $GCONF_BRIGHTNESS_MIN

	# Restore brightness
	gconf_set_int $GCONF_DISPLAY_BRIGHTNESS_PATH $old_brightness
}

test_gconf_timeouts()
{
	# Save old blank timeout
	gconf_get_int $GCONF_DISPLAY_BLANK_TIMEOUT_PATH
	old_blank_timeout=$retval

	# Save old dim timeout
	gconf_get_int $GCONF_DISPLAY_DIM_TIMEOUT_PATH
	old_dim_timeout=$retval

	# Save old display on with charger setting
	gconf_get_bool $GCONF_DISPLAY_ON_WITH_CHARGER_PATH
	old_display_on_with_charger=$retval

	# Set 5 second dim timeout
	gconf_set_int $GCONF_DISPLAY_DIM_TIMEOUT_PATH 5

	# Set 15 second blank timeout
	gconf_set_int $GCONF_DISPLAY_DIM_TIMEOUT_PATH 15

	# Enable display on with charger
	gconf_set_bool $GCONF_DISPLAY_ON_WITH_CHARGER_PATH true

	# Disable display on with charger
	gconf_set_bool $GCONF_DISPLAY_ON_WITH_CHARGER_PATH false

	# Restore blank timeout
	gconf_set_int $GCONF_DISPLAY_BLANK_TIMEOUT_PATH $old_blank_timeout

	# Restore dim timeout
	gconf_set_int $GCONF_DISPLAY_DIM_TIMEOUT_PATH $old_dim_timeout

	# Restore display on with charger
	gconf_set_bool $GCONF_DISPLAY_ON_WITH_CHARGER_PATH $old_display_on_with_charger
}

test_gconf_led()
{
	# Save old PatternError LED setting
	gconf_get_bool $GCONF_LED_PATTERN_ERROR_PATH
	old_led_pattern_error=$retval

	# Enable PatternError
	gconf_set_bool $GCONF_LED_PATTERN_ERROR_PATH true

	# enable LED
	mcetool $MCETOOL_FLAGS --no-status --enable-led

	# activate error LED pattern
	mcetool $MCETOOL_FLAGS --no-status --activate-led-pattern=PatternError

	# Disable PatternError
	gconf_set_bool $GCONF_LED_PATTERN_ERROR_PATH false

	# Deactivate error LED pattern
	mcetool $MCETOOL_FLAGS --no-status --deactivate-led-pattern=PatternError

	# Disable LED
	mcetool $MCETOOL_FLAGS --no-status --disable-led

	# Restore display on with charger
	gconf_set_bool $GCONF_LED_PATTERN_ERROR_PATH $old_led_pattern_error
}

test_event_errors()
{
	# Inject invalid events into the powerbutton event queue
	inject_keyshort $EVENT_TOO_LONG_KEY $POWERBUTTON_EVENT_FILE
	inject_keyshort $EVENT_TOO_LONG_KEY $KEYBOARD_EVENT_FILE
	inject_keyshort $EVENT_TOO_SHORT_KEY $POWERBUTTON_EVENT_FILE
	inject_keyshort $EVENT_TOO_SHORT_KEY $KEYBOARD_EVENT_FILE
}

test_dbus_errors()
{
	# Send invalid D-Bus method calls to MCE

	# LED tests

	# Invalid LED disabling (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_led_disable int32:42

	# Invalid LED enabling (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_led_enable string:Foo

	# activate LED pattern (too few arguments)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_led_pattern_activate

	# activate LED pattern (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_led_pattern_activate string:PatternError int32:42

	# activate LED pattern (invalid type)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_led_pattern_activate int32:42

	# activate LED pattern (non-existing pattern)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_led_pattern_activate string:PatternNonExisting

	# de-activate LED pattern (too few arguments)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_led_pattern_deactivate

	# de-activate LED pattern (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_led_pattern_deactivate string:PatternError int32:42

	# de-activate LED pattern (invalid type)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_led_pattern_deactivate int32:42

	# de-activate LED pattern (non-existing pattern)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_led_pattern_deactivate string:PatternNonExisting


	# Misc

	# non-existing D-Bus method call
	$DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.non_existing_method_call

	# get device lock mode (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.get_devicelock_mode int32:42

	# get display status (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.get_display_status int32:42

	# get inactivity status (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.get_inactivity_status int32:42

	# get MCE version (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.get_version int32:42

	# Display state

	# blank screen
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_display_state_off int32:42

	# dim screen
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_display_state_dim int32:42

	# unblank screen
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_display_state_on int32:42

	# prevent blank
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_display_blanking_pause int32:42


	# Device mode

	# get device mode (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.get_device_mode int32:42

	# request device mode change (too few arguments)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_device_mode_change

	# request device mode change (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_device_mode_change string:normal int32:42

	# request device mode change (invalid type)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_device_mode_change int32:42

	# request device mode change (invalid value)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_device_mode_change string:foo


	# Tklock mode

	# get touchscreen/keypad lock mode (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.get_tklock_mode int32:42

	# request tklock mode change (too few arguments)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_device_mode_change

	# request tklock mode change (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_device_mode_change string:unlocked int32:42

	# request tklock mode change (invalid type)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_device_mode_change int32:42

	# request tklock mode change (invalid value)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_device_mode_change string:foo


	# Powerkey trigger

	# trigger powerkey event (too few arguments)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_trigger_powerkey_event

	# trigger powerkey event (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_trigger_powerkey_event boolean:false int32:42

	# trigger powerkey event (invalid type)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.req_trigger_powerkey_event string:foo


	# Device lock code

	# validate device lock code (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.validate_devicelock_code string:42 string:428JIDAMFgh3Y int32:42

	# validate device lock code (too few arguments)
	$DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.validate_devicelock_code string:42

	# validate device lock code (invalid types)
	$DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.validate_devicelock_code string:42 int32:42
	$DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.validate_devicelock_code int32:42 string:428JIDAMFgh3Y

	# change device lock code (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.change_devicelock_code string:42 string:428JIDAMFgh3Y string:54321 int32:42

	# change device lock code (too few arguments)
	$DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.change_devicelock_code string:42 string:428JIDAMFgh3Y

	# change device lock code (invalid types)
	$DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.change_devicelock_code int32:42 string:428JIDAMFgh3Y string:54321
	$DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.change_devicelock_code string:42 int32:42 string:54321
	$DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.change_devicelock_code string:42 string:428JIDAMFgh3Y int32:54321

	# change device lock code (invalid value)
	$DBUS_SEND $DBUS_SEND_FLAGS_REPLY --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.change_devicelock_code string:42 string:428JIDAMFgh3Y string:12345678910


	# Alarm mode

	# set alarm mode (too many arguments)
	# $DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.set_alarm_mode string:off int32:42

	# set alarm mode (too few arguments)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.set_alarm_mode

	# set alarm mode (invalid type)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.set_alarm_mode int32:42

	# set alarm mode (invalid value)
	$DBUS_SEND $DBUS_SEND_FLAGS --dest=$DBUS_DEST $DBUS_PATH $DBUS_INTERFACE.set_alarm_mode string:foo
}

# setup command line options
while ! [ $# -eq 0 ]; do
	case $1 in
	blank)
		blank=test_${1}
		tests=$((tests + 1))
		;;
	mceinfo)
		mceinfo=test_${1}
		tests=$((tests + 1))
		;;
	unblank)
		unblank=test_${1}
		tests=$((tests + 1))
		;;
	dim)
		dim=test_${1}
		tests=$((tests + 1))
		;;
	offline)
		offline=test_${1}
		tests=$((tests + 1))
		;;
	voip)
		voip=test_${1}
		tests=$((tests + 1))
		;;
	actdead-ui)
		actdeadui=test_actdead_ui
		tests=$((tests + 1))
		;;
	splashscreen-ui)
		splashscreenui=test_splashscreen_ui
		tests=$((tests + 1))
		;;
	modechange-ui)
		modechangeui=test_modechange_ui
		tests=$((tests + 1))
		;;
	powerkeymenu)
		powerkeymenu=test_${1}
		tests=$((tests + 1))
		;;
	powerkeymenu-ui)
		powerkeymenuui=test_powerkeymenu_ui
		tests=$((tests + 1))
		;;
	devicelock-ui)
		devicelockui=test_devicelock_ui
		tests=$((tests + 1))
		;;
	tklock)
		tklock=test_${1}
		tests=$((tests + 1))
		;;
	tklock-ui)
		tklockui=test_tklock_ui
		tests=$((tests + 1))
		;;
	alarm)
		alarm=test_${1}
		tests=$((tests + 1))
		;;
	alarm-ui)
		alarmui=test_alarm_ui
		tests=$((tests + 1))
		;;
	led)
		led=test_${1}
		tests=$((tests + 1))
		;;
	homeshort)
		homeshort=test_${1}
		tests=$((tests + 1))
		;;
	homelong)
		homelong=test_${1}
		tests=$((tests + 1))
		;;
	powershort)
		powershort=test_${1}
		tests=$((tests + 1))
		;;
	powerlong)
		powerlong=test_${1}
		tests=$((tests + 1))
		;;
	gconf-brightness)
		gconfbrightness=test_gconf_brightness
		tests=$((tests + 1))
		;;
	gconf-timeouts)
		gconftimeouts=test_gconf_timeouts
		tests=$((tests + 1))
		;;
	gconf-led)
		gconfled=test_gconf_led
		tests=$((tests + 1))
		;;
	event-errors)
		eventerrors=test_event_errors
		tests=$((tests + 1))
		;;
	dbus-errors)
		dbuserrors=test_dbus_errors
		tests=$((tests + 1))
		;;
	--no-leakcheck)
		noleakcheck=1
		;;
	--no-abort)
		noabort=1
		;;
	--session)
		MCETOOL_FLAGS="$MCETOOL_FLAGS --session"
		;;
	--skip-systemui)
		skipsystemui=1
		;;
	--one-shot)
		oneshot=1
		;;
	--help)
		usage
		exit 0
		;;
	--version)
		version
		exit 0
		;;
	*)
		usage
		exit 1
		;;
	esac
	shift
done

if ! [ -x "/sbin/mcetool" ]; then
	printf "mcetool is not installed; exiting\n"
	exit 1
fi

if [ $tests -eq 0 ]; then
	if [ $skipsystemui -eq 0 ]; then
		printf "No test cases specified; enabling all tests\n"

		actdeadui=test_actdead_ui
		splashscreenui=test_splashscreen_ui
		modechangeui=test_modechange_ui
		powerkeymenuui=test_powerkeymenu_ui
		devicelockui=test_devicelock_ui
		tklockui=test_tklock_ui
		alarmui=test_alarm_ui
	else
		printf "No test cases specified; enabling all tests except "
		printf "SystemUI tests\n"
	fi

	mceinfo=test_mceinfo
	unblank=test_unblank
	dim=test_dim
	blank=test_blank
	offline=test_offline
	voip=test_voip
	powerkeymenu=test_powerkeymenu
	tklock=test_tklock
	alarm=test_alarm
	led=test_led
	homeshort=test_homeshort
	homelong=test_homelong
	powershort=test_powershort
	gconfbrightness=test_gconf_brightness
	gconftimeouts=test_gconf_timeouts
	gconfled=test_gconf_led
	eventerrors=test_event_errors
	dbuserrors=test_dbus_errors
fi

cp /proc/$mcepid/smaps $memfile.before

get_memstats

while /bin/true; do
	x=$((x+1))

	$actdeadui
	leakcheck || abort "actdead-ui test-case leaked"
	$splashscreenui
	leakcheck || abort "splashscreen-ui test-case leaked"
	$modechangeui
	leakcheck || abort "modechange-ui test-case leaked"
	$powerkeymenuui
	leakcheck || abort "powerkeymenu-ui test-case leaked"
	$devicelockui
	leakcheck || abort "devicelock-ui test-case leaked"
	$tklockui
	leakcheck || abort "tklock-ui test-case leaked"
	$alarmui
	leakcheck || abort "alarm-ui test-case leaked"
	$blank
	leakcheck || abort "blank test-case leaked"
	$mceinfo
	leakcheck || abort "mceinfo test-case leaked"
	$unblank
	leakcheck || abort "unblank test-case leaked"
	$dim
	leakcheck || abort "dim test-case leaked"
	$offline
	leakcheck || abort "offline test-case leaked"
	$voip
	leakcheck || abort "voip test-case leaked"
	$powerkeymenu
	leakcheck || abort "powerkeymenu test-case leaked"
	$tklock
	leakcheck || abort "tklock test-case leaked"
	$alarm
	leakcheck || abort "alarm test-case leaked"
	$led
	leakcheck || abort "led test-case leaked"
	$homeshort
	leakcheck || abort "homeshort test-case leaked"
	$homelong
	leakcheck || abort "homelong test-case leaked"
	$powershort
	leakcheck || abort "powershort test-case leaked"
	$powerlong
	leakcheck || abort "powerlong test-case leaked"
	$gconfbrightness
	leakcheck || abort "gconf-brightness test-case leaked"
	$gconftimeouts
	leakcheck || abort "gconf-timeouts test-case leaked"
	$gconfled
	leakcheck || abort "gconf-led test-case leaked"
	$eventerrors
	leakcheck || abort "event-errors test-case leaked"
	$dbuserrors
	leakcheck || abort "dbus-errors test-case leaked"

	echo iterations: $x
	tail -n100 /var/ftd-log/syslog | grep -q "DSME: process" && abort "A process monitored by DSME died"

	[ $oneshot -eq 1 ] && normal_exit
done
