mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-06-22 06:22:06 +08:00
Merge branch 'devel-en' into devel-zhs
This commit is contained in:
Binary file not shown.
Binary file not shown.
+18
-14
@@ -4,6 +4,7 @@ import itertools
|
||||
import re
|
||||
import struct
|
||||
import subprocess
|
||||
import random
|
||||
|
||||
ANDROID = os.path.isfile('/EON')
|
||||
|
||||
@@ -17,9 +18,10 @@ def get_imei(slot):
|
||||
if slot not in ("0", "1"):
|
||||
raise ValueError("SIM slot must be 0 or 1")
|
||||
|
||||
ret = parse_service_call_string(["iphonesubinfo", "3" ,"i32", str(slot)])
|
||||
ret = parse_service_call_string(service_call(["iphonesubinfo", "3" ,"i32", str(slot)]))
|
||||
if not ret:
|
||||
ret = "000000000000000"
|
||||
# allow non android to be identified differently
|
||||
ret = "%015d" % random.randint(0, 1<<32)
|
||||
return ret
|
||||
|
||||
def get_serial():
|
||||
@@ -29,7 +31,7 @@ def get_serial():
|
||||
return ret
|
||||
|
||||
def get_subscriber_info():
|
||||
ret = parse_service_call_string(["iphonesubinfo", "7"])
|
||||
ret = parse_service_call_string(service_call(["iphonesubinfo", "7"]))
|
||||
if ret is None or len(ret) < 8:
|
||||
return ""
|
||||
return ret
|
||||
@@ -47,15 +49,23 @@ def reboot(reason=None):
|
||||
"i32", "1" # wait
|
||||
])
|
||||
|
||||
def parse_service_call_unpack(call, fmt):
|
||||
r = parse_service_call_bytes(call)
|
||||
def service_call(call):
|
||||
if not ANDROID:
|
||||
return None
|
||||
|
||||
ret = subprocess.check_output(["service", "call", *call], encoding='utf8').strip()
|
||||
if 'Parcel' not in ret:
|
||||
return None
|
||||
|
||||
return parse_service_call_bytes(ret)
|
||||
|
||||
def parse_service_call_unpack(r, fmt):
|
||||
try:
|
||||
return struct.unpack(fmt, r)[0]
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def parse_service_call_string(call):
|
||||
r = parse_service_call_bytes(call)
|
||||
def parse_service_call_string(r):
|
||||
try:
|
||||
r = r[8:] # Cut off length field
|
||||
r = r.decode('utf_16_be')
|
||||
@@ -71,13 +81,7 @@ def parse_service_call_string(call):
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def parse_service_call_bytes(call):
|
||||
if not ANDROID:
|
||||
return None
|
||||
ret = subprocess.check_output(["service", "call", *call], encoding='utf8').strip()
|
||||
if 'Parcel' not in ret:
|
||||
return None
|
||||
|
||||
def parse_service_call_bytes(ret):
|
||||
try:
|
||||
r = b""
|
||||
for hex_part in re.findall(r'[ (]([0-9a-f]{8})', ret):
|
||||
|
||||
@@ -32,6 +32,7 @@ def start_frame():
|
||||
|
||||
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")
|
||||
appops_set("ai.comma.plus.offroad", "SU", "allow")
|
||||
appops_set("ai.comma.plus.offroad", "WIFI_SCAN", "allow")
|
||||
appops_set("ai.comma.plus.offroad", "READ_EXTERNAL_STORAGE", "allow")
|
||||
|
||||
@@ -204,8 +204,8 @@ def getSimInfo():
|
||||
network_type = android.getprop("gsm.network.type").split(',')
|
||||
mcc_mnc = android.getprop("gsm.sim.operator.numeric") or None
|
||||
|
||||
sim_id = android.parse_service_call_string(['iphonesubinfo', '11'])
|
||||
cell_data_state = android.parse_service_call_unpack(['phone', '46'], ">q")
|
||||
sim_id = android.parse_service_call_string(android.service_call(['iphonesubinfo', '11']))
|
||||
cell_data_state = android.parse_service_call_unpack(android.service_call(['phone', '46']), ">q")
|
||||
cell_data_connected = (cell_data_state == 2)
|
||||
|
||||
return {
|
||||
|
||||
@@ -5,6 +5,7 @@ import cereal
|
||||
import cereal.messaging as messaging
|
||||
ThermalStatus = cereal.log.ThermalData.ThermalStatus
|
||||
from selfdrive.swaglog import cloudlog
|
||||
from common.realtime import sec_since_boot
|
||||
from common.params import Params, put_nonblocking
|
||||
params = Params()
|
||||
|
||||
@@ -13,8 +14,9 @@ class App():
|
||||
# app type
|
||||
TYPE_GPS = 0
|
||||
TYPE_SERVICE = 1
|
||||
TYPE_FULLSCREEN = 2
|
||||
TYPE_UTIL = 3
|
||||
TYPE_GPS_SERVICE = 2
|
||||
TYPE_FULLSCREEN = 3
|
||||
TYPE_UTIL = 4
|
||||
|
||||
# frame app
|
||||
FRAME = "ai.comma.plus.frame"
|
||||
@@ -70,33 +72,38 @@ class App():
|
||||
|
||||
self.set_package_permissions()
|
||||
self.system("pm disable %s" % self.app)
|
||||
self.last_ts = sec_since_boot()
|
||||
|
||||
def read_params(self):
|
||||
self.last_is_enabled = self.is_enabled
|
||||
if self.enable_param is None:
|
||||
self.is_enabled = False
|
||||
else:
|
||||
self.is_enabled = True if params.get(self.enable_param, encoding='utf8') == "1" else False
|
||||
|
||||
if self.is_enabled:
|
||||
# a service app should run automatically and not manual controllable.
|
||||
if self.app_type == App.TYPE_SERVICE:
|
||||
self.is_auto_runnable = True
|
||||
self.manual_ctrl_status = self.MANUAL_IDLE
|
||||
cur_time = sec_since_boot()
|
||||
if cur_time - self.last_ts > 5:
|
||||
self.last_is_enabled = self.is_enabled
|
||||
if self.enable_param is None:
|
||||
self.is_enabled = False
|
||||
else:
|
||||
if self.manual_ctrl_param is None:
|
||||
self.is_enabled = True if params.get(self.enable_param, encoding='utf8') == "1" else False
|
||||
|
||||
if self.is_enabled:
|
||||
# a service app should run automatically and not manual controllable.
|
||||
if self.app_type in [App.TYPE_SERVICE, App.TYPE_GPS_SERVICE]:
|
||||
self.is_auto_runnable = True
|
||||
self.manual_ctrl_status = self.MANUAL_IDLE
|
||||
else:
|
||||
self.manual_ctrl_status = params.get(self.manual_ctrl_param, encoding='utf8')
|
||||
if self.manual_ctrl_param is None:
|
||||
self.manual_ctrl_status = self.MANUAL_IDLE
|
||||
else:
|
||||
self.manual_ctrl_status = params.get(self.manual_ctrl_param, encoding='utf8')
|
||||
|
||||
if self.auto_run_param is None:
|
||||
self.is_auto_runnable = False
|
||||
else:
|
||||
self.is_auto_runnable = True if params.get(self.auto_run_param, encoding='utf8') == "1" else False
|
||||
else:
|
||||
self.is_auto_runnable = False
|
||||
self.manual_ctrl_status = self.MANUAL_IDLE
|
||||
self.manually_ctrled = False
|
||||
if self.auto_run_param is None:
|
||||
self.is_auto_runnable = False
|
||||
else:
|
||||
self.is_auto_runnable = True if params.get(self.auto_run_param, encoding='utf8') == "1" else False
|
||||
else:
|
||||
self.is_auto_runnable = False
|
||||
self.manual_ctrl_status = self.MANUAL_IDLE
|
||||
self.manually_ctrled = False
|
||||
|
||||
self.last_ts = cur_time
|
||||
|
||||
def run(self, force = False):
|
||||
if force or self.is_enabled:
|
||||
@@ -110,17 +117,19 @@ class App():
|
||||
if force or not self.is_running:
|
||||
# if it's a full screen app, we need to stop frame and offroad to get keyboard access
|
||||
if self.app_type == self.TYPE_FULLSCREEN:
|
||||
self.system("pkill %s" % self.FRAME)
|
||||
self.system("pm disable %s" % self.FRAME)
|
||||
self.system("am start -n %s/%s" % (self.OFFROAD, self.OFFROAD_MAIN))
|
||||
|
||||
self.system("pm enable %s" % self.app)
|
||||
|
||||
if self.app_type == self.TYPE_SERVICE:
|
||||
if self.app_type == self.TYPE_GPS_SERVICE:
|
||||
self.appops_set(self.app, "android:mock_location", "allow")
|
||||
|
||||
if self.app_type in [self.TYPE_SERVICE, self.TYPE_GPS_SERVICE]:
|
||||
self.system("am startservice %s/%s" % (self.app, self.activity))
|
||||
else:
|
||||
self.system("am start -n %s/%s" % (self.app, self.activity))
|
||||
|
||||
self.is_running = True
|
||||
self.is_running = True
|
||||
|
||||
def kill(self, force = False):
|
||||
if force or self.is_enabled:
|
||||
@@ -139,13 +148,14 @@ class App():
|
||||
self.system("pm enable %s" % self.FRAME)
|
||||
self.system("am start -n %s/%s" % (self.FRAME, self.FRAME_MAIN))
|
||||
|
||||
if self.app_type == self.TYPE_GPS_SERVICE:
|
||||
self.appops_set(self.app, "android:mock_location", "deny")
|
||||
|
||||
self.system("pkill %s" % self.app)
|
||||
self.is_running = False
|
||||
|
||||
def system(self, 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",
|
||||
@@ -227,7 +237,7 @@ def init_apps(apps):
|
||||
"DragonGreyPandaMode",
|
||||
None,
|
||||
None,
|
||||
App.TYPE_SERVICE,
|
||||
App.TYPE_GPS_SERVICE,
|
||||
[],
|
||||
[],
|
||||
))
|
||||
@@ -274,26 +284,40 @@ def main():
|
||||
last_thermal_status = None
|
||||
thermal_status = None
|
||||
|
||||
set_location_provider_allowed = False
|
||||
|
||||
while 1: #has_enabled_apps:
|
||||
has_fullscreen_apps = False
|
||||
has_gps_apps = False
|
||||
has_gps_service_apps = False
|
||||
|
||||
for app in apps:
|
||||
# read params loop
|
||||
app.read_params()
|
||||
if app.last_is_enabled and not app.is_enabled:
|
||||
if app.last_is_enabled and not app.is_enabled and app.is_running:
|
||||
app.kill(True)
|
||||
|
||||
if app.is_enabled:
|
||||
if app.app_type == App.TYPE_FULLSCREEN:
|
||||
if not has_fullscreen_apps and app.app_type == App.TYPE_FULLSCREEN:
|
||||
has_fullscreen_apps = True
|
||||
elif not has_gps_apps and app.app_type == App.TYPE_GPS:
|
||||
has_gps_apps = True
|
||||
elif not has_gps_service_apps and app.app_type == App.TYPE_GPS_SERVICE:
|
||||
has_gps_service_apps = True
|
||||
|
||||
# process manual ctrl apps
|
||||
for app in apps:
|
||||
if app.manual_ctrl_status != App.MANUAL_IDLE:
|
||||
if app.manual_ctrl_status == App.MANUAL_ON:
|
||||
app.run(True)
|
||||
else:
|
||||
app.kill(True)
|
||||
# process manual ctrl apps
|
||||
if app.manual_ctrl_status != App.MANUAL_IDLE:
|
||||
if app.manual_ctrl_status == App.MANUAL_ON:
|
||||
app.run(True)
|
||||
else:
|
||||
app.kill(True)
|
||||
|
||||
# set location provider accuracy
|
||||
if not set_location_provider_allowed and (has_gps_apps or has_gps_service_apps):
|
||||
system(f"settings put secure location_providers_allowed -gps")
|
||||
system(f"settings put secure location_providers_allowed -network")
|
||||
system(f"settings put secure location_providers_allowed +gps,network")
|
||||
set_location_provider_allowed = True
|
||||
|
||||
msg = messaging.recv_sock(thermal_sock, wait=True)
|
||||
started = msg.thermal.started
|
||||
@@ -320,7 +344,7 @@ def main():
|
||||
# only run once
|
||||
if last_started != started:
|
||||
for app in apps:
|
||||
if app.app_type == App.TYPE_SERVICE:
|
||||
if app.app_type in [App.TYPE_SERVICE, App.TYPE_GPS_SERVICE]:
|
||||
app.run()
|
||||
elif app.app_type == App.TYPE_UTIL:
|
||||
app.kill()
|
||||
|
||||
@@ -1,353 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import time
|
||||
import subprocess
|
||||
import cereal
|
||||
import cereal.messaging as messaging
|
||||
ThermalStatus = cereal.log.ThermalData.ThermalStatus
|
||||
from selfdrive.swaglog import cloudlog
|
||||
from common.params import Params, put_nonblocking
|
||||
params = Params()
|
||||
|
||||
class App():
|
||||
|
||||
# app type
|
||||
TYPE_GPS = 0
|
||||
TYPE_SERVICE = 1
|
||||
TYPE_FULLSCREEN = 2
|
||||
TYPE_UTIL = 3
|
||||
|
||||
# frame app
|
||||
FRAME = "ai.comma.plus.frame"
|
||||
FRAME_MAIN = ".MainActivity"
|
||||
|
||||
# offroad app
|
||||
OFFROAD = "ai.comma.plus.offroad"
|
||||
OFFROAD_MAIN = ".MainActivity"
|
||||
|
||||
# manual switch stats
|
||||
MANUAL_OFF = "-1"
|
||||
MANUAL_IDLE = "0"
|
||||
MANUAL_ON = "1"
|
||||
|
||||
def appops_set(self, package, op, mode):
|
||||
self.system(f"LD_LIBRARY_PATH= appops set {package} {op} {mode}")
|
||||
|
||||
def pm_grant(self, package, permission):
|
||||
self.system(f"pm grant {package} {permission}")
|
||||
|
||||
def set_package_permissions(self):
|
||||
if self.permissions is not None:
|
||||
for permission in self.permissions:
|
||||
self.pm_grant(self.app, permission)
|
||||
if self.opts is not None:
|
||||
for opt in self.opts:
|
||||
self.appops_set(self.app, opt, "allow")
|
||||
|
||||
def __init__(self, app, activity, enable_param, auto_run_param, manual_ctrl_param, app_type, permissions, opts):
|
||||
self.app = app
|
||||
# main activity
|
||||
self.activity = activity
|
||||
# read enable param
|
||||
self.enable_param = enable_param
|
||||
# read auto run param
|
||||
self.auto_run_param = auto_run_param
|
||||
# read manual run param
|
||||
self.manual_ctrl_param = manual_ctrl_param
|
||||
# if it's a service app, we do not kill if device is too hot
|
||||
# if it's a full screen app, we need to do extra process on frame/offroad
|
||||
self.app_type = app_type
|
||||
|
||||
self.permissions = permissions
|
||||
self.opts = opts
|
||||
|
||||
self.is_enabled = False
|
||||
self.last_is_enabled = False
|
||||
self.is_auto_runnable = False
|
||||
self.is_running = False
|
||||
self.manual_ctrl_status = self.MANUAL_IDLE
|
||||
self.manually_ctrled = False
|
||||
|
||||
self.set_package_permissions()
|
||||
self.system(f"pm disable %s" % self.app)
|
||||
|
||||
def read_params(self):
|
||||
self.last_is_enabled = self.is_enabled
|
||||
if self.enable_param is None:
|
||||
self.is_enabled = False
|
||||
else:
|
||||
self.is_enabled = True if params.get(self.enable_param, encoding='utf8') == "1" else False
|
||||
|
||||
if self.is_enabled:
|
||||
# a service app should run automatically and not manual controllable.
|
||||
if self.app_type == App.TYPE_SERVICE:
|
||||
self.is_auto_runnable = True
|
||||
self.manual_ctrl_status = self.MANUAL_IDLE
|
||||
else:
|
||||
if self.manual_ctrl_param is None:
|
||||
self.manual_ctrl_status = self.MANUAL_IDLE
|
||||
else:
|
||||
self.manual_ctrl_status = params.get(self.manual_ctrl_param, encoding='utf8')
|
||||
|
||||
if self.auto_run_param is None:
|
||||
self.is_auto_runnable = False
|
||||
else:
|
||||
self.is_auto_runnable = True if params.get(self.auto_run_param, encoding='utf8') == "1" else False
|
||||
else:
|
||||
self.is_auto_runnable = False
|
||||
self.manual_ctrl_status = self.MANUAL_IDLE
|
||||
self.manually_ctrled = False
|
||||
|
||||
def run(self):
|
||||
if self.is_enabled:
|
||||
# app is manually ctrl, we record that
|
||||
if self.manual_ctrl_param is not None and self.manual_ctrl_status == self.MANUAL_ON:
|
||||
put_nonblocking(self.manual_ctrl_param, '0')
|
||||
self.manually_ctrled = True
|
||||
self.is_running = False
|
||||
|
||||
# only run app if it's not running
|
||||
if not self.is_running:
|
||||
# if it's a full screen app, we need to stop frame and offroad to get keyboard access
|
||||
if self.app_type == self.TYPE_FULLSCREEN:
|
||||
self.system(f"pm disable %s" % self.FRAME)
|
||||
self.system(f"am start -n %s/%s" % (self.OFFROAD, self.OFFROAD_MAIN))
|
||||
|
||||
self.system(f"pm enable %s" % self.app)
|
||||
|
||||
if self.app_type == self.TYPE_SERVICE:
|
||||
self.system(f"am startservice %s/%s" % (self.app, self.activity))
|
||||
else:
|
||||
self.system(f"am start -n %s/%s" % (self.app, self.activity))
|
||||
|
||||
self.is_running = True
|
||||
|
||||
def kill(self):
|
||||
if self.is_enabled:
|
||||
# app is manually ctrl, we record that
|
||||
if self.manual_ctrl_param is not None and self.manual_ctrl_status == self.MANUAL_OFF:
|
||||
put_nonblocking(self.manual_ctrl_param, '0')
|
||||
self.manually_ctrled = True
|
||||
self.is_running = True
|
||||
|
||||
# only kill app if it's running
|
||||
if self.is_running:
|
||||
# if it's a full screen app, we need to restart offroad and frame
|
||||
if self.app_type == self.TYPE_FULLSCREEN:
|
||||
self.system(f"pm disable %s" % self.OFFROAD)
|
||||
self.system(f"pm enable %s" % self.OFFROAD)
|
||||
self.system(f"pm enable %s" % self.FRAME)
|
||||
self.system(f"am start -n %s/%s" % (self.FRAME, self.FRAME_MAIN))
|
||||
|
||||
self.system(f"pm disable %s" % self.app)
|
||||
self.is_running = False
|
||||
|
||||
def system(self, cmd):
|
||||
try:
|
||||
# cloudlog.info("running %s" % cmd)
|
||||
print(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)
|
||||
|
||||
def init_apps(apps):
|
||||
apps.append(App(
|
||||
# v1.16.2
|
||||
"com.tomtom.speedcams.android.map",
|
||||
"com.tomtom.speedcams.android.activities.SpeedCamActivity",
|
||||
"DragonEnableTomTom",
|
||||
"DragonBootTomTom",
|
||||
"DragonRunTomTom",
|
||||
App.TYPE_GPS,
|
||||
[
|
||||
"android.permission.ACCESS_FINE_LOCATION",
|
||||
"android.permission.ACCESS_COARSE_LOCATION",
|
||||
"android.permission.READ_EXTERNAL_STORAGE",
|
||||
"android.permission.WRITE_EXTERNAL_STORAGE",
|
||||
],
|
||||
[
|
||||
"SYSTEM_ALERT_WINDOW",
|
||||
]
|
||||
))
|
||||
apps.append(App(
|
||||
# v4.3.0.600310 R2098NSLAE
|
||||
"com.autonavi.amapauto",
|
||||
"com.autonavi.amapauto.MainMapActivity",
|
||||
"DragonEnableAutonavi",
|
||||
"DragonBootAutonavi",
|
||||
"DragonRunAutonavi",
|
||||
App.TYPE_GPS,
|
||||
[
|
||||
"android.permission.ACCESS_FINE_LOCATION",
|
||||
"android.permission.ACCESS_COARSE_LOCATION",
|
||||
"android.permission.READ_EXTERNAL_STORAGE",
|
||||
"android.permission.WRITE_EXTERNAL_STORAGE",
|
||||
],
|
||||
[
|
||||
"SYSTEM_ALERT_WINDOW",
|
||||
]
|
||||
))
|
||||
apps.append(App(
|
||||
# v6.40.3
|
||||
"com.mixplorer",
|
||||
"com.mixplorer.activities.BrowseActivity",
|
||||
"DragonEnableMixplorer",
|
||||
None,
|
||||
"DragonRunMixplorer",
|
||||
App.TYPE_UTIL,
|
||||
[
|
||||
"android.permission.READ_EXTERNAL_STORAGE",
|
||||
"android.permission.WRITE_EXTERNAL_STORAGE",
|
||||
],
|
||||
[],
|
||||
))
|
||||
apps.append(App(
|
||||
# v2.9.5 build 74
|
||||
"tw.com.ainvest.outpack",
|
||||
"tw.com.ainvest.outpack.ui.MainActivity",
|
||||
"DragonEnableAegis",
|
||||
"DragonBootAegis",
|
||||
"DragonRunAegis",
|
||||
App.TYPE_GPS,
|
||||
[
|
||||
"android.permission.ACCESS_FINE_LOCATION",
|
||||
"android.permission.READ_EXTERNAL_STORAGE",
|
||||
"android.permission.WRITE_EXTERNAL_STORAGE",
|
||||
],
|
||||
[
|
||||
"SYSTEM_ALERT_WINDOW",
|
||||
]
|
||||
))
|
||||
apps.append(App(
|
||||
"cn.dragonpilot.gpsservice",
|
||||
"cn.dragonpilot.gpsservice.MainService",
|
||||
"DragonGreyPandaMode",
|
||||
None,
|
||||
None,
|
||||
App.TYPE_SERVICE,
|
||||
[],
|
||||
[],
|
||||
))
|
||||
apps.append(App(
|
||||
# v4.57.2.0
|
||||
"com.waze",
|
||||
"com.waze.MainActivity",
|
||||
"DragonWazeMode",
|
||||
None,
|
||||
"DragonRunWaze",
|
||||
App.TYPE_FULLSCREEN,
|
||||
[
|
||||
"android.permission.ACCESS_FINE_LOCATION",
|
||||
"android.permission.ACCESS_COARSE_LOCATION",
|
||||
"android.permission.READ_EXTERNAL_STORAGE",
|
||||
"android.permission.WRITE_EXTERNAL_STORAGE",
|
||||
"android.permission.RECORD_AUDIO",
|
||||
],
|
||||
[],
|
||||
))
|
||||
|
||||
def main():
|
||||
# has_enabled_apps = False
|
||||
has_fullscreen_apps = False
|
||||
has_auto_run_apps = False
|
||||
apps = []
|
||||
|
||||
init_apps(apps)
|
||||
|
||||
last_started = False
|
||||
thermal_sock = messaging.sub_sock('thermal')
|
||||
allow_auto_run = True
|
||||
|
||||
frame = 0
|
||||
start_delay = None
|
||||
stop_delay = None
|
||||
|
||||
|
||||
while 1: #has_enabled_apps:
|
||||
msg = messaging.recv_sock(thermal_sock, wait=True)
|
||||
started = msg.thermal.started
|
||||
|
||||
for app in apps:
|
||||
# read params loop
|
||||
app.read_params()
|
||||
if app.is_enabled:
|
||||
if app.app_type == App.TYPE_FULLSCREEN:
|
||||
has_fullscreen_apps = True
|
||||
if app.is_auto_runnable:
|
||||
has_auto_run_apps = True
|
||||
if app.manual_ctrl_status != App.MANUAL_IDLE:
|
||||
if app.manual_ctrl_status == App.MANUAL_ON:
|
||||
app.run()
|
||||
else:
|
||||
app.kill()
|
||||
|
||||
# when car is running
|
||||
if started:
|
||||
stop_delay = None
|
||||
if start_delay is None:
|
||||
start_delay = frame + 5
|
||||
|
||||
# start service and fullscreen apps and kill the reset
|
||||
if has_fullscreen_apps:
|
||||
for app in apps:
|
||||
if not app.manually_ctrled and app.app_type in [App.TYPE_SERVICE, App.TYPE_FULLSCREEN]:
|
||||
app.run()
|
||||
else:
|
||||
app.kill()
|
||||
else:
|
||||
# kill any util apps
|
||||
for app in apps:
|
||||
if app.app_type == App.TYPE_UTIL:
|
||||
app.kill()
|
||||
|
||||
# auto run ctrl for normal apps
|
||||
if has_auto_run_apps:
|
||||
thermal_status = msg.thermal.thermalStatus
|
||||
if not allow_auto_run and thermal_status <= ThermalStatus.yellow:
|
||||
allow_auto_run = True
|
||||
|
||||
if allow_auto_run and thermal_status >= ThermalStatus.red:
|
||||
allow_auto_run = False
|
||||
|
||||
if frame > start_delay:
|
||||
for app in apps:
|
||||
if app.is_auto_runnable and not app.manually_ctrled:
|
||||
if allow_auto_run:
|
||||
if not app.is_running and app.app_type not in [App.TYPE_FULLSCREEN, App.TYPE_UTIL]:
|
||||
app.run()
|
||||
else:
|
||||
if app.is_running and app.app_type not in [App.TYPE_SERVICE]:
|
||||
app.kill()
|
||||
|
||||
# when car is stopped
|
||||
else:
|
||||
start_delay = None
|
||||
# set delay to 30 seconds
|
||||
if stop_delay is None:
|
||||
stop_delay = frame + 30
|
||||
|
||||
# when car is off, we want to kill full screen app first
|
||||
if has_fullscreen_apps:
|
||||
for app in apps:
|
||||
if not app.manually_ctrled and app.is_running:
|
||||
app.kill()
|
||||
else:
|
||||
# kill rest of the apps after delay
|
||||
if frame > stop_delay:
|
||||
for app in apps:
|
||||
if not app.manually_ctrled and app.is_running:
|
||||
app.kill()
|
||||
|
||||
if last_started != started:
|
||||
for app in apps:
|
||||
app.manually_ctrled = False
|
||||
|
||||
last_started = started
|
||||
frame += 3
|
||||
time.sleep(3)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -67,11 +67,13 @@ def clear_locks(root):
|
||||
def is_on_wifi():
|
||||
# ConnectivityManager.getActiveNetworkInfo()
|
||||
try:
|
||||
result = android.parse_service_call_string(["connectivity", "2"])
|
||||
# TODO: figure out why the android service call sometimes dies with SIGUSR2 (signal from MSGQ)
|
||||
result = android.parse_service_call_string(android.service_call(["connectivity", "2"]))
|
||||
if result is None:
|
||||
return True
|
||||
return 'WIFI' in result
|
||||
except AttributeError:
|
||||
except (AttributeError, subprocess.CalledProcessError):
|
||||
cloudlog.exception("is_on_wifi failed")
|
||||
return False
|
||||
|
||||
def is_on_hotspot():
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ def update_panda():
|
||||
serial = None
|
||||
|
||||
panda_version = "bootstub" if panda.bootstub else panda.get_version()
|
||||
panda_signature = "bootstub" if panda.bootstub else panda.get_signature()
|
||||
panda_signature = b"" if panda.bootstub else panda.get_signature()
|
||||
cloudlog.warning("Panda %s connected, version: %s, signature %s, expected %s" % (
|
||||
serial,
|
||||
panda_version,
|
||||
|
||||
+68
-67
@@ -790,78 +790,75 @@ static void ui_draw_infobar(UIState *s) {
|
||||
int ui_viz_rx = scene->ui_viz_rx;
|
||||
bool hasSidebar = !s->scene.uilayout_sidebarcollapsed;
|
||||
// rect_w = screen_width - sidebar width
|
||||
int rect_w = vwp_w - (hasSidebar? sbr_w : 0);
|
||||
if (s->dragon_driving_ui) {
|
||||
// if driving ui is enabled, rect_w = rect_w - vision start x - small boarder
|
||||
rect_w = rect_w - ui_viz_rx - bdr_s;
|
||||
}
|
||||
|
||||
int rect_w = vwp_w - ui_viz_rx - bdr_s;
|
||||
int rect_h = 80;
|
||||
// rect_x = 0 + sidebar width
|
||||
int rect_x = 0;
|
||||
if (s->dragon_driving_ui) {
|
||||
// if driving ui is enabled, rect_x = rect_x + vision start x
|
||||
rect_x = rect_x + (hasSidebar? sbr_w : 0) + ui_viz_rx;
|
||||
}
|
||||
|
||||
// if driving ui is enabled, rect_x = rect_x + vision start x
|
||||
int rect_x = (hasSidebar? (bdr_s+sbr_w) : ui_viz_rx);
|
||||
|
||||
// rect_y = screen height - board - background height
|
||||
int rect_y = vwp_h - bdr_s - rect_h;
|
||||
|
||||
// int text_width;
|
||||
int text_x = rect_w / 2;
|
||||
if (s->dragon_driving_ui) {
|
||||
text_x = text_x + (hasSidebar? sbr_w : 0) + ui_viz_rx;
|
||||
}
|
||||
int text_x = rect_w / 2 + ui_viz_rx;
|
||||
int text_y = rect_y + 55;
|
||||
|
||||
// Get local time to display
|
||||
char infobar[68];
|
||||
time_t t = time(NULL);
|
||||
struct tm tm = *localtime(&t);
|
||||
char infobar[100];
|
||||
// create time string
|
||||
char date_time[17];
|
||||
time_t rawtime = time(NULL);
|
||||
struct tm timeinfo;
|
||||
localtime_r(&rawtime, &timeinfo);
|
||||
strftime(date_time, sizeof(date_time),"%D %T", &timeinfo);
|
||||
|
||||
// Create temp string
|
||||
char temp[6];
|
||||
snprintf(temp, sizeof(temp), "%02.0f°C", s->scene.pa0);
|
||||
|
||||
// create battery percentage string
|
||||
char battery[4];
|
||||
snprintf(battery, sizeof(battery), "%02d%%", s->scene.batteryPercent);
|
||||
|
||||
if (s->dragon_ui_dev_mini) {
|
||||
char rel_steer[9];
|
||||
snprintf(rel_steer, sizeof(rel_steer), "%s%05.1f°", s->scene.angleSteers < 0? "-" : "+", fabs(s->scene.angleSteers));
|
||||
char rel_steer[9];
|
||||
snprintf(rel_steer, sizeof(rel_steer), "%s%05.1f°", s->scene.angleSteers < 0? "-" : "+", fabs(s->scene.angleSteers));
|
||||
|
||||
char des_steer[9];
|
||||
if (s->scene.engaged) {
|
||||
snprintf(des_steer, sizeof(des_steer), "%s%05.1f°", s->scene.angleSteersDes < 0? "-" : "+", fabs(s->scene.angleSteersDes));
|
||||
} else {
|
||||
snprintf(des_steer, sizeof(des_steer), "%7s", "N/A");
|
||||
}
|
||||
char des_steer[9];
|
||||
if (s->scene.engaged) {
|
||||
snprintf(des_steer, sizeof(des_steer), "%s%05.1f°", s->scene.angleSteersDes < 0? "-" : "+", fabs(s->scene.angleSteersDes));
|
||||
} else {
|
||||
snprintf(des_steer, sizeof(des_steer), "%7s", "-");
|
||||
}
|
||||
|
||||
char lead_dist[8];
|
||||
if (s->scene.lead_status) {
|
||||
snprintf(lead_dist, sizeof(lead_dist), "%06.2fm", s->scene.lead_d_rel);
|
||||
} else {
|
||||
snprintf(lead_dist, sizeof(lead_dist), "%7s", "-");
|
||||
}
|
||||
|
||||
char lead_dist[8];
|
||||
if (s->scene.lead_status) {
|
||||
snprintf(lead_dist, sizeof(lead_dist), "%06.2fm", s->scene.lead_d_rel);
|
||||
} else {
|
||||
snprintf(lead_dist, sizeof(lead_dist), "%7s", "N/A");
|
||||
}
|
||||
|
||||
snprintf(
|
||||
infobar,
|
||||
sizeof(infobar),
|
||||
"%04d/%02d/%02d %02d:%02d:%02d | REL: %s | DES: %s | DIST: %s",
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec,
|
||||
rel_steer,
|
||||
des_steer,
|
||||
lead_dist
|
||||
);
|
||||
snprintf(
|
||||
infobar,
|
||||
sizeof(infobar),
|
||||
"%s /TMP: %s /BAT: %s /REL: %s /DES: %s /DIS: %s",
|
||||
date_time,
|
||||
temp,
|
||||
battery,
|
||||
rel_steer,
|
||||
des_steer,
|
||||
lead_dist
|
||||
);
|
||||
} else {
|
||||
snprintf(
|
||||
infobar,
|
||||
sizeof(infobar),
|
||||
"%04d/%02d/%02d %02d:%02d:%02d",
|
||||
tm.tm_year + 1900,
|
||||
tm.tm_mon + 1,
|
||||
tm.tm_mday,
|
||||
tm.tm_hour,
|
||||
tm.tm_min,
|
||||
tm.tm_sec
|
||||
);
|
||||
snprintf(
|
||||
infobar,
|
||||
sizeof(infobar),
|
||||
"%s /TMP: %s /BAT: %s",
|
||||
date_time,
|
||||
temp,
|
||||
battery
|
||||
);
|
||||
}
|
||||
|
||||
nvgBeginPath(s->vg);
|
||||
@@ -869,7 +866,7 @@ static void ui_draw_infobar(UIState *s) {
|
||||
nvgFillColor(s->vg, nvgRGBA(0, 0, 0, 180));
|
||||
nvgFill(s->vg);
|
||||
|
||||
nvgFontSize(s->vg, hasSidebar? 40:50);
|
||||
nvgFontSize(s->vg, hasSidebar? 35:42);
|
||||
nvgFontFace(s->vg, "courbd");
|
||||
nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 180));
|
||||
nvgTextAlign(s->vg, NVG_ALIGN_CENTER);
|
||||
@@ -1096,7 +1093,7 @@ static void ui_draw_vision_footer(UIState *s) {
|
||||
if (s->dragon_ui_dev) {
|
||||
ui_draw_bbui(s);
|
||||
}
|
||||
if (s->dragon_ui_dev_mini || s->dragon_enable_dashcam) {
|
||||
if (s->dragon_ui_dev_mini || s->dragon_enable_dashcam || s->dragon_waze_mode) {
|
||||
ui_draw_infobar(s);
|
||||
}
|
||||
}
|
||||
@@ -1170,7 +1167,9 @@ static void ui_draw_vision(UIState *s) {
|
||||
glScissor(ui_viz_rx, s->fb_h-(box_y+box_h), ui_viz_rw, box_h);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
draw_frame(s);
|
||||
if (s->dragon_driving_ui) {
|
||||
draw_frame(s);
|
||||
}
|
||||
glViewport(0, 0, s->fb_w, s->fb_h);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
@@ -1180,12 +1179,14 @@ static void ui_draw_vision(UIState *s) {
|
||||
nvgSave(s->vg);
|
||||
|
||||
// Draw augmented elements
|
||||
const int inner_height = viz_w*9/16;
|
||||
nvgScissor(s->vg, ui_viz_rx, box_y, ui_viz_rw, box_h);
|
||||
nvgTranslate(s->vg, ui_viz_rx+ui_viz_ro, box_y + (box_h-inner_height)/2.0);
|
||||
nvgScale(s->vg, (float)viz_w / s->fb_w, (float)inner_height / s->fb_h);
|
||||
if (!scene->frontview && !scene->fullview) {
|
||||
ui_draw_world(s);
|
||||
if (s->dragon_driving_ui) {
|
||||
const int inner_height = viz_w*9/16;
|
||||
nvgScissor(s->vg, ui_viz_rx, box_y, ui_viz_rw, box_h);
|
||||
nvgTranslate(s->vg, ui_viz_rx+ui_viz_ro, box_y + (box_h-inner_height)/2.0);
|
||||
nvgScale(s->vg, (float)viz_w / s->fb_w, (float)inner_height / s->fb_h);
|
||||
if (!scene->frontview && !scene->fullview) {
|
||||
ui_draw_world(s);
|
||||
}
|
||||
}
|
||||
|
||||
nvgRestore(s->vg);
|
||||
|
||||
+10
-1
@@ -113,6 +113,7 @@ static void ui_init(UIState *s) {
|
||||
s->livecalibration_sock = SubSocket::create(s->ctx, "liveCalibration");
|
||||
s->radarstate_sock = SubSocket::create(s->ctx, "radarState");
|
||||
s->carstate_sock = SubSocket::create(s->ctx, "carState");
|
||||
s->thermal_sock = SubSocket::create(s->ctx, "thermal");
|
||||
|
||||
assert(s->model_sock != NULL);
|
||||
assert(s->controlsstate_sock != NULL);
|
||||
@@ -120,6 +121,7 @@ static void ui_init(UIState *s) {
|
||||
assert(s->livecalibration_sock != NULL);
|
||||
assert(s->radarstate_sock != NULL);
|
||||
assert(s->carstate_sock != NULL);
|
||||
assert(s->thermal_sock != NULL);
|
||||
|
||||
s->poller = Poller::create({
|
||||
s->model_sock,
|
||||
@@ -127,7 +129,8 @@ static void ui_init(UIState *s) {
|
||||
s->uilayout_sock,
|
||||
s->livecalibration_sock,
|
||||
s->radarstate_sock,
|
||||
s->carstate_sock
|
||||
s->carstate_sock,
|
||||
s->thermal_sock
|
||||
});
|
||||
|
||||
#ifdef SHOW_SPEEDLIMIT
|
||||
@@ -481,6 +484,12 @@ void handle_message(UIState *s, Message * msg) {
|
||||
}
|
||||
s->scene.leftBlinker = datad.leftBlinker;
|
||||
s->scene.rightBlinker = datad.rightBlinker;
|
||||
} else if (eventd.which == cereal_Event_thermal) {
|
||||
struct cereal_ThermalData datad;
|
||||
cereal_read_ThermalData(&datad, eventd.thermal);
|
||||
|
||||
s->scene.batteryPercent = datad.batteryPercent;
|
||||
s->scene.pa0 = datad.pa0;
|
||||
}
|
||||
capn_free(&ctx);
|
||||
}
|
||||
|
||||
@@ -122,6 +122,8 @@ typedef struct UIScene {
|
||||
// for minimal UI
|
||||
float angleSteersDes;
|
||||
float angleSteers;
|
||||
float pa0;
|
||||
int batteryPercent;
|
||||
|
||||
// for blinker, from kegman
|
||||
bool leftBlinker;
|
||||
@@ -255,6 +257,7 @@ typedef struct UIState {
|
||||
|
||||
// dragonpilot
|
||||
SubSocket *carstate_sock;
|
||||
SubSocket *thermal_sock;
|
||||
int dragon_ui_speed_timeout;
|
||||
int dragon_ui_event_timeout;
|
||||
int dragon_ui_maxspeed_timeout;
|
||||
|
||||
Reference in New Issue
Block a user