Описание игры: Wuthering Waves - это ролевая игра в открытом мире с богатым сюжетом и высокой степенью свободы. Вы просыпаетесь ото сна в роли Ровера, к которому присоединяется энергичный состав Резонаторов в путешествии, чтобы вернуть утраченные воспоминания и преодолеть Плач.
Описание игры: Представляем запатентованную технологию Warbits+ от Risky Lab. Загрузите симулированное поле битвы и ведите более цивилизованную войну против своих врагов. Не согласны с другими фракциями? Вам не обязательно! Опустите эти бластеры, загрузите Warbits и практически сокрушите противников!
Описание игры: Игра Pixel Archmage предложит пиксельную графику и 6 типов навыков, с помощью которых можно покорить все локации. Помимо этого нужно коллекционировать реликвии, снаряжение, монстров и другие ценные предметы, спрятанные внутри башни. Вероятно, это Бесконечная башня будет одним из игровых режимов.
Описание игры: Создайте свою собственную историю и исследуйте мир Афин в Athenian Rhapsody, платоническом симуляторе свиданий, похожем на соулс, с механикой приготовления пищи и сражений в стиле WarioWare... и я имею в виду, что это приключенческая ролевая игра с возможностью обмена целыми игровыми залами между друзьями!!!
Описание игры: Amikin Survival выполнена по всем законам Palworld, то есть игрок создаёт своего аватара, собирает ресурсы, обустраивает базу, приручает различных существ и с их помощью автоматизирует крафт и свою ферму. Но у Amikin Survival будут и отличия — судя по скриншотам из маркетов, игровой процесс изометрический.
Описание игры: Zero to Hero: Pixel Saga выполнена в жанре RPG и в пиксельной аниме стилистике. Игроки должны собирать команду из редких бойцов, которые участвуют в авто-битвах на парящих в небе кораблях. Также геймерам надо собирать AFK-награду и прокачивать своих бойцов. Ещё можно выбить новых и более сильных через гача-автоматы, как в Японии.
Описание игры: Отправляйтесь в эпическое приключение вместе с The Legend of Heroes: Trails of Cold Steel – Northern War! Эта история, действие которой разворачивается между Trails of Cold Steel II и Trails of Cold Steel III, рассказывает о путешествии Лави, члена Северных егерей, родившегося и выросшего в Северной Амбрии. Вместе со своими товарищами по команде Мартином, Изерией и Талионом им предстоит выполнить сложную миссию. Они должны проникнуть в Эребонскую империю, чтобы собрать информацию о таинственной угрозе, угрожающей безопасности Северной Амбрии.
Описание игры: Отправляйтесь в грандиозное приключение, покоряя холмы в LEGO® Hill Climb Adventures, однопользовательской исследовательской игре, в которой сталкиваются культовые миры LEGO и Hill Climb Racing!
Описание игры: Solo Leveling — веб-роман, по сюжету которого повсюду возникли Врата, соединяющие Землю с миром, населённым монстрами. К счастью, некоторым избранным дали суперспособности. Со временем Охотники организовали гильдии и стали профессионально заниматься поиском и уничтожением чудовищ. Теперь одноимённая игра — Solo Leveling — готовится корейской компанией Netmarble.
Видео и музыка предназначены для информационных целей 16 + 🎮 Все авторские права принадлежат их законным владельцам. 💽 Примечание: Дата выпуска может быть изменена. 💢
Отвал флэш-памяти типа eMMC - весьма частая болячка смартфонов и планшетов, которая массово преследует современные девайсы на протяжении вот уже более 10 лет. Симптомы проблемы знакомы многим читателям: смартфон виснет на заставке, системные приложения регулярно вылетают, или настройки системы внезапно перестают сохраняться. Сам процесс замены флэш-памяти требует навыков перекатки и пайки BGA-чипов, оборудования (трафареты для реболла, программатор с колодками, опционально подогрев) и понимания того, как работает загрузчик той или иной аппаратной платформы, поэтому в СЦ за эту процедуру могут взять достаточно большую сумму. На некоторых девайсах менять память уже совсем невыгодно, особенно когда другой такой-же аппарат стоит полторы тысячи рублей на барахолке, но воспоминания о любимом девайсе порой гораздо дороже, чем сумма за ремонт смартфона. Год назад я уже писал материал о загрузке Android с MicroSD при условии того, что eMMC ещё подает хоть какие-то признаки жизни, а сегодня я вам расскажу о способе загрузить систему с флэшки уже после того, как чип флэш-памяти отказал и ушёл в read-only. Сегодня мы с вами: узнаем о том, какие типы флэш-памяти существуют и причины их отказа, разметим MicroSD-флэшку и запишем на неё образ системы, пропатчим пути монтирования в boot.img, а также узнаем, как теперь запускать наш смартфон и посмотрим, сможет ли он работать достаточно шустро с MicroSD флэшки! Интересно узнать, как вернуть жизнь таким легендам, как Google Nexus? Тогда добро пожаловать под кат!
❯ Почему отказывает флэш-память?
Как я уже говорил в вводном абзаце, проблема внезапно отваливающейся флэш-памяти существует вот уже более 10 лет. Ещё с выходом iPhone 3Gs/4, мастера познакомились с такой болячкой, как внезапное падение устройства в режим DFU и отказ прошиваться через iTunes. Ближе к выходу Galaxy S III, HTC Desire и Wildfire, LG Nexus возникла потребность в программаторах, поскольку чипы eMMC в этих смартфонах очень часто помирали «сами по себе» из-за косяков производителя флэш-памяти. Более опытная часть моих пользователей может вспомнить такие проблемы, как отказ входа в HSPL (загрузчик HTC), бесконечная загрузка с отказом прошиваться в режиме Odin на самсунгах, падение смартфонов на базе чипсетов Qualcomm в режим 9008 (QHSUSB_BULK), а также внезапное прекращение работоспособности девайса даже при наличии адекватного потребления и реакции на кнопку включения.
В относительно современных смартфонах используется два типа чипов флэш-памяти с разными протоколами: NAND и eMMC (в современных чаще используется UFS — наследник eMMC с дифференциальным протоколом, вместо MMC). Устройства конца 2000х годов чаще использовали флэш-память типа NAND с Legacy-протоколом, который требовал ручного управления SPARE-страницами и расчета кода коррекции ошибок (ECC), чем занималось отдельное периферийное ядро в процессоре, называемое NAND-контроллером. Момент, когда нужно «приговорить» флэш-память и перевести её в режим read-only решал не сам контроллер, а драйвер NAND в прошивке устройства — и обычно он был весьма лоялен даже к «сыпящейся» памяти. Кроме того, NAND-контроллер позволял практически напрямую взаимодействовать с чипом флэш-памяти, благодаря чему в загрузчиках типа U-boot есть команда для очистки таблицы Bad-блоков и низкоуровневого форматирования флэш-памяти, дабы в дальнейшем контроллер попробовал пересчитать бэды и, потенциально, вернул некоторое число блоков обратно в строй. Такой тип «флэшек» помирал значительно реже, в основном из-за того, что софт (на моём опыте) практически никогда не уводил флэшку в read-only, «добивая» её до последнего. Из минусов такого подхода — если флэш помирала совсем, то данные из нее можно было достать только с помощью программатора, да и то не факт.
В моей довольно большой коллекции нет ни одного смартфона с Legacy NAND, где флэш бы действительно «приехала», хотя на форумах мастеров иногда встречаются старые сообщения о замене флэши на телефонах Nokia.
Второй тип памяти появился примерно в начале 2010х годов и имя ему — eMMC. Фактически, eMMC — это адаптация интерфейса MMC для использования в виде обычных чипов памяти, а не карточек, совместимая с спецификацией ~SDHC. Если выпаять чип с телефона и припаять сигнальные линии к обычному SD-кардридеру на ПК — он будет работать и определяться как полноценный диск! Таким образом, на некоторых смартфонах можно заменить eMMC на MicroSD напрямую припаяв флэшку на место чипа к соответствующим сигнальным линиям. Однако работать такое будет только если у вашего смартфона «бутербродная» компоновка, где ОЗУ припаяна поверх процессора (MTK и Spreadtrum в пролете). В eMMC используется память типа NAND, которой управляет не чипсет, а встроенный в сам чип памяти контроллер, работающий с протоколом MMC и имеющий собственную прошивку и карту бэд-блоков. Такая флэш-память может самостоятельно уходить в режим read-only когда это посчитает нужным контроллер, зачастую не давая смартфону загрузится, но при этом потенциально сохраняет данные пользователя и позволяет их прочитать дома (сделав дамп памяти устройства и смонтировав раздел userdata в Linux). Однако всё равно иногда данные теряются безвозвратно. Нюанс в том, что состояние eMMC определяет сам контроллер в чипе — поэтому «оживить» его дома и вывести из read-only невозможно. Однако я слышал, что на некоторых «бракованных» чипах памяти (в основном Samsung 2012-2013 годов), которые ушли в read-only слишком рано, можно подпаяться к тест-поинтам программатором и прошить чуть более свежую прошивку с другой ревизии этого же чипа памяти. Флэшка, бывало, оживала.
В некоторых случаях, eMMC были бракованными с завода и помирали сами по себе (!) через короткое время (около года) после покупки устройства. Я знаю как минимум два примера массового брака флэш-памяти: смартфоны HTC 2011-2012 годов, которые время от времени страдали от валящихся чипов Hynix (это касается не всех устройств, многие дожили), хотя я лично видел не так много HTC'шек с дохлой памятью, так что здесь читатели-сервисники с опытом работы в те годы могут только подтвердить или опровергнуть мои слова. А вот подтвержденный пример — смартфоны и планшеты Samsung 2012-2014 годов. Galaxy S3 с артефактами на дисплее при включении, S4 Mini в 9008 или повисшие на заставке, S4 с теми же симптомами, S4 Zoom, которые практически все померли «сами по себе» после обновления до 4.4 KitKat, N8000… Добавьте к этому слабые NC-пятаки, которые срывает при попытке снять чип феном, близко расположенный «бутербродный» процессор, который легко «убить», если орудовать феном, компаунд… и по итогу многие мастера просто спиливали чип дремелем. А что ещё делать!?
По итогу, нам остаётся искать софтварные способы загрузить систему с внешней MicroSD флэшки. И я нашел два таких способа! Первый — предварительно подготовить образ boot.img и прошить его в смартфон вместо recovery, дабы если память ушла в read-only, мы могли просто «дуалбутнутся» во второй образ с пропатченными точками монтирования системных разделов на MicroSD. А о втором, к сожалению, знают лишь единицы, хотя это просто замечательный способ, который позволяет загрузить систему уже «пост-фактум» после ухода флэшки в read-only и требует некоторых манипуляций с fastboot! Давайте же рассмотрим его подробнее.
Нашим подопытным будет рабочий смартфон Alcatel OT-5020D 2013 года выпуска, который пока не подает признаков помирающей eMMC: к сожалению, смартфонов с полудохлой памятью и разлоченным бутом у меня не оказалось, дохлые флэшки я иногда меняю и сам :) Но тем не менее, грузиться мы в любом случае будем с флэшки и вы сможете повторить все шаги в статье, дабы загрузить систему с MicroSD самому!
❯ Подготавливаем систему
Друзья! Для следующих действий, вам понадобится разблокированный загрузчик или устройство, на котором с завода загрузчик не заблокирован. Главный критерий — наличие режима fastboot.
Какие устройства не подойдут: многие смартфоны на базе чипов Spreadtrum, а также часть смартфонов Samsung на Exynos. Ни те, ни другие частенько не имеют режима fastboot от слова совсем. У Samsung есть режим загрузки с MicroSD (т. н. T-Flash Mode), но ядро он не грузит.
Какие устройства подойдут, но требуется подготовка: все смартфоны от Sony (исключение — Xperia Tipo, забагованный fastboot), Google Nexus (некоторые модели страдали из-за отвалов флэши), современные китайские новодельные noname-смартфоны (с вот таким патчем), Xiaomi, Meizu. Чипсеты: MediaTek 67xx/Qualcomm Snapdragon, возможно Kirin. Таким устройствам требуется предварительная разблокировка загрузчика.
Какие устройства подойдут даже при условии уже мертвой флэш-памяти: большинство девайсов на базе чипсетов MediaTek прошлого десятилетия, особенно бюджетных: MT6572, MT6582, MT6592, MT6580, MT6570, MT6575, MT83xx, некоторые Spreadtrum. Это касается Fly, Explay, ZTE и многих других ультрабюджетных смартфонов тех лет. Загрузчик там разблокирован с завода, никакого секьюрбута и верификации загружаемых образов нет. Но не везде можно загрузится в fastboot напрямую (попробуйте громкость вверх и громкость вниз при включении — если сразу грузится в рекавери, то нужно до отказа eMMC включить ADB, если показывает менюшку fastboot, recovery, normal boot — значит все ок).
Не подойдут: MT6573, MT6571 — там U-Boot (но его тоже можно попробовать заставить грузиться с SD).
Список устройств для потенциальной возможности загрузки с SD весьма большой! Как понять, что eMMC «всё»?
Смартфон не реагирует на зарядку и кнопку включения при заряженной АКБ: это не 100% показатель, но если поднимаются питальники с КП и потребление от кнопки есть ~0.1-0.3А — значит процессор вероятно пытается стартовать. Но не откуда. В таком случае, девайс поднять не получится — доступа к fastboot нет, флэшка полностью посыпалась. Исключение — некоторые Qualcomm'ы при наличии прожженного фьюза с завода, разрешающего загрузку с MicroSD могут стартовать ядро, но всё зависит от конфигурации aboot.
Смартфон загружается и сразу вылетают приложения, настройки не сохраняются: явный показатель того, что флэша ушла в read-only потенциально не повредив данные. Если смартфон грузится в fastboot — его ещё можно оживить, но не факт что получится вытащить данные (из-за шифрования). Если после сброса до заводских настроек эффект остается тот-же — eMMC приехала 100%.
Смартфон висит на заставке, сброс и прошивка не помогает: тоже явная причина: eMMC в read-only. В таком случае, не рекомендуется еще раз шить смартфон в надежде что все заработает, есть шанс что флэша посыпеться окончательно и вы потеряете доступ к fastboot.
Весьма всё просто, согласитесь? Как я уже сказал выше, на некоторых устройствах нужно сначала разблокировать загрузчик. Кое-где это, вероятно, получится сделать и при том что флэша ушла в read-only. Например, на устройствах Sony можно без проблем зайти в fastboot и разлочить устройство с помощью кода, полученного на сайте Sony (используйте VPN, если вы в РФ):
Как зайти в fastboot — вам придётся погуглить для конкретно своего устройства. Не нашли? Поищите как это делается на других смартфонах, которые работают на том же чипсете. Почти всегда можно зайти, если у вас включена отладка по USB с помощью команды:
adb reboot bootloader
Краткая справка: на устройствах Sony, в Fastboot можно зайти подключив устройство к ПК с зажатой громкостью вниз, на MTK громкость вверх или вниз, на HTC в HSPL, на Nexus'ах в фирменном загрузчике сразу режим Fastboot, на устройствах Tegra — включение с зажатой громкостью вверх, на смартфонах с чипсетом Intel есть fastboot, насколько помню зайти в него можно с помощью громкости вниз.
Команда для разблокировки загрузчика почти везде одна:
fastboot oem unlock
Вас могут запросить код разлочки или просто предупредить о последствиях такого действия. Как узнать, что бут разлочен?
fastboot getvar all
secure, locking и т. п. — отвечают за статус разлочки. Но даже если таких переменных нет, это не всегда значит, что загрузчик заблокирован. Возможно он разблокирован с завода :)
Теперь нам нужен образ раздела boot — boot.img. Его можно найти в файлах родной прошивки устройства, или, иногда, в zip-файлах кастомов. boot.img содержит в себе ядро Linux и небольшой раздел с файловой системой initrd (рамдиск), которая загружается в оперативную память и содержит в себе программы init, adbd, recovery, а также скрипты инициализации, которые управляют загрузкой Android и процессом зарядки (показывают анимацию, когда вы подключаете устройство выключенным к ЗУ. Да, в таком случае Linux тоже грузится!). Если у вас есть доступ к fastboot, то попробуйте запустить его с помощью команды:
fastboot boot boot.img
Работать она будет не везде, на MTK её поддержка отключена в загрузчиках некоторых устройств. Если вы увидели на экране устройства USB Transferring — половину дела сделана! Если устройство показало лого и анимацию загрузки или ушло в ребут — потенциально, вы сможете загрузить Android с MicroSD. Если ошибка secure-boot — нужно сначала разблокировать загрузчик. Если unknown command — команда не поддерживается :(
Теперь у нас есть возможность загрузить ядро и пропатчить скрипты конфигурации, дабы изменить точки монтирования раздела /system/, /data/ и /cache/ на MicroSD-флэшку, вместо встроенной памяти.
❯ Записываем систему на MicroSD
Обратите внимание: Android очень интенсивно использует ресурс флэшки и постоянно перезаписывает сектора памяти, поэтому не поскупитесь купить нормальную MicroSD флэшку от, например, Transcend, Kingston или Samsung. Дешевые MicroSD флэшки очень-очень быстро (вероятно, за пару дней — это не шутка) выйдут из строя и придется делать всё заново!
Сначала, нам придется разбить флэшку на три раздела: /system/, /cache/, и /data/. Раздел system будет первым, cache — вторым, data — третьим. При этом раздел /sdcard/ не нужен — он автоматически маппится в /data/media/ на современных версиях Android. Сделать это можно как с ПК с помощью MicroSD-адаптера и fdisk/diskpart/gparted, так и с самого смартфона с помощью того же fdisk в busybox. Я решил это сделать с помощью другого вспомогательного смартфона с TWRP, где изначально был root-доступ через adb! Размеры выбирайте следующие: для системного диска чуть больше или по размерам с system.img (раздел read-only и не «растет» со временем), cache — 100-200Мб, userdata — всё оставшееся место на флэшке.
Разметили MicroSD? Теперь нам нужно записать на неё образ системы. Тут три пути: если у вас есть Linux-машина, то можете подмонтировать образ system.img из оригинальной прошивки и скопировать все файлы с сохранением прав, закинуть system.img в внутреннюю память другого смартфона с root-доступом и проделать все тоже самое, либо записать с помощью dd образ system.img напрямую в нужный нам раздел флэш-памяти. Я выбрал третий способ:
dd if=/sdcard/system.img of=/dev/mmcblk1p1
Разделы cache и userdata можно просто форматировать в ext4:
Готово! Необходимые для базовой работы разделы перенесены на MicroSD. Теперь, когда, у нас есть образ системы, нам нужно распаковать родной boot.img устройства и поменять точки монтирования. Я использую кухню MTKImgTools. Идём в Boot -> Unpack -> boot.img. В Unpack/boot/ появятся файлы нашего раздела boot:
Открываем файл init.rc (в случае MediaTek). Ищем строки с монтированием разделов вида emmc@system, emmc@cache, emmc@userdata и меняем их на /dev/block/mmcblk1p1, /dev/block/mmcblk1p2 и /dev/mmcblk1p3. На некоторых чипсетах, править нужно сразу fstab, или init.<чипсет>.rc:
Готово! Собираем образ обратно с помощью Boot -> Pack -> boot.img и получаем образ, который нам и надо будет загрузить с помощью fastboot. Копируем boot.img в папку с adb и пробуем загрузить систему. Это будет основная команда для старта загрузки смартфона в будущем:
fastboot boot boot.img
Увидели бутанимацию? Значит система пошла загружаться, нужно лишь подождать первой загрузки 5-10 минут! Система висит на лого или уходит в ребут? Значит, возможно, вы неверно прописали точки монтирования, записали образ system или форматировали раздел userdata. Если система 4.4 и ниже, то можно изменить default.prop, заменив ro.secure на 0 и debuggable на 1. Если вы на Android 5+ — то заменить adbd (не требующий ключи авторизации) в /system/bin на вариант из TWRP и посмотреть logcat и dmesg. Монтируется ли /system/? Загружается ли app_process? На каком этапе стопорится? Всё это пригодится при дальнейшей отладке!
Например, такая ошибка при запуске adb shell означает то, что раздел /system/ не монтирован.
Ну а на моем девайсе система уже загрузилась и работает. Но насколько шустро? В комментариях читатели часто говорили, что из-за скорости MicroSD система будет не юзабельной. Насколько это правда? Давайте посмотрим!
Вывод mount:
Как мы и видим, /system/, /data/ и /cache/ на MicroSD. custpack и mobile_info, а также nvram трогать не нужно — если в родной флэше они не повреждены, то у девайса без проблем будет работать и сеть, и Wi-Fi.
❯ Можно ли пользоваться?
Наш девайс работает на базе Android 4.2 — казалось бы, совсем старенький дроид, но тем не менее ещё кое-что, да может. Alcatel OT — это бюджетный девайс из 2013 года, но работает он, на удивление, весьма шустро и приятно!
Начинаем с самых необходимых приложений — звонилка, контакты и галерея. Все эти приложения стартуют практически моментально, лишь иногда с небольшими лагами. Однако если поставить в браузере что-то скачиваться на фоне — конечно-же, система начнет лагать.
Как насчет браузера? Ставить последний хром, поддерживающий 4.2 смысла нет — уже и он открывает далеко не все сайты. Но те сайты, что пока ещё открывает стандартный браузер почитать ещё можно: например, opennet. На смартфонах с более свежим Android, браузер будет работать относительно адекватно. Зато с соц. сетями проблем особых нет. Telegram, конечно, может конкретно подвесить смартфон в процессе подгрузки картинок с каналов, но потом все будет нормально. Решение одно: отключить автоматическое кэширование картинок и видео!
С записью видео ситуация сложная. Даже в профессиональных камерах для 1080p рекомендуются карточки не ниже 10-класса (10Мб/с) и UHS-класса для 2+K видео. На нексусе, это скорее всего превратит девайс в лагодром даже при записе 720p видео: система в фоне так или иначе регулярно читает и записывает данные и рано или поздно мы упираемся в дисковой кэш.
Об играх с динамическим стримингом ресурсов можно забыть, если флэшка достаточно медленная — будут лаги.
А в динамике это всё выглядит так:
Достаточно шустро, для смартфона 2013 года за 4 тыщи рублей?
❯ Заключение
Сегодня мы с вами узнали, каким же образом можно перенести систему на MicroSD! Да, сработает далеко не на всех девайсах, однако сам способ может помочь поднять сотни устройств обратно в строй и сделать их полезными! Это всяко лучше, чем распаивать потенциально рабочие девайсы на «доноров» или, тем-более, отправлять их на мусорку или в чермет. С современными версиями Android ситуация сложнее: и не только из-за большего числа необходимых для загрузки разделов, но и из-за возросших требований к скорости флэш-памяти (упомянутые выше UFS работают на скорости ~500Мб/с), а также, внезапно, стремительно исчезающего слота для MicroSD :(
Надеюсь, материал вам был полезен! Сегодняшняя статья подготавливалась специально в «классическом», более коротком стиле с максимумом конкретики. Если вам больше нравится такой формат, нежели подробный на 15-20+ минут на чтения — напишите в комментариях!
Кстати, если у кого-то из читателей есть ненужные устройства (в том числе с косяками) или дешевые китайские подделки на айфоны/айпады/макбуки и другие брендовые девайсы будучи нерабочими, тормозящими, или окирпиченными и вам не хотелось бы выкидывать их на свалку, а наоборот, отдать их в хорошие руки и увидеть про них статью — пишите мне в Telegram или в комментах! Готов в том числе и купить их. Особенно ищу донора дисплея на китайскую реплику iPhone 11 Pro Max: мой ударник, контроллер дисплея калится и изображения нет :(
А ещё у меня есть Telegram-канал, куда я публикую различные заметки по ремонту, программированию и моддингу девайсов, свои мысли и вовремя публикую ссылки на новый материал!
Полезный материал?
Статья подготовлена при поддержке TimeWeb.Cloud. Подписывайтесь на меня и @Timeweb.Cloud, чтобы не пропускать новые статьи каждую неделю!
Мы постарались сделать каждый город, с которого начинается еженедельный заед в нашей новой игре, по-настоящему уникальным. Оценить можно на странице совместной игры Torero и Пикабу.
С момента выхода первой части статьи из рубрики «сам себе экосистема» прошёл уже практически год! За это время, мы успели с вами реализовать клиенты VK и YouTube, которые работают на Android 2.2+, а также на Windows Phone 8, написать небольшую 2D-игру с нуля весом менее 1Мб, которая работает практически везде и довести существующее приложение до ума, дабы оно работало даже на смартфоне с дисплеем 240x320! Но на дворе 2024 год, люди стремительно переходят из соц. сетей в продвинутые мессенджеры и уже сложно себе представить современного человека, который не пользовался бы «телегой» или даже «вайбером» в качестве основного средства общения. Поэтому я решил реализовать клиент Telegram на смартфоне 14-летней давности на базе официальной реализации MTProto от команды Telegram — TDLib. Сегодня мы с вами: узнаем новые причины мотивации вернуть в строй смартфоны прошлых лет, напишем на C# реле-сервер, который обрабатывает пакеты MTProto и кодирует их в простой текстовый формат датасетов, который можно моментально обработать даже при нестабильном GPRS-соединении на 21-летнем Siemens C60, а также узнаем о разработке миниатюрных Android-приложений на базе «голого» API-системы, которые не тянут за собой никаких зависимостей, в том числе и AppCompat/androidx. Интересно? Тогда жду вас под катом!
На дворе уже стукнул 2024 год, современные смартфоны предлагают какие-то немыслимые мощности относительно тех, которые когда-то были в первых Android-девайсах. Сейчас за сотню баксов можно купить смартфон с хорошей 1080p IPS-матрицей, 4Гб ОЗУ и 8-ядерным шустрым чипсетом, который вполне способен плавно тянуть даже стремительно «жиреющие» на ресурсы клиенты социальных сетей, банков и прочие необходимые в повседневной жизни приложения. И казалось бы: всё хорошо, покупай себе редмик раз в год или айфон раз в несколько лет и наслаждайся всеми прелестями работы современных приложений…
Для многих людей смартфон — это лишь инструмент, повседневный компаньон, который помогает облегчить выполнение каких-то задач. Им совершенно не важно, как он выглядит, как ощущается в руках, какой у него дисплей и железо «под капотом», лишь бы работал да и нормально. Но есть и другая категория людей, для которых телефоны, смартфоны и любые портативные гаджеты — это не просто утилитарный девайс, а настоящее инженерное произведение искусства, с которого буквально сдувают пылинки и стараются до последнего пользоваться ими как повседневными устройствами. Хотите пример? Смотрите ниже:
Фактически, среди современных смартфонов по сути и нет представителей такого нынче вымершего форм-фактора, как сайдслайдеры с физической QWERTY-клавиатурой, боковые раскладушки с двумя дисплеями и даже из QWERTY-моноблоков есть только смартфоны от Unihertz. Даже среди моноблоков с тачскринами нет никакого разнообразия, лишь без-рамочные одинаковые девайсы за исключением устройств от Sony.
Galaxy S Plus
Раньше меня часто спрашивали, мол, да как ты вообще можешь пользоваться смартфоном 10-летней давности, на котором давно нет официальных клиентов популярных сервисов и только недавно, с развитием блога, мне перестали задавать этот вопрос, поняв, что это бесполезно — ведь это дело принципа и порыва энтузиазма! Смотрите сами: у нас уже есть простенькие, но вполне рабочие клиенты ВК, YouTube, сейчас я допиливаю клиент «Сбера» на СМСках, реализую карты OpenStreetMap (правда пока без адекватной навигации), а в будущем планирую написать приложение для мониторинга погоды и трекинга посылок. Кроме того, в рамках этой статьи мы реализуем с вами клиент Telegram: так чем же это не функционал современного смартфона?
Но хорошо, с функционалом разобрались, однако для многих читателей слова «старый смартфон» это прямые синонимы «тормозной смартфон», мол «фуу, да как можно пользоваться этим тормозным кирпичом, он же лагает в последней версии моей ВКшечки!». Но давайте поставим вопрос ребром: может, это не столько девайсы немощные, сколько сами приложения, с кодовой базой, которая тянется более 10 лет, откровенно жиреют, обрастают костылями и хаками после далеко не одного поколения программистов, которые над ними работали? :) Один, вот, предпочитал пользоваться чистым AppCompat'ом, другой решил притащить зависимость, которая, например, оптимизирует виртуализацию ListView, третий решил заменить всю сериализацию Json со встроенных классов в Android на что-то стороннее и реализовал это костылями и вот так, по чуть-чуть изначально оптимальный и шустрый код превращается в неповоротливое УГ, которое не рефакторили кучу лет.
На видео Galaxy Pocket Neo — очень дешёвый Android-смартфон из 2011 года с 1-ядерным чипсетом на ~800МГц и 256Мб ОЗУ. При этом всём, Android софтварно рисует все анимации на процессоре, без участия GPU.
А значит у стареньких девайсов всё равно есть шанс быть полезными и стать полноценными повседневными смартфонами даже спустя более чем десять лет после выхода! И в сегодняшнем материале, я вам расскажу об особенностях разработки самопального клиента Telegram с собственным прокси-сервером, которое концептуально допускает реализацию даже на кнопочном Siemens C60 2003 года. Как? Читаем ниже!
❯ Принцип работы
В отличии от ВК (который разрабатывали те же самые люди, что и Telegram), API которого построено на базе REST-запросов и концепции Longpolling'а для моментального получения событий с сервера, Telegram построен на базе собственного протокола под названием MTProto, который может работать поверх любого «транспорта» (протокола нижнего уровня) — TCP, HTTP, WebSocket и т.п. Сам по себе MTProto в современном виде, разработка прожженного математика Николая Дурова и его команды — протокол относительно сложный для реализации «на коленке» и в первую очередь требует довольно серьезного понимания принципов работы современной криптографии, да и документирован он всё ещё не особо хорошо. Кроме того, у MTProto весьма интересный бинарный формат пакетов, эдакий велосипед Protobuf. В долгосрочной перспективе поддерживать свой велосипед MTProto может быть весьма проблематично, учитывая не самую лучшую документацию.
Но городить велосипед и не нужно, поскольку у команды Telegram есть официальная реализация MTProto — библиотека TDLib, которая инкапсулирует в себе не только детали реализации протокола, но и сетевой ввод/вывод и выбор транспорта, хранение базы данных сообщений и авторизации, автоматическую загрузку фото и видео, конвертация объектов из бинарного формата MTProto в JSON и полная многопоточность и частичная потоко-безопасность. С одной стороны это плюс — уже готовое решение для реализации клиента на новой поддерживаемой платформе, где есть OpenSSL (можно статически слинковать), zlib (линкуется статически), сокеты и файловый ввод/вывод, а также довольно неплохой механизм JSON-based API, которое позволяет использовать библиотеку в любом языке, который поддерживает вызов C-функций, а с другой и минус — библиотека довольно много весит, в одиночку прибавляя ~20Мб веса приложения для каждой архитектуры, у неё течёт память и у нее странный механизм получения данных с сервера (например, нельзя ответить на сообщение, зная его ID, если сообщение предварительно не загружено, при том что на сервере весь ответ — это просто ID, на какое сообщение прилетел ответ).
Понятное дело, что на стареньком смартфоне использовать оригинальный TDLib будет проблематичным — даже если собрать либы современным NDK и запилить JNI-интерфейс, библиотека «жрёт» много ОЗУ (20-100Мб «вхолостую», в зависимости от числа диалогов и частоты прилетающих событий, плюс со временем течет до 1-2Гб, если не использовать базу данных сообщений. Скорее всего, это косяк в реализации пулов, объекты из которых выгружаются при сбросе в базу, но не выгружаются при высоком потреблении ОЗУ) и уж тем-более TDLib не запустить на любимых кнопочных Java-сонериках! Поэтому я решил написать прокси-сервер, который отправляет команды, слушает ивенты TDLib и предоставляет REST-like API для клиентских программ, которые просто вызывают какой-либо метод, а в ответ получают простой и короткий строковой датасет только с необходимыми полями, весом до 10Кб (что позволяет его быстро загрузить даже с GPRS-интернетом), который можно быстро распарсить даже на преусловутом Siemens C60!
К сожалению, поскольку TDLib прожорлив, я не смогу захостить на своём сервере инстансы для читателей, которые хотят поюзать приложение, поэтому вам придется ставить и запускать сервер на своём VDS/компьютере с белым IP/роутере, если под него есть .NET Core :)
Клиентом же будет выступать Android-смартфон, где приложение будет фронтэндом данных с сервера. Ничего сложного на первое время нет: первое окно — это список диалогов, второе окно — список сообщений в диалоге + поле для написания сообщения, третье окно — информация о пользователе. Всё это я реализовал за три дня не-напряжной работы «на коленке».
Давайте же перейдем к реализации сервера!
❯ Прокси-сервер
Сервер я решил писать на C#, поскольку у .NET Core сейчас всё очень хорошо с кроссплатформенностью и производительностью. Его можно даже на Raspberry Pi запустить :)
Итак, какая-же архитектура такого сервера может быть? Программа инициализирует TDLib, начинает слушать её события в отдельном потоке, пока в основном потоке крутится HTTP-сервер, который обрабатывает каждый отдельный запрос с клиентского приложения. Почему синхронно? Потому что TDLib фактически не возвращает никаких идентификаторов для возвращаемых датасетов, дабы их можно было отличить друг от друга. Приведу пример: у нас есть метод getChatHistory, который возвращает n-сообщений. При этом TDLib сам определяет, сколько хочет сообщений вернуть (и в первый вызов возвращает одно сообщение вне зависимости от настрое и отправляем пакет message n-раз. При этом в пакете message нет какого-либо ID, который позволял бы ассоциировать текущий объект с какой-либо операцией. Увы!
Начинаем с коммуникации с TDLib. Для работы с библиотекой, мы будем использовать json-интерфейс. Для .NET есть биндинги через C++/CLI, но в таком случае, сервер не будет работать на Linux. Для работы с библиотекой хватит лишь три функции: CreateClientID, которая аллокейтит новый инстанс клиента, Send, которая асинхронно отправляет JSON-объект с командой, которую затем обработает TDLib и Receive, которая ждёт N-секунд и возвращает в виде ASCII-строки (!) JSON-объект с описанием события или данными после одного из запросов. За это у нас отвечает класс TDLibInterface, который объявляет PInvoke-методы для вызова нативных методов из библиотеки. .NET Core сам подгрузит библиотеку tdjson (причём на Linux он добавит ей префикс а-ля libtdjson.so, а на Windows загрузит tdjson.dll) и сам разберется с маршаллингом аргументов функций: например, string автоматически преобразует в const char*. Тем не менее, с const char* возвратами нужно быть аккуратнее — у меня был SIGSEGV, пока я ручками не конвертировал их в обычную строку.
З.Ы: На Пикабу нет отдельного тега для кода, а вставить листинги картинками я не могу из-за ограничения на 25 медиаэлементов. Так что листинги будут совсем без табов, но алгоритм их работы понять можно :)
Позволю себе чуточку критики в сторону TDLib. Во первых, почему нет s-версии функции с возможностью указать длину входной строки, а tdjson полагается исключительно на \0 в конце строки? Во вторых, почему const char*, а не wchar_t*? Сейчас юникод во входной строке приходится escape'ами превращать в \u-последовательности. После этого, нам нужно написать обёртку над TDLib, которая будет вызывать для зарегистрированных событий специальные функции, называемые коллбэками. При этом закомментированный WriteLine снизу — это «дебаг» для того, чтобы узнать названия неизвестных мне ивентов :)
В каждом объекте, полученном с помощью receive, есть поле "@type", которое содержит в себе имя класса возвращаемого объекта. Первый же вопрос от читателей — почему я использую JObject с ручным дерганьем нужных полей и вручную пишу JSON в виде строковых литералов вместо нормальной сериализации/десериализации? Ответ прост: во-первых, для актуализации Data-классов придется писать кодогенератор из TL-схемы, а во-вторых иногда TDLib может возвращать немного разные объекты в JSON, из-за чего приходится мудрить с атрибутами на этих самых Data-классах, иначе десериализатор выбросит исключение. Это решается нормальными юнит-тестами на всех вариантах данных, но зачем себе в колени стрелять, если нужен конкретный фиксированный функционал и лишь малое число от всех полей, возвращаемых TDLib?
string recv = NativeInterface.Receive(10.0d);
if (recv != null) { JObject json = JObject.Parse(recv);
if (!handlers.ContainsKey(type)) { //Console.WriteLine("Unknown event type: {0}", type); continue; }
handlers[type](recv, json); }
Теперь переходим к самому интересному — обработке событий и реализации синхронного клиента, который позволяет без async/await просто запросить список сообщений и сразу же его получить (такой подход может быть полезен и юзерботам, которые не хотят размазывать стейты по всей программе). Почему без асинков? Честно сказать, мне они просто не нравятся: как привык к концепции wait/notify и коллбэков из Java, так их и юзаю всю жизнь :)
Сначала TDLib запрашивает параметры инициализации (стейт authorizationStateWaitTdlibParameters), затем если пользователь не авторизован — запрашивает номер телефона и код подтверждения (плюс дополнительные шаги для авторизации если они есть). В конце, TDLib возвращает стейт Ready, что означает готовность библиотеки к работе:
После этого, можно начать работу с данными. Обратите внимание, мой подход потоко-небезопасен, его нельзя дергать из нескольких потоков одновременно! В коде ниже, я вызываю метод для фетча сообщений, а затем в соответствующем коллбэке от TDLib обрабатываю данные (дабы статья не разрасталась на 20+ минут, я чуть урезал все листинги).
public List<Message> QueryMessagesInChat(long chatId, long lastMessage, int count) { messages.Clear();
public User QueryUser(long userId) { string json = Utils.Format("{\"@type\": \"getUser\", \"user_id\": \"{0}\" }", userId); NativeInterface.Send(InstanceID, json);
waitHandle.WaitOne(); return user; }
Переходим к реализации самого сервера, для наших целей хватит обычного HttpListener. Сначала мы зарегистрируем все поддерживаемые методы и занесем их в ассоциативный список ключ-значение. Сами методы реализованы в виде делегатов, которые принимают лишь один аргумент — список параметров из строки запроса, а возвращают строку — все ответы, за исключением особых (связанных с загрузкой вложений) — текстовые.
Переходим к обработке запроса. Метод ищет, зарегистрирован ли запрошенный метод и если да, то парсит строку запроса, которая начинается с "?", которую затем передаёт в виде коллекции ключ->значения обработчику метода:
А сами методы, в свою очередь, дергают соответствующие функции из клиента и формируют на их основе датасет в примитивном формате:
public staticstring QueryChats(Dictionary<string, string> args) { if(args.ContainsKey("count")) { int count = int.Parse(args["count"]); StringBuilder ret = new StringBuilder();
В результате получаем вот такой простой датасет, который, как я и говорил, легко распарсить и на Siemens C60, и на Atmega328 — да где угодно! В целом, такой сервер можно использовать для реализации бота в телеграме, который будет передавать показания каких-то датчиков, сигнализацию и прочие клевые штуки!
Переходим к реализации клиента, т.е. приложения на Android. Здесь будет не менее интересно!
❯ Пилим для Android
В геймдеве есть своеобразный мем — некоторые инди-разработчики сначала начинают делать меню, вместо основного геймплея, что становится предметом насмешек среди других разработчиков. Но в разработке приложений для смартфонов всё по другому — здесь как-раз таки хорошо заранее продумывать макет будущего приложения!
Поскольку у нас с вами мессенджер, то главный экран должен представлять из себя список чатов (ListView) и верхнюю панельку, где в будущем могут разместиться настройки и свайп-менюшка:
Такой вот простой макет.
Каждый пункт меню — это тоже отдельный layout, в котором мы по шаблону строим внешний вид будущего элемента списка. На немолодых устройствах есть смысл использовать как можно меньше контейнеров в layout'е, поскольку пересчет позиций и размеров элементов — одна из самых «тяжелых» операций в UI-фреймворке вообще. Кроме того, не стоит использовать кучу картинок и drawable — в Android 2.x всё 2D рисуется софтварно, аппаратное ускорение появилось только в 3.0 (частично).
Но дабы в списке диалогов что-то появилось, нужно сначала реализовать фетчинг (получение) этих самых диалогов с сервера! Сам объект, который занимается обработкой запросов называется ClientManager и является синглтоном — он в единственном экземпляре на все время работы программы. Помимо менеджмента «ноды» (т.е. прокси-сервера), токена для авторизации и обработчика ошибок, ClientManager реализует метод для асинхронного запроса информации с сервера и, собственно, формирует строки запросов с помощью соответствующих методов:
Подгрузка чатов и сообщений реализована через Adapter — концепция «виртуальных» списков, которая предполагает что система создаст не 50 элементов интерфейса на каждую кнопку чата, а только 5 и будет их виртуально «мотать по кругу», обновляя только данные в уже существующих элементах. Это позволяет значительно ускорить отрисовку, учитывая то, что Android 2.x Canvas рисуется программно.
Ну вы уже явно замучились видеть простыни кода, давайте посмотрим что у нас вышло!
Шустренько, да? А ведь это ультрабюджетник Alcatel OT-916D, один из последних массовых дешевых QWERTY-смартфонов за 5 000 рублей из 2012 года. Кстати, смартфон подарил мне читатель chuvakoff с Хабра!
Переходим к окну чата. Основной макет почти такой-же, как и у основного окна: только добавилась панелька для ввода сообщения снизу.
Концептуально, всё тоже самое — запрашиваем данные с сервера, парсим их и загружаем в адаптер, благодаря чему мы сможем листать наш диалог. Однако в сообщения я добавил контекстное меню с стандартными фишками типа копирования, ответа и прочих подобных действий. Поскольку у нас нет ни пушей, ни еще каких-либо средств для поулчения данных о новых сообщениях, я раз в определенный интервал просто получаю сообщения — и если новый датасет отличается от старого — обновляю окошко чата.
Переходим к реализации поля для ввода сообщения. Здесь всё просто — на серверсайде за это отвечает метод SendMessage. Однако для того, чтобы с нашего клиента можно было ответить на другие сообщения, я ввёл также «контекст ответа», в котором запоминается сообщение, на которое мы хотим ответить. Telegram также поддерживает Markdown, однако его полная поддержка пока не реализована.
В остальном же, функционал конечно пока совсем базовый, однако клиент работает очень шустро даже бюджетной X10 Mini Pro и позволяет чатится с моими читателями в Telegram. В будущем хотелось бы допилить:
Поддержка картинок: Сейчас уже есть кривоватый механизм кэширования изображений на стороне сервера, который позволяет загружать аватарки чатов. В будущем, я добавлю поддержку «галерей» с картинками!
Поддержка голосовых сообщений: Не все их любят, но они порой удобны и выручают. Реализую как прослушивание, так и запись!
Подробный просмотр профилей и менеджмент чатов: Удаление сообщений, чатов и прочие фишечки из официальных клиентов.
Казалось бы — до официальных клиентов ещё очень далеко. Но сам факт, чтобы всё это работало достаточно шустро на девайсах, которым уже более 10 лет!
❯ Звучит интересно! Как заюзать твой клиент?
Тут всё очень и очень просто! В первую очередь, нам понадобится ПК с белым IP, роутер (если под него есть сборка dotnet), либо VDS. Виртуальные сервера сейчас стоят копейки, у ТаймВеба есть тариф за 188 рублей в месяц, которого с головой хватит для нашего сервера.
Такая вот рекламная интеграция (к слову, прокси для всех приложений уже более года крутятся именно на мощностях TimeWeb Cloud)!
Программа сначала запросит номер телефона, а затем код подтверждения Telegram. После этого будет создана папка tdlib/, где будут хранится данные вашей сессии, а также файл authkey.txt, где хранится случайный ключ для сессии (md5 phone_number + response code + псевдослучайное число). Не оставляйте его в /var/www/!
Если всё нормально, программа начнёт слушать порт 13377 на всех сетевых интерфейсах, в т.ч и в локальной сети. После этого, ставим уже предварительно собранный, либо собираем сами в Android Studio APK и в окне авторизации пишем адрес ноды и ключ авторизации. Если всё настроено верно — программа запомнит сервер и будет работать без проблем! Вот так всё легко :) Как видите — всё очень и очень просто!
Кроме того, буквально за пару дней до публикации статьи я сел вечерком из интереса что-нить под Java-телефоны попилить… и, как и обещал, реализовал Proof of Concept возможности работы Telegram даже на сонериках, которым скоро 20 лет стукнет! А ведь если ещё чуть заморочится, можно запустить приложение даже на преусловутых монохромных сименсах!
❯ Заключение
Вот такой у нас получился проект с реализацией лёгкого, примитивного, но тем не менее рабочего клиента Telegram, который на клиентской части вообще не использует никаких зависимостей. Вес собранного APK в release-версии — всего 54 килобайта! Понятное дело что с ростом функционала, вес программы будет увеличиваться, но я обещаю — больше 1Мб он не вырастет :)
Ну а вам, моим читателям, надеюсь было интересно прочитать такой «двойной материал» не только о разработке сетевой части без использования Apache/nginx/IIS, но и UI-фронтэнда для Android-смартфонов, которым уже более 10 лет! Исходный код проекта можно найти на моём GitHub: как приложения, так и сервера, а также убедиться в отсутствии каких либо закладок и, если совсем не доверяете, собрать бинарники сами! Для сборки понадобится VS2017 или свежее, а также Android Studio 2.3.2 (если собираете для Android 2.1 и ниже).
Друзья! Сейчас на Хабре опросы сломаны, поэтому если у вас есть желание, вы можете проголосовать в комментариях: какой стиль статей вам больше нравится — где больше конкретики и кода с пояснением как конкретно работает та или иная часть программы, или наоборот стиль ближе к научпопу, где фрагментов кода нет, или их значительно меньше? Пишите своё мнение о проекте в комментариях!
Кроме того, у меня есть канал в Telegram, куда я публикую бэкстейдж статей, ссылки на новый материал, свои наработки, а также посты о ремонте девайсов и различные мысли.
Статья подготовлена при поддержке TimeWeb Cloud. Подписывайтесь на меня и @Timeweb.Cloud, чтобы не пропускать новые статьи каждую неделю!
Друзья, приветствую всех! В очередной раз призываю силу Пикабу, поскольку не смог разобраться в проблема самостоятельно.
В приложении Youtube Revanced в окне просмотра видео появился черный экран и надпись по-английски, "The following content is not available on this app. Watch this content on the latest version of Youtube".
Проблема в том, что теперь не помню, где качал этот Revanced, в поисковике отображается куча разных сайтов и, причем, с совершенно разными приложениями, как я думаю, это закосы под Вансед...
Люди добрые, помогите разобраться в проблеме. Как установить нормальный Вансед или Ревансед и где его скачать???
Осторожно: в статье аппаратная диагностика и ремонт, реверс-инжиниринг и патчинг загрузчика, а также программный моддинг noname-устройства, для которого нет вообще никакой информации. В материале куча познавательного контента, даже если вы не фанат такого своеобразного класса устройств, как подделки на брендовые девайсы.
Пожалуй, споры о том, какая мобильная платформа лучше не утихнут никогда. Люди из года в год спорят, какая же мобильная платформа круче: iOS или Android, и какие только аргументы не выдвигают в сторону оппонента. Но что делать, когда хочется усидеть сразу на двух стульях и иметь смартфон в корпусе iPhone, но при этом с привычным Android на борту? Когда душа моддера и любителя красноглазия просто требует чего-то необычного!? Правильно, обратиться к китайским «подвалам» и взять себе дешевую реплику на андроиде! А в моём случае — ещё и Б/У утопленную подделку 14 Pro Max чуть больше, чем за «тыщу» рублей, так ещё и проапгрейдить её! Сегодня будет познавательный и интересный материал, в котором мы с вами: узнаем как диагностировать некоторые аппаратные проблемы с помощью минимального и дешевого оборудования, оживим наше «яблочко» после попадания влаги, «отреверсим» и пропатчим в IDA Pro загрузчик, дабы разрешить загрузку unsigned-ядер, портируем кастомное рекавери и накатим рут, а также узнаем что из себя представляет такой «айфон» в повседневной жизни и как мне вообще взбрело в голову купить китайскую подделку яблочной техники! Материал диковинный, но обещаю — будет интересно! Жду вас под катом :)
❯ Содержание
Ещё каких-то 10-12 лет назад люди собирались в комментариях под различными постами и жарко спорили о том, чья платформа более продвинутая. Чаще всего темой спорой была iPhone vs Android, реже — iPhone vs Windows Phone, а иногда и Android vs Symbian! Но годы идут, на рынке осталось только два крупных игрока, а споры всё не утихают. Стоит только зайти на профильный сайт, зайти в любой пост с новостями и насладится всеми прелестями споров «A vs B». Кто-то поддерживает экосистему Apple, кто-то Android в чистом виде, а кто-то микс фишек Apple в Android окружении от Xiaomi. Некоторые люди даже поддерживают, казалось бы, «неактуальные» платформы как Symbian/WP и среди них есть мои читатели (я и сам очень люблю их и запилил клиенты ВК и YouTube на них, о чём рассказываю в отдельной статье) :)
Но как мои давние читатели наверняка знают, я лично всегда придерживался позиции, что и iOS, и Android, и Symbian, и WP — замечательные системы, которые так или иначе нашли своего пользователя. У меня сейчас есть довольно много смартфонов прошлого десятилетия: полтора года назад я взял себе Galaxy S4 Mini в качестве основного девайса, год назад ходил уже с обычным Galaxy S4, а чуть больше полугода назад читатели подарили мне оригинальные iPhone, от 2G до 5s! И лично я очень люблю iPhone за отличный дизайн, за шуструю iOS, за достойную поддержку старых девайсов, но в тоже время… я ведь и сам вырос на 4pda, пользуясь ультрабюджетными «декспами», «зте» и «флаями»! И тяга к аппаратному и программному моддингу, а также написанию хоумбрю-приложений и прочим фишкам действительно открытых платформ отнюдь не угасла, скорее только наоборот!
Поэтому от нового девайса, с которым я хотел бы походить как с основным, я требовал лишь три вещи:
Дизайн одной из последних моделей iPhone. Пожалуй, кто-то из читателей сочтет это за «тупой понт», но это не совсем так, яблочные дизайны действительно неплохо продуманы и их приятно держать в руках. Важно понимать, что выпуская подделки, заводы откровенно экономят на железе, но при этом стараются достаточно качественно скопировать корпус, используя в конструкции и алюминий, и каленое стекло, а также установить относительно неплохую IPS-матрицу, пусть и низкого разрешения.
Поддержка LTE. Вы удивитесь, но да, всё ещё выходят реплики iPhone, Samsung, да даже Poco и Realme, которые построены на базе чипсета 2015 года — речь, конечно же, о MT6580. И к сожалению, радиотракт этого чипсета не умеет работать с LTE, да и у платформы очень серьезные ограничения на объём ОЗУ (не более 2Гб) и разрешение дисплея (не выше HD) :(
Android на борту. Ну, по этому пункту я всё рассказал выше. При этом для меня не имеет значение версия системы, я не гонюсь за самыми новыми фишками: китайцы уже не ставят Android ниже 6-7 версии (впрочем, это спорно, предположительно ещё попадаются девайсы с 5.1 на борту среди самого дешевого сегмента), а «шестерки» мне вполне достаточно для всех моих применений, в том числе и YouTube с ВКшечкой. Чего там говорить, если мне чего-то действительно не хватает и у меня есть настроение — я сам себе запилю приложение :) Касательно статуса загрузчика я не волнуюсь: в «подвальных» девайсах практически никогда не бывает секьюрбута и нет никакой необходимости патчить загрузчик, что открывает широкие возможности к его моддингу. Эх, вот бы еще исходники ядер выкладывали — но это уже мечты :)
И под эти требования вполне попадают «новодельные» реплики последних моделей iPhone в среднем ценовом сегменте (от 10 000 рублей). Казалось бы, кто-то из читателей спросит: «автор, ты дурак за фуллпрайс брать такой девайс?». И нет, не дурак, поскольку смартфон я купил за 1 500 рублей (и это ещё дорого за его состояние, после покупки мне попался похожий девайс, но уже рабочий, с коробкой и всего за 500 рублей). Девайс продавал человек из СЦ, с которым мы состоим в одной беседе посвященной ретро-телефонам. Смартфон был заявлен как «невключайка» без признаков жизни, в непонятном состоянии, с битой задней крышкой и даже без базовой информации, такой, как о потреблении девайса на зарядки и при зажатой кнопке включения. Ну, как вы и сами понимаете, это настоящее комбо: не подающий признаков жизни китайский смартфон без какой-либо сервисной документации и схемы, который уже побывал в СЦ (потенциально в качестве донора) и наверняка разбирался, да ещё и, как потом оказалось, утопленный в воде… Это же только интереснее! Конечно берем!
Когда девайс приехал ко мне, то ещё до прихода домой я решил оценить его тактильные качества. Конечно, задняя крышка, увы, была подбита, но в целом мне всё равно девайс очень понравился. Как я уже сказал, рама смартфона выполнена из алюминия (за исключением толкателей кнопок), а задняя крышка из стекла с приятной на ощупь текстурой и, конечно же, выгравированным яблочком! Пока дисплей выключен, даже рамки дисплея едва ли дают себя выдать: по сути, определить реплику сможет только человек, который в теме яблочек и сможет опознать фейковые линзы с обратной стороны смартфона. Остальным можно наплести про «китайский дисплей» и т. п. :)
Придя домой, я понял — приключения только начинаются. Отклеив заднюю крышку с помощью фена, выяснилось, что девайс вскрывался: пару винтов потеряли, да и заводскую пломбу содрали.
Замеряем напряжение на АКБ и понимаем, что она села ниже 3.4В (3.5В — это уже 0%) и контроллер питания должен начать зарядку в режиме Precharge (режим «расталкивания» аккумулятора низким током). В режиме Precharge смартфон не показывает никакой индикации зарядки, поэтому остаётся лишь смотреть на потребление девайса и терпеливо ждать включения! Я ещё немного помог устройству раскачать АКБ с помощью внешнего 5В источника и вот, потребление поползло выше 0.2А — а девайс показал яблочко и индикацию зарядки. Неужели он рабочий?
На фото выше не видно, однако смартфон был залит водой и на дисплее появились большие разводы. И попадание воды не прошло просто так: он просто перезагружался на «яблочке», как и настоящий айфон… Вы, читатели, можете пока предположить, что же с девайсом было не так, а я включаю логическое мышление и перехожу к диагностике.
Друзья! Если вам не особо интересны технические детали аппаратного ремонта, или наоборот программного и вы хотели увидеть только обзор на устройство — можете прыгнуть сразу к обзору смартфона. Однако в технической части тоже много всего интересного!
❯ Диагностируем и ремонтируем
Итак, давайте сделаем выводы, которые мы можем понять из существующих симптомов:
Девайс заряжается и у него есть потребление, пусть оно и кажется заниженным, а значит модуль чарджера в контроллере питания, скорее всего, исправен.
Девайс включается и есть изображение яблочка, а значит, есть связь с eMMC и контроллер DDR инициализируется успешно, девайс проходит цепочку загрузки Preloader -> LK и возможно ядро, а также КП нормально реагирует на кнопку включения и включает необходимые выходы LDO для питания всех основных модулей смартфона (процессор и его периферия, чип памяти eMCP, драйвер bias-напряжений дисплея и т. п.). Скорее всего (но это не 100% гарантия), от воды не пострадали ни процессор, ни флэш-память.
Девайс уходит в перезагрузку: здесь причин может быть масса, например, данные на eMMC были повреждены в процессе залития и требуется прошивка, или всё же процессор или его обвязка оказались частично повреждены и при обращении к одному из встроенных периферийных модулей основное вычислительное ядро виснет и встроенный в КП WatchDog при отсутствии сигналов «сердцебиения» считает смартфон зависшим и отправляет его в намеренный ребут, из-за чего мы получаем циклическую перезагрузку. Не исключён вариант, что одна из внешних шин данных оказалась посаженной на массу в следствии КЗ одного из чипов на плате (или их обвязки), из-за чего драйвер, например, вываливает систему в Kernel panic и WatchDog также отправляет систему в ребут…
Наш девайс отказывался зайти в рекавери, что даёт нам понять, что до init дело скорее всего не доходит и девайс стопорится либо на LK (который и показывает анимацию зарядки и первое лого), либо на загрузке ядра. Казалось бы, столько причин, а метод лечения у многих ребят один: сейчас будем делать диагностический прогрев, а потом снимать все чипы и катать их, и если не поможет — глянем обвязку и межслойные обрывы :) Но не стоит так торопиться, ведь в некоторых случаях для диагностики аппаратных проблем можно использовать программные инструменты!
Дело вот в чём: многие китайские производители, особенно это касается ультрадешёвых смартфонов и планшетов, специально оставляют диагностические пятачки, которые дублируют контакты АКБ, если вы случайно сорвали пятачки при пайке аккума, USB, если вы не смогли найти китайский Lightning под замену, а также пятаки UART, иногда даже на несколько каналов, которые позволяют читать логи — диагностическую информацию, которую девайс выводит при загрузке и работе устройства! И порой, подписанные пятачки с включенным дебагом на UART'е полезнее даже полной схемы устройства с бордвью!
На фото отмечены пятаки, дублирующие USB
Ой-ой, а ведь присмотревшись к плате, мы увидим, что кто-то снимал защитный экран и пытался прогревать BT/Wi-Fi/FM комбочип, а также то, что вся плата в подтеках флюса! Да ещё и всю обвязку кто-то посдувал фиг пойми куда, да так, что часть обвязки лежала прямо на пинах комбочипа, а у нас ведь даже схемы нет! Не беда — эти смартфоны построены на базе референсной платы MediaTek и с большой вероятностью, обвязка будет расположена идентично с другими смартфонами на базе этих чипсетов. Но в моем случае, я просто поставил SMD-компоненты туда, где они, очевидно, стояли: резисторы к резисторам, конденсаторы к конденсаторам, а иных элементов у меня пока-что не было. Дабы комбочип точно не вмешался в работу устройства, я временно его сдул с платы:
За качество фото извиняюсь, сделано в попыхах
Я сразу же снял дамп своего устройства и нашел по платформе прелоадера и названию сборки оригинальную прошивку (линк в описании, решил оставить оригинальную ссылку, поскольку автор нормальный и не просит писать ему в мессенджеры за паролем для архива), дабы исключить вероятность косяка со стороны eMMC.
Обратите внимание — я сначала сделал дамп, дабы в случае неподходящей прошивки, прошить свою или собрать из двух прошивок одну! Поскольку мой китайский псевдолайтнинг уже был слегка подуставший (хотя 14 Pro Max ещё относительно свежий девайс) и сигнальные линии D+ D- были просажены, а девайс не определялся ПК, я отключил нижнюю плату АКБ и подпаялся напрямую к дублирующим пятачкам USB: после этого, девайс определился в системе как MTK Preloader, что дало мне возможность прошить официальную прошивку, но ожидаемо, эффекта это не принесло — смартфон всё так же перезагружался на яблочке :(
Затем я решил подпаяться к UART'у и всё же почитать логи подробнее: для этого, нам пригодится UART-преобразователь. Также, в качестве UART-преобразователя подойдет и ESP32, который частенько можно найти в местных радиомагазинах за копейки. Сигнал EN необходимо кинуть на 3.3В - это погрузит МК в RESET и не даст ему влиять на шину!
Подпаиваемся так, как я отметил на фото ниже, не забывая подключить общую массу. Для чтения UART'а я использую putty.exe: выбираем наш COM-порт, ставим бодрейт 921600 и запитываем девайс: теперь у нас побежали логи…
С левой стороны каждой строки лога написано время с момента старта ядра — т. н. «аптайм». На него тоже важно обращать внимание, поскольку он помогает приблизительно понять, на каком визуальном (т. е. то, что мы видим на дисплее) этапе стопорится загрузка. Мой девайс падал в Kernel panic и уходил в перезагрузку на 30 секунде работы… казалось бы, что можно понять из этих логов и как определить неисправность? Вот тут мы фокусируем наше внимание на двух строках:
Первая — это то, что у нас пытается проинициализироваться драйвер stk301x — датчика освещенности и приближения к уху, а вторая, где написано таймаут — означает об ошибке передачи данных на шине I2C к устройству по адресу 47. И чтобы понять суть ошибки, нам нужно иметь базовое понимание о принципах работы самых часто применяемых аппаратных протоколах для общения с другими чипами: SPI, I2C и 8080. В протоколе I2C, у каждого устройства есть собственный адрес, выраженный в 7-битном формате (до 127 адресов на одной шине), в случае stk301x — это 47. Что делает драйвер: он посылает датчику набор команд для инициализации или получения данных, при этом на хост-устройстве (т. е. процессор в нашем случае), сначала формируется состояние СТАРТ и посылает всем устройствам на шине адрес нужного устройства. Затем, нужный чип должен «подхватить» свой адрес и на все байты передаваемых данных формировать статус ПОЛУЧЕНО (ACK). Если статус ACK не получен аппаратным I2C-контроллером процессора телефона за определенное время (допустим, 1 секунда), то он формирует прерывание (или просто изменяет статусный регистр), который обрабатывает драйвер контроллера I2C, который затем и выдает драйверу датчика статус таймаут, а тот в свою очередь выводит ошибку в логи!
Пример с сайта компании Microchip
Всё равно ничего не понятно? И снова мы с вами включаем смекалку. Если устройство жалуется на отсутствие состояния ACK, значит, возможны две причины поломки: обрыв линии SDA/SCL до устройства, либо то, что в следствии попадания воды, одно из периферийных устройств «сгорело» и садит всю шину I2C на массу, из-за чего, например, драйвер другого устройства на шине I2C крашится, а поскольку это драйвер работающий в пространстве ядра — он тащит за собой все! Может быть и такой вариант, что драйвер КП не может посылать сигналы Heartbeat из-за просаженной шины и КП отправляет устройство в ребут.
Сдуваем наш датчик освещенности, включаем девайс и он вроде даже не выключился спустя 30 секунд… проходит пару минут и…
Решил вставить оригинальное фото первого включения, как раз сделанное «по быстрому» и в порыве радости :)
Он включился и работает! Он выжил, хотя разводы воды заметно сказались на состоянии его дисплея! Но поскольку комбочип пока что выпаян, у нас не будет ни Wi-Fi, ни BT, ни GPS, ни радио. Поэтому отключаем девайс и припаиваем обратно комбочип, не забыв восстановить всю обвязку. В финале мы отмываем плату от подтеков флюса (не весь флюс мне удалось нормально вымыть, потому что старый прикипел).
После установки комбочипа и остатков обвязки (а может, это и вся обвязка что была с завода, китайцы ведь часто экономят и на этом — ставят необходимый минимум), я проверил и Wi-Fi, и BT — теперь девайс звонит и без проблем выходит в интернет!
На этом аппаратный ремонт закончен. Поскольку девайс теперь работает, можно приступать к его программному моддингу! Но сначала, нужно отключить проверку подписи образа ядра.
❯ Патчим загрузчик
Как я уже говорил выше, в подобных репликах и просто дешевых noname-девайсах фактически отключен полноценный секьюрбут. Однако конкретно в этой реплике, при сборки прошивки, производитель включил в lk (загрузчик второго уровня) принудительную проверку подписи у образов ядра boot.img и recovery.img, предварительно включив возможность его отключения (т. е. разблокировки загрузчика) в режиме fastboot. На многих девайсах достаточно лишь перезагрузить устройство в режим fastboot и выполнить специальную oem-команду:
adb reboot bootloader fastboot oem unlock
Которая вызовет соответствующий диалог. Но вот незадача: девайс не реагирует на кнопку вверх, из-за чего загрузчик разблокировать не получается. Намеренная подлянка от производителя? Скорее недосмотр при проектировании платы, благо исходный код вторичного загрузчика LK, который и реализовывает режим fastboot сливали в сеть. Давайте изучим его подробнее!
Итак, что мы здесь видим? При запросе разлочки устройства, девайс падает в бесконечный цикл, в котором проверяет и реагирует на одну из соответствующих клавиш — громкость вверх, или кнопка «ОК», которая считается кнопкой вниз. Почему же девайс не определяет кнопку вверх? В чипсете есть отдельный периферийный модуль, который отвечает за обработку Keypad-кнопок клавиатуры. Он же позволяет реализовать полноценную QWERTY-клавиатуру без внешних контроллеров, если того захочет производитель. Однако он оперирует не конкретными логическими уровнями на GPIO (иначе потребовалось бы слишком много пинов и, скорее всего, сильно увеличивать размер чипа), а специальным АЦП (аналогово-цифровой преобразователь) с низким разрешением, который вычисляет, какая кнопка нажата относительно определенного сопротивления. Следовательно, если производитель каким-то образом накосячил при разводке платы и резистором иного номинала «присвоил» громкости вверх другой аппаратный KeyCode-клавиши, функция mtk_detect_key банально не «увидит» нажатие нужной нам кнопки, которая захардкожена как 0x0.
Но почему тогда в Android, кнопка громкости вверх работает нормально?
У Android есть отдельный механизм для маппинга кнопок, называемый keylayout'ами. В текстовом файле хранятся ассоциации числовых KeyCode'ов с константными обозначениями, такими как VOLUME_UP и VOLUME_DOWN например. Поэтому вы без проблем можете поменять их значение местами, или, например, если у вас сломалась кнопка включения, переназначить её на громкость вверх без необходимости кидать перемычку!
Подробнее о подсистеме ввода в Android я рассказывал в другой своей статье.
Как же это поправить? Не собирать же нам lk самим, да и будет ли пропатченный загрузчик работать? И да, будет! Как я уже сказал, в девайсе не включен полноценный секьюрбут с верификацией того, что вы прошиваете через FlashTool в внутреннюю память устройства. Preloader (первичный загрузчик после BootROM) не проверяет ни целостность lk, ни хэш-суммы, просто читает его в 0x0 и передает ему управление… А что это значит? Что мы можем просто пропатчить условие, отвечающее за «громкость вверх», дабы lk считал, что мы все таки нажали эту кнопку! Открываем дизассемблер IDA Pro и наш lk.bin в нём, как обычный binary-файл со смещением 0x0 и ищем те строки, которые встречаются ближе всего к нужному нам условию. В нашем случае, это Start unlock flow.
Как видите, IDA Pro, как самый крутой дизассемблер по моему мнению, уже построил xref'ы (все ссылки на бинарные данные из инструкций) и сразу показывает нам куда обращается тот или иной код. Опана! А вот мы и нашли код функции, которая отвечает за старт анлока загрузчика и проверяет нажатые кнопки. Что же нам с этим делать? Правильно, переключится в режим графа и анализировать код подробнее. Я не так силен в ARM-ассемблере, как x86, но всё же не без помощи ISA-мануала от ARM понял значение всех мнемоник.
Обратите внимание на инструкцию BL — она вызывает подфункцию и сохраняет адрес PC + длина инструкции в стек, дабы продолжить выполнение после возврата из неё. Это и есть вызов нашей функции mtk_detect_key. Оптимизатор сократил код так, что сразу после возврата из функции, её возвращаемое значение оказывается в регистре R4, который программа переносит в регистр R0, а затем сравнивает R0 с нулем. Если R0 оказывается ноль (инструкция BEQ, branch if equal to zero, т. е. кнопка не нажата), программа прыгает к проверке кнопки «вниз», а если нет — то продолжает выполнение кода, который стартует разблокировку загрузчика. Уже смекнули, о чем я? Нам достаточно лишь пропатчить CMP R0, #0, дабы заставить программу считать, будто кнопку мы все таки нажали и перейти к процессу разблокировки!
Обратите внимание, что в #0 (т. е. с решеткой) — это Immediate-значение, которое уже является операндом инструкции, а не загружается, например из регистра, а значит мы можем просто найти это значение в HEX-редакторе и пропатчить его на 1, либо просто NOP'нуть всю инструкцию. Адрес операнда инструкции — 0x1FB0C, поэтому сразу переходим к нему в hex редакторе и просто меняем 0 на 1 и сохраняем:
Прошиваем новый lk.bin с помощью SP Flash Tool, перезагружаемся в fastboot, пишем fastboot oem unlock и… сработало! Смотрим статус разлочки с помощью fastboot oem device-info (unlocked и secure) и видим что девайс действительно разлочен! Теперь смартфон каждое включение будет напоминать нам о том, что мы разлочили загрузчик. Ну разлочили и разлочили, зато теперь у нас полная свобода действий :) Переходим к ответственному действияю — портированию рекавери и накатыванию рута! Но здесь всё уже гораздо проще.
❯ Портируем рекавери и накатываем рут
Поскольку мы с вами уже разблокировали загрузчик, то и без проблем можем грузить что захотим: и LineageOS, и MIUI — всё что уже портировано для этого чипсета на этой версии ядра. Правда не забывайте, что чипсет 64х-битный, множество прошивок — тоже, а китайцы почему-то собрали 32х-битную прошивку — это стоит иметь ввиду при портировании. Если честно, изначально я хотел включить часть с портированием прошивки в основную статью, но опросив читателей понял, что вам не особо комфортно читать статьи 20+ минут длиной, поэтому если вам интересен подробный материал о портировании прошивки без пересборки ядра на нонейм устройствах — проголосуйте в опросе ниже (или маякните в комментариях)!
Начинаем с накатывания «кухни». Я пользуюсь MTK Img Tools, весьма удобный софт. Для его использования, нужно вручную создать папки Pack/Image и Unpack/Image.
Закидываем в папку Unpack/Image родной recovery.img, и тот, который будем портировать — назовем его recoverytwrp.img. Распаковываем их в менюшке Unpack image -> Boot. После распаковки, у нас появятся папки recovery и recoverytwrp в папке Unpack, где мы и будем вести нашу работу. В целом, на MT6753 в нашем случае достаточно лишь перенести родное ядро в тот рекавери, который мы портируем. fstab же трогать не нужно. Делается это легко: просто копируем recovery/kernel/kernel в recoverytwrp/kernel/kernel с заменой и пересобираем образ командой Pack image -> Boot обратно. Собранный образ мы найдем в папке Pack/Image, его можно либо прошить в флэштуле взамен стандартного, либо загрузить прям из фастбута без необходимости прошивать память устройства (это, кстати, ещё один отличный способ грузить Android с MicroSD если флэшка «закончилась»).
fastboot boot recovery.img
Кастомный рекавери загрузился без проблем — а это значит, что нам открыты большие возможности по кастомизации нашего девайса! Берем SuperSU с официального сайта, прошиваем SuperSU.zip с помощью adb sideload и балдеем, теперь с полноценным рут-доступом к устройству и без необходимости патчить Magisk'ом или распаковывать раздел system!
Теперь можно вычистить весь мусор из предустановленных приложений благодаря спец. софту для менеджмента приложений на смартфоне.
❯ Можно ли пользоваться девайсом?
Давайте посмотрим! Девайс из коробки похож на iOS 16, при этом, поскольку такие «айфоны» работают на общей аппаратной платформе, теоретически есть возможность поставить на 12 Pro Max прошивку от, например, 15 Pro Max (с некоторыми изменениями) :)
Функционал системы скопирован достаточно точно. На некоторых репликах особо не заморачиваются и просто чуть изменяют значки на айфоновские, не убирая даже нижнюю панель кнопок. Здесь же все скопировано с настоящей iOS: свайп снизу вверх сворачивает приложение, свайп до центра экрана открывает меню многозадачности, свайп шторки с левой стороны открывает панель нотификаций, а справа — панель управления. И ведь это не просто чужие готовые лаунчеры из условного Play Market, компания-производитель либо аутсорсит копирование некоторых фишек разработчикам на стороне, либо держит свой собственный штат программеров, который, в том числе, занимается сборкой прошивок и портами с рефборды!
В настройках, система гордо называет себя iOS, а модель смартфона — iPhone 14 Pro Max! Но что на практике? CPU-Z говорит о следующих характеристиках:
Тоже не знали, что Apple A16 разрабатывала MediaTek? :)
Более половины характеристик — брехня. Настоящие спецификации девайса следующие:
Процессор: MediaTek MT6753. 8 ядер Cortex-A53, 4 из которых работают на частоте 1.5ГГц, а оставшиеся — на частоте 1.3ГГц. Чипсет выпущен в 2015 году и выполнен по техпроцессу 28Нм, поддерживает до 3Гб ОЗУ.
GPU: Mali T720, преемник легендарного Mali 400. Уже немолодой, но всё ещё кое-что, да может. Vulkan не умеет.
ОЗУ: 3Гб DDR3. Не так много, но в целом пока ещё относительно адекватно.
Флэш-память: хотели 512Гб? Получите 32Гб, а недостаток можно нарастить MicroSD-флэшкой, слот под которую производитель заботливо предусмотрел под крышкой устройства. Это частая практика для китайских айфонов.
Дисплей: с диагональю не наврали, честные 6.7". А вот с разрешением, конечно-же, приукрасили: здесь стоит HD+ IPS матрица с разрешением 720x1540. Не особо высокое разрешение для такой диагонали дисплея, но в остальном дисплей показывает себя адекватно: яркость приемлемая, цвета хорошие, матрица отзывчивая.
В целом, характеристики ближе к ультрабюджетным моделям Realme и Poco. Нельзя сказать, что всё прям очень плохо, но ожидать что он будет работать на уровне флагманов, конечно же, не стоит. Но как оно на практике?
Начинаем с мессенджеров: ВКшечка и Telegram. В качестве клиента ВК, я юзаю исключительно Kate Mobile, который шустро работает даже на 10-летних китайцах на MT6572. Официальный клиент давно не признаю, всё таки при grishka он был лучше :)
Последний официальный клиент телеги работает шустро. Чипсет, конечно, печка ещё та, но посидеть в чатиках, посмотреть видосы и всякое такое можно без каких либо проблем. Главное чтобы память резко не закончилась. WhatsApp здесь тоже работает нормально.
Переходим к видосам. Ни официальный клиент, ни ревансед последних версий нормально здесь работать не будет — официальные клиенты требуют Android 8+. Но разве ж это проблема для нас, когда есть SkyTube? :) Работает шустренько, девайс без проблем держит 720p видосы, а больше и смысла нет.
Как насчет навигации? Google-карты работают адекватно. Всё весьма шустренько, хотя порой просадки FPS всё же бывают. Но я лично предпочитаю выкидывать гаппсы из своих смартфонов и накатывать навигацию по OSM. Что забавно — в девайсе есть собственный клон AppStore'а! И если рескины Google Play в стиле яблочного магазина для меня не удивление, то наличие полноценного бренда CH с эдаким фидбеком у смартфона меня весьма удивило. Я всё ещё помню GooPhone'ы, которые когда-то предоставляли хороший клиентский сервис покупателям своих реплик айфонов, но не думал что эта практика даже сейчас актуальна. Вполне возможно, что CH — это и относительно крупный завод-производитель со своим R&D отделом, поскольку маркировка есть и на межплатном шлейфе, и на АКБ. Эта компания также производит реплики Galaxy S и Note серии, на базе той-же аппаратной платформы.
И переходим, конечно-же, к камере! Самое приложение скопировано 1 в 1 с оригинала, даже есть какие-то панорамные режимы и фишки с цифровым зумом и подобием изменения FOV. Но понятное дело, тест не может быть объективным на 100%: девайс после воды, топился в районе камеры и на фото явно видны засветы. Есть вероятность, что оптика всё же оказалась немного повреждена :(
"Фотосет" из двух наиболее удачных фотографий есть на imgur. Увы, на Пикабу очень большие ограничения на число картинок в одном посте!
Но на скринах всё красиво, а как на деле? Смотрим:
❯ Заключение
В целом, девайс весьма хорош для моих повседневных задач. Работает шустренько, выглядит как айфон как с внешней точки зрения, так и с точки зрения системы, дисплей весьма неплох по качеству, смартфон отлично поддаётся моддингу. Собственно, а почему-бы и нет?
Цель материала была рассказать вам не только о том, на что подобные реплики способны «из коробки», но и об их возможностях моддинга и кастомизации с подробной практической частью, а не на уровне «пойдите туда и сделайте это»! Но учтите, я не рекомендую покупать реплики айфонов, если вы ожидаете от них хорошей работы из коробки и у вас нет желания в них ковыряться. Зато мне очень понравилось с ним возиться и я надеюсь, по итогу было интересно и вам! Пишите своё мнение в комментариях, будет интересно почитать! Также у меня есть канал в телеге, где я публикую бэкстейджи статей, различные посты по тематике аппаратного и программного моддинга, программирования, а также разработки собственного DIY-железа!
Кстати, если у кого-то из читателей есть похожие подделки будучи нерабочими, тормозящими, или окирпиченными и вам не хотелось бы выкидывать их на свалку, а наоборот, отдать их в хорошие руки и увидеть про них статью — пишите мне в Telegram или в комментах! Готов в том числе и купить их. Особенно ищу донора дисплея на китайскую реплику iPhone 11 Pro Max: мой ударник, контроллер дисплея калится и изображения нет :(
Что думаете о девайсе?
Что думаете о покупке его за 10.000 рублей? А за 1.000 рублей?
Материал полезен?
Статья подготовлена при поддержке TimeWeb Cloud. Подписывайтесь на меня и @Timeweb.Cloud, дабы не пропускать новые статьи каждую неделю!