Перейти к содержанию

Загрузки и TorrServer для плагина

Черновик (2026-10-30). Встроенный TorrServer, встроенный плагин downloads и демон загрузок dl_manager: как это устроено и как плагину добавить торрент, получить поток и поставить загрузку. Основа: код tv188b 261021_0117_r25 (PHP-плагин downloads, dunelib/dl_state.php, листинги libxxx_dl_manager.so; уровень code), наблюдения на одном tv188b с прошивкой 261021_0117_r25 (несколько проверок на устройстве; уровень device), карты r24 и APK 260724_0207_r24. Разбор восстановления и папки загрузок в dl_manager ещё идёт, поэтому §4.3–4.4 неполны. Каждое фактическое предложение ссылается на claim id.

Коротко: вопрос → ответ

Вопрос Ответ Где
Есть ли встроенный TorrServer? да: libxxx_ts.so (44235376 байт, TorrServer MatriX.134) в r24, r25 и APK (код)1; r25, device: тот же размер (устройство r25)2 §1.1
Как запускается? r25, device: downloads (ensure_ts) кладёт команду в /tmp/run/dl_input, dl_manager через 2 мс пишет start_internal_ts и «TorrServer started» (устройство r25)3 §1.2
Где слушает? r25, device: встроенный — http://127.0.0.1:8095, процесс ts запущен с --port 8095 (устройство r25)4; порт слушается на всех интерфейсах, /echo отвечает из LAN (устройство r25)5; код r25: внешний — ext_torrserver из cookies online_movies, порт по умолчанию 8090 (код r25)6 §1.3
Где файлы TorrServer? r25, device: работающий ts — -d /data/data/com.dunehd.app/flashdata/ts, логи …/tmp/run/ts.log и …/tmp/run/tsweb.log (устройство r25)7; код r25: дисковый кэш — <FS_PREFIX>/flashdata/ts_cache (код r25)8 §2
Как плагину открыть magnet? r25, device: plugin_launcher://{name=downloads}{action_id=open_magnet}{magnet_url=<magnet>} запускает open_magnet (устройство r25)9; дальше — диалог «Воспроизвести» / «Скачать все файлы» (устройство r25)10 §3.1
Какой URL потока? код r25: /stream/<имя>?link=<hash>&index=<id>&play у адреса TorrServer (код r25)11; r25, device: http://127.0.0.1:8095/stream/Big%20Buck%20Bunny.mp4?link=<hash>&index=2&play (устройство r25)12 §3.2, §3.3
Можно ли отдать оболочке голую magnet-ссылку или .torrent? r25, device: нет — голая magnet отклоняется invalid_parameters (устройство r25)13, URL .torrent ничего не запускает (устройство r25)14 §3.4
Сколько загрузок идёт одновременно? r25, device: на плеере с 8 ГБ лог dl_manager — «dl_max_loads_at_once is 3», затем «is now 1» (устройство r25)15 §4.5
Что есть в r24 и APK? r24: ts есть (код r24)16, downloads и dl_manager нет (код)17; APK: ts есть, downloads среди встроенных плагинов нет (код r24)18 §5

1. TorrServer на устройстве

1.1. Встроенный бинарник

Где Что Claim
tv188b r24 /system/dunehd/firmware/bin/ts — симлинк на /data/data/com.dunehd.app/lib/libxxx_ts.so (код r24)19
tv188b r24 libxxx_ts.so лежит в /system/bin/, 44235376 байт — крупнейший из libxxx_*.so (код r24)16
tv188b r25 firmware/bin/ts — симлинк на libxxx_ts.so, 44235376 байт (код r25)20
tv188b r25 в strings libxxx_ts.so — «TorrServer/MatriX.134», «Start TorrServer MatriX.134», torrserver.db (код r25)21
tv188b r25, device /system/bin/libxxx_ts.so — 44235376 байт (устройство r25)2
APK 260724 r24 libxxx_ts.so (44235376 байт; firmware/bin/ts по apk_bin_map.txt) — программа на Go с идентификацией TorrServer/MatriX.134, а не ядро медиаплеера (код r24)22

По коду плагин downloads r25 запускает $FS_PREFIX/flashdata/ts/ts (утверждение disputed, §7). На r25 (device) $P/firmware/bin/ts — симлинк на $P/lib/libxxx_ts.so, а $P/flashdata/ts/ts — симлинк на $P/flashdata/plugins/dunemdb_supplier_online_movies/bin/ts; при проверке на устройстве у работающего ts был снят только argv (устройство r25)23. При проверке на устройстве (tv188b r25, device) у владельца порта :8095 — процесса ts (root, PPid 1) — /proc/<pid>/exe указывал на /system/bin/libxxx_ts.so, cwd — /system/dunehd/firmware_ext/plugins/downloads, /echo ответил MatriX.134 (устройство r25)24, а cmdline начинался с .../flashdata/ts/ts (устройство r25)25. Кто создаёт симлинк в flashdata/ts/, claims не говорят (см. «Расхождения»). TsHelper::ensure_ts_file при HD::is_apk() сразу возвращает true, а вне APK запускает через php-cgi update.php плагина online_movies, если тот найден (код r25)26. HD::is_apk() — это getenv("HD_APK") (код r24)27; на tv188b r25 у httpd и network_manager в окружении HD_APK=1 (устройство r25)28.

1.2. Как запускается встроенный TorrServer

Цепочка по коду r25:

  1. entry.ensure_ts плагина downloads: если задан внешний TorrServer и он недоступен — ensure_ts_status=-1 без локального запуска; если внутренний запускался недавно — ждёт его; иначе посылает DlState::start_ts (код r25)29.
  2. DlState::start_ts пишет JSON с единственным cmd_type в /tmp/run/dl_input/<microtime>.<cmd_type>.in (код r25)30.
  3. dl_manager сопоставляет start_ts с номером 4 (код r25)31 и вызывает запуск TS с аргументом 0 (код r25)32. В strings демона есть шаблоны запуска php-cgi tscli.php с TORRSERV_IP=internal (код r25)33; какой именно командой он запускает TS — гипотеза (§7).
  4. tscli.php start запускает TsHelper::start_ts, если TS ещё не работает, ждёт и вызывает configure_ts; start_nowait вызывает только start_ts (код r25)34.
  5. TsHelper::start_ts запускает сам ts; что именно написано в коде (путь, условия, TORRSERV_NAME, GODEBUG) — disputed, §7. На r25 (device) работающий ts запущен с --port 8095 -k -d /data/data/com.dunehd.app/flashdata/ts -l /data/data/com.dunehd.app/tmp/run/ts.log -w /data/data/com.dunehd.app/tmp/run/tsweb.log, имя настроек и логов — ts (устройство r25)7. При проверке на устройстве (device) окружение работающего ts содержало GODEBUG=madvdontneed=1 и TORRSERV_IP=internal, а TORRSERV_NAME в нём не было (устройство r25)25.
  6. Защита от повторного запуска (ts_launch.lock, ts_launch_time.txt) по коду — disputed, §7. На r25 (device) /tmp/run/ts_launch.lock есть (0 байт, rw-rw-rw-, root), /tmp/run/ts_launch_time.txt нет, а ensure_ts при уже работающем TS завершился за 50 мс (устройство r25)35. wait_for_running_ts делает до 100 проверок через 400 мс (код r25)36.

Что видно на r25 (device):

  • Вызов downloads->handle_user_input(entry.ensure_ts) совпал по времени со сменой mtime /tmp/run/dl_input; через 2 мс dl_manager записал start_internal_ts(wait:0), затем «DONE: TorrServer started» (устройство r25)37 и «start_internal_ts(wait:0): OK» через ~5,6 с (устройство r25)3.
  • Весь шаг ensure_ts в цепочке open_magnet занял ~11 с (устройство r25)38.
  • Запуск 2026-10-28 в dl_manager.log: start_internal_ts(wait:0)... → DONE: TorrServer started → OK за ≈5,5 с; строки команды и имени tscli.php в журнале нет (устройство r25)39.
  • Процесс ts (root, ppid 1) 2026-10-30 не менялся с 12:45 до 13:09 и пережил am force-stop com.dunehd.app; в его ts.log есть записи 2026-10-28 17:24:34–37 (устройство r25)40.

1.3. Адрес: встроенный и внешний

  • r25, device: клиент downloads использует локальный TorrServer http://127.0.0.1:8095 (устройство r25)41; поток открывался по http://127.0.0.1:8095/stream/..., процесс ts — с --port 8095 (устройство r25)42.
  • r25, device: встроенный ts слушает *:8095 и отвечает MatriX.134 на /echo с компьютера, то есть доступен из LAN (устройство r25)5.
  • Порядок выбора адреса в коде TorrServer::ensureIp (TORRSERV_IP, внешний, internal) и запрос /echo в debug_dump.sh — disputed, §7: проверка на устройстве подтвердил только адрес по умолчанию.
  • Внешний TorrServer — значение ext_torrserver из cookies плагина online_movies; без двоеточия к нему дописывается :8090 (код r25)6. r25, device (проверка на устройстве): в dunemdb_supplier_online_movies_plugin_cookies.properties был только ключ sort_video_streams, ext_torrserver не было, и поток из open_magnet.m3u шёл на http://127.0.0.1:8095 (устройство r25)43.
  • При внешнем TS downloads встроенный не запускает: недоступный внешний даёт ensure_ts_status=-1 (код r25)29.
  • r25, device (прогон 2026-10-23): на плеере работал внешний TorrServer — приложение ru.yourok.torrserve (процесс torrserver, root), слушал *:8090, 127.0.0.1:36535 и 0.0.0.0:32400 (устройство r25)44. При проверке на устройстве на :8090 тоже слушал отдельный процесс torrserver, а :8095 — процесс ts (устройство r25)24.

1.4. Не путать: btpd

В прошивке есть и другой торрент-клиент, не связанный с downloads:

  • init_torrents.sh хранит данные btpd в /D/.btpd, список — в /tmp/run/torrent_list, статус — в /tmp/run/btpd.status; настройки torrent_client_* читаются из config/settings.properties (код r25)45.
  • При загрузке btpd стартует, только если torrent_client_run_on_boot=yes, и требует смонтированный /D с ext2, ext3 или tntfs (код r25)46.
  • Скрипты в r24 и r25 совпадают побайтово (код r24, r25)47.

2. Настройки и файлы TorrServer

Что оболочка (код TsHelper, r25) делает с TorrServer:

Что Поведение Claim
Где кэш /config/ts_disk_cache.txt, отличный от -1, решает; иначе MemTotal < 1100000 kB — кэш на диске (код r25)48
Дисковый кэш UseDisk=true, TorrentsSavePath=<FS_PREFIX>/flashdata/ts_cache, RemoveCacheOnDrop=true; без диска — UseDisk=false, пустой TorrentsSavePath (код r25)8
Голова и хвост кэша при валидных CacheSize/ReaderReadAHead/PreloadCache поднимает минимумы до 60000000 байт головы и 30000000 байт хвоста (код r25)49
Раздача DisableUpload=true, если было false или не задано; настройки сохраняются при любом изменении (код r25)50
Соединения ConnectionsLimit=50 только при HD2::with_dl() и не low-RAM продукте, иначе 25 (код r25)51
Удаление downloads omgr_uninstall для внутреннего TS вызывает stop_ts_and_clear_cache (код r25)52
Простаивающие торренты tscli drop_idle/rem_idle не удаляет торрент с непустым Readers из /cache и выходит с кодом 2 (код r25)53

В r24 в экране playback_preferences есть настройка optimize_torrserver_settings (код r24)54; связь её с configure_ts claims не описывают.

Файлы:

Путь Что Claim
$FS_PREFIX/flashdata/ts (r25: /data/data/com.dunehd.app/flashdata/ts) каталог данных TS (-d), r25, device (устройство r25)7
$FS_PREFIX/tmp/run/ts.log, tsweb.log логи TS (-l, -w), r25, device (устройство r25)7
<FS_PREFIX>/flashdata/ts_cache дисковый кэш (код r25)8
/config/ts_disk_cache.txt переключатель кэша (код r25)48
/tmp/run/ts_launch.lock, /tmp/run/ts_launch_time.txt r25, device: lock-файл 0 байт есть, ts_launch_time.txt нет; роль по коду — §7 (устройство r25)35
/tmp/run/ts_player.txt есть в strings dl_manager; назначение не разобрано (код r25)55
/flashdata/dl_cache/bt_hashes_to_delete.txt в strings dl_manager, рядом сообщения о загрузке хэшей на удаление (код r25)56

