From 39fc865f6066eb7795c30180dfd992bc5c18f0b0 Mon Sep 17 00:00:00 2001 From: dk Date: Tue, 30 Jul 2019 00:31:46 -0400 Subject: [PATCH 1/3] show process progress --- selfdrive/manager.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/selfdrive/manager.py b/selfdrive/manager.py index 4e52f2beb4bd4c..095a42d58b3082 100755 --- a/selfdrive/manager.py +++ b/selfdrive/manager.py @@ -494,15 +494,27 @@ def manager_update(): update_ssh() update_apks() -def manager_prepare(): +def manager_prepare(spinner_text): # 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__))) - for p in managed_processes: + + process_cnt = len(managed_processes) + loader_proc = [] + + for n,p in enumerate(managed_processes): + if os.getenv("PREPAREONLY") is None: + loader_proc.append(subprocess.Popen(["./spinner", + "loading {0}: {1}/{2} {3}".format(spinner_text, n+1, process_cnt, p)], + cwd=os.path.join(BASEDIR, "selfdrive", "ui", "spinner"), + close_fds=True)) prepare_managed_process(p) + # end subprocesses here to stop screen flickering + loader_proc = [loader_proc[pc].terminate() for pc in range(process_cnt) if loader_proc] + def uninstall(): cloudlog.warning("uninstalling") with open('/cache/recovery/command', 'w') as f: @@ -576,16 +588,17 @@ def main(): # put something on screen while we set things up if os.getenv("PREPAREONLY") is not None: + spinner_text = None spinner_proc = None else: spinner_text = "chffrplus" if params.get("Passive")=="1" else "openpilot" - spinner_proc = subprocess.Popen(["./spinner", "loading %s"%spinner_text], + spinner_proc = subprocess.Popen(["./spinner", "initializing {0}".format(spinner_text)], cwd=os.path.join(BASEDIR, "selfdrive", "ui", "spinner"), close_fds=True) try: manager_update() manager_init() - manager_prepare() + manager_prepare(spinner_text) finally: if spinner_proc: spinner_proc.terminate() From ff79075dd3600dd768c6cfa2086c2bde2789a820 Mon Sep 17 00:00:00 2001 From: dk Date: Tue, 30 Jul 2019 17:59:31 -0400 Subject: [PATCH 2/3] manager_prepare independence --- selfdrive/manager.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/selfdrive/manager.py b/selfdrive/manager.py index 095a42d58b3082..3207739b58a2ae 100755 --- a/selfdrive/manager.py +++ b/selfdrive/manager.py @@ -494,7 +494,7 @@ def manager_update(): update_ssh() update_apks() -def manager_prepare(spinner_text): +def manager_prepare(): # build cereal first subprocess.check_call(["make", "-j4"], cwd=os.path.join(BASEDIR, "cereal")) @@ -503,7 +503,8 @@ def manager_prepare(spinner_text): process_cnt = len(managed_processes) loader_proc = [] - + params = Params() + spinner_text = "chffrplus" if params.get("Passive")=="1" else "openpilot" for n,p in enumerate(managed_processes): if os.getenv("PREPAREONLY") is None: loader_proc.append(subprocess.Popen(["./spinner", @@ -513,7 +514,7 @@ def manager_prepare(spinner_text): prepare_managed_process(p) # end subprocesses here to stop screen flickering - loader_proc = [loader_proc[pc].terminate() for pc in range(process_cnt) if loader_proc] + [loader_proc[pc].terminate() for pc in range(process_cnt) if loader_proc] def uninstall(): cloudlog.warning("uninstalling") @@ -588,7 +589,6 @@ def main(): # put something on screen while we set things up if os.getenv("PREPAREONLY") is not None: - spinner_text = None spinner_proc = None else: spinner_text = "chffrplus" if params.get("Passive")=="1" else "openpilot" @@ -598,7 +598,7 @@ def main(): try: manager_update() manager_init() - manager_prepare(spinner_text) + manager_prepare() finally: if spinner_proc: spinner_proc.terminate() From a7923e00f393f18f0699c48b84b85c2e405fba4d Mon Sep 17 00:00:00 2001 From: dekerr Date: Sat, 17 Aug 2019 06:19:28 -0400 Subject: [PATCH 3/3] new piping --- selfdrive/manager.py | 30 +++++++++++++++++++----------- selfdrive/ui/spinner/spinner | Bin 239976 -> 239976 bytes selfdrive/ui/spinner/spinner.c | 28 ++++++++++++++++------------ 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/selfdrive/manager.py b/selfdrive/manager.py index e956a11a3fdbd6..5562dc98b50f5f 100755 --- a/selfdrive/manager.py +++ b/selfdrive/manager.py @@ -47,7 +47,7 @@ def unblock_stdout(): if is_neos: version = int(open("/VERSION").read()) if os.path.isfile("/VERSION") else 0 revision = int(open("/REVISION").read()) if version >= 10 else 0 # Revision only present in NEOS 10 and up - neos_update_required = version < 10 or (version == 10 and revision != 3) + neos_update_required = version < 10 or (version == 10 and revision != 4) if neos_update_required: # update continue.sh before updating NEOS @@ -504,21 +504,24 @@ def manager_prepare(): # build all processes os.chdir(os.path.dirname(os.path.abspath(__file__))) - - process_cnt = len(managed_processes) - loader_proc = [] + params = Params() + process_cnt = len(managed_processes) + loader_proc = subprocess.Popen(["./spinner"], stdin = subprocess.PIPE, + cwd=os.path.join(BASEDIR, "selfdrive", "ui", "spinner"), + close_fds=True) spinner_text = "chffrplus" if params.get("Passive")=="1" else "openpilot" + for n,p in enumerate(managed_processes): if os.getenv("PREPAREONLY") is None: - loader_proc.append(subprocess.Popen(["./spinner", - "loading {0}: {1}/{2} {3}".format(spinner_text, n+1, process_cnt, p)], - cwd=os.path.join(BASEDIR, "selfdrive", "ui", "spinner"), - close_fds=True)) + loader_text = "loading {0}: {1}/{2} {3}".format(spinner_text, n+1, process_cnt, p) + loader_proc.stdin.write(loader_text + "\n") prepare_managed_process(p) - + + loader_proc.stdin.close() + loader_proc.terminate() # end subprocesses here to stop screen flickering - [loader_proc[pc].terminate() for pc in range(process_cnt) if loader_proc] + #[loader_proc[pc].terminate() for pc in range(process_cnt) if loader_proc] def uninstall(): cloudlog.warning("uninstalling") @@ -531,6 +534,9 @@ def main(): # the flippening! os.system('LD_LIBRARY_PATH="" content insert --uri content://settings/system --bind name:s:user_rotation --bind value:i:1') + # disable bluetooth + os.system('service call bluetooth_manager 8') + if os.getenv("NOLOG") is not None: del managed_processes['loggerd'] del managed_processes['tombstoned'] @@ -598,9 +604,11 @@ def main(): spinner_proc = None else: spinner_text = "chffrplus" if params.get("Passive")=="1" else "openpilot" - spinner_proc = subprocess.Popen(["./spinner", "initializing {0}".format(spinner_text)], + init_text = "initializing {0}".format(spinner_text) + spinner_proc = subprocess.Popen(["./spinner"], stdin = subprocess.PIPE, cwd=os.path.join(BASEDIR, "selfdrive", "ui", "spinner"), close_fds=True) + spinner_proc.stdin.write(init_text + "\n") try: manager_update() manager_init() diff --git a/selfdrive/ui/spinner/spinner b/selfdrive/ui/spinner/spinner index acc86c78cd12292e0a9b765ff06f0be33cd30a8e..50f2bce6e7bab7828411989d1a8e119ff00ed146 100755 GIT binary patch delta 21678 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 delta 21027 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 2) { - spintext = argv[1]; - } + fd_set readfds; + FD_ZERO(&readfds); + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + char spintext[50]; // spinner int fb_w, fb_h; @@ -35,7 +36,7 @@ int main(int argc, char** argv) { NVGcontext *vg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES); assert(vg); - int font = nvgCreateFont(vg, "Bold", "../../assets/OpenSans-SemiBold.ttf"); + int font = nvgCreateFont(vg, "Bold", "../../assets/fonts/opensans_semibold.ttf"); assert(font >= 0); int spinner_img = nvgCreateImage(vg, "../../assets/img_spinner_track.png", 0); @@ -49,6 +50,11 @@ int main(int argc, char** argv) { assert(spinner_comma_img >= 0); for (int cnt = 0; ; cnt++) { + FD_SET(STDIN_FILENO, &readfds); + if (select(1, &readfds, NULL, NULL, &timeout)) { + fgets(spintext, sizeof spintext, stdin); + spintext[strcspn(spintext, "\n")] = 0; + } glClearColor(0.1, 0.1, 0.1, 1.0); glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); @@ -85,11 +91,9 @@ int main(int argc, char** argv) { nvgFill(vg); // message - if (spintext) { - nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_TOP); - nvgFontSize(vg, 96.0f); - nvgText(vg, fb_w/2, (fb_h*2/3)+24, spintext, NULL); - } + nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_TOP); + nvgFontSize(vg, 96.0f); + nvgText(vg, fb_w/2, (fb_h*2/3)+24, spintext, NULL); nvgEndFrame(vg); eglSwapBuffers(display, surface);