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 }