mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
Rename PackageManager to AppManager
This commit is contained in:
@@ -4,7 +4,7 @@ from .app.activity import Activity
|
||||
from .content.intent import Intent
|
||||
from .activity_navigator import ActivityNavigator
|
||||
|
||||
from .content.package_manager import PackageManager
|
||||
from .content.app_manager import AppManager
|
||||
from .config import SharedPreferences
|
||||
from .net.connectivity_manager import ConnectivityManager
|
||||
from .net.wifi_service import WifiService
|
||||
@@ -65,7 +65,7 @@ __all__ = [
|
||||
"Activity",
|
||||
"SharedPreferences",
|
||||
"ConnectivityManager", "DownloadManager", "WifiService", "AudioFlinger", "Intent",
|
||||
"ActivityNavigator", "PackageManager", "TaskManager", "CameraManager",
|
||||
"ActivityNavigator", "AppManager", "TaskManager", "CameraManager",
|
||||
# Device and build info
|
||||
"DeviceInfo", "BuildInfo",
|
||||
# Common activities
|
||||
|
||||
@@ -2,7 +2,7 @@ import sys
|
||||
import utime
|
||||
|
||||
from .content.intent import Intent
|
||||
from .content.package_manager import PackageManager
|
||||
from .content.app_manager import AppManager
|
||||
|
||||
import mpos.ui
|
||||
|
||||
@@ -13,7 +13,7 @@ class ActivityNavigator:
|
||||
if not isinstance(intent, Intent):
|
||||
raise ValueError("Must provide an Intent")
|
||||
if intent.action: # Implicit intent: resolve handlers
|
||||
handlers = PackageManager.resolve_activity(intent)
|
||||
handlers = AppManager.resolve_activity(intent)
|
||||
if not handlers:
|
||||
print("No handler for action:", intent.action)
|
||||
return
|
||||
@@ -31,7 +31,7 @@ class ActivityNavigator:
|
||||
if not isinstance(intent, Intent):
|
||||
raise ValueError("Must provide an Intent")
|
||||
if intent.action: # Implicit intent: resolve handlers
|
||||
handlers = PackageManager.resolve_activity(intent)
|
||||
handlers = AppManager.resolve_activity(intent)
|
||||
if not handlers:
|
||||
print("No handler for action:", intent.action)
|
||||
return
|
||||
|
||||
@@ -2,7 +2,7 @@ from ..activity import Activity
|
||||
# Chooser doesn't handle an action — it shows handlers
|
||||
# → No registration needed
|
||||
|
||||
from ...content.package_manager import PackageManager
|
||||
from ...content.app_manager import AppManager
|
||||
|
||||
class ChooserActivity(Activity):
|
||||
def __init__(self):
|
||||
@@ -27,7 +27,7 @@ class ChooserActivity(Activity):
|
||||
self.setContentView(screen)
|
||||
|
||||
def _select_handler(self, handler_name, original_intent):
|
||||
for handler in PackageManager.APP_REGISTRY.get(original_intent.action, []):
|
||||
for handler in AppManager.APP_REGISTRY.get(original_intent.action, []):
|
||||
if handler.__name__ == handler_name:
|
||||
original_intent.activity_class = handler
|
||||
navigator.startActivity(original_intent)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from ..activity import Activity
|
||||
from ...content.package_manager import PackageManager
|
||||
from ...content.app_manager import AppManager
|
||||
|
||||
class ShareActivity(Activity):
|
||||
def __init__(self):
|
||||
@@ -35,4 +35,4 @@ class ShareActivity(Activity):
|
||||
else:
|
||||
print("Stopped for other screen")
|
||||
|
||||
PackageManager.register_activity("share", ShareActivity)
|
||||
AppManager.register_activity("share", ShareActivity)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from ..activity import Activity
|
||||
from ...content.package_manager import PackageManager
|
||||
from ...content.app_manager import AppManager
|
||||
|
||||
class ViewActivity(Activity):
|
||||
def __init__(self):
|
||||
@@ -28,4 +28,4 @@ class ViewActivity(Activity):
|
||||
print("Stopped for other screen")
|
||||
|
||||
# Register this activity for "view" intents
|
||||
PackageManager.register_activity("view", ViewActivity)
|
||||
AppManager.register_activity("view", ViewActivity)
|
||||
|
||||
+18
-19
@@ -28,7 +28,7 @@ Question: does it make sense to cache the database?
|
||||
|
||||
'''
|
||||
|
||||
class PackageManager:
|
||||
class AppManager:
|
||||
|
||||
_registry = {} # action → [ActivityClass, ...]
|
||||
|
||||
@@ -52,9 +52,9 @@ class PackageManager:
|
||||
|
||||
"""Registry of all discovered apps.
|
||||
|
||||
* PackageManager.get_app_list() -> list of App objects (sorted by name)
|
||||
* PackageManager[fullname] -> App (raises KeyError if missing)
|
||||
* PackageManager.get(fullname) -> App or None
|
||||
* AppManager.get_app_list() -> list of App objects (sorted by name)
|
||||
* AppManager[fullname] -> App (raises KeyError if missing)
|
||||
* AppManager.get(fullname) -> App or None
|
||||
"""
|
||||
|
||||
_app_list = [] # sorted by app.name
|
||||
@@ -93,7 +93,7 @@ class PackageManager:
|
||||
|
||||
@classmethod
|
||||
def refresh_apps(cls):
|
||||
print("PackageManager finding apps...")
|
||||
print("AppManager finding apps...")
|
||||
|
||||
cls.clear() # <-- this guarantees both containers are empty
|
||||
seen = set() # avoid processing the same fullname twice
|
||||
@@ -117,7 +117,7 @@ class PackageManager:
|
||||
if not (st[0] & 0x4000):
|
||||
continue
|
||||
except Exception as e:
|
||||
print("PackageManager: stat of {} got exception: {}".format(full_path, e))
|
||||
print("AppManager: stat of {} got exception: {}".format(full_path, e))
|
||||
continue
|
||||
|
||||
fullname = name
|
||||
@@ -132,7 +132,7 @@ class PackageManager:
|
||||
from ..app.app import App
|
||||
app = App.from_manifest(full_path)
|
||||
except Exception as e:
|
||||
print("PackageManager: parsing {} failed: {}".format(full_path, e))
|
||||
print("AppManager: parsing {} failed: {}".format(full_path, e))
|
||||
continue
|
||||
|
||||
# ---- store in both containers ---------------------------
|
||||
@@ -141,7 +141,7 @@ class PackageManager:
|
||||
print("added app {}".format(app))
|
||||
|
||||
except Exception as e:
|
||||
print("PackageManager: handling {} got exception: {}".format(base, e))
|
||||
print("AppManager: handling {} got exception: {}".format(base, e))
|
||||
|
||||
# ---- sort the list by display name (case-insensitive) ------------
|
||||
cls._app_list.sort(key=lambda a: a.name.lower())
|
||||
@@ -153,7 +153,7 @@ class PackageManager:
|
||||
shutil.rmtree(f"apps/{app_fullname}") # never in builtin/apps because those can't be uninstalled
|
||||
except Exception as e:
|
||||
print(f"Removing app_folder {app_folder} got error: {e}")
|
||||
PackageManager.refresh_apps()
|
||||
AppManager.refresh_apps()
|
||||
|
||||
@staticmethod
|
||||
def install_mpk(temp_zip_path, dest_folder):
|
||||
@@ -169,7 +169,7 @@ class PackageManager:
|
||||
except Exception as e:
|
||||
print(f"Unzip and cleanup failed: {e}")
|
||||
# Would be good to show error message here if it fails...
|
||||
PackageManager.refresh_apps()
|
||||
AppManager.refresh_apps()
|
||||
|
||||
@staticmethod
|
||||
def compare_versions(ver1: str, ver2: str) -> bool:
|
||||
@@ -200,20 +200,20 @@ class PackageManager:
|
||||
|
||||
@staticmethod
|
||||
def is_builtin_app(app_fullname):
|
||||
return PackageManager.is_installed_by_path(f"builtin/apps/{app_fullname}")
|
||||
return AppManager.is_installed_by_path(f"builtin/apps/{app_fullname}")
|
||||
|
||||
@staticmethod
|
||||
def is_overridden_builtin_app(app_fullname):
|
||||
return PackageManager.is_installed_by_path(f"apps/{app_fullname}") and PackageManager.is_installed_by_path(f"builtin/apps/{app_fullname}")
|
||||
return AppManager.is_installed_by_path(f"apps/{app_fullname}") and AppManager.is_installed_by_path(f"builtin/apps/{app_fullname}")
|
||||
|
||||
@staticmethod
|
||||
def is_update_available(app_fullname, new_version):
|
||||
appdir = f"apps/{app_fullname}"
|
||||
builtinappdir = f"builtin/apps/{app_fullname}"
|
||||
installed_app=PackageManager.get(app_fullname)
|
||||
installed_app=AppManager.get(app_fullname)
|
||||
if not installed_app:
|
||||
return False
|
||||
return PackageManager.compare_versions(new_version, installed_app.version)
|
||||
return AppManager.compare_versions(new_version, installed_app.version)
|
||||
|
||||
@staticmethod
|
||||
def is_installed_by_path(dir_path):
|
||||
@@ -231,7 +231,7 @@ class PackageManager:
|
||||
@staticmethod
|
||||
def is_installed_by_name(app_fullname):
|
||||
print(f"Checking if app {app_fullname} is installed...")
|
||||
return PackageManager.is_installed_by_path(f"apps/{app_fullname}") or PackageManager.is_installed_by_path(f"builtin/apps/{app_fullname}")
|
||||
return AppManager.is_installed_by_path(f"apps/{app_fullname}") or AppManager.is_installed_by_path(f"builtin/apps/{app_fullname}")
|
||||
|
||||
@staticmethod
|
||||
def execute_script(script_source, is_file, classname, cwd=None):
|
||||
@@ -311,7 +311,7 @@ class PackageManager:
|
||||
mpos.ui.set_foreground_app(fullname)
|
||||
import utime
|
||||
start_time = utime.ticks_ms()
|
||||
app = PackageManager.get(fullname)
|
||||
app = AppManager.get(fullname)
|
||||
if not app:
|
||||
print(f"Warning: start_app can't find app {fullname}")
|
||||
return
|
||||
@@ -325,7 +325,7 @@ class PackageManager:
|
||||
else:
|
||||
entrypoint = app.main_launcher_activity.get('entrypoint')
|
||||
classname = app.main_launcher_activity.get("classname")
|
||||
result = PackageManager.execute_script(app.installed_path + "/" + entrypoint, True, classname, app.installed_path + "/assets/")
|
||||
result = AppManager.execute_script(app.installed_path + "/" + entrypoint, True, classname, app.installed_path + "/assets/")
|
||||
# Launchers have the bar, other apps don't have it
|
||||
if app.is_valid_launcher():
|
||||
mpos.ui.topmenu.open_bar()
|
||||
@@ -343,5 +343,4 @@ class PackageManager:
|
||||
# Stop all apps
|
||||
mpos.ui.remove_and_stop_all_activities()
|
||||
# No need to stop the other launcher first, because it exits after building the screen
|
||||
return PackageManager.start_app(PackageManager.get_launcher().fullname)
|
||||
|
||||
return AppManager.start_app(AppManager.get_launcher().fullname)
|
||||
@@ -5,7 +5,7 @@ import lvgl as lv
|
||||
import mpos.ui
|
||||
import mpos.ui.topmenu
|
||||
|
||||
from mpos import AppearanceManager, DisplayMetrics, PackageManager, SharedPreferences, TaskManager, DeviceInfo
|
||||
from mpos import AppearanceManager, DisplayMetrics, AppManager, SharedPreferences, TaskManager, DeviceInfo
|
||||
|
||||
# White text on black logo works (for dark mode) and can be inverted (for light mode)
|
||||
logo_white = "M:builtin/res/mipmap-mdpi/MicroPythonOS-logo-white-long-w296.png" # from the MPOS-logo repo
|
||||
@@ -124,12 +124,12 @@ except Exception as e:
|
||||
print(f"Couldn't start WifiService.auto_connect thread because: {e}")
|
||||
|
||||
# Start launcher so it's always at bottom of stack
|
||||
launcher_app = PackageManager.get_launcher()
|
||||
started_launcher = PackageManager.start_app(launcher_app.fullname)
|
||||
launcher_app = AppManager.get_launcher()
|
||||
started_launcher = AppManager.start_app(launcher_app.fullname)
|
||||
# Then start auto_start_app if configured
|
||||
auto_start_app = prefs.get_string("auto_start_app", None)
|
||||
if auto_start_app and launcher_app.fullname != auto_start_app:
|
||||
result = PackageManager.start_app(auto_start_app)
|
||||
result = AppManager.start_app(auto_start_app)
|
||||
if result is not True:
|
||||
print(f"WARNING: could not run {auto_start_app} app")
|
||||
|
||||
|
||||
@@ -815,7 +815,7 @@ class MockThread:
|
||||
|
||||
class MockApps:
|
||||
"""
|
||||
Mock mpos.apps module for testing (deprecated, use MockPackageManager instead).
|
||||
Mock mpos.apps module for testing (deprecated, use MockAppManager instead).
|
||||
|
||||
This is kept for backward compatibility with existing tests.
|
||||
|
||||
@@ -839,12 +839,12 @@ class MockApps:
|
||||
return True
|
||||
|
||||
|
||||
class MockPackageManager:
|
||||
class MockAppManager:
|
||||
"""
|
||||
Mock mpos.content.package_manager module for testing.
|
||||
Mock mpos.content.app_manager module for testing.
|
||||
|
||||
Usage:
|
||||
sys.modules['mpos.content.package_manager'] = MockPackageManager
|
||||
sys.modules['mpos.content.app_manager'] = MockAppManager
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -13,10 +13,10 @@ infrastructure are already initialized (boot.py and main.py executed).
|
||||
|
||||
Usage in tests:
|
||||
from mpos.ui.testing import wait_for_render, capture_screenshot
|
||||
from mpos import PackageManager
|
||||
from mpos import AppManager
|
||||
|
||||
# Start your app
|
||||
PackageManager.start_app("com.example.myapp")
|
||||
AppManager.start_app("com.example.myapp")
|
||||
|
||||
# Wait for UI to render
|
||||
wait_for_render()
|
||||
@@ -63,8 +63,8 @@ def wait_for_render(iterations=10):
|
||||
iterations: Number of task handler iterations to run (default: 10)
|
||||
|
||||
Example:
|
||||
from mpos import PackageManager
|
||||
PackageManager.start_app("com.example.myapp")
|
||||
from mpos import AppManager
|
||||
AppManager.start_app("com.example.myapp")
|
||||
wait_for_render() # Ensure UI is ready
|
||||
assert verify_text_present(lv.screen_active(), "Welcome")
|
||||
"""
|
||||
|
||||
@@ -7,7 +7,7 @@ from .appearance_manager import AppearanceManager
|
||||
from .util import (get_foreground_app)
|
||||
from . import focus_direction
|
||||
from .widget_animator import WidgetAnimator
|
||||
from mpos.content.package_manager import PackageManager
|
||||
from mpos.content.app_manager import AppManager
|
||||
|
||||
CLOCK_UPDATE_INTERVAL = 1000 # 10 or even 1 ms doesn't seem to change the framerate but 100ms is enough
|
||||
WIFI_ICON_UPDATE_INTERVAL = 1500
|
||||
@@ -268,7 +268,7 @@ def create_drawer():
|
||||
wifi_label.center()
|
||||
def wifi_event(e):
|
||||
close_drawer()
|
||||
PackageManager.start_app("com.micropythonos.wifi")
|
||||
AppManager.start_app("com.micropythonos.wifi")
|
||||
wifi_btn.add_event_cb(wifi_event,lv.EVENT.CLICKED,None)
|
||||
settings_btn=lv.button(drawer)
|
||||
settings_btn.set_size(lv.pct(drawer_button_pct),lv.pct(20))
|
||||
@@ -278,7 +278,7 @@ def create_drawer():
|
||||
settings_label.center()
|
||||
def settings_event(e):
|
||||
close_drawer()
|
||||
PackageManager.start_app("com.micropythonos.settings")
|
||||
AppManager.start_app("com.micropythonos.settings")
|
||||
settings_btn.add_event_cb(settings_event,lv.EVENT.CLICKED,None)
|
||||
launcher_btn=lv.button(drawer)
|
||||
launcher_btn.set_size(lv.pct(drawer_button_pct),lv.pct(20))
|
||||
@@ -289,7 +289,7 @@ def create_drawer():
|
||||
def launcher_event(e):
|
||||
print("Launch button pressed!")
|
||||
close_drawer(True)
|
||||
PackageManager.restart_launcher()
|
||||
AppManager.restart_launcher()
|
||||
launcher_btn.add_event_cb(launcher_event,lv.EVENT.CLICKED,None)
|
||||
'''
|
||||
sleep_btn=lv.button(drawer)
|
||||
@@ -308,7 +308,7 @@ def create_drawer():
|
||||
else: # assume unix:
|
||||
# maybe do a system suspend here? or at least show a popup toast "not supported"
|
||||
close_drawer(True)
|
||||
PackageManager.restart_launcher()
|
||||
AppManager.restart_launcher()
|
||||
sleep_btn.add_event_cb(sleep_event,lv.EVENT.CLICKED,None)
|
||||
'''
|
||||
restart_btn=lv.button(drawer)
|
||||
|
||||
Reference in New Issue
Block a user