| #include <linux/input.h> |
| #include <string.h> |
| #include <fcntl.h> |
| #include <unistd.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <sys/ioctl.h> |
| #include <getopt.h> |
| #include <errno.h> |
| #include <time.h> |
| |
| #define DELAY 10 |
| #define CLOCK_REALTIME_ALARM 8 |
| #define CLOCK_BOOTTIME_ALARM 9 |
| |
| static int suspend_resume_test(int seconds) |
| { |
| // struct timespec now, target, latest; |
| int ret; |
| int pm_state_fd; |
| int len, n; |
| char buf[32]; |
| timer_t timerid; |
| struct itimerspec its; |
| struct timespec t1, t2; |
| |
| if (seconds < 6) { |
| printf("Please input suspend time more than 4 seconds!\n"); |
| return -1; |
| } |
| |
| ret = timer_create(CLOCK_REALTIME_ALARM, NULL, &timerid); |
| if (-1 == ret) { |
| // printf("Create alarm timer failed!\n"); |
| return -1; |
| } |
| |
| if(clock_gettime(CLOCK_REALTIME_ALARM, &its.it_value)) |
| return -1; |
| |
| its.it_value.tv_sec += seconds; |
| |
| ret = timer_settime(timerid, TIMER_ABSTIME, &its, NULL); |
| if (-1 == ret) { |
| // perror("Set alarm timer failed!\n"); |
| return -1; |
| } |
| |
| ret = clock_gettime(CLOCK_REALTIME, &t1); |
| if (-1 == ret) { |
| // perror("Get the suspend start time failed\n"); |
| return -1; |
| } |
| |
| #if 0 |
| fd = open("/dev/alarm", O_RDWR); |
| if (fd < 0) { |
| printf("Open /dev/alarm failed!\n"); |
| return -1; |
| } |
| |
| ret = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP), &now); |
| if (ret < 0) { |
| printf("Get time failed!\n"); |
| close(fd); |
| return -1; |
| } |
| |
| target = now; |
| target.tv_sec += seconds; |
| |
| ret = ioctl(fd, ANDROID_ALARM_SET(ANDROID_ALARM_RTC_WAKEUP), &target); |
| if (ret < 0) { |
| printf("Set time failed:"); |
| if (errno == EBUSY) |
| printf("Android using this alarm ANDROID_ALARM_RTC_WAKEUP!\n"); |
| close(fd); |
| return -1; |
| } |
| #endif |
| |
| /*start suspend the system now*/ |
| pm_state_fd = open("/sys/power/state", O_WRONLY); |
| if (pm_state_fd < 0) { |
| // printf("Open /sys/power/state failed!\n"); |
| return -1; |
| } |
| sprintf(buf, "%s\n", "mem"); |
| len = strlen(buf); |
| n = write(pm_state_fd, buf, len); |
| if (n < 0 || n != len) { |
| // printf("Write /sys/power/state failed!\n"); |
| close(pm_state_fd); |
| return -1; |
| } |
| #if 0 |
| /*Get the time after the system resume*/ |
| ret = ioctl(fd, ANDROID_ALARM_GET_TIME(ANDROID_ALARM_RTC_WAKEUP), &latest); |
| if (ret < 0) { |
| printf("Get time again failed!\n"); |
| close(fd); |
| close(pm_state_fd); |
| return -1; |
| } |
| |
| /*judge if the system suspend/resume works well */ |
| if (latest.tv_sec - now.tv_sec >= seconds) { |
| close(fd); |
| close(pm_state_fd); |
| return 0; |
| } else { |
| close(fd); |
| close(pm_state_fd); |
| return 1; |
| } |
| #endif |
| close(pm_state_fd); |
| /*Maybe need sleep here for several seconds to wait system to suspend itself!!!!*/ |
| /* |
| * |
| * |
| */ |
| ret = clock_gettime(CLOCK_REALTIME, &t2); |
| if (-1 == ret) { |
| // printf("Get the suspend start time failed\n"); |
| 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; |
| long enable_lock=1, disable_lock=0, lockvalue = -1; |
| int fd, fd_evdev_run; |
| int c, opti = 0; |
| int ret, len, n; |
| char buf[32]; |
| unsigned int clk; |
| struct input_event ev[64]; |
| struct timespec tp1, tp2; |
| |
| if(getuid()) { |
| perror("Need run this test as root!\n"); |
| 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: |
| perror("Warning, unknown option!\n"); |
| break; |
| } |
| } |
| |
| if (!evdevice) { |
| perror("You need to input the event input device!\n"); |
| return -1; |
| } |
| |
| /*Open the evdev input device*/ |
| if ((fd = open(evdevice, O_RDONLY)) < 0) { |
| perror("Open input device failed, please check it!\n"); |
| return -1; |
| } |
| |
| |
| printf("===========================\n"); |
| printf("Starting evdev ioctl cmd EVIOCGSUSPENDBLOCK/EVIOCCSUSPENDBLOCK test:\n"); |
| /* Read lock command */ |
| if (ioctl(fd, EVIOCGSUSPENDBLOCK, &lockvalue)) |
| printf("[EVDEV EVIOCGSUSPENDBLOCK READ TEST1]: test failed\n"); |
| else |
| printf("[EVDEV EVIOCGSUSPENDBLOCK READ TEST1]: test passed\n"); |
| |
| if (0 == lockvalue) /*default lock value*/ |
| printf("[EVDEV TEST2]: test passed\n"); |
| else |
| printf("[EVDEV TEST2]: test failed\n"); |
| |
| /*Set user_wake_lock*/ |
| if (ioctl(fd, EVIOCSSUSPENDBLOCK, enable_lock)) |
| printf("[EVDEV EVIOCSSUSPENDBLOCK SET TEST3]: test failed\n"); |
| else |
| printf("[EVDEV EVIOCSSUSPENDBLOCK SET TEST3]: test passed\n"); |
| |
| /*Verfify the lock value equals what we set before*/ |
| if (ioctl(fd, EVIOCGSUSPENDBLOCK, &lockvalue)) |
| perror("[EVDEV READ user_wake_lock value]: test failed\n"); |
| |
| if (enable_lock == lockvalue) |
| printf("[EVDEV TEST4]: test passed\n"); |
| else { |
| printf("[EVDEV TEST4]: test failed\n"); |
| goto para_test; |
| } |
| |
| if ((fd_evdev_run = open("/sys/juice_input/run", O_WRONLY)) < 0) { |
| perror("[EVDEV OPEN SYS RUN]: test failed\n"); |
| perror("Please check input kernel test module!\n"); |
| goto para_test; |
| } else { |
| sprintf(buf, "%d\n", 1); |
| len = strlen(buf); |
| n = write(fd_evdev_run, buf, len); |
| if (n < 0 || n != len) |
| perror("Write /sys/juice_input/run failed!\n"); |
| |
| close(fd_evdev_run); |
| } |
| /*Judge the system can not be suspend*/ |
| ret = suspend_resume_test(DELAY); |
| if (1 == ret) |
| printf("[EVDEV CMD DISABLE SUSPEND TEST5]: test passed\n"); |
| else |
| printf("[EVDEV CMD DISABLE SUSPEND TEST5]: test failed\n"); |
| |
| /*Disable evdev usr_wake_lock*/ |
| ioctl(fd, EVIOCSSUSPENDBLOCK, disable_lock); |
| ioctl(fd, EVIOCGSUSPENDBLOCK, &lockvalue); |
| if ( disable_lock == lockvalue) |
| printf("[EVDEV TEST6]: test passed\n"); |
| else |
| printf("[EVDEV TEST6]: test failed\n"); |
| |
| /*Judge the system can be suspend resume*/ |
| ret = suspend_resume_test(DELAY); |
| if (0 == ret) |
| printf("[EVDEV ENABLE SUSPEND/RESUME TEST7]: test passed\n"); |
| else |
| printf("[EVDEV ENABLE SUSPEND/RESUME TEST7]: test failed\n"); |
| |
| if ((fd_evdev_run = open("/sys/juice_input/run", O_WRONLY)) < 0) { |
| perror("[EVDEV OPEN SYS RUN]: test failed\n"); |
| goto para_test; |
| } else { |
| sprintf(buf, "%d\n", 0); |
| len = strlen(buf); |
| n = write(fd_evdev_run, buf, len); |
| if (n < 0 || n != len) |
| perror("Write /sys/juice_input/run failed!\n"); |
| |
| close(fd_evdev_run); |
| } |
| |
| |
| para_test: |
| /*The following is the test cases for verifying different parameters*/ |
| /* Null parameters test!*/ |
| printf("Starting test EVIOCGSUSPENDBLOCK/EVIOCSSUSPENDBLOCK with different parameters:\n"); |
| ret = ioctl(fd, EVIOCGSUSPENDBLOCK); |
| if (ret == -1) |
| printf("[EVDEV TEST8]: test passed\n"); |
| else |
| printf("[EVDEV TEST8]: test failed\n"); |
| |
| ret = ioctl(fd, EVIOCSSUSPENDBLOCK); |
| if (!ret) |
| printf("[EVDEV TEST9]: test passed\n"); |
| else |
| printf("[EVDEV TEST9]: test failed\n"); |
| |
| /* byte parameters test*/ |
| ret = ioctl(fd, EVIOCGSUSPENDBLOCK, ¶meter1); |
| if (!ret) |
| printf("[EVDEV TEST10]: test passed\n"); |
| else |
| printf("[EVDEV TEST10]: test failed\n"); |
| |
| ret = ioctl(fd, EVIOCSSUSPENDBLOCK, parameter1); |
| if (!ret) |
| printf("[EVDEV TEST11]: test passed\n"); |
| else |
| printf("[EVDEV TEST11]: test failed\n"); |
| |
| /* int parameters test*/ |
| ret = ioctl(fd, EVIOCGSUSPENDBLOCK, ¶meter2); |
| if (!ret) |
| printf("[EVDEV TEST12]: test passed\n"); |
| else |
| printf("[EVDEV TEST12]: test failed\n"); |
| |
| ret = ioctl(fd, EVIOCSSUSPENDBLOCK, parameter2); |
| if (!ret) |
| printf("[EVDEV TEST13]: test passed\n"); |
| else |
| printf("[EVDEV TEST13]: test failed\n"); |
| |
| /* 64bit parameters test*/ |
| ret = ioctl(fd, EVIOCGSUSPENDBLOCK, ¶meter3); |
| if (!ret) |
| printf("[EVDEV TEST14]: test passed\n"); |
| else |
| printf("[EVDEV TEST14]: test failed\n"); |
| |
| ret = ioctl(fd, EVIOCSSUSPENDBLOCK, parameter3); |
| if (!ret) |
| printf("[EVDEV TEST15]: test passed\n"); |
| else |
| printf("[EVDEV TEST15]: test failed\n"); |
| |
| |
| /*EVIOCSCLOCKID test*/ |
| printf("Starting EVIOCSCLOCKID test:\n"); |
| clk = CLOCK_REALTIME_ALARM; |
| ret = ioctl(fd, EVIOCSCLOCKID, &clk); |
| if (ret < 0) |
| printf("[EVDEV TEST16]: test passed\n"); |
| else |
| printf("[EVDEV TEST16]: test failed\n"); |
| clk = CLOCK_BOOTTIME; |
| ret = ioctl(fd, EVIOCSCLOCKID, &clk); |
| if (ret < 0) |
| printf("[EVDEV TEST17]: test passed\n"); |
| else |
| printf("[EVDEV TEST17]: test failed\n"); |
| |
| ret = ioctl(fd, EVIOCSCLOCKID); |
| if (ret < 0) |
| printf("[EVDEV TEST18]: test passed\n"); |
| else |
| printf("[EVDEV TEST18]: test failed\n"); |
| |
| /*EVIOCSCLOCKID & CLOCK_REALTIME test*/ |
| clk = CLOCK_REALTIME; |
| ret = ioctl(fd, EVIOCSCLOCKID, &clk); |
| if (ret < 0) |
| printf("[EVDEV TEST19]: test failed\n"); |
| else |
| printf("[EVDEV TEST19]: test passed\n"); |
| |
| /*Start generate event here!*/ |
| if ((fd_evdev_run = open("/sys/juice_input/run", O_WRONLY)) < 0) { |
| perror("[EVDEV OPEN SYS RUN]: test failed\n"); |
| goto finish; |
| } else { |
| sprintf(buf, "%d\n", 1); |
| len = strlen(buf); |
| n = write(fd_evdev_run, buf, len); |
| if (n < 0 || n != len) |
| perror("Write /sys/juice_input/run failed!\n"); |
| |
| close(fd_evdev_run); |
| } |
| |
| ret = clock_gettime(CLOCK_REALTIME, &tp1); |
| if (ret < 0) |
| perror("Clock MONOTONIC gettime1 FAILED\n"); |
| |
| /*Get event here!*/ |
| ret = read(fd, ev, sizeof(struct input_event)); |
| if (ret < (int) sizeof(struct input_event)) |
| perror("evtest: error reading\n"); |
| |
| ret = clock_gettime(CLOCK_REALTIME, &tp2); |
| if (ret < 0) |
| perror("Clock MONOTONIC gettime2 FAILED\n"); |
| |
| if (tp1.tv_sec <= ev[0].time.tv_sec && ev[0].time.tv_sec <= tp2.tv_sec) |
| printf("[EVDEV TEST20]: test passed\n"); |
| else |
| printf("[EVDEV TEST20]: test failed\n"); |
| |
| if ((fd_evdev_run = open("/sys/juice_input/run", O_WRONLY)) < 0) { |
| perror("[EVDEV OPEN SYS RUN]: test failed\n"); |
| goto finish; |
| } else { |
| sprintf(buf, "%d\n", 0); |
| len = strlen(buf); |
| n = write(fd_evdev_run, buf, len); |
| if (n < 0 || n != len) |
| perror("Write /sys/juice_input/run failed!\n"); |
| close(fd_evdev_run); |
| } |
| |
| /*EVIOCSCLOCKID & CLOCK_MONOTONIC test*/ |
| close(fd); |
| if ((fd = open(evdevice, O_RDONLY)) < 0) { |
| perror("Test is not finished but exit!\n"); |
| return -1; |
| } |
| |
| clk = CLOCK_MONOTONIC; |
| ret = ioctl(fd, EVIOCSCLOCKID, &clk); |
| if (ret < 0) |
| printf("[EVDEV TEST21]: test failed\n"); |
| else |
| printf("[EVDEV TEST21]: test passed\n"); |
| |
| if ((fd_evdev_run = open("/sys/juice_input/run", O_WRONLY)) < 0) { |
| perror("[EVDEV OPEN SYS RUN]: test failed\n"); |
| goto finish; |
| } else { |
| sprintf(buf, "%d\n", 1); |
| len = strlen(buf); |
| n = write(fd_evdev_run, buf, len); |
| if (n < 0 || n != len) |
| perror("Write /sys/juice_input/run failed!\n"); |
| close(fd_evdev_run); |
| } |
| |
| ret = clock_gettime(CLOCK_MONOTONIC, &tp1); |
| if (ret < 0) |
| perror("Clock MONOTONIC gettime1 FAIL\n"); |
| |
| /*Get event here!*/ |
| ret = read(fd, ev, sizeof(struct input_event)); |
| if (ret < (int) sizeof(struct input_event)) |
| perror("evtest: error reading\n"); |
| |
| ret = clock_gettime(CLOCK_MONOTONIC, &tp2); |
| if (ret < 0) |
| perror("Clock MONOTONIC gettime2 FAILED\n"); |
| |
| if (tp1.tv_sec <= ev[0].time.tv_sec && ev[0].time.tv_sec<= tp2.tv_sec) |
| printf("[EVDEV TEST22]: test passed\n"); |
| else |
| printf("[EVDEV TEST22]: test failed\n"); |
| |
| /*Stop generate input dev event here!*/ |
| if ((fd_evdev_run = open("/sys/juice_input/run", O_WRONLY)) < 0) { |
| perror("[EVDEV OPEN SYS RUN]: test failed\n"); |
| goto finish; |
| } else { |
| sprintf(buf, "%d\n", 0); |
| len = strlen(buf); |
| n = write(fd_evdev_run, buf, len); |
| if (n < 0 || n != len) |
| perror("Write /sys/juice_input/run failed!\n"); |
| close(fd_evdev_run); |
| } |
| |
| finish: |
| close(fd); |
| printf("===========================\n"); |
| return -1; |
| } |