Skip to content

Application Manager 重构调研报告

HarryLoong edited this page May 5, 2023 · 5 revisions

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的后端,其功能拆分如下:

  1. 作为dde-launcher和dde-dock的后端,提供维护应用列表,dock和launcher从AM获取应用信息并且展示。(launcher自己缓存了一份应用列表,在~/.config/dde-launcher/
  2. 作为application的代理管理器,提供app-proxy的设置。v23控制中心对于应用级代理是由此实现。
  3. 作为application的环境变量管理器,提供app-env的设置。v23控制中心对于应用级环境变量是由此实现。
  4. 作为应用的启动入口,统一管理应用的启动方式。

问题

  1. 导致launcher和dock的卡顿和崩溃问题
  2. app-proxy的设置无法正常使用
  3. deepin-grand-search并非从AM启动应用
  4. 使用命令行启动应用,并非从AM启动应用(比如使用ll-cli启动应用,或者使用code .启动vscode)
  5. 对于appimage的支持不完善
  6. xdg-open启动应用也不会经过AM

重构Application Manager

对于AM的重构,我们需要考虑以下几个问题:

  1. AM是一个用户级的systemd服务(至少有一个系统级代理)
  2. AM在运行时直接对外暴露的接口是DBus接口
  3. AM需要对其暴露的DBus接口提供c/stdc++/qt/go的封装
  4. 负责所有的.desktop应用的启动。
  5. 维护应用列表,当应用发生变化时,对外通知更新应用列表
  6. 维护运行中应用实例的列表

AM的定位

AM在讨论后决定拆分为三个模块:

ASM(APP start manager) AIM(APP install manager) APM(APP permission manager)

此三个模块彼此独立,但功能相近,所以建议放在同一仓库维护和版本管理

ASM
  1. ASM是一个用户级的systemd服务
  2. ASM在运行时直接对外暴露的接口是DBus接口
  3. ASM需要对其暴露的DBus接口提供c/stdc++/qt/go的封装
  4. ASM负责包括deb应用、appimage、linglong、安卓容器、wine的应用在内的应用的启动。
  5. ASM维护应用列表,当应用发生变化时,通知dde-launcher和dde-dock更新应用列表
AIM
  1. AIM不常驻后台
  2. AIM是一个工具,在安装应用和卸载应用时被调用,对安装和卸载的应用做出相应处理
  3. AIM提供一个对appimage fatpak linglong 和 deb包 的上层支持
APM
  1. APM管理应用权限
  • 注: "应用"和"程序"是不同的。AM所管理的应用指的是具有GUI图形界面,可独立启动的程序(可以简单的理解为在/usr/share/applications中的应用)。

删除功能

  1. app-proxy: 由新的模块负责维护
  2. mime管理:此功能将移动至xdg-portal进行管理

更改功能

AutoStrat

AM自启动管理,目标用户是launcher和控制中心

AM的自启动管理遵循XDG规范:https://wiki.archlinux.org/title/XDG_Autostart

不动系统提供的/etc/xdg/autostart/目录,使用用户目录下新建一个同名文件,并且使用Hidden=true来覆盖系统目录下的自启动

下面描述下AM在自动启动需要进行的工作:

  1. 监听/etc/xdg/autostart/目录,如果有变动则拷贝到目录下的$XDG_CONFIG_HOME/autostart文件夹,并且询问用户是否开机自启。如果不开机自启动则将$XDG_CONFIG_HOME/autostart的同名.desktop文件赋予Hidden=true属性,覆盖系统自动启动目录
  2. AM使用DConfig保存一份自动启动名单,如果应用被添加自动启动则在DConfig中保存一份,如果$XDG_CONFIG_HOME/autostart下的文件被非AM修改,则AM负责恢复现场
  3. AM提供希望自启动的应用列表,此列表从/etc/xdg/autostart获取。
  4. AM提供自启动应用列表,此列表从DConfig获取
  5. 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"]

Loading

dde-launcher和dde-dock的工作流程

我考虑到,dde-launcher和dde-dock是系统常驻进程,也许他们本来应该是前后端一体的。 事实上之前将AM作为launcher和dock的后端不是很合理,因为这样违反了软件工程上的高内聚,低耦合的要求,一旦am出现问题,launcher和dock也会出现问题。

在重构之后,AM定位是作为应用的启动入口,提供一个dbus接口(初步定为:org.deepin.dde.am.startapp)供其他应用调用(包括launcher和dock)

同时launcher和dock同步需要重构。

start app

appenv

这个会交给systemd管理,不过AM还是会负责维护app-env的配置(相当于对systemd.environment-generator进行封装),具体实现由systemd负责。这里不会详细介绍(见下文app启动流程)。

参考资料:systemd.environment-generator

改善xdg-open的启动流程

xdg-open的启动流程是这样的:dde-open 是对于xdg-open的一个实现,我们想的是对于AM管理的应用,dde-open会调用AM的dbus接口来启动应用,而对于AM不管理的应用,dde-open按照原有逻辑来启动应用。

重构影响范围

已知,AM当初是作为dde-dock和dde-lauuncher的后端设计的,所以在重构AM时候,这两个项目同样需要重构。 deeping-ground-search对于应用启动的部分也需要做出相应更改


技术方案

整体设计

关键技术

小结

(占比 5%)

小结对整个技术方案的功能、性能、稳定、安全、兼容、易用、可扩展性、先进性,以及可能的改进与下一步演进进行小结。

参考资料

DBus和Qt类型对照

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的支持

对于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的插件