3. Как плагину работать с торрентом

3.1. Отдать magnet плагину downloads

downloads объявляет public_actions open_magnet и download_settings (код r25)57; оба направлены в handler_id=entry с одноимённым control_id (код r25)58.

  • r25, device: launch_media_url с plugin_launcher://{name=downloads}{action_id=open_magnet}{magnet_url=<magnet>} запускает действие без точки входа: «launching plugin 'downloads' (ep (null), action open_magnet)» и handle_user_input(entry.open_magnet) с тайм-аутом 300 с (устройство r25)9.
  • r25, device: plugin_launcher из одноэлементного M3U по HTTP тоже запускает действие плагина и передаёт from в user_input — и через IP Control launch_media_url (устройство r25)59, и из GUI-действия launch_media_url с M3U из www плагина (from=gui) (устройство r25)60. Плагин Screenshoter запускает plugin_launcher:// через ActionFactory::launch_media_url (код)61. Запуск именно open_magnet из GUI-действия плагина на устройстве не проверялся — проверено только через IP Control. Правило SDK о выборе запускателя — §7.
  • open_magnet требует непустой magnet_url и строит цепочку ensure_ts → open_dl с результатом в tmp_dir_path/open_magnet.json (код r25)62.

Что увидит пользователь (r25, device):

  1. Цепочка entry.open_magnet → entry.ensure_ts (~11 с) → entry.open_dl → диалог с опросом entry.dialog_open_dl раз в ~1 с → entry.show_open_magnet; тайм-аут open_magnet и dialog_open_dl — 300 с, остальных шагов — 60 с (устройство r25)38.
  2. Диалог «Выберите действие для торрента»: «Название торрента: <имя>», «Найдено файлов: 3», кнопки «Воспроизвести» (в фокусе) и «Скачать все файлы» (устройство r25)10. Вторая кнопка — «Скачать все файлы» при нескольких файлах и «Скачать» при одном; «Воспроизвести» в обоих случаях первая (устройство r25)63.
  3. «Скачать все файлы» без заданной папки загрузок открывает выбор «Папка загрузок» со списком хранилищ (устройство r25)64. При проверке на устройстве после выбора «Встроенная память» показано предложение добавить папку в «Мою коллекцию» (entry.confirm_add_mc_folder), сохранён dl_folder_url = sdcard:///DuneHD (устройство r25)65; при следующем «Скачать», с уже заданной папкой, ни одного из этих диалогов не было — сразу «Добавлено в загрузки» (устройство r25)66.

Если у раздачи нет сидов (r25, device, раздача с 0 сидов), вместо диалога выбора действия примерно через 70 с после начала open_magnet показан диалог «Не удалось подключиться к источнику», open_magnet.m3u не создан (устройство r25)67.

По коду r25: dialog_open_dl опрашивает torrserverActionGet, пока не придут file_stats (код r25)68; «Скачать» выбирает все файлы, «Воспроизвести» — только прошедшие фильтр воспроизводимости (код r25)69; при «Скачать» торрент повторно добавляется в TorrServer, а group_id загрузки берётся из возвращённого hash (код r25)70.

3.2. Работать с TorrServer напрямую (как это делает downloads)

Ниже — HTTP-клиент ext/TorrServer.php плагина downloads r25. Это код клиента, а не описание API TorrServer: документации TorrServer в базе нет.

Что Как в клиенте Claim
Адрес r25, device: локальный http://127.0.0.1:8095; порядок выбора в коде (TORRSERV_IP → внешний → локальный) — §7 (устройство r25)41
Транспорт JSON методом POST, Content-Type: application/octet-stream; тайм-аут 10 с, для добавления — 30 с (код r25)71
Пути /settings (get/set), /cache (get), /torrents (list/drop/rem/add/get), /torrent/upload (файл), /echo (проверка), /shutdown (код r25)72
Добавить торрент torrserverActionAdd передаёт save_to_db=!dont_save, upload — поле save=!dont_save (код r25)73
Состояние torrserverActionGet; до json_decode числа из 10 и более цифр превращаются в строки (код r25)74
Список файлов и URL потока массив, отсортированный по пути: title, id=md5(path), size/size_mb, URL /stream/<имя>?link=<hash>&index=<id>&play; по умолчанию фильтр расширений включён (код r25)11

Грабля клиента: при запросе без ожидаемого JSON-ответа apiHttpPost возвращает true даже после неудачного file_get_contents, а SettingsWrite всегда возвращает true (код r25)75.

Для вызовов из командной строки и из демона есть tscli.php: команды status, start, start_nowait, stop, list_torrents, get, cache, add, add_save_to_db, drop, rem, drop_idle, rem_idle, settings, set_setting (код r25)76; include_path он строит из FS_PREFIX/firmware_ext/php/include и текущего каталога (код r25)77.

3.3. Воспроизвести

Что видно на r25 (device, проверка на устройстве; торрент из трёх файлов):

  • После «Воспроизвести» выбора файла не было: apply_open_magnet получил в magnet_play_files только .mp4 (index=2), а в magnet_all_files — все три файла (.srt, .mp4, poster.jpg) (устройство r25)78.
  • При одном воспроизводимом файле play_magnet сразу вернул downloads->launch_media_url с потоком http://127.0.0.1:8095/stream/…?link=<hash>&index=2&play; open_magnet.m3u и open_magnet.json не создавались (устройство r25)12.

Ветка нескольких воспроизводимых файлов (r25, device, проверка на устройстве; торрент из 12 файлов — шесть серий .avi и субтитры .srt):

  • entry.play_magnet вернул launch_media_url с file:///data/data/com.dunehd.app/tmp/plugins/downloads/open_magnet.m3u; в плейлисте шесть записей #EXTINF с .avi, .srt в него не попали (устройство r25)79.
  • URL записи — http://127.0.0.1:8095/stream/<имя>?link=<btih>&index=<N>&play|||dune_params|||http_online_subs:1,file_id:<папка>/<имя>; у шести .avi индексы 1, 3, 5, 7, 9, 11 — номера из полного списка файлов торрента, где S01E01.srt имеет index=2, а не номера в плейлисте (устройство r25)80.
  • После запуска плейлиста играет первая серия: playback_url — S01E01 с index=1, подпись Pioneer.One.S01E01.avi (1 из 6), движок VLC (устройство r25)81.

По коду r25:

  • К URL потока дописывается |||dune_params|||http_online_subs:1,file_id:<путь файла> (код r25)82.
  • Воспроизведение скачанного с историей идёт через shell_ext entry/play_recent с sup_id, movie_id, autoplay=1, single_mode=1, wh_single_torrent=1, wh_torrent и wh_uid вида <sup_id>:<movie_id>:<md5(file_path)>:<uid группы> (код r25)83; без любого из sup_id, movie_id, uid, id, torrent_name в params действие не строится (код r25)84.

3.4. Что не работает

Попытка (r25, device) Результат Claim
launch_media_url с голой magnet:?xt=urn:btih:… command_status=failed, invalid_parameters, «qualified url is expected» (устройство r25)13
launch_media_url с HTTPS-URL .torrent ни воспроизведения, ни downloads; /tmp/run/dl_input не изменился (устройство r25)14

3.5. Плагин-поставщик и кнопка загрузки

  • В r25 у описателя поставщика новый ключ dl_capable: первый такой поставщик становится dl-поставщиком (кнопка «Загрузки», Suppliers::get_dl_sup), только если в firmware_features есть downloads (код r25)85.
  • Карточка фильма получает кнопку dl сразу после play, если dl-поставщик есть и sup_<id> не исключён в конфигурации списка плееров (код r25)86; нажатие вызывает do_get_play_action('online_dl', sup->id) (код r25)87.
  • Внутреннее действие entry.choose_enter_action плагина downloads требует dl_id, dl_name, положительный dl_total и непустые JSON-массивы dl_files и dl_all_files (код r25)88; ветка add_dl передаёт их в DlState::add_download (код r25)89. Эти действия не объявлены в public_actions (код r25)58, а как ответ online_dl поставщика доходит до них, claims не описывают.

4. Менеджер загрузок

4.1. Что видно пользователю

  • Точка входа downloads в root://applications показывается по условию is_plugin_file(dunemdb_supplier_online_movies/__v2), вторая — в setup://applications (код r25)57; пункт верхнего меню (downloads_epf) — при and(ff(downloads),is_file(/flashdata/plugins/dunemdb_supplier_online_movies/__v2)) (код r25)90.
  • Флаг downloads есть в firmware_features.txt r25 (код r25)91 и на устройстве (устройство r25)92; при файле /tmp/flm.txt PHP убирает его (комментарий кода: «lite»-лицензия без загрузок) (код r25)93.
  • Экраны: DownloadsScreen, FilesScreen, SetupScreen (код r25)94; таймер списков — 1 с при fast_timer_countdown>0, иначе 5 с, у настройки — 2 с (код r25)95.
  • Прогресс: 100 для готовых (O), не больше 99.9 для незавершённых (код r25)96; E — ERR, p/P — PAUSE, скорость — только у L и p от 1024 (код r25)97.
  • show_in_folder строит embedded_app://{name=path_from_source} и, пока файл не в O, указывает на <имя>.part (код r25)98.
  • Жёлтая кнопка открывает настройки загрузок плагина online_movies (action_id=setup_download_settings) (код r25)99.
  • EPF downloads_epf обновляется по смене mtime dl_gstat.txt и dl_state.txt (код r25)100.

4.2. Папка загрузок

  • Выбор: choose_file только по каталогам, с проверкой записи и сетевыми папками, имя новой папки — dune_downloads (код r25)101; URL сохраняется в cookies как dl_folder_url (код r25)102. Демон читает его из /config/downloads_plugin_cookies.properties (код r25)103. r25, device: до первого выбора файла downloads_plugin_cookies.properties не было, а dl_state.txt содержал пустые dl_folder_url и dl_folder_path; после выбора «Встроенная память» в cookies записан dl_folder_url = sdcard:///DuneHD, в dl_state.txt — тот же URL и dl_folder_path = /sdcard/DuneHD (устройство r25)104.
  • Поддерживаемые URL: sdcard, storage_name, network_folder_id, nfs/nfs-tcp/nfs-udp, smb (код r25)105; накопители с is_persistfs_capable=1 исключены (код r25)106.
  • После выбора папки SetupScreen вызывает shell_ext entry/ensure_mc_folder (код r25)107; если папка ещё не в «Моей коллекции», shell_ext спрашивает, добавить ли её (код r25)108.
  • Смена папки при непустом списке разрешена не всегда: при группах вне O/P/E кнопки продолжения нет (код r25)109; демон при смене снимает все группы, не удаляя файлов (код r25)110.
  • Демон проверяет папку: не каталог — dir_access_error (код r25)111, нет записи — dir_write_error (код r25)112; без доступной папки add отклоняется («dl folder not available») (код r25)113.
  • Свободное место: предупреждения нет, если mb_pending+mb_new <= mb_free-1000 (код r25)114. При ненулевом FS_is_exfs демон публикует mb_free=0 и mb_total=0 (код r25)115.

4.3. Очередь: файловый протокол PHP ↔ dl_manager

