125 lines
4.4 KiB
Diff
125 lines
4.4 KiB
Diff
diff --git a/extendedcommands.c b/extendedcommands.c
|
|
index 30b2f3e..3ec3436 100644
|
|
--- a/extendedcommands.c
|
|
+++ b/extendedcommands.c
|
|
@@ -19,6 +19,7 @@
|
|
|
|
#include <signal.h>
|
|
#include <sys/wait.h>
|
|
+#include <pthread.h>
|
|
|
|
#include "bootloader.h"
|
|
#include "common.h"
|
|
@@ -1158,22 +1159,95 @@ int volume_main(int argc, char **argv) {
|
|
return 0;
|
|
}
|
|
|
|
+static int write_file(char* path, void* data, int data_size)
|
|
+{
|
|
+ int fd;
|
|
+ fd = open(path, O_WRONLY);
|
|
+ if (fd >= 0) {
|
|
+ int written = write(fd, data, data_size);
|
|
+ close(fd);
|
|
+ return written;
|
|
+ }
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+static int read_file(char* path, void* data, int data_size)
|
|
+{
|
|
+ int fd;
|
|
+ fd = open(path, O_RDONLY);
|
|
+ if(fd >= 0){
|
|
+ int readed = read(fd, data, data_size);
|
|
+ close(fd);
|
|
+ return readed;
|
|
+ }
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+static void* battery_thread(void *cookie)
|
|
+{
|
|
+ char status[40];
|
|
+ int state=-1;
|
|
+ int dischargeCount=0;
|
|
+
|
|
+ while(1){
|
|
+ memset(status, 0, sizeof(status));
|
|
+ read_file("/sys/class/power_supply/battery/status", status, sizeof(status)-1);
|
|
+ if(strstr(status, "Full")!=NULL && state!=1){
|
|
+ state=1;
|
|
+ write_file("/sys/class/leds/amber/brightness", "0\n", sizeof("0\n")-1);
|
|
+ write_file("/sys/class/leds/green/brightness", "1\n", sizeof("1\n")-1);
|
|
+ }else if(strstr(status, "Charging")!=NULL && state!=2){
|
|
+ state=2;
|
|
+ write_file("/sys/class/leds/amber/brightness", "1\n", sizeof("1\n")-1);
|
|
+ write_file("/sys/class/leds/green/brightness", "0\n", sizeof("0\n")-1);
|
|
+ }else if(strstr(status, "Discharging")!=NULL){
|
|
+ state=3;
|
|
+ if(dischargeCount==0){ //blink every 2 seconds
|
|
+ read_file("/sys/class/leds/amber/brightness", status, sizeof(status)-1);
|
|
+ if(status[0]=='0') write_file("/sys/class/leds/amber/brightness", "1\n", sizeof("1\n")-1);
|
|
+ else write_file("/sys/class/leds/amber/brightness", "0\n", sizeof("0\n")-1);
|
|
+ }
|
|
+ read_file("/sys/class/power_supply/battery/over_vchg", status, sizeof(status)-1);
|
|
+ dischargeCount=(dischargeCount+1)%4;
|
|
+ }else if(strstr(status,"Not charging")!=NULL && state!=4){
|
|
+ state=4;
|
|
+ write_file("/sys/class/leds/amber/brightness", "0\n", sizeof("0\n")-1);
|
|
+ write_file("/sys/class/leds/green/brightness", "0\n", sizeof("0\n")-1);
|
|
+ sync();
|
|
+ reboot(RB_POWER_OFF);
|
|
+ for(;;);
|
|
+ }
|
|
+ usleep(500000); //wait half a second
|
|
+ }
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
void handle_chargemode() {
|
|
- const char* filename = "/proc/cmdline";
|
|
- struct stat file_info;
|
|
- if (0 != stat(filename, &file_info))
|
|
- return;
|
|
|
|
- int file_len = file_info.st_size;
|
|
- char* file_data = (char*)malloc(file_len + 1);
|
|
- FILE *file = fopen(filename, "rb");
|
|
- if (file == NULL)
|
|
- return;
|
|
- fread(file_data, file_len, 1, file);
|
|
- // supposedly not necessary, but let's be safe.
|
|
- file_data[file_len] = '\0';
|
|
- fclose(file);
|
|
-
|
|
- if (strstr(file_data, "androidboot.mode=offmode_charging") != NULL)
|
|
- reboot(RB_POWER_OFF);
|
|
+ // old code to read /proc/cmdline was broken because file size is always 0 so file_data was always empty string
|
|
+ char cmdline[1024];
|
|
+ memset(cmdline, 0, sizeof(cmdline));
|
|
+ if(read_file("/proc/cmdline", cmdline, sizeof(cmdline)-1) < 0) return;
|
|
+
|
|
+ if (strstr(cmdline, "androidboot.mode=offmode_charging") != NULL)
|
|
+ {
|
|
+ write_file("/sys/class/leds/lcd-backlight/brightness", "0\n", sizeof("0\n")-1);
|
|
+ write_file("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "powersave\n", sizeof("powersave\n")-1);
|
|
+ write_file("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", "245000\n", sizeof("245000\n")-1);
|
|
+ write_file("/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed", "245000\n", sizeof("245000\n")-1);
|
|
+
|
|
+ pthread_t t;
|
|
+ pthread_create(&t, NULL, battery_thread, NULL);
|
|
+
|
|
+ // let recovery kernel charge the battery, reboot on any key press so Android will start as user would expect
|
|
+ ev_init();
|
|
+ struct input_event ev;
|
|
+ do {
|
|
+ ev_get(&ev, 0);
|
|
+ if(ev.type==EV_KEY) write_file("/sys/class/leds/lcd-backlight/brightness", "0\n", sizeof("0\n")-1);
|
|
+ } while (!(ev.type==EV_KEY && ev.code==KEY_END));
|
|
+
|
|
+ reboot(RB_AUTOBOOT);
|
|
+ for(;;);
|
|
+ }
|
|
}
|