Files
dragonpilot/selfdrive/manager.py

565 lines
16 KiB
Python
Raw Normal View History

2019-10-09 18:43:53 +00:00
#!/usr/bin/env python3.7
2016-11-29 18:34:21 -08:00
import os
2019-10-31 17:14:40 -07:00
import time
2017-10-31 02:27:39 -07:00
import sys
import fcntl
import errno
import signal
2018-05-24 00:03:09 +02:00
import subprocess
2019-10-09 18:43:53 +00:00
import datetime
from common.spinner import Spinner
2017-05-11 12:41:17 -07:00
2018-05-23 03:59:04 +00:00
from common.basedir import BASEDIR
sys.path.append(os.path.join(BASEDIR, "pyextra"))
os.environ['BASEDIR'] = BASEDIR
2018-09-03 16:43:12 -07:00
def unblock_stdout():
2017-10-31 02:27:39 -07:00
# get a non-blocking stdout
child_pid, child_pty = os.forkpty()
if child_pid != 0: # parent
# child is in its own process group, manually pass kill signals
signal.signal(signal.SIGINT, lambda signum, frame: os.kill(child_pid, signal.SIGINT))
signal.signal(signal.SIGTERM, lambda signum, frame: os.kill(child_pid, signal.SIGTERM))
fcntl.fcntl(sys.stdout, fcntl.F_SETFL,
fcntl.fcntl(sys.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
while True:
try:
dat = os.read(child_pty, 4096)
except OSError as e:
if e.errno == errno.EIO:
break
continue
if not dat:
break
try:
2019-10-09 18:43:53 +00:00
sys.stdout.write(dat.decode('utf8'))
2017-10-31 02:27:39 -07:00
except (OSError, IOError):
pass
os._exit(os.wait()[1])
2017-05-11 12:41:17 -07:00
2018-09-03 16:43:12 -07:00
if __name__ == "__main__":
unblock_stdout()
2018-01-16 16:51:33 -08:00
import glob
2017-12-23 17:15:27 -08:00
import shutil
2017-10-31 02:27:39 -07:00
import hashlib
2016-11-29 18:34:21 -08:00
import importlib
import traceback
from multiprocessing import Process
2017-09-30 03:07:27 -07:00
2018-03-31 07:33:16 +00:00
from setproctitle import setproctitle #pylint: disable=no-name-in-module
2016-11-29 18:34:21 -08:00
2017-10-31 02:27:39 -07:00
from common.params import Params
2018-07-12 18:52:06 -07:00
import cereal
ThermalStatus = cereal.log.ThermalData.ThermalStatus
2017-09-30 03:07:27 -07:00
2016-11-29 18:34:21 -08:00
from selfdrive.swaglog import cloudlog
import selfdrive.messaging as messaging
from selfdrive.registration import register
2018-07-12 18:52:06 -07:00
from selfdrive.version import version, dirty
2017-10-03 00:22:32 -07:00
import selfdrive.crash as crash
2016-11-29 18:34:21 -08:00
2017-01-09 20:59:00 -08:00
from selfdrive.loggerd.config import ROOT
2016-11-29 18:34:21 -08:00
# comment out anything you don't want to run
managed_processes = {
2018-07-12 18:52:06 -07:00
"thermald": "selfdrive.thermald",
2016-11-29 18:34:21 -08:00
"uploader": "selfdrive.loggerd.uploader",
2019-05-16 13:20:29 -07:00
"deleter": "selfdrive.loggerd.deleter",
2016-11-29 18:34:21 -08:00
"controlsd": "selfdrive.controls.controlsd",
2019-02-20 01:39:02 +00:00
"plannerd": "selfdrive.controls.plannerd",
2016-11-29 18:34:21 -08:00
"radard": "selfdrive.controls.radard",
2019-04-23 01:41:19 +00:00
"ubloxd": ("selfdrive/locationd", ["./ubloxd"]),
2017-09-30 03:07:27 -07:00
"loggerd": ("selfdrive/loggerd", ["./loggerd"]),
2016-11-29 18:34:21 -08:00
"logmessaged": "selfdrive.logmessaged",
2017-05-11 12:41:17 -07:00
"tombstoned": "selfdrive.tombstoned",
2017-09-30 03:07:27 -07:00
"logcatd": ("selfdrive/logcatd", ["./logcatd"]),
"proclogd": ("selfdrive/proclogd", ["./proclogd"]),
2017-10-31 02:27:39 -07:00
"boardd": ("selfdrive/boardd", ["./boardd"]), # not used directly
"pandad": "selfdrive.pandad",
2019-06-06 04:38:45 +00:00
"ui": ("selfdrive/ui", ["./start.py"]),
2018-08-19 20:36:37 -07:00
"calibrationd": "selfdrive.locationd.calibrationd",
2019-07-22 19:17:47 +00:00
"paramsd": ("selfdrive/locationd", ["./paramsd"]),
2019-10-31 17:14:40 -07:00
"visiond": ("selfdrive/visiond", ["./start.py"]),
2019-06-28 21:11:30 +00:00
"sensord": ("selfdrive/sensord", ["./start_sensord.py"]),
"gpsd": ("selfdrive/sensord", ["./start_gpsd.py"]),
2017-10-31 02:27:39 -07:00
"updated": "selfdrive.updated",
2019-07-22 19:17:47 +00:00
}
daemon_processes = {
2019-10-31 17:14:40 -07:00
"manage_athenad": ("selfdrive.athena.manage_athenad", "AthenadPid"),
2017-10-31 02:27:39 -07:00
}
2018-07-12 18:52:06 -07:00
android_packages = ("ai.comma.plus.offroad", "ai.comma.plus.frame")
2016-11-29 18:34:21 -08:00
running = {}
2017-06-28 13:57:09 -07:00
def get_running():
return running
2016-11-29 18:34:21 -08:00
2016-12-12 17:47:46 -08:00
# due to qualcomm kernel bugs SIGKILLing visiond sometimes causes page table corruption
unkillable_processes = ['visiond']
# processes to end with SIGINT instead of SIGTERM
2017-05-11 12:41:17 -07:00
interrupt_processes = []
2019-07-30 02:27:48 +00:00
# processes to end with SIGKILL instead of SIGTERM
2019-10-09 18:43:53 +00:00
kill_processes = ['sensord', 'paramsd']
2019-07-30 02:27:48 +00:00
2017-10-31 02:27:39 -07:00
persistent_processes = [
2018-07-12 18:52:06 -07:00
'thermald',
2017-10-31 02:27:39 -07:00
'logmessaged',
'logcatd',
'tombstoned',
'uploader',
'ui',
'updated',
]
2017-05-11 12:41:17 -07:00
car_started_processes = [
'controlsd',
2019-02-20 01:39:02 +00:00
'plannerd',
2017-05-11 12:41:17 -07:00
'loggerd',
'sensord',
'radard',
2018-08-19 20:36:37 -07:00
'calibrationd',
2019-07-22 19:17:47 +00:00
'paramsd',
2017-05-11 12:41:17 -07:00
'visiond',
'proclogd',
2018-08-02 02:58:52 +00:00
'ubloxd',
2019-06-06 04:38:45 +00:00
'gpsd',
'deleter',
2017-05-11 12:41:17 -07:00
]
def register_managed_process(name, desc, car_started=False):
2017-10-31 02:27:39 -07:00
global managed_processes, car_started_processes, persistent_processes
2018-07-12 18:52:06 -07:00
print("registering %s" % name)
2017-05-11 12:41:17 -07:00
managed_processes[name] = desc
if car_started:
car_started_processes.append(name)
2017-10-31 02:27:39 -07:00
else:
persistent_processes.append(name)
2016-11-29 18:34:21 -08:00
# ****************** process management functions ******************
2019-06-28 21:11:30 +00:00
def launcher(proc):
2016-11-29 18:34:21 -08:00
try:
# import the process
mod = importlib.import_module(proc)
# rename the process
setproctitle(proc)
2019-10-31 17:14:40 -07:00
# create now context since we forked
messaging.context = messaging.Context()
2019-06-28 21:11:30 +00:00
2016-11-29 18:34:21 -08:00
# exec the process
2019-06-28 21:11:30 +00:00
mod.main()
2017-01-09 20:59:00 -08:00
except KeyboardInterrupt:
2017-10-31 02:27:39 -07:00
cloudlog.warning("child %s got SIGINT" % proc)
2016-11-29 18:34:21 -08:00
except Exception:
# can't install the crash handler becuase sys.excepthook doesn't play nice
# with threads, so catch it here.
2017-05-11 12:41:17 -07:00
crash.capture_exception()
2016-11-29 18:34:21 -08:00
raise
def nativelauncher(pargs, cwd):
# exec the process
os.chdir(cwd)
# because when extracted from pex zips permissions get lost -_-
os.chmod(pargs[0], 0o700)
os.execvp(pargs[0], pargs)
def start_managed_process(name):
if name in running or name not in managed_processes:
return
proc = managed_processes[name]
2018-07-12 18:52:06 -07:00
if isinstance(proc, str):
2016-11-29 18:34:21 -08:00
cloudlog.info("starting python %s" % proc)
2019-06-28 21:11:30 +00:00
running[name] = Process(name=name, target=launcher, args=(proc,))
2016-11-29 18:34:21 -08:00
else:
pdir, pargs = proc
2017-09-30 03:07:27 -07:00
cwd = os.path.join(BASEDIR, pdir)
2016-11-29 18:34:21 -08:00
cloudlog.info("starting process %s" % name)
running[name] = Process(name=name, target=nativelauncher, args=(pargs, cwd))
running[name].start()
2019-07-22 19:17:47 +00:00
def start_daemon_process(name, params):
2019-10-31 17:14:40 -07:00
proc, pid_param = daemon_processes[name]
2019-07-22 19:17:47 +00:00
pid = params.get(pid_param)
if pid is not None:
try:
os.kill(int(pid), 0)
# process is running (kill is a poorly-named system call)
return
except OSError:
# process is dead
pass
cloudlog.info("starting daemon %s" % name)
proc = subprocess.Popen(['python', '-m', proc],
cwd='/',
stdout=open('/dev/null', 'w'),
stderr=open('/dev/null', 'w'),
preexec_fn=os.setpgrp)
params.put(pid_param, str(proc.pid))
2017-09-30 03:07:27 -07:00
def prepare_managed_process(p):
proc = managed_processes[p]
2018-07-12 18:52:06 -07:00
if isinstance(proc, str):
2017-09-30 03:07:27 -07:00
# import this python
cloudlog.info("preimporting %s" % proc)
importlib.import_module(proc)
else:
# build this process
cloudlog.info("building %s" % (proc,))
try:
subprocess.check_call(["make", "-j4"], cwd=os.path.join(BASEDIR, proc[0]))
except subprocess.CalledProcessError:
# make clean if the build failed
2017-10-31 02:27:39 -07:00
cloudlog.warning("building %s failed, make clean" % (proc, ))
2017-09-30 03:07:27 -07:00
subprocess.check_call(["make", "clean"], cwd=os.path.join(BASEDIR, proc[0]))
subprocess.check_call(["make", "-j4"], cwd=os.path.join(BASEDIR, proc[0]))
2016-11-29 18:34:21 -08:00
def kill_managed_process(name):
if name not in running or name not in managed_processes:
return
cloudlog.info("killing %s" % name)
2016-12-12 17:47:46 -08:00
2016-11-29 18:34:21 -08:00
if running[name].exitcode is None:
2017-05-11 12:41:17 -07:00
if name in interrupt_processes:
os.kill(running[name].pid, signal.SIGINT)
2019-07-30 02:27:48 +00:00
elif name in kill_processes:
os.kill(running[name].pid, signal.SIGKILL)
2016-12-12 17:47:46 -08:00
else:
2017-05-11 12:41:17 -07:00
running[name].terminate()
2019-10-31 17:14:40 -07:00
# Process().join(timeout) will hang due to a python 3 bug: https://bugs.python.org/issue28382
# We have to poll the exitcode instead
# running[name].join(5.0)
t = time.time()
while time.time() - t < 5 and running[name].exitcode is None:
time.sleep(0.001)
2017-05-11 12:41:17 -07:00
if running[name].exitcode is None:
if name in unkillable_processes:
cloudlog.critical("unkillable process %s failed to exit! rebooting in 15 if it doesn't die" % name)
running[name].join(15.0)
if running[name].exitcode is None:
cloudlog.critical("FORCE REBOOTING PHONE!")
2017-10-31 02:27:39 -07:00
os.system("date >> /sdcard/unkillable_reboot")
2017-05-11 12:41:17 -07:00
os.system("reboot")
raise RuntimeError
else:
cloudlog.info("killing %s with SIGKILL" % name)
os.kill(running[name].pid, signal.SIGKILL)
running[name].join()
2016-12-12 17:47:46 -08:00
cloudlog.info("%s is dead with %d" % (name, running[name].exitcode))
2016-11-29 18:34:21 -08:00
del running[name]
2018-07-12 18:52:06 -07:00
def pm_apply_packages(cmd):
for p in android_packages:
system("pm %s %s" % (cmd, p))
2016-11-29 18:34:21 -08:00
def cleanup_all_processes(signal, frame):
cloudlog.info("caught ctrl-c %s %s" % (signal, frame))
2017-12-23 17:15:27 -08:00
2018-07-12 18:52:06 -07:00
pm_apply_packages('disable')
2017-12-23 17:15:27 -08:00
2018-07-12 18:52:06 -07:00
for name in list(running.keys()):
2016-11-29 18:34:21 -08:00
kill_managed_process(name)
2017-12-23 17:15:27 -08:00
cloudlog.info("everything is dead")
2017-05-11 12:41:17 -07:00
2017-10-31 02:27:39 -07:00
2016-11-29 18:34:21 -08:00
# ****************** run loop ******************
2018-03-17 00:01:50 -07:00
def manager_init(should_register=True):
if should_register:
reg_res = register()
if reg_res:
dongle_id, dongle_secret = reg_res
else:
raise Exception("server registration failed")
2016-11-29 18:34:21 -08:00
else:
2018-03-17 00:01:50 -07:00
dongle_id = "c"*16
2016-11-29 18:34:21 -08:00
# set dongle id
cloudlog.info("dongle id is " + dongle_id)
os.environ['DONGLE_ID'] = dongle_id
2017-05-22 22:26:12 -07:00
cloudlog.info("dirty is %d" % dirty)
if not dirty:
os.environ['CLEAN'] = '1'
2018-07-12 18:52:06 -07:00
cloudlog.bind_global(dongle_id=dongle_id, version=version, dirty=dirty, is_eon=True)
2017-05-11 12:41:17 -07:00
crash.bind_user(id=dongle_id)
2018-07-12 18:52:06 -07:00
crash.bind_extra(version=version, dirty=dirty, is_eon=True)
2017-05-11 12:41:17 -07:00
2017-05-22 22:26:12 -07:00
os.umask(0)
try:
2018-07-12 18:52:06 -07:00
os.mkdir(ROOT, 0o777)
2017-05-22 22:26:12 -07:00
except OSError:
pass
2016-11-29 18:34:21 -08:00
2017-05-22 22:26:12 -07:00
def system(cmd):
try:
cloudlog.info("running %s" % cmd)
subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
2018-07-12 18:52:06 -07:00
except subprocess.CalledProcessError as e:
2017-05-22 22:26:12 -07:00
cloudlog.event("running failed",
cmd=e.cmd,
2017-09-30 03:07:27 -07:00
output=e.output[-1024:],
2017-05-22 22:26:12 -07:00
returncode=e.returncode)
2017-10-31 02:27:39 -07:00
2016-11-29 18:34:21 -08:00
def manager_thread():
# now loop
2019-10-31 17:14:40 -07:00
thermal_sock = messaging.sub_sock('thermal')
2016-11-29 18:34:21 -08:00
2017-05-11 12:41:17 -07:00
cloudlog.info("manager start")
2017-10-31 02:27:39 -07:00
cloudlog.info({"environ": os.environ})
2018-08-02 02:58:52 +00:00
# save boot log
subprocess.call(["./loggerd", "--bootlog"], cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))
2019-07-22 19:17:47 +00:00
params = Params()
# start daemon processes
for p in daemon_processes:
start_daemon_process(p, params)
2019-06-06 04:38:45 +00:00
# start persistent processes
2017-10-31 02:27:39 -07:00
for p in persistent_processes:
start_managed_process(p)
2016-11-29 18:34:21 -08:00
2017-12-23 17:15:27 -08:00
# start frame
2018-07-12 18:52:06 -07:00
pm_apply_packages('enable')
2019-09-09 23:03:02 +00:00
system("LD_LIBRARY_PATH= appops set ai.comma.plus.offroad SU allow")
2017-12-23 17:15:27 -08:00
system("am start -n ai.comma.plus.frame/.MainActivity")
2016-11-29 18:34:21 -08:00
2017-09-30 03:07:27 -07:00
if os.getenv("NOBOARD") is None:
2017-10-31 02:27:39 -07:00
start_managed_process("pandad")
2017-01-09 20:59:00 -08:00
logger_dead = False
2017-01-29 09:20:32 -08:00
2016-11-29 18:34:21 -08:00
while 1:
2018-07-12 18:52:06 -07:00
msg = messaging.recv_sock(thermal_sock, wait=True)
2016-11-29 18:34:21 -08:00
# uploader is gated based on the phone temperature
2018-07-12 18:52:06 -07:00
if msg.thermal.thermalStatus >= ThermalStatus.yellow:
2016-11-29 18:34:21 -08:00
kill_managed_process("uploader")
2018-07-12 18:52:06 -07:00
else:
2016-11-29 18:34:21 -08:00
start_managed_process("uploader")
2018-07-12 18:52:06 -07:00
if msg.thermal.freeSpace < 0.05:
2017-01-09 20:59:00 -08:00
logger_dead = True
2018-07-12 18:52:06 -07:00
if msg.thermal.started:
2017-05-11 12:41:17 -07:00
for p in car_started_processes:
if p == "loggerd" and logger_dead:
2016-12-12 17:47:46 -08:00
kill_managed_process(p)
2017-05-11 12:41:17 -07:00
else:
start_managed_process(p)
else:
logger_dead = False
for p in car_started_processes:
kill_managed_process(p)
2016-11-29 18:34:21 -08:00
# check the status of all processes, did any of them die?
2019-06-06 04:38:45 +00:00
running_list = [" running %s %s" % (p, running[p]) for p in running]
cloudlog.debug('\n'.join(running_list))
2016-11-29 18:34:21 -08:00
2019-11-07 13:53:42 -08:00
# Exit main loop when uninstall is needed
if params.get("DoUninstall", encoding='utf8') == "1":
2017-12-23 17:15:27 -08:00
break
2017-05-11 12:41:17 -07:00
def get_installed_apks():
2019-10-09 18:43:53 +00:00
dat = subprocess.check_output(["pm", "list", "packages", "-f"], encoding='utf8').strip().split("\n") # pylint: disable=unexpected-keyword-arg
2017-05-11 12:41:17 -07:00
ret = {}
for x in dat:
if x.startswith("package:"):
v,k = x.split("package:")[1].split("=")
ret[k] = v
return ret
2016-11-29 18:34:21 -08:00
2017-12-23 17:15:27 -08:00
def install_apk(path):
# can only install from world readable path
install_path = "/sdcard/%s" % os.path.basename(path)
shutil.copyfile(path, install_path)
2017-06-28 13:57:09 -07:00
2017-12-23 17:15:27 -08:00
ret = subprocess.call(["pm", "install", "-r", install_path])
os.remove(install_path)
return ret == 0
2016-11-29 18:34:21 -08:00
2017-12-23 17:15:27 -08:00
def update_apks():
2017-05-11 12:41:17 -07:00
# install apks
installed = get_installed_apks()
2018-01-16 16:51:33 -08:00
2018-07-12 18:52:06 -07:00
install_apks = glob.glob(os.path.join(BASEDIR, "apk/*.apk"))
2018-01-16 16:51:33 -08:00
for apk in install_apks:
app = os.path.basename(apk)[:-4]
if app not in installed:
installed[app] = None
2017-05-11 12:41:17 -07:00
cloudlog.info("installed apks %s" % (str(installed), ))
2017-12-23 17:15:27 -08:00
getting ready for Python 3 (#619) * tabs to spaces python 2 to 3: https://portingguide.readthedocs.io/en/latest/syntax.html#tabs-and-spaces * use the new except syntax python 2 to 3: https://portingguide.readthedocs.io/en/latest/exceptions.html#the-new-except-syntax * make relative imports absolute python 2 to 3: https://portingguide.readthedocs.io/en/latest/imports.html#absolute-imports * Queue renamed to queue in python 3 Use the six compatibility library to support both python 2 and 3: https://portingguide.readthedocs.io/en/latest/stdlib-reorg.html#renamed-modules * replace dict.has_key() with in python 2 to 3: https://portingguide.readthedocs.io/en/latest/dicts.html#removed-dict-has-key * make dict views compatible with python 3 python 2 to 3: https://portingguide.readthedocs.io/en/latest/dicts.html#dict-views-and-iterators Where needed, wrapping things that will be a view in python 3 with a list(). For example, if it's accessed with [] Python 3 has no iter*() methods, so just using the values() instead of itervalues() as long as it's not too performance intensive. Note that any minor performance hit of using a list instead of a view will go away when switching to python 3. If it is intensive, we could use the six version. * Explicitly use truncating division python 2 to 3: https://portingguide.readthedocs.io/en/latest/numbers.html#division python 3 treats / as float division. When we want the result to be an integer, use // * replace map() with list comprehension where a list result is needed. In python 3, map() returns an iterator. python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-map-and-filter * replace filter() with list comprehension In python 3, filter() returns an interatoooooooooooor. python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-map-and-filter * wrap zip() in list() where we need the result to be a list python 2 to 3: https://portingguide.readthedocs.io/en/latest/iterators.html#new-behavior-of-zip * clean out some lint Removes these pylint warnings: ************* Module selfdrive.car.chrysler.chryslercan W: 15, 0: Unnecessary semicolon (unnecessary-semicolon) W: 16, 0: Unnecessary semicolon (unnecessary-semicolon) W: 25, 0: Unnecessary semicolon (unnecessary-semicolon) ************* Module common.dbc W:101, 0: Anomalous backslash in string: '\?'. String constant might be missing an r prefix. (anomalous-backslash-in-string) ************* Module selfdrive.car.gm.interface R:102, 6: Redefinition of ret.minEnableSpeed type from float to int (redefined-variable-type) R:103, 6: Redefinition of ret.mass type from int to float (redefined-variable-type) ************* Module selfdrive.updated R: 20, 6: Redefinition of r type from int to str (redefined-variable-type)
2019-05-02 11:08:59 -07:00
for app in installed.keys():
2018-02-06 12:43:45 -08:00
2017-06-28 13:57:09 -07:00
apk_path = os.path.join(BASEDIR, "apk/"+app+".apk")
2018-01-16 16:51:33 -08:00
if not os.path.exists(apk_path):
continue
2019-10-09 18:43:53 +00:00
h1 = hashlib.sha1(open(apk_path, 'rb').read()).hexdigest()
2018-01-16 16:51:33 -08:00
h2 = None
if installed[app] is not None:
2019-10-09 18:43:53 +00:00
h2 = hashlib.sha1(open(installed[app], 'rb').read()).hexdigest()
2018-01-16 16:51:33 -08:00
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)
2017-12-23 17:15:27 -08:00
success = install_apk(apk_path)
2018-01-16 16:51:33 -08:00
assert success
2017-12-23 17:15:27 -08:00
def manager_update():
update_apks()
2019-09-09 23:03:02 +00:00
uninstall = [app for app in get_installed_apks().keys() if app in ("com.spotify.music", "com.waze")]
for app in uninstall:
cloudlog.info("uninstalling %s" % app)
os.system("pm uninstall % s" % app)
2019-10-09 18:43:53 +00:00
def manager_prepare(spinner=None):
2017-12-23 17:15:27 -08:00
# build cereal first
subprocess.check_call(["make", "-j4"], cwd=os.path.join(BASEDIR, "cereal"))
# build all processes
os.chdir(os.path.dirname(os.path.abspath(__file__)))
2019-10-09 18:43:53 +00:00
for i, p in enumerate(managed_processes):
if spinner is not None:
spinner.update("%d" % (100.0 * (i + 1) / len(managed_processes),))
2017-12-23 17:15:27 -08:00
prepare_managed_process(p)
def uninstall():
cloudlog.warning("uninstalling")
with open('/cache/recovery/command', 'w') as f:
f.write('--wipe_data\n')
# IPowerManager.reboot(confirm=false, reason="recovery", wait=true)
2018-01-16 16:51:33 -08:00
os.system("service call power 16 i32 0 s16 recovery i32 1")
2017-05-11 12:41:17 -07:00
2016-11-29 18:34:21 -08:00
def main():
2018-06-16 20:59:34 -07:00
# the flippening!
os.system('LD_LIBRARY_PATH="" content insert --uri content://settings/system --bind name:s:user_rotation --bind value:i:1')
2019-08-13 01:36:45 +00:00
# disable bluetooth
os.system('service call bluetooth_manager 8')
2016-11-29 18:34:21 -08:00
if os.getenv("NOLOG") is not None:
del managed_processes['loggerd']
2017-05-11 12:41:17 -07:00
del managed_processes['tombstoned']
2016-12-12 17:47:46 -08:00
if os.getenv("NOUPLOAD") is not None:
del managed_processes['uploader']
2016-12-14 21:29:12 -08:00
if os.getenv("NOVISION") is not None:
del managed_processes['visiond']
if os.getenv("LEAN") is not None:
del managed_processes['uploader']
del managed_processes['loggerd']
del managed_processes['logmessaged']
del managed_processes['logcatd']
2017-05-11 12:41:17 -07:00
del managed_processes['tombstoned']
del managed_processes['proclogd']
2017-01-29 09:20:32 -08:00
if os.getenv("NOCONTROL") is not None:
del managed_processes['controlsd']
2019-02-20 01:39:02 +00:00
del managed_processes['plannerd']
2017-01-29 09:20:32 -08:00
del managed_processes['radard']
2018-05-23 03:59:04 +00:00
2017-05-11 12:41:17 -07:00
# support additional internal only extensions
try:
import selfdrive.manager_extensions
selfdrive.manager_extensions.register(register_managed_process) # pylint: disable=no-member
2017-05-11 12:41:17 -07:00
except ImportError:
pass
params = Params()
params.manager_start()
2017-05-22 22:26:12 -07:00
# set unset params
2019-10-09 18:43:53 +00:00
if params.get("CompletedTrainingVersion") is None:
params.put("CompletedTrainingVersion", "0")
2017-05-22 22:26:12 -07:00
if params.get("IsMetric") is None:
params.put("IsMetric", "0")
2018-04-14 06:10:58 +00:00
if params.get("RecordFront") is None:
params.put("RecordFront", "0")
2017-12-06 12:48:00 -08:00
if params.get("HasAcceptedTerms") is None:
params.put("HasAcceptedTerms", "0")
2019-10-09 18:43:53 +00:00
if params.get("HasCompletedSetup") is None:
params.put("HasCompletedSetup", "0")
2019-06-28 21:11:30 +00:00
if params.get("IsUploadRawEnabled") is None:
params.put("IsUploadRawEnabled", "1")
2017-12-23 17:15:27 -08:00
if params.get("IsUploadVideoOverCellularEnabled") is None:
params.put("IsUploadVideoOverCellularEnabled", "1")
2018-07-12 18:52:06 -07:00
if params.get("IsGeofenceEnabled") is None:
params.put("IsGeofenceEnabled", "-1")
2018-12-10 14:13:12 -08:00
if params.get("SpeedLimitOffset") is None:
params.put("SpeedLimitOffset", "0")
if params.get("LongitudinalControl") is None:
params.put("LongitudinalControl", "0")
if params.get("LimitSetSpeed") is None:
params.put("LimitSetSpeed", "0")
2019-07-30 02:27:48 +00:00
if params.get("LimitSetSpeedNeural") is None:
params.put("LimitSetSpeedNeural", "0")
2019-10-09 18:43:53 +00:00
if params.get("LastUpdateTime") is None:
t = datetime.datetime.now().isoformat()
params.put("LastUpdateTime", t.encode('utf8'))
if params.get("OpenpilotEnabledToggle") is None:
params.put("OpenpilotEnabledToggle", "1")
2017-05-22 22:26:12 -07:00
2018-03-17 00:01:50 -07:00
# is this chffrplus?
if os.getenv("PASSIVE") is not None:
params.put("Passive", str(int(os.getenv("PASSIVE"))))
if params.get("Passive") is None:
raise Exception("Passive must be set to continue")
2017-10-31 02:27:39 -07:00
2019-10-09 18:43:53 +00:00
with Spinner() as spinner:
spinner.update("0") # Show progress bar
manager_update()
manager_init()
manager_prepare(spinner)
2017-07-28 01:24:39 -07:00
2017-01-29 09:20:32 -08:00
if os.getenv("PREPAREONLY") is not None:
2017-10-31 02:27:39 -07:00
return
2016-11-29 18:34:21 -08:00
2017-12-23 17:15:27 -08:00
# SystemExit on sigterm
signal.signal(signal.SIGTERM, lambda signum, frame: sys.exit(1))
2017-01-29 09:20:32 -08:00
try:
manager_thread()
except Exception:
traceback.print_exc()
2017-05-11 12:41:17 -07:00
crash.capture_exception()
2017-01-29 09:20:32 -08:00
finally:
cleanup_all_processes(None, None)
2016-11-29 18:34:21 -08:00
2019-11-07 13:53:42 -08:00
if params.get("DoUninstall", encoding='utf8') == "1":
2017-12-23 17:15:27 -08:00
uninstall()
2016-11-29 18:34:21 -08:00
if __name__ == "__main__":
main()
2017-10-31 02:27:39 -07:00
# manual exit because we are forked
sys.exit(0)