import  os 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  subprocess 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  glob 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  hashlib 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  shutil 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  common . basedir  import  BASEDIR 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  selfdrive . swaglog  import  cloudlog 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								android_packages  =  ( " ai.comma.plus.offroad " , ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  get_installed_apks ( ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  dat  =  subprocess . check_output ( [ " pm " ,  " list " ,  " packages " ,  " -f " ] ,  encoding = ' utf8 ' ) . strip ( ) . split ( " \n " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ret  =  { } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  x  in  dat : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  x . startswith ( " package: " ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      v ,  k  =  x . split ( " package: " ) [ 1 ] . split ( " = " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ret [ k ]  =  v 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  ret 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  install_apk ( path ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # can only install from world readable path 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  install_path  =  " /sdcard/ %s "  %  os . path . basename ( path ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  shutil . copyfile ( path ,  install_path ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ret  =  subprocess . call ( [ " pm " ,  " install " ,  " -r " ,  install_path ] ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  os . remove ( install_path ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  ret  ==  0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								def  start_offroad ( ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  set_package_permissions ( ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  system ( " am start -n ai.comma.plus.offroad/.MainActivity " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  set_package_permissions ( ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  pm_grant ( " ai.comma.plus.offroad " ,  " android.permission.ACCESS_FINE_LOCATION " ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  pm_grant ( " ai.comma.plus.offroad " ,  " android.permission.READ_PHONE_STATE " ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  pm_grant ( " ai.comma.plus.offroad " ,  " android.permission.READ_EXTERNAL_STORAGE " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  appops_set ( " ai.comma.plus.offroad " ,  " SU " ,  " allow " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  appops_set ( " ai.comma.plus.offroad " ,  " WIFI_SCAN " ,  " allow " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  appops_set ( package ,  op ,  mode ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  system ( f " LD_LIBRARY_PATH= appops set  { package }   { op }   { mode } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  pm_grant ( package ,  permission ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  system ( f " pm grant  { package }   { permission } " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  system ( cmd ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  try : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    cloudlog . info ( " running  %s "  %  cmd ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    subprocess . check_output ( cmd ,  stderr = subprocess . STDOUT ,  shell = True ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  except  subprocess . CalledProcessError  as  e : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    cloudlog . event ( " running failed " , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      cmd = e . cmd , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      output = e . output [ - 1024 : ] , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      returncode = e . returncode ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# *** external functions *** 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  update_apks ( ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # install apks 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  installed  =  get_installed_apks ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  install_apks  =  glob . glob ( os . path . join ( BASEDIR ,  " apk/*.apk " ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  apk  in  install_apks : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    app  =  os . path . basename ( apk ) [ : - 4 ] 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  app  not  in  installed : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      installed [ app ]  =  None 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  cloudlog . info ( " installed apks  %s "  %  ( str ( installed ) ,  ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  app  in  installed . keys ( ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    apk_path  =  os . path . join ( BASEDIR ,  " apk/ " + app + " .apk " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  not  os . path . exists ( apk_path ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      continue 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    h1  =  hashlib . sha1 ( open ( apk_path ,  ' rb ' ) . read ( ) ) . hexdigest ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    h2  =  None 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  installed [ app ]  is  not  None : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      h2  =  hashlib . sha1 ( open ( installed [ app ] ,  ' rb ' ) . read ( ) ) . hexdigest ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      cloudlog . info ( " comparing version of  %s    %s  vs  %s "  %  ( app ,  h1 ,  h2 ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  h2  is  None  or  h1  !=  h2 : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      cloudlog . info ( " installing  %s "  %  app ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      success  =  install_apk ( apk_path ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  not  success : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        cloudlog . info ( " needing to uninstall  %s "  %  app ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        system ( " pm uninstall  %s "  %  app ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        success  =  install_apk ( apk_path ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      assert  success 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  pm_apply_packages ( cmd ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  p  in  android_packages : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    system ( " pm  %s   %s "  %  ( cmd ,  p ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if  __name__  ==  " __main__ " : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  update_apks ( )