#include #include #include #include #include #include #include #include #include #include #include #define debug 0 #define JUICE_DEBUG() if (debug) \ do \ printf("##Juice debug in %s and line ##\n", __FUNCTION__, __LINE__); \ while(0) #define JUICE_ERROR(X) \ do \ printf("##Juice error: %s in %s at line %d ##: %s\n", X, __FUNCTION__, __LINE__, strerror(errno)); \ while(0) #define DELAY 10 #define CLOCK_REALTIME_ALARM 8 #define CLOCK_BOOTTIME_ALARM 9 #ifndef EVIOCGSUSPENDBLOCK /* Those calls aren't part of the official kernel - but we're likely * using Bionic's kernel headers */ #define EVIOCGSUSPENDBLOCK _IOR('E', 0x91, int) #define EVIOCSSUSPENDBLOCK _IOW('E', 0x91, int) #endif void sigalarm(int signumber) { /*We just want to test the suspend and resuem * nothing need to be done here! */ } static int suspend_resume_test(const int seconds) { int ret; timer_t timerid; struct itimerspec its; struct timespec t1, t2; struct sigevent se; struct sigaction act; sigset_t sigmask; int signum = SIGRTMAX; /* Set up signal handler */ sigfillset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = sigalarm; sigaction(signum, &act, NULL); /* Set up timer */ memset(&se, 0, sizeof(se)); se.sigev_notify = SIGEV_SIGNAL; se.sigev_signo = signum; se.sigev_value.sival_int = 0; if (seconds < 6) { JUICE_ERROR("Input suspend time less than 6 seconds"); return -1; } ret = timer_create(CLOCK_REALTIME_ALARM, &se, &timerid); if (ret < 0) { JUICE_ERROR("Create alarm timer failed"); return -1; } memset(&its, 0, sizeof(struct itimerspec)); ret = clock_gettime(CLOCK_REALTIME_ALARM, &its.it_value); if (ret < 0) { JUICE_ERROR("Get time failed"); return -1; } its.it_value.tv_sec += seconds; ret = timer_settime(timerid, TIMER_ABSTIME, &its, NULL); if (ret < 0) { JUICE_ERROR("Set alarm timer failed"); return -1; } /*record the suspend start time*/ ret = clock_gettime(CLOCK_REALTIME, &t1); if (ret < 0) { JUICE_ERROR("Get start time of suspend failed"); return -1; } /*start suspend the system now*/ ret = system("echo mem > /sys/power/state"); if (ret < 0) { JUICE_ERROR("echo mem to power state failed"); return -1; } /*record the system resume time*/ ret = clock_gettime(CLOCK_REALTIME, &t2); if (ret < 0) { JUICE_ERROR("Get the suspend end time failed"); return -1; } if (t2.tv_sec - t1.tv_sec >= seconds) return 0; else return 1; } int main (int argc, char **argv) { struct option lopt[] = { { "path", required_argument, NULL, 'p' }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 }, }; char parameter1 = 0; int parameter2 = 0; long long parameter3 = 0; char * shopt = "p:h"; char *evdevice = NULL; unsigned int enable_lock = 1, disable_lock = 0, lockvalue = -1; int fd, c, opti = 0, ret; unsigned int clk; struct input_event ev[64]; struct timespec tp1, tp2; if(getuid()) { JUICE_ERROR("Not run this test as root"); return -1; } while ((c = getopt_long(argc, argv, shopt, lopt, &opti)) != -1 ) { switch (c) { case 'h': fprintf(stdout, "Userage:\n" "juice_evtest -p /dev/input/eventX \n"); break; case 'p': evdevice = strdup(optarg); break; default: JUICE_ERROR("Warning, unknown option!"); break; } } if (!evdevice) { JUICE_ERROR("No input device"); return -1; } /*Open the evdev input device*/ if ((fd = open(evdevice, O_RDONLY)) < 0) { JUICE_ERROR("Open input device failed"); return -1; } printf("===========================\n"); printf("Starting input ioctl cmd EVIOCGSUSPENDBLOCK/EVIOCCSUSPENDBLOCK test:\n"); /* Read lock command */ if (ioctl(fd, EVIOCGSUSPENDBLOCK, &lockvalue)) printf("[EVDEV_EVIOCGSUSPENDBLOCK_READ]: test failed\n"); else printf("[EVDEV_EVIOCGSUSPENDBLOCK_READ]: test passed\n"); if (0 == lockvalue) /*default lock value*/ printf("[EVDEV_EVIOCGSUSPENDBLOCK_VALUE_ZERO]: test passed\n"); else printf("[EVDEV_EVIOCGSUSPENDBLOCK_VALUE_ZERO]: test failed\n"); /*Set user_wake_lock*/ if (ioctl(fd, EVIOCSSUSPENDBLOCK, enable_lock)) printf("[EVDEV_EVIOCSSUSPENDBLOCK_SET]: test failed\n"); else printf("[EVDEV_EVIOCSSUSPENDBLOCK_SET]: test passed\n"); /*Verfify the lock value equals what we set*/ ioctl(fd, EVIOCGSUSPENDBLOCK, &lockvalue); if (enable_lock == lockvalue) printf("[EVDEV_EVIOCSSUSPENDBLOCK_ENABLED]: test passed\n"); else { printf("[EVDEV_EVIOCSSUSPENDBLOCK_ENABLED]: test failed\n"); goto para_test; } /*Start generating input event*/ ret = system("echo 1 > /sys/juice_input/run"); if (ret < 0) { JUICE_ERROR("Enable generate input event failed"); goto para_test; } /*Judge the system can not suspend*/ ret = suspend_resume_test(DELAY); if (1 == ret) printf("[EVDEV_CMD_DISABLE_SUSPEND]: test passed\n"); else printf("[EVDEV_CMD_DISABLE_SUSPEND]: test failed\n"); /*Disable evdev usr_wake_lock*/ ioctl(fd, EVIOCSSUSPENDBLOCK, disable_lock); ioctl(fd, EVIOCGSUSPENDBLOCK, &lockvalue); if ( disable_lock == lockvalue ) printf("[EVDEV_EVIOCSSUSPENDBLOCK_DISABLED]: test passed\n"); else printf("[EVDEV_EVIOCSSUSPENDBLOCK_DISABLED]: test failed\n"); /*Judge the system can be suspend resume*/ ret = suspend_resume_test(DELAY); if (0 == ret) printf("[EVDEV_ENABLE_SUSPEND_RESUME]: test passed\n"); else printf("[EVDEV_ENABLE_SUSPEND_RESUME]: test failed\n"); /*Stop generateing input event*/ ret = system("echo 0 > /sys/juice_input/run"); if (ret < 0) { JUICE_ERROR("Disable generate input event failed"); goto para_test; } /*The followings are the test cases for verifying different parameters*/ para_test: /* Null parameters test!*/ printf("Starting test EVIOCGSUSPENDBLOCK/EVIOCSSUSPENDBLOCK with different parameters:\n"); ret = ioctl(fd, EVIOCGSUSPENDBLOCK, NULL); if (ret < 0) printf("[EVDEV_PARA_EVIOCGSUSPENDBLOCK_NULL]: test passed\n"); else printf("[EVDEV_PARA_EVIOCGSUSPENDBLOCK_NULL]: test failed\n"); ret = ioctl(fd, EVIOCSSUSPENDBLOCK, NULL); if (!ret) printf("[EVDEV_PARA_EVIOCSSUSPENDBLOCK_NULL]: test passed\n"); else printf("[EVDEV_PARA_EVIOCSSUSPENDBLOCK_NULL]: test failed\n"); /* byte parameters test*/ ret = ioctl(fd, EVIOCGSUSPENDBLOCK, ¶meter1); if (!ret) printf("[EVDEV_PARA_EVIOCGSUSPENDBLOCK_CHAR]: test passed\n"); else printf("[EVDEV_PARA_EVIOCGSUSPENDBLOCK_CHAR]: test failed\n"); ret = ioctl(fd, EVIOCSSUSPENDBLOCK, parameter1); if (!ret) printf("[EVDEV_PARA_EVIOCSSUSPENDBLOCK_CHAR]: test passed\n"); else printf("[EVDEV_PARA_EVIOCSSUSPENDBLOCK_CHAR]: test failed\n"); /* int parameters test*/ ret = ioctl(fd, EVIOCGSUSPENDBLOCK, ¶meter2); if (!ret) printf("[EVDEV_PARA_EVIOCGSUSPENDBLOCK_INT]: test passed\n"); else printf("[EVDEV_PARA_EVIOCGSUSPENDBLOCK_INT]: test failed\n"); ret = ioctl(fd, EVIOCSSUSPENDBLOCK, parameter2); if (!ret) printf("[EVDEV_PARA_EVIOCSSUSPENDBLOCK_INT]: test passed\n"); else printf("[EVDEV_PARA_EVIOCSSUSPENDBLOCK_INT]: test failed\n"); /* 64bit parameters test*/ ret = ioctl(fd, EVIOCGSUSPENDBLOCK, ¶meter3); if (!ret) printf("[EVDEV_PARA_EVIOCGSUSPENDBLOCK_LONG_LONG]: test passed\n"); else printf("[EVDEV_PARA_EVIOCGSUSPENDBLOCK_LONG_LONG]: test failed\n"); ret = ioctl(fd, EVIOCSSUSPENDBLOCK, parameter3); if (!ret) printf("[EVDEV_PARA_EVIOCSSUSPENDBLOCK_LONG_LONG]: test passed\n"); else printf("[EVDEV_PARA_EVIOCSSUSPENDBLOCK_LONG_LONG]: test failed\n"); /*The followings are testcases for ioctl cmd EVIOCSCLOCKID*/ printf("Starting EVIOCSCLOCKID test:\n"); clk = CLOCK_REALTIME_ALARM; ret = ioctl(fd, EVIOCSCLOCKID, &clk); if (ret < 0) printf("[EVDEV_EVIOCSCLOCKID_CLOCK_REALTIME_ALARM]: test passed\n"); else printf("[EVDEV_EVIOCSCLOCKID_CLOCK_REALTIME_ALARM]: test failed\n"); clk = CLOCK_BOOTTIME; ret = ioctl(fd, EVIOCSCLOCKID, &clk); if (ret < 0) printf("[EVDEV_EVIOCSCLOCKID_CLOCK_BOOTTIME]: test passed\n"); else printf("[EVDEV_EVIOCSCLOCKID_CLOCK_BOOTTIME]: test failed\n"); ret = ioctl(fd, EVIOCSCLOCKID, NULL); if (ret < 0) printf("[EVDEV_EVIOCSCLOCKID_NULL]: test passed\n"); else printf("[EVDEV_EVIOCSCLOCKID_NULL]: test failed\n"); /*EVIOCSCLOCKID with CLOCK_REALTIME test start*/ clk = CLOCK_REALTIME; ret = ioctl(fd, EVIOCSCLOCKID, &clk); if (ret < 0) printf("[EVDEV_EVIOCSCLOCKID_CLOCK_REALTIME]: test failed\n"); else printf("[EVDEV_EVIOCSCLOCKID_CLOCK_REALTIME]: test passed\n"); /*Start generate event*/ ret = system("echo 1 > /sys/juice_input/run"); if (ret < 0) { JUICE_ERROR("Enable generating input event failed"); goto finish; } ret = clock_gettime(CLOCK_REALTIME, &tp1); if (ret < 0) JUICE_ERROR("Get time with clock id REALTIME failed"); /*Get event here!*/ ret = read(fd, ev, sizeof(struct input_event)); if (ret < (int) sizeof(struct input_event)) JUICE_ERROR("Reading input event failed"); ret = clock_gettime(CLOCK_REALTIME, &tp2); if (ret < 0) JUICE_ERROR("Get time with clock id REALTIME failed"); if (tp1.tv_sec <= ev[0].time.tv_sec && ev[0].time.tv_sec <= tp2.tv_sec) printf("[EVDEV_CLOCK_REALTIME]: test passed\n"); else printf("[EVDEV_CLOCK_REALTIME]: test failed\n"); /*Stop generate input event*/ ret = system("echo 0 > /sys/juice_input/run"); if (ret < 0) { JUICE_ERROR("Disable generating input event failed"); goto finish; } /*EVIOCSCLOCKID with CLOCK_REALTIME test end*/ /*EVIOCSCLOCKID with CLOCK_MONOTONIC test start*/ close(fd); if ((fd = open(evdevice, O_RDONLY)) < 0) { JUICE_ERROR("Open input device failed"); return -1; } clk = CLOCK_MONOTONIC; ret = ioctl(fd, EVIOCSCLOCKID, &clk); if (ret < 0) printf("[EVDEV_EVIOCSCLOCKID_CLOCK_MONOTONIC]: test failed\n"); else printf("[EVDEV_EVIOCSCLOCKID_CLOCK_MONOTONIC]: test passed\n"); ret = system("echo 1 > /sys/juice_input/run"); if (ret < 0) { JUICE_ERROR("Enable generating input event failed"); goto finish; } ret = clock_gettime(CLOCK_MONOTONIC, &tp1); if (ret < 0) JUICE_ERROR("Get time with clock id MONOTONIC failed"); /*Get event here!*/ ret = read(fd, ev, sizeof(struct input_event)); if (ret < (int) sizeof(struct input_event)) JUICE_ERROR("Reading input event failed"); ret = clock_gettime(CLOCK_MONOTONIC, &tp2); if (ret < 0) JUICE_ERROR("Get time with clock id MONOTONIC failed"); if (tp1.tv_sec <= ev[0].time.tv_sec && ev[0].time.tv_sec<= tp2.tv_sec) printf("[EVDEV_CLOCK_MONOTONIC]: test passed\n"); else printf("[EVDEV_CLOCK_MONOTONIC]: test failed\n"); /*Stop generate input event*/ ret = system("echo 0 > /sys/juice_input/run"); if (ret < 0) { JUICE_ERROR("Disable generating input event failed"); goto finish; } /*EVIOCSCLOCKID with CLOCK_MONOTONIC test end*/ finish: close(fd); printf("===========================\n"); return 0; }