APK purge (#20446)
* purge begins
* release files
* remove those
* no more android
* only qt
* text and spinner
* neos update script
* update sounds
* update cpu usage
* all done
Co-authored-by: Comma Device <device@comma.ai>
old-commit-hash: e76c80ffa1
commatwo_master
parent
5fc14c8db3
commit
51c13aa552
30 changed files with 92 additions and 1069 deletions
@ -1,3 +0,0 @@ |
|||||||
version https://git-lfs.github.com/spec/v1 |
|
||||||
oid sha256:34f8beca20214315be942f67aa3a6f2743174430da06b15706fbca610a9150b5 |
|
||||||
size 13715186 |
|
@ -1,105 +0,0 @@ |
|||||||
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(): |
|
||||||
try: |
|
||||||
output = subprocess.check_output(['dumpsys', 'package', 'ai.comma.plus.offroad'], encoding="utf-8") |
|
||||||
given_permissions = output.split("runtime permissions")[1] |
|
||||||
except Exception: |
|
||||||
given_permissions = "" |
|
||||||
|
|
||||||
wanted_permissions = ["ACCESS_FINE_LOCATION", "READ_PHONE_STATE", "READ_EXTERNAL_STORAGE"] |
|
||||||
for permission in wanted_permissions: |
|
||||||
if permission not in given_permissions: |
|
||||||
pm_grant("ai.comma.plus.offroad", "android.permission."+permission) |
|
||||||
|
|
||||||
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() |
|
@ -0,0 +1,4 @@ |
|||||||
|
#!/usr/bin/bash |
||||||
|
|
||||||
|
ROOT=$PWD/../../.. |
||||||
|
$ROOT/installer/updater/updater "file://$ROOT/installer/updater/update.json" |
@ -1,125 +0,0 @@ |
|||||||
#include <math.h> |
|
||||||
#include <stdlib.h> |
|
||||||
#include <atomic> |
|
||||||
#include "common/swaglog.h" |
|
||||||
#include "common/timing.h" |
|
||||||
|
|
||||||
#include "android/sl_sound.hpp" |
|
||||||
|
|
||||||
#define LogOnError(func, msg) \ |
|
||||||
if ((func) != SL_RESULT_SUCCESS) { LOGW(msg); } |
|
||||||
|
|
||||||
#define ReturnOnError(func, msg) \ |
|
||||||
if ((func) != SL_RESULT_SUCCESS) { LOGW(msg); return false; } |
|
||||||
|
|
||||||
struct SLSound::Player { |
|
||||||
SLObjectItf player; |
|
||||||
SLPlayItf playItf; |
|
||||||
std::atomic<int> repeat; |
|
||||||
}; |
|
||||||
|
|
||||||
SLSound::SLSound() { |
|
||||||
if (!init()){ |
|
||||||
throw std::runtime_error("Failed to initialize sound"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool SLSound::init() { |
|
||||||
SLEngineOption engineOptions[] = {{SL_ENGINEOPTION_THREADSAFE, SL_BOOLEAN_TRUE}}; |
|
||||||
const SLInterfaceID ids[1] = {SL_IID_VOLUME}; |
|
||||||
const SLboolean req[1] = {SL_BOOLEAN_FALSE}; |
|
||||||
SLEngineItf engineInterface = NULL; |
|
||||||
ReturnOnError(slCreateEngine(&engine_, 1, engineOptions, 0, NULL, NULL), "Failed to create OpenSL engine"); |
|
||||||
ReturnOnError((*engine_)->Realize(engine_, SL_BOOLEAN_FALSE), "Failed to realize OpenSL engine"); |
|
||||||
ReturnOnError((*engine_)->GetInterface(engine_, SL_IID_ENGINE, &engineInterface), "Failed to get OpenSL engine interface"); |
|
||||||
ReturnOnError((*engineInterface)->CreateOutputMix(engineInterface, &outputMix_, 1, ids, req), "Failed to create output mix"); |
|
||||||
ReturnOnError((*outputMix_)->Realize(outputMix_, SL_BOOLEAN_FALSE), "Failed to realize output mix"); |
|
||||||
|
|
||||||
for (auto &kv : sound_map) { |
|
||||||
SLDataLocator_URI locUri = {SL_DATALOCATOR_URI, (SLchar *)kv.second.first}; |
|
||||||
SLDataFormat_MIME formatMime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED}; |
|
||||||
SLDataSource audioSrc = {&locUri, &formatMime}; |
|
||||||
SLDataLocator_OutputMix outMix = {SL_DATALOCATOR_OUTPUTMIX, outputMix_}; |
|
||||||
SLDataSink audioSnk = {&outMix, NULL}; |
|
||||||
|
|
||||||
SLObjectItf player = NULL; |
|
||||||
SLPlayItf playItf = NULL; |
|
||||||
ReturnOnError((*engineInterface)->CreateAudioPlayer(engineInterface, &player, &audioSrc, &audioSnk, 0, NULL, NULL), "Failed to create audio player"); |
|
||||||
ReturnOnError((*player)->Realize(player, SL_BOOLEAN_FALSE), "Failed to realize audio player"); |
|
||||||
ReturnOnError((*player)->GetInterface(player, SL_IID_PLAY, &playItf), "Failed to get player interface"); |
|
||||||
ReturnOnError((*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PAUSED), "Failed to initialize playstate to SL_PLAYSTATE_PAUSED"); |
|
||||||
|
|
||||||
player_[kv.first] = new SLSound::Player{player, playItf}; |
|
||||||
} |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
void SLAPIENTRY slplay_callback(SLPlayItf playItf, void *context, SLuint32 event) { |
|
||||||
SLSound::Player *s = reinterpret_cast<SLSound::Player *>(context); |
|
||||||
if (event == SL_PLAYEVENT_HEADATEND && s->repeat != 0) { |
|
||||||
if (s->repeat > 0) --s->repeat; |
|
||||||
(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED); |
|
||||||
(*playItf)->SetMarkerPosition(playItf, 0); |
|
||||||
(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bool SLSound::play(AudibleAlert alert) { |
|
||||||
if (currentSound_ != AudibleAlert::NONE) { |
|
||||||
stop(); |
|
||||||
} |
|
||||||
|
|
||||||
auto player = player_.at(alert); |
|
||||||
SLPlayItf playItf = player->playItf; |
|
||||||
|
|
||||||
int loops = sound_map[alert].second; |
|
||||||
player->repeat = loops > 0 ? loops - 1 : loops; |
|
||||||
if (player->repeat != 0) { |
|
||||||
ReturnOnError((*playItf)->RegisterCallback(playItf, slplay_callback, player), "Failed to register callback"); |
|
||||||
ReturnOnError((*playItf)->SetCallbackEventsMask(playItf, SL_PLAYEVENT_HEADATEND), "Failed to set callback event mask"); |
|
||||||
} |
|
||||||
|
|
||||||
// Reset the audio player
|
|
||||||
ReturnOnError((*playItf)->ClearMarkerPosition(playItf), "Failed to clear marker position"); |
|
||||||
uint32_t states[] = {SL_PLAYSTATE_PAUSED, SL_PLAYSTATE_STOPPED, SL_PLAYSTATE_PLAYING}; |
|
||||||
for (auto state : states) { |
|
||||||
ReturnOnError((*playItf)->SetPlayState(playItf, state), "Failed to set SL_PLAYSTATE_PLAYING"); |
|
||||||
} |
|
||||||
currentSound_ = alert; |
|
||||||
return true; |
|
||||||
} |
|
||||||
|
|
||||||
void SLSound::stop() { |
|
||||||
if (currentSound_ != AudibleAlert::NONE) { |
|
||||||
auto player = player_.at(currentSound_); |
|
||||||
player->repeat = 0; |
|
||||||
LogOnError((*(player->playItf))->SetPlayState(player->playItf, SL_PLAYSTATE_PAUSED), "Failed to set SL_PLAYSTATE_PAUSED"); |
|
||||||
currentSound_ = AudibleAlert::NONE; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void SLSound::setVolume(int volume) { |
|
||||||
if (last_volume_ == volume) return; |
|
||||||
|
|
||||||
double current_time = nanos_since_boot(); |
|
||||||
if ((current_time - last_set_volume_time_) > (5 * (1e+9))) { // 5s timeout on updating the volume
|
|
||||||
char volume_change_cmd[64]; |
|
||||||
snprintf(volume_change_cmd, sizeof(volume_change_cmd), "service call audio 3 i32 3 i32 %d i32 1 &", volume); |
|
||||||
system(volume_change_cmd); |
|
||||||
last_volume_ = volume; |
|
||||||
last_set_volume_time_ = current_time; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
SLSound::~SLSound() { |
|
||||||
for (auto &kv : player_) { |
|
||||||
(*(kv.second->player))->Destroy(kv.second->player); |
|
||||||
delete kv.second; |
|
||||||
} |
|
||||||
if (outputMix_) { |
|
||||||
(*outputMix_)->Destroy(outputMix_); |
|
||||||
} |
|
||||||
if (engine_) { |
|
||||||
(*engine_)->Destroy(engine_); |
|
||||||
} |
|
||||||
} |
|
@ -1,26 +0,0 @@ |
|||||||
#pragma once |
|
||||||
#include <SLES/OpenSLES.h> |
|
||||||
#include <SLES/OpenSLES_Android.h> |
|
||||||
|
|
||||||
#include "sound.hpp" |
|
||||||
|
|
||||||
|
|
||||||
class SLSound : public Sound { |
|
||||||
public: |
|
||||||
SLSound(); |
|
||||||
~SLSound(); |
|
||||||
bool play(AudibleAlert alert); |
|
||||||
void stop(); |
|
||||||
void setVolume(int volume); |
|
||||||
|
|
||||||
private: |
|
||||||
bool init(); |
|
||||||
SLObjectItf engine_ = nullptr; |
|
||||||
SLObjectItf outputMix_ = nullptr; |
|
||||||
int last_volume_ = 0; |
|
||||||
double last_set_volume_time_ = 0.; |
|
||||||
AudibleAlert currentSound_ = AudibleAlert::NONE; |
|
||||||
struct Player; |
|
||||||
std::map<AudibleAlert, Player *> player_; |
|
||||||
friend void SLAPIENTRY slplay_callback(SLPlayItf playItf, void *context, SLuint32 event); |
|
||||||
}; |
|
@ -1,77 +0,0 @@ |
|||||||
CC = clang
|
|
||||||
CXX = clang++
|
|
||||||
|
|
||||||
ROOT_DIR = ../../..
|
|
||||||
PHONELIBS = $(ROOT_DIR)/phonelibs
|
|
||||||
COMMON = $(ROOT)/selfdrive/common
|
|
||||||
|
|
||||||
WARN_FLAGS = -Werror=implicit-function-declaration \
|
|
||||||
-Werror=incompatible-pointer-types \
|
|
||||||
-Werror=int-conversion \
|
|
||||||
-Werror=return-type \
|
|
||||||
-Werror=format-extra-args
|
|
||||||
|
|
||||||
CFLAGS = -std=gnu11 -fPIC -O2 $(WARN_FLAGS)
|
|
||||||
CXXFLAGS = -std=c++1z -fPIC -O2 $(WARN_FLAGS)
|
|
||||||
|
|
||||||
NANOVG_FLAGS = -I$(PHONELIBS)/nanovg
|
|
||||||
|
|
||||||
OPENGL_LIBS = -lGLESv3
|
|
||||||
|
|
||||||
FRAMEBUFFER_LIBS = -lutils -lgui -lEGL
|
|
||||||
|
|
||||||
OBJS = spinner.o \
|
|
||||||
$(COMMON)/framebuffer.o \
|
|
||||||
$(COMMON)/util.o \
|
|
||||||
$(PHONELIBS)/nanovg/nanovg.o \
|
|
||||||
$(COMMON)/spinner.o \
|
|
||||||
opensans_semibold.o \
|
|
||||||
img_spinner_track.o \
|
|
||||||
img_spinner_comma.o
|
|
||||||
|
|
||||||
DEPS := $(OBJS:.o=.d)
|
|
||||||
|
|
||||||
.PHONY: all |
|
||||||
all: spinner |
|
||||||
|
|
||||||
spinner: $(OBJS) |
|
||||||
@echo "[ LINK ] $@"
|
|
||||||
$(CXX) -fPIC -o '$@' $^ \
|
|
||||||
-s \
|
|
||||||
$(FRAMEBUFFER_LIBS) \
|
|
||||||
-L/system/vendor/lib64 \
|
|
||||||
$(OPENGL_LIBS) \
|
|
||||||
-lm -llog
|
|
||||||
|
|
||||||
$(COMMON)/framebuffer.o: $(COMMON)/framebuffer.cc |
|
||||||
@echo "[ CXX ] $@"
|
|
||||||
$(CXX) $(CXXFLAGS) -MMD \
|
|
||||||
-I$(PHONELIBS)/android_frameworks_native/include \
|
|
||||||
-I$(PHONELIBS)/android_system_core/include \
|
|
||||||
-I$(PHONELIBS)/android_hardware_libhardware/include \
|
|
||||||
-c -o '$@' '$<'
|
|
||||||
|
|
||||||
opensans_semibold.o: $(ROOT_DIR)/selfdrive/assets/fonts/opensans_semibold.ttf |
|
||||||
@echo "[ bin2o ] $@"
|
|
||||||
cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)'
|
|
||||||
|
|
||||||
img_spinner_track.o: $(ROOT_DIR)/selfdrive/assets/img_spinner_track.png |
|
||||||
@echo "[ bin2o ] $@"
|
|
||||||
cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)'
|
|
||||||
|
|
||||||
img_spinner_comma.o: $(ROOT_DIR)/selfdrive/assets/img_spinner_comma.png |
|
||||||
@echo "[ bin2o ] $@"
|
|
||||||
cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)'
|
|
||||||
|
|
||||||
%.o: %.c |
|
||||||
@echo "[ CC ] $@"
|
|
||||||
$(CC) $(CFLAGS) -MMD \
|
|
||||||
-I../.. \
|
|
||||||
$(NANOVG_FLAGS) \
|
|
||||||
-c -o '$@' '$<'
|
|
||||||
|
|
||||||
.PHONY: clean |
|
||||||
clean: |
|
||||||
rm -f spinner $(OBJS) $(DEPS)
|
|
||||||
|
|
||||||
-include $(DEPS) |
|
@ -1,3 +0,0 @@ |
|||||||
version https://git-lfs.github.com/spec/v1 |
|
||||||
oid sha256:faaf9aa68d97142708c474a0221f1cd2db020c79d6385bac7749586918db3c99 |
|
||||||
size 551136 |
|
@ -1,182 +0,0 @@ |
|||||||
#include <stdio.h> |
|
||||||
#include <stdlib.h> |
|
||||||
#include <stdbool.h> |
|
||||||
#include <math.h> |
|
||||||
#include <unistd.h> |
|
||||||
#include <assert.h> |
|
||||||
#include <ctype.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 "framebuffer.h" |
|
||||||
#include "spinner.h" |
|
||||||
|
|
||||||
#define SPINTEXT_LENGTH 128 |
|
||||||
|
|
||||||
// external resources linked in
|
|
||||||
extern const unsigned char _binary_opensans_semibold_ttf_start[]; |
|
||||||
extern const unsigned char _binary_opensans_semibold_ttf_end[]; |
|
||||||
|
|
||||||
extern const unsigned char _binary_img_spinner_track_png_start[]; |
|
||||||
extern const unsigned char _binary_img_spinner_track_png_end[]; |
|
||||||
|
|
||||||
extern const unsigned char _binary_img_spinner_comma_png_start[]; |
|
||||||
extern const unsigned char _binary_img_spinner_comma_png_end[]; |
|
||||||
|
|
||||||
bool stdin_input_available() { |
|
||||||
struct timeval timeout; |
|
||||||
timeout.tv_sec = 0; |
|
||||||
timeout.tv_usec = 0; |
|
||||||
|
|
||||||
fd_set fds; |
|
||||||
FD_ZERO(&fds); |
|
||||||
FD_SET(STDIN_FILENO, &fds); |
|
||||||
select(STDIN_FILENO+1, &fds, NULL, NULL, &timeout); |
|
||||||
return (FD_ISSET(0, &fds)); |
|
||||||
} |
|
||||||
|
|
||||||
int main(int argc, char** argv) { |
|
||||||
|
|
||||||
bool draw_progress = false; |
|
||||||
float progress_val = 0.0; |
|
||||||
|
|
||||||
char spintext[SPINTEXT_LENGTH]; |
|
||||||
spintext[0] = 0; |
|
||||||
|
|
||||||
const char* spintext_arg = NULL; |
|
||||||
if (argc >= 2) { |
|
||||||
strncpy(spintext, argv[1], SPINTEXT_LENGTH); |
|
||||||
} |
|
||||||
|
|
||||||
// spinner
|
|
||||||
int fb_w, fb_h; |
|
||||||
FramebufferState *fb = framebuffer_init("spinner", 0x00001000, false, |
|
||||||
&fb_w, &fb_h); |
|
||||||
assert(fb); |
|
||||||
framebuffer_set_power(fb, HWC_POWER_MODE_NORMAL); |
|
||||||
|
|
||||||
NVGcontext *vg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES); |
|
||||||
assert(vg); |
|
||||||
|
|
||||||
int font = nvgCreateFontMem(vg, "Bold", (unsigned char*)_binary_opensans_semibold_ttf_start, _binary_opensans_semibold_ttf_end-_binary_opensans_semibold_ttf_start, 0); |
|
||||||
assert(font >= 0); |
|
||||||
|
|
||||||
int spinner_img = nvgCreateImageMem(vg, 0, (unsigned char*)_binary_img_spinner_track_png_start, _binary_img_spinner_track_png_end - _binary_img_spinner_track_png_start); |
|
||||||
assert(spinner_img >= 0); |
|
||||||
int spinner_img_s = 360; |
|
||||||
int spinner_img_x = ((fb_w/2)-(spinner_img_s/2)); |
|
||||||
int spinner_img_y = 260; |
|
||||||
int spinner_img_xc = (fb_w/2); |
|
||||||
int spinner_img_yc = (fb_h/2)-100; |
|
||||||
int spinner_comma_img = nvgCreateImageMem(vg, 0, (unsigned char*)_binary_img_spinner_comma_png_start, _binary_img_spinner_comma_png_end - _binary_img_spinner_comma_png_start); |
|
||||||
assert(spinner_comma_img >= 0); |
|
||||||
|
|
||||||
for (int cnt = 0; ; cnt++) { |
|
||||||
// Check stdin for new text
|
|
||||||
if (stdin_input_available()){ |
|
||||||
fgets(spintext, SPINTEXT_LENGTH, stdin); |
|
||||||
spintext[strcspn(spintext, "\n")] = 0; |
|
||||||
|
|
||||||
// Check if number (update progress bar)
|
|
||||||
size_t len = strlen(spintext); |
|
||||||
bool is_number = len > 0; |
|
||||||
for (int i = 0; i < len; i++){ |
|
||||||
if (!isdigit(spintext[i])){ |
|
||||||
is_number = false; |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if (is_number) { |
|
||||||
progress_val = (float)(atoi(spintext)) / 100.0; |
|
||||||
progress_val = fmin(1.0, progress_val); |
|
||||||
progress_val = fmax(0.0, progress_val); |
|
||||||
} |
|
||||||
|
|
||||||
draw_progress = is_number; |
|
||||||
} |
|
||||||
|
|
||||||
glClearColor(0.1, 0.1, 0.1, 1.0); |
|
||||||
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); |
|
||||||
glEnable(GL_BLEND); |
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
|
||||||
nvgBeginFrame(vg, fb_w, fb_h, 1.0f); |
|
||||||
|
|
||||||
// background
|
|
||||||
nvgBeginPath(vg); |
|
||||||
NVGpaint bg = nvgLinearGradient(vg, fb_w, 0, fb_w, fb_h, |
|
||||||
nvgRGBA(0, 0, 0, 175), nvgRGBA(0, 0, 0, 255)); |
|
||||||
nvgFillPaint(vg, bg); |
|
||||||
nvgRect(vg, 0, 0, fb_w, fb_h); |
|
||||||
nvgFill(vg); |
|
||||||
|
|
||||||
// spin track
|
|
||||||
nvgSave(vg); |
|
||||||
nvgTranslate(vg, spinner_img_xc, spinner_img_yc); |
|
||||||
nvgRotate(vg, (3.75*M_PI * cnt/120.0)); |
|
||||||
nvgTranslate(vg, -spinner_img_xc, -spinner_img_yc); |
|
||||||
NVGpaint spinner_imgPaint = nvgImagePattern(vg, spinner_img_x, spinner_img_y, |
|
||||||
spinner_img_s, spinner_img_s, 0, spinner_img, 0.6f); |
|
||||||
nvgBeginPath(vg); |
|
||||||
nvgFillPaint(vg, spinner_imgPaint); |
|
||||||
nvgRect(vg, spinner_img_x, spinner_img_y, spinner_img_s, spinner_img_s); |
|
||||||
nvgFill(vg); |
|
||||||
nvgRestore(vg); |
|
||||||
|
|
||||||
// comma
|
|
||||||
NVGpaint comma_imgPaint = nvgImagePattern(vg, spinner_img_x, spinner_img_y, |
|
||||||
spinner_img_s, spinner_img_s, 0, spinner_comma_img, 1.0f); |
|
||||||
nvgBeginPath(vg); |
|
||||||
nvgFillPaint(vg, comma_imgPaint); |
|
||||||
nvgRect(vg, spinner_img_x, spinner_img_y, spinner_img_s, spinner_img_s); |
|
||||||
nvgFill(vg); |
|
||||||
|
|
||||||
if (draw_progress){ |
|
||||||
// draw progress bar
|
|
||||||
int progress_width = 1000; |
|
||||||
int progress_x = fb_w/2-progress_width/2; |
|
||||||
int progress_y = 775; |
|
||||||
int progress_height = 25; |
|
||||||
|
|
||||||
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); |
|
||||||
|
|
||||||
int bar_pos = ((progress_width - 2) * progress_val); |
|
||||||
|
|
||||||
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); |
|
||||||
} else { |
|
||||||
// message
|
|
||||||
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); |
|
||||||
framebuffer_swap(fb); |
|
||||||
assert(glGetError() == GL_NO_ERROR); |
|
||||||
} |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
@ -1,64 +0,0 @@ |
|||||||
CC = clang
|
|
||||||
CXX = clang++
|
|
||||||
|
|
||||||
PHONELIBS = ../../../../phonelibs
|
|
||||||
COMMON = ../../../common
|
|
||||||
|
|
||||||
WARN_FLAGS = -Werror=implicit-function-declaration \
|
|
||||||
-Werror=incompatible-pointer-types \
|
|
||||||
-Werror=int-conversion \
|
|
||||||
-Werror=return-type \
|
|
||||||
-Werror=format-extra-args
|
|
||||||
|
|
||||||
CFLAGS = -std=gnu11 -fPIC -O2 $(WARN_FLAGS)
|
|
||||||
CXXFLAGS = -std=c++1z -fPIC -O2 $(WARN_FLAGS)
|
|
||||||
|
|
||||||
NANOVG_FLAGS = -I$(PHONELIBS)/nanovg
|
|
||||||
|
|
||||||
OPENGL_LIBS = -lGLESv3
|
|
||||||
|
|
||||||
FRAMEBUFFER_LIBS = -lutils -lgui -lEGL
|
|
||||||
|
|
||||||
OBJS = text.o \
|
|
||||||
$(COMMON)/framebuffer.o \
|
|
||||||
$(COMMON)/util.o \
|
|
||||||
$(COMMON)/touch.o \
|
|
||||||
$(PHONELIBS)/nanovg/nanovg.o \
|
|
||||||
opensans_regular.o \
|
|
||||||
|
|
||||||
DEPS := $(OBJS:.o=.d)
|
|
||||||
|
|
||||||
.PHONY: all |
|
||||||
all: text |
|
||||||
|
|
||||||
text: $(OBJS) |
|
||||||
@echo "[ LINK ] $@"
|
|
||||||
$(CXX) -fPIC -o '$@' $^ \
|
|
||||||
-s \
|
|
||||||
$(FRAMEBUFFER_LIBS) \
|
|
||||||
-L/system/vendor/lib64 \
|
|
||||||
$(OPENGL_LIBS) \
|
|
||||||
-lm -llog
|
|
||||||
|
|
||||||
opensans_regular.o: ../../../assets/fonts/opensans_regular.ttf |
|
||||||
@echo "[ bin2o ] $@"
|
|
||||||
cd '$(dir $<)' && ld -r -b binary '$(notdir $<)' -o '$(abspath $@)'
|
|
||||||
|
|
||||||
%.o: %.cc |
|
||||||
mkdir -p $(@D)
|
|
||||||
@echo "[ CXX ] $@"
|
|
||||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) \
|
|
||||||
-I../../../selfdrive \
|
|
||||||
-I../../../ \
|
|
||||||
-I$(PHONELIBS)/android_frameworks_native/include \
|
|
||||||
-I$(PHONELIBS)/android_system_core/include \
|
|
||||||
-I$(PHONELIBS)/android_hardware_libhardware/include \
|
|
||||||
$(NANOVG_FLAGS) \
|
|
||||||
-c -o '$@' '$<'
|
|
||||||
|
|
||||||
|
|
||||||
.PHONY: clean |
|
||||||
clean: |
|
||||||
rm -f text $(OBJS) $(DEPS)
|
|
||||||
|
|
||||||
-include $(DEPS) |
|
@ -1,3 +0,0 @@ |
|||||||
version https://git-lfs.github.com/spec/v1 |
|
||||||
oid sha256:be30fb76fbf9a21853c5357757e126210254f46b758ec2fd7438c24604d2bd70 |
|
||||||
size 494112 |
|
@ -1,133 +0,0 @@ |
|||||||
#include <stdio.h> |
|
||||||
#include <stdlib.h> |
|
||||||
#include <stdbool.h> |
|
||||||
#include <math.h> |
|
||||||
#include <unistd.h> |
|
||||||
#include <assert.h> |
|
||||||
#include <memory> |
|
||||||
#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 "common/framebuffer.h" |
|
||||||
#include "common/touch.h" |
|
||||||
|
|
||||||
|
|
||||||
#define COLOR_WHITE nvgRGBA(255, 255, 255, 255) |
|
||||||
#define MAX_TEXT_SIZE 2048 |
|
||||||
|
|
||||||
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"); |
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv) { |
|
||||||
int err; |
|
||||||
|
|
||||||
// spinner
|
|
||||||
int fb_w, fb_h; |
|
||||||
std::unique_ptr<FrameBuffer> fb = std::make_unique<FrameBuffer>("text", 0x00001000, false, |
|
||||||
&fb_w, &fb_h); |
|
||||||
assert(fb); |
|
||||||
|
|
||||||
NVGcontext *vg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES); |
|
||||||
assert(vg); |
|
||||||
|
|
||||||
int font = nvgCreateFontMem(vg, "regular", (unsigned char*)bin_opensans_regular, (bin_opensans_regular_end - bin_opensans_regular), 0); |
|
||||||
assert(font >= 0); |
|
||||||
|
|
||||||
// Awake
|
|
||||||
fb->set_power(HWC_POWER_MODE_NORMAL); |
|
||||||
set_brightness(255); |
|
||||||
|
|
||||||
glClearColor(0.1, 0.1, 0.1, 1.0); |
|
||||||
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); |
|
||||||
glEnable(GL_BLEND); |
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
|
||||||
nvgBeginFrame(vg, fb_w, fb_h, 1.0f); |
|
||||||
|
|
||||||
// background
|
|
||||||
nvgBeginPath(vg); |
|
||||||
NVGpaint bg = nvgLinearGradient(vg, fb_w, 0, fb_w, fb_h, |
|
||||||
nvgRGBA(0, 0, 0, 175), nvgRGBA(0, 0, 0, 255)); |
|
||||||
nvgFillPaint(vg, bg); |
|
||||||
nvgRect(vg, 0, 0, fb_w, fb_h); |
|
||||||
nvgFill(vg); |
|
||||||
|
|
||||||
|
|
||||||
// Text
|
|
||||||
nvgFillColor(vg, COLOR_WHITE); |
|
||||||
nvgFontSize(vg, 75.0f); |
|
||||||
|
|
||||||
if (argc >= 2) { |
|
||||||
float x = 150; |
|
||||||
float y = 150; |
|
||||||
|
|
||||||
// Copy text
|
|
||||||
char * text = (char *)malloc(MAX_TEXT_SIZE); |
|
||||||
strncpy(text, argv[1], MAX_TEXT_SIZE); |
|
||||||
|
|
||||||
float lineh; |
|
||||||
nvgTextMetrics(vg, NULL, NULL, &lineh); |
|
||||||
|
|
||||||
// nvgTextBox strips leading whitespace. We have to reimplement
|
|
||||||
char * next = strtok(text, "\n"); |
|
||||||
while (next != NULL){ |
|
||||||
nvgText(vg, x, y, next, NULL); |
|
||||||
y += lineh; |
|
||||||
next = strtok(NULL, "\n"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// Button
|
|
||||||
int b_x = 1500; |
|
||||||
int b_y = 800; |
|
||||||
int b_w = 300; |
|
||||||
int b_h = 150; |
|
||||||
|
|
||||||
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)); |
|
||||||
nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE); |
|
||||||
nvgText(vg, b_x+b_w/2, b_y+b_h/2, "Exit", 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 to screen
|
|
||||||
nvgEndFrame(vg); |
|
||||||
fb->swap(); |
|
||||||
assert(glGetError() == GL_NO_ERROR); |
|
||||||
|
|
||||||
|
|
||||||
// Wait for button
|
|
||||||
TouchState touch; |
|
||||||
touch_init(&touch); |
|
||||||
|
|
||||||
while (true){ |
|
||||||
int touch_x = -1, touch_y = -1; |
|
||||||
int res = touch_poll(&touch, &touch_x, &touch_y, 0); |
|
||||||
if (res){ |
|
||||||
|
|
||||||
if (touch_x > b_x && touch_x < b_x + b_w){ |
|
||||||
if (touch_y > b_y && touch_y < b_y + b_h){ |
|
||||||
return 1; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
usleep(1000000 / 60); |
|
||||||
} |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
@ -1,191 +0,0 @@ |
|||||||
#include <stdio.h> |
|
||||||
#include <stdlib.h> |
|
||||||
#include <math.h> |
|
||||||
#include <sys/resource.h> |
|
||||||
|
|
||||||
#include <algorithm> |
|
||||||
|
|
||||||
#include "common/framebuffer.h" |
|
||||||
#include "common/util.h" |
|
||||||
#include "common/params.h" |
|
||||||
#include "common/swaglog.h" |
|
||||||
#include "common/touch.h" |
|
||||||
#include "common/watchdog.h" |
|
||||||
|
|
||||||
#include "ui.hpp" |
|
||||||
#include "paint.hpp" |
|
||||||
#include "android/sl_sound.hpp" |
|
||||||
|
|
||||||
ExitHandler do_exit; |
|
||||||
static void ui_set_brightness(UIState *s, int brightness) { |
|
||||||
static int last_brightness = -1; |
|
||||||
if (last_brightness != brightness && (s->awake || brightness == 0)) { |
|
||||||
if (set_brightness(brightness)) { |
|
||||||
last_brightness = brightness; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void handle_display_state(UIState *s, FrameBuffer *fb, bool user_input) { |
|
||||||
static int awake_timeout = 0; |
|
||||||
|
|
||||||
constexpr float accel_samples = 5*UI_FREQ; |
|
||||||
static float accel_prev = 0., gyro_prev = 0.; |
|
||||||
|
|
||||||
bool should_wake = s->scene.started || s->scene.ignition || user_input; |
|
||||||
if (!should_wake) { |
|
||||||
// tap detection while display is off
|
|
||||||
bool accel_trigger = abs(s->scene.accel_sensor - accel_prev) > 0.2; |
|
||||||
bool gyro_trigger = abs(s->scene.gyro_sensor - gyro_prev) > 0.15; |
|
||||||
should_wake = accel_trigger && gyro_trigger; |
|
||||||
gyro_prev = s->scene.gyro_sensor; |
|
||||||
accel_prev = (accel_prev * (accel_samples - 1) + s->scene.accel_sensor) / accel_samples; |
|
||||||
} |
|
||||||
|
|
||||||
// determine desired state
|
|
||||||
if (should_wake) { |
|
||||||
awake_timeout = 30*UI_FREQ; |
|
||||||
} else if (awake_timeout > 0){ |
|
||||||
--awake_timeout; |
|
||||||
should_wake = true; |
|
||||||
} |
|
||||||
|
|
||||||
// handle state transition
|
|
||||||
if (s->awake != should_wake) { |
|
||||||
s->awake = should_wake; |
|
||||||
int display_mode = s->awake ? HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF; |
|
||||||
LOGW("setting display mode %d", display_mode); |
|
||||||
fb->set_power(display_mode); |
|
||||||
|
|
||||||
if (s->awake) { |
|
||||||
system("service call window 18 i32 1"); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void handle_vision_touch(UIState *s, int touch_x, int touch_y) { |
|
||||||
if (s->scene.started && (touch_x >= s->viz_rect.x - bdr_s) |
|
||||||
&& (s->active_app != cereal::UiLayoutState::App::SETTINGS)) { |
|
||||||
if (!s->scene.driver_view) { |
|
||||||
s->sidebar_collapsed = !s->sidebar_collapsed; |
|
||||||
} else { |
|
||||||
Params().write_db_value("IsDriverViewEnabled", "0", 1); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void handle_sidebar_touch(UIState *s, int touch_x, int touch_y) { |
|
||||||
if (!s->sidebar_collapsed && touch_x <= sbr_w) { |
|
||||||
if (settings_btn.ptInRect(touch_x, touch_y)) { |
|
||||||
s->active_app = cereal::UiLayoutState::App::SETTINGS; |
|
||||||
} else if (home_btn.ptInRect(touch_x, touch_y)) { |
|
||||||
if (s->scene.started) { |
|
||||||
s->active_app = cereal::UiLayoutState::App::NONE; |
|
||||||
s->sidebar_collapsed = true; |
|
||||||
} else { |
|
||||||
s->active_app = cereal::UiLayoutState::App::HOME; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void update_offroad_layout_state(UIState *s, PubMaster *pm) { |
|
||||||
static int timeout = 0; |
|
||||||
static bool prev_collapsed = false; |
|
||||||
static cereal::UiLayoutState::App prev_app = cereal::UiLayoutState::App::NONE; |
|
||||||
if (timeout > 0) { |
|
||||||
timeout--; |
|
||||||
} |
|
||||||
if (prev_collapsed != s->sidebar_collapsed || prev_app != s->active_app || timeout == 0) { |
|
||||||
MessageBuilder msg; |
|
||||||
auto layout = msg.initEvent().initUiLayoutState(); |
|
||||||
layout.setActiveApp(s->active_app); |
|
||||||
layout.setSidebarCollapsed(s->sidebar_collapsed); |
|
||||||
pm->send("offroadLayout", msg); |
|
||||||
LOGD("setting active app to %d with sidebar %d", (int)s->active_app, s->sidebar_collapsed); |
|
||||||
prev_collapsed = s->sidebar_collapsed; |
|
||||||
prev_app = s->active_app; |
|
||||||
timeout = 2 * UI_FREQ; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
int main(int argc, char* argv[]) { |
|
||||||
setpriority(PRIO_PROCESS, 0, -14); |
|
||||||
|
|
||||||
SLSound sound; |
|
||||||
UIState uistate = {}; |
|
||||||
UIState *s = &uistate; |
|
||||||
FrameBuffer fb = FrameBuffer("ui", 0, true, &s->fb_w, &s->fb_h); |
|
||||||
|
|
||||||
ui_init(s); |
|
||||||
s->sound = &sound; |
|
||||||
|
|
||||||
TouchState touch = {0}; |
|
||||||
touch_init(&touch); |
|
||||||
handle_display_state(s, &fb, true); |
|
||||||
|
|
||||||
PubMaster *pm = new PubMaster({"offroadLayout"}); |
|
||||||
|
|
||||||
// light sensor scaling and volume params
|
|
||||||
float brightness_b = 0, brightness_m = 0; |
|
||||||
int result = read_param(&brightness_b, "BRIGHTNESS_B", true); |
|
||||||
result += read_param(&brightness_m, "BRIGHTNESS_M", true); |
|
||||||
if (result != 0) { |
|
||||||
brightness_b = 10.0; |
|
||||||
brightness_m = 2.6; |
|
||||||
write_param_float(brightness_b, "BRIGHTNESS_B", true); |
|
||||||
write_param_float(brightness_m, "BRIGHTNESS_M", true); |
|
||||||
} |
|
||||||
float smooth_brightness = brightness_b; |
|
||||||
|
|
||||||
const int MIN_VOLUME = 12; |
|
||||||
const int MAX_VOLUME = 15; |
|
||||||
s->sound->setVolume(MIN_VOLUME); |
|
||||||
|
|
||||||
while (!do_exit) { |
|
||||||
watchdog_kick(); |
|
||||||
if (!s->scene.started) { |
|
||||||
util::sleep_for(50); |
|
||||||
} |
|
||||||
double u1 = millis_since_boot(); |
|
||||||
|
|
||||||
ui_update(s); |
|
||||||
|
|
||||||
// poll for touch events
|
|
||||||
int touch_x = -1, touch_y = -1; |
|
||||||
int touched = touch_poll(&touch, &touch_x, &touch_y, 0); |
|
||||||
if (touched == 1) { |
|
||||||
handle_sidebar_touch(s, touch_x, touch_y); |
|
||||||
handle_vision_touch(s, touch_x, touch_y); |
|
||||||
} |
|
||||||
|
|
||||||
// Don't waste resources on drawing in case screen is off
|
|
||||||
handle_display_state(s, &fb, touched == 1); |
|
||||||
if (!s->awake) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
// up one notch every 5 m/s
|
|
||||||
s->sound->setVolume(fmin(MAX_VOLUME, MIN_VOLUME + s->scene.car_state.getVEgo() / 5)); |
|
||||||
|
|
||||||
// set brightness
|
|
||||||
float clipped_brightness = fmin(512, (s->scene.light_sensor*brightness_m) + brightness_b); |
|
||||||
smooth_brightness = fmin(255, clipped_brightness * 0.01 + smooth_brightness * 0.99); |
|
||||||
ui_set_brightness(s, (int)smooth_brightness); |
|
||||||
|
|
||||||
update_offroad_layout_state(s, pm); |
|
||||||
|
|
||||||
ui_draw(s); |
|
||||||
double u2 = millis_since_boot(); |
|
||||||
if (!s->scene.driver_view && (u2-u1 > 66)) { |
|
||||||
// warn on sub 15fps
|
|
||||||
LOGW("slow frame(%llu) time: %.2f", (s->sm)->frame, u2-u1); |
|
||||||
} |
|
||||||
fb.swap(); |
|
||||||
} |
|
||||||
|
|
||||||
handle_display_state(s, &fb, true); |
|
||||||
delete s->sm; |
|
||||||
delete pm; |
|
||||||
return 0; |
|
||||||
} |
|
@ -1,3 +1,3 @@ |
|||||||
version https://git-lfs.github.com/spec/v1 |
version https://git-lfs.github.com/spec/v1 |
||||||
oid sha256:c6edce17d54bf9762133e71fdddb5eb112eb182bef5d49c668e478c988aaf572 |
oid sha256:2bf424d78e157f284cd63f0f8cbd394fee929954fef069c27b09d55ef5ca5233 |
||||||
size 439744 |
size 603472 |
||||||
|
@ -0,0 +1,3 @@ |
|||||||
|
version https://git-lfs.github.com/spec/v1 |
||||||
|
oid sha256:c6edce17d54bf9762133e71fdddb5eb112eb182bef5d49c668e478c988aaf572 |
||||||
|
size 439744 |
@ -1,3 +1,3 @@ |
|||||||
version https://git-lfs.github.com/spec/v1 |
version https://git-lfs.github.com/spec/v1 |
||||||
oid sha256:9ade107da94609e36256abf30fc45a6c8ad76804fb0f099f8d3d792e61bc118c |
oid sha256:cbd82920a8d9a995d3596406cefb59476c4352012b639515902f93835d659960 |
||||||
size 217160 |
size 302968 |
||||||
|
@ -0,0 +1,3 @@ |
|||||||
|
version https://git-lfs.github.com/spec/v1 |
||||||
|
oid sha256:9ade107da94609e36256abf30fc45a6c8ad76804fb0f099f8d3d792e61bc118c |
||||||
|
size 217160 |
@ -1,12 +1,10 @@ |
|||||||
#!/bin/sh |
#!/bin/sh |
||||||
|
|
||||||
if [ -f /EON ]; then |
if [ -f /EON ] && [ ! -f qt/spinner ]; then |
||||||
export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH" |
|
||||||
exec ./android/spinner/spinner "$1" |
|
||||||
else |
|
||||||
if [ -f /TICI ] && [ ! -f qt/spinner ]; then |
|
||||||
cp qt/spinner_aarch64 qt/spinner |
cp qt/spinner_aarch64 qt/spinner |
||||||
fi |
elif [ -f /TICI ] && [ ! -f qt/spinner ]; then |
||||||
|
cp qt/spinner_larch64 qt/spinner |
||||||
exec ./qt/spinner "$1" |
|
||||||
fi |
fi |
||||||
|
|
||||||
|
export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH" |
||||||
|
exec ./qt/spinner "$1" |
||||||
|
@ -1,12 +1,10 @@ |
|||||||
#!/bin/sh |
#!/bin/sh |
||||||
|
|
||||||
if [ -f /EON ]; then |
if [ -f /EON ] && [ ! -f qt/text ]; then |
||||||
export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH" |
|
||||||
exec ./android/text/text "$1" |
|
||||||
else |
|
||||||
if [ -f /TICI ] && [ ! -f qt/text ]; then |
|
||||||
cp qt/text_aarch64 qt/text |
cp qt/text_aarch64 qt/text |
||||||
fi |
elif [ -f /TICI ] && [ ! -f qt/text ]; then |
||||||
|
cp qt/text_larch64 qt/text |
||||||
exec ./qt/text "$1" |
|
||||||
fi |
fi |
||||||
|
|
||||||
|
export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH" |
||||||
|
exec ./qt/text "$1" |
||||||
|
Loading…
Reference in new issue