Кейс · 2026
BMW iDrive Launcher
Собственный проект · Дизайн и разработка
В разработке

Заводской лаунчер на китайских магнитолах XTRONS тормозит и не умеет главного. Мы начали с малого — заменить его быстрым домашним экраном в эстетике современного iDrive и надёжно поднимать бортовой компьютер при старте машины. А выросло это в полноценную приборную панель: 3D-карусель плиток над живой картой, приборный янтарь на графите, музыка из Яндекса и собственный борткомпьютер, который читает шину I-Bus машины напрямую.
Всё на Kotlin и Jetpack Compose, со скриншот-тестами, без root. Обновляется по воздуху, исходный код открыт на GitHub. Машина — настоящая, ездит каждый день.
Как сделано
Чистый Kotlin + Jetpack Compose, без тяжёлых фреймворков. Инженерная часть — там же, где и «характер» интерфейса:
- Логика отделена от UI и покрыта тестами — геометрия карусели, разбор кадров шины I-Bus, форматирование времени, маппинг воспроизведения, разрешение темы.
- Скриншот-тесты Paparazzi рендерят каждый экран в родном разрешении головы: визуальная регрессия валит сборку, интерфейс не «уезжает» между версиями.
- Лаунчер — это HOME, он не имеет права падать: все внешние вызовы, USB и карта обёрнуты в защиту и деградируют молча. Всё работает без root.
- OTA-обновления по кнопке — правки прилетают на голову без флешки и без ADB.
История: решения и грабли
Проект интересен не фичами, а тем, с чем пришлось столкнуться — и как это обошли. Почти каждый шаг упирался в особенности дешёвой магнитолы.
Голова без разработчика. Стандартный трюк «семь тапов по номеру сборки» на этих
XTRONS не работает — режим разработчика просто не появляется. Вечер ушёл на то,
чтобы найти недокументированный вход: в заводских настройках пароль adbon
открывает ADB. Написали отдельную инструкцию — таких голов в стране много.
Эквалайзер, который врал. Сначала на экране музыки крутился «живой» эквалайзер. Оказалось, ROM магнитолы блокирует захват аудио, поэтому любой анализатор был синтетическим — просто дёргался не в такт. Честнее убрать: оставили спокойную янтарную полосу прогресса.
Серый экран и зависания. Периодически лаунчер уходил в серый экран с ребутом. Добавили «сторожа» главного потока и отчёты о зависаниях, которые переживают перезагрузку и сами прилетают на сервер — так поймали причину, а не гадали.
Карта, которая капризничала. Хотелось живую карту фоном — в нашем стиле, а не дефолтный жёлтый Яндекс. Проприетарный формат стиля Яндекс.Карт молча не применялся. Перешли на открытый движок MapLibre + бесплатные тайлы OpenFreeMap со своим style.json на нашем сервере — теперь цвета карты правятся на сервере без пересборки приложения. А когда выяснилось, что провайдер магнитолы не пускает заграничный CDN тайлов, подняли прокси на своём сервере: голова ходит только к нам, мы тянем тайлы за неё.
Свой борткомпьютер вместо чужого приложения. Изначально лаунчер просто запускал стороннее i-Bus приложение. Оно глючило и дралось за единственный USB-порт адаптера. Решение — написать свой ридер шины I-Bus: подключаемся к адаптеру Resler (CP210x, 9600 8E1) по USB и сами разбираем сообщения приборной панели — скорость, обороты, температуры, зажигание. Протокол подтвердили декомпилом родного приложения. Собирали, по сути, вслепую — доступа к машине не было — но цифры на приборке сошлись с первого раза. Стороннее приложение удалили: порт теперь наш.
Кирпич — и воскрешение. Самый напряжённый эпизод: эксперимент с правами root залил на голову несовместимый загрузочный образ, и она ушла в вечный цикл «логотип → чёрный экран». Инструкции продавца (меню по кнопке, флешка) на этой Qualcomm-платформе не работают; предлагали возврат по почте — это месяцы без машины. Разобрались сами: нашли, что сервисный режим (fastboot) выходит только через один конкретный USB-разъём — четырёхпиновый OTG, а не «флешечные» порты, — и через него перезалили родной загрузочный образ, снятый с этой же головы. Всё восстановилось без потери данных и настроек. Заодно написали пошаговый разбор, чтобы такой кирпич больше не был приговором.
Кнопки, которые нельзя перехватить. Захотели, чтобы физические кнопки панели открывали наши экраны. Живой захват ввода показал: реальный код шлёт только «Назад» — остальные кнопки намертво зашиты в контроллер и сами запускают штатные приложения, не отдавая события. Перехватить нельзя — но можно перенаправить: сервис ловит запуск штатного приложения и мгновенно открывает наш экран. Теперь панельная «Музыка» открывает наш плеер.
Парктроник, который пищит поздно. Штатный парктроник E53 молчит, пока не подъедешь вплотную, — это ощущается как «тупит». Дистанции при этом есть на шине I-Bus (модуль отвечает на запрос). Добавили режим записи, который опрашивает датчики и логирует ответы, — чтобы раскодировать их и сделать более ранний, ступенчатый сигнал, чем штатный зуммер.
Разработка вслепую. Машины под рукой нет — итерации идут через OTA-кнопку «обновить» и диагностические логи с устройства. Логи стали нашими «глазами»: именно по ним настраивается разбор шины и добавляются новые показатели.
Уже добавили среднюю скорость поездки (со сбросом), считаемую прямо из шины. Дальше — топливо и расход в том же борткомпьютере и ранний сигнал парктроника.
Экраны




Живой, ежедневно используемый лаунчер для головного устройства BMW X5 E53 — 3D-карусель в стиле iDrive над живой картой, собственный борткомпьютер (читает шину I-Bus машины напрямую по USB), музыка из Яндекса, OTA-обновления. Активная разработка, открытый код на GitHub.