欢迎阅读 UBPorts 文档!¶
欢迎来到 Ubports 项目的官方文档库!
Ubports 开发了 Ubuntu Touch 手机操作系统。Ubuntu Touch 是一款专注于易用性,隐私性和融合性的移动操作系统。
在本站中,您可以找到如何在手机上安装 Ubuntu Touch 的说明、用户指南和所有系统组件的详细文档。如果您是第一次来这里,请考虑阅读我们的:doc:介绍 <about/introduction>.
如果您想要协助我们改进本文档,文档贡献页面 将会帮助你开始。
您可以使用以下语言查看此文档:
- English
- 加泰罗尼亚语(Català)
- 法语(Français)
- 德语(Deutsch)
- 意大利语(Italiano)
- 罗马尼亚语(Română)
- 土耳其语(Türkçe)
- 西班牙语(Español)
介绍¶
这是 UBports 项目的文档。我们的目标是创建一个开源(若可能则为 GPL 许可证)的移动操作系统,它将拥有融合性并尊重您的自由。
关于 UBports¶
UBports 项目由 Marius Gripsgard 于 2015 年创立,在其初期阶段,开发人员可以分享想法并互相教育,希望将 Ubuntu Touch 平台带入越来越多的设备。
After Canonical suddenly announced their plans to terminate support of Ubuntu Touch in April of 2017, UBports and its sister projects began work on the open-source code, maintaining and expanding its possibilities for the future.
关于本文档¶
感谢 UBports 社区的成员,本文档得以不断改进。它由 ReStructuredText 写成并由 Sphinx 、 ReCommonMark 和 Read the Docs 转换为可读格式。您可以通过阅读 介绍 开始你的贡献。
所有文件均根据知识共享署名相同方式共享4.0 (CC-BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0/> `_) 许可证。请给予“UBports 社区”的署名。
归属¶
本文档高度依赖 Godot Engine’s Documentation 建模,归属于 Juan Linietsky, Ariel Manzur 和 Godot 社区。
流程¶
这部分文档详细说明了不同团队的标准化流程。
注解
流程定义的工作仍在进行中,需要由各个团队共同完成它。
问题跟踪指南¶
本文档描述了处理UBports项目中新问题的标准流程。请不要与 :doc:编写好的bug报告指南</贡献/错误报告> 混淆。
Bug 会在哪里被跟踪?¶
Since our quality assurance depends heavily on the community, we try to track issues where the user would expect them, instead of separated by repository. This means, that issues of almost all components that are distributed as with the system-image are tracked in the Ubuntu Touch tracker. An exception of this are click-apps that can be updated independently through the OpenStore.
大多数其他存储库在本地跟踪问题。 如果您不确定资源库是否使用自己的跟踪器,请查阅README.md文件。 不在本地跟踪问题的存储库禁用了错误跟踪器。
此页面主要介绍了关于Ubuntu Touch跟踪器的信息,但大多数原则上也适用于其他项目。
注解
实用性要大于整洁度!例外情况可能适用,应在项目README.md文件中加以说明。
GitHub 项目¶
To increase transparency and communication, GitHub projects (Kanban-Boards) are used wherever practical. In case of github.com/ubports/ubuntu-touch, a single project is used for all issues. Projects support filtering by labels, so that only issues that belong to a specific team or affect a specific device can be viewed.
以下是标准列:
- None (awaiting triage): The issue has been approved by a member of the QA team and is awaiting review from the responsible development team. if the issue is a bug, instructions to reproduce are included in the issue description. if the issue is a feature request, it has passed a primary sanity check by the qa-team but has not yet been accepted by the responsible development-team.
- Accepted: The issue has been accepted by the responsible development-team. If the issue is a bugreport, the team has decided that it should be fixable and accepts the responsibility. If the issue is a feature request, the team thinks it should be implemented as described.
- In Development :补丁正在开发中。 通常意味着开发人员已被分配到该问题。
- Quality Assurance :补丁已完成并已通过初始测试。 质量检查小组现在将对其进行检查并提供反馈。 如果发现问题,问题将转回“已接受”。
- Release Candidate :该补丁已通过质量保证并准备发布。 如果系统映像中包含 Debian 软件包,该补丁将包含在 rc 频道的下一个 OTA 更新中,如果一切顺利,则将在稳定版频道的下一个版本中发布。
- None (removed from the project) :如果问题是开放的且标记为“需要帮助”,则需要社群贡献才能解决问题。 如果它关闭,这意味着或者在稳定频道上发布了一个补丁(对该问题的评论应链接到该补丁),或者该问题已被拒绝(标记为“wontfix”)。
标签¶
所有问题 - 甚至是已关闭的问题 - 都应该贴上标签以使用 GitHub 的全局过滤功能。比如 `这些都是 @ubports 内部标记为“增强功能”的所有问题<https://github.com/search?utf8=%E2%9C%93&q=is%3Aopen+org%3Aubports+label%3A%22feature+request%22&type=>`_。有关搜索和过滤的更多信息,请参阅 GitHub 帮助页面 以获取更多信息。
这里是存储库通常使用的标签列表。
- needs confirmation:这个 bug 需要受影响用户的确认和进一步提供信息
- bug: This issue is a confirmed bug. If it’s reproducible, reproduction steps are described.
- opinion:这个问题需要进一步讨论。
- enhancement:这个问题是功能请求。
- question:这个问题是一个支持请求或一般问题。
- invalid:这个问题无法得到确认或是在错误的跟踪器中报告的。
- help wanted:这个问题已经被报告。请提供链接并关闭。
- help wanted:这个问题已经准备好由社区开发者提供帮助。
- good first issue:这个问题并不严重,可以被修复。它被保留给新的贡献者作为开始的地方。
- wontfix: 这个问题没有修复的意义,因为它要么可能会被自行解决、要么需要太多精力、要么不可修复,或者因底层组件即将改变而不需要修复。
流程定义仍在进行中,它需要由各个团队来完成:
- ** critical(devel)**:这个严重的问题只在``devel通道上阻塞了下一个rc图像的发布``这一情况中发生。
- ** critical(rc)**:仅在devel通道和rc通道上发生的关键问题阻碍了下一个稳定版本的发布。 通常情况下,不能简单地移动到不同版本并且有权推迟发布的问题都标记为此。
- **device: [DEVICE CODENAME] **:此问题仅影响指定的设备。
- **team: [TEAM NAME] **:这个问题属于特定团队(hal,middleware,UI)的责任范围。
注解
如果在本地跟踪问题的存储库定义了它自己的标签,则应将其记录在README.md中。
里程碑¶
里程碑仅用于稳定的OTA释放。 通常,创建正在进行中的OTA和下一个OTA的里程碑。 一旦发布的工作开始(从开始日期起6周),ETA就会设置,但之后可以进行调整。 有关详细信息,请参阅:doc:release-schedule <release-schedule>。
申请人¶
为了使处理问题的人员变得透明,应该指派开发人员。 这也允许使用GitHub的全局过滤作为一种TODO列表。 例如,`这是在@ubports <https://github.com/search?utf8=%E2%9C%93&q=is%3Aopen+org%3Aubports+assignee%3Amariogrip&type=>`_中分配给mariogrip的所有内容。
鼓励开发人员保持他们的清单简短并更新他们的问题状态。
事例¶
Bug 生命周期¶
- 一个 * 用户 *使用问题模板提交新错误。
- The QA-Team adds the label needs confirmation and tries to work with the user to confirm the bug and add potentially missing information to the report. Once the report is complete a team-label will be added to the issue, the issue will be put on the awaiting-triage-list of the project and the label needs confirmation will be replaced with bug.
- 受影响的* 团队 将对问题进行分类,并拒绝(标签* wontfix ,关闭并从项目中删除)或接受该问题。 团队决定他们是否会在内部解决问题(转到“接受”并指派一名团队成员)或等待社区开发人员接收它(标签**帮助想要,从项目板中删除, 提供有关如何解决问题的提示以及有关如何在必要时实施修复的更多详细信息。 对于非常难以解决的非关键问题,也可以添加标签**良好的第一期**。
- Once a developer is assigned and starts working on the issue, it is moved to “In Development”. As soon as they have something to show for, the issue is closed and automatically moved to “Quality Assurance” for feedback from the QA team. If necessary, the developer will provide hints on how to test his patch in a comment on the issue.
- The QA-Team tests the fix on all devices and provides feedback to the developer. If problems are found, the issue is re-opened and goes back to “Accepted”, else it’s moved to “Release Candidate” to be included in the next release.
- 如果尚未完成,则会将问题添加到下一个 Milestone。 一旦 Milestones 发布,问题就会从项目板中删除。
发布时间表¶
OTA 更新通常遵循这个节奏:
- devel:每日构建
- rc:如果devel频道中不存在严重问题,则每周一次
- 稳定版:如果rc频道中没有关键问题,则每六到八周一次
这不是一个明确的周期。 稳定的版本在准备就绪时就已准备完整了,不应引入新的错误或发布非常不完整的功能。 由于OTA更新无法在所有关键问题结束前发布,因此可能需要通过对所有问题何时可以处理进行有根据的猜测来调动ETA。 如果添加到这次重要阶段的问题太多,则应将其删除或添加到下一个重要阶段。
repo.ubports.com¶
This is the package archive system for UBports projects. It hosts various PPAs containing all deb-components of Ubuntu Touch.
Repository naming convention¶
Native packages¶
Native packages are repositories which contain a debian/
directory with the source used to create the Debian source package (.dsc
).
The name of the Debian source package generated from the repository and the name of the git-repository should be the same.
Packaging repositories¶
Packaging repositories contain a debian/
directory without the source used to create the Debian source package (.dsc
). They also contain instructions to tell debhelper
how to get the source used to create the source package.
The repository should have the name of the source package it generates with -packaging
appended to the end. For example, a packaging repository that generates a source package called sandwich
would be called sandwich-packaging
.
Creating new PPAs¶
New PPAs can be created dynamically by the CI server using a special git-branch naming convention. The name of the branch translates literally to the name of the PPA: http://repo.ubports.com/dists/[branch name]
Non-standard PPAs (i.e. not xenial
, vivid
or bionic
) are kept for three months. In case they need to be kept for a longer time, a file with the name ubports.keep
can be created in the root of the repository, containing the date until which the PPA shall be kept open in the form of YYYY-MM-dd
. If this file is empty, the PPA will be kept for two years after the last build.
文件命名规则¶
我们的约定好分支命名的规则以确保我们的CI可以构建软件并由其他开发人员轻松测试。
每个Git存储库的README文件都应该说明使用哪个分支命名约定以及可能与规范的偏差。
一键安装包¶
专门作为 click-package(而不是deb)分发的软件只使用一个受保护的``master``分支。 可以创建具有任意描述性名称的单独临时开发分支,并及时合并到master分支中。为了标记和归档在开发历史记录中的重要阶段性数据,最好使用Git的tags功能或GitHub 的 releases页面。
Debian 软件包¶
为了最有效地使用我们的CI系统,我们使用了一个特殊的git-分支命名规则。
对于预先安装的Ubuntu Touch组件,尽可能使用deb包。 这包括核心应用程序,因为它们仍然可以使用OpenStore的点击包下载进行独立更新。 这个策略允许我们利用强大的Debian构建系统来解决依赖关系。
每个使用这种规定的资料库都会有分支,用于代号(“bionic”,“xenial”,“vivid”等)引用的主动支持的Ubuntu发布版本。这些都是直接构建到相应镜像中并发布在:doc:`repo.ubports.com <ppa>`上的分支。如果不需要用于不同Ubuntu版本的独立版本,版本库将只有一个``master``分支,并且CI系统仍然会为所有主动支持的发布版本构建版本并相应地解决依赖关系。
分支-扩展¶
基于另一个存储库构建和发布包,形式为的扩展可以使用``xenial _-_ some-descriptive_extension``。 然后,CI系统将使用其他存储库的``xenial _-_ some-descriptive_extension``分支来解析所有依赖关系,或者如果不存在则回退到正常的``xenial``依赖关系。 这些特殊的依赖项没有内置到图像中,但仍然被推送到on:doc:repo.ubports.com <ppa>。
多个分支扩展可以以“xenial _-_ dependency-1 _-_ dependency-2 _-_ dependency-3”的形式链接在一起。 这意味着CI系统将会在以下存储库中查找依赖关系:
xenial
xenial_-_dependency-1
xenial_-_dependency-1_-_dependency-2
xenial_-_dependency-1_-_dependency-2_-_dependency-3
注解
因为没有优先级,构建系统将始终使用版本号最高的软件包或版本相同的最新版本。
依赖文件¶
对于复杂或非线性的依赖关系,可以在存储库的根目录中创建一个名为``ubports.depends``的文件来指定其他依赖项。 如果此文件存在,则自动忽略分支名称。
xenial
xenial_-_dependency-1_-_dependency-2_-_dependency-3
xenial_-_something-else
注解
ubports.depends``文件是一个**独占列表**,因此构建系统不会像在分支名称中那样线性地解析依赖关系!每个依赖项都必须列出。你几乎总是希望每一个依赖项均包含于你的基本版本中(即``xenial
)。
安装 Ubuntu Touch¶
Installing Ubuntu Touch is easy, and a lot of work has gone in to making the installation process less intimidating to less technical users. The UBports Installer is a nice graphical tool that you can use to install Ubuntu Touch on a supported device from your Linux, Mac or Windows computer.
警告
If you’re switching your device over from Android, you will not be able to keep any data that is currently on the device. Create an external backup if you want to keep it.
Go to the download page and download the version of the installer for your operating system:
- Windows: ubports-installer-<版本号>.exe
- macOS:
ubports-installer-<版本号>.dmg
- Ubuntu 或 Debian:
ubports-installer-<版本号>.deb
- Other Linux distributions:
ubports-installer-<version-number>.snap
orubports-installer-<version-number>.AppImage
Start the installer and follow the on-screen instructions that will walk you through the installation process. That’s it! Have fun exploring Ubuntu Touch!
If you’re an experienced android developer and want to help us bring Ubuntu Touch to more devices, visit the porting section.
在旧式 Android 设备上安装¶
While the installation process is fairly simple on most devices, some legacy Bq and Meizu devices require special steps. This part of the guide does not apply to other devices.
注解
This is more or less uncharted territory. If your device’s manufacturer does not want you to install an alternative operating system, there’s not a lot we can do about it. The instructions below should only be followed by experienced users. While we appreciate that lots of people want to use our OS, flashing a device with OEM tools shouldn’t be done without a bit of know-how and plenty of research.
Meizu devices are pretty much stuck on Flyme. While the MX4 can be flashed successfully in some cases, the Pro5 is Exynos-based and has its own headaches.
警告
请三思而后行!
从 PC 上断开所有(移动)设备和非必要外围设备的连接。 请使用充电器(而不是 PC)为设备充电至至少 40% 的电量。
为您的设备下载 Ubuntu Touch 刷机包:
- Bq E4.5 (krillin)
- Bq E5 HD (vegetahd)
- Bq M10 HD (cooler)
- Bq M10 FHD (frieza)
- 魅族 MX4 (arale)
下载适用于 Linux 的 SP flash tool <https://storage.googleapis.com/otas/2015/Tablets/Freezer%20FHD/Ubuntu/SP_Flash_Tool_exe_Linux_v5.1612.00.100.zip>`_ 。
On Ubuntu 17.10, there are issues with flash_tool loading the shared library ‘libpng12’, so this can be used as a workaround:
wget -q -O /tmp/libpng12.deb http://mirrors.kernel.org/ubuntu/pool/main/libp/libpng/libpng12-0_1.2.54-1ubuntu1_amd64.deb \
&& sudo dpkg -i /tmp/libpng12.deb \
&& rm /tmp/libpng12.deb
You will also need to use the latest version of the tool.
- 解压 zip 文件
- 使用
sudo
命令打开工具 - Select the
*Android_scatter.txt
file from the archive you downloaded in the first step as the scatter-loading file - 选择“固件更新”
- 仔细检查您选择的是“固件升级”而不是“下载”或“全部格式化”
警告
If you select DOWNLOAD rather than FIRMWARE UPGRADE, you will end up with a useless brick rather than a fancy Ubuntu Touch device. Be sure to select FIRMWARE UPGRADE.
- 让您的设备完全关机,但请不要将其连接。
- 请按“下载”按钮
- 执行最终的完整性检查,选择“固件升级”选项,而不是“下载”。
- 确保您的设备已关闭并将其连接到 PC。 请勿使用 USB 3.0 端口,因为它会导致设备出现通信问题。
- Magic happens. Your device will boot into a super old version of Ubuntu Touch.
- 恭喜! 您的设备现在将启动到老旧版本的 Ubuntu Touch 。您现在可以使用 UBports 安装程序继续操作。
日常使用¶
This section of the documentation details common tasks that users may want to perform while using their Ubuntu Touch device.
运行桌面应用¶
Libertine allows you to use standard desktop applications in Ubuntu Touch.
To display and launch applications you need the Desktop Apps Scope which is available in the Open Store. To install applications you need to use the commandline as described below.
管理容器¶
创建一个容器¶
The first step is to create a container where applications can be installed:
libertine-container-manager create -i CONTAINER-IDENTIFIER
You can add extra options such as:
-n name
name is a more user friendly name of the container-t type
type can be eitherchroot
orlxc
. Default ischroot
and is compatible with every device. If the kernel of your device supports it thenlxc
is suggested.
由于容器较大(几百 MB),所以可能需要一些时间创建它。
注解
The create
command shown above cannot be run directly in the terminal app, due apparmor restrictions. You can run it from another device using either adb
or ssh
connection. Alternatively, you can run it from the terminal app using a loopback ssh connection running this command: ssh localhost
.
销毁容器¶
libertine-container-manager destroy -i CONTAINER-IDENTIFIER
管理应用程序¶
Once a container is set up, you can list the installed applications:
libertine-container-manager list-apps
Install a package:
libertine-container-manager install-package -p PACKAGE-NAME
Remove a package:
libertine-container-manager remove-package -p PACKAGE-NAME
注解
If you have more than one container, then you can use the option -i CONTAINER-IDENTIFIER
to specify for which container you want to perform an operation.
Tips¶
位置¶
For every container you create there will be two directories created:
- A root directory
~/.cache/libertine-container/CONTAINER-IDENTIFIER/rootfs/
and- a user directory
~/.local/share/libertine-container/user-data/CONTAINER-IDENTIFIER/
Shell access¶
There are 2 options for executing commands inside the container.
The first option is based on libertine-container-manager exec
. It lets you run your commands as root. The drawback is that the container is not completely set up. So far we know that the folders mentioned above (Documents, Music, …) are not mounted i.e., the /home/phablet/
directory is empty. Likewise the directory referenced in TMPDIR
is not available what may lead to problems with software that tries to create temporary files or directories.
You may use this option e.g., for installing packages.
To execute a command you can use the following pattern:
libertine-container-manager exec -i CONTAINER-IDENTIFIER -c "COMMAND-LINE"
For example run:
libertine-container-manager exec -i CONTAINER-IDENTIFIER -c "apt-get --help"
To get a shell into your container as root
run:
libertine-container-manager exec -i CONTAINER-IDENTIFIER -c "/bin/bash"
The second option is based on libertine-launch
. It will execute your commands as user phablet in a completely set up container. So you may use this option to modify your files using installed packages.
To execute a command you can use the following pattern:
libertine-launch -i CONTAINER-IDENTIFIER COMMAND-LINE
For example run:
libertine-launch -i CONTAINER-IDENTIFIER ls -a
To get a shell as user phablet
run:
DISPLAY= libertine-launch -i CONTAINER-IDENTIFIER /bin/bash
注解
When you launch bash in this way you will not get any specific feedback to confirm that you are now inside the container. You can check ls /
to confirm for yourself that you are inside the container. The listing of ls /
will be different inside and outside of the container.
Shortcuts¶
If you want, you can add aliases for command line tools. Add lines like the following ones to your ~/.bash_aliases
:
alias git='libertine-launch -i CONTAINER-IDENTIFIER git'
alias screenfetch='libertine-launch -i CONTAINER-IDENTIFIER screenfetch'
背景¶
A display server coordinates input and output of an operating system. Most Linux distributions today use the X server. Ubuntu Touch does not use X, but a new display server called Mir. This means that standard X applications are not directly compatible with Ubuntu Touch. A compatibility layer called XMir resolves this. Libertine relies on XMir to display desktop applications.
Another challenge is that Ubuntu Touch system updates are released as OTA images. A consequence of this is that the root filesystem is read only. Libertine provides a container with a read-write filesystem to allow the installation of regular Linux desktop applications.
Run Android applications¶
Anbox is a minimal Android container and compatibility layer that allows you to run Android applications on GNU/Linux operating systems.
注解
- Anbox is in early development
- When “host” is used in this document, it refers to another device which you can connect your Ubuntu Touch device to. Your host device must have
adb
andfastboot
installed.
支持设备¶
请确保你的设备被支持:
- Meizu Pro 5 (codename:
turbo
, name of the boot partition:bootimg
) - Fairphone 2 (codename:
FP2
, name of the boot partition:boot
) - Oneplus one (codename:
bacon
, name of the boot partition:boot
) - Nexus 5 (codename:
hammerhead
, name of the boot partition:boot
) - BQ M10 HD (codename:
cooler
, name of the boot partition:boot
) - BQ M10 FHD (codename:
frieza
, name of the boot partition:boot
)
You will need the device codename and the name of your boot partition for the installation.
如何安装¶
警告
Because this feature is in such an early stage of development, the installation is only recommended for experienced users.
Make sure your supported device runs on 16.04 (anbox doesn’t work on 15.04)
Open a terminal on your host and set some device specific variables by running
export CODENAME="turbo" && export PARTITIONNAME="bootimg"
, but replace the part between the quotes respectively with the codename and name of the boot partition for your device. See the above list.Activate developer mode on your device.
Connect the device to your host and run the following commands from your host (same terminal that you ran the
export
command in):adb shell sudo reboot -f bootloader # 'adb shell' will exit after this command wget http://cdimage.ubports.com/anbox-images/anbox-boot-$CODENAME.img sudo fastboot flash $PARTITIONNAME anbox-boot-$CODENAME.img sudo fastboot reboot rm anbox-boot-$CODENAME.img exit
Wait for the device to reboot, then run from your host:
adb shell sudo mount -o rw,remount / sudo apt update sudo apt install anbox-ubuntu-touch anbox-tool install exit
Done! You might have to refresh the apps scope (pull down from the center of the screen and release) for the new Android apps to show up.
How to install new apks¶
Copy the apk to
/home/phablet/Downloads
, then run the following from your host:adb shell sudo mount -o rw,remount / sudo apt update sudo apt install android-tools-adb adb install /home/phablet/Downloads/my-app.apk exit
Done! You might have to refresh the apps scope (pull down from the center of the screen and release) for the new Android apps to show up.
Keep your apps up to date¶
- To keep your apps running the lasted version you can make use of F-Droid or ApkTrack. If you like to install one of the above apps you can find them here:
- F-Droid: https://f-droid.org/
- ApkTrack: https://f-droid.org/packages/fr.kwiatkowski.ApkTrack/
How to uninstall applications¶
This is a example of the app-list installed apps on your device
To uninstall apps, run
adb uninstall [APP_ID]
from your Ubuntu Touch device:adb shell sudo mount -o rw,remount / adb uninstall [APP_ID] exit
Done! You might have to refresh the apps scope (pull down from the center of the screen and release) for the new Android apps to show up.
Troubleshooting¶
If installing
anbox-ubuntu-touch
orandroid-tools-adb
on the device fails with an error about unsufficient space, try this:adb shell sudo mount -o rw,remount / sudo rm -r /var/cache/apt # delete the apt cache; frees space on system image sudo tune2fs -m 0 /dev/loop0 # space reserved exclusively for root user on system image set to zero sudo apt update # recreate apt cache to install anbox and adb sudo apt install anbox-ubuntu-touch android-tools-adb sudo mount -o ro,remount / exit
When you want to install an apk but get the error
Invalid APK file
that error could also mean “file not found”- check that you typed the file name correctly
- if the apk does not reside in the current folder where you execute adb, you have to specify the full path, e.g.
/home/phablet/Downloads/my-app.apk
instead of justmy-app.apk
报告 bug¶
Please report any bugs you come across. Bugs with Ubuntu Touch 16.04 are reported in the normal Ubuntu Touch tracker and issues with anbox are reported on our downstream fork. Thank you!
高级使用¶
本文档的这一部分详细介绍了高级用户可能希望在其Ubuntu Touch设备上执行的高级任务。
注解
有些指南可能会使您的系统镜像可写入,这可能破坏OTA升级。这些指南也可能削弱您的Ubuntu Touch设备的整体安全性。在您玩机之前请三思!
通过 adb 访问 shell¶
您可以将您的 UBports 设备置于开发者模式并从 PC 访问 Bash Shell。这对调试和高级使用非常有帮助。
安装 ADB¶
首先,您需要在您的计算机上安装 ADB。
在 Ubuntu 上:
sudo apt install android-tools-adb
在 Fedora 上:
sudo dnf install android-tools
在 MacOS 上使用 Homebrew:
brew install android-platform-tools
对于 Windows,从`这里 <https://developer.android.com/studio/index.html#downloads>`_ 获取命令行工具包。
启用开发者模式¶
接下来,您需要启用开发者模式。
- 重启你的设备
- 将您的设备置于开发者模式(设置 - 关于 - 开发者模式 - 选中此框将其打开)
- 将设备插入已安装 adb 的计算机上
- 打开终端,运行
adb devices
。
注解
当您使用完 shell 之后,最好关闭开发者模式。
如果列表中有设备(该命令不显示 “List of devices attached” 和空行),则说明可以使用 ADB 。若没有,请读下面。
添加硬件 ID¶
ADB doesn’t always know what devices on your computer it should or should not talk to. You can manually add the devices that it does not know how to talk to.
Just run the command for your selected device if it’s below. Then, run adb kill-server
followed by the command you were initially trying to run.
Fairphone 2:
printf "0x2ae5 \n" >> ~/.android/adb_usb.ini
Oneplus One:
printf "0x9d17 \n" >> ~/.android/adb_usb.ini
通过 ssh 访问 shell¶
您可以使用 ssh 从 PC 访问 shell。 这对于调试或更高级的shell 使用来说非常有用
You need a ssh key pair for this. Logging in via password is disabled by default.
创建你的公钥¶
If not already created, create your public key, default choices should be fine for LAN, you can leave empty password if you don’t want to deal with it each time:
ssh-keygen
将公钥复制到您的设备¶
然后,您需要将公钥传输到您的设备。 有许多方法实现。 例如:
Connect the ubports device and the PC with a USB cable. Then copy the file using your filemanager.
Or transfer the key via the internet by mailing it to yourself, or uploading it to your own cloud storage, or webserver, etc.
You can also connect via adb and use the following command to copy it:
adb push ~/.ssh/id_rsa.pub /home/phablet/
配置您的设备¶
Now you have the public key on the UBports device.
Let’s assume it’s stored as /home/phablet/id_rsa.pub
. Use the terminal app or and adb connection to perform the following steps on your phone.
mkdir /home/phablet/.ssh
chmod 700 /home/phablet/.ssh
cat /home/phablet/id_rsa.pub >> /home/phablet/.ssh/authorized_keys
chmod 600 /home/phablet/.ssh/authorized_keys
chown -R phablet.phablet /home/phablet/.ssh
现在开启 SSH 服务器:
sudo android-gadget-service enable ssh
连接¶
Now everything is set up and you can use ssh
ssh phablet@<ip-address>
Of course you can now also use scp
or sshfs
to transfer files.
切换发行通道¶
Screen Casting your UT device to your computer¶
Ubuntu Touch comes with a command line utility called mirscreencast
which dumps screen frames to a file.
The idea here is to stream UT display to a listening computer over the network or directly trough adb so that we can either watch it live or record it to a file.
使用 adb¶
You can catch output directly from adb exec-out
command and forward it to mplayer:
adb exec-out timeout 120 mirscreencast -m /run/mir_socket --stdout --cap-interval 2 -s 384 640 | mplayer -demuxer rawvideo -rawvideo w=384:h=640:format=rgba -
NB: timeout
here is used in order to kill process properly on device ( here 120 seconds ). Otherwise process still continuing even if killed on computer.
You can reduce or increase frame per second with``–cap-interval`` (1 = 60fps, 2=30fps, …) and size of frames 384 640
means width=384 height=640
通过网络¶
On receiver¶
For real time casting:
Prepare your computer to listen to a tcp port(here 1234) and forward raw stream to a video player (here mplayer) with a frame size of 384x640:
nc -l -p 1234 | gzip -dc | mplayer -demuxer rawvideo -rawvideo w=384:h=640:format=rgba -
For stream recording:
Prepare your computer to listen to a tcp port(here 1234), ungzip and forward raw stream to a video encoder (here mencoder):
nc -l -p 1234 | gzip -dc | mencoder -demuxer rawvideo -rawvideo fps=60:w=384:h=640:format=rgba -ovc x264 -o out.avi -
On device¶
Forward and gzip stream with 60fps (–cap-interval 1) and frame size of 384x640 to computer 10.42.0.209 on port 1234
mirscreencast -m /run/mir_socket --stdout --cap-interval 1 -s 384 640 | gzip -c | nc 10.42.0.209 1234
示例脚本¶
This script allows you to screen cast remote UT device to your local PC (must have ssh access to UT and mplayer installed on PC), run it on your computer:
#!/bin/bash
SCREEN_WIDTH=384
SCREEN_HEIGHT=640
PORT=1234
FORMAT=rgba
if [[ $# -eq 0 ]] ; then
echo 'usage: ./mircast.sh UT_IP_ADDRESS , e.g: ./mircast.sh 192.168.1.68'
exit 1
fi
IP=$1
LOCAL_COMMAND='nc -l -p $PORT | gzip -dc | mplayer -demuxer rawvideo -rawvideo w=$SCREEN_WIDTH:h=$SCREEN_HEIGHT:format=$FORMAT -'
REMOTE_COMMAND="mirscreencast -m /run/mir_socket --stdout --cap-interval 1 -s $SCREEN_WIDTH $SCREEN_HEIGHT | gzip -c | nc \$SSH_CLIENT $PORT"
ssh -f phablet@$IP "$REMOTE_COMMAND"
eval $LOCAL_COMMAND
您可以从这下载: files/mircast.sh
参考文献¶
Reverse tethering¶
某些用户可能没有可用的WiFi连接或者来自他们的移动运营商的数据网络连接。以下的小教程会帮助你将你的Ubuntu Touch设备连接至你的计算机来访问互联网。
前提:手机已通过USB连接至计算机,并且启用了开发者模式。
步骤¶
手机端:
android-gadget-service enable rndis
电脑端:获取你的RNDIS IP地址,比如:
hostname -I
在手机上:
add gateway:
sudo route add default gw YOUR_COMPUTER_RNDIS_IP
add nameservers:
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf
refresh dns table:
resolvconf -u
在计算机上:
enable ip forwarding:
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
apply NAT:
sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/8 -o eth0 -j MASQUERADE
CallDAV和CardDAV同步¶
CalDAV and CardDAV are protocols to synchronize calendars and contacts with a remote server. Many email-hosters provide a CalDAV and CardDAV interface.
Note: CalDAV Sync can also be set up in using the calendar app. Open the app, click on the little calendar icon in the top right corner and select “Add internet calendar > Generic CalDAV”. Enter your calendar URL as well as your username and password to complete the process.
At the moment, there is no carddav implementation directly accessible from the Ubuntu Touch graphical user-interface, so the only way to sync carddav is by using syncevolution + cron. However, there is a simple way to do that with a script that you can run in the terminal or via phablet SSH connection. These instructions work for caldav as well.
- 可以借助这个 `教程 <https://docs.ubports.com/en/latest/userguide/advanceduse/adb.html>`_来启用开发者模式和ADB(或者SSH)连接。
- 下载这个`脚本 <https://gist.github.com/bastos77/0c47a94dd0bf3e394f879c0ff42b7839>`_ (我们将其命名为 dav.sh) 并编辑以下变量:
- server side : CAL_URL, CONTACTS_URL, USERNAME, PASSWORD (of your ownCloud/nextCloud/baikal/SOGO/… server)
- CONTACT and CALENDAR _ NAME / VISUAL_NAME / CONFIG_NAME (it’s more cosmetic)
- CRON_FREQUENCY (for the frequency of synchronization)
- 第61行:用
sudo sh -c "echo '$COMMAND_LINE' > /sbin/sogosync"
, 替换``sudo echo “$COMMAND_LINE” > /sbin/sogosync``, 以避免权限不足的错误
Move the file to your Ubuntu Touch device, either by file manager or with adb:
adb push dav.sh /home/phablet
将手机连接至shell (
adb shell
)或者直接使用手机端的终端,并输入以下内容:chmod +x dav.sh ./dav.sh
为 UBports 做贡献¶
Welcome! You’re probably here because you want to contribute to UBports. The pages you’ll find below here will help you do this in a way that’s helpful to both the project and yourself.
If you’re just getting started, we always need help with thorough bug reporting. If you are multilingual, translations are also a great place to start.
If those aren’t enough for you, see our contribute page for an introduction of our focus groups.
Bug 报告¶
此页面包含的信息可帮助您通过报告 Ubuntu Touch 的可操作错误来帮助我们。 它不包含有关报告应用程序中的错误的信息,大多数情况下,它们在OpenStore中的输入将指定在哪里以及如何执行该操作。
获得最新版本的 Ubuntu Touch¶
这似乎很明显,但却很容易错过。 请转到(设置 - 更新)以确保您的设备没有任何可用的 Ubuntu 更新。 如果没有更新,请继续阅读本指南。 如果有可用更新,请更新您的设备并尝试重现该错误。如果问题仍然出现,请继续阅读本指南。 如果没有出现,请开心一下! 该错误已被修复,您可以继续使用 Ubuntu Touch。
检查是否已报告错误¶
打开 ubuntu-touch 的问题跟踪器
首先,您需要确保您尝试报告的错误在以前没有被报告过。 请先搜索报告的错误。 搜索时,请使用几个词来描述你所看到的错误。 例如,“锁定 屏幕 透明”或“锁定 屏幕 显示活动”。
如果您发现错误报告已存在,请选择 “Add your Reaction” 按钮(看起来像笑脸)并选择 +1(竖起大拇指)。 这表明您也遇到了这个错误。
If the report is missing any of the information specified later in this document, please add it yourself to help the developers fix the bug.
重现您发现的问题¶
Next, find out exactly how to recreate the bug that you’ve found. Document the exact steps that you took to find the problem in detail. Then, reboot your phone and perform those steps again. If the problem still occurs, continue on to the next step. If not…
获取日志¶
We appreciate as many good logs as we can get when you report a bug. In general, /var/log/dmesg and the output of /android/system/bin/logcat are helpful when resolving an issue. I’ll show you how to get these logs.
请参阅 :doc:`设置 ADB </userguide/advanceduse/adb>`以准备就绪。
现在,你可以得到两个最重要的日志。
dmesg¶
dmesg (显示消息 或 驱动消息)命令显示来自内核的调试消息。
- 使用您之前记录的步骤,重现您报告的问题。
- 切换到您能够记录日志的文件夹
- 运行命令:adb shell dmesg > UTdmesg.txt
这个日志现在应该位于您工作目录下的 UTdmesg.txt 文件中,以备日后上传。
制作错误报告¶
恭喜您终于等到提交错误报告的那一刻!提交错误报告需要用到英文 。
首先,打开`问题跟踪器 <https://github.com/ubports/ubuntu-touch>`_ 并点击 “New Issue”。如果没有登录 GitHub 请先登录。
接下来,您需要为您的 bug 命名。 选择一个名称,说明发生了什么,但不要太罗嗦。 四到八个字应该就够了。
现在,请书写您的 bug 报告。好的 bug 报告应该包含以下内容:
- 发生了什么:错误行为的概要
- 我想要发生的事情:如果没有错误,应该发生的事情的概要
- 重现的步骤:您之前已经写下了这些,对吧?
- 日志:请通过单击并将其拖入 GitHub Issue 来附加日志。
- 软件版本:进入(设置 - 关于)并列出出现在此屏幕的“操作系统”那一行中的内容。这还包括您在此手机上安装 Ubuntu 时使用的发行频道。
一旦您完成了 bug提交,将无法自行添加标签,因此请不要忘记在说明中说明您遇到问题的设备,以便维护者稍后可以轻松添加正确的标签。
A developer or QA-team member will confirm and triage your bug, then work can begin on it. If you are missing any information, you will be asked for it, so make sure to check in often!
质量保证¶
This page explains how to help the UBports QA team, both as an official member or a new contributor. Please also read the issue tracking and bugreporting guides to better understand the workflow. For real-time communication, you can join our telegram group.
Smoke testing¶
To test the core functionality of the operating system, we have compiled a set of standardized tests. Run these tests on your device to find and report bugs and regressions. It’s usually run on all devices before a new release to make sure no new issues were introduced.
确认错误报告¶
Unconfirmed bugreports are labeld needs confirmation to enable global filtering. Browse through the list, read the bugreports and try to reproduce the issues that are described. If necessary, add missing information or logs, or improve the quality of the report by other means. Leave a comment stating your device, channel, build number and whether or not you were able to reproduce the issue.
If you have write-access to the repository, you can replace the needs confirmation label with bug (to mark it confirmed) or invalid (if the issue is definitely not reproducible). In that case it should be closed.
If you find two issues describing the same problem, leave a comment and try to find their differences. If they are in fact identical, close the newer one and label it duplicate.
测试补丁¶
Pull-requests can be tested using the QA scripts. Run ubports-qa -h
for usage information.
Once the pull-request has been merged, the issue it fixes is moved to the quality assurance column of the GitHub project. Please check if the issues in this column are still present in the latest update on the devel channel, then see if anything else has broken in the update. Check if the developer mentioned specific things to look out for when testing and leave a comment detailing your experience. If you have write-access to the repository, you can move the issue back to In Development (and reopen it) or forward to Release Candidate as specified by the issue tracking guidelines.
最初的问题分类¶
Initial triaging of new issues is done by QA-team members with write-access to the repository. If a new issue is filed, read the report and add the correct labels as specified by the issue tracking guidelines. You can also immediately start confirming the bugreport.
If the new issue has already been reported elsewhere, label it duplicate and close it.
文档¶
小技巧
Documentation on this site is written in ReStructuredText, or RST for short. Please check the RST Primer if you are not familiar with RST.
本页面将指导您编写可在本网站上发布的关于 UBports 项目的优秀文档。
文档指南¶
These rules govern how you should write your documentation to avoid problems with style, format, or linking. If you don’t follow these guidelines, we will not accept your document.
标题¶
All pages must have a document title that will be shown in the table of contents (left sidebar) and at the top of the page.
Titles should be sentence cased rather than Title Cased. For example:
Incorrect casing:
Writing A Good Bug Report
Correct casing:
Writing a good bug report
Correct casing when proper nouns are involved:
Installing Ubuntu Touch on your phone
There isn’t a single definition of title casing that everyone follows, but sentence casing is easy. This helps keep capitalization in the table of contents consistent.
Page titles are underlined with equals signs. For example, the markup for Bug 报告 includes the following title:
Bug reporting
=============
Note that:
- The title is sentence cased
- The title is underlined with equals signs
- The underline spans the title completely without going over
Incorrect examples of titles include:
Incorrect casing
Bug Reporting =============
Underline too short
Bug reporting =====
Underline too long
Bug reporting ================
Headings¶
There are several levels of headings that you may place on your page. These levels are shown here in order:
Page title
==========
Level one
---------
Level two
^^^^^^^^^
Level three
"""""""""""
Each heading level creates a sub-section in the global table of contents tree available when the documentation is built. In the primary (web) version of the documentation, this only shows four levels deep from the top level of the documentation. Please refrain from using more heading levels than will show in this tree as it makes navigating your document difficult. If you must use this many heading levels, it is a good sign that your document should be split up into multiple pages.
目录¶
People can’t navigate to your new page if they can’t find it. Neither can Sphinx. That’s why you need to add new pages to Sphinx’s table of contents.
You can do this by adding the page to the index.rst
file in the same directory that you created it. For example, if you create a file called “newpage.rst”, you would add the line marked with a chevron (>) in the nearest index:
.. toctree::
:maxdepth: 1
:name: example-toc
oldpage
anotheroldpage
> newpage
The order matters. If you would like your page to appear in a certain place in the table of contents, place it there. In the previous example, newpage would be added to the end of this table of contents.
警告¶
Your edits must not introduce any warnings into the documentation build. If any warnings occur, the build will fail and your pull request will be marked with a red ‘X’. Please ensure that your RST is valid and correct before you create a pull request. This is done automatically (via sphinx-build crashing with your error) if you follow our build instructions below.
Line length¶
There is no restriction on line length in this repository. Please do not break lines at an arbitrary line length. Instead, turn on word wrap in your text editor.
贡献流程¶
The following steps will help you to make a contribution to this documentation after you have written a document.
注解
You will need a GitHub account to complete these steps. If you do not have one, click here to begin the process of making an account.
Fork 存储库¶
You can make more advanced edits to our documentation by forking ubports/docs.ubports.com on GitHub. If you’re not sure how to do this, check out the excellent GitHub guide on forking projects.
构建文档¶
If you’d like to build this documentation before sending a PR (which you should), follow these instructions on your local copy of your fork of the repository.
The documentation can be built by running ./build.sh
in the root of this repository. The script will also create a virtual build environment in ~/ubportsdocsenv
if none is present.
If all went well, you can enter the _build/html
directory and open index.html
to view the UBports documentation.
If you have trouble building the docs, the first thing to try is deleting the build environment. Run rm -r ~/ubportsdocsenv
and try the build again. Depending on when you first used the build script, you may need to run the rm
command with sudo
.
Alternative methods to contribute¶
翻译¶
You may find the components of this document to translate at its project in UBports Weblate.
Writing documents not in RST format¶
If you would like to write documents for UBports but are not comfortable writing ReStructuredText, please write it without formatting and post it on the UBports Forum in the relevant section (likely General). Someone will be able to help you revise your draft and write the required ReStructuredText.
Uncomfortable with Git¶
If you’ve written a complete document in ReStructuredText but aren’t comfortable using Git or GitHub, please post it on the UBports Forum in the relevant section (likely General). Someone will be able to help you revise your draft and submit it to this documentation.
Current TODOs¶
This section lists the TODOs that have been included in this documentation. If you know how to fix one, please send us a Pull Request to make it better!
To create a todo, add this markup to your page:
.. todo:
My todo text
待处理
Change the rootstock link to point to UBports once the actuallyfixit PR is merged.
(原始记录 见 /home/docs/checkouts/readthedocs.org/user_builds/docsubportscom-zh-cn/checkouts/translation-testing/porting/installing-16-04.rst,第 28 行。)
翻译¶
尽管英语是所有 UBports 项目的官方基础语言,但我们相信您有权以任何您想要的语言使用它。
我们正在努力实现这一目标,并且您也可以提供帮助。
这有两个级别:
- 一种较为随意的方式,作为志愿者进行翻译。
- 作为一个 UBPorts 正式成员进行翻译,请填写`申请表 <https://ubports.com/survey/start/ubports-membership-application-6>`_加入我们。
翻译工具¶
适合所有人:基于 Web 的翻译工具,称为 Weblate。这是一种推荐方式。
对于高级用户:使用您选择的编辑器和 GitHub 帐户直接处理 .po 文件。每个项目的 .po 文件都在`我们 GitHub 组织<https://github.com/ubports>`_的存储库中。
登录`翻译论坛 <https://forums.ubports.com/category/39/translations>`_ 讨论 Ubuntu Touch 及其核心应用程序的翻译。
方法¶
UBports Weblate¶
You can go to UBports Weblate, click on “Dashboard” button, go to a project, and start making anonymous suggestions without being registered. If you want to save your translations, you must be logged in.
为此,请转到 UBports Weblate 并单击“注册”按钮。 进入“注册”页面后,您会看到两个选项:
- 使用有效的电子邮件地址,用户名和全名注册。 您还需要解决一个简单的验证问题。
- 使用第三方注册信息注册。 目前注册系统支持来自 openSUSE,GitHub,Fedora 和 Ubuntu 的帐户。
登录后,网站内容将会一目了然显示在你面前,您将找到所有你能做的选项和个性化设置。
现在继续。第一步是搜索您选择的项目中是否已存在您的语言。
如果您的语言不适用于特定项目,则可以自行添加。
您可以决定将多少时间用于翻译。 从几分钟到几小时,一切都很重要。
.po 文件编辑器¶
如上所述,您需要一个您所选择的文件编辑器和一个 GitHub 帐户来直接翻译.po文件。
这里有在线的 gettext .po 编辑器和您可以在计算机中安装的编辑器。
你可以选择你想要的任何编辑器,但我们更喜欢只使用自由软件。 有很多纯文本编辑器和工具可供帮助您翻译 .po 文件以在此处列出一个列表。
如果您想直接使用 .po 文件,您肯定知道您在做什么。
翻译团队交流¶
The straightforward and recommended way is to use the forum category that UBports provides for this task.
要使用它,您需要注册,或者如果您已经注册,则需要登录。
The only requirement is to start your post putting down your language in brackets in the “Enter your topic title here” field. For example, [Spanish] How to translate whatever?
仅供参考,有的项目也使用 Telegram 组,还有一些团队仍在使用 Ubuntu Launchpad 框架。
在与团队的互动中,您会找到协调翻译的最佳方式。
许可证¶
All the translation projects, and all your contributions to this project, are under a Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license that you explicitly accept by contributing to the project.
转到该链接以了解这究竟意味着什么。
Preinstalled apps¶
This page will help you get started with developing the apps which are included with Ubuntu Touch.
Core apps¶
Core apps are applications which are included with UBports distributions of Ubuntu Touch and placed in the OpenStore for updates. Core apps are a good “first development” experience within UBports. Many are built with Clickable, an easy to use build and test system for Ubuntu Touch apps. Most core apps can even be built and run without an Ubuntu Touch device!
Which core apps currently exist?¶
A full list of the Ubuntu Touch core apps follows.
Application Name | Store page | Code repository |
---|---|---|
Calculator | Calculator on OpenStore | calculator-app on GitHub |
Calendar | Calendar on OpenStore | calendar-app on GitHub |
Clock | Clock on OpenStore | clock-app on GitHub |
File Manager | File Manager on OpenStore | filemanager-app on GitHub |
Gallery | Gallery on OpenStore | gallery-app on GitHub |
Music | Not yet in OpenStore | music-app on GitHub |
Notes | Notes on OpenStore | notes-app on GitHub |
OpenStore | OpenStore… on OpenStore | openstore-app on GitHub |
Terminal | Terminal on OpenStore | terminal-app on GitHub |
UBports Welcome | UBports Welcome on OpenStore | ubports-app on GitHub |
Weather | Not yet in OpenStore | weather-app on GitHub |
Other preinstalled apps¶
The following appplications are preinstalled in Ubuntu Touch but are not considered core apps. Most of the time these projects must be updated with the system because they use many system services which do not necessarily have a stable API.
These apps may be more difficult to work with, but their repository should contain a document stating how to build and run them on a device.
- Browser (morph-browser on GitHub)
- Contacts (address-book-app on GitHub)
- Camera (camera-app on GitHub)
- External Drives (ciborium on GitHub)
- Media Player (mediaplayer-app on GitHub)
- Messaging (messaging-app on GitHub)
- Phone (dialer-app on GitHub)
- System Settings (system-settings on GitHub)
Instructions for contributing to these applications can be found in their respective repositories.
应用开发¶
Welcome to an open source and free platform under constant scrutiny and improvement by a vibrant global community, whose energy, connectedness, talent and commitment is unmatched. Ubuntu is also the third most deployed desktop OS in the world.
Get started¶
Ubuntu Touch is a fun and vibrant platform for development. Whether you’re a new developer or an experienced one, we have several resources to help you get started.
Ubuntu Touch supports several different types of apps. Native apps are apps with interfaces made using QML or HTML with their behavior defined in JavaScript, C++, Python, or Go. Web apps are special containers to run websites in.
本地应用程序¶
Web 应用程序¶
Ubuntu Web 应用程序是向 Ubuntu 提供在线 Web 应用程序的绝佳方式。
Ubuntu 平台提供了一个高级 Web 引擎容器,用于在 Ubuntu 客户端设备上运行在线应用程序。
Web applications are hosted online. They can be as simple as a website, like an online news site, or they can distribute content like videos. They can also have a rich user interface or use the WebGL extension to deliver games online.
注意:Ubuntu Web 应用程序和 Ubuntu HTML5 应用程序是相似的,但并不相同。两者的主要区别是:Web 应用程序的内容是通过 URL 提供的,而 HTML5 应用程序安装了它们的内容(通常提供 Ubuntu HTML5 图形用户界面), 且 Web 应用程序对平台 API 的访问也有限制。
指南¶
本指南针对融合版 Ubuntu 的 Web 应用程序,即 Ubuntu for Devices(手机和平板电脑)。 Ubuntu 桌面具有此处未涉及的其他 Web 应用程序支持。 在融合版 Ubuntu 上支持 Web 应用程序将继续增长,当然Ubuntu的未来是融合,敬请期待。
指南¶
A web app displays in a webview inside a webapp-container that runs as an Ubuntu app in the Ubuntu/Unity shell.
Taking a closer look:
At the innermost level, there is a website that the developer identifies by URL. The website is rendered and runs in an Oxide webview. Oxide is a Blink/Chrome webview that is customized for Ubuntu. The Oxide webview runs and displays in the webapp-container. The webapp-container is the executable app runtime that is integrated with the Ubuntu/unity shell.
You can launch a webapp from the terminal with::
webapp-container URL
示例:
webapp-container http://www.ubuntu.com
This simple form works, but almost every webapp also uses other features, such as URL containment with URL patterns as described below.
A webapp generally fills the entire app screen space, without the need of the UI controls generally found on standard browsers.
In some cases some navigation controls are appropriate, such as Back and Forward buttons, or a URL address bar. These are added as command line arguments:
--enable-back-forward
Enable the display of the back and forward buttons in the toolbar (at the bottom of the webapp window)--enable-addressbar
Enable the display of the address bar (at the bottom of the webapp window)
Webapp authors often want to contain browsing to the target website. That is, the developer wants to control the URLs that can be opened in the webapp (all other URLs are opened in the browser). This is done with URL patterns as part of the webapp command line.
However, many web apps use pages that are hosted over multiple sites or that use external resources and pages.
However, both containment and access to specified external URLs are implemented with URL patterns provided as arguments at launch time. Let’s take a closer look.
By default, there is no URL containment. Suppose you launch a webapp without any patters and only a starting URL like this::
webapp-container http://www.ubuntu.com
The user can navigate to any URL without limitation. For example, if they click the Developer button at the top, they navigate to developer.ubuntu.com, and it displays in the webapp.
Tip: You can see the URL of the current page by enabling the address bar with --enable-addressbar
.
One often wants to contain users to the site itself. That is, if the website is www.ubuntu.com, it may be useful to contain webapp users only to subpages of www.ubuntu.com. This is done by adding a wildcard URL pattern to the launch command, as follows::
webapp-container --webappUrlPatterns=http://www.ubuntu.com/* http://www.ubuntu.com
--webappUrlPatterns=
indicates a pattern is next- http://www.ubuntu.com/* is the pattern The asterisk is a wildcard that matches any valid sequence of trailing (right-most) characters in a URL
With this launch command and URL pattern, the user can navigate to and open in the webapp any URL that starts with http://www.ubuntu.com/. For example, they can click on the Phone button (http://www.ubuntu.com/phone) in the banner and it opens in the webapp, or the Tablet button (http://www.ubuntu.com/tablet). But, clicking Developer opens the corresponding URL in the browser.
Tip: Make sure to fully specify the subdomain in your starting URL, that is, use http://www.ubuntu.com instead of www.ubuntu.com. Not specifying the subdomain would create an ambiguous URL and thus introduces security concerns. More complex wildcard patterns
You might want to limit access to only some subpages of your site from within the webapp. This is easy with wildcard patterns. (Links to other subpages are opened in the browser.) For example, the following allows access to www.ubuntu.com/desktop/features and www.ubuntu.com/phone/features while not allowing access to www.ubuntu.com/desktop or www.ubuntu.com/phone:
webapp-container --webappUrlPatterns=http://www.ubuntu.com/*/features http://www.ubuntu.com
You can use multiple patterns by separating them with a comma. For example, the following allows access only to www.ubuntu.com/desktop/features and www.ubuntu.com/phone/features::
webapp-container --webappUrlPatterns=http://www.ubuntu.com/desktop/features,http://www.ubuntu.com/phone/features http://www.ubuntu.com
Tip: Multiple patterns are often necessary to achieve the intended containment behavior.
Many URLs have one or more subdomains. (For example, in the following, “developer” is the subdomain: developer.ubuntu.com.) You can allow access to a single subdomain (and all of its subpages) with a pattern like this::
--webappUrlPatterns=http://developer.ubuntu.com/*
However, one usually wants the user to be able to navigate back to the starting URL (and its subpages). So, if the starting URL is http://www.ubuntu.com, a second pattern is needed::
--webappUrlPatterns=http://developer.ubuntu.com/*,http://www.ubuntu.com/*
Putting these together, here’s an example that starts on http://www.ubuntu.com and allows navigation to http://developer.ubuntu.com and subpages and back to http://www.ubuntu.com and subpages::
webapp-container --webappUrlPatterns=http://developer.ubuntu.com/*,http://www.ubuntu.com/* http://www.ubuntu.com
Some URLs have multiple subdomains. For example, www.ubuntu.com has design.ubuntu.com, developer.ubuntu.com and more. You can add access to all subdomains with a wildcard in the subdomain position::
webapp-container --webappUrlPatterns=http://*.ubuntu.com/* http://www.ubuntu.com
Note: An asterisk in the subdomain position matches any valid single subdomain. This single pattern is sufficient to enable browsing to any subdomain and subpages, including back to the starting URL (http://www.ubuntu.com) and its subpages.
Sometimes a site uses https for some of its URLs. Here is an example that allows https and https as access within the webapp to www.launchpad.net (and all subpages due to the wildcard)::
webapp-container --webappUrlPatterns=https?://http://www.launchpad.net/* http://www.launchpad.net
Note: the question mark in https?. This means the preceding character (the ‘s’) is optional. If https is always required, omit the question mark.
The webapp-container accepts many options to fine tune how it hosts various web applications.
See all help with::
webapp-container --help
Note: Only the following options apply to converged Ubuntu.:
--fullscreen Display full screen
--inspector[=PORT] Run a remote inspector on a specified port or 9221 as the default port
--app-id=APP_ID Run the application with a specific APP_ID
--name=NAME Display name of the webapp, shown in the splash screen
--icon=PATH Icon to be shown in the splash screen. PATH can be an absolute or path relative to CWD
--webappUrlPatterns=URL_PATTERNS List of comma-separated url patterns (wildcard based) that the webapp is allowed to navigate to
--accountProvider=PROVIDER_NAME Online account provider for the application if the application is to reuse a local account.
--accountSwitcher Enable switching between different Online Accounts identities
--store-session-cookies Store session cookies on disk
--enable-media-hub-audio Enable media-hub for audio playback
--user-agent-string=USER_AGENT Overrides the default User Agent with the provided one.
Chrome options (if none specified, no chrome is shown by default)::
--enable-back-forward Enable the display of the back and forward buttons (implies --enable-addressbar)
--enable-addressbar Enable the display of a minimal chrome (favicon and title)
Note: The other available options are specific to desktop webapps. It is recommended to not use them anymore.
Some websites check specific portions of the web engine identity, aka the User-Agent string, to adjust their presentation or enable certain features. While not a recommended practice, it is sometimes necessary to change the default string sent by the webapp container.
To change the string from the command line, use the following option::
--user-agent-string='<string>' Replaces the default user-agent string by the string specified as a parameter
The webapp experience is contained and isolated from the browser data point of view. That is webapps do not access data from any other installed browser, such as history, cookies and so on. Other browser on the system do not access the webapp’s data. Storage
W3C allows apps to use local storage, and Oxide/Webapp-container supports the main standards here: LocalStorage, IndexedDB, WebSQL.
快速开始¶
There are several tools to help you package and deploy your webapp to your device:
- Webapp creator application available from the openstore
- Clickable CLI
调试你的 Web 应用¶
This guide give you some tips to help you debug your webapp.
调试 Web 应用程序¶
Most web-devs will probably want do most of their coding and debugging in the usual browser environment. The Ubuntu Touch browser is compliant with modern web standards, and most webapps will just work without further changes.
For those (hopefully) rare cases where further debugging is needed, there are two ways to gain further information on the failure.
查看日志¶ If you are comfortable in a CLI environment, most Javascript errors will leave an entry in the app log file:
.cache/upstart/application-click-[YOUR_APP_NAME.AUTHOR_NAME..].log在浏览器中调试¶ The default Ubuntu Touch browser is based on the Blink technology that is also used in Chrome/Chromium. By starting the browser in a special mode, you have access to the regular Chrome-style debugger.
On your phone, start the browser in inspector mode::
ubuntu-app-launch webbrowser-app --inspector现在打开您的计算机,开启 Chrome/Chromium 浏览器,地址栏中输入
http://YOUR_UT_IP_ADDRESS:9221
。
Community¶
Have questions that aren’t answered in the docs or want to chat with other Ubuntu Touch developers? Join our app dev Telegram group or chat with us on the UBports app dev forum.
Tools¶
Clickable is a meta-build system for Ubuntu Touch applications that allows you to compile, build, test and publish click
packages and provides various templates to get you started with app development. It is currently the easiest and most convenient way of building click packages for Ubuntu Touch. You can use any code editor or IDE that you choose and build your apps from the commandline with Clickable.
Alternatively there is the old Ubuntu SDK IDE. Be aware that it is no longer supported by Canonical, and UBports has chosen to not support it either due to lack of manpower.
You can still install the SDK IDE in Ubuntu 16.04, but it is not guaranteed to work correctly. You can use the following commands to install:
sudo add-apt-repository ppa:ubuntu-sdk-team/ppa
sudo apt update && sudo apt dist-upgrade
sudo apt install ubuntu-sdk
sudo reboot # or logout/login
Guides¶
Get started building your first app or learn about advanced concepts with our Developer guides.
Developer guides¶
We are currently working on expanding our list of developer guides. In the mean time we recommend the Ubuntu Touch Programming Course.
If you are interested in helping create developer guides check out our GitLab Project.
应用开发指南¶
Playground¶
In a completely free and open source community, it is natural to have community members exploring the limits of the platform in many many directions. In this section you will find links to external resources that do exactly that: Explore. The purpose of this list is to show the unlimited possibilities of an open platform like Ubuntu Touch.
注解
The resources listed here do not necessarily represent the officially endorsed way of developing applications for Ubuntu Touch, but are interesting experiments.
The content hub - tips and tricks¶

Content Hub Share Page
On Ubuntu Touch the apps are confined. The way of sharing files between them is through the Content Hub, a part of the system that takes care of file import, export and sharing.
Different ways of sharing the content¶
As we can see in the Content Hub documentation, there are several ways of handling the file to be shared:
ContentHandler.Source
(The app selected is going to be the source of the file imported)ContentHandler.Destination
(The app selected is going to be the destination of the file exported)ContentHandler.Share
(The app selected is going to be the app from witch the file is going to be shared from)
Importing¶

Webapp Creator on the OpenStore
Looking into the code of Webapp Creator, we’ll find the code to import an image to be used as icon. Tapping on the place holder will open the Content Hub that will let us choose from where to import the image (see the Webapp Creator source code)
ContentPeerPicker {
anchors { fill: parent; topMargin: picker.header.height }
visible: parent.visible
showTitle: false
contentType: picker.contentType //ContentType.Pictures
handler: picker.handler //ContentHandler.Source
ContentPeerPicker
is the element that shows the apps.
var importPage = mainPageStack.push(Qt.resolvedUrl("ImportPage.qml"),{"contentType": ContentType.Pictures, "handler": ContentHandler.Source})
contentType
is passed in Main.qml as ContentType.Pictures. So, we will only see apps from which we only can import images. handler
is passed in the same line as ContentHandler.Source. As we want to import an image from the app selected in the Content Hub.
Exporting¶

Gelek in the OpenStore
In Gelek, we are going to end with some saved games that we want to save in our device or share with ourselves (in Telegram and then save them to our computer).

Tapping on the download icon we will get a Content Hub to save the game file (which is actually an export).
The game file is a file of type glksave
. We will tell Content Hub that we are sending a file of type All
(see the Install Page code).
ContentPeerPicker {
anchors { fill: parent; topMargin: picker.header.height }
visible: parent.visible
showTitle: false
contentType: ContentType.All
handler: ContentHandler.Destination
onPeerSelected: {
contentType
is ContentType.All
, so we will only see apps which are able to receive unmarked file types. handler
is ContentHandler.Destination
, so the app selected should store the saved game.
Tapping on the File Manager we will save the saved game in the folder we choose.
Sharing¶
Similarly, tapping on the share icon will allow us to send the saved game through Telegram to ourselves (see the Webapp Creator Import Page source code).
ContentPeerPicker {
anchors { fill: parent; topMargin: picker.header.height }
visible: parent.visible
showTitle: false
contentType: picker.contentType //ContentType.Pictures
handler: picker.handler //ContentHandler.Source
onPeerSelected: {
The only difference between this and the previous code is that handler
is ContentHandler.Share
Wait a minute. Why the different apps?¶

Content Hub: Export vs Share
Each developer can decide the rules each app would follow in relation to the Content Hub. Why the OpenStore is shown as the destination of an export?
Let’s check its manifest.json
"hooks": {
"openstore": {
"apparmor": "openstore/openstore.apparmor",
"desktop": "openstore/openstore.desktop",
"urls": "openstore/openstore.url-dispatcher",
"content-hub": "openstore/openstore-contenthub.json"
}
},
The above code defines that the hooks for the app named "openstore"
in relation to the "content-hub"
should follow the rules defined in openstore-contenthub.json
{
"destination": [
"all"
]
}
This means, the OpenStore will be the destination for all ContentTypes
.
What about uMatriks? Let’s see its content-hub.json
{
"destination": [
"pictures",
"documents",
"videos",
"contacts",
"music"
],
"share": [
"pictures",
"documents",
"videos",
"contacts",
"music"
],
"source": [
"pictures",
"documents",
"videos",
"contacts",
"music"
]
}
So, with this example, uMatriks will be able to be the destination, source and share app for all kinds of ContentType
.
What about the other hooks in the manifest.json
? That is discussed in the next guide.
Importing from Content Hub and URLdispatcher¶

In the previous guide we have seen a little bit about how Content Hub works. In this guide we will see how URLdispatcher
works and how to handle imported data from the Content Hub.
Handle data from the Content Hub¶

OpenStore app from open-store.io
One of the easiest ways of testing an app, is to send a test click to yourself on Telegram, and opening that click file with the OpenStore through the Content Hub:

If we tap on the OpenStore app, it will be opened and it will ask if we want to install the click file. Let’s take a look into the Main.qml code of the app to see how it is done:
Connections {
target: ContentHub
onImportRequested: {
var filePath = String(transfer.items[0].url).replace('file://', '')
print("Should import file", filePath)
var fileName = filePath.split("/").pop();
var popup = PopupUtils.open(installQuestion, root, {fileName: fileName});
popup.accepted.connect(function() {
contentHubInstallInProgress = true;
PlatformIntegration.clickInstaller.installPackage(filePath)
})
}
}
Do you see that Connections element that targets the ContentHub? When it receives the signal onImportRequested, it will take the url of the data sent from the Content Hub (transfer.items[0].url
is the url of the first data sent) and open a PopUp
element to let the user install the click.
What about the URLdispatcher?¶
The URL dispatcher is a piece of software, similar to the Content Hub, that makes our life easier trying to choose the correct app for a certain protocol. For example: We probably want to open the web browser when tapping on an http protocol. If we tap on a map link it is handy to open it with uNav or to open a twitter link in the Twitter app! How does that work?
The URLdispatcher
selects which app (according to their manifest.json
) will open a certain link.

Let’s see how our navigation app looks inside. uNav’s manifest shows special hooks for the URLdispatcher
in its manifest.json code:
1 [
2 {
3 "protocol": "http",
4 "domain-suffix": "map.unav.me"
5 },
6 {
7 "protocol": "http",
8 "domain-suffix": "unav-go.github.io"
9 },
10 {
11 "protocol": "geo"
12 },
13 {
14 "protocol": "http",
15 "domain-suffix": "www.openstreetmap.org"
16 },
17 {
18 "protocol": "http",
19 "domain-suffix": "www.opencyclemap.org"
20 },
21 {
22 "protocol": "https",
23 "domain-suffix": "maps.google.com"
24 }
25 ]
This means that a link that looks like http://map.unav.me/xxxxx,xxxxx will be opened in uNav. And that’s defined in lines 2 and 3, where it looks for protocol http followed by map.unav.me.
Also, a URI formatted geo:xxx,xxx should open in uNav, as it’s defined in line 11.
And how do we manage the received URL?¶
After the URLdispatcher
sends the link to the correspondent app, we need to handle that URL or URI in the targeted app. Let’s see how to do that:
In the main qml file, we need to add some code to know what to do with the dispatched URL. First add an Arguments element that holds the URL, as is done, for example, in the Linphone app. Also, we add connection to the URI Handler with a Connection element with UriHandler
as a target.
Arguments {
id: args
Argument {
name: 'url'
help: i18n.tr('Incoming Call from URL')
required: false
valueNames: ['URL']
}
}
Connections {
target: UriHandler
onOpened: {
console.log('Open from UriHandler')
if (uris.length > 0) {
console.log('Incoming call from UriHandler ' + uris[0]);
showIncomingCall(uris[0]);
}
}
}
This code will manage a URI in the form linphone://sip:xxx@xxx.xx
when the app is opened. But what do we need to do to handle this link when the app is closed?
We need to add a little bit extra code that will cover two cases: 1) We receive one URL 2) We receive more than one URL
Component.onCompleted: {
//Check if opened the app because we have an incoming call
if (args.values.url && args.values.url.match(/^linphone/)) {
console.log("Incoming Call on Closed App")
showIncomingCall(args.values.url);
} else if (Qt.application.arguments && Qt.application.arguments.length > 0) {
for (var i = 0; i < Qt.application.arguments.length; i++) {
if (Qt.application.arguments[i].match(/^linphone/)) {
showIncomingCall(Qt.application.arguments[i]);
}
}
}
//Start timer for Registering Status
checkStatus.start()
}
What happens if more than one app has the same URL type defined?¶
A very good question. What happens if we tap on a Twitter link? How is such a URL handled by the URLdispatcher
as protocol http
or the protocol http://twitter
?
What happens if two apps have the same defined protocol?
Now it’s time to do some tests and share the results in the next guide.
Writable directories¶
App confinement is part of the Ubuntu Touch security concept. Data can be exchanged between apps only according to the AppArmor policies, mainly using the ContentHub. This being said, apps can only read and write files that are located in one of three app specific directories explained in this guide.
Standard Paths¶
Besides the write access to the app directories explained below, the app can write debug messages into the app log file located at /home/phablet/.cache/upstart/application-click-<fullappname>_<appname>_<version>.log
. To append messages to the log file, use the Qt debug functions.
Config¶
Path: /home/phablet/.config/<fullappname>/
This is the place to store configurations files to. The music app for example stores its configuration to /home/phablet/.config/com.ubuntu.music/com.ubuntu.music.conf
.
Cache¶
Path: /home/phablet/.cache/<fullappname>/
This is the place to cache data for later use. The cache is also used by the Content Hub. Files that have been shared with the music app for example can be found in /home/phablet/.cache/com.ubuntu.music/HubIncoming/
.
App data¶
Path: /home/phablet/.local/share/<fullappname>/
This is where your app stores any data. The music app for example stores its data bases to /home/phablet/.local/share/com.ubuntu.music/Databases/
.
Using Standard Paths in C++¶
The Qt header QStandardPaths
provides the app’s writable locations:
#include <QStandardPaths>
...
QString configPath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
QString appDataPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
...
Using Standard Paths in QML¶
The Qt module Qt.labs.platform provides the QStandardPaths in QML. Unfortunately it is not available on Ubuntu Touch, yet. Probably you don’t want to ship that module with your app. Instead, you could simply let your C++ plugin provide the paths to your QML part. Therefore, add these methods to your plugin class:
#include <QStandardPaths>
...
Q_INVOKABLE QString configPath()
{
return QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
}
Q_INVOKABLE QString cachePath()
{
return QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
}
Q_INVOKABLE QString appDataPath()
{
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
}
...
Assuming the name of your plugin is MyPlugin, you can access these paths in QML:
Label
{
text: MyPlugin.configPath()
}
Label
{
text: MyPlugin.cachePath()
}
Label
{
text: MyPlugin.appDataPath()
}
Publishing¶
After you are done building your app, distribute it on the OpenStore with our Publishing guides.
App publishing guides¶
We are currently working on expanding our list of publishing guides. In the mean time you can get started over at the OpenStore’s submission page.
If you are interested in helping create developer guides check out our GitLab Project.
Documentation¶
More Documentation¶
Platform¶
- Content Hub
- Each application can expose content outside its sandbox, giving the user precise control over what can be imported, exported or shared with the world and other apps.
- 推送通知
- By using a push server and a companion client, instantly serve users with the latest information from their network and apps.
- URL dispatcher
- Help users navigate between your apps and drive their journey with the URL dispatcher.
- 在线账户
- Simplify user access to online services by integrating with the online accounts API. Accounts added by the user on the device are registered in a centralized hub, allowing other apps to re-use them.
AppArmor Policy Groups¶
本文档包含 Ubuntu Touch 可用策略组的完整列表,以及它们为您的应用程序提供访问权限的说明。
Each entry follows this format
Title
-----
Description: Description from apparmor file
Usage: How common it is to use this policy (from apparmor file)
Optional longer description
权限使用政策将决定您的应用能否进入OpenStore。仅包括一般权限的应用通常会被立即接受,包含保留权限的则需要人工审核。
描述:可播放音频(允许通过媒体播放器播放远程内容)
用法:普通
The audio policy is needed for your app to play audio via pulseaudio or media-hub. The permission also gives it the ability to send album art to the thumbnailer service, which is then shown on the sound indicator.
Description: Use bluetooth (bluez5) as an administrator.
用法:保留
这个权限允许你无限制的使用蓝牙设备。这可用于蓝牙管理程序。同时这也是开发安全的蓝牙API的基石。
描述:可访问相机。
用法:保留
Calendar grants access to the Evolution dataserver’s calendar and alarms APIs. It also grants access to sync-monitor.
This policy is reserved since it grants free access to all calendars on the device at any time. The legacy bug about this situation is LP #1227824 .
Description: Can access coarse network connectivity information
用法:普通
连接权限允许应用了解粗略的设备连线情况。包括是否连接到互联网和连接的方式(使用Wifi或移动数据)。
描述:可以从其他应用程序请求/导入数据
用法:普通
Using the content_exchange policy allows your app to be a consumer of content on content-hub.
描述:可对文档文件进行读写。此策略组保留给某些应用程序,例如文档查看器。开发人员通常应该使用内容交换策略组和应用编程接口来访问文档文件。
用法:保留
此策略允许应用程序读取和写入用户主目录和外部设备中的“文档”文件夹。
描述:可以读取所有文档文件。 此策略组保留用于某些应用程序,例如文档查看器。 开发人员通常应使用内容交换策略组和应用编程接口来访问文档文件。
用法:保留
此策略允许应用程序读取用户主目录和外部媒体中的“文档”文件夹。
Description: Can read and write to music files. This policy group is reserved for certain applications, such as music players. Developers should typically use the content_exchange policy group and API to access music files instead.
用法:保留
music_files 策略组允许应用程序读写用户主文件夹或外部媒体上的音乐目录。
Description: Can read all music files. This policy group is reserved for certain applications, such as music players. Developers should typically use the content_exchange policy group and API to access music files instead.
用法:保留
The music_files_read policy group allows an app to read the Music directories in the user’s home folder or on external media.
描述:可读写图片文件。 此策略组保留用于某些应用程序,例如相册类应用。 开发人员通常应使用 content_exchange 策略组和 API 来访问图片文件。
用法:保留
The picture_files policy group allows an app to read and write to the Pictures directories in the user’s home folder or on external media.
Description: Can read all picture files. This policy group is reserved for certain applications, such as gallery applications. Developers should typically use the content_exchange policy group and API to access picture files instead.
用法:保留
The picture_files_read policy group allows an app to read the Pictures directories in the user’s home folder or on external media.
Description: Can use UserMetrics to update the InfoGraphic
用法:普通
Allows an app to write metrics to the UserMetrics service so they can be displayed on the InfoGraphic.
Description: Can read and write to video files. This policy group is reserved for certain applications, such as gallery applications. Developers should typically use the content_exchange policy group and API to access video files instead.
用法:保留
video_files 策略组允许应用程序读取和写入用户主文件夹或外部媒体上的视频目录。
描述:可以读取所有视频文件。 此策略组保留用于某些应用程序,例如相册应用程序。开发人员通常应使用content_exchange 策略组和 API 来访问视频文件。
用法:保留
The video_files_read policy group allows an app to read the Videos directories in the user’s home folder or on external media.
描述:可使用 UbuntuWebview
用法:普通
The webview policy group allows apps to embed a web browser view.
Click package¶
Every click
application package must embed at least 3 files:
manifest.json
文件Contains application declarations such as application name, description, author, framework sdk target, and version.
manifest.json
文件示例:{ "name": "myapp.author", "title": "App Title", "version": "0.1" "description": "Description of the app", "framework": "ubuntu-sdk-15.04", "maintainer": "xxxx <xxx@xxxx>", "hooks": { "myapp": { "apparmor": "apparmor.json", "desktop": "app.desktop" } }, }
- AppArmor profile policy file
- Contains which policy the app needs to work properly. See Security and app isolation below for more information on this file.
.desktop
文件启动器文件将告诉 Ubuntu Touch 如何启动应用程序,在主屏幕上显示什么样的名称和图标,以及其他一些属性。
``app.desktop``示例:
[Desktop Entry] Name=Application title Exec=qmlscene qml/Main.qml Icon=assets/logo.svg Terminal=false Type=Application X-Ubuntu-Touch=true
非详尽的属性列表:
- Name:显示在 Dash 中的应用程序标题
- Exec:可执行文件路径
- Icon:显示的图标路径
- Terminal:
false
if will not run in terminal window - Type: Specifies the type of the launcher file. The type can be Application, Link or Directory.
- X-Ubuntu-Touch:
true
to make the app visible - X-Ubuntu-XMir-Enable:
true
if your app is built for X
All Ubuntu apps and scopes are confined respecting AppArmor access control mechanism (see Application Confinement) , meaning they only have access to their own resources and are isolated from other apps and parts of the system. The developer must declare which policy groups are needed for the app or scope to function properly with an apparmor .json
file.
Example apparmor.json
file:
{
"policy_version": 1.3,
"policy_groups": [
"networking",
"webview",
"content_exchange"
]
}
For a full list of available policy groups, see AppArmor Policy Groups.
Sample apps¶
Learn more about app development by digging into our Sample apps.
Sample Apps¶
We are currently working on expanding our list of sample apps. In the mean time many apps on the OpenStore are open source and can be used as a reference.
If you are interested in helping create sample apps check out our GitLab Project.
Preinstalled apps¶
The Preinstalled apps page has information on developing the apps which are included with Ubuntu Touch.
System software development¶
This section has various documents which will teach you how to work with the packages included with Ubuntu Touch. This includes the Ubuntu UI Toolkit, Unity8, and all of the other software that makes Ubuntu Touch what it is.
This section does not cover most of the applications preinstalled on Ubuntu Touch. See Preinstalled apps for more information on those.
System Software guides¶
These guides will give you general instructions on building and testing your own changes to Ubuntu Touch system software. They are not not an exhaustive reference on everything you will come across during development, but they are a great starting point.
注解
If you get stuck at any point while going through this documentation, please contact us for help via the UBports Forum or your preferred communication medium.
Making changes and testing locally¶
On this page you’ll find information on how to build Ubuntu Touch system software for your device. Most of the software preinstalled on your Ubuntu Touch device is shipped in the device image in the form of a Debian package. This format is used by several Linux distributions, such as Debian, Ubuntu, and Linux Mint. Plenty of documentation on deb packages is available, so we won’t be covering it here. Besides, in most cases you’ll find yourself in need of modifying existing software rather than developing new packages from scratch. For this reason, this guide is mostly about recompiling an existing Ubuntu Touch package.
There are essentially two ways of developing Ubuntu Touch system software locally:
We’ll examine both methods, using address-book-app (the Contacts application) as an example.
We only recommend developing packages using a device with Ubuntu Touch installed from the devel channel. This ensures that you are testing your changes against the most current state of the Ubuntu Touch code.
警告
Installing packages has a risk of damaging the software on your device, rendering it unusable. If this happens, you can reinstall Ubuntu Touch.
Cross-building with crossbuilder¶
Crossbuilder is a script which automates the setup and use of a crossbuild environment for Debian packages. It is suitable for developers with any device since the code compilation occurs on your desktop PC rather than the target device. This makes Crossbuilder the recommended way to develop non-trivial changes to Ubuntu Touch.
注解
Crossbuilder requires a Linux distribution with lxd
installed and the unprivileged commandset available. In other words, you must be able to run the lxc
command. If you are running Ubuntu on your host, Crossbuilder will set up lxd
for you.
Start by installing Crossbuilder on your host:
cd ~
git clone https://github.com/ubports/crossbuilder.git
Crossbuilder is a shell script, so you don’t need to build it. Instead, you will need to add its directory to your PATH
environment variable, so that you can execute it from any directory:
echo "export PATH=$HOME/crossbuilder:$PATH" >> ~/.bashrc
# and add it to your own session:
export PATH="$HOME/crossbuilder:$PATH"
Now that Crossbuilder is installed, we can use it to set up LXD:
crossbuilder setup-lxd
If this is the first time you have used LXD, you might need to reboot your host once everything has completed.
After LXD has been set up, move to the directory where the source code of your project is located (for example, cd ~/src/git/address-book-app
) and launch Crossbuilder:
crossbuilder
Crossbuilder will create the LXD container, download the development image, install all your package build dependencies, and perform the package build. It will also copy the packages over to your target device and install them if it is connected (see 通过 adb 访问 shell to learn more about connecting your device). The first two steps (creating the LXD image and getting the dependencies) can take a few minutes, but will be executed only the first time you launch crossbuilder for a new package.
Now, whenever you change the source code in your git repository, the same changes will be available inside the container. The next time you type the crossbuilder
command, only the changed files will be rebuilt.
Unit tests¶
By default crossbuilder does not run unit tests; that’s both for speed reasons, and because the container created by crossbuilder is not meant to run native (target) executables: the development tools (qmake/cmake, make, gcc, etc.) are all run in the host architecture, with no emulation (again, for speed reasons). However, qemu emulation is available inside the container, so it should be possible to run unit tests. You can do that by getting a shell inside the container:
crossbuilder shell
Then find the unit tests and execute them. Be aware that the emulation is not perfect, so there’s a very good chance that the tests will fail even when they’d otherwise succeed when run in a proper environment. For that reason, it’s probably wiser not to worry about unit tests when working with crossbuilder, and run them only when not cross-compiling.
Building on the device itself¶
This is the fastest and simplest method to develop small changes and test them in nearly real-time. Depending on your device resources, however, it might not be possible to follow this path: if you don’t have enough free space in your root filesystem you won’t be able to install all the package build dependencies; you may also run out of RAM while compiling.
警告
This method is limited. Many devices do not have enough free image space to install the packages required to build components of Ubuntu Touch.
In this example, we’ll build and install the address-book-app. All commands shown here must be run on your Ubuntu Touch device over a remote shell.
You can gain a shell on the device using 通过 adb 访问 shell or 通过 ssh 访问 shell. Remount the root filesystem read-write to begin:
sudo mount / -o remount,rw
Next, install all the packages needed to rebuild the component you want to modify (the Contacts app, in this example):
sudo apt update
sudo apt build-dep address-book-app
sudo apt install fakeroot
Additionally, you probably want to install git
in order to get your app’s source code on the device and later push your changes back into the repository:
sudo apt install git
Once you’re finished, you can retrieve the source for an app (in our example, the address book) and move into its directory:
git clone https://github.com/ubports/address-book-app.git
cd address-book-app
Now, you are ready to build the package:
DEB_BUILD_OPTIONS="parallel=2 debug" dpkg-buildpackage -rfakeroot -b
The dpkg-buildpackage
command will print out the names of generated packages. Install those packages with dpkg
:
sudo dpkg -i ../<package>.deb [../<package2>.deb ...]
Note, however, that you might not need to install all the packages: generally, you can skip all packages whose names end with -doc
or dev
, since they don’t contain code used by the device.
Next steps¶
Now that you’ve successfully made changes and tested them locally, you’re ready to upload them to GitHub. Move on to the next page to learn about using the UBports CI to build and provide development packages!
Uploading and testing with ubports-qa
¶
The UBports build service is capable of building Ubuntu Touch packages and deploying them to the UBports repository. This capability is offered to any developer who wishes to take advantage of it.
This guide assumes that you have a cursory understanding of using Git and making Pull Requests on GitHub.
To use the UBports build service, make sure you understand our branch naming convention. It is required that you follow the convention for deb-packages for CI to build your package correctly.
Fork the repository¶
The first step to make a change to any repository you don’t have write access to is to fork it. Open your desired repository on GitHub and click the “Fork” button in the upper right corner. If offered, select an appropriate account to fork the repository to. Then, clone your fork to your computer.
Now you’re ready to make changes!
Make and commit changes¶
Now that you have the package source downloaded, you can make your desired changes.
Before changing anything, make sure you have checked out the branch you want to work from (probably xenial
, assuming you are making changes for the phone images). Then, create a new branch abiding by the branch naming convention.
After making your changes, commit them with a descriptive commit message stating what is wrong and why your changes fix that problem.
You have successfully created and committed your changes. Before pushing your changes, we’ll want to make sure your device will install them.
Update the debian/changelog
file¶
Generally, apt
will not install a new package from any repository if it has a lower (or the same) version number as the package it replaces. Users may also want to see the changes that are included in a new version of a package. For that reason, we will need to update the package changelog to add a new version.
注解
This is not an exhaustive reference of the debian/changelog
format. See deb-changelog(5) for more information.
Determine a new version number¶
To start, figure out what the current version numbering for the package is:
head debian/changelog
This will return a few lines, but the first is the most important to us:
morph-browser (0.24+ubports2) xenial; urgency=medium
The part inside the parentheses (0.24+ubports2)
is our version number. It consists of several parts:
- The
0.24
is the upstream version number, the version that the original project maintainers give to the release we are using. For most UBports projects, the repository you’ll be working on is the original project code. This makes UBports the “upstream” of that project.
If you are making large changes to the repository and UBports is the upstream, you should increment the first part of the version number before the plus (+) and reset the distribution suffix. In our example above, you would make this new version number:
0.25+ubports0
If you are making changes only to the package build (files in the debian/
folder), it is best to only increment the version suffix:
0.24+ubports3
注解
If you find a package which does not seem to follow the above versioning format, please contact us to ask how to proceed.
Write the changelog entry¶
Now it is time to write your changelog entry! Start with the following template:
PACKAGE-NAME (VERSION) DISTRIBUTION; urgency=medium
* CHANGES
-- NAME <EMAIL> DATETIME
If you open the debian/changelog
file, you’ll find that every entry follows this format. This helps everyone (including computers) read and understand the contents. This is used, for example, to name the output package correctly for every package version.
Let’s assume I, John Doe, am making a packaging change to the morph-browser
package for Ubuntu Touch. I’ll replace the different all-caps placeholders above in the following way:
PACKAGE-NAME is replaced with
morph-browser
VERSION is replaced with
0.24+ubports3
(which we determined above)DISTRIBUTION is replaced with
xenial
CHANGES is replaced with the changes I made in this release. This will include summarized information from my commit messages along with the bugs fixed by those changes. If I’ve fixed multiple bugs, I’ll create multiple bullet points.
NAME is replaced with my name,
John Doe
EMAIL is replaced with my e-mail,
john.doe@example.com
.注解
You should not use a “noreply” e-mail as your EMAIL for package changelog entries.
DATETIME is replaced with the date and time I made this changelog entry in RFC2822/RFC5322 format. The easiest way to retrieve this is by running the command
date -R
in a terminal.
Note that no line in your changelog entry should exceed 80 characters in length.
With that, my new changelog entry follows:
morph-browser (0.24+ubports3) xenial; urgency=medium
* Add the new "Hello world" script to the package. Fixes
https://github.com/ubports/morph-browser/issues/404.
* Fix whitespace and formatting in the format.qml file
-- John Doe <john.doe@example.com> Mon, 29 Oct 2018 12:53:08 -0500
Add your new changelog entry to the top of the debian/changelog
file and commit it with the message “Update changelog”. Push your changes. Now you’re ready to make your Pull Request!
Create your pull request¶
A pull request asks UBports maintainers to review your code changes and add them to the official repository. We’ll create one now.
Open your fork of the repository on GitHub. Navigate to the branch that you just pushed to using the “Branch” selector:

Once you’ve opened your desired branch, click the “New pull request” button to start your pull request. You’ll be taken to a page where you can review your changes and create a pull request.
Give your pull request a descriptive title and description (include links to reference bugs or other material). Ensure that the “base” branch is the one you want your changes to be applied to (likely xenial
), then click “Create pull request”.
With your pull request created, we can move on to testing your changes using the UBports build service!
Test your changes¶
Once your pull request is built (a green check mark appears next to your last commit), you are ready to test your changes on your device.
注解
If a red “X” appears next to your last commit, your pull request has failed to build. Click the red “X” to view the build log. Until your build errors are resolved, your pull request cannot be installed or accepted.
We’ll use ubports-qa
to install your changes. Take note of your pull request’s ID (noted as #number
after the title of the pull request) and follow these steps to install your changes:
- Ensure your device is running the newest version of Ubuntu Touch from the
devel
channel. - Get shell access to your device using 通过 adb 访问 shell or 通过 ssh 访问 shell.
- Run
sudo ubports-qa install REPOSITORY PR
, replacingREPOSITORY
with the name of the repository you have submitted a PR to (morph-browser
for example) and PR with the number of your pull request (without the#
).
ubports-qa
will automatically add the repository containing your changed software and start the installation for you. All you will need to do is check the packages it asks you to install and say “yes” if they are correct.
If ubports-qa
fails to install your packages, run it again with the -v
flag (for example, ubports-qa -v install ...
). If it still fails, submit the entire log (starting from the $
before the ubports-qa
command) to Ubuntu Pastebin and contact us for help.
Once ubports-qa
is finished, test your changes to ensure they have fixed the original bug. Add the ubports-qa
command to your pull request, then send the link to the pull request to other developers and testers so they may also test your changes.
When getting feedback from your testers, be sure to add the information to the pull request (or ask them to do it for you) so that everyone is updated on the status of your code.
Every time you make a change and push it to GitHub, it will trigger a new build. You can run sudo ubports-qa update
to get the freshest changes every time this happens.
Celebrate!¶
If you and your testers are satisfied with the results of your pull request, it will be merged. Following the merge, the UBports build service will build your code and deploy it to Ubuntu Touch users worldwide.
Thank you for your contribution to Ubuntu Touch!
System Software reference¶
This section includes reference guides on how different parts of the Ubuntu Touch system interact to create the user experience.
There’s nothing here yet, but maybe you’d like to add some reference material? Check out our guide to contributing to documentation to learn more.
移植信息¶
注解
If you are looking for information on installing Ubuntu Touch on a supported device, or if you would like to check if your device is supported, please see this page.
本节将向您介绍将 Ubuntu Touch 移植到 Android 设备的一些细节。
Before you begin, you’ll want to head over to the Halium porting guide and get your systemimage
built without errors. Once you’re at the point of installing a rootfs, you can come back here.
Start at 构建 halium-boot if you’d like to install the UBports Ubuntu Touch 16.04 rootfs.
构建 halium-boot¶
Halium-boot是 Halium 项目新推出的启动映像,用以取代 hybris-boot。 我们将为 Ubuntu Touch 构建和使用它。
修复挂载¶
Halium-boot的``mount``不知道SELinux的内容。 如果您的设备的``fstab``文件包含任何内容,则它们所在的分区将无法安装,并且您的端口将无法正常工作。
Halium-boot这个过程的第一步是确定你的fstab实际上在哪里。 对于大多数人来说,这是在``BUILDDIR / device / MANUFACTUER / CODENAME / rootdir / etc``中,它被命名为``fstab.qcom``或``fstab.devicename``。 打开文件进行编辑。
如果 “data” 或 “userdata” 分区的类型是 f2fs
,则需要将其更改为` ext4` 。
打开文件后,从文件中的所有块设备中删除所有``context =``选项。 该选项将从文本``context =``开始,并以逗号后面的逗号结束。
例如,这一行``ro,nosuid,nodev,context = u:object_r:firmware_file:s0,barrier = 0``应该变为``ro,nosuid,nodev,barrier = 0``
保存并退出。
修改内核配置¶
Ubuntu Touch需要与Halium略有不同的内核配置,包括启用应用甲。 幸运的是,我们有一个很好的脚本用于此目的,check-kernel-config
。 它包含在halium-boot存储库中。 只需在您的配置上运行它,如下所示:
./halium/halium-boot/check-kernel-config path/to/my/defconfig -w
你可能要做两次。 它可能会解决问题。 然后,运行没有`-w``标志的脚本,看看是否还有错误。 如果有,请手动修复它们。 完成后,再次运行不带“-w``标志的脚本,以确保一切正确。
构建镜像¶
一旦 halium-boot 到位,您就可以非常简单地构建它。 但由于我们的改动了它,您还需要重建 system.img。
cd
(切换到)您的 Halium 编译目录(BUILDDIR)source build/envsetup.sh
- 运行``breakfast``或``lunch``,无论您使用哪种设备
mka halium-boot
mka systemimage
继续¶
现在您已经构建了 halium-boot,请移步到 在 Halium 上构建 Ubuntu Touch 16.04 镜像。
在 Halium 上构建 Ubuntu Touch 16.04 镜像¶
警告
这些步骤将清除设备上的**所有**数据。 如果您有任何需要保留的内容,请确保在继续之前将其备份并从设备上复制下来。
Now that you’ve built halium-boot, we’re ready to install Ubuntu Touch on your device.
为了安装 Ubuntu Touch,您需要在手机上安装带有 Busybox 的 Recovery (比如 TWRP)。 您还需要确保 /data 分区使用 ext4 文件系统格式化,并且没有任何进行加密。
安装 halium-boot¶
我们需要在安装镜像之前安装 halium-boot 镜像。 重新启动手机进入 fastboot 模式,然后在 Halium 树中执行以下操作:
cout
fastboot flash boot halium-boot.img
下载 rootfs 文件系统¶
Next we’ll need to download the rootfs (root filesystem) that’s appropriate for your device. Right now, we only have one available. Simply download ubports-touch.rootfs-xenial-armhf.tar.gz
from our CI server. If you have a 64-bit ARM (aarch64) device, this same rootfs should work for you. If you have an x86 device, let us know. We do not have a rootfs available for these yet.
安装 system.img 和 rootfs 文件系统¶
待处理
Change the rootstock link to point to UBports once the actuallyfixit PR is merged.
Download the halium-install-standalone script from jbbgameich/halium-install’s releases (direct link to download). Boot your device into recovery and run the script as follows:
halium-install-standalone.sh -p ut path/to/rootfs.tar.gz path/to/system.img
The script will copy and extract the files to their proper places, then allow you to set the phablet user’s password.
获得 SSH 访问权限¶
当您的设备启动时,它可能会卡在引导界面上。 但是,您还应该在插入设备的计算机上获得新的网络连接。 我们将使用它来调试系统。
To confirm that your device has booted correctly, run dmesg -w
and watch for “GNU/Linux device” in the output. If you instead get something similar to “Halium initrd Failed to boot”, please get in contact with us so we can find out why.
Similar to the Halium reference rootfs, you should set your computer’s IP on the newly connected RNDIS interface to 10.15.19.100
if you don’t get one automatically. Then, run the following to access your device:
ssh phablet@10.15.19.82
密码将是您在运行 halium-install 时设置的密码。
常见问题¶
If you have any errors while performing these steps, check see if any of the following suggestions match what you are seeing. If you have installed successfully, skip down to Continue on.
尝试连接时 SSH 挂起¶
尝试连接时,SSH连接可能会无限期挂起。 尝试停止与Control-C的连接可能会也可能不会返回到shell提示符。 如果你运行``ssh -vvvv phablet @ 10.15.19.82``,你只能在程序停止之前得到以下输出:
debug1: Connecting to 10.15.19.82 [10.15.19.82] port 22.
debug1: Connection established.
[...]
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH[...]
启用rsyslogd时,这似乎是内核3.10的arm64设备上的常见错误。 如果您有此错误,请将您的声音添加到`ubports / ubuntu-touch#560`_然后尝试以下解决方法:
重新启动设备以恢复并连接“adb shell”
运行以下命令来禁用 rsyslogd:
mkdir /a mount /data/rootfs.img /a echo manual |tee /a/etc/init/rsyslog.override umount /a sync
您现在可以重启设备。 一旦重新联机,您应该能够连接到 SSH。
一分钟后设备重启¶
The device may reboot cleanly after about a minute of uptime. If you are logged in when the reboot occurs, you will see the following message:
Broadcast message from root@ubuntu-phablet
(unknown) at 16:00 ...
The system is going down for reboot NOW!
This happens because lightdm
, the Ubuntu Touch display manager, is crashing repeatedly. The system watchdog process sees this and reboots the device.
To fix this problem, log in before the reboot occurs and run the following command:
sudo stop lightdm
继续¶
Congratulations! Ubuntu Touch has now booted on your device. Move on to 运行 Ubuntu Touch to learn about more specific steps you will need to take for a complete port.
运行 Ubuntu Touch¶
Now that you’re logged in, there are a few more steps before Ubuntu Touch will be fully functional on your device.
Make / writable¶
Before we make any changes to the rootfs (which will be required for the next steps), you’ll need to remount it with write permissions. To do that, run the following command:
sudo mount -o remount,rw /
添加 udev 规则¶
You must create some udev rules to allow Ubuntu Touch software to access your hardware. Run the following command, replacing [codename] with your device’s codename:
sudo -i # And enter your password
cat /var/lib/lxc/android/rootfs/ueventd*.rc|grep ^/dev|sed -e 's/^\/dev\///'|awk '{printf "ACTION==\"add\", KERNEL==\"%s\", OWNER=\"%s\", GROUP=\"%s\", MODE=\"%s\"\n",$1,$3,$4,$2}' | sed -e 's/\r//' >/usr/lib/lxc-android-config/70-[codename].rules
Now, reboot the device. If all has gone well, you will eventually see the Ubuntu Touch spinner followed by Unity 8. Your lock password is the same as you set for SSH.
显示设置¶
When the device boots, you’ll probably notice that everything is very small. There are two variables that set the content scaling for Unity 8 and Ubuntu Touch applications: GRID_UNIT_PX
and QTWEBKIT_DPR
.
There are also some other options available that may be useful for you depending on your device’s form factor. These are discussed below.
All of these settings are guessed by Unity 8 if none are set. There are many cases, however, where the guess is wrong (for example, very high resolution phone displays will be identified as desktop computers). To manually set a value for these variables, simply create a file at /etc/ubuntu-session.d/[codename].conf
specifying them. For example, this is the file for the Nexus 7 tablet:
$ cat /etc/ubuntu-touch-session.d/flo.conf
GRID_UNIT_PX=18
QTWEBKIT_DPR=2.0
NATIVE_ORIENTATION=landscape
FORM_FACTOR=tablet
Methods for deriving values for these variables are below.
显示缩放¶
GRID_UNIT_PX
(Pixels per Grid Unit or Px/GU) is specific to each device. Its goal is to make the user interface of the system and its applications the same perceived size regardless of the device they are displayed on. It is primarily dependent on the pixel density of the device’s screen and the distance to the screen the user is at. The latter value cannot be automatically detected and is based on heuristics. We assume that tablets and laptops are the same distance and that they are held at 1.235 times the distance phones tend to be held at.
QTWEBKIT_DPR
sets the display scaling for the Oxide web engine, so changes to this value will affect the scale of the browser and webapps.
A reference device has been chosen from which we derive the values for all other devices. The reference device is a laptop with a 120ppi screen. However, there is no exact formula since these options are set for perceived size rather than physical size. Here are some values for other devices so you may derive the correct one for yours:
设备 | 分辨率 | 显示大小 | PPI | Px/GU | QtWebKit DPR |
---|---|---|---|---|---|
“正常”密度笔记本 | N/A | N/A | 96-150 | 8 | 1.0 |
ASUS Nexus 7 | 1280x800 | 7 英寸 | 216 | 12 | 2.0 |
高密度笔记本 | N/A | N/A | 150-250 | 16 | 1.5 |
Samsung Galaxy Nexus | 1280x720 | 4.65” | 316 | 18 | 2.0 |
LG Nexus 4 | 1280x768 | 4.7” | 320 | 18 | 2.0 |
Samsung Nexus 10 | 2560x1600 | 10.1” | 299 | 20 | 2.0 |
Fairphone 2 | 1080x1920 | 5 英寸 | 440 | 23 | 2.5 |
LG Nexus 5 | 1080x1920 | 4.95” | 445 | 23 | 2.5 |
Experiment with a few values to find one that feels good when compared to the Ubuntu Touch experience on other devices. If you are unsure of which is the best, share some pictures (including some object for scale) along with the device specs with us.
Form factor¶
There are two other settings that may be of interest to you.
FORM_FACTOR
specifies the device’s form factor. This value is set as the device’s Chassis, which you can find by running hostnamectl
. The acceptable values are handset
, tablet
, laptop
and desktop
. Apps such as the gallery use this information to change their functionality. For more information on the Chassis, see the freedesktop.org hostnamed specification.
NATIVE_ORIENTATION
sets the display orientation for the device’s built-in screen. This value is used whenever autorotation isn’t working correctly or when an app wishes to be locked to the device’s native orientation. Acceptable values are landscape
, which is normally used for tablets, laptops, and desktops; and portrait
, which is usually used for phone handsets.
常见问题¶
If you have any errors while performing these steps, check see if any of the following suggestions match what you are seeing. If you have completed these steps successfully, congratulations! You’ve reached the end of the porting guide for now. Try to check the functionality of your device by following the Smoke Testing information in 质量保证.
运行 Ubuntu Touch 的平常问题¶
This page details problems commonly faced while following the 运行 Ubuntu Touch page.
屏幕上没有显示任何内容¶
If nothing is showing on screen even after adding udev rules to your port, it is likely that you have a problem with graphical applications crashing. See Mir servers crash for more information.
Mir 服务器崩溃¶
Mir servers crashing can be caused by many different problems with the port. To troubleshoot more, you can try the following:
Is the Android container running?¶
If the Android container is not running, many parts of Ubuntu Touch will not work. Run this command to check on the container’s status:
sudo lxc-info -n android
If you get output similar to the following, the Android container is running and you can move on to the next troubleshooting step:
Name: android
State: RUNNING
PID: 1194
IP: 10.15.19.82
If you do not get State: RUNNING
, the container is stopped. You can run sudo start lxc-android-config
to attempt to start it. If the container does not start after that, you can run sudo lxc-start -n android -F
to get a more detailed log of why it has failed.
所有 Android 分区都被挂载了么?¶
If some partitions used for Android drivers are not mounted, the container may start but not work correctly.
To check the mounted Android partitions, run ls /android
. At least the following folders should be contained within:
data
system
firmware
persist
If any of these are missing, run dmesg
to get the kernel log. Mounting Android partitions will start after the following line:
initrd: checking fstab [...] for additional mount points
Try to diagnose and fix any mounting errors that you find in the log for the partitions listed above.
注解
Some devices have a vendor
partition that contains proprietary libraries and executables required to run Android. If your device has this partition, make sure that it is mounted in addition to the others listed above.
获取更多 Mir 日志¶
If the Android container is running and all of its partitions seem to be mounted, you will need to get a few more logs before enlisting community help.
First, stop the display manager if it is not already:
sudo stop lightdm
If you have Wi-Fi working (See the Halium docs for Wi-Fi), install the libc6-dbg
package first:
sudo apt update
sudo apt install libc6-dbg
Then, run the following commands to get all of the needed logs:
sudo unity-system-compositor --debug-without-dm &> ~/usc.log
sudo gdb -ex 'set confirm off' -ex 'run' -ex 'bt full' -ex quit --args unity-system-compositor --debug-without-dm &> ~/usc-gdb.log
sudo /system/bin/logcat -d &> ~/usc-logcat.log
Use scp
or a similar program to copy the usc.log
, usc-gdb.log
, and usc-logcat.log
files from phablet’s home folder to your computer. Then, post the content of these files to paste.ubuntu.com, Pastebin, GitHub Gists, or a similar service so the people helping you can view them easily.
程序在崩溃前挂起¶
有时进程会挂起很长时间,然后中止或出现段错误。 挂起的原因是 apport,它试图在允许程序停止之前收集有关崩溃的有用信息。
If you don’t need apport’s information and would rather have the programs crash faster while troubleshooting, issue the following commands:
sudo stop apport
sudo stop whoopsie
获取社区帮助¶
If you’re having trouble with the porting steps after building your Halium systemimage, check out the “Common Problems” section of the page you’re stuck on. If none of the suggestions are helpful, you can get help from the community via the following channels:
- Telegram: @ubports_porting
- IRC: #ubports-porting on freenode
- Forum: forums.ubports.com