
tl;dr: упаковываю и отправляю приложение без троянов для управления своими лампами в F-Droid без каких-либо знаний в разработке для Android.
У меня есть политическая позиция, я сторонник СПО во многом согласен со Столлманом. Как это часто бывает, такая позиция дополняется лёгкой паранойей. Я стараюсь избавляться от проприетарных приложений, особенно, если они работают через сторонние сервера.
А ещё у меня есть умные лампы Xiaomi Yeelight, которые контролируются приложением, работающим через сервера Xiaomi. Но в нём есть возможность включить в лампе API, работающее внутри локалки. Чтобы чувствовать себя спокойней, я пошёл искать приложение в Github и Gitlab и теперь намереваюсь продвинуть его в F-Droid, чтобы поддержать наше параноидальное сообщество.
Сборка и проверка
Для того, чтобы приложение попало в каталог, оно должно хотя бы собираться и, по-хорошему, работать. Мой выбор оказался скудным, а на Gitlab ничего не нашлось ни одного приложения. Из доступных приложений я смог собрать лишь два, а запустилось в итоге только одно из них. Я очень далёк от разработки под Android, за несколько дней я освоил только простую сборку с помощью Gradle, её дальше и опишу.
Нам понадобится: git, Java Runtime Environment, Android SDK, Android Debugging Bridge и свежий Gradle. JRE, ADB и git для Debian Testing можно установить из пакетов
apt install git adb
openjdk-11-jre-headless
.Android SDK обычно устанавливается вместе с Android Studio, но я воспользовался консольной утилитой sdkmanager:
unzip commandlinetools-linux-6609375_latest.zipexport PATH=$PATH:$PWD/tools/bin/mkdir android-sdkexport ANDROID_SDK_ROOT=$PWD/android-sdk/
Если вам показалось, что я пропустил установку собственно Android SDK, то вам не показалось. Потом объясню. В репозиториях Debian лежит протухшая версия Gradle, сборка с ней не работает, свежую тоже придётся устанавливать с сайта:
wget https://services.gradle.org/distributions/gradle-6.6.1-bin.zipunzip gradle-6.6.1-bin.zipexport PATH=$PATH:$PWD/gradle-6.6.1/bin/
Репозиторий я форкнул к себе и почистил автосгенерированный мусор. Собирается всё так:
yes | sdkmanager --licenses --sdk_root=$ANDROID_SDK_ROOTgit clone https://github.com/asz/OpenLight.gitcd OpenLight/gradle wrapper./gradlew assemble
Первой командой принимаем оптом принимаем все лицензионные условия, как того требует
sdkmanager
для неинтерактивной
установки. При автогенерации обёртки (gradle wrapper
)
Gradle сам распарсит и установит все необходимые зависимости.
Скачивание нужной версии Android SDK, сборочного инструментария и
других специфичных для Android зависимостей выполняется именно с
помощью sdkmanager
, поэтому руками это делать не
обязательно, а лицензии придётся принять заранее.
Самое время включить API в официальном приложении. Включите в смартфоне отладку по USB, подключите его к компьютеру и устанавливайте сгенерированный отладочный пакет:
adb install
app/build/outputs/apk/debug/app-debug.apk
. Не забудьте
разрешить отладку с вашего компьютера во всплывающем окне на
телефоне. Если приложение на телефоне демонстрирует признаки жизни,
то можно продолжать.Подготовка патча в F-Droid
У F-Droid есть правила для включения приложения в каталог. Основные довольно простые: никаких несвободных зависимостей сборки, проблемы с приватностью и любые несвободные зависимости самого приложения должны быть помечены. Я не стал проверять зависимости самостоятельно, ведь у F-Droid есть CI и собственная система сборки, это позволяет просто прогнать коммит через пайплайн.
Теперь пойдём на GitLab, где ведётся разработка F-Droid. Сначала обязательно проверьте, что вашим приложением ещё никто не занимается. Подобная активность сосредоточена в запросах на упаковку и в запросах на слияние. Форкайте репозиторий Data и клонируйте его из своего профиля.
Для того, чтобы приложение оказалось в F-Droid, достаточно одного YML-файла. Найдите любой подходящий YML-файл в подкаталоге
metadata/
вашего репозитория и скопируйте его в
аналогичном формате: applicationId.yml
. Значение
applicationId
для вашего приложения можно достать из
какого-нибудь build.gradle
его же репозитория, в моём
случае из app/build.gradle
. Не помню, какой из файлов
я взял в качестве референса, покажу лишь итоговый файл
metadata/grmasa.com.open_light.yml
:AntiFeatures:
- NonFreeDep
Categories:
- Connectivity
License: GPL-2.0-or-later
AuthorWebSite: https://github.com/grmasa
SourceCode: https://github.com/grmasa/Open_light
IssueTracker: https://github.com/grmasa/Open_light/issues
Changelog: https://github.com/grmasa/Open_light/tags
AutoName: Open Light
Summary: Control Xiaomi Yeelight WiFi smart bulbs
Description: |-
Control Xiaomi Yeelight smart bulbs within your Local Area
Network.
Only fits WiFi controlled bulbs.
This app requires enabled LAN control for bulbs: open the official
app, set up
all the bulbs, go to LAN control in the menu, and enable it for
every device.
RepoType: git
Repo: https://github.com/grmasa/Open_light.git
Builds:
- versionName: 1.1.2
versionCode: 1
commit: v1.1.2
subdir: app
gradle:
- yes
AutoUpdateMode: Version v%v
UpdateCheckMode: Tags
CurrentVersion: 1.1.2
CurrentVersionCode: 1
Мне было сложно выбрать конкретную AntiFeature, но доскональная точность не требуется, указал
NonFreeDep
. Категория
Connectivity
подходит для приложений-компаньонов
устройств. Ключ Build
описывает, из какого
коммита/тега собирать приложение. versionCode
также
можно найти в build.gradle
. Если вы не хотите
обновлять приложение вручную, то можно заполнить
UpdateCheckMode
и AutoUpdateMode
(v%v
описывает формат тега).Для базовой проверки файла потребуется утилита
fdroid
из репозитория F-Droid
Server, его зависимости и переменная
ANDROID_HOME
:
git clone https://gitlab.com/fdroid/fdroidserver.gitexport PATH=$PATH:$PWD/fdroidserverapt -y install python3-git python3-pyasn1 python3-pyasn1-modules python3-yaml python3-requestsexport ANDROID_HOME=$ANDROID_SDK_ROOT
Можно вернуться в директорию
fdroiddata
и проверить,
рабочие ли метаданные:
fdroid readmetafdroid lint grmasa.com.open_lightfdroid build -v -l grmasa.com.open_light
Первые две команды проверяют синтаксис, третья собирает приложение. На выходе у вас должен появиться APK:
unsigned/grmasa.com.open_light_1.apk
.Можно на всякий случай запустить
fdroid checkupdates
grmasa.com.open_light
для проверки обновлений и fdroid
rewritemeta grmasa.com.open_light
для корректного
перезаполнения файла с метаданными, после чего перепроверить
сборку.Почти счастливый конец
Теперь можно коммитить и проверять пайплайн Gitlab CI. У меня всё прошло!
Я заполнил Merge Request, его проверили и попросили уведомить автора оригинального приложения. Если автор будет игнорировать меня больше двух недель, я просто перепишу ссылки в метаданных на свой форк и тогда его примут.

Теперь я могу убрать подальше свой специальный телефон для троянов. И у меня даже останется возможность извращённым образом управлять ими из интернета даже забанив им локалку!
Как ни печально, в иллюстрации в заголовке есть доля правды. В приложении обнаружился неприятный баг на втором шаге визарда: из списка обнаруженных ламп, чаще всего добавляется не та, которую я выбрал. Из-за этого лампы в основном списке. Чтобы обойти эту проблему, я заводил лампы в приложение поочерёдно. Надеюсь, когда-нибудь я разберусь, в чём проблема, или упакую другое приложение.
