# include  <cstdio> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <cstdlib> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <cstring> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <cassert> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <unistd.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <sys/stat.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <sys/statvfs.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <string> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <sstream> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <fstream> 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <iostream> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <mutex> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <thread> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <curl/curl.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <openssl/sha.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <GLES3/gl3.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <EGL/egl.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <EGL/eglext.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "nanovg.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define NANOVG_GLES3_IMPLEMENTATION 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "nanovg_gl.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "nanovg_gl_utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "json11.hpp" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "common/framebuffer.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "common/touch.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "common/utilpp.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define USER_AGENT "NEOSUpdater-0.2" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define MANIFEST_URL_NEOS_STAGING "https: //github.com/commaai/eon-neos/raw/master/update.staging.json"
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define MANIFEST_URL_NEOS_LOCAL "http: //192.168.5.1:8000/neosupdate/update.local.json"
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define MANIFEST_URL_NEOS "https: //github.com/commaai/eon-neos/raw/master/update.json"
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  char  * manifest_url  =  MANIFEST_URL_NEOS ; 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RECOVERY_DEV " / dev / block / bootdevice / by-name / recovery" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RECOVERY_COMMAND " / cache / recovery / command" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define UPDATE_DIR " / data / neoupdate" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								extern  const  uint8_t  bin_opensans_regular [ ]  asm ( " _binary_opensans_regular_ttf_start " ) ; 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								extern  const  uint8_t  bin_opensans_regular_end [ ]  asm ( " _binary_opensans_regular_ttf_end " ) ; 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								extern  const  uint8_t  bin_opensans_semibold [ ]  asm ( " _binary_opensans_semibold_ttf_start " ) ; 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								extern  const  uint8_t  bin_opensans_semibold_end [ ]  asm ( " _binary_opensans_semibold_ttf_end " ) ; 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								extern  const  uint8_t  bin_opensans_bold [ ]  asm ( " _binary_opensans_bold_ttf_start " ) ; 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								extern  const  uint8_t  bin_opensans_bold_end [ ]  asm ( " _binary_opensans_bold_ttf_end " ) ; 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								std : : string  sha256_file ( std : : string  fn ,  size_t  limit = 0 )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SHA256_CTX  ctx ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SHA256_Init ( & ctx ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  FILE  * file  =  fopen ( fn . c_str ( ) ,  " rb " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! file )  return  " " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  size_t  buf_size  =  8192 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : unique_ptr < char [ ] >  buffer (  new  char [  buf_size  ]  ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  bool  read_limit  =  ( limit  ! =  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  while  ( true )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  read_size  =  buf_size ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( read_limit )  read_size  =  std : : min ( read_size ,  limit ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    size_t  bytes_read  =  fread ( buffer . get ( ) ,  1 ,  read_size ,  file ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! bytes_read )  break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SHA256_Update ( & ctx ,  buffer . get ( ) ,  bytes_read ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( read_limit )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      limit  - =  bytes_read ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( limit  = =  0 )  break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  uint8_t  hash [ SHA256_DIGEST_LENGTH ] ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  SHA256_Final ( hash ,  & ctx ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  fclose ( file ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  util : : tohex ( hash ,  sizeof ( hash ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								size_t  download_string_write ( void  * ptr ,  size_t  size ,  size_t  nmeb ,  void  * up )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  size_t  sz  =  size  *  nmeb ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ( ( std : : string * ) up ) - > append ( ( char * ) ptr ,  sz ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  sz ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								std : : string  download_string ( CURL  * curl ,  std : : string  url )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : string  os ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  curl_easy_setopt ( curl ,  CURLOPT_URL ,  url . c_str ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  curl_easy_setopt ( curl ,  CURLOPT_FOLLOWLOCATION ,  1 ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  curl_easy_setopt ( curl ,  CURLOPT_NOSIGNAL ,  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  curl_easy_setopt ( curl ,  CURLOPT_USERAGENT ,  USER_AGENT ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  curl_easy_setopt ( curl ,  CURLOPT_FAILONERROR ,  1 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  curl_easy_setopt ( curl ,  CURLOPT_RESUME_FROM ,  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  curl_easy_setopt ( curl ,  CURLOPT_NOPROGRESS ,  1 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  curl_easy_setopt ( curl ,  CURLOPT_WRITEFUNCTION ,  download_string_write ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  curl_easy_setopt ( curl ,  CURLOPT_WRITEDATA ,  & os ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  CURLcode  res  =  curl_easy_perform ( curl ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( res  ! =  CURLE_OK )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  " " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  os ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								size_t  download_file_write ( void  * ptr ,  size_t  size ,  size_t  nmeb ,  void  * up )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  fwrite ( ptr ,  size ,  nmeb ,  ( FILE * ) up ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  battery_capacity ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : string  bat_cap_s  =  util : : read_file ( " /sys/class/power_supply/battery/capacity " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  atoi ( bat_cap_s . c_str ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  battery_current ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : string  current_now_s  =  util : : read_file ( " /sys/class/power_supply/battery/current_now " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  atoi ( current_now_s . c_str ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  check_battery ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  bat_cap  =  battery_capacity ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  current_now  =  battery_current ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  bat_cap  >  35  | |  ( current_now  <  0  & &  bat_cap  >  10 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  check_space ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  struct  statvfs  stat ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( statvfs ( " /data/ " ,  & stat )  ! =  0 )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  size_t  space  =  stat . f_bsize  *  stat . f_bavail ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  space  >  2000000000ULL ;  // 2GB
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  start_settings_activity ( const  char *  name )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  char  launch_cmd [ 1024 ] ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  snprintf ( launch_cmd ,  sizeof ( launch_cmd ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								           " am start -W --ez :settings:show_fragment_as_subsetting true -n 'com.android.settings/.%s' " ,  name ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  system ( launch_cmd ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  is_settings_active ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  FILE  * fp ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  char  sys_output [ 4096 ] ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  fp  =  popen ( " /bin/dumpsys window windows " ,  " r " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( fp  = =  NULL )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  bool  active  =  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  while  ( fgets ( sys_output ,  sizeof ( sys_output ) ,  fp )  ! =  NULL )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( strstr ( sys_output ,  " mCurrentFocus=null " )   ! =  NULL )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( strstr ( sys_output ,  " mCurrentFocus=Window " )  ! =  NULL )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      active  =  true ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pclose ( fp ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  active ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  Updater  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  bool  do_exit  =  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  TouchState  touch ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  fb_w ,  fb_h ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  FramebufferState  * fb  =  NULL ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  NVGcontext  * vg  =  NULL ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  font_regular ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  font_semibold ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  font_bold ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : thread  update_thread_handle ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : mutex  lock ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  enum  UpdateState  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CONFIRMATION , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    LOW_BATTERY , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    RUNNING , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ERROR , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  UpdateState  state ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : string  progress_text ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  float  progress_frac ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : string  error_text ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : string  low_battery_text ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : string  low_battery_title ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : string  low_battery_context ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : string  battery_cap_text ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  min_battery_cap  =  35 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // button
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  b_x ,  b_w ,  b_y ,  b_h ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  balt_x ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  // download stage writes these for the installation stage
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  recovery_len ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : string  recovery_hash ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : string  recovery_fn ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  std : : string  ota_fn ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  CURL  * curl  =  NULL ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  void  ui_init ( )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    touch_init ( & touch ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fb  =  framebuffer_init ( " updater " ,  0x00001000 ,  false , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                          & fb_w ,  & fb_h ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( fb ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    framebuffer_set_power ( fb ,  HWC_POWER_MODE_NORMAL ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    vg  =  nvgCreateGLES3 ( NVG_ANTIALIAS  |  NVG_STENCIL_STROKES  |  NVG_DEBUG ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    font_regular  =  nvgCreateFontMem ( vg ,  " opensans_regular " ,  ( unsigned  char * ) bin_opensans_regular ,  ( bin_opensans_regular_end  -  bin_opensans_regular ) ,  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( font_regular  > =  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    font_semibold  =  nvgCreateFontMem ( vg ,  " opensans_semibold " ,  ( unsigned  char * ) bin_opensans_semibold ,  ( bin_opensans_semibold_end  -  bin_opensans_semibold ) ,  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( font_semibold  > =  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    font_bold  =  nvgCreateFontMem ( vg ,  " opensans_bold " ,  ( unsigned  char * ) bin_opensans_bold ,  ( bin_opensans_bold_end  -  bin_opensans_bold ) ,  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( font_bold  > =  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    b_w  =  640 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    balt_x  =  200 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    b_x  =  fb_w - b_w - 200 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    b_y  =  720 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    b_h  =  220 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    state  =  CONFIRMATION ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  download_file_xferinfo ( curl_off_t  dltotal ,  curl_off_t  dlno , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             curl_off_t  ultotal ,  curl_off_t  ulnow )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      std : : lock_guard < std : : mutex >  guard ( lock ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( dltotal  ! =  0 )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        progress_frac  =  ( float )  dlno  /  dltotal ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // printf("info: %ld %ld %f\n", dltotal, dlno, progress_frac);
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  0 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  bool  download_file ( std : : string  url ,  std : : string  out_fn )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    FILE  * of  =  fopen ( out_fn . c_str ( ) ,  " ab " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( of ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    CURLcode  res ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    long  last_resume_from  =  0 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fseek ( of ,  0 ,  SEEK_END ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  tries  =  4 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  ret  =  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( true )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      long  resume_from  =  ftell ( of ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      curl_easy_setopt ( curl ,  CURLOPT_URL ,  url . c_str ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      curl_easy_setopt ( curl ,  CURLOPT_FOLLOWLOCATION ,  1 ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      curl_easy_setopt ( curl ,  CURLOPT_NOSIGNAL ,  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      curl_easy_setopt ( curl ,  CURLOPT_USERAGENT ,  USER_AGENT ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      curl_easy_setopt ( curl ,  CURLOPT_FAILONERROR ,  1 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      curl_easy_setopt ( curl ,  CURLOPT_RESUME_FROM ,  resume_from ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      curl_easy_setopt ( curl ,  CURLOPT_WRITEFUNCTION ,  download_file_write ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      curl_easy_setopt ( curl ,  CURLOPT_WRITEDATA ,  of ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      curl_easy_setopt ( curl ,  CURLOPT_NOPROGRESS ,  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      curl_easy_setopt ( curl ,  CURLOPT_XFERINFODATA ,  this ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      curl_easy_setopt ( curl ,  CURLOPT_XFERINFOFUNCTION ,  & Updater : : download_file_xferinfo ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      CURLcode  res  =  curl_easy_perform ( curl ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      long  response_code  =  0 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      curl_easy_getinfo ( curl ,  CURLINFO_RESPONSE_CODE ,  & response_code ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // double content_length = 0.0;
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &content_length);
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      printf ( " download %s res %d, code %ld, resume from %ld \n " ,  url . c_str ( ) ,  res ,  response_code ,  resume_from ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( res  = =  CURLE_OK )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ret  =  true ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }  else  if  ( res  = =  CURLE_HTTP_RETURNED_ERROR  & &  response_code  = =  416 )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // failed because the file is already complete?
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ret  =  true ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }  else  if  ( resume_from  = =  last_resume_from )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // failed and dind't make make forward progress. only retry a couple times
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tries - - ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( tries  < =  0 )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      last_resume_from  =  resume_from ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // printf("res %d\n", res);
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // printf("- %ld %f\n", response_code, content_length);
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fclose ( of ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  ret ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  void  set_progress ( std : : string  text )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : lock_guard < std : : mutex >  guard ( lock ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    progress_text  =  text ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  void  set_error ( std : : string  text )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : lock_guard < std : : mutex >  guard ( lock ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    error_text  =  text ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    state  =  ERROR ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  void  set_battery_low ( )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : lock_guard < std : : mutex >  guard ( lock ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    state  =  LOW_BATTERY ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  void  set_running ( )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : lock_guard < std : : mutex >  guard ( lock ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    state  =  RUNNING ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  std : : string  download ( std : : string  url ,  std : : string  hash ,  std : : string  name )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : string  out_fn  =  UPDATE_DIR  " / "  +  util : : base_name ( url ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // start or resume downloading if hash doesn't match
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : string  fn_hash  =  sha256_file ( out_fn ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( hash . compare ( fn_hash )  ! =  0 )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_progress ( " Downloading  "  +  name  +  " ... " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      bool  r  =  download_file ( url ,  out_fn ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! r )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        set_error ( " failed to download  "  +  name ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        unlink ( out_fn . c_str ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  " " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      fn_hash  =  sha256_file ( out_fn ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    set_progress ( " Verifying  "  +  name  +  " ... " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    printf ( " got %s hash: %s \n " ,  name . c_str ( ) ,  hash . c_str ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( fn_hash  ! =  hash )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_error ( name  +  "  was corrupt " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      unlink ( out_fn . c_str ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return  " " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  out_fn ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  bool  download_stage ( )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    curl  =  curl_easy_init ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    assert ( curl ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // ** quick checks before download **
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! check_space ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_error ( " 2GB of free space required to update " ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    mkdir ( UPDATE_DIR ,  0777 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    set_progress ( " Finding latest version... " ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    std : : string  manifest_s  =  download_string ( curl ,  manifest_url ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    printf ( " manifest: %s \n " ,  manifest_s . c_str ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : string  err ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  manifest  =  json11 : : Json : : parse ( manifest_s ,  err ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( manifest . is_null ( )  | |  ! err . empty ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_error ( " failed to load update manifest " ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : string  ota_url  =  manifest [ " ota_url " ] . string_value ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : string  ota_hash  =  manifest [ " ota_hash " ] . string_value ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : string  recovery_url  =  manifest [ " recovery_url " ] . string_value ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    recovery_hash  =  manifest [ " recovery_hash " ] . string_value ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    recovery_len  =  manifest [ " recovery_len " ] . int_value ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // std::string installer_url = manifest["installer_url"].string_value();
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // std::string installer_hash = manifest["installer_hash"].string_value();
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ota_url . empty ( )  | |  ota_hash . empty ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_error ( " invalid update manifest " ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // std::string installer_fn = download(installer_url, installer_hash, "installer");
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // if (installer_fn.empty()) {
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //   //error'd
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //   return;
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // }
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // ** handle recovery download **
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( recovery_url . empty ( )  | |  recovery_hash . empty ( )  | |  recovery_len  = =  0 )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_progress ( " Skipping recovery flash... " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // only download the recovery if it differs from what's flashed
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_progress ( " Checking recovery... " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      std : : string  existing_recovery_hash  =  sha256_file ( RECOVERY_DEV ,  recovery_len ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      printf ( " existing recovery hash: %s \n " ,  existing_recovery_hash . c_str ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( existing_recovery_hash  ! =  recovery_hash )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        recovery_fn  =  download ( recovery_url ,  recovery_hash ,  " recovery " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( recovery_fn . empty ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          // error'd
   
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								          return  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // ** handle ota download **
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ota_fn  =  download ( ota_url ,  ota_hash ,  " update " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ota_fn . empty ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      //error'd
   
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // download sucessful
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  true ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // thread that handles downloading and installing the update
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  void  run_stages ( )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    printf ( " run_stages start \n " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // ** download update **
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! check_battery ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_battery_low ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  battery_cap  =  battery_capacity ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      while ( battery_cap  <  min_battery_cap )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        battery_cap  =  battery_capacity ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        battery_cap_text  =  std : : to_string ( battery_cap ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        usleep ( 1000000 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_running ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    bool  sucess  =  download_stage ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! sucess )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // ** install update **
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! check_battery ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_battery_low ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  battery_cap  =  battery_capacity ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      while ( battery_cap  <  min_battery_cap )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        battery_cap  =  battery_capacity ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        battery_cap_text  =  std : : to_string ( battery_cap ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        usleep ( 1000000 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_running ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! recovery_fn . empty ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // flash recovery
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_progress ( " Flashing recovery... " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      FILE  * flash_file  =  fopen ( recovery_fn . c_str ( ) ,  " rb " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! flash_file )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        set_error ( " failed to flash recovery " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      FILE  * recovery_dev  =  fopen ( RECOVERY_DEV ,  " w+b " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! recovery_dev )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        fclose ( flash_file ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        set_error ( " failed to flash recovery " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      const  size_t  buf_size  =  4096 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      std : : unique_ptr < char [ ] >  buffer (  new  char [  buf_size  ]  ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      while  ( true )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        size_t  bytes_read  =  fread ( buffer . get ( ) ,  1 ,  buf_size ,  flash_file ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! bytes_read )  break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        size_t  bytes_written  =  fwrite ( buffer . get ( ) ,  1 ,  bytes_read ,  recovery_dev ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( bytes_read  ! =  bytes_written )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          fclose ( recovery_dev ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          fclose ( flash_file ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          set_error ( " failed to flash recovery: write failed " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          return ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      fclose ( recovery_dev ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      fclose ( flash_file ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_progress ( " Verifying flash... " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      std : : string  new_recovery_hash  =  sha256_file ( RECOVERY_DEV ,  recovery_len ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      printf ( " new recovery hash: %s \n " ,  new_recovery_hash . c_str ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( new_recovery_hash  ! =  recovery_hash )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        set_error ( " recovery flash corrupted " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // write arguments to recovery
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    FILE  * cmd_file  =  fopen ( RECOVERY_COMMAND ,  " wb " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! cmd_file )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      set_error ( " failed to reboot into recovery " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fprintf ( cmd_file ,  " --update_package=%s \n " ,  ota_fn . c_str ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fclose ( cmd_file ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    set_progress ( " Rebooting " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // remove the continue.sh so we come back into the setup.
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // maybe we should go directly into the installer, but what if we don't come back with internet? :/
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //unlink("/data/data/com.termux/files/continue.sh");
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // TODO: this should be generic between android versions
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // IPowerManager.reboot(confirm=false, reason="recovery", wait=true)
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    system ( " service call power 16 i32 0 s16 recovery i32 1 " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while ( 1 )  pause ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // execl("/system/bin/reboot", "recovery");
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // set_error("failed to reboot into recovery");
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  void  draw_ack_screen ( const  char  * title ,  const  char  * message ,  const  char  * button ,  const  char  * altbutton )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFillColor ( vg ,  nvgRGBA ( 255 , 255 , 255 , 255 ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgTextAlign ( vg ,  NVG_ALIGN_CENTER  |  NVG_ALIGN_BASELINE ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontFace ( vg ,  " opensans_bold " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontSize ( vg ,  120.0f ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgTextBox ( vg ,  110 ,  220 ,  fb_w - 240 ,  title ,  NULL ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontFace ( vg ,  " opensans_regular " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontSize ( vg ,  86.0f ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgTextBox ( vg ,  130 ,  380 ,  fb_w - 260 ,  message ,  NULL ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // draw button
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( button )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgBeginPath ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFillColor ( vg ,  nvgRGBA ( 8 ,  8 ,  8 ,  255 ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgRoundedRect ( vg ,  b_x ,  b_y ,  b_w ,  b_h ,  20 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFill ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFillColor ( vg ,  nvgRGBA ( 255 ,  255 ,  255 ,  255 ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFontFace ( vg ,  " opensans_semibold " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgTextAlign ( vg ,  NVG_ALIGN_CENTER  |  NVG_ALIGN_MIDDLE ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgText ( vg ,  b_x + b_w / 2 ,  b_y + b_h / 2 ,  button ,  NULL ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgBeginPath ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgStrokeColor ( vg ,  nvgRGBA ( 255 ,  255 ,  255 ,  50 ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgStrokeWidth ( vg ,  5 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgRoundedRect ( vg ,  b_x ,  b_y ,  b_w ,  b_h ,  20 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgStroke ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // draw button
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( altbutton )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgBeginPath ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFillColor ( vg ,  nvgRGBA ( 8 ,  8 ,  8 ,  255 ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgRoundedRect ( vg ,  balt_x ,  b_y ,  b_w ,  b_h ,  20 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFill ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFillColor ( vg ,  nvgRGBA ( 255 ,  255 ,  255 ,  255 ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFontFace ( vg ,  " opensans_semibold " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgTextAlign ( vg ,  NVG_ALIGN_CENTER  |  NVG_ALIGN_MIDDLE ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgText ( vg ,  balt_x + b_w / 2 ,  b_y + b_h / 2 ,  altbutton ,  NULL ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgBeginPath ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgStrokeColor ( vg ,  nvgRGBA ( 255 ,  255 ,  255 ,  50 ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgStrokeWidth ( vg ,  5 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgRoundedRect ( vg ,  balt_x ,  b_y ,  b_w ,  b_h ,  20 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgStroke ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  void  draw_battery_screen ( )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    low_battery_title  =  " Low Battery " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    low_battery_text  =  " Please connect EON to your charger. Update will continue once EON battery reaches 35%. " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    low_battery_context  =  " Current battery charge:  "  +  battery_cap_text  +  " % " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFillColor ( vg ,  nvgRGBA ( 255 , 255 , 255 , 255 ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgTextAlign ( vg ,  NVG_ALIGN_CENTER  |  NVG_ALIGN_BASELINE ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontFace ( vg ,  " opensans_bold " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontSize ( vg ,  120.0f ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgTextBox ( vg ,  110 ,  220 ,  fb_w - 240 ,  low_battery_title . c_str ( ) ,  NULL ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontFace ( vg ,  " opensans_regular " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontSize ( vg ,  86.0f ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgTextBox ( vg ,  130 ,  380 ,  fb_w - 260 ,  low_battery_text . c_str ( ) ,  NULL ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontFace ( vg ,  " opensans_bold " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontSize ( vg ,  86.0f ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgTextBox ( vg ,  130 ,  700 ,  fb_w - 260 ,  low_battery_context . c_str ( ) ,  NULL ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  void  draw_progress_screen ( )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // draw progress message
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontSize ( vg ,  64.0f ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFillColor ( vg ,  nvgRGBA ( 255 , 255 , 255 , 255 ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgTextAlign ( vg ,  NVG_ALIGN_CENTER  |  NVG_ALIGN_BASELINE ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontFace ( vg ,  " opensans_bold " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgFontSize ( vg ,  86.0f ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgTextBox ( vg ,  0 ,  380 ,  fb_w ,  progress_text . c_str ( ) ,  NULL ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // draw progress bar
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  progress_width  =  1000 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  progress_x  =  fb_w / 2 - progress_width / 2 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  progress_y  =  520 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  progress_height  =  50 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  powerprompt_y  =  312 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFontFace ( vg ,  " opensans_regular " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFontSize ( vg ,  64.0f ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      nvgText ( vg ,  fb_w / 2 ,  740 ,  " Ensure your device remains connected to a power source. " ,  NULL ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      NVGpaint  paint  =  nvgBoxGradient ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          vg ,  progress_x  +  1 ,  progress_y  +  1 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          progress_width  -  2 ,  progress_height ,  3 ,  4 ,  nvgRGB ( 27 ,  27 ,  27 ) ,  nvgRGB ( 27 ,  27 ,  27 ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgBeginPath ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgRoundedRect ( vg ,  progress_x ,  progress_y ,  progress_width ,  progress_height ,  12 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFillPaint ( vg ,  paint ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFill ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      float  value  =  std : : min ( std : : max ( 0.0f ,  progress_frac ) ,  1.0f ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  bar_pos  =  ( ( progress_width  -  2 )  *  value ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      paint  =  nvgBoxGradient ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          vg ,  progress_x ,  progress_y , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          bar_pos + 1.5f ,  progress_height - 1 ,  3 ,  4 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          nvgRGB ( 245 ,  245 ,  245 ) ,  nvgRGB ( 105 ,  105 ,  105 ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgBeginPath ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgRoundedRect ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          vg ,  progress_x + 1 ,  progress_y + 1 , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          bar_pos ,  progress_height - 2 ,  12 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFillPaint ( vg ,  paint ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFill ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  void  ui_draw ( )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : lock_guard < std : : mutex >  guard ( lock ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgBeginFrame ( vg ,  fb_w ,  fb_h ,  1.0f ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( state )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  CONFIRMATION : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      draw_ack_screen ( " An update to NEOS is required. " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      " Your device will now be reset and upgraded. You may want to connect to wifi as download is around 1 GB. Existing data on device should not be lost. " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      " Continue " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                      " Connect to WiFi " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  LOW_BATTERY : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      draw_battery_screen ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  RUNNING : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      draw_progress_screen ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  ERROR : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      draw_ack_screen ( " There was an error " ,  ( error_text ) . c_str ( ) ,  NULL ,  " Reboot " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    nvgEndFrame ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  void  ui_update ( )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : lock_guard < std : : mutex >  guard ( lock ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( state  = =  ERROR  | |  state  = =  CONFIRMATION )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  touch_x  =  - 1 ,  touch_y  =  - 1 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  res  =  touch_poll ( & touch ,  & touch_x ,  & touch_y ,  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( res  = =  1  & &  ! is_settings_active ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( touch_x  > =  b_x  & &  touch_x  <  b_x + b_w  & &  touch_y  > =  b_y  & &  touch_y  <  b_y + b_h )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( state  = =  CONFIRMATION )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            state  =  RUNNING ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            update_thread_handle  =  std : : thread ( & Updater : : run_stages ,  this ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( touch_x  > =  balt_x  & &  touch_x  <  balt_x + b_w  & &  touch_y  > =  b_y  & &  touch_y  <  b_y + b_h )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if  ( state  = =  CONFIRMATION )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            start_settings_activity ( " Settings$WifiSettingsActivity " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          }  else  if  ( state  = =  ERROR )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            do_exit  =  1 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  void  go ( )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    ui_init ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( ! do_exit )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ui_update ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      glClearColor ( 0.08 ,  0.08 ,  0.08 ,  1.0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      glClear ( GL_STENCIL_BUFFER_BIT  |  GL_COLOR_BUFFER_BIT ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // background
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgBeginPath ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      NVGpaint  bg  =  nvgLinearGradient ( vg ,  fb_w ,  0 ,  fb_w ,  fb_h , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        nvgRGBA ( 0 ,  0 ,  0 ,  0 ) ,  nvgRGBA ( 0 ,  0 ,  0 ,  255 ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFillPaint ( vg ,  bg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgRect ( vg ,  0 ,  0 ,  fb_w ,  fb_h ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      nvgFill ( vg ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      glEnable ( GL_BLEND ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      glBlendFunc ( GL_SRC_ALPHA ,  GL_ONE_MINUS_SRC_ALPHA ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ui_draw ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      glDisable ( GL_BLEND ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      framebuffer_swap ( fb ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      assert ( glGetError ( )  = =  GL_NO_ERROR ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // no simple way to do 30fps vsync with surfaceflinger...
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      usleep ( 30000 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( update_thread_handle . joinable ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      update_thread_handle . join ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // reboot
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    system ( " service call power 16 i32 0 i32 0 i32 1 " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ; 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  main ( int  argc ,  char  * argv [ ] )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  bool  background_cache  =  false ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( argc  >  1 )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( strcmp ( argv [ 1 ] ,  " local " )  = =  0 )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      manifest_url  =  MANIFEST_URL_NEOS_LOCAL ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( strcmp ( argv [ 1 ] ,  " staging " )  = =  0 )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      manifest_url  =  MANIFEST_URL_NEOS_STAGING ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( strcmp ( argv [ 1 ] ,  " bgcache " )  = =  0 )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      manifest_url  =  argv [ 2 ] ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      background_cache  =  true ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      manifest_url  =  argv [ 1 ] ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  printf ( " updating from %s \n " ,  manifest_url ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Updater  updater ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  int  err  =  0 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( background_cache )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    err  =  ! updater . download_stage ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  }  else  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    updater . go ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  err ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}