-
Notifications
You must be signed in to change notification settings - Fork 47
Application Manager 重构调研报告
版本变更记录
| 时间 | 版本 | 说明 | 修改人 |
|---|---|---|---|
| 2023-03-28 | 1.0.0 | 创建,添加方案说明 | xzl01 |
| 2023-04-03 | 1.0.1 | 添加新的功能需求 | xzl01 |
| 2023-04-13 | 1.0.2 | 整理模块,剔除需求,完善功能分析 | xzl01 |
| 2023-05-5 | 1.0.3 | 拆分模块 | xzl01 |
现有的application manager(以下简称AM)在deepin v23系统中工作不佳,dde-dock和dde-launcher因为此问题无法正常使用,且AM在开发过程中无文档留存,导致后续开发者无法继续开发。并且AM实际定位与我们设想的AM的作用有偏离,导致AM的功能过于复杂,不易维护。所以我们需要对AM进行重构,以便于后续的开发和维护。
现有的AM是作为dde-launcher和dde-dock的后端,其功能拆分如下:
- 作为dde-launcher和dde-dock的后端,提供维护应用列表,dock和launcher从AM获取应用信息并且展示。(launcher自己缓存了一份应用列表,在
~/.config/dde-launcher/) - 作为application的代理管理器,提供app-proxy的设置。v23控制中心对于应用级代理是由此实现。
- 作为application的环境变量管理器,提供app-env的设置。v23控制中心对于应用级环境变量是由此实现。
- 作为应用的启动入口,统一管理应用的启动方式。
- 导致launcher和dock的卡顿和崩溃问题
- app-proxy的设置无法正常使用
- deepin-grand-search并非从AM启动应用
- 使用命令行启动应用,并非从AM启动应用(比如使用
ll-cli启动应用,或者使用code .启动vscode) - 对于appimage的支持不完善
- xdg-open启动应用也不会经过AM
对于AM的重构,我们需要考虑以下几个问题:
- AM是一个用户级的systemd服务(至少有一个系统级代理)
- AM在运行时直接对外暴露的接口是DBus接口
- AM需要对其暴露的DBus接口提供c/stdc++/qt/go的封装
- 负责所有的
.desktop应用的启动。 - 维护应用列表,当应用发生变化时,对外通知更新应用列表
- 维护运行中应用实例的列表
AM在讨论后决定拆分为三个模块:
ASM(APP start manager) AIM(APP install manager) APM(APP permission manager)
此三个模块彼此独立,但功能相近,所以建议放在同一仓库维护和版本管理
- ASM是一个用户级的systemd服务
- ASM在运行时直接对外暴露的接口是DBus接口
- ASM需要对其暴露的DBus接口提供c/stdc++/qt/go的封装
- ASM负责包括deb应用、appimage、linglong、安卓容器、wine的应用在内的应用的启动。
- ASM维护应用列表,当应用发生变化时,通知dde-launcher和dde-dock更新应用列表
- AIM不常驻后台
- AIM是一个工具,在安装应用和卸载应用时被调用,对安装和卸载的应用做出相应处理
- AIM提供一个对appimage fatpak linglong 和 deb包 的上层支持
- APM管理应用权限
- 注: "应用"和"程序"是不同的。AM所管理的应用指的是具有GUI图形界面,可独立启动的程序(可以简单的理解为在
/usr/share/applications中的应用)。
- app-proxy: 由新的模块负责维护
- mime管理:此功能将移动至xdg-portal进行管理
AM自启动管理,目标用户是launcher和控制中心
AM的自启动管理遵循XDG规范:https://wiki.archlinux.org/title/XDG_Autostart
不动系统提供的/etc/xdg/autostart/目录,使用用户目录下新建一个同名文件,并且使用Hidden=true来覆盖系统目录下的自启动
下面描述下AM在自动启动需要进行的工作:
- 监听
/etc/xdg/autostart/目录,如果有变动则拷贝到~目录下的$XDG_CONFIG_HOME/autostart文件夹,并且询问用户是否开机自启。如果不开机自启动则将$XDG_CONFIG_HOME/autostart的同名.desktop文件赋予Hidden=true属性,覆盖系统自动启动目录 - AM使用DConfig保存一份自动启动名单,如果应用被添加自动启动则在DConfig中保存一份,如果
$XDG_CONFIG_HOME/autostart下的文件被非AM修改,则AM负责恢复现场 - AM提供希望自启动的应用列表,此列表从
/etc/xdg/autostart获取。 - AM提供自启动应用列表,此列表从DConfig获取
- AM提供应用设置自启动的接口
AM提供了对于app自启动的管理,包括添加、删除、查询自启动应用。
<method name='AddAutostart'>
<arg type='s' name='fileNamae' direction='in' />
<arg type='b' name='outArg0' direction='out' />
</method>
<method name='AutostartList'>
<arg type='as' name='outArg0' direction='out' />
</method>
<method name='IsAutostart'>
<arg type='s' name='APPID' direction='in' />
<arg type='b' name='outArg0' direction='out' />
</method>
<method name='RemoveAutostart'>
<arg type='s' name='fileNamae' direction='in' />
<arg type='b' name='outArg0' direction='out' />
</method>
下面是APP添加自启动的工作流程:
graph
A((APP)) --添加自启动--> B["/etc/xdg/autosta/"]
B --由AM拷贝到--> C["~/.config/autostart/"]
C -->D{由用户判断是\n否允许自启动}
D --是--> E["不修改~/.config/autostart/\n的.desktop文件"]
D --否--> F["修改~/.config/autostart/\n的.desktop文件\nHidden=true"]
我考虑到,dde-launcher和dde-dock是系统常驻进程,也许他们本来应该是前后端一体的。 事实上之前将AM作为launcher和dock的后端不是很合理,因为这样违反了软件工程上的高内聚,低耦合的要求,一旦am出现问题,launcher和dock也会出现问题。
在重构之后,AM定位是作为应用的启动入口,提供一个dbus接口(初步定为:org.deepin.dde.am.startapp)供其他应用调用(包括launcher和dock)
同时launcher和dock同步需要重构。
这个会交给systemd管理,不过AM还是会负责维护app-env的配置(相当于对systemd.environment-generator进行封装),具体实现由systemd负责。这里不会详细介绍(见下文app启动流程)。
参考资料:systemd.environment-generator
xdg-open的启动流程是这样的:dde-open 是对于xdg-open的一个实现,我们想的是对于AM管理的应用,dde-open会调用AM的dbus接口来启动应用,而对于AM不管理的应用,dde-open按照原有逻辑来启动应用。
已知,AM当初是作为dde-dock和dde-lauuncher的后端设计的,所以在重构AM时候,这两个项目同样需要重构。 deeping-ground-search对于应用启动的部分也需要做出相应更改
(占比 5%)
小结对整个技术方案的功能、性能、稳定、安全、兼容、易用、可扩展性、先进性,以及可能的改进与下一步演进进行小结。
| xml | D-Bus Type | Qt DBUS Type |
|---|---|---|
| y | BYTE | uchar |
| b | BOOLEAN | bool |
| n | INT16 | short |
| q | UINT16 | ushort |
| i | INT32 | qint32 |
| u | UINT32 | quint32 |
| x | INT64 | qint64 |
| t | UINT64 | quint64 |
| d | DOUBLE | double |
| s | STRING | QString |
| v | VARIANT | QDBusVariant |
| o | OBJECT_PATH | QDBusObjectPath |
| g | SIGNATURE | QDBusSignature |
| as | Array of [string] | QStringList |
| ai | Array of [int32] | QList |
| ay | Array of [BYTE] | QByteArray |
| {sv} | Dict of {String,Variant} | QMap<QString,QVariant> |
| a | Array | QList |
| () | struct of { } | QVariant |
| {} | Dict | QMap |
讨论了AM是否需要实现一个全局的application管理。通过讨论,确定是应该要做,但不是AM的功能,所以将拆分此功能为一个新的项目
讨论AM内部对于APP的抽象是否使用APPID形式管理,通过讨论确定使用APPID,避免出现APPID相同情况,如果出现则弹窗提示用户选择
讨论动态图标支持相关问题,认为AM应该在一定程度支持动态图标,但是这个功能不应该由AM完成
讨论AM是否需要管理mime,认为应当使用使用 https://github.com/linuxdeepin/xdg-desktop-portal-dde 项目完成,而不是AM
讨论AM是否需要管理autostart,需要调研systemd相关功能以确定
讨论AM对dbus启动应用管理
讨论AM权限管理机制
讨论AM自启动方案,明确不能违反XDG标准
对于appimage的支持,我已经在freelist发邮件列表讨论了,见这里。在收到的意见和反馈中认为其实别的开源组织也在做这件事,是否可以避免重复造轮子?
链接:go-appimage其中提供了appimaged守护进程,可以使得appimage能像普通的应用一样启动。
不过appimaged还是监视指定文件夹,也就是说必须要求用户将appimage放在对应文件夹才可以启动,是否意味着我们还是需要一个appimage安装器来帮助用户把appimage放在指定文件夹中? 而且appimmaged不会为apimage补充缺失的图标,这个问题是否能得到解决?
参考另外一个项目:AppImageLauncher。这个项目提供了一个appimage安装器,可以帮助用户安装appimage, 同时也提供了一个appimage管理器,可以帮助用户管理appimage,它对于appimag的处理就是从内部提出图标,并且生成一个.desktop文件。
经过讨论,对于appimage的支持不应该放在AM之中,而是其他项目提供了appimage的支持,如生成了.desktop文件,提供了图标。AM维护的app列表也至针对其他项目提供的.desktop文件而言。而这个其他项目可以被AM的插件