Направление Формат Claim
PHP → /tmp/run/dl_input/*.in JSON, cmd_type: add, remove, pause, resume, start_ts, change_dl_folder, test_dl_folder (код r25)116
запись .in через <path>.tmp и rename (код r25)117
add id, name, total, files[] (path, url, size_mb, ext_ts), необязательно params (код r25)118
remove/pause/resume group_id, необязательно file_paths (код r25)119
dl_manager → /tmp/run/dl_state.txt properties: dl_folder_url, dl_folder_path, error; mb_free/mb_total — при заданной папке (код r25)120
dl_manager → /tmp/run/dl_gstat.txt r25, device: строка группы — буква статуса, <файлов>/<всего>, процент, скорость, btih; формат и порядок по коду — §7 (устройство r25)121
<group_id>.json сначала /tmp/run/dl_cache, затем /flashdata/dl_cache (код r25)122

Демон (код r25):

  • Обработанный .in из каталога исчезает (r25, device, §4.3 ниже) (устройство r25)123; что он читается целиком и удаляется до разбора JSON, — код, disputed (§7); файлы не на .in удаляет не читая (код r25)124; неизвестный cmd_type отбрасывает («cmd_type missing or unsupported») (код r25)125.
  • Помимо команд PHP знает восьмую — on_playback_finish (код r25)31; она запускает очередь отложенного удаления хэшей (код r25)126.
  • add принимает только непустые id и name, total ≥ 1 и массив files (код r25)127; элемент без url или path молча пропускает (код r25)128; путь, уже занятый другой группой, отклоняет всю команду («path already added») (код r25)129.
  • Ответа на .in нет: GUI после add_dl ждёт смены статуса до 50 опросов по 200 мс (код r25)130.

r25, device: /tmp/run/dl_input и /tmp/run/dl_cache — drwxrwxrwx root:root, dl_gstat.txt, dl_state.txt, dl_manager.log, dl_manager.pid — -rw-rw-rw- root:root (устройство r25)131; без папки загрузок dl_state.txt — две строки dl_folder_url = и dl_folder_path = (устройство r25)15.

Что видно на r25 (device, проверка на устройстве; загрузка одного файла):

  • Команда появилась в /tmp/run/dl_input сначала как <id>.in.tmp, затем как <id>.in и была удалена так быстро, что наблюдатель не успел сделать на неё ссылку (содержимое .in поэтому не снято); при этом команда обработана: в dl_manager.log — handle add_dl и added group … status N (устройство r25)123.
  • Статусы группы прошли N → L → O: при добавлении в логе status changed: N -> L, по завершении status changed: L -> O и сразу I: all finished (устройство r25)132.
  • Строка dl_gstat.txt — пять полей: буква статуса, <файлов>/<всего>, процент с одним знаком после запятой, скорость и btih; в ходе загрузки — L 1/1 10.1 6666186 <btih>, в конце — O 1/1 100.0 0 <btih> (устройство r25)121. Как выглядит dl_gstat.txt с несколькими группами, device-claims нет.

4.4. Файлы .part, пауза и докачка

Демон считает статусы номерами 0–7; как номера соотносятся с буквами N L p P O E d D в PHP, — гипотеза (§7).

  • Начиная файл, демон создаёт каталоги для <папка>/<path>.part и пишет в него с позиции файла (код r25)133; готовый файл переименовывает из .part в <path> (код r25)134.
  • Докачка начинается с размера .part, округлённого вниз до 16 МиБ, минус 16 МиБ (код r25)135; не обычный файл .part удаляется, и файл качается заново (код r25)136.
  • pause: статусы 0 и 5 — в 3 (P), активный 1 — в 2 (p) с отменой задачи (код r25)137; resume трогает только 3 и 5 (код r25)138.
  • remove с file_paths удаляет файлы с диска, активные — после конца задачи (код r25)139.
  • Восстановленная при bootstrap непустая очередь ждёт 20 с, прежде чем начать файл: на r25 (device) — 20,023 с (устройство r25)140; механизм отметки по коду — §7.
  • Очередь отложенного удаления хэшей (код r25): если hash группы совпал с прочитанным hash воспроизведения и установлен младший бит третьего аргумента, fcn.00056cf4 ставит удаление в очередь для каждого собранного сервера (код r25)141. Обработчик очереди убирает запись, только если вызов удаления (0x00067248) вернул 0 или 2, иначе запись остаётся (код r25)142; запускает его команда on_playback_finish (§4.3).

Перезапуск демона посреди загрузки (r25, device, проверка на устройстве; один прогон, файл BIG_BUCK_BUNNY.iso):

  1. На 10,1 % демон убит kill; за 60 с его никто не поднял. После am force-stop com.dunehd.app приложение поднялось само, новый dl_manager восстановил ту же группу и довёл загрузку до O 1/1 100.0; первый dl_gstat после перезапуска — 11,2 % (устройство r25)143.
  2. Bootstrap прочитал одну группу (1 groups loaded), разрешил и смонтировал папку (dl_folder_url is suitable: sdcard:///DuneHD, dl folder mount: /sdcard/DuneHD), вернул группу в очередь (added to load) и только затем записал boot D: postpone download for 20s (устройство r25)144.
  3. Между postpone download for 20s и start load f BIG_BUCK_BUNNY.iso, pos 234881024 прошло 20,023 с (устройство r25)140.
  4. .part усечён с 260046848 до 234881024 байт (resume D: truncate 260046848 -> 234881024), докачка пошла с 234881024 (CURLOPT_RESUME_FROM_LARGE to 234881024), а не с нуля (устройство r25)145. Числа сходятся с правилом кода выше: 260046848 вниз до кратного 16 МиБ — 251658240, минус 16 МиБ (16777216) — 234881024.

4.5. Сколько загрузок одновременно

  • Планировщик начинает новые загрузки, пока их меньше dl_max_loads_at_once (код r25)146.
  • Проверка по адресу 0x54dd0 при результате 0 сводит лимит к 1 (код r25)147; что она проверяет, не установлено (§7).
  • r25, device (MemTotal 8146624 kB): «dl_max_loads_at_once is 3», затем «… is now 1» (устройство r25)15 — на этом плеере загрузки идут по одной. При проверке на устройстве то же повторилось и у демона, поднятого после перезапуска приложения (устройство r25)148.
  • r25, device: загрузка дошла до O при отсутствующем /tmp/flm.txt — и до, и после скачивания (устройство r25)149; device-claims о загрузке с файлом /tmp/flm.txt нет (роль флага — §4.1).
  • PHP перед добавлением вызывает builtin pf_check с pf2=1, если есть другая группа не в статусе O (код r25)150.

4.6. Процесс dl_manager

Что Наблюдение Claim
Бинарник r25: /system/bin/libxxx_dl_manager.so (630612 байт) как firmware/bin/dl_manager (код r25)151
Процесс r25, device: root, u:r:shell:s0, PPID 1, pid в /tmp/run/dl_manager.pid (устройство r25)152
pid-файл r25, device: совпадает с pidof dl_manager до и после перезапуска; после kill старый pid-файл остаётся с прежним mtime (устройство r25)153
Дескрипторы r25, device: stdout/stderr → /tmp/run/dl_manager.log, fd 4 — inotify (устройство r25)154
Старт r25, device: поднимается при старте приложения (через ~8 с после am start) (устройство r25)155
Убит r25, device: работающее приложение за 60 с его не подняло (устройство r25)155
force-stop приложения r25, device: демон его переживает (устройство r25)156
kill, затем force-stop r25, device: после kill демон 60 с не поднимался; после am force-stop приложение поднялось само, появился новый dl_manager (root, PPid 1), и он продолжил загрузку (§4.4) (устройство r25)143
Java-сторона r25: в classes.dex есть /firmware/bin/dl_manager, «dl_manager started», «dl_manager stopped» (код r25)157
Java: запуск код r25: DlManagerService по onApkReady, если есть /firmware/bin/dl_manager, шлёт MSG_START_DL_MANAGER=900; при process == null демон запускается через ProcessHelper.runDaemonProcess({"/firmware/bin/dl_manager"}, true, true, null) (код r25)158
Java: остановка код r25: DlManagerService.onDestroy → handleStop: process.destroy(), затем exec killall dl_manager; ошибка exec только печатает stack trace (код r25)159

5. Отличия r24, r25 и APK

Что tv188b r24 tv188b r25 APK 260724 r24 (ATV)
libxxx_ts.so, firmware/bin/ts есть (код r24)160 есть (код r25)20 есть (код r24)22
Плагин downloads нет: в r25 он добавлен к 13 плагинам r24 (код r25)161 есть (код r25)57 нет среди 12 встроенных (код r24)18
dl_manager нет (код r24)162 есть (код r25)163 нет данных
Флаг downloads нет: флаг новый в r25 (код r25)91 есть (устройство r25)92 нет данных
dl_capable у поставщиков нет: ключ новый в r25 (код r25)85 есть (код r25)85 нет данных
btpd (init_torrents.sh) тот же скрипт (код r24, r25)47 тот же скрипт (код r24, r25)47 нет данных

Код ensure_ts_file различает APK и не-APK (HD::is_apk()) (код r25)26, но сборок APK с плагином downloads в базе нет.

6. Расхождения

  • Кто запускает и останавливает dl_manager. Гипотеза (disputed, см. §7): его запускает и останавливает Java-оболочка. Код r25 это описывает: DlManagerService запускает /firmware/bin/dl_manager по onApkReady, если процесса ещё нет (код r25)158, а в onDestroy делает process.destroy() и killall dl_manager (код r25)159. На r25 (device) force-stop приложения демон не остановил (устройство r25)156, а после kill работающее приложение его не подняло (устройство r25)155; при проверке на устройстве после kill и последующего force-stop новый демон появился, когда приложение поднялось само (устройство r25)143. Вызывается ли onDestroy при force-stop, claims не говорят. Связи conflicts_with нет.
  • Какой бинарник TorrServer запускается. В прошивке он лежит как firmware/bin/ts (код r25)20, а по коду TsHelper::start_ts запускает $FS_PREFIX/flashdata/ts/ts (disputed, §7). На r25 (device) это два разных симлинка: firmware/bin/ts → lib/libxxx_ts.so, flashdata/ts/ts → bin/ts плагина dunemdb_supplier_online_movies (устройство r25)23. При проверке на устройстве cmdline работающего ts начинался с .../flashdata/ts/ts (устройство r25)25, а /proc/<pid>/exe указывал на /system/bin/libxxx_ts.so (устройство r25)24: запущен путь flashdata/ts/ts, как в коде TsHelper::start_ts (§7), а исполняемый файл — /system/bin/libxxx_ts.so. Через какие звенья симлинков bin/ts плагина приводит к нему, claims не говорят. Это не противоречие источников, а пробел.

7. Не проверено

Гипотезы (inference) и disputed; кандидаты на проверку.

Утверждение Статус Claim
firmware/bin/ts — встроенный TorrServer (MatriX.134), а не ядро плеера inference (вывод r25)164
Код: TsHelper::start_ts запускает $FS_PREFIX/flashdata/ts/ts, если файл есть и ts не запускался недавно, с --port, -k, -d, -l, -w; имя по умолчанию ts, порт 8095. Проверка на устройстве: аргументы и порт совпали (§1.2), start_ts не вызывался — условия запуска не проверены; проверка на устройстве: cmdline начинается с .../flashdata/ts/ts (устройство r25)25 code, disputed (код r25)165
Код: локальный TsHelper берёт имя из TORRSERV_NAME и задаёт GODEBUG=madvdontneed=1. Проверка на устройстве: аргументы совпали; проверка на устройстве: в окружении ts есть GODEBUG=madvdontneed=1 и TORRSERV_IP=internal, TORRSERV_NAME нет (устройство r25)25, exe — /system/bin/libxxx_ts.so (устройство r25)24 code, disputed (код r25)166
Код: start_ts под блокировкой /tmp/run/ts_launch.lock проверяет и ставит /tmp/run/ts_launch_time.txt; «недавний» запуск — 0–59 с. Проверка на устройстве: lock-файл есть, start_ts не вызывался code, disputed (код r25)167
Код: TorrServer::ensureIp берёт TORRSERV_IP, затем внешний адрес; пустой или internal заменяет на http://127.0.0.1:8095, без http дописывает http://. Проверка на устройстве: подтверждён только адрес по умолчанию; проверка на устройстве: в cookies online_movies ключа ext_torrserver нет, поток идёт на 127.0.0.1:8095 (устройство r25)43; ветка с заданным внешним адресом не проверялась code, disputed (код r25)168
debug_dump.sh r25 запрашивает версию TS через /echo; клиент шлёт торрент POST на /torrent/upload. Проверка на устройстве: адрес и ответ /echo подтверждены (§1.3), /torrent/upload не вызывался code, disputed (код r25)169
SDK: LaunchMediaUrl с одним URL plugin_installer://*, plugin_uninstaller://* или plugin_launcher://* выбирает установщик, деинсталлятор или запускатель. Проверка на устройстве: запускатель подтверждён (§3.1), остальные не проверялись doc, disputed (SDK)170
Код: play_magnet для нескольких файлов пишет open_magnet.m3u и запускает file://-плейлист. Проверка на устройстве: один файл — прямой поток; проверка на устройстве: шесть .avi — open_magnet.m3u по file:// (§3.3) (устройство r25)79 code, disputed (код r25)171
start_ts демона запускает TS командой TORRSERV_IP=internal … php-cgi … tscli.php start_nowait и не ждёт готовности inference (вывод r25)172
Строка запуска tscli.php в strings связывает демон со стартом встроенного TS inference (вывод r25)173
Номера статусов 0–7 — буквы N, L, p, P, O, E, d, D inference (вывод r25)174
Базовый dl_max_loads_at_once по MemTotal: ≤ 1099999 kB — 1, > 2200000 kB — 3, иначе 2 (ветвь «3» видна на r25, §4.5) inference, verified (вывод r25)175
Проверка 0x54dd0 — скрытая проверка разрешения (лицензии), без неё загрузки идут по одной inference (вывод r25)176
Демон сам не проверяет /tmp/flm.txt и «lite»; r25: без /tmp/flm.txt загрузка дошла до O (§4.5) (устройство r25)149 inference (вывод r25)177
dl_manager следит за /tmp/run/dl_input через fs_watch и при старте один раз сканирует каталог; r25: .in обработан и удалён раньше, чем наблюдатель его прочитал (§4.3) (устройство r25)123 inference (вывод r25)178
Демон уходит в фон (daemon(1,1)) с flock на pid-файле (r25: дескрипторы — §4.6) inference, verified (вывод r25)179
Строка downloads в main — имя плагина для /tmp/plugins/downloads/update_epfs_if_needed_flag inference (вывод r25)180
Код: dl_gstat.txt пишется через FS_write_using_tmp_if_changed, строка на группу в порядке str_nat_cmp по формату "%s %d/%d %.1f %lld %s". r25, device: строка одной группы совпала (§4.3) (устройство r25)121, сортировка нескольких групп и способ записи не проверены code, disputed (код r25)181
Код: .in читается целиком (FS_read_string_unlimited) и удаляется до разбора JSON; ошибки — «unlink(%s) failed», «failed to load file». r25, device: подтверждено только исчезновение .in нормальной команды (устройство r25)123 code, disputed (код r25)182
Код: для непустой восстановленной очереди bootstrap при успешном clock_gettime ставит отметку +0x60, и планировщик не начинает файл, пока от положительной отметки не пройдёт 20 с. r25, device: задержка 20,023 с подтверждена (устройство r25)140, механизм отметки — нет code, disputed (код r25)183
dl_manager запускает и останавливает Java-оболочка; код DlManagerService — §4.6, наблюдения — §6 inference, disputed (вывод r25)184
dl_manager потребляет команды DlState и публикует состояние для PHP (код демона — §4.3) inference (вывод r25)185
Пары {ключ=значение} в plugin_launcher:// доходят до данных действия; r25, device: from из M3U доходит до user_input (§3.1), пары {k=v} по IP Control — буквально, без URL-декодирования (устройство r25)186 inference (вывод r25)187
ff(downloads) проверяет firmware_feature downloads; cond делает pattern условием видимости inference (вывод r25)188

    • fw-tv188b-261021-0117-r25--network-services.c048 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В strings libxxx_ts.so присутствуют TorrServer/MatriX.134, Start TorrServer MatriX.134 и torrserver.db.
    • fw-apk-260724-0207-r24.c054 · code · android-atv; прошивка 260724_0207_r24 · libxxx_ts.so (44235376 байт; firmware/bin/ts по apk_bin_map.txt) — программа на Go с идентификацией TorrServer/MatriX.134 (торрент-сервер), а не ядро медиаплеера

    ↩

  1. fw-tv188b-261021-0117-r25.c087 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 размер /system/bin/libxxx_ts.so — 44235376 байт. ↩↩

  2. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c050 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при ensure_ts плагина downloads mtime каталога /tmp/run/dl_input сменился на 20:24:27.857, а через 2 мс dl_manager записал «D: start_internal_ts(wait:0)...», затем «DONE: TorrServer started» и «start_internal_ts(wait:0): OK» (через ~5,6 с); сам файл команды в dl_input опрос каждые 0,5 с не застал. ↩↩

    • fw-tv188b-261021-0117-r25--downloads.c077 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В прогоне collect8 поток встроенного TS открывался по адресу http://127.0.0.1:8095/stream/... (loopback, порт 8095), а сам процесс ts запущен с --port 8095; внешний TorrServer и переменная TORRSERV_IP в прогоне не проверялись.
    • fw-tv188b-261021-0117-r25.c334 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 клиент downloads использует локальный TorrServer по адресу http://127.0.0.1:8095.

    ↩

  3. fw-tv188b-261021-0117-r25--network-services.c065 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В прогоне collect8 встроенный ts (pid 32670) слушает порт 8095 на всех интерфейсах (*:8095) и отвечает MatriX.134 на /echo с компьютера (http://<адрес в LAN>:8095/echo), то есть доступен из LAN. ↩↩

  4. fw-tv188b-261021-0117-r25--downloads.c037 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · TsHelper::get_ext_torrserver_ip читает ext_torrserver из cookies online_movies, кэширует по mtime и добавляет :8090, если непустое значение не содержит двоеточия. ↩↩

  5. fw-tv188b-261021-0117-r25--downloads.c079 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Работающий в прогоне collect8 ts (pid 32670) запущен с аргументами --port 8095 -k -d /data/data/com.dunehd.app/flashdata/ts -l /data/data/com.dunehd.app/tmp/run/ts.log -w /data/data/com.dunehd.app/tmp/run/tsweb.log; имя настроек и логов — ts; FS_PREFIX=/data/data/com.dunehd.app — из окружения php_server test_plugin8, окружение самого ts не снималось. ↩↩↩↩

  6. fw-tv188b-261021-0117-r25--downloads.c050 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · При дисковом кэше TsHelper задаёт UseDisk=true, TorrentsSavePath=/flashdata/ts_cache и RemoveCacheOnDrop=true; без диска — UseDisk=false и пустой TorrentsSavePath. ↩↩↩

  7. fw-tv188b-260827-0003-r24--http-api--ext-command-params.c094 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 launch_media_url с plugin_launcher://{name=downloads}{action_id=open_magnet}{magnet_url=} запускает публичное действие плагина без точки входа: «[plugin_launcher] launching plugin 'downloads' (ep (null), action open_magnet)» и handle_user_input(entry.open_magnet) с тайм-аутом 300 с. ↩↩

  8. fw-tv188b-261021-0117-r25--downloads.c073 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 show_open_magnet для торрента из трёх файлов показывает диалог «Выберите действие для торрента» с «Название торрента: <имя>», «Найдено файлов: 3» и кнопками «Воспроизвести» (в фокусе) и «Скачать все файлы». ↩↩

  9. fw-tv188b-261021-0117-r25--downloads.c042 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · do_get_series_list возвращает отсортированный по пути массив с title, id=md5(path), size/size_mb при наличии length и URL /stream/<имя>?link=&index=&play; filter_extensions по умолчанию true. ↩↩

  10. fw-tv188b-261021-0117-r25--downloads.c076 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В прогоне collect8 при одном воспроизводимом файле торрента play_magnet сразу вернул downloads->launch_media_url с потоком http://127.0.0.1:8095/stream/Big%20Buck%20Bunny.mp4?link=dd8255ecdc7ca55fb0bbf81323d87062db1f6d1c&index=2&play; open_magnet.m3u и open_magnet.json в $P/tmp/plugins/downloads не созданы, выбора файла не было. ↩↩

  11. fw-tv188b-260827-0003-r24--http-api--ext-command-params.c096 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 launch_media_url с голой magnet-ссылкой (magnet:?xt=urn:btih:…) отклоняется: command_status=failed, error_kind=invalid_parameters, «'media_url' parameter value '…' is invalid: qualified url is expected»; в shell.log «[extcmd] launch_media_url failed: invalid media_url specified». ↩↩

  12. fw-tv188b-260827-0003-r24--http-api--ext-command-params.c097 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 launch_media_url с HTTPS-URL файла .torrent не запустил ни воспроизведение, ни плагин downloads: в shell.log только «[bp_dialog] root item #0 type URL caption ''» без строки элемента «#1: …», каталог /tmp/run/dl_input не изменился. ↩↩

  13. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c049 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 (MemTotal 8146624 kB, папка загрузок не задана) dl_manager при старте пишет в dl_manager.log «PID: …», «INITIALIZING», «D: MemTotal: 8146624 kB», «D: dl_max_loads_at_once is 3», «… is now 1», «0 groups loaded», «W: dl_folder_url not specified», «dl ipc I: warm-up», а /tmp/run/dl_state.txt — две строки «dl_folder_url = » и «dl_folder_path = » (35 байт). ↩↩↩

  14. fw-tv188b-260827-0003-r24.c019 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Сами исполняемые файлы libxxx_*.so лежат в /system/bin/ (37 ELF); крупнейший — libxxx_ts.so (44235376 байт) ↩↩

    • fw-tv188b-261021-0117-r25.c006 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 в firmware_ext/plugins 15 каталогов встроенных плагинов с dune_plugin.xml: к 13 из r24 добавлены downloads и s928x_dvfel
    • fw-tv188b-261021-0117-r25--downloads--manager-runtime.c040 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В r24 (260827_0003) файла system/system/bin/libxxx_dl_manager.so нет: в отсортированном tree.tsv за libxxx_curl.so сразу идёт libxxx_do.so.

    ↩

  15. fw-apk-260724-0207-r24.c044 · code · android-atv; прошивка 260724_0207_r24 · В data.zip 12 встроенных плагинов: android_apps, bluray, dunemdb_supplier_generic, dunemdb_supplier_rutube, dunemdb_supplier_youtube, dunestore, ext_epg, kartina_tv_launcher, ktv_start, radiotime, shell_ext, widget ↩↩

  16. fw-tv188b-260827-0003-r24.c018 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Утилиты Dune в /system/dunehd/firmware/bin/ — симлинки на /data/data/com.dunehd.app/lib/libxxx_<имя>.so (например php_server, run_plugin_cgi, ts, root) ↩

  17. fw-tv188b-261021-0117-r25--network-services.c047 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 firmware/bin/ts — симлинк на /data/data/com.dunehd.app/lib/libxxx_ts.so; сам libxxx_ts.so в /system/bin занимает 44235376 байт. ↩↩↩

  18. fw-tv188b-261021-0117-r25--network-services.c048 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В strings libxxx_ts.so присутствуют TorrServer/MatriX.134, Start TorrServer MatriX.134 и torrserver.db. ↩

  19. fw-apk-260724-0207-r24.c054 · code · android-atv; прошивка 260724_0207_r24 · libxxx_ts.so (44235376 байт; firmware/bin/ts по apk_bin_map.txt) — программа на Go с идентификацией TorrServer/MatriX.134 (торрент-сервер), а не ядро медиаплеера ↩↩

  20. fw-tv188b-261021-0117-r25--network-services.c064 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В прогоне collect8 (2026-10-30) на tv188b r25 $P/firmware/bin/ts — симлинк на $P/lib/libxxx_ts.so, а $P/flashdata/ts/ts — симлинк на $P/flashdata/plugins/dunemdb_supplier_online_movies/bin/ts; у работающего процесса ts (pid 32670) снят только argv (ts --port 8095 ...), /proc/<pid>/exe не снят, поэтому тождество бинарников не установлено. ↩↩

  21. fw-tv188b-261021-0117-r25--network-services.c068 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 владельцем порта :8095 был ts pid 20513: /proc/<pid>/exe → /system/bin/libxxx_ts.so, cwd /system/dunehd/firmware_ext/plugins/downloads, PPid 1, uid 0; /echo ответил MatriX.134; на :8090 слушает отдельный torrserver pid 3885. ↩↩↩↩

  22. fw-tv188b-261021-0117-r25--network-services.c069 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 окружение работающего ts содержит GODEBUG=madvdontneed=1 и TORRSERV_IP=internal; TORRSERV_NAME в нём отсутствует; cmdline — .../flashdata/ts/ts --port 8095 -k -d .../flashdata/ts -l .../tmp/run/ts.log -w .../tmp/run/tsweb.log. ↩↩↩↩↩

  23. fw-tv188b-261021-0117-r25--downloads.c048 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · TsHelper::ensure_ts_file немедленно возвращает true при HD::is_apk(); вне APK, если найден update.php online_movies, запускает его через php-cgi. ↩↩

  24. fw-apk-260724-0207-r24.c030 · code · android-atv; прошивка 260724_0207_r24 · PHP-фреймворк APK (dunelib/utils.php) определяет HD::is_android() = true, is_apk() = getenv("HD_APK"), is_fw_apk() = getenv("HD_FW_APK"), is_limited_apk() = is_apk() && !is_fw_apk(), with_network_manager() = !is_limited_apk(), get_apk_package_name() = getenv("APK_PACKAGE_NAME") ↩

    • fw-tv188b-261021-0117-r25.c092 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 у процесса httpd ($FS_PREFIX/bin/httpd, PPID 1) в окружении HD_HTTP_LOCAL_PORT=80, HD_FW_APK=1, HD_APK=1, FS_PREFIX=/data/data/com.dunehd.app, LOG_DIR=/tmp/run, DUNEHD_SERVICE_DONT_FORK=1, PATH начинается с $FS_PREFIX/firmware/bin:$FS_PREFIX/bin:/bin, а LD_LIBRARY_PATH=$FS_PREFIX/firmware/lib:/lib:/usr/lib (без /system/xbin/dunehd/firmware/lib).
    • fw-tv188b-261021-0117-r25.c091 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 у процесса network_manager ($FS_PREFIX/firmware/bin/network_manager, PPID 1) в окружении HD_HTTP_LOCAL_PORT=80, HD_FW_APK=1, HD_APK=1, FS_PREFIX=/data/data/com.dunehd.app, LOG_DIR=/tmp/run, DUNEHD_SERVICE_DONT_FORK=1, PATH начинается с $FS_PREFIX/firmware/bin:$FS_PREFIX/bin:/bin, а LD_LIBRARY_PATH=$FS_PREFIX/firmware/lib:/lib:/usr/lib (без /system/xbin/dunehd/firmware/lib).

    ↩

  25. fw-tv188b-261021-0117-r25--downloads.c070 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · ensure_ts при недоступном внешнем TS возвращает ensure_ts_status=-1 без локального запуска; при недавнем внутреннем запуске ждёт TS, иначе посылает DlState::start_ts. ↩↩

  26. fw-tv188b-261021-0117-r25--downloads.c017 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · DlState::start_ts, change_dl_folder и test_dl_folder записывают JSON с единственным cmd_type в /tmp/run/dl_input/..in. ↩

  27. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c001 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Демон dl_manager сопоставляет cmd_type с номерами 0–7: add, remove, pause, resume, start_ts, change_dl_folder, test_dl_folder, on_playback_finish (fcn.000535d8); прочие номера дают пустую строку. ↩↩

  28. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c011 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Обработчик команд fcn.00063010 ветвится по номеру: 0 — add внутри себя, 1–3 — fcn.00062028, 4 — fcn.00066ef8 (запуск TS с аргументом 0), 5 — смена папки, 6 — fcn.00059da0, 7 — fcn.00055770. ↩

  29. fw-tv188b-261021-0117-r25--downloads.c065 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В strings dl_manager присутствуют шаблоны запуска php-cgi tscli.php с TORRSERV_IP=internal и с TORRSERV_IP=%s для add/rem_idle. ↩

    • fw-tv188b-261021-0117-r25--network-services.c052 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · tscli.php по команде start, если TorrServer ещё не запущен, вызывает TsHelper::start_ts, затем ждёт запуска и вызывает configure_ts; start_nowait в том же случае вызывает только start_ts.
    • fw-tv188b-261021-0117-r25--downloads.c054 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · tscli.php диспетчеризует status/start/start_nowait/stop/list_torrents(list)/get/cache/add/add_save_to_db/drop/rem/drop_idle/rem_idle/settings/set_setting; start_nowait пропускает ожидание и configure_ts.

    ↩

  30. fw-tv188b-261021-0117-r25--downloads.c078 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На 2026-10-30 в /tmp/run/ts_launch.lock есть файл 0 байт, rw-rw-rw-, root, с mtime 2026-10-28 20:24:27, а /tmp/run/ts_launch_time.txt отсутствует; в том же прогоне ensure_ts завершился за 50 мс (26.306532 → 26.356912) при уже работающем TS (pid 32670). ↩↩

  31. fw-tv188b-261021-0117-r25--downloads.c047 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · wait_for_running_ts делает до 100 проверок через 400 мс; при доступности сервера удаляет метку запуска, при исчерпании возвращает false. ↩

  32. fw-tv188b-261021-0117-r25.c332 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 вызов downloads->handle_user_input(entry.ensure_ts) в 17:24:27.857 UTC совпал с mtime каталога /tmp/run/dl_input (20:24:27.857 +0300); через 2 мс dl_manager записал start_internal_ts(wait:0), затем DONE: TorrServer started. ↩

  33. fw-tv188b-261021-0117-r25--downloads.c072 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 действие open_magnet плагина downloads с непустым magnet_url прошло цепочку entry.open_magnet → entry.ensure_ts (~11 с, запуск TorrServer) → entry.open_dl → show_dialog с опросом entry.dialog_open_dl раз в ~1 с (три вызова) → close_dialog_and_run → entry.show_open_magnet → show_dialog; тайм-аут open_magnet и dialog_open_dl — 300 с, остальных шагов — 60 с. ↩↩

    • fw-tv188b-261021-0117-r25--downloads--manager-runtime.c051 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В dl_manager.log за 2026-10-28 17:24:27–33 записан запуск внутреннего TS: start_internal_ts(wait:0)... → DONE: TorrServer started → start_internal_ts(wait:0): OK (≈5,5 с); строка команды и имя tscli.php в журнале не видны.
    • fw-tv188b-261021-0117-r25--network-services.c067 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В прогоне collect8 журнал dl_manager.log подтверждает запуск встроенного TS демоном загрузок: запись 2026-10-28 17:24:27 start_internal_ts(wait:0)..., затем DONE: TorrServer started и start_internal_ts(wait:0): OK в 17:24:33; имя tscli.php в журнале не видно, связь с ним — по коду c053.

    ↩

  34. fw-tv188b-261021-0117-r25--network-services.c066 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Процесс ts (pid 32670, root, ppid 1) в прогоне collect8 (2026-10-30) не менялся с 12:45 до 13:09 и пережил am force-stop com.dunehd.app в 13:02; в его ts.log есть записи 2026-10-28 17:24:34–37, в том числе «end set settings». ↩

  35. fw-tv188b-261021-0117-r25.c334 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 клиент downloads использует локальный TorrServer по адресу http://127.0.0.1:8095. ↩↩

  36. fw-tv188b-261021-0117-r25--downloads.c077 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В прогоне collect8 поток встроенного TS открывался по адресу http://127.0.0.1:8095/stream/... (loopback, порт 8095), а сам процесс ts запущен с --port 8095; внешний TorrServer и переменная TORRSERV_IP в прогоне не проверялись. ↩

  37. fw-tv188b-261021-0117-r25--downloads.c087 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 cookies поставщика online_movies (dunemdb_supplier_online_movies_plugin_cookies.properties) содержат только ключ sort_video_streams; ключа ext_torrserver нет, а поток S01E01 в open_magnet.m3u идёт на http://127.0.0.1:8095. ↩↩

  38. fw-tv188b-261021-0117-r25--network-services.c054 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 в прогоне 2026-10-23 TorrServer был внешним приложением ru.yourok.torrserve (процесс torrserver, root) и слушал *:8090, 127.0.0.1:36535 и 0.0.0.0:32400. ↩

  39. fw-tv188b-261021-0117-r25--network-services.c037 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · init_torrents.sh по умолчанию хранит данные btpd в /D/.btpd, список — в /tmp/run/torrent_list, статус — в /tmp/run/btpd.status; настройки torrent_client_run_on_boot (по умолчанию no), torrent_client_empty_start, torrent_client_bw_in/out (0 = без лимита), max_peers (default), max_uploads (auto), ip (default) и port (6881) читаются из config/settings.properties. ↩

  40. fw-tv188b-261021-0117-r25--network-services.c038 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В режиме boot/boot_bg init_torrents.sh запускает btpd, только если torrent_client_run_on_boot=yes; старт требует смонтированного /D с ФС ext2, ext3 или tntfs, иначе выходит с ошибкой. Запуск — nice -n 19 firmware/torrent_client/btpd/bin/btpd -d /D/.btpd ... --port , если torrent_client_port != 0; если btpd уже работает, вызывается manage_torrents.sh restart. ↩

  41. fw-tv188b-261021-0117-r25--network-services.c063 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25, 260827_0003_r24 · init_network.sh, init_torrents.sh, udhcpc_callback.sh и smb.bash в r24 и r25 совпадают побайтово: размеры и SHA-256 в tree.tsv одинаковые. ↩↩↩

  42. fw-tv188b-261021-0117-r25--downloads.c049 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Для кэша TS значение /config/ts_disk_cache.txt, отличное от -1, имеет приоритет; иначе MemTotal<1100000 kB выбирает диск, а MemTotal<100000 считается ошибкой определения. ↩↩

  43. fw-tv188b-261021-0117-r25--downloads.c051 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · ensure_head_and_tail при валидных CacheSize/ReaderReadAHead/PreloadCache увеличивает недостаточные части кэша до минимумов 60000000 байт головы и 30000000 байт хвоста и пересчитывает три настройки. ↩

  44. fw-tv188b-261021-0117-r25--downloads.c052 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · configure_ts выставляет DisableUpload=true, если настройка была false/отсутствовала, и сохраняет настройки при любом из четырёх признаков изменения. ↩

  45. fw-tv188b-261021-0117-r25--downloads.c053 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · configure_connections выбирает ConnectionsLimit=50 только при HD2::with_dl() и falsey is_low_ram_product(), иначе 25. ↩

  46. fw-tv188b-261021-0117-r25--downloads.c061 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · omgr_install создаёт флаг очистки shown-cache и помечает EPF изменённым; omgr_uninstall создаёт тот же флаг и для внутреннего TS вызывает stop_ts_and_clear_cache. ↩

  47. fw-tv188b-261021-0117-r25--downloads.c055 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В tscli drop_idle/rem_idle непустой Readers из /cache предотвращает удаление и завершает процесс с кодом 2. ↩

  48. fw-tv188b-260827-0003-r24--firmware-config.c051 · code · android-dune-fw; прошивка 260827_0003_r24 · Экран playback_preferences в menu_config.xml перечисляет setting id: player_for_video, player_for_avi, player_for_audio, player_for_audio_hifi_output, vc1_hardware_acceleration, persistent_zoom, osd_3d_depth, resume_playback_position, hls_initial_bandwidth_new, optimize_torrserver_settings. ↩

  49. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c031 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В strings dl_manager присутствует путь /tmp/run/ts_player.txt. ↩

  50. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c030 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В strings dl_manager есть путь /flashdata/dl_cache/bt_hashes_to_delete.txt и сообщения о загрузке хэшей на удаление из файла. ↩

  51. fw-tv188b-261021-0117-r25.c030 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Встроенный плагин downloads (r25, type php, program main.php): точка входа в root://applications показывается действием cond с pattern is_plugin_file(dunemdb_supplier_online_movies/__v2); вторая — в setup://applications (show_by_default no); public_actions open_magnet и download_settings; EPF включены ↩↩↩

  52. fw-tv188b-261021-0117-r25--downloads.c002 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Публичные действия open_magnet и download_settings манифеста downloads направлены в handler_id=entry с одноимённым control_id. ↩↩

  53. fw-tv188b-261021-0117-r25--media-player.c068 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 IP Control launch_media_url с одноэлементным M3U по HTTP (компьютер либо www плагина), содержащим plugin_launcher, вызывает действие b3 и передаёт from в user_input. ↩

  54. fw-tv188b-261021-0117-r25--media-player.c069 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 GUI-действие launch_media_url с M3U из www плагина вызывает b3 по plugin_launcher и передаёт from=gui. ↩

  55. plg-dc-screenshoter.c035 · code · unknown; прошивка — · ActionFactory::launch_media_url возвращает GuiAction с LAUNCH_MEDIA_URL_ACTION_ID; плагин запускает так URL plugin_launcher:// ↩

  56. fw-tv188b-261021-0117-r25--downloads.c003 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · open_magnet требует непустой magnet_url и строит цепочку ensure_ts → open_dl с требованием файлов и результатом в tmp_dir_path/open_magnet.json. ↩

  57. fw-tv188b-261021-0117-r25--downloads.c084 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 диалог «Выберите действие для торрента» показывает кнопку «Скачать все файлы» при нескольких файлах и «Скачать» при одном; первой в обоих случаях идёт «Воспроизвести». ↩

  58. fw-tv188b-261021-0117-r25--downloads.c074 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 выбор «Скачать все файлы» без заданной папки загрузок (cookies плагина downloads нет) ведёт по цепочке entry.apply_open_magnet → entry.choose_enter_action → entry.add_dl → choose_file и открывает диалог выбора «Папка загрузок» со списком хранилищ (Встроенная память, Браузер сети, сетевые папки). ↩

  59. fw-tv188b-261021-0117-r25--downloads.c085 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при первой загрузке без заданной папки после «Скачать» открылся диалог «Папка загрузок»; «Встроенная память» выбрана стрелкой вправо, затем показано предложение добавить папку в Мою коллекцию (entry.confirm_add_mc_folder), пропущенное; сохранён dl_folder_url = sdcard:///DuneHD. ↩

  60. fw-tv188b-261021-0117-r25--downloads.c086 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 во втором прогоне, когда dl_folder_url уже был sdcard:///DuneHD, после «Скачать» диалогов «Папка загрузок» и «Добавить в Мою коллекцию» не было: сразу показано «Добавлено в загрузки», dl_gstat — L 1/1 0.0 0 <btih>. ↩

  61. fw-tv188b-261021-0117-r25--downloads.c083 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 для раздачи без сидов (Pioneer One VO, 0 сидов) после open_magnet вместо диалога выбора действия через ~70 с показан диалог «Не удалось подключиться к источнику»; open_magnet начался в 19:18:23, show_open_magnet — в 19:19:33, open_magnet.m3u не создан. ↩

  62. fw-tv188b-261021-0117-r25--downloads.c004 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · dialog_open_dl опрашивает TorrServer::torrserverActionGet до получения file_stats (при open_dl_require_files — непустых), сохраняя JSON в open_dl_result_path и передавая open_dl_status в callback. ↩

  63. fw-tv188b-261021-0117-r25--downloads.c005 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · show_open_magnet предлагает play и download; apply_open_magnet для download выбирает все файлы, для play — только прошедшие фильтр воспроизводимости. ↩

  64. fw-tv188b-261021-0117-r25--downloads.c006 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · При magnet_choice=download apply_open_magnet повторно добавляет торрент в TorrServer с аргументом 2, а group_id для последующего добавления загрузки берёт из возвращённого hash. ↩

  65. fw-tv188b-261021-0117-r25--downloads.c039 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · apiHttpPost посылает JSON методом POST с Content-Type application/octet-stream; таймаут по умолчанию 10 секунд, для torrserverActionAdd задано 30. ↩

  66. fw-tv188b-261021-0117-r25--downloads.c040 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Клиент TorrServer определяет /settings для get/set, /cache для get, /torrents для list/drop/rem/add/get, /torrent/upload для загрузки файла, /echo для проверки состояния и /shutdown для остановки. ↩

  67. fw-tv188b-261021-0117-r25--downloads.c041 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · torrserverAddTorrent задаёт dont_save только при втором аргументе 1; torrserverActionAdd передаёт save_to_db=!dont_save, а upload — поле save=!dont_save. ↩

  68. fw-tv188b-261021-0117-r25--downloads.c043 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · torrserverActionGet включает API_OPT_LONG_INT_AS_STRING: перед json_decode клиент заменяет значения из 10 и более десятичных цифр после ключа \w+ на JSON-строки. ↩

  69. fw-tv188b-261021-0117-r25--downloads.c044 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · При opts без ожидаемого JSON-ответа apiHttpPost возвращает true даже после false от file_get_contents; SettingsWrite дополнительно безусловно возвращает true. ↩

  70. fw-tv188b-261021-0117-r25--downloads.c054 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · tscli.php диспетчеризует status/start/start_nowait/stop/list_torrents(list)/get/cache/add/add_save_to_db/drop/rem/drop_idle/rem_idle/settings/set_setting; start_nowait пропускает ожидание и configure_ts. ↩

  71. fw-tv188b-261021-0117-r25--downloads.c056 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · tscli.php строит include_path из FS_PREFIX/firmware_ext/php/include и текущего каталога. ↩

  72. fw-tv188b-261021-0117-r25--downloads.c075 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В прогоне collect8 торрент Big Buck Bunny из 3 файлов (.srt, .mp4, poster.jpg) после кнопки «Воспроизвести» не показал выбора файла: apply_open_magnet получил magnet_play_files только с mp4 (index=2), а magnet_all_files — все 3 файла. ↩

  73. fw-tv188b-261021-0117-r25--downloads.c080 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 для торрента Pioneer One VO (12 файлов) entry.play_magnet вернул launch_media_url с file:///data/data/com.dunehd.app/tmp/plugins/downloads/open_magnet.m3u; файл содержит шесть записей #EXTINF с avi, srt в плейлист не попали. ↩↩

  74. fw-tv188b-261021-0117-r25--downloads.c081 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 URL записи open_magnet.m3u имеет вид http://127.0.0.1:8095/stream/<имя>?link=<btih>&index=<N>&play|||dune_params|||http_online_subs:1,file_id:<папка>/<имя>; у шести avi индексы 1, 3, 5, 7, 9, 11, а в полном списке файлов S01E01.srt имеет index=2. ↩

  75. fw-tv188b-261021-0117-r25--downloads.c082 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 после запуска open_magnet.m3u играет первая серия: playback_url — S01E01 с index=1, playback_caption=Pioneer.One.S01E01.avi (1 из 6), движок VLC; кадр видеослоя снят с ТВ. ↩

  76. fw-tv188b-261021-0117-r25--downloads.c008 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · get_magnet_playback_url добавляет к playback_url суффикс |||dune_params|||http_online_subs:1,file_id:<путь файла>. ↩

  77. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c071 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 плагин downloads вызывает shell_ext entry/play_recent с sup_id, movie_id, autoplay=1, single_mode=1, sup_data=0, wh_manual=1, wh_single_torrent=1, wh_torrent и wh_uid вида :::, таймаут 20000 мс. ↩

  78. fw-tv188b-261021-0117-r25--downloads.c009 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · get_play_action возвращает null без любого из params sup_id, movie_id, uid, id, torrent_name; иначе строит вызов shell_ext entry/play_recent с wh_uid из sup_id:movie_id:md5(file_path):uid. ↩

  79. fw-tv188b-261021-0117-r25.c053 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Новый ключ описателя поставщика dl_capable (r25): первый поставщик с dl_capable становится dl-поставщиком (кнопка «Загрузки», Suppliers::get_dl_sup), только если в firmware_features есть флаг downloads ↩↩↩

  80. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c042 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · MainStack::get_movie_button_ids r25 добавляет кнопку dl сразу после play, если есть dl-поставщик (Suppliers::get_dl_sup) и в конфигурации списка плееров (mc или all) элемент sup_ не исключён операцией -. ↩

  81. fw-tv188b-261021-0117-r25--shell-ext--entry-handler--movie-screen.c037 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Нажатие кнопки dl берёт Suppliers::get_dl_sup и вызывает do_get_play_action('online_dl',sup->id), а при отсутствии поставщика возвращает null. ↩

  82. fw-tv188b-261021-0117-r25--downloads.c010 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · choose_enter_action требует dl_id, заданное dl_name, положительное dl_total и непустые JSON-массивы dl_files и dl_all_files. ↩

  83. fw-tv188b-261021-0117-r25--downloads.c011 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Ветка add_dl читает add_dl_id/name/total и JSON add_dl_files/params, затем передаёт их в DlState::add_download вместе с текущим внешним TorrServer. ↩

  84. fw-tv188b-261021-0117-r25.c032 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · rows_menu_config.json r25 добавляет пункт верхнего меню плагина downloads (epf_id downloads_epf) с условием "if":"and(ff(downloads),is_file(/flashdata/plugins/dunemdb_supplier_online_movies/__v2))" ↩

  85. fw-tv188b-261021-0117-r25.c026 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · firmware_features.txt r25 содержит новый флаг downloads ↩↩

  86. fw-tv188b-261021-0117-r25.c101 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 /tmp/firmware_features.txt — по флагу в строке: tmpfs, dunemdb_supplier_plugin_api_v2…v7, sup_api_v8, tv_config, newgui2021, app_root_url_type, movie_suppliers_update, movie_suppliers_order, url_sdcard, lcfg_v2, light_stop, apk, fw_apk, drm_apps, downloads. ↩↩

  87. fw-tv188b-261021-0117-r25.c025 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · ConfigUtils::load_firmware_features() в r25 убирает флаг downloads из набора, если есть файл /tmp/flm.txt (комментарий: оболочка создаёт его для «lite»-лицензии без загрузок) ↩

  88. fw-tv188b-261021-0117-r25--downloads.c001 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · MainPlugin создаёт общий DlState и регистрирует экраны DownloadsScreen, FilesScreen и SetupScreen. ↩

  89. fw-tv188b-261021-0117-r25--downloads.c058 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · DownloadsScreen и FilesScreen выбирают таймер 1000 мс при fast_timer_countdown>0 и 5000 мс иначе; SetupScreen задаёт 2000 мс. ↩

  90. fw-tv188b-261021-0117-r25--downloads.c027 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · DlUi::make_progress показывает 100 для O, использует resume_pos для N и pos для остальных; расчёт незавершённого прогресса ограничен строкой 99.9 при доле >=0.99. ↩

  91. fw-tv188b-261021-0117-r25--downloads.c028 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · DlUi помечает E как ERR, p/P как PAUSE, O значком 100%; скорость выводится только при status L или p и speed>=1024. ↩

  92. fw-tv188b-261021-0117-r25--downloads.c059 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · show_in_folder добавляет .part к имени файла, если запись отсутствует либо status!=O, и строит embedded_app://{name=path_from_source} с source_type/source_id/path/sel_id. ↩

  93. fw-tv188b-261021-0117-r25--downloads.c060 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Жёлтая кнопка DownloadsScreen и FilesScreen запускает online_movies с ep_media_url=setup и action_id=setup_download_settings. ↩

  94. fw-tv188b-261021-0117-r25--downloads.c057 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · EpfsHandler пишет downloads_epf; stamp объединяет mtime dl_gstat.txt и dl_state.txt, обновление пропускается при прежнем stamp вне cold_boot и при выключенном HD::with_epfs(). ↩

  95. fw-tv188b-261021-0117-r25--downloads.c029 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · SetupScreen предлагает папку с именем dune_downloads через choose_file: только каталоги, проверка записи и оба сетевых режима включены. ↩

  96. fw-tv188b-261021-0117-r25--downloads.c030 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · apply_dl_folder_url принимает только успешный выбор одного URL, сохраняет dl_folder_url в cookies и возвращает отдельное действие post_apply_dl_folder_url перед change_dl_folder. ↩

  97. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c001 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · fcn.000596ac читает dl_folder_url из /config/downloads_plugin_cookies.properties через properties_build_from_buffer и properties_get. ↩

  98. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c060 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 в первом прогоне файла cookies downloads_plugin_cookies.properties не было, а /tmp/run/dl_state.txt содержал пустые dl_folder_url и dl_folder_path; после выбора «Встроенная память» в cookies записан dl_folder_url = sdcard:///DuneHD, а в dl_state — dl_folder_url = sdcard:///DuneHD и dl_folder_path = /sdcard/DuneHD. ↩

    • fw-tv188b-261021-0117-r25--downloads.c034 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · StorageHelper::parse_dl_folder_url распознаёт sdcard, storage_name, network_folder_id, nfs/nfs-tcp/nfs-udp и smb; непригодный или неизвестный URL даёт объект с type=null.
    • fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c002 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Разбор dl_folder_url допускает схемы sdcard и storage_name, а также префиксы network_folder_id://, nfs://, nfs-tcp://, nfs-udp:// и smb://.

    ↩

  99. fw-tv188b-261021-0117-r25--downloads.c035 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · reload_storage_list читает /tmp/run/storage_list.xml и исключает записи storage с is_persistfs_capable=1; для storage_name требуется найденный mount_path. ↩

  100. fw-tv188b-261021-0117-r25--downloads.c033 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · После применения папки SetupScreen строит для shell_ext вызов entry/ensure_mc_folder с folder_url из dl_folder_url. ↩

    • fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c028 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Ветка ensure_mc_folder (r25) читает folder_url и JSON ensure_mc_folder_result_action: если папка уже входит в папку «Моей коллекции» или её тип не sdcard, storage, network_folder_id, nfs или smb, возвращает это действие; иначе повторяет вход как confirm_add_mc_folder с dl_mode=1, source_id и path.
    • fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c030 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · confirm_add_mc_folder в r25 показывает диалог добавления папки: при dl_mode — тексты msg_add_dl_folder_to_my_collection_*, заголовок downloads_plugin_title_downloads_folder, кнопки «добавить» (повтор входа как add_mc_folder) и «пропустить» (JSON ensure_mc_folder_result_action); без dl_mode — прежние тексты и «Отмена».

    ↩

  101. fw-tv188b-261021-0117-r25--downloads.c031 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · При незаданном change_dl_folder_confirmed SetupScreen сразу разрешает смену папки лишь при пустом списке; при группах вне O/P/E кнопка продолжения не добавляется. ↩

  102. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c015 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · change_dl_folder при непустом списке ставит каждой группе статус 6 и удаляет её из состояния вызовом fcn.00056f94 с третьим аргументом 1 (без удаления файлов, c027), затем перечитывает папку (fcn.000596ac) и записывает dl_state. ↩

  103. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c009 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Проверка папки fcn.0005764c возвращает отказ с dir_access_error, если FS_is_dir для разрешённого пути дал 0. ↩

  104. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c012 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Неуспешный тест записи в fcn.0005764c задаёт dir_write_error и возвращает 0. ↩

  105. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c016 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Обработчик add отклоняет команду с сообщением dl E: dl folder not available, если разрешённого пути папки нет. ↩

  106. fw-tv188b-261021-0117-r25--downloads.c015 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Проверка места пропускает предупреждение при mb_pending+mb_new <= mb_free-1000; иначе один раз посылает test_dl_folder, ждёт 2 секунды и затем позволяет продолжить вручную. ↩

  107. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c013 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · После успешного разрешения папки с ненулевым FS_is_exfs демон публикует mb_free=0 и mb_total=0 вместо вызова помощника обновления места 0x00056bdc. ↩

  108. fw-tv188b-261021-0117-r25.c027 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · dunelib/dl_state.php (r25): DlState отправляет команды менеджеру загрузок JSON-файлами в /tmp/run/dl_input/<время>.<…>.in с cmd_type add (id, name, total, files[path, url, size_mb, ext_ts], params), remove, pause, resume (group_id, file_paths), start_ts, change_dl_folder, test_dl_folder ↩

  109. fw-tv188b-261021-0117-r25--downloads.c021 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Записи команд DlState используют HD::write_to_file_using_tmp: запись .tmp, затем rename в целевой путь; при ошибке записи или rename помощник возвращает false. ↩

    • fw-tv188b-261021-0117-r25--downloads.c018 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · DlState::add_download пишет cmd_type=add с id, name, total, files и, только при truthy params, params; имя файла содержит microtime и md5(group_id).
    • fw-tv188b-261021-0117-r25--downloads.c019 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · DlState::add_download_file добавляет path/url/size_mb, а add_download дописывает одинаковый ext_ts в каждый элемент files.

    ↩

  110. fw-tv188b-261021-0117-r25--downloads.c020 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · DlState::remove_download/pause_download/resume_download пишут cmd_type remove/pause/resume и group_id, добавляя file_paths только при truthy списке. ↩

  111. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c037 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · /tmp/run/dl_state.txt демон пишет через FS_write_using_tmp_if_changed строками dl_folder_url = …, dl_folder_path = …, error = … (если задана); mb_free и mb_total — только при непустом dl_folder_path. ↩

  112. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c053 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 строка /tmp/run/dl_gstat.txt для одной группы содержит пять полей: букву статуса, <файлов>/<всего>, процент с одним десятичным знаком, скорость и btih; в ходе загрузки — L 1/1 10.1 6666186 <btih>, в конце — O 1/1 100.0 0 <btih>. ↩↩↩

  113. fw-tv188b-261021-0117-r25--downloads.c024 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Для .json DlState сначала ищет /tmp/run/dl_cache, затем /flashdata/dl_cache; all_state_load использует тот же приоритет и устраняет повторы id. ↩

  114. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c059 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 файл команды появился в /tmp/run/dl_input как <id>.in.tmp, затем как <id>.in; на событие y в events.txt записано не успел (ссылку на файл сделать не удалось), после чего файл удалён; команда при этом обработана: в dl_manager.log — handle add_dl и added group … status N. ↩↩↩↩

  115. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c002 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Файл в /tmp/run/dl_input, имя которого короче 3 символов или не оканчивается на .in, демон удаляет (FS_unlink), не читая. ↩

  116. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c004 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Если cmd_type в .in отсутствует или не совпал ни с одним именем таблицы, команда отбрасывается с сообщением input E: cmd_type missing or unsupported (индекс-заглушка 99). ↩

  117. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c025 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Команда on_playback_finish (номер 7) вызывает обработчик очереди отложенного удаления хэшей fcn.00055770. ↩

  118. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c005 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Команда add принимается только с непустыми (не из одних пробелов) id и name, total не меньше 1 и массивом files; params необязателен и копируется в свойства группы. ↩

  119. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c006 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Из элементов files демон читает url, path, ext_ts и size_mb; элемент без url или без path молча пропускается. ↩

  120. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c013 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Если путь файла из add уже есть в другой группе в статусе, отличном от 7, вся команда add отклоняется (add E: path already added). ↩

  121. fw-tv188b-261021-0117-r25--downloads.c013 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · После add_dl и операций над загрузкой GUI ждёт смены статуса до 50 опросов с usleep(200000), а в result_action добавляет dl_status_changed=1 либо 0. ↩

  122. fw-tv188b-261021-0117-r25.c117 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 /tmp/run/dl_input и /tmp/run/dl_cache — каталоги drwxrwxrwx root:root, а dl_gstat.txt, dl_state.txt, dl_manager.log и dl_manager.pid — файлы -rw-rw-rw- root:root. ↩

  123. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c052 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 загрузка одного файла прошла статусы группы N → L → O: при добавлении в dl_manager.log записано status changed: N -> L, по завершении — status changed: L -> O и сразу I: all finished; итоговая строка dl_gstat — O 1/1 100.0 0 <btih>. ↩

  124. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c022 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Начиная загрузку файла, планировщик создаёт каталоги для <папка загрузок>/.part (FS_ensure_dirs, 0777), ставит задачу с id / и записью в этот .part с позиции файла и переводит файл в статус 1. ↩

  125. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c023 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Файл в статусе 4 демон переименовывает из <папка>/.part в <папка>/ (FS_rename, затем FS_sync_parent_dir); при ошибке rename или недоступной папке файл получает статус 5. ↩

  126. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c026 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Для обычного .part позиция докачки — его размер, округлённый вниз до кратного 16 МиБ (маска 0xff000000 младшего слова) минус 16 МиБ, но не меньше 0 (resume D: truncate). ↩

  127. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c025 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Если .part существует, но не обычный файл, демон удаляет его рекурсивно (FS_remove_recursively_if_exists) и начинает файл заново (статус 0, позиция 0); при неудаче удаления — статус 5. ↩

  128. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c029 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · pause переводит файлы группы (или из file_paths) из статусов 0 и 5 в 3 ('P'), активные (статус 1) — в 2 ('p') с отменой задачи; файлы в 2, 3 и 4 не меняются, 6 и 7 пропускаются. ↩

  129. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c030 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · resume возобновляет только файлы в статусах 3 и 5 (остальные — ignore f): сверяет позицию с размером .part, уже докачанный файл ставит в 4 и переименовывает, остальным ставит статус 0. ↩

    • fw-tv188b-261021-0117-r25--downloads--manager-runtime.c032 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · remove с file_paths переводит файлы в статусах 1 и 2 в 6 (для 1 — с отменой задачи), остальные — в 7 с удалением с диска через fcn.00057594 при доступной папке.
    • fw-tv188b-261021-0117-r25--downloads--manager-runtime.c033 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · По завершении задачи загрузки (apply_task) файл в статусе 6 или 7 либо из группы в статусе 6 удаляется с диска и получает 7, а группа в 6 без оставшихся файлов удаляется. Иначе при состоянии задачи 1 статус 2 становится 3, прочие — 4 с переименованием .part; при ином состоянии 2 становится 3, прочие — 5, кроме повтора после HTTP 500 (статус 0).

    ↩

  130. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c059 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при восстановлении непустой группы старт загрузки отложен на 20 с: boot D: postpone download for 20s записан в 19:46:31.893706, а D: start load f BIG_BUCK_BUNNY.iso, pos 234881024 — в 19:46:51.917072 (разница 20,023 с). ↩↩↩

  131. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c028 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · При совпадении hash группы с прочитанным hash воспроизведения и установленном младшем бите третьего аргумента fcn.00056cf4 ставит удаление в очередь через 0x00056158 для каждого собранного сервера. ↩

  132. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c029 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · fcn.00055770 убирает запись из очереди при результате 0x00067248, равном 0 или 2; прочие результаты оставляют запись в очереди. ↩

  133. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c054 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при активной загрузке (10.1 %) kill dl_manager не привёл к подъёму демона за 60 с; после am force-stop com.dunehd.app (приложение поднялось само) новый dl_manager (pid 31489, PPid 1, root) восстановил ту же группу и довёл загрузку до O 1/1 100.0 (первый dl_gstat после перезапуска — 11.2 %); в этом прогоне перезапуск приложения возобновил прерванную загрузку. ↩↩↩

  134. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c058 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 bootstrap после перезапуска демона прочитал одну группу (1 groups loaded), разрешил и смонтировал папку (D: dl_folder_url is suitable: sdcard:///DuneHD, I: dl folder mount: /sdcard/DuneHD), затем восстановил группу в очередь (added to load) и только после этого записал boot D: postpone download for 20s. ↩

  135. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c055 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 bootstrap после перезапуска демона усек .part файла BIG_BUCK_BUNNY.iso с 260046848 до 234881024 байт (resume D: truncate 260046848 -> 234881024) и начал докачку с 234881024 (seeking to 234881024, CURLOPT_RESUME_FROM_LARGE to 234881024); докачка пошла с 234881024, а не с нуля. ↩

  136. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c021 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Планировщик fcn.0005b510 запускает новые загрузки, только пока число начатых меньше текущего dl_max_loads_at_once (глобал 0x9a904). ↩

  137. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c018 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · fcn.00054e78 (и начало fcn.00063010) вызывает проверку по адресу 0x54dd0: при результате 0 текущий dl_max_loads_at_once становится 1, иначе берётся базовое значение из глобала 0x9a900; смена пишется в лог D: dl_max_loads_at_once is now %d. ↩

  138. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c057 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при MemTotal 8146624 kB демон при старте пишет D: dl_max_loads_at_once is 3, затем D: dl_max_loads_at_once is now 1; то же повторяется у демона, поднятого после restart_app (pid 31489). ↩

  139. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c058 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 загрузка BIG_BUCK_BUNNY.iso завершилась до O при отсутствующем /tmp/flm.txt и до, и после скачивания (ls: /tmp/flm.txt: No such file or directory). ↩↩

  140. fw-tv188b-261021-0117-r25--downloads.c014 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · check_on_add вызывает builtin pf_check с pf2=1, если существует другая группа со статусом, отличным от O; при add_dl_check_failed возвращается status(-1). ↩

  141. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c039 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 /system/bin/libxxx_dl_manager.so (ELF, 630612 байт) доступен как firmware/bin/dl_manager через символьную ссылку на /data/data/com.dunehd.app/lib/libxxx_dl_manager.so; priv-app/dune/lib/arm/libxxx_dl_manager.so ссылается на /system/bin/libxxx_dl_manager.so. ↩

  142. fw-tv188b-261021-0117-r25.c116 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 dl_manager работает отдельным процессом от root (метка u:r:shell:s0, PPID 1), его pid записан в /tmp/run/dl_manager.pid. ↩

  143. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c056 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 pid-файл /tmp/run/dl_manager.pid совпадает с pidof dl_manager (1795 до перезапуска, 31489 после), процесс — root с PPid 1, каталог /tmp/run/dl_input имеет права drwxrwxrwx; после kill старый pid-файл остаётся с прежним mtime. ↩

  144. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c046 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 у работающего dl_manager (root, PPid 1) открыты fd 0 → /dev/null, 1 и 2 → /tmp/run/dl_manager.log, 3 → /tmp/run/dl_manager.pid и 4 → anon_inode:inotify; pid в dl_manager.pid совпадает с pidof. ↩

  145. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c047 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 после kill (SIGTERM) dl_manager работающее приложение Dune не подняло его за 60 с (dl_manager.pid остался со старым pid и mtime); после am force-stop и am start com.dunehd.app новый dl_manager запустился (через ~8 с после старта приложения) — root, PPid 1. ↩↩↩

  146. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c048 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 am force-stop com.dunehd.app не останавливает dl_manager: демон pid 1981, запущенный при загрузке плеера 2026-10-27 19:43:14, пережил force-stop приложения в 20:14:56 и работал в 20:40. ↩↩

  147. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c044 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В строках classes.dex APK оболочки r25 есть /firmware/bin/dl_manager и сообщения dl_manager is available, dl_manager not available, dl_manager started, dl_manager stopped. ↩

  148. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c060 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · DlManagerService оболочки r25 по onApkReady, если существует /firmware/bin/dl_manager, отправляет сообщение MSG_START_DL_MANAGER=900; handleMessage обрабатывает только what == 900 и вызывает handleStartDlManager, который при this.process == null вызывает doStartDlManager; тот запускает /firmware/bin/dl_manager через ProcessHelper.runDaemonProcess({"/firmware/bin/dl_manager"}, true, true, null). ↩↩

  149. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c061 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · DlManagerService оболочки r25 при onDestroy вызывает handleStop: если процесс демона не null, делает process.destroy(), обнуляет ссылку и выполняет Runtime.getRuntime().exec(new String[]{"killall", "dl_manager"}); ошибка exec только печатает stack trace. ↩↩

    • fw-tv188b-260827-0003-r24.c018 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Утилиты Dune в /system/dunehd/firmware/bin/ — симлинки на /data/data/com.dunehd.app/lib/libxxx_<имя>.so (например php_server, run_plugin_cgi, ts, root)
    • fw-tv188b-260827-0003-r24.c019 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Сами исполняемые файлы libxxx_*.so лежат в /system/bin/ (37 ELF); крупнейший — libxxx_ts.so (44235376 байт)

    ↩

  150. fw-tv188b-261021-0117-r25.c006 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 в firmware_ext/plugins 15 каталогов встроенных плагинов с dune_plugin.xml: к 13 из r24 добавлены downloads и s928x_dvfel ↩

  151. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c040 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В r24 (260827_0003) файла system/system/bin/libxxx_dl_manager.so нет: в отсортированном tree.tsv за libxxx_curl.so сразу идёт libxxx_do.so. ↩

  152. fw-tv188b-261021-0117-r25.c007 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Новые исполняемые файлы Dune в r25: libxxx_dl_manager.so, libxxx_lcconv.so, libxxx_vsftpd.so в /system/bin; симлинки firmware/bin/dl_manager, firmware/bin/lcconv и firmware_ext/ftpserver/bin/vsftpd ведут в /data/data/com.dunehd.app/lib/ ↩

  153. fw-tv188b-261021-0117-r25--network-services.c049 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · firmware/bin/ts — встроенный TorrServer (MatriX.134), а не ядро медиаплеера. ↩

  154. fw-tv188b-261021-0117-r25--network-services.c051 · code, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · TsHelper::start_ts запускает $FS_PREFIX/flashdata/ts/ts, если файл существует и ts не запускался недавно, с --port , -k, -d $FS_PREFIX/flashdata/, -l $FS_PREFIX/tmp/run/.log и -w $FS_PREFIX/tmp/run/web.log; имя по умолчанию ts, порт по умолчанию 8095. ↩

  155. fw-tv188b-261021-0117-r25--downloads.c046 · code, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Локальный TsHelper запускает /flashdata/ts/ts с --port, -k, -d, -l и -w; имя настроек и логов берёт из TORRSERV_NAME (по умолчанию ts), задаёт GODEBUG=madvdontneed=1. ↩

  156. fw-tv188b-261021-0117-r25--downloads.c045 · code, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · TsHelper::start_ts при успешном открытии /tmp/run/ts_launch.lock блокирует проверку и установку /tmp/run/ts_launch_time.txt; недавний запуск — возраст от 0 до 59 секунд. ↩

  157. fw-tv188b-261021-0117-r25--downloads.c038 · code, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · TorrServer::ensureIp выбирает TORRSERV_IP, затем внешний адрес из TsHelper; пустой адрес или internal заменяет на http://127.0.0.1:8095, при отсутствии начального http добавляет http://. ↩

  158. fw-tv188b-261021-0117-r25.c037 · code, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Плагин downloads содержит клиент TorrServer (ext/TorrServer.php): адрес по умолчанию http://127.0.0.1:8095, загрузка торрента POST на /torrent/upload; debug_dump.sh r25 запрашивает версию TS через curl http://127.0.0.1:8095/echo ↩

  159. doc-sdk-plugins--gui-actions.c089 · doc, disputed · any-documented; прошивка — · LaunchMediaUrl выбирает установщик, деинсталлятор или запускатель плагинов, если плейлист состоит из одного URL plugin_installer://, plugin_uninstaller:// или plugin_launcher://* соответственно ↩

  160. fw-tv188b-261021-0117-r25--downloads.c007 · code, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · play_magnet запускает один поток непосредственно, а для нескольких файлов пишет open_magnet.m3u и запускает file:// плейлист. ↩

  161. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c017 · inference, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, start_ts (номер 4) запускает внутренний TS командой TORRSERV_IP=internal /firmware_ext/php/php-cgi -f /firmware_ext/plugins/downloads/tscli.php start_nowait через safe_system_ext и не ждёт его готовности. ↩

  162. fw-tv188b-261021-0117-r25--network-services.c053 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В strings dl_manager есть команда запуска php-cgi tscli.php с TORRSERV_IP=internal, что связывает демон загрузок со стартом встроенного TorrServer. ↩

  163. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c035 · inference, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, номера статусов 0–7 соответствуют буквам N, L, p, P, O, E, d, D: fcn.0006405c возвращает строки таблицы с шагом 4 байта от 0x93594, где r2 показывает N для номера 0. ↩

  164. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c020 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, при старте main выбирает базовый dl_max_loads_at_once по MemTotal из /proc/meminfo: не больше 1099999 kB — 1, больше 2200000 kB — 3, иначе остаётся начальное значение глобала (2 по шестнадцатеричному дампу). ↩

  165. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c019 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Проверка fcn.00054dd0 вызывает fcn.00055964 (адрес вычисляется тем же приёмом) и передаёт результат в функцию из GOT; fcn.00055964 побайтно собирает данные вызовами fcn.0005591c и кэширует результат. Вероятно, это скрытая проверка разрешения (например, лицензии), которая без него сводит загрузки к одной одновременной. ↩

  166. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c041 · inference, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, демон сам не проверяет /tmp/flm.txt и признак lite: в его strings нет подстрок flm и lite, а единственное ограничение без разрешения в коде — сведение лимита к 1 (c018, c019). ↩

  167. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c010 · inference, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, main регистрирует наблюдение fs_watch_init("dl_ipc", "/tmp/run/dl_input", …, fcn.00063afc) и при первом проходе цикла (dl ipc I: warm-up) один раз сканирует каталог (fcn.00063b74), далее ждёт событий fs_watch_do_work(…, 1000). ↩

  168. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c038 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, dl_manager при старте открывает /tmp/run/dl_manager.pid, берёт на него flock(…, 6), уходит в фон daemon(1,1), пишет лог в dl_manager.log и PID в pid-файл, создаёт /tmp/run/dl_input (0777); при неудаче пишет error_code/error_description и завершается exit(1). ↩

  169. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c043 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, строка downloads в main — имя плагина для флага /tmp/plugins/downloads/update_epfs_if_needed_flag (поле +0x58, c042), а не проверка функции downloads или лицензии: fcn.00033e74 подставляет аргумент в /tmp/plugins/%s/update_epfs_if_needed_flag. ↩

  170. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c036 · code, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · /tmp/run/dl_gstat.txt демон пишет через FS_write_using_tmp_if_changed: по строке на группу в порядке str_nat_cmp по формату "%s %d/%d %.1f %lld %s", первым — строка статуса группы от fcn.0006405c. ↩

  171. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c003 · code, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Файл .in демон читает целиком (FS_read_string_unlimited) и сразу удаляет до разбора JSON; ошибка удаления только пишется в лог (input E: unlink(%s) failed), ошибка чтения — input: E: failed to load file. ↩

  172. fw-tv188b-261021-0117-r25--downloads--manager-runtime--folder-boot.c024 · code, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Для непустой восстановленной очереди bootstrap при успешном clock_gettime записывает отметку +0x60; планировщик не начинает файл до истечения 20 секунд от положительной отметки, затем сбрасывает её. ↩

  173. fw-tv188b-261021-0117-r25--downloads--manager-runtime.c045 · inference, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, dl_manager запускает и останавливает Java-оболочка (APK com.dunehd.app) по пути /firmware/bin/dl_manager, предварительно проверив его наличие. ↩

    • fw-tv188b-261021-0117-r25--downloads.c066 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, dl_manager потребляет файловые команды DlState и публикует читаемые PHP состояния загрузок; точный цикл и гарантии исполнения по strings не установлены.
    • fw-tv188b-261021-0117-r25.c333 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, на tv188b r25 dl_manager публикует состояние загрузок в /tmp/run/dl_state.txt и /tmp/run/dl_gstat.txt, а PHP перечитывает эти файлы.

    ↩

  174. fw-tv188b-261021-0117-r25.c342 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 plugin_launcher://{name=test_plugin9}{action_id=kv}{k1=v1}{k2=a b}{k3=x=y}{k4=%41} запустил действие kv, и пары дошли в user_input буквально: k2 = «a b», k3 = «x=y», k4 = «%41» (без URL-декодирования). ↩

  175. fw-tv188b-260827-0003-r24--http-api--ext-command-params.c095 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 дополнительные пары {ключ=значение} в plugin_launcher://{name=…}{action_id=…}{ключ=значение}, по-видимому, доходят до данных запускаемого действия: open_magnet плагина downloads, который без magnet_url возвращает null, вернул следующее действие entry.ensure_ts. ↩

    • fw-tv188b-261021-0117-r25--php-framework.c024 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, нативный pattern ff(downloads) проверяет firmware_feature downloads: таково прямое значение ff в отдельном PHP-интерпретаторе Expr, а нативный конфиг rows_menu_config.json использует это выражение.
    • fw-tv188b-261021-0117-r25--php-framework.c023 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, cond вычисляет булев pattern и использует его результат как условие видимости entry_point downloads.

    ↩