00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "config.h"
00032
00033
00034 #include <glib.h>
00035 #include <hal/libhal.h>
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <unistd.h>
00040 #include <dirent.h>
00041 #include <fcntl.h>
00042 #include <sys/statvfs.h>
00043
00044
00045 #include <liberipc/eripc.h>
00046 #include <liberutils/display_utils.h>
00047
00048
00049 #include "log.h"
00050 #include "connections.h"
00051 #include "busy.h"
00052 #include "conf.h"
00053 #include "display.h"
00054 #include "hal.h"
00055 #include "ipc.h"
00056 #include "wacom.h"
00057 #include "xwindow.h"
00058 #include "tasks.h"
00059
00060
00061
00062
00063
00064
00065 enum state_usb
00066 {
00067 STATE_USB_UNKNOWN = 0,
00068 STATE_USB_DISCONNECT_PENDING,
00069 STATE_USB_DISCONNECTED,
00070 STATE_USB_UNMOUNTED,
00071 STATE_USB_MOUNT_CONFIRM,
00072 STATE_USB_MOUNT_PENDING,
00073 STATE_USB_MOUNTED
00074 };
00075
00076
00077
00078
00079
00080
00081 #define AUTOINSTALL_FILE "autoinstall"
00082 #define UPDATE_PATH MOUNTPOINT_CARD "/System/Update/"
00083 #define UPDATE_FILE UPDATE_PATH "update.dat"
00084 #define UPDATE_AUTO_FILE UPDATE_PATH AUTOINSTALL_FILE
00085 #define DRZ_PATH MOUNTPOINT_CARD "/System/drz/"
00086 #define DRZ_AUTO_FILE DRZ_PATH AUTOINSTALL_FILE
00087
00088 #define DEMO_FILE "slideshow.pdf"
00089 #define DEMO_FLIP_INTERVAL 8
00090
00091 #define DRZINSTALL_TOOL "/usr/bin/drzinstall"
00092 #define MDB_INDEXER "/usr/bin/mdbindex"
00093 #define ADOBE_SYNC "/usr/bin/adobe-sync.sh"
00094
00095 #define USB_DEVICE_POLL_INTERVAL 1
00096 #define USB_DEVICE_POLL_TIMEOUT 8 * USB_DEVICE_POLL_INTERVAL
00097 #define USB_DEVICE_ONLINE_DELAY 5
00098
00099 #define BATTERY_LOW_THRESHOLD 5
00100 #define BATTERY_SHUTDOWN_THRESHOLD 2
00101 #define BATTERY_FULL_THRESHOLD 100
00102
00103 #define IDLE_TIMEOUT_SEC 5
00104 #define PREPARE_STANDBY_TIMEOUT_MS 2500
00105 #define CHECK_STANDBY_TIMEOUT_MS 500
00106 #define HOLDOFF_STANDBY_TIMEOUT 10
00107
00108
00109 #define ST_HW_COVER (1 << 4)
00110 #define ST_HW_CARD (1 << 6)
00111 #define ST_HW_USB (1 << 7)
00112
00113
00114 #define WAKEUP_NO_REASON 0 // unknown
00115 #define WAKEUP_KEY 1 // sensor pressed
00116 #define WAKEUP_PEN 2 // wacom pen detected
00117 #define WAKEUP_TIMER 3 // standby timer
00118 #define WAKEUP_BATTERY 4 // battery level update
00119 #define WAKEUP_COVER 5 // cover state change
00120 #define WAKEUP_CARD 6 // mmc card state change
00121 #define WAKEUP_USB 7 // usb state change
00122 #define WAKEUP_CHARGE_DETECTED 8 // charge state change
00123
00124 const char *sys_devices = "/sys/devices";
00125 const char *micro_device_name = "serio";
00126 const char *lun_device_name = "gadget-lun";
00127 const char *sysset_device_name = "sysset0";
00128 const char *power_device_name = "ionpower";
00129 const char *usb_device_name = "fsl-usb2-udc";
00130
00131 static const gint SD_FREE_MB_WARN_LEVEL = 10;
00132
00133 #define read_ionkbd(file, ...) read_sysfs(g_serio, file, __VA_ARGS__)
00134 #define read_sysset(file, ...) read_sysfs(g_sysset, file, __VA_ARGS__)
00135 #define read_power(file, ...) read_sysfs(g_power, file, __VA_ARGS__)
00136 #define read_usb(file, ...) read_sysfs(g_usb, file, __VA_ARGS__)
00137 #define read_lun(file, ...) read_sysfs(g_lun, file, __VA_ARGS__)
00138 #define write_ionkbd(file, ...) write_sysfs(g_serio, file, __VA_ARGS__)
00139 #define write_power(file, ...) write_sysfs(g_power, file, __VA_ARGS__)
00140
00141
00142
00143
00144
00145
00146 static enum state_device device_state = STATE_DEVICE_STARTING;
00147 static enum state_charge charge_state = STATE_CHARGE_UNKNOWN;
00148 static enum state_usb usb_state = STATE_USB_UNKNOWN;
00149 static enum state_card card_state = STATE_CARD_UNKNOWN;
00150 static enum state_power power_state = STATE_POWER_RUN;
00151
00152 static gint g_battery_level = 0;
00153 static gchar *g_serio = NULL;
00154 static gchar *g_sysset = NULL;
00155 static gchar *g_power = NULL;
00156 static gchar *g_usb = NULL;
00157 static gchar *g_card_device = NULL;
00158 static gchar *g_lun = NULL;
00159
00160 static enum rotate_direction g_rotate_direction = ROTATE_UNKOWN;
00161 static enum display_orientation g_orientation = ORIENTATION_PORTRAIT;
00162
00163 static gfloat g_version_micro = 0.0;
00164 static gint g_sensor_disable_config = 0x07;
00165 static gboolean g_sensor_locked = FALSE;
00166 static gboolean g_sound_enabled = FALSE;
00167 static gboolean g_popup_enabled = TRUE;
00168 static gboolean g_idle_enabled = TRUE;
00169 static gboolean g_standby_if_plugged = TRUE;
00170 static guint g_usb_device_source = 0;
00171 static guint g_volume_unmount_source = 0;
00172 static guint g_idle_time_source = 0;
00173 static guint g_standby_timeout_sec = 30*60;
00174 static guint g_holdoff_standby = 0;
00175 static gboolean g_index_splash_enabled = TRUE;
00176 static gboolean g_index_with_metadata = TRUE;
00177 static gboolean g_pageturn_inverted = FALSE;
00178 static gboolean g_wallcharger_found = FALSE;
00179 static gboolean g_demo_mode = FALSE;
00180 static gboolean g_demo_invert_flipbar = FALSE;
00181
00182
00183
00184
00185
00186
00187 static gint read_sysfs (const char *device, const char *filename, const char *format, ...);
00188 static gboolean write_sysfs (const char *device, const char *filename, const char *buffer);
00189 static gchar *find_dir (const char *dir, const char *file, gboolean recurse);
00190
00191 static gboolean usb_driver_load (void);
00192 static gboolean usb_driver_unload (void);
00193 static void usb_connection_finish (void);
00194 static void usb_set_state (enum state_usb new_state);
00195 static void on_usb_connected (gpointer data);
00196 static gboolean on_usb_disconnected (gpointer data);
00197 static gboolean on_usb_read_device_state (gpointer data);
00198 static gboolean on_usb_read_online (gpointer data);
00199
00200 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
00201 static void prepare_standby (void);
00202 static gboolean on_standby (gpointer data);
00203 #endif
00204 static void do_poweroff (void);
00205 static void do_idle (void);
00206 static void set_idle_time (gint time);
00207 static gboolean on_idle_timeout (gpointer data);
00208 static gint get_wakeup_reason (void);
00209
00210 static enum state_charge get_battery_state (gint level, gint charging);
00211 static void update_battery_info (gint cur_level, enum state_charge cur_state, gboolean force_send);
00212 static gboolean write_ionkbd_orientation (gint orientation);
00213 static gboolean write_ionkbd_battery_alerts(gint l1, gint l2, gint l3, gint l4, gint l5);
00214
00215 static void on_eject_continue (gpointer data);
00216 static void on_poweroff_continue (gpointer data);
00217 static void on_restart_continue (gpointer data);
00218 static void on_install_drz_ready (GPid pid, gint status, gpointer data);
00219 static void report_unmounting_volumes (void);
00220 static void check_hardware (void);
00221 static gboolean check_and_install_drz (void);
00222 static void do_unmount (gboolean show_busy, const char *splash,
00223 gpointer callback_function, gpointer user_data);
00224
00225
00226
00227
00228
00229
00230 void sys_set_services(void)
00231 {
00232 LOGPRINTF("entry");
00233
00234
00235
00236 g_sysset = find_dir(sys_devices, sysset_device_name, TRUE);
00237 if (!g_sysset)
00238 {
00239 ERRORPRINTF("%s not found or not unique", sysset_device_name);
00240 }
00241 else
00242 {
00243 LOGPRINTF("Sysset found at %s", g_sysset);
00244 }
00245
00246
00247
00248 g_power = find_dir(sys_devices, power_device_name, TRUE);
00249 if (!g_power)
00250 {
00251 ERRORPRINTF("%s not found or not unique", power_device_name);
00252 }
00253 else
00254 {
00255 LOGPRINTF("Ionpower found at %s", g_power);
00256 }
00257
00258
00259
00260 g_serio = find_dir(sys_devices, micro_device_name, FALSE);
00261 if (!g_serio)
00262 {
00263 ERRORPRINTF("%s not found or not unique", micro_device_name);
00264 }
00265 else
00266 {
00267 LOGPRINTF("Device micro found as %s", g_serio);
00268
00269 read_ionkbd("micro_ver", "%f", &g_version_micro);
00270 LOGPRINTF("Micro version %.2f", g_version_micro);
00271
00272
00273 write_ionkbd_battery_alerts(BATTERY_LOW_THRESHOLD, 13, 38, 63, 88);
00274
00275
00276 sys_get_battery(&g_battery_level, &charge_state, NULL);
00277
00278
00279 sys_update_rgb_led();
00280 }
00281
00282
00283 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00284 if (g_version_micro < 0.34f)
00285 {
00286 g_idle_enabled = FALSE;
00287 }
00288 #endif
00289 if (sys_is_emulator())
00290 {
00291 g_idle_enabled = FALSE;
00292 }
00293
00294 if (g_idle_enabled)
00295 {
00296 g_idle_time_source = g_timeout_add_seconds(IDLE_TIMEOUT_SEC, on_idle_timeout, NULL);
00297 }
00298 }
00299
00300
00301 void sys_starting_finished()
00302 {
00303 if ((card_state != STATE_CARD_MOUNTED) &&
00304 (card_state != STATE_CARD_INACCESSIBLE) &&
00305 (card_state != STATE_CARD_INDEXING))
00306 {
00307 ipc_show_splash("nosd");
00308 }
00309
00310 conf_set_first_boot(FALSE);
00311
00312
00313 check_hardware();
00314 }
00315
00316
00317 void sys_set_idle_mode(gboolean idle_enabled)
00318 {
00319 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00320 if (g_version_micro < 0.34f)
00321 {
00322 g_idle_enabled = FALSE;
00323 }
00324 else
00325 #endif
00326 if (sys_is_emulator())
00327 {
00328 g_idle_enabled = FALSE;
00329 }
00330 else
00331 {
00332 g_idle_enabled = idle_enabled;
00333 }
00334
00335 if (g_idle_enabled)
00336 {
00337
00338 sys_reset_idle_time();
00339 }
00340 else
00341 {
00342 if (g_idle_time_source)
00343 {
00344 g_source_remove(g_idle_time_source);
00345 g_idle_time_source = 0;
00346 }
00347 }
00348 }
00349
00350
00351 void sys_set_standby_time(guint time_sec)
00352 {
00353 g_standby_timeout_sec = time_sec;
00354 }
00355
00356
00357 void sys_set_standby_mode(gboolean standby_if_plugged)
00358 {
00359 g_standby_if_plugged = standby_if_plugged;
00360 }
00361
00362
00363 void sys_reset_idle_time()
00364 {
00365 set_idle_time(0);
00366 }
00367
00368
00369 gboolean sys_set_beeper_config(gboolean use_sound)
00370 {
00371 LOGPRINTF("entry");
00372
00373 g_sound_enabled = use_sound;
00374 return TRUE;
00375 }
00376
00377
00378 gboolean sys_set_beeper(gint duration_ms, const char *tone)
00379 {
00380 LOGPRINTF("entry");
00381
00382 gboolean retval = FALSE;
00383 char *buffer = NULL;
00384 gint beep_pitch = -1;
00385
00386 if (!g_sound_enabled)
00387 {
00388 return FALSE;
00389 }
00390
00391 if (g_ascii_strcasecmp(tone, "high") == 0)
00392 {
00393 beep_pitch = 1;
00394 }
00395 else if (g_ascii_strcasecmp(tone, "low") == 0)
00396 {
00397 beep_pitch = 0;
00398 }
00399 else
00400 {
00401 WARNPRINTF("Unknown tone: %s", tone);
00402 }
00403
00404 if (beep_pitch != -1)
00405 {
00406
00407
00408 buffer = g_strdup_printf("%d", ((duration_ms / 10) & 0xEF) | ((beep_pitch & 0x01) << 7));
00409 retval = write_ionkbd("beeper", buffer);
00410 g_free(buffer);
00411 }
00412
00413 return retval;
00414 }
00415
00416
00417 gboolean sys_set_rgb_led(enum led_color color, gint flash_ms)
00418 {
00419 LOGPRINTF("entry");
00420
00421 gboolean retval = FALSE;
00422 gchar *buffer = NULL;
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433 buffer = g_strdup_printf("%d %d", (color & 0xFF), (flash_ms / 500) & 0xFF);
00434 retval = write_ionkbd("rgbled", buffer);
00435 g_free(buffer);
00436
00437 return retval;
00438 }
00439
00440
00441 gboolean sys_set_index_with_metadata(gboolean with_metadata)
00442 {
00443 LOGPRINTF("entry");
00444
00445 g_index_with_metadata = with_metadata;
00446
00447 return TRUE;
00448 }
00449
00450 gboolean sys_set_pageturn_inverted(gboolean is_inverted)
00451 {
00452 LOGPRINTF("entry");
00453
00454 g_pageturn_inverted = is_inverted;
00455
00456 ipc_send_changed_pageturn_inverted(g_pageturn_inverted);
00457
00458 return TRUE;
00459 }
00460
00461
00462 gboolean sys_set_rotate_direction(const char *direction)
00463 {
00464 LOGPRINTF("entry");
00465
00466 g_return_val_if_fail(direction!=NULL, FALSE);
00467
00468 if (strcmp(direction, "clockwise") == 0)
00469 {
00470 g_rotate_direction = ROTATE_CLOCKWISE;
00471 }
00472 else
00473 {
00474 g_rotate_direction = ROTATE_ANTICLOCKWISE;
00475 }
00476
00477 return TRUE;
00478 }
00479
00480
00481 static gboolean on_rotated(gpointer data)
00482 {
00483 LOGPRINTF("entry");
00484
00485 display_update_return_control(DM_HINT_FULL);
00486
00487
00488 write_ionkbd_orientation(g_orientation);
00489
00490
00491 ipc_send_changed_orientation(g_orientation);
00492
00493 return FALSE;
00494 }
00495
00496
00497 gboolean sys_set_orientation(const char *orientation)
00498 {
00499 LOGPRINTF("entry");
00500
00501 g_return_val_if_fail(orientation!=NULL, FALSE);
00502
00503 static gboolean is_portrait = TRUE;
00504 gboolean retval = FALSE;
00505 gboolean is_changed = FALSE;
00506
00507 if (g_ascii_strcasecmp(orientation, "portrait") == 0)
00508 {
00509 if (!is_portrait)
00510 {
00511 is_portrait = TRUE;
00512 is_changed = TRUE;
00513 }
00514 }
00515 else if (g_ascii_strcasecmp(orientation, "landscape") == 0)
00516 {
00517 if (is_portrait)
00518 {
00519 is_portrait = FALSE;
00520 is_changed = TRUE;
00521 }
00522 }
00523 else if (g_ascii_strcasecmp(orientation, "toggle") == 0)
00524 {
00525 is_portrait = !is_portrait;
00526 is_changed = TRUE;
00527 }
00528 else
00529 {
00530 WARNPRINTF("Unknown orientation: %s", orientation);
00531 }
00532
00533 if (is_changed)
00534 {
00535 display_gain_control();
00536
00537 if (is_portrait)
00538 {
00539
00540 sys_spawn_sync("xrandr -display 0:0 --screen 0 --orientation normal");
00541 g_orientation = ORIENTATION_PORTRAIT;
00542 }
00543 else
00544 {
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 if (g_rotate_direction == ROTATE_CLOCKWISE)
00573 {
00574
00575 sys_spawn_sync("xrandr -display 0:0 --screen 0 --orientation left");
00576 g_orientation = ORIENTATION_LANDSCAPE_CLOCKWISE;
00577 }
00578 else
00579 {
00580
00581 sys_spawn_sync("xrandr -display 0:0 --screen 0 --orientation right");
00582 g_orientation = ORIENTATION_LANDSCAPE_ANTICLOCKWISE;
00583 }
00584 }
00585
00586
00587 g_timeout_add(800, (GSourceFunc)on_rotated, NULL);
00588 }
00589
00590 return retval;
00591 }
00592
00593
00594 gboolean sys_set_sensor_feedback(gboolean use_light, gboolean use_sound)
00595 {
00596 LOGPRINTF("entry");
00597
00598 gboolean retval = FALSE;
00599 char *buffer = NULL;
00600
00601
00602
00603 buffer = g_strdup_printf("%d", use_sound | (use_light << 1));
00604 retval = write_ionkbd("sensor_feedback", buffer);
00605
00606 g_free(buffer);
00607 return retval;
00608 }
00609
00610
00611 gboolean sys_set_sensor_lock_config(gboolean lock_left, gboolean lock_right, gboolean lock_middle)
00612 {
00613 LOGPRINTF("entry");
00614
00615
00616
00617
00618 g_sensor_disable_config = !lock_right | (!lock_left << 1) | (!lock_middle << 2);
00619
00620
00621 sys_set_sensor_lock("update");
00622
00623 return TRUE;
00624 }
00625
00626
00627 gboolean sys_set_sensor_lock(const char *lock_mode)
00628 {
00629 LOGPRINTF("entry");
00630
00631 g_return_val_if_fail(lock_mode!=NULL, FALSE);
00632
00633 gboolean retval = FALSE;
00634 gboolean is_changed = FALSE;
00635
00636 if (g_ascii_strcasecmp(lock_mode, "lock") == 0)
00637 {
00638 if (!g_sensor_locked)
00639 {
00640 g_sensor_locked = TRUE;
00641 is_changed = TRUE;
00642 }
00643 }
00644 else if (g_ascii_strcasecmp(lock_mode, "unlock") == 0)
00645 {
00646 if (g_sensor_locked)
00647 {
00648 g_sensor_locked = FALSE;
00649 is_changed = TRUE;
00650 }
00651 }
00652 else if (g_ascii_strcasecmp(lock_mode, "toggle") == 0)
00653 {
00654 g_sensor_locked = !g_sensor_locked;
00655 is_changed = TRUE;
00656 }
00657 else if (g_ascii_strcasecmp(lock_mode, "update") == 0)
00658 {
00659 if (g_sensor_locked)
00660 {
00661 is_changed = TRUE;
00662 }
00663
00664 if (g_sensor_disable_config == 7)
00665 {
00666 g_sensor_locked = FALSE;
00667 }
00668 }
00669 else
00670 {
00671 WARNPRINTF("Unknown lock mode: %s", lock_mode);
00672 }
00673
00674 if (is_changed)
00675 {
00676 if (g_sensor_locked)
00677 {
00678
00679 char *lock_config = g_strdup_printf("%d", g_sensor_disable_config);
00680 write_ionkbd("sensor_enable", lock_config);
00681 g_free(lock_config);
00682
00683
00684 ipc_menu_set_item_state("lock", "general", "selected");
00685 ipc_menu_set_statusitem_state("statusbar_lock", "locked");
00686 }
00687 else
00688 {
00689
00690 write_ionkbd("sensor_enable", "7");
00691
00692
00693 ipc_menu_set_item_state("lock", "general", "normal");
00694 ipc_menu_set_statusitem_state("statusbar_lock", "normal");
00695 }
00696 }
00697
00698 return retval;
00699 }
00700
00701
00702 void sys_eject_card(gboolean silent)
00703 {
00704 LOGPRINTF("entry");
00705 do_unmount(!silent, NULL, on_eject_continue, (gpointer) silent);
00706 }
00707
00708
00709 void sys_standby(void)
00710 {
00711 LOGPRINTF("entry");
00712
00713
00714 if ((device_state == STATE_DEVICE_STARTING) && conf_get_first_boot())
00715 {
00716 busy_add_background(0);
00717 sys_spawn_sync("shutdown -h now");
00718 return;
00719 }
00720
00721 if ( usb_state == STATE_USB_MOUNT_PENDING ||
00722 usb_state == STATE_USB_MOUNTED ||
00723 card_state == STATE_CARD_INDEXING )
00724 {
00725 LOGPRINTF("System is connected to PC or indexing, don't enter standby");
00726 return;
00727 }
00728
00729 if (g_holdoff_standby)
00730 {
00731 LOGPRINTF("Just back from standby, ignore key press");
00732 return;
00733 }
00734
00735 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
00736 prepare_standby();
00737 #elif MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00738 do_poweroff();
00739 #else
00740 #error Unhandled machine type
00741 #endif
00742 }
00743
00744
00745 void sys_restart(void)
00746 {
00747 LOGPRINTF("entry");
00748
00749 device_state = STATE_DEVICE_STOPPING;
00750 busy_add_foreground(0, BUSY_DIALOG_NONE, NULL);
00751 do_unmount(TRUE, "restart", on_restart_continue, NULL);
00752 }
00753
00754
00755 static gboolean sys_check_and_install_firmware(void)
00756 {
00757 LOGPRINTF("entry");
00758
00759 if (card_state == STATE_CARD_MOUNTED)
00760 {
00761 if (g_file_test(UPDATE_FILE, G_FILE_TEST_IS_REGULAR))
00762 {
00763 LOGPRINTF("Update file found");
00764
00765 if (g_file_test(UPDATE_AUTO_FILE, G_FILE_TEST_IS_REGULAR))
00766 {
00767
00768 LOGPRINTF("Autoinstall file found, restart device");
00769 sys_restart();
00770 }
00771 else
00772 {
00773
00774 ipc_confirm_install_update(TRUE);
00775 }
00776 return TRUE;
00777 }
00778 }
00779 return FALSE;
00780 }
00781
00782
00783 gboolean sys_usb_connect()
00784 {
00785 gboolean retval = FALSE;
00786
00787 LOGPRINTF("entry");
00788
00789 if ((card_state == STATE_CARD_MOUNTED) &&
00790 (usb_state == STATE_USB_MOUNT_CONFIRM))
00791 {
00792 usb_set_state(STATE_USB_MOUNT_PENDING);
00793 do_unmount(TRUE, "usbconnect", on_usb_connected, NULL);
00794 retval = TRUE;
00795 }
00796 else
00797 {
00798 LOGPRINTF("no volume mounted or not confirmed");
00799 }
00800
00801 return retval;
00802 }
00803
00804
00805 gboolean sys_spawn_async(const char *command)
00806 {
00807 LOGPRINTF("entry");
00808 return sys_spawn_async_with_callback(command, NULL, NULL);
00809 }
00810
00811
00812 gboolean sys_spawn_async_with_callback(const char *command, GChildWatchFunc callback, gpointer data)
00813 {
00814 LOGPRINTF("entry");
00815
00816 g_return_val_if_fail(command!=NULL, FALSE);
00817
00818 char *argv[4];
00819 gboolean retval = FALSE;
00820 GError *error = NULL;
00821 GPid child_pid;
00822
00823 argv[0] = "/bin/sh";
00824 argv[1] = "-c";
00825 argv[2] = (char*) command;
00826 argv[3] = NULL;
00827
00828 LOGPRINTF("Spawning: %s", argv[2]);
00829
00830 if (callback)
00831 {
00832 retval = g_spawn_async(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &child_pid, &error);
00833 }
00834 else
00835 {
00836 retval = g_spawn_async(NULL, argv, NULL, 0, NULL, NULL, NULL, &error);
00837 }
00838
00839 if (error)
00840 {
00841 WARNPRINTF("Execution of '%s' failed with error: %s", command, error->message);
00842 g_error_free(error);
00843 return FALSE;
00844 }
00845
00846 if (retval && callback)
00847 {
00848 LOGPRINTF("Add callback handler for pid [%d]", (gint) child_pid);
00849 g_child_watch_add(child_pid, (GChildWatchFunc) callback, data);
00850 }
00851
00852 return retval;
00853 }
00854
00855
00856 gboolean sys_spawn_sync(const char *command)
00857 {
00858 LOGPRINTF("entry");
00859
00860 g_return_val_if_fail(command!=NULL, FALSE);
00861
00862 char *argv[4];
00863 gboolean retval = FALSE;
00864 GError *error = NULL;
00865
00866 argv[0] = "/bin/sh";
00867 argv[1] = "-c";
00868 argv[2] = (char*) command;
00869 argv[3] = NULL;
00870
00871 LOGPRINTF("Spawning: %s", argv[2]);
00872
00873 retval = g_spawn_sync(NULL, argv, NULL, 0, NULL, NULL, NULL, NULL, NULL, &error);
00874
00875 if (error)
00876 {
00877 WARNPRINTF("Execution of '%s' failed with error: %s", command, error->message);
00878 g_error_free(error);
00879 return FALSE;
00880 }
00881
00882 return retval;
00883 }
00884
00885
00886 gint sys_battery_level()
00887 {
00888 int level;
00889 enum state_charge state;
00890
00891 sys_get_battery(&level, &state, NULL);
00892
00893 return level;
00894 }
00895
00896
00897 gboolean sys_get_battery(int *level, enum state_charge *state, int *timeleft)
00898 {
00899 LOGPRINTF("entry");
00900
00901 gboolean result = FALSE;
00902 gint cur_level = 0;
00903 gint charging = 0;
00904 gint rc = 0;
00905
00906 if (sys_is_emulator())
00907 {
00908 *level = 100;
00909 *state = STATE_CHARGE_DISCHARGING;
00910 return TRUE;
00911 }
00912
00913 rc = read_ionkbd("battery", "%d %d", &cur_level, &charging);
00914
00915 if ((rc > 0) && (cur_level != 0xFF))
00916 {
00917 *level = cur_level;
00918 *state = get_battery_state(cur_level, charging);
00919
00920 LOGPRINTF("battery level %d, charging %d", cur_level, charging);
00921 result = TRUE;
00922 }
00923 else
00924 {
00925 WARNPRINTF("Failed to read battery information");
00926 }
00927
00928 return result;
00929 }
00930
00931
00932 void sys_update_battery(const char *battery)
00933 {
00934 gint charging = 0;
00935 gint cur_level = 0;
00936 enum state_charge cur_state = STATE_CHARGE_UNKNOWN;
00937
00938 LOGPRINTF("entry");
00939
00940 sscanf(battery, "%d %d", &cur_level, &charging);
00941 cur_state = get_battery_state(cur_level, charging);
00942 update_battery_info(cur_level, cur_state, FALSE);
00943 }
00944
00945
00946 gfloat sys_get_display_vcom()
00947 {
00948 LOGPRINTF("entry");
00949 gfloat vcom;
00950
00951 read_sysset("display/vcom", "%f", &vcom);
00952
00953 return vcom;
00954 }
00955
00956
00957 static void set_keypress_generation(int delay)
00958 {
00959 int fd = open("/sys/devices/serio0/demo_mode", O_WRONLY);
00960 if (fd == -1) {
00961 perror("open");
00962 return;
00963 } else {
00964 char buffer[10];
00965 sprintf(buffer, "%d", delay);
00966 write(fd, buffer, strlen(buffer));
00967 close(fd);
00968 }
00969
00970 }
00971
00972
00973 static gboolean start_demo(gpointer data)
00974 {
00975 set_keypress_generation(DEMO_FLIP_INTERVAL);
00976 return FALSE;
00977 }
00978
00979
00980 static void start_demo_mode()
00981 {
00982 WARNPRINTF("found "DEMO_FILE", starting demo mode");
00983 if (g_demo_mode)
00984 {
00985 ERRORPRINTF("already in demo mode");
00986 return;
00987 }
00988 g_demo_invert_flipbar = g_pageturn_inverted;
00989 if (g_pageturn_inverted) {
00990 sys_set_pageturn_inverted(FALSE);
00991 }
00992
00993 wacom_disable();
00994 write_ionkbd("sensor_enable", "0");
00995
00996
00997 ipc_send_demo_mode(TRUE);
00998 task_start("/usr/bin/uds "MOUNTPOINT_CARD"/"DEMO_FILE, MOUNTPOINT_CARD, "Slideshow", NULL, NULL, NULL);
00999
01000
01001 g_timeout_add(5000, start_demo, NULL);
01002 g_demo_mode = TRUE;
01003 }
01004
01005
01006 static void stop_demo_mode()
01007 {
01008 if (!g_demo_mode) return;
01009
01010 WARNPRINTF("stopping demo mode");
01011 set_keypress_generation(0);
01012 if (g_demo_invert_flipbar) {
01013 sys_set_pageturn_inverted(TRUE);
01014 }
01015 ipc_send_demo_mode(FALSE);
01016 wacom_enable();
01017 if (g_sensor_locked) {
01018 char buf[20];
01019 sprintf(buf, "%d", g_sensor_disable_config);
01020 write_ionkbd("sensor_enable", buf);
01021 } else {
01022 write_ionkbd("sensor_enable", "7");
01023
01024 }
01025
01026 g_demo_mode = FALSE;
01027 }
01028
01029
01030 static void update_usb_state(gboolean connected)
01031 {
01032 static gboolean last_connected = FALSE;
01033
01034
01035 if (usb_state != STATE_CHARGE_UNKNOWN
01036 && connected == last_connected) return;
01037
01038 last_connected = connected;
01039
01040 if (connected)
01041 {
01042
01043 usb_set_state(STATE_USB_UNMOUNTED);
01044
01045 if (card_state == STATE_CARD_MOUNTED)
01046 {
01047 LOGPRINTF("SD/MMC available, load USB drivers check for host");
01048 if (usb_driver_load())
01049 {
01050 busy_add_background(0);
01051 g_usb_device_source = g_timeout_add_seconds(USB_DEVICE_POLL_INTERVAL, on_usb_read_device_state, NULL);
01052 }
01053 }
01054 else
01055 {
01056 LOGPRINTF("Card not mounted; don't connect to USB, card_state [%d]", card_state);
01057 }
01058 }
01059 else
01060 {
01061
01062 if (usb_state == STATE_USB_MOUNT_PENDING)
01063 {
01064 usb_set_state(STATE_USB_DISCONNECT_PENDING);
01065 }
01066 else
01067 {
01068 usb_set_state(STATE_USB_DISCONNECTED);
01069 }
01070 }
01071 }
01072
01073
01074 void sys_update_hardware(const char *hardware)
01075 {
01076 LOGPRINTF("entry");
01077
01078 static gint old_state = 0;
01079 gint cur_state = 0;
01080
01081 sscanf(hardware, "%d", &cur_state);
01082
01083 LOGPRINTF("old state [%d] cur state [%d]", old_state, cur_state);
01084
01085 if ( ((old_state & ST_HW_CARD) != (cur_state & ST_HW_CARD))
01086 ||
01087 (card_state == STATE_CARD_UNKNOWN) )
01088 {
01089
01090
01091 if (!(cur_state & ST_HW_CARD))
01092 {
01093
01094 LOGPRINTF("SD/MMC card inserted");
01095 }
01096 else
01097 {
01098
01099 LOGPRINTF("SD/MMC card ejected");
01100 stop_demo_mode();
01101 }
01102 }
01103
01104 update_usb_state(cur_state & ST_HW_USB);
01105
01106
01107 sys_reset_idle_time();
01108
01109
01110 old_state = cur_state;
01111 }
01112
01113
01114 gboolean sys_has_network(void)
01115 {
01116 gboolean ignore = FALSE;
01117 gboolean found_wifi = FALSE;
01118 gboolean found_bluetooth = FALSE;
01119 gboolean found_3g = FALSE;
01120
01121 sys_get_device_capabilities(&ignore, &found_wifi, &found_bluetooth, &found_3g);
01122
01123 return (found_wifi || found_bluetooth || found_3g);
01124 }
01125
01126
01127 gboolean sys_has_stylus(void)
01128 {
01129 gboolean found_stylus = FALSE;
01130 gboolean ignore = FALSE;
01131
01132 sys_get_device_capabilities(&found_stylus, &ignore, &ignore, &ignore);
01133
01134 return (found_stylus);
01135 }
01136
01137
01138 gboolean sys_is_dr800(void)
01139 {
01140 int type = 0;
01141 int rc = read_ionkbd("device_type", "%d", &type);
01142 if ((rc > 0) && ((type == 3) || (type == 4) || (type == 5)))
01143 {
01144 return TRUE;
01145 }
01146
01147 return FALSE;
01148 }
01149
01150
01151 gboolean sys_is_emulator(void)
01152 {
01153 char hostname[100] = {0};
01154 int rc = gethostname(hostname, sizeof(hostname));
01155 if ((rc == 0) && (strcmp(hostname, "qemuarm") == 0))
01156 {
01157 return TRUE;
01158 }
01159 return FALSE;
01160 }
01161
01162
01163 void sys_get_device_capabilities(gboolean *has_stylus, gboolean *has_wifi, gboolean *has_bluetooth, gboolean *has_3g)
01164 {
01165 LOGPRINTF("entry");
01166
01167 gboolean found_stylus = FALSE;
01168 gboolean found_wifi = FALSE;
01169 gboolean found_bluetooth = FALSE;
01170 gboolean found_3g = FALSE;
01171 char data[64];
01172
01173 bzero(data, sizeof(data));
01174 read_sysset("wacom/serial", "%s", &data);
01175 if ((data[0] != '\0') && (data[0] != '\xFF'))
01176 {
01177 LOGPRINTF("data %s", data);
01178 if ((strlen(data) > 0) && (strtoul(data,NULL,16) != 0))
01179 {
01180 found_stylus = TRUE;
01181 }
01182 }
01183
01184 bzero(data, sizeof(data));
01185 read_sysset("wifi/address", "%s", &data);
01186 if ((data[0] != '\0') && (data[0] != '\xFF'))
01187 {
01188 if (strlen(data) > 0)
01189 {
01190 found_wifi = TRUE;
01191 }
01192 }
01193
01194 bzero(data, sizeof(data));
01195 read_sysset("bluetooth/address", "%s", &data);
01196 if ((data[0] != '\0') && (data[0] != '\xFF'))
01197 {
01198 if (strlen(data) > 0)
01199 {
01200 found_bluetooth = TRUE;
01201 }
01202 }
01203
01204 bzero(data, sizeof(data));
01205 read_sysset("3g/imei", "%s", &data);
01206 if ((data[0] != '\0') && (data[0] != '\xFF'))
01207 {
01208 if (strlen(data) > 0)
01209 {
01210 found_3g = TRUE;
01211 }
01212 }
01213
01214 bzero(data, sizeof(data));
01215 read_sysset("3g/meid", "%s", &data);
01216 if ((data[0] != '\0') && (data[0] != '\xFF'))
01217 {
01218 if (strlen(data) > 0)
01219 {
01220 found_3g = TRUE;
01221 }
01222 }
01223
01224 if (sys_is_emulator())
01225 {
01226 found_stylus = TRUE;
01227 found_3g = TRUE;
01228 }
01229
01230 LOGPRINTF("capabilities from sysset: wacom %d, wifi %d, bluetooth %d, 3g %d", found_stylus, found_wifi, found_bluetooth, found_3g);
01231
01232 *has_stylus = found_stylus;
01233 *has_wifi = found_wifi;
01234 *has_bluetooth = found_bluetooth;
01235 *has_3g = found_3g;
01236 }
01237
01238
01239 static gboolean check_disk_free(void)
01240 {
01241 LOGPRINTF("entry");
01242
01243 if (card_state == STATE_CARD_MOUNTED)
01244 {
01245
01246 gint64 mbfree = -1;
01247
01248 LOGPRINTF("mbfree [%lld]", mbfree);
01249
01250 struct statvfs s;
01251 if (statvfs(MOUNTPOINT_CARD, &s) == 0)
01252 {
01253 mbfree = s.f_frsize * s.f_bavail >> 20;
01254 }
01255
01256 if (mbfree == -1)
01257 {
01258 ERRORPRINTF("failed to get free space from mount point [%s]", MOUNTPOINT_CARD);
01259 }
01260 else if (mbfree <= SD_FREE_MB_WARN_LEVEL)
01261 {
01262 WARNPRINTF("sdcard disk space low, free %lld Mb", mbfree);
01263 ipc_show_message("sdfullwarn", NULL, NULL);
01264 return TRUE;
01265 }
01266 }
01267 return FALSE;
01268 }
01269
01270
01271 static void on_card_indexed(GPid pid, gint status, gpointer data)
01272 {
01273 LOGPRINTF("entry pid [%d] status [%d]", (gint) pid, status);
01274
01275 g_spawn_close_pid(pid);
01276
01277 busy_remove_foreground(0);
01278
01279 sys_set_card(STATE_CARD_MOUNTED);
01280
01281 if (g_index_splash_enabled)
01282 {
01283 ipc_show_splash("hide");
01284 gboolean do_drz = check_and_install_drz();
01285 gboolean do_firmware = sys_check_and_install_firmware();
01286 gboolean do_disk = check_disk_free();
01287
01288 if (!(do_drz || do_firmware || do_disk)) {
01289 if (g_file_test(MOUNTPOINT_CARD"/"DEMO_FILE, G_FILE_TEST_EXISTS)) {
01290 start_demo_mode();
01291 }
01292 }
01293 }
01294 else
01295 {
01296
01297 g_index_splash_enabled = TRUE;
01298 }
01299 }
01300
01301
01302 void sys_set_card(enum state_card new_state)
01303 {
01304 #if (LOGGING_ON)
01305 const gchar *state_str[] = { "UKNOWN", "INACCESSIBLE", "EJECTED", "UNMOUNTING", "UNMOUNTED", "INDEXING", "MOUNTED" };
01306 LOGPRINTF("prepare card_state %s > %s", state_str[card_state], state_str[new_state]);
01307 #endif
01308
01309 switch (new_state)
01310 {
01311 case STATE_CARD_EJECTED:
01312 ipc_show_splash("nosd");
01313
01314
01315 sys_spawn_async(ERCONFTOOL_DELETE);
01316
01317 if ( (usb_state != STATE_USB_DISCONNECTED)
01318 && (usb_state != STATE_USB_UNMOUNTED) )
01319 {
01320
01321 LOGPRINTF("change card_state %s > %s", state_str[card_state], state_str[new_state]);
01322 card_state = new_state;
01323 usb_set_state(STATE_USB_UNMOUNTED);
01324 }
01325 break;
01326
01327 case STATE_CARD_INDEXING:
01328 {
01329 busy_add_foreground(0, BUSY_DIALOG_NONE, NULL);
01330 if (g_index_splash_enabled)
01331 {
01332 ipc_show_splash("indexing");
01333 }
01334 sys_spawn_sync(ERCONFTOOL_IMPORT);
01335
01336
01337 sys_spawn_sync(ADOBE_SYNC);
01338
01339 gchar *command = g_strdup_printf("%s %s %s",
01340 MDB_INDEXER,
01341 MOUNTPOINT_CARD,
01342 g_index_with_metadata ? "" : "--quick");
01343 sys_spawn_async_with_callback(command, on_card_indexed, (gpointer) FALSE);
01344 g_free(command);
01345
01346 }
01347 break;
01348
01349 case STATE_CARD_MOUNTED:
01350 ipc_send_volume_mounted(MOUNTPOINT_CARD);
01351 g_card_device = hal_get_mountpoint_device();
01352 break;
01353
01354 case STATE_CARD_INACCESSIBLE:
01355 case STATE_CARD_UNMOUNTED:
01356 default:
01357 break;
01358 }
01359
01360 LOGPRINTF("change card_state %s > %s", state_str[card_state], state_str[new_state]);
01361
01362 card_state = new_state;
01363 }
01364
01365
01366 enum state_card sys_get_card()
01367 {
01368 return card_state;
01369 }
01370
01371
01372 void sys_usb_no_connect()
01373 {
01374 LOGPRINTF("entry");
01375 if (usb_state == STATE_USB_MOUNT_CONFIRM)
01376 {
01377 usb_set_state(STATE_USB_UNMOUNTED);
01378 }
01379 }
01380
01381
01382 gboolean sys_request_popup(const char *state)
01383 {
01384 g_return_val_if_fail(state!=NULL, FALSE);
01385
01386 if (strcmp(state, "localblock") == 0)
01387 {
01388 g_popup_enabled = FALSE;
01389 }
01390 else if (strcmp(state, "block") == 0)
01391 {
01392 g_popup_enabled = FALSE;
01393 ipc_show_popup(state);
01394 }
01395 else if (strcmp(state, "localunblock") == 0)
01396 {
01397 g_popup_enabled = TRUE;
01398 }
01399 else if (strcmp(state, "unblock") == 0)
01400 {
01401 g_popup_enabled = TRUE;
01402 ipc_show_popup(state);
01403 }
01404 else if (g_popup_enabled)
01405 {
01406 ipc_show_popup(state);
01407 }
01408 return TRUE;
01409 }
01410
01411
01412 gboolean sys_set_power(const char *device, gint mode)
01413 {
01414 LOGPRINTF("entry");
01415
01416 gboolean retval = FALSE;
01417
01418 gchar *modestr = g_strdup_printf("%d", mode);
01419 retval = write_power(device, modestr);
01420 g_free(modestr);
01421
01422 return retval;
01423 }
01424
01425
01426 gboolean sys_get_power(const char *device, gint *mode)
01427 {
01428 LOGPRINTF("entry");
01429
01430 gboolean retval = FALSE;
01431 retval = read_power(device, "%d", &mode);
01432
01433 return retval;
01434 }
01435
01436
01437 guint sys_get_orientation(void)
01438 {
01439 return g_orientation;
01440 }
01441
01442
01443 gboolean sys_get_pageturn_inverted(void)
01444 {
01445 return g_pageturn_inverted;
01446 }
01447
01448
01449 static void on_install_drz_ready(GPid pid, gint status, gpointer data)
01450 {
01451 WARNPRINTF("pid [%d] exit status [%d]", (gint) pid, status);
01452 g_spawn_close_pid(pid);
01453 }
01454
01455
01456 void sys_install_drz(void)
01457 {
01458
01459
01460 gchar *command = g_strdup_printf(DRZINSTALL_TOOL" -s %s", DRZ_PATH);
01461 sys_spawn_async_with_callback(command, on_install_drz_ready, NULL);
01462 g_free(command);
01463 return;
01464 }
01465
01466
01467 static gboolean check_and_install_drz(void)
01468 {
01469 LOGPRINTF("entry");
01470
01471 if (card_state == STATE_CARD_MOUNTED)
01472 {
01473 if (g_file_test(DRZ_PATH, G_FILE_TEST_IS_DIR))
01474 {
01475 LOGPRINTF("DRZ path found");
01476
01477 if (g_file_test(DRZ_AUTO_FILE, G_FILE_TEST_IS_REGULAR))
01478 {
01479
01480 LOGPRINTF("Autoinstall file found, install DRZ");
01481 sys_install_drz();
01482 }
01483 else
01484 {
01485
01486 ipc_confirm_install_drz(TRUE);
01487 }
01488
01489 return TRUE;
01490 }
01491 }
01492
01493 return FALSE;
01494 }
01495
01496
01497 enum state_device sys_get_device_state(void)
01498 {
01499 #if (LOGGING_ON)
01500 const gchar *state_str[] = { "UKNOWN", "STARTING", "STARTED", "STOPPING" };
01501 LOGPRINTF("device_state [%s]", state_str[device_state]);
01502 #endif
01503 return device_state;
01504 }
01505
01506
01507 enum state_power sys_get_power_state(void)
01508 {
01509 #if (LOGGING_ON)
01510
01511
01512 #endif
01513 return power_state;
01514 }
01515
01516
01517 void sys_set_device_state(enum state_device new_state)
01518 {
01519 LOGPRINTF("entry, new state: %d", new_state);
01520
01521 device_state = new_state;
01522 }
01523
01524
01525 void sys_update_rgb_led()
01526 {
01527 LOGPRINTF("entry");
01528
01529 if (is_busy_foreground())
01530 {
01531
01532 sys_set_rgb_led(COLOR_GREEN, 500);
01533 return;
01534 }
01535
01536 if (conn_is_online())
01537 {
01538
01539 sys_set_rgb_led(COLOR_BLUE, 0);
01540 return;
01541 }
01542
01543 if (charge_state == STATE_CHARGE_CHARGING)
01544 {
01545
01546 sys_set_rgb_led(COLOR_YELLOW, 0);
01547 return;
01548 }
01549 else if (charge_state == STATE_CHARGE_FULL)
01550 {
01551
01552 if ((usb_state != STATE_USB_DISCONNECTED) && (usb_state != STATE_USB_UNKNOWN))
01553 {
01554 sys_set_rgb_led(COLOR_GREEN, 0);
01555 return;
01556 }
01557 }
01558 else if (charge_state == STATE_CHARGE_LOW)
01559 {
01560
01561 sys_set_rgb_led(COLOR_RED, 0);
01562 return;
01563 }
01564
01565
01566 sys_set_rgb_led(COLOR_OFF, 0);
01567 }
01568
01569
01570 gboolean sys_get_enable_index_splash(void)
01571 {
01572 return g_index_splash_enabled;
01573 }
01574
01575
01576 void sys_set_enable_index_splash(gboolean value)
01577 {
01578 g_index_splash_enabled = value;
01579 }
01580
01581
01582
01583
01584
01585
01586 static gint read_sysfs(const char *device, const char *filename, const char *format, ...)
01587 {
01588 va_list ap;
01589 gint retval = 0;
01590 gchar *file = NULL;
01591 gint fd = 0;
01592 char buffer[256 + 1] = {0};
01593
01594 if (!device)
01595 {
01596 return retval;
01597 }
01598 va_start(ap, format);
01599
01600 file = g_strconcat(device, "/", filename, NULL);
01601
01602 fd = open(file, O_RDONLY);
01603 if (fd >= 0)
01604 {
01605 retval = read(fd, buffer, sizeof(buffer));
01606 close(fd);
01607
01608 if (retval > -1)
01609 {
01610
01611 retval = vsscanf(buffer, format, ap);
01612 }
01613 else
01614 {
01615 WARNPRINTF("Could not read %s", file);
01616 }
01617 }
01618 else
01619 {
01620 WARNPRINTF("Could not open %s", file);
01621 }
01622
01623 g_free(file);
01624
01625 va_end(ap);
01626
01627 return retval;
01628 }
01629
01630
01631 static gboolean write_ionkbd_orientation(gint orientation)
01632 {
01633 LOGPRINTF("entry");
01634
01635 gboolean retval = FALSE;
01636
01637 switch (orientation)
01638 {
01639 case ORIENTATION_PORTRAIT:
01640 write_ionkbd("orientation", "portrait");
01641 retval = TRUE;
01642 break;
01643
01644 case ORIENTATION_LANDSCAPE_CLOCKWISE:
01645 write_ionkbd("orientation", "lh-landscape");
01646 retval = TRUE;
01647 break;
01648
01649 case ORIENTATION_LANDSCAPE_ANTICLOCKWISE:
01650 write_ionkbd("orientation", "rh-landscape");
01651 retval = TRUE;
01652 break;
01653
01654 default:
01655 WARNPRINTF("Unknown orientation: %d", g_orientation);
01656 break;
01657 }
01658
01659 return retval;
01660 }
01661
01662
01663 static gboolean write_ionkbd_battery_alerts(gint l1, gint l2, gint l3, gint l4, gint l5)
01664 {
01665 LOGPRINTF("entry");
01666
01667 gchar *message = g_strdup_printf("%d %d %d %d %d", l1, l2, l3, l4, l5);
01668
01669 write_ionkbd("battery_alerts", message);
01670
01671 g_free(message);
01672
01673 return TRUE;
01674 }
01675
01676
01677 static gboolean write_sysfs(const char *device, const char *filename, const char *buffer)
01678 {
01679 LOGPRINTF("entry");
01680
01681 gboolean retval = FALSE;
01682 char *file = NULL;
01683 gint fd = 0;
01684 gint result = 0;
01685
01686 if (!device)
01687 {
01688 return FALSE;
01689 }
01690
01691 file = g_strconcat(device, "/", filename, NULL);
01692
01693 fd = open(file, O_WRONLY);
01694 if (fd >= 0)
01695 {
01696 result = write(fd, buffer, strlen(buffer));
01697 close(fd);
01698
01699 if (result > -1)
01700 {
01701 retval = TRUE;
01702 }
01703 else
01704 {
01705 WARNPRINTF("Could not write to `%s` (%d), %s", file, errno, strerror(errno));
01706 }
01707 }
01708 else
01709 {
01710 WARNPRINTF("Could not open %s", filename);
01711 }
01712
01713 g_free(file);
01714
01715 return retval;
01716 }
01717
01718
01719 static char *find_dir(const char *dir, const char *name, gboolean recurse)
01720 {
01721 LOGPRINTF("entry: [%s] [%s]", dir, name);
01722
01723 struct dirent **namelist;
01724 char *full_name = NULL;
01725 int i = 0;
01726 int count = 0;
01727
01728 count = scandir(dir, &namelist, 0, alphasort);
01729 for(i = 0; i < count; i++)
01730 {
01731 char *filename = namelist[i]->d_name;
01732
01733 if (filename && (strcmp(filename, ".") != 0) && (strcmp(filename, "..") != 0))
01734 {
01735 char fullpath[512] = "";
01736 strcat(fullpath, dir);
01737 strcat(fullpath, "/");
01738 strcat(fullpath, filename);
01739
01740 struct stat attributs;
01741 if (lstat(fullpath, &attributs) == -1)
01742 {
01743 WARNPRINTF("Error reading attributes of '%s'", fullpath);
01744 }
01745
01746 if S_ISDIR(attributs.st_mode)
01747 {
01748 if (name != NULL)
01749 {
01750 if (strncmp(filename, name, strlen(name)) == 0)
01751 {
01752
01753 full_name = g_strdup(fullpath);
01754 break;
01755 }
01756 else if (recurse && name != NULL)
01757 {
01758
01759 full_name = find_dir(fullpath, name, recurse);
01760 if (full_name)
01761 {
01762
01763 break;
01764 }
01765 g_free(full_name);
01766 }
01767 }
01768 }
01769 }
01770 }
01771
01772 g_free(namelist);
01773 return full_name;
01774 }
01775
01776
01777 static void report_unmounting_volumes()
01778 {
01779 LOGPRINTF("entry");
01780
01781 hal_device *device = hal_device_list_get_root();
01782 hal_device_property *property;
01783
01784 while (device != NULL)
01785 {
01786 property = hal_device_list_get_property("volume.mount_point", device);
01787 if ((property != NULL) && (*property->values != NULL) && ((*property->values)[0] != '\0'))
01788 {
01789 LOGPRINTF("about to unmount: %s", *property->values);
01790 ipc_send_prepare_unmount(*property->values);
01791 }
01792 device = device->next;
01793 }
01794 }
01795
01796
01797 static enum state_charge get_battery_state(gint level, gint charging)
01798 {
01799 LOGPRINTF("entry");
01800
01801 enum state_charge cur_state;
01802
01803 if (charging == 1)
01804 {
01805 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
01806 if (level >= BATTERY_FULL_THRESHOLD)
01807 {
01808 cur_state = STATE_CHARGE_FULL;
01809 }
01810 else
01811 #endif
01812 {
01813 cur_state = STATE_CHARGE_CHARGING;
01814 }
01815 }
01816 else
01817 {
01818 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
01819 if (level >= BATTERY_FULL_THRESHOLD)
01820 {
01821 cur_state = STATE_CHARGE_FULL;
01822 }
01823 else
01824 #endif
01825 if (level <= BATTERY_LOW_THRESHOLD)
01826 {
01827 cur_state = STATE_CHARGE_LOW;
01828 }
01829 else
01830 {
01831 cur_state = STATE_CHARGE_DISCHARGING;
01832 }
01833 }
01834
01835 LOGPRINTF("returns %d", cur_state);
01836 return cur_state;
01837 }
01838
01839
01840 static void check_hardware()
01841 {
01842 LOGPRINTF("entry");
01843
01844 char hardware[5] = {0};
01845 gint rc = 0;
01846
01847 rc = read_ionkbd("hardware_state", "%s", &hardware);
01848 if (rc > 0)
01849 {
01850 LOGPRINTF("hardware: %s", hardware);
01851 sys_update_hardware(hardware);
01852 }
01853 }
01854
01855
01856 static void update_battery_info(gint cur_level, enum state_charge cur_state, gboolean force_send)
01857 {
01858 LOGPRINTF("entry");
01859
01860 enum state_charge old_state = charge_state;
01861
01862
01863
01864
01865
01866 if ( (force_send == TRUE) ||
01867 (cur_state != old_state) ||
01868 (g_battery_level != cur_level)
01869 )
01870 {
01871
01872 g_battery_level = cur_level;
01873 charge_state = cur_state;
01874
01875 ipc_send_battery_state(cur_level, cur_state, -1);
01876
01877
01878
01879 switch (old_state)
01880 {
01881 case STATE_CHARGE_LOW:
01882 if ( cur_state == STATE_CHARGE_CHARGING )
01883 {
01884 ipc_show_splash("hide");
01885 break;
01886 }
01887 if ( cur_state == STATE_CHARGE_LOW )
01888 {
01889 ipc_show_splash("batterylow");
01890 break;
01891 }
01892 case STATE_CHARGE_CHARGING:
01893 case STATE_CHARGE_DISCHARGING:
01894 if ( cur_state == STATE_CHARGE_LOW )
01895 {
01896 ipc_show_splash("batterylow");
01897 }
01898 break;
01899 default:
01900
01901 break;
01902 }
01903
01904
01905 sys_update_rgb_led();
01906 }
01907
01908 if ( (charge_state == STATE_CHARGE_LOW) && (cur_level <= BATTERY_SHUTDOWN_THRESHOLD) )
01909 {
01910 if (g_standby_if_plugged || (usb_state == STATE_USB_DISCONNECTED) || (usb_state == STATE_USB_UNKNOWN))
01911 {
01912 LOGPRINTF("Power off now");
01913 do_poweroff();
01914 return;
01915 }
01916 else
01917 {
01918 LOGPRINTF("Don't power off as device is plugged in. usb_state [%d] if_plugged [%d]", usb_state, g_standby_if_plugged);
01919 }
01920 }
01921
01922 conn_check_battery(cur_level);
01923 }
01924
01925
01926 static void usb_set_state(enum state_usb new_state)
01927 {
01928 #if (LOGGING_ON)
01929 static const gchar *state_str[] =
01930 {
01931 [STATE_USB_UNKNOWN] = "STATE_USB_UNKNOWN",
01932 [STATE_USB_DISCONNECT_PENDING] = "STATE_USB_DISCONNECT_PENDING",
01933 [STATE_USB_DISCONNECTED] = "STATE_USB_DISCONNECTED",
01934 [STATE_USB_UNMOUNTED] = "STATE_USB_UNMOUNTED",
01935 [STATE_USB_MOUNT_CONFIRM] = "STATE_USB_MOUNT_CONFIRM",
01936 [STATE_USB_MOUNT_PENDING] = "STATE_USB_MOUNT_PENDING",
01937 [STATE_USB_MOUNTED] = "STATE_USB_MOUNTED",
01938 };
01939 #endif
01940 enum state_usb old_state = usb_state;
01941 if (old_state == new_state)
01942 {
01943 WARNPRINTF("huh? already in state [%d]", new_state);
01944 return;
01945 }
01946 usb_state = new_state;
01947 LOGPRINTF("change usb_state %s > %s", state_str[old_state], state_str[new_state]);
01948
01949 if (new_state == STATE_USB_DISCONNECTED || new_state == STATE_USB_UNMOUNTED)
01950 {
01951 if (old_state == STATE_USB_MOUNT_CONFIRM)
01952 {
01953
01954 ipc_confirm_usbconnect(FALSE);
01955 }
01956
01957 if ( (old_state == STATE_USB_MOUNT_CONFIRM)
01958 || (old_state == STATE_USB_DISCONNECT_PENDING)
01959 || (old_state == STATE_USB_MOUNTED)
01960 || (old_state == STATE_USB_UNMOUNTED) )
01961 {
01962
01963 usb_driver_unload();
01964 g_wallcharger_found = FALSE;
01965 }
01966
01967 if ( (old_state == STATE_USB_MOUNTED)
01968 || (old_state == STATE_USB_DISCONNECT_PENDING))
01969 {
01970 if (card_state == STATE_CARD_EJECTED)
01971 {
01972
01973 usb_connection_finish();
01974 ipc_show_splash("nosd");
01975 }
01976 else
01977 {
01978
01979 hal_remount_all_volumes(on_usb_disconnected, NULL);
01980 }
01981 }
01982 }
01983
01984 switch (new_state)
01985 {
01986 case STATE_USB_UNKNOWN:
01987 break;
01988 case STATE_USB_DISCONNECTED:
01989 ipc_send_usb_state("disconnected");
01990 break;
01991 case STATE_USB_UNMOUNTED:
01992 ipc_send_usb_state("unmounted");
01993 break;
01994 case STATE_USB_MOUNT_CONFIRM:
01995 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
01996
01997 if (!g_demo_mode)
01998 {
01999 ipc_confirm_usbconnect(TRUE);
02000 }
02001 else
02002 #endif
02003 {
02004
02005 sys_usb_connect();
02006 }
02007 break;
02008 case STATE_USB_DISCONNECT_PENDING:
02009 case STATE_USB_MOUNT_PENDING:
02010 break;
02011 case STATE_USB_MOUNTED:
02012 ipc_send_usb_state("mounted");
02013 break;
02014 }
02015 }
02016
02017
02018 static gboolean usb_driver_load()
02019 {
02020 LOGPRINTF("entry");
02021
02022
02023 g_usleep(G_USEC_PER_SEC * 2);
02024
02025 gboolean retval = sys_spawn_sync("modprobe g_file_storage removable=y");
02026 if (retval)
02027 {
02028
02029 if (g_usb) g_free(g_usb);
02030 g_usb = find_dir(sys_devices, usb_device_name, TRUE);
02031 if (!g_usb)
02032 {
02033 ERRORPRINTF("%s not found or not unique", usb_device_name);
02034 retval = FALSE;
02035 }
02036 }
02037 return retval;
02038 }
02039
02040
02041 static gboolean usb_driver_unload()
02042 {
02043 LOGPRINTF("entry");
02044
02045 gboolean retval = sys_spawn_sync("modprobe -r g_file_storage");
02046 if (retval)
02047 {
02048 g_usb = NULL;
02049 }
02050 return retval;
02051 }
02052
02053
02054 static gboolean usb_connect()
02055 {
02056 gboolean retval = FALSE;
02057
02058 LOGPRINTF("entry");
02059
02060 if (g_volume_unmount_source)
02061 {
02062 g_source_remove(g_volume_unmount_source);
02063 }
02064
02065
02066 if (g_lun) g_free(g_lun);
02067 g_lun = find_dir(sys_devices, lun_device_name, TRUE);
02068 if (g_lun)
02069 {
02070
02071 if (g_card_device)
02072 {
02073 write_sysfs(g_lun, "file", g_card_device);
02074
02075
02076 busy_add_background(0);
02077 g_usb_device_source = g_timeout_add_seconds(USB_DEVICE_POLL_INTERVAL, on_usb_read_online, NULL);
02078
02079 usb_set_state(STATE_USB_MOUNTED);
02080 retval = TRUE;
02081 }
02082 else
02083 {
02084 ERRORPRINTF("device of mountpoint not found");
02085 }
02086 }
02087 else
02088 {
02089 ERRORPRINTF("%s not found or not unique", lun_device_name);
02090 }
02091
02092 return retval;
02093 }
02094
02095
02096 static void on_usb_connected(gpointer data)
02097 {
02098 LOGPRINTF("entry");
02099
02100 if (usb_state == STATE_USB_MOUNT_PENDING)
02101 {
02102 usb_connect();
02103 }
02104 else if (usb_state == STATE_USB_DISCONNECT_PENDING)
02105 {
02106 usb_set_state(STATE_USB_DISCONNECTED);
02107 }
02108
02109 busy_remove_foreground(0);
02110 }
02111
02112
02113 static gboolean on_usb_disconnected(gpointer data)
02114 {
02115 LOGPRINTF("entry");
02116
02117 usb_connection_finish();
02118
02119 if (usb_state == STATE_USB_MOUNTED)
02120 {
02121 usb_set_state(STATE_USB_UNMOUNTED);
02122 }
02123
02124
02125 return FALSE;
02126 }
02127
02128
02129 static void usb_connection_finish()
02130 {
02131 LOGPRINTF("entry");
02132
02133
02134 if (g_usb_device_source)
02135 {
02136 g_source_remove(g_usb_device_source);
02137 g_usb_device_source = 0;
02138 }
02139 }
02140
02141
02142 static gboolean on_usb_read_device_state(gpointer data)
02143 {
02144 static gint count = 0;
02145 gboolean continue_polling = TRUE;
02146 gboolean host_available = FALSE;
02147
02148 char state[80] = {0};
02149 read_usb("device_state", "%*d:%s", &state);
02150 LOGPRINTF("device_state [%s]", state);
02151
02152 if (strcmp(state, "address") == 0)
02153 {
02154 host_available = TRUE;
02155 }
02156
02157 if (usb_state == STATE_USB_UNMOUNTED)
02158 {
02159 if ((host_available) && (card_state == STATE_CARD_MOUNTED))
02160 {
02161 LOGPRINTF("USB host found, connect immediately");
02162 usb_set_state(STATE_USB_MOUNT_CONFIRM);
02163 continue_polling = FALSE;
02164 }
02165 else if (count > USB_DEVICE_POLL_TIMEOUT)
02166 {
02167 LOGPRINTF("USB not host found (is charger), stop polling and unload");
02168 usb_driver_unload();
02169
02170 g_wallcharger_found = TRUE;
02171 continue_polling = FALSE;
02172 }
02173 }
02174 else
02175 {
02176 if (!host_available)
02177 {
02178 if (usb_state != STATE_USB_DISCONNECTED)
02179 {
02180 LOGPRINTF("USB suspended, remove dialog and disconnect");
02181 usb_set_state(STATE_USB_UNMOUNTED);
02182 }
02183 continue_polling = FALSE;
02184 }
02185 }
02186
02187 if (continue_polling)
02188 {
02189 count++;
02190 }
02191 else
02192 {
02193 busy_remove_background(0);
02194 g_usb_device_source = 0;
02195 count = 0;
02196 }
02197
02198 return continue_polling;
02199 }
02200
02201
02202 static gboolean on_usb_read_online(gpointer data)
02203 {
02204 static gint count = 0;
02205 gboolean continue_polling = TRUE;
02206
02207 gint state = -1;
02208 read_lun("online", "%d", &state);
02209 LOGPRINTF("online [%d]", state);
02210
02211 if (state == 0 && count > USB_DEVICE_ONLINE_DELAY)
02212 {
02213 if (usb_state != STATE_USB_DISCONNECTED)
02214 {
02215 LOGPRINTF("OFFLINE, remove dialog and disconnect");
02216 usb_set_state(STATE_USB_UNMOUNTED);
02217 }
02218 continue_polling = FALSE;
02219 }
02220 else if (state == -1)
02221 {
02222 LOGPRINTF("Can't read OFFLINE state, gadget probably unloaded");
02223 continue_polling = FALSE;
02224 }
02225
02226 if (continue_polling)
02227 {
02228 count++;
02229 }
02230 else
02231 {
02232 busy_remove_background(0);
02233 g_usb_device_source = 0;
02234 count = 0;
02235 }
02236
02237 return continue_polling;
02238 }
02239
02240
02241 static void on_poweroff_continue(gpointer data)
02242 {
02243 LOGPRINTF("entry");
02244
02245
02246 write_ionkbd("sensor_enable", "7");
02247
02248
02249 sys_spawn_sync("shutdown -h now");
02250
02251 while (1)
02252 {
02253 g_usleep(G_USEC_PER_SEC * 1);
02254 }
02255
02256 WARNPRINTF("this should never be reached");
02257 }
02258
02259
02260 static void on_restart_continue(gpointer data)
02261 {
02262 LOGPRINTF("entry");
02263
02264
02265 sys_spawn_sync("reboot");
02266 }
02267
02268
02269 static void on_eject_continue(gpointer data)
02270 {
02271 LOGPRINTF("entry");
02272
02273 gboolean silent = (gboolean) data;
02274
02275 busy_remove_foreground(0);
02276
02277 if (!silent)
02278 {
02279 ipc_show_splash("safelyremove");
02280 }
02281 }
02282
02283
02284 static void set_idle_time(gint time)
02285 {
02286 if (!g_idle_enabled)
02287 {
02288 return;
02289 }
02290
02291 if ((power_state == STATE_POWER_IDLE) || (power_state == STATE_POWER_STANDBY))
02292 {
02293 if (g_idle_time_source)
02294 {
02295
02296 LOGPRINTF("stop idle time when preparing for idle or standby");
02297 g_source_remove(g_idle_time_source);
02298 g_idle_time_source = 0;
02299 }
02300 return;
02301 }
02302
02303 #if (LOGGING_ON)
02304 GTimeVal curtime;
02305 g_get_current_time(&curtime);
02306 LOGPRINTF(" %ld:%3ld Reset idle >>> STATE_POWER_RUN", curtime.tv_sec, curtime.tv_usec / 1000);
02307 #endif
02308
02309 power_state = STATE_POWER_RUN;
02310
02311 if (time <= 0)
02312 {
02313 time = IDLE_TIMEOUT_SEC;
02314 }
02315
02316 if (g_idle_time_source)
02317 {
02318 g_source_remove(g_idle_time_source);
02319 }
02320 g_idle_time_source = g_timeout_add_seconds(time, on_idle_timeout, NULL);
02321 }
02322
02323
02324 static gboolean on_idle_timeout(gpointer data)
02325 {
02326 LOGPRINTF("entry");
02327
02328 #if (LOGGING_ON)
02329 GTimeVal curtime;
02330 g_get_current_time(&curtime);
02331 LOGPRINTF(" %ld:%3ld Idle for %d seconds, idle pending >>> STATE_POWER_IDLE",
02332 curtime.tv_sec, curtime.tv_usec / 1000, IDLE_TIMEOUT_SEC);
02333 #endif
02334
02335 if (!g_idle_enabled)
02336 {
02337 return FALSE;
02338 }
02339
02340 if ( is_busy_background() ||
02341 conn_is_online() || conn_is_initialising() ||
02342 (usb_state == STATE_USB_MOUNT_CONFIRM) || (usb_state == STATE_USB_MOUNT_PENDING) || (usb_state == STATE_USB_MOUNTED ) ||
02343 (device_state == STATE_DEVICE_STOPPING) ||
02344 (power_state == STATE_POWER_IDLE) )
02345 {
02346 LOGPRINTF("Don't idle as system is busy (bgbusy [%d] online [%d] usb_state [%d] device_state [%d] power_state [%d])",
02347 is_busy_background(), conn_is_online(), usb_state, device_state, power_state);
02348 return TRUE;
02349 }
02350 else
02351 {
02352 gint x_idle = window_get_idle_time();
02353
02354 if ((x_idle != -1) && (x_idle < IDLE_TIMEOUT_SEC))
02355 {
02356 LOGPRINTF("Don't idle as X is idle for %d sec, wait %d sec more", x_idle, IDLE_TIMEOUT_SEC-x_idle);
02357 set_idle_time(IDLE_TIMEOUT_SEC-x_idle);
02358 }
02359 else
02360 {
02361 do_idle();
02362 }
02363 }
02364
02365
02366 return FALSE;
02367 }
02368
02369
02370 static void do_unmount(gboolean show_busy, const char *splash, gpointer callback_function, gpointer user_data)
02371 {
02372 LOGPRINTF("entry");
02373
02374 if (show_busy)
02375 {
02376 busy_add_foreground(0, BUSY_DIALOG_DIRECT, NULL);
02377 }
02378
02379 if (splash)
02380 {
02381 ipc_show_splash(splash);
02382 }
02383
02384
02385 stop_demo_mode();
02386
02387
02388 report_unmounting_volumes();
02389
02390
02391 sys_spawn_sync(ERCONFTOOL_EXPORT);
02392
02393
02394 sys_spawn_sync(ADOBE_SYNC);
02395
02396
02397 hal_unmount_all_volumes(callback_function, user_data);
02398 }
02399
02400
02401 static void do_poweroff(void)
02402 {
02403 LOGPRINTF("entry");
02404
02405 if (device_state != STATE_DEVICE_STOPPING)
02406 {
02407 device_state = STATE_DEVICE_STOPPING;
02408 busy_add_foreground(0, BUSY_DIALOG_NONE, NULL);
02409 if (card_state == STATE_CARD_MOUNTED)
02410 {
02411 do_unmount(TRUE, "shutdown", on_poweroff_continue, NULL);
02412 }
02413 else
02414 {
02415
02416 on_poweroff_continue(NULL);
02417 }
02418 }
02419 }
02420
02421
02422 static gint get_wakeup_reason()
02423 {
02424
02425 gint reason = WAKEUP_NO_REASON;
02426 gint rc = 0;
02427
02428 g_usleep(75*1000);
02429 rc = read_ionkbd("wakeup_reason", "%d", &reason);
02430 if (rc <= 0)
02431 {
02432 reason = WAKEUP_NO_REASON;
02433 }
02434
02435 #if (LOGGING_ON)
02436 const gchar *reason_str[] = { "NO_REASON", "KEY", "PEN", "TIMER (standby)", "BATTERY", "COVER", "CARD", "USB", "CHARGE_DETECTED" };
02437 LOGPRINTF("Wakeup reason: %s", reason_str[reason]);
02438 #endif
02439
02440 return reason;
02441 }
02442
02443
02444 #if MACHINE_IS_DR800SG || MACHINE_IS_DR800S || MACHINE_IS_DR800SW
02445 static gboolean on_check_standby(gpointer data)
02446 {
02447 LOGPRINTF("entry");
02448
02449 g_timeout_add(CHECK_STANDBY_TIMEOUT_MS, on_standby, NULL);
02450 return FALSE;
02451 }
02452
02453
02454 static void prepare_standby()
02455 {
02456 LOGPRINTF("entry");
02457
02458 if ( (device_state == STATE_DEVICE_STOPPING) ||
02459 (power_state == STATE_POWER_STANDBY) ||
02460 (power_state == STATE_POWER_IDLE) ||
02461 ((usb_state == STATE_USB_UNMOUNTED) && (g_usb_device_source != 0)) )
02462 {
02463 LOGPRINTF("Don't enter standby now! (device_state [%d] power_state [%d] usb_state [%d][%d])",
02464 device_state, power_state, usb_state, g_usb_device_source);
02465 return;
02466 }
02467
02468 power_state = STATE_POWER_STANDBY;
02469
02470 LOGPRINTF("Prepare standby");
02471
02472
02473 display_splash_lock();
02474 display_blank();
02475
02476
02477 stop_demo_mode();
02478
02479
02480 ipc_send_prepare_standby();
02481 conn_stop();
02482
02483 g_timeout_add(PREPARE_STANDBY_TIMEOUT_MS, on_check_standby, NULL);
02484 }
02485
02486
02487 static gboolean on_holdoff_timeout(gpointer data)
02488 {
02489 g_holdoff_standby = 0;
02490 return FALSE;
02491 }
02492
02493
02494 static gboolean on_standby(gpointer data)
02495 {
02496 LOGPRINTF("entry");
02497
02498 gint cur_level = 0;
02499 gint retval = 0;
02500 enum state_charge cur_state = STATE_CHARGE_UNKNOWN;
02501
02502 if (device_state == STATE_DEVICE_STOPPING)
02503 {
02504 WARNPRINTF("Device is stopping, don't enter standby now!");
02505 return FALSE;
02506 }
02507
02508
02509
02510 LOGPRINTF("Enter standby");
02511
02512
02513 sys_spawn_sync(ERCONFTOOL_EXPORT);
02514
02515
02516 sync();
02517
02518
02519 gboolean wacom_enabled = wacom_is_enabled();
02520 if (wacom_enabled)
02521 {
02522 wacom_disable();
02523 }
02524
02525
02526 conn_on_enter_standby();
02527
02528 if (g_wallcharger_found)
02529 {
02530
02531
02532 write_ionkbd("fastcharge", "1");
02533 }
02534
02535 sys_spawn_sync("standby.sh");
02536
02537
02538
02539
02540
02541 LOGPRINTF("Back from standby");
02542
02543 gint reason = get_wakeup_reason();
02544 if ( reason == WAKEUP_BATTERY )
02545 {
02546 WARNPRINTF("Low battery, power off now");
02547 do_poweroff();
02548 return FALSE;
02549 }
02550
02551
02552 display_init();
02553 display_set_vcom(sys_get_display_vcom());
02554 display_set_waveforms();
02555
02556
02557 display_splash_unlock();
02558 display_update_return_control(DM_HINT_FULL);
02559
02560
02561 check_hardware();
02562
02563
02564 retval = sys_get_battery(&cur_level, &cur_state, NULL);
02565 if (retval == TRUE)
02566 {
02567
02568 update_battery_info(cur_level, cur_state, TRUE);
02569 }
02570
02571 sys_update_rgb_led();
02572
02573 power_state = STATE_POWER_RUN;
02574
02575
02576 sys_reset_idle_time();
02577
02578
02579 if (wacom_enabled)
02580 {
02581 wacom_enable();
02582 }
02583
02584 g_holdoff_standby = g_timeout_add_seconds(HOLDOFF_STANDBY_TIMEOUT, on_holdoff_timeout, NULL);
02585
02586 gboolean do_drz = check_and_install_drz();
02587 gboolean do_firmware = sys_check_and_install_firmware();
02588 gboolean do_disk = check_disk_free();
02589
02590 conn_on_leave_standby();
02591
02592 if (!(do_drz || do_firmware || do_disk)) {
02593 if (g_file_test(MOUNTPOINT_CARD"/"DEMO_FILE, G_FILE_TEST_EXISTS)) {
02594 start_demo_mode();
02595 }
02596 }
02597
02598 return FALSE;
02599 }
02600
02601 #endif
02602
02603
02604 static void do_idle()
02605 {
02606 LOGPRINTF("entry");
02607
02608 gint cur_level = 0;
02609 gint retval = 0;
02610 static glong standby_time = 0;
02611 enum state_charge cur_state = STATE_CHARGE_UNKNOWN;
02612
02613 if (!g_idle_enabled)
02614 {
02615 return;
02616 }
02617
02618 if ((device_state == STATE_DEVICE_STOPPING) || (power_state == STATE_POWER_STANDBY))
02619 {
02620 LOGPRINTF("Don't enter idle now! (device_state [%d] power_state [%d])",
02621 device_state, power_state);
02622 return;
02623 }
02624
02625 power_state = STATE_POWER_IDLE;
02626
02627
02628
02629 if (wacom_is_enabled())
02630 {
02631 wacom_suspend();
02632 }
02633
02634 if ( (g_standby_timeout_sec > 0)
02635 && (g_standby_if_plugged || (usb_state == STATE_USB_DISCONNECTED)) )
02636 {
02637
02638 GTimeVal curtime;
02639 g_get_current_time(&curtime);
02640
02641 if ((standby_time == 0) || (standby_time <= curtime.tv_sec))
02642 {
02643 standby_time = curtime.tv_sec + g_standby_timeout_sec;
02644 }
02645
02646 gint min_before_standby = (standby_time - curtime.tv_sec) / 60;
02647
02648 LOGPRINTF("Minutes before standby: %d, standby time: %ld, now: %ld",
02649 min_before_standby, standby_time, curtime.tv_sec);
02650
02651 if (min_before_standby > 0)
02652 {
02653
02654 gchar *command = g_strdup_printf("idle.sh %d", min_before_standby);
02655 sys_spawn_sync(command);
02656 g_free(command);
02657 }
02658 else
02659 {
02660 WARNPRINTF("Go to standby immediately");
02661 sys_standby();
02662 return;
02663 }
02664 }
02665 else
02666 {
02667
02668 LOGPRINTF("Enter idle without standby");
02669 sys_spawn_sync("idle.sh");
02670 }
02671
02672
02673
02674
02675
02676 LOGPRINTF("Back from idle");
02677
02678 gint reason = get_wakeup_reason();
02679 if ( (reason == WAKEUP_TIMER) &&
02680 (g_standby_if_plugged || (usb_state == STATE_USB_DISCONNECTED)) )
02681 {
02682 WARNPRINTF("Idle timed out, go to standby now");
02683 standby_time = 0;
02684 power_state = STATE_POWER_RUN;
02685 sys_standby();
02686 }
02687 else
02688 {
02689
02690 if (reason == WAKEUP_USB)
02691 {
02692 check_hardware();
02693 }
02694
02695
02696 retval = sys_get_battery(&cur_level, &cur_state, NULL);
02697 if (retval == TRUE)
02698 {
02699
02700 if (reason == WAKEUP_BATTERY)
02701 {
02702
02703 update_battery_info(cur_level, cur_state, TRUE);
02704 }
02705 else
02706 {
02707 update_battery_info(cur_level, cur_state, FALSE);
02708 }
02709 }
02710
02711 sys_update_rgb_led();
02712
02713 standby_time = 0;
02714 power_state = STATE_POWER_RUN;
02715 sys_reset_idle_time();
02716
02717 if (wacom_is_enabled())
02718 {
02719 if (reason == WAKEUP_PEN)
02720 {
02721
02722 wacom_resume();
02723 }
02724 else
02725 {
02726
02727 wacom_reset();
02728 }
02729 }
02730 }
02731 }