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

Поставщик каталога «Фильмы»

Черновик. Глава для разработчика плагина-поставщика видеотеки («Фильмы», dunemdb). Каждое фактическое предложение ссылается на claim id из базы. Основа — код tv188b 260827_0003_r24 (дальше — r24, уровень code: «так написано в коде», а не «так работает»). Изменения в tv188b 261021_0117_r25 (r25) и 250815_1012_r22 (r22) отмечены отдельно. Уровень device назван явно: почти все наблюдения на устройстве — r25, тестовые плагины test_plugin5*/test_plugin6* (логи collect4–collect6), и на r24 они не переносятся. Гипотезы (inference) и ослабленные верификатором утверждения (disputed) вынесены в раздел «Не проверено». Чего в базе нет — в разделе «Не известно» со ссылками на задачи.

Источники главы — единицы fw-tv188b-260827-0003-r24--movie-suppliers (регистрация, описатель, команды, встроенные поставщики), …--movie-suppliers--stream-protocol (потоковый протокол), fw-tv188b-261021-0117-r25--movie-suppliers (изменения r25), fw-tv188b-260827-0003-r24--shell-ext--entry-handler (запуск приложений, история), fw-tv188b-261021-0117-r25--shell-ext--entry-handler (история и «Продолжить» в r25), fw-tv188b-261021-0117-r25--app-launch (разбор am start), карта fw-tv188b-261021-0117-r25 (device-факты c069–c330) и соседние. Единица …--movie-suppliers--movie-services (конфигурация сервисов generic) ещё не разобрана.

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

Вопрос Короткий ответ Scope Уровень Claims
Как объявить поставщика? <params><movie_suppliers>id1-id2</movie_suppliers> в манифесте и скрипт bin/movie_suppliers_update.sh в плагине tv188b r24 code; device — наличие у сторонних плагинов (устройство r24, код r24)1
Когда оболочка запускает movie_suppliers_update.sh? Только если строка version_index:id1-id2… отличается от сохранённой в movie_suppliers_params.txt; на r25 скрипт перезапущен после смены version_index и не перезапускался без неё tv188b r24; r25 code; device (r25) (устройство r25, код r24)2
Что будет, если скрипт упал? Код возврата только пишется в лог; повторного запуска нет, пока не сменится version_index или список id. На r25 при коде выхода 3 params записан, описатели скопированы, поставщики зарегистрированы tv188b r24; r25 code; device (r25) (устройство r25, код r24)3
Куда писать описатель? $FS_PREFIX/flashdata/plugins_data/<плагин>/movie_suppliers/<id>; оболочка копирует его в /tmp/movie_suppliers/<id> tv188b r24 code (код r24)4
Что обязательно в описателе? Только bin; без него описатель пропускается. На r25 описателя из пяти ключей (plugin, caption, supported_video_types, bin, playback_type) хватило для регистрации tv188b r24; r25 code; device (r25) (устройство r25, код r24)5
Какой playback_type выбрать? stream — экран выбора файлов; stream_special — сразу воспроизведение, без экрана выбора; app — запуск приложения через start_playback_app tv188b r24 code (код r24)6
Что делает play_action? Непустой play_action отменяет путь по playback_type: оболочка запускает pf_check, а затем действие плагина tv188b r24 code (код r24)7
Что приходит поставщику о фильме? movieInfo: movieExtId, supplierId, title, type, videoType, иногда year и publications tv188b r24 code (код r24)8
Как запустить Android-приложение? start_playback_app отвечает {bin, package, wait_app_start_delay, title}; оболочка ищет приложение по package и запускает launch_ext_app. Строку am start … приложение Dune на r25 разбирает само, без am и sh; ставьте wait_app_start_delay > 0 tv188b r24; r25; APK DMC code; device (r25) (устройство r25, код)9
Что делает оболочка со статусом запуска? Ненулевой — действие из error_action; ноль — ждёт потери фокуса не дольше delay, при delay < 1 ожидание сразу кончается неудачей r25 code; device (устройство r25, код r25)10
Приложения нет — что делать? Ответить error.missing_app; оболочка предложит скачать и установить tv188b r24 code (код r24)11
Что видит пользователь при ошибке start_playback_app? Длинный error.message — одной строкой с многоточием в середине; ключ %tr%… переводится r25 device (устройство r25)12
Под каким uid и где работает bin? uid 1000, текущий каталог /; у movie_suppliers_update.sh — uid 1000 и FS_PREFIX=/data/data/com.dunehd.app r25 device (устройство r25)13
Где смотреть ошибки поставщика? stderr команд — /tmp/run/<id>__supplier.log; файл /tmp/suppliers_debug включает печать входа и выхода tv188b r24; r25 — новый формат строк code; device — наличие логов (r24), запись stderr и Input/Output (r25) (устройство, код)14
Подхватит ли оболочка изменённый описатель? r24 — по флагу /tmp/movie_suppliers_changed.flag; r25 — ещё и по смене mtime каталога /tmp/movie_suppliers r24, r25 code (код)15
Кто удаляет описатель при удалении плагина? Во встроенных плагинах — сам плагин, global_actions/uninstall с rm -f tv188b r24 code (код r24)16
Как поставщик попадает в «Продолжить» (историю)? r24: только через play_recent (sup_id, movie_id, поля wh_* → sup_info). r25: кнопка поставщика, совпавшего с поставщиком последней записи истории с прогрессом, получает sup_info с wh_* tv188b r24; r25 code (код)17
Есть ли механизм на APK и tv175u? Встроенные плагины поставщиков в APK есть; работу регистрации на APK и tv175u никто не разбирал APK r24 code (код r24)18

1. Где поставщик виден

Оболочка (shell_ext, класс Suppliers) читает описатели поставщиков из каталога /tmp/movie_suppliers: id поставщика — имя файла, категория — movies (код r24)19. Поставщик предлагается для фильма, только если поддерживает тип материала (код r24)20. Типы задаёт ключ supported_video_types — список через «|» из video, trailer, add_material, это ass_type 0, 1 и 2 (код r24)21. Поставщик не предлагается, если у фильма для него пустой список публикаций (исключения — YouTube и server_ignored), а server_managed — если публикаций нет (код r24)20.

Что ещё скрывает поставщика:

  • ложное условие expr в описателе (код r24)22;
  • файл /flashdata/plugins_data/<plugin>/movie_suppliers_disabled — его создаёт dunestore, когда пользователь отключает плагин с movie_supplier_disable_capable == 1 (код r24)23;
  • имя файла netflix в /tmp/movie_suppliers — такой файл пропускается всегда (код r24)24.

Манифестный ключ movie_supplier/disable_capable = yes встречается у стороннего плагина globaltv (код)25. В шаблоне записи installed_plugins.xml r24 есть поле movie_supplier_disable_capable (код r24)26.

Порядок в списке: поставщики не-community идут раньше community, затем подходящие по языку (langs) (код r24)27. rutube и YouTube всегда считаются community и получают индексы 1001 и 1002 (код r24)28.

В r25 список поставщиков для воспроизведения строится иначе: get_movie_suppliers возвращает отображение id → bool, где play_filter ограничивает набор, а main_play_filter отмечает главные (код r25)29. Непустой ключ описателя key_show_only_one выдаётся в списке id один раз вместо id поставщика (код r25)30. Поиск по такому групповому ключу возвращает первое совпадение id или ключа (код r25)31.

2. Регистрация

2.1. Объявление в манифесте

Плагин объявляет id своих поставщиков элементом манифеста <params><movie_suppliers>: у dunemdb_supplier_rutube это rutube, у dunemdb_supplier_youtube — YouTube (код r24)32. В libduneshell.so есть шаблон <movie_suppliers>%s</movie_suppliers> рядом с шаблоном записи installed_plugins.xml (код r24)33. На устройстве (tv188b r24, device) элемент movie_suppliers в /tmp/run/installed_plugins.xml есть у сторонних плагинов: melange — aio, dunemdb_supplier_online_movies — online_movies-online_movies_manual, play_in_apps — 11 id через «-» (устройство r24)34. На r25 (device) у тестового плагина test_plugin5_sup в installed_plugins.xml то же значение, что в params/movie_suppliers его манифеста (устройство r25)35, а плагин plain без params/program регистрируется с launch_capable 0 и этим movie_suppliers (устройство r25)36. Каким кодом значение переносится, не доказано (см. «Не проверено»).

shell_ext (async_worker.php) читает из installed_plugins.xml поля name, path, movie_suppliers и version_index каждого плагина (код r24)37.

2.2. Запуск movie_suppliers_update.sh

Для каждого установленного плагина с непустым movie_suppliers оболочка делит строку по «-» на id; подпись каждого поставщика равна его id (код r24)38. Затем do_movie_suppliers_update запускает sh <path плагина>/bin/movie_suppliers_update.sh с парами аргументов <id> <caption> (код r24)39.

Когда это происходит:

  • скрипт запускается, только если строка version_index:id1-id2… отличается от сохранённой в /flashdata/plugins_data/<плагин>/movie_suppliers_params.txt; после запуска строка записывается туда (код r24)39;
  • update_other_plugins (поставщики из movie_suppliers) вызывается только при installed_plugins_dirty, а в конце update_plugins создаёт файл MainHelper::$suppliers_prepared_path (код r24)40.

Если скрипт завершился с ошибкой, код возврата только пишется в лог («E: command failed with status»), а movie_suppliers_params.txt всё равно записывается (код r24)41. Значит, до смены version_index или списка id повторного запуска нет (код r24)41.

На устройстве r25 (device, тестовые плагины test_plugin5_sup и test_plugin6_sup):

  • скрипт запущен с парами «<id> <id>» (подпись равна id) для всех id в порядке params/movie_suppliers (устройство r25)42, под uid 1000 с FS_PREFIX=/data/data/com.dunehd.app (устройство r25)43;
  • movie_suppliers_params.txt содержит 1:kbp5_stream-kbp5_special — version_index, двоеточие и список id (устройство r25)44;
  • при трёх следующих стартах оболочки без смены версии и списка скрипт не вызывался (устройство r25)45; после замены version_index 1→2 прямо в dune_plugin.xml и am force-stop — запущен снова, а params стал 2:… (устройство r25)46;
  • при коде выхода 3 params всё равно записан (устройство r25)47, описатели скопированы в /tmp/movie_suppliers и поставщики зарегистрированы (устройство r25)48. Строк async_worker «params changed», «Updating …» и «E: command failed with status» нет ни в одном /tmp/run/*.log (устройство r25)49 (см. «Расхождения»).

Встроенные скрипты различаются: movie_suppliers_update.sh generic обрабатывает аргументы парами (id, caption), а rutube и youtube аргументы не читают — id и caption у них зашиты в скрипт (код r24)50.

2.3. От описателя на флеше до /tmp/movie_suppliers

Все три встроенных скрипта пишут описатель (JSON) в $FS_PREFIX/flashdata/plugins_data/<имя плагина>/movie_suppliers/<id> (код r24)51. После скрипта do_movie_suppliers_update копирует этот файл в /tmp/movie_suppliers/<id>, если содержимое отличается; пустой или отсутствующий файл — предупреждение и пропуск (код r24)52. Каталог $FS_PREFIX/tmp/movie_suppliers создаёт run_async_worker.sh с правами 777 (код r24)53. На r25 (device) описатели, которые скрипт тестового плагина писал только в plugins_data/<плагин>/movie_suppliers/, после регистрации оказались и в /tmp/movie_suppliers/ с теми же размерами (устройство r25)54.

В снимке r25 (device) у dunemdb_supplier_generic описатели AppleTV, Ivi, Kinopoisk и Premier лежат в plugins_data/…/movie_suppliers, но в /tmp/movie_suppliers их нет (устройство r25)55; у generic и dune-hd.tv нет и movie_suppliers_params.txt (устройство r25)56. Почему, claims не говорят (конфигурация сервисов generic не разобрана, см. «Не известно»).

Оболочка перечитывает поставщиков при наличии /tmp/movie_suppliers_changed.flag; в первый раз ждёт файл suppliers_prepared_path до 30 раз по 0,1 с (код r24)57. В r25 Suppliers::reload_if_changed перечитывает список ещё и при смене mtime каталога /tmp/movie_suppliers (код r25)58. Отслеживается mtime каталога, переданный в reload_suppliers (код r25)59.

2.4. Отключение и удаление

Пользователь может отключить поставщиков плагина в dunestore: при movie_supplier_disable_capable == 1 и не в режиме ТВ dunestore создаёт или удаляет movie_suppliers_disabled и пишет /tmp/movie_suppliers_changed.flag (код r24)60.

Встроенные rutube и youtube при удалении убирают свой описатель сами: в global_actions/uninstall у них /bin/rm -f /tmp/movie_suppliers/rutube и /tmp/movie_suppliers/YouTube (код r24)16.

2.5. Другие пути регистрации

Сервисы movie services регистрирует update_service_plugins: для сервисов из эффективного списка, чей плагин установлен с version_index > 0, он собирает id поставщиков и вызывает тот же do_movie_suppliers_update (код r24)61. Файлы скрытых сервисов в /tmp/movie_suppliers он удаляет и при изменениях пишет флаг /tmp/movie_suppliers_changed.flag (код r24)62.

У dunemdb_supplier_generic есть старый путь: global_actions boot_end, install и update запускают bin/update_movie_suppliers.sh с условием if="not(firmware_feature(movie_suppliers_update))" (код r24)63. Флаг movie_suppliers_update в firmware_features.txt r24 есть (код r24)64. В r22 youtube регистрировался сам: register_supplier.sh писал описатель прямо в $FS_PREFIX/tmp/movie_suppliers/YouTube (код r22)65.

3. Описатель /tmp/movie_suppliers/<id>

Комментарий в suppliers.php называет ключи plugin, caption, bin, supported_video_types (код r24)66. По коду ключей больше. Значения по умолчанию из кода r24 верификатор ослабил: часть из них условна (у logo_* и server_managed), поэтому они вынесены в «Не проверено».

Ключ Смысл Claims
bin обязателен; без него описатель пропускается с предупреждением «invalid info, 'bin' missing» (код r24)67
plugin нет — имя берётся из пути bin по шаблону /(flashdata\|firmware_ext\|persistfs)/plugins/<имя>/bin/, иначе _unknown_ (код r24)68
caption подпись поставщика; у rutube — ключ перевода %tr%title_supplier (код r24)69
supported_video_types список через «|» из video, trailer, add_material (код r24)21
playback_type допустимы stream, stream_special, app (код r24)70
play_action GUI-действие строкой JSON, объектом или массивом (код r24)71
play_action_with_seasons у сериала полные сезоны пишутся в файл, путь — в params.seasons_file (код r24)72
server_managed, server_ignored принудительно true для id из списков Config (код r24)73
location_handling ignore или skip_unmatched_publications (код r24)70
special_category, special_category_icon_url значок категории, по умолчанию plugin_file://icons/genre_all.png (код r24)74
sticker_icon_url, logo_icon_url значение без схемы xxx:// дополняется до plugin_file://%<plugin>%/<значение> (код r24)74
logo_width, logo_height размеры логотипа; умолчание условно — см. «Не проверено» —
langs нет или any — любой язык, иначе ищется слово языка интерфейса (код r24)27
expr условие; ложь — поставщик отключается (код r24)22
fixed_trailer_files готовые элементы трейлеров (есть в описателе rutube r24; читается оболочкой r25) (код)75
dl_capable (r25) первый поставщик с ним становится dl-поставщиком при флаге downloads (код r25)76

Образцы встроенных описателей:

  • generic: plugin dunemdb_supplier_generic, supported_video_types video, server_managed true, location_handling skip_unmatched_publications, playback_type app, special_category true (код r24)77; в r25 те же значения (код r25)78;
  • rutube: caption %tr%title_supplier, langs russian, supported_video_types video|trailer, playback_type app, fixed_trailer_files, expr country(ru) (код r24)69;
  • YouTube: supported_video_types video|trailer|add_material, playback_type app, icon_url и play_icon_url в виде plugin_file://%<плагин>%/… (код r24)79.

Команда в bin встроенных generic и rutube — cd <каталог bin> && $FS_PREFIX/firmware_ext/php/php-cgi -f ./run.php, у youtube добавлен -c <каталог bin> (свой php.ini) (код r24)80.

4. Протокол команд

Оболочка вызывает поставщика командой <bin> <команда> через proc_open: вход — JSON в stdin, результат — JSON из stdout, stderr дописывается в /tmp/run/<id>__supplier.log (код r24)81. Ненулевой код выхода или не-JSON на stdout — результат команды null, то есть ошибка (код r24)82. Лог поставщика проверяется не чаще раза в 60 с и при размере ≥ 100000 байт переименовывается в .old (код r24)83. На устройстве (tv188b r24, device) логи YouTube__supplier.log и rutube__supplier.log в /tmp/run есть (устройство r24)84.

На r25 (device) то же видно по тестовому плагину: команда запускается строкой «<bin> <команда>» (устройство r25)85; JSON входа приходит в stdin (устройство r25)86; команды стороннего поставщика (bin без cd) выполняются под uid 1000 с текущим каталогом / (устройство r25)87; stderr дописывается в /tmp/run/<id>__supplier.log, по строке на вызов (устройство r25)88.

Команды, которые оболочка передаёт bin: get_episodes, do_file_search, get_file_search_state, stop_file_search, get_stream_url, start_playback_app (код r24)89.

Команда Вход Claims
get_episodes {movieInfo} (код r24)90
do_file_search movieInfo и, если заданы, season, episode, fileId, private, premiered (код r24)91
get_file_search_state, stop_file_search пустой объект (код r24)91
get_stream_url {fileId} (код r24)90
start_playback_app {movieInfo, assType, season, episode, fileId} (код r24)90

Что пришло на вход на r25 (device):

Команда Наблюдалось Claims
get_episodes только movieInfo (videoType video), без season, episode, private (устройство r25)92
do_file_search серии movieInfo, season, episode и private из ответа get_episodes; premiered — только если задан у серии (устройство r25)93
get_stream_url только {"fileId": …} (устройство r25)94
start_playback_app (фильм single) {movieInfo, assType:0, season:-1, episode:-1, fileId:null} (устройство r25)95

Константы статусов поиска: active, suspended, done, stopped (код r24)96. Как оболочка ждёт окончания поиска, зависит от экрана: на экране онлайн-файлов, пока status == active, она показывает уже полученные файлы и опрашивает get_file_search_state по таймеру 500 мс (код r24)97. Описание цикла «0,5 с до 60 с» верификатор ослабил — см. «Не проверено». На r25 (device) поставщик, всегда отвечавший status done, получил do_file_search и в ту же секунду stop_file_search, а get_file_search_state не вызывался (устройство r25)98.

Отладка: файл /tmp/suppliers_debug включает печать входа и выхода команд в лог оболочки (код r24)99. Вход и выход get_stream_url пишутся в лог всегда (код r24)100. В r25 флаг сохранён, строки получили префиксы Input/Output (<len> bytes), а без флага печатается только длина (код r25)101. В r25 поиск больше не печатает вход принудительно (код r25)102, а start_playback_app принудительно печатает только выход (код r25)103. В r25 оболочка обрезает завершающие пробельные символы stdout (rtrim) до json_decode (код r25)104. На r25 (device) при существующем /tmp/suppliers_debug в /tmp/run/shell_ext.log печатаются полные «Input ( bytes): » и «Output ( bytes): » — и для тестового плагина, и для YouTube (устройство r25)105.

5. playback_type и выбор пути воспроизведения

Пути онлайн-воспроизведения по коду r24:

  1. Непустой play_action — воспроизведение идёт не по playback_type: оболочка запускает встроенное действие pf_check с plugin_name плагина поставщика, а play_action передаёт ему следующим действием (код r24)71.
  2. YouTube оболочка воспроизводит сама, мимо команд поставщика: через plugin_launcher://{name=android_apps}…{action_id=launch_youtube}… (код r24)106.
  3. playback_type = app — команда start_playback_app; ответ разобран в §8 (код r24)107.
  4. playback_type = stream_special — экран выбора файлов не открывается, воспроизведение запускается сразу (код r24)108.
  5. playback_type = stream (по умолчанию) — экран онлайн-файлов: оболочка ещё до выбора пользователя получает URL каждого файла и проверяет его программой media_check (код r24)109.

Кэш ответа get_episodes — §7.1. Полный перечень условий, при которых get_episodes не вызывается, верификатор уточнил — он в «Не проверено». На r25 (device) для фильма single и поставщика app оболочка вызывала только start_playback_app, по одному вызову на выбор; get_episodes, do_file_search и другие команды не вызывались (устройство r25)110.

6. Что приходит поставщику: movieInfo

movieInfo строит MdbMovie::get_movie_info: ключи movieExtId, supplierId, title, type, videoType есть всегда; year — только если больше 0; publications — только если для поставщика есть список публикаций (код r24)111.

Поле Содержимое Claims
movieExtId dunemdb:<id> и через запятую непустые kinopoisk:, imdb:, tmdb:, tmdbtv: (код r24)112
title объект «код языка → название»: под языком системы — название, под en — оригинальное или то же (код r24)113
type series или single (код r24)114
videoType video, trailer или bonus (тип add_material здесь называется bonus) (код r24)114
publications публикации сервера dunemdb для этого поставщика (код r24)115

Публикации берутся из ответа сервера dunemdb: поле suppliers — объект «id поставщика → {publications: [...]}»; публикация принимается, только если у неё есть id или deeplink и есть caption (код r24)116. Отбор по языку: сначала публикации без lang или на языке системы, затем на других языках; к caption каждой дописывается « []» (код r24)117. Оболочка добавляет каждой публикации sup_id, а при отсутствии type ставит video (код r24)118. При location_handling = skip_unmatched_publications и известной стране отбрасываются публикации с непустым countries без этой страны (код r24)119.

На r25 (device) movieInfo во входе do_file_search новых сторонних поставщиков-тестовых плагинов содержал только movieExtId, supplierId, title, year, type, videoType — без publications (устройство r25)120, а встроенный YouTube для того же фильма получил publications с id, caption, lang, size, type, sup_id (устройство r25)121. Это согласуется с гипотезой о публикациях стороннего поставщика (см. «Не проверено»).

7. Потоковый поставщик: stream и stream_special

7.1. get_episodes (сериал)

Ответ кэшируется по паре (фильм, поставщик): для того же фильма и поставщика get_episodes повторно не вызывается (код r24)122. Если ответ null, в нём есть error или нет seasons, список эпизодов пуст; необязательное private приводится к строке и потом уходит в do_file_search (код r24)123.

  • seasons[].number обязателен, число от −1 до 99; seasons[].episodes обязателен; title сезона необязателен (код r24)124.
  • episodes[].number обязателен, число от 0 до 999; title и premiered необязательны, premiered уходит в do_file_search (код r24)125.
  • Сезон −1 и прочие вне 0…99 означают «нет сезона» (код r24)126; если сезонов нет, а эпизоды без сезона есть, открывается экран эпизодов (код r24)127.

7.2. do_file_search и get_file_search_state

Элемент files[] принимается, только если id задан и не состоит из одних пробелов и задан caption; при наличии order хотя бы у одного файла список сортируется по intval(order) (код r24)128. Список видеофайлов эпизода считается полным только при status == done (код r24)129. Необязательный files[].url становится готовым stream_url файла (код r24)130. Поле files[].quality встроенные поставщики r24 пишут (youtube и rutube — «HD»), но оболочка r24 его не читает: get_video_files и get_non_video_files строят объекты файлов из явного набора полей без quality, так что на выбор и подпись файла оно не влияет (код r24)131.

Прочие ответы: при error оболочка запоминает объект (message и необязательный action), файлов нет; при redirect — запись в лог «Supplier redirected to external app», файлов нет (код r24)132.

На экране онлайн-файлов поиск асинхронный: пока status == active, оболочка показывает уже полученные файлы и опрашивает get_file_search_state по таймеру 500 мс (код r24)97. В r25 таймер 500 мс сохранён (код r25)133.

7.3. Экран онлайн-файлов (stream)

  • URL каждого файла — url из ответа или вызов get_stream_url; затем очередь проверки <install_dir>/bin/media_check (код r24)109.
  • Показываются только файлы с готовым результатом media_check; файл не длиннее 1/10 фильма отбрасывается (код r24)134.
  • Сортировка: без ошибки media_check, затем по overall_rating, затем по order поставщика (код r24)135.
  • Подпись, оканчивающаяся выражением в скобках, обрезается до текста в последних скобках (код r24)136.
  • get_stream_url_by_file_id бросает исключение при любой ошибке, а update_good_files вызывает его без try/catch (код r24)137. Поэтому в r24 ошибка get_stream_url хотя бы для одного файла без url прерывает построение всего списка онлайн-файлов, а не только убирает этот файл: исключение перехватывает default_dune_plugin_fw::invoke_operation и возвращает is_error с error_action (код r24)138.

На r25 (device, поставщик-тестовый плагин kbp5_stream):

  • сразу после ответа do_file_search серии, без выбора пользователя, оболочка по очереди вызвала get_stream_url для файлов без url (устройство r25)139;
  • url вида http://… из ответа get_stream_url принят без изменений (устройство r25)140;
  • ответ {"error":{"message":M}} для одного файла дал в shell_ext.log «Supplier failed to provide stream, reason: M» и «DuneException caught: Error getting stream url» (устройство r25)141;
  • media_check пишет журнал в /tmp/run/<id>__media_check.log (устройство r25)142, но вызывает /firmware/scripts/ffmpeg.sh, которого на устройстве нет: «No such file or directory», «ffmpeg finished with status 1» (устройство r25)143.

7.4. stream_special

Без файлов: если в error ответа есть action с handler_string_id, оболочка выполняет это GUI-действие; иначе показывает error.message, а без него — title_content_is_unavailable (код r24)144. Выбор файла идёт по count($file->path) с комментарием «FIXME: temporarily workaround for dune-hd.tv records» и без cur_stream_url (код r24)145.

На r25 (device, тестовый плагин kbp5_special) из двух файлов с order 1 и 2 оболочка через 0,3 с без выбора пользователя запросила get_stream_url для первого по order (устройство r25)146. url файла из do_file_search она не использовала: URL взят из get_stream_url (устройство r25)147. Для r24 оба вывода остаются гипотезами (см. «Не проверено»).

7.5. get_stream_url и playback_url

Ответ get_stream_url: null, объект error или отсутствие url — исключение; пользователь во всех случаях видит errmsg_failed_to_start_playback (код r24)148. url должен соответствовать |^([a-z\-_]*:/)?/| (код r24)149.

Внутренний playback_url поставщика — JSON с ключами movie_id, s, e, ass_type, sup_id, is_current, file_id, stream_url (код r24)150; MainVod дописывает к нему :movies (код r24)151. Серии добавляются с playback_url_is_stream_url = false, buffering_ms = 3000 и keep_playing_on_reenter = true (код r24)152. По SDK при false get_vod_stream_url() вызывается каждый раз, когда нужен stream URL (SDK)153.

Случай Что делает оболочка Claims
is_current != 0, stream_url не пуст возвращает stream_url, поставщика не зовёт (код r24)154
is_current != 0, stream_url пуст get_stream_url {fileId} (код r24)155
is_current == 0 (следующая серия) do_file_search для s/e с fileId прежнего файла, берёт первый файл: его url или get_stream_url (код r24)156

Для фильма и трейлера VOD-описание содержит одну серию с id «-1» (код r24)157; для сериала — все эпизоды выбранного сезона из get_episodes (код r24)158.

7.6. Трейлеры и доп. материалы

Трейлеры (ass_type 1) и доп. материалы (2) собираются со всех поставщиков фильма: каждому — do_file_search только с movieInfo (код r24)159. Ответ со status, отличным от done, целиком игнорируется («lazy loading not supported yet») (код r24)160. Экрану уходят caption, необязательный icon, file_id, sup_id; url поставщика сюда не переносится (код r24)161. В r25 для трейлеров при ключе fixed_trailer_files оболочка берёт этот массив вместо поиска (код r25)162, а элементы без id или caption отбрасывает (код r25)163.

На r25 (device):

  • в одном цикле запросов по фильму поставщики-тестовые плагины с video|trailer получили do_file_search с videoType trailer, а YouTube (video|trailer|add_material) — с trailer и bonus (устройство r25)164;
  • трейлер, который тестовые плагины вернули сразу со status done, попал в список трейлеров фильма (устройство r25)165;
  • при запуске такого трейлера оболочка вызвала get_stream_url {"fileId":"t1"} и взяла его результат, хотя url в ответе do_file_search был — и у stream, и у stream_special (устройство r25)166.

8. play_action против bin

play_action — ключ описателя с GUI-действием плагина; при нём playback_type не используется (код r24)71. В params действия оболочка кладёт supplier_id, season, episode, callback_action, series_type, publications, supplier_info (если есть), lang, region, movie_str (код r24)167. callback_action — закодированное действие shell_ext play_online с ignore_play_action, то есть путь, по которому можно вернуть управление обычному воспроизведению (код r24)167. movie_str — JSON полей фильма; сезоны в нём заменены на season_numbers, а при play_action_with_seasons полные сезоны пишутся в <tmp_dir>/sup_seasons.json (код r24)72.

Перед play_action выполняется встроенное pf_check (код r24)71. В MainEntryHandler при user_input->pf_error возвращается фатальная ошибка, а pf_checked на Android считается истинным (код r24)168. Что именно проверяет pf_check для поставщика, в базе нет.

Итого: при play_action воспроизведение ведёт GUI-действие плагина (код r24)71, без него — команды bin (код r24)89.

9. Поставщик-приложение: start_playback_app

Успешный ответ: bin (команда запуска), package, wait_app_start_delay, title; приложение ищется по package, не найдено — ошибка; запуск через ActionFactory::launch_ext_app (код r24)169. Данные действия launch_ext_app в r24: cmd, ensure_playback_stopped, delay, package, version, msg_toast, params, error_action (код r24)170. Если в ответе есть first_start_dialog.title, оболочка один раз (cookie <sup_id>_first_dialog_shown) показывает диалог перед запуском (код r24)171.

Нет приложения: ответ с error.missing_app (title, package, непустой urls; необязательно indirect, intro_dialog_urls) превращается в действие «скачать и установить»; иначе показывается error.message (код r24)172. Ветка confirm_install_app выбирает install_from_market при is_limited_apk(), иначе download_and_install_apk (код r24)173. При повторном вызове launch_playback_app (repeat) с action_status=1 оболочка до 10 раз с паузой 0,5 с проверяет, что пакет установлен (код r24)174.

Что известно о r25

По коду r25 (code): shell_ext ищет приложение по package (затем по старому имени пакета); не нашёл — показывает errmsg_failed_to_start_playback и ничего не запускает (код r25)175. Перед запуском bin проходит через finalize_launch_cmd, а действие launch_ext_app получает ensure_playback_stopped=true, delay=wait_app_start_delay (по умолчанию −1), package и error_action с показом errmsg_failed_to_start_playback (код r25)176. finalize_launch_cmd меняет команду только на системах с двумя ОС (dual_system, src=atv) (код r25)177. Обёртка ActionFactory::launch_ext_app в shell_ext r25 передаёт шесть ключей, без version и params (код r25)178.

На устройстве r25 (device, тестовый плагин test_plugin6_sup):

Ответ start_playback_app Что произошло Claims
bin «am start -n <pkg>/<activity>», с --activity-clear-task или «am start 'intent:#Intent;component=<pkg>/<activity>;end'» activity запущена, «activity launch status: 0» (устройство r25)179
bin «am start 'intent:…;end'» строка передана apk_helper одним аргументом без кавычек, ActivityManager запустил activity с act=VIEW (устройство r25)180
bin «am start -p '<pkg>' -a MAIN -c LEANBACK_LAUNCHER» приложение не открылось, «activity launch status: -1» (устройство r25)181
статус запуска −1 выполнен error_action: «Не удалось запустить воспроизведение» (устройство r25)182
package несуществующего приложения «sup E: app not found for package», показано «Не удалось запустить воспроизведение», launch_ext_app не выполнялось (устройство r25)183
без wait_app_start_delay / 10 / 5 delay -1 / 10 / 5; всегда ensure_playback_stopped 1 (устройство r25)184
error.message длиной 409 символов показан одной строкой, сокращённой посередине многоточием, без заголовка (устройство r25)185
error.message = %tr%errmsg_failed_to_start_playback на экране переведено: «Не удалось запустить воспроизведение» (устройство r25)186

Строку am start … приложение Dune разбирает само, без запуска am или sh: apk_helper делит её на аргументы и снимает одинарные кавычки, activity стартует в процессе com.dunehd.app (устройство r25)187. В таблице строк dune.apk (tv188b r24, r25 и APK DMC) есть имена опций am start из AOSP (код r24, r25)188, а строки --user нет (код r24, r25)189. dune.apk tv188b работает с sharedUserId="android.uid.system" (код r24, r25)190, а в APK DMC этого атрибута нет (код r24)191. Что из этого следует для неэкспортированной activity, — гипотеза (см. «Не проверено»).

Как launch_ext_app исполняет bin (код r25, r24 и APK DMC)

Нативный код — листинги libduneshell.so tv188b r24, r25 и APK DMC 260724_0207_r24; Java — dune.apk r25 и APK DMC (байткод совпадает). Для tv188b r24 в базе есть листинг: шаги 1, 2, 5 и 6 ниже отмечены ссылками на его claims. Поведение на устройстве r24 не проверялось.

  1. Выбор пути. tv188b r25: если cmd начинается с /system/dunehd/dunehd_service (сравнение с первого символа, ведущие пробелы не пропускаются), она уходит в popen, любая другая — в разборщик apk_helper (код r25)192. В APK DMC ветки popen нет, любая cmd идёт в apk_helper (код r24)193. В tv188b r24 (code) cmd с /system/dunehd/dunehd_service с начала строки уходит в popen-помощник, иначе — в apk_helper; ведущие пробелы при этом сравнении не пропускаются (код r24)194. Пустая или пробельная cmd ничего не запускает и сразу переходит к ожиданию фокуса (r25 (код r25)195, DMC (код r24)196, r24 (код r24)197).
  2. apk_helper. Требует префикс am start (иначе −1), делит остаток по пробелам, снимает кавычки '…' и "…", выбрасывает аргументы, начинающиеся с > или 2> (r25 (код r25)198, DMC (код r24)199). Ведущие пробелы cmd перед проверкой префикса apk_helper r25 пропускает (код r25)200. Затем через JNI зовёт Java startActivityFromArgs; false даёт статус −1, true — 0 (r25 (код r25)201, DMC (код r24)202). Функции r25 совпадают с DMC по инструкциям, кроме ветки dunehd_service (код r25)203. В tv188b r24 (code) apk_helper пропускает ведущие пробельные байты, требует am start, снимает кавычки '…'/"…", отбрасывает >/2>, а при пустом списке аргументов возвращает −1 с ошибкой (код r24)204; JNI-помощник зовёт startActivityFromArgs (код r24)205.
  3. IntentBuilder. Понимает опции -a, -d, -t, -c, -p, -e/--es, --ei, --ez, -n, -f, --activity-* и другие; любая иная опция, в том числе --user, — «Unknown option», intent не строится, статус −1 (устройство r25, код r25)206. Опции читаются, пока аргумент начинается с «-»; первый аргумент без «-» — позиционный, а всё после него молча игнорируется (код r24, r25)207. Позиционный с «:» идёт в Intent.parseUri, с «/» — компонент с MAIN/LAUNCHER, иначе — пакет; без позиционного и без -a, -d, -t, -c, -p, -n — «No intent supplied» (код r24, r25)208. -a снимает категории позиционного intent, extras опций кладутся поверх (код r24, r25)209. --activity-* добавляют флаги, а -f <число> заменяет все флаги, набранные до него (код r24, r25)210.
  4. Запуск. startActivityFromArgs вызывает mainActivity.startActivity(intent); исключение даёт «Failed to start activity» и false (код r24, r25)211. На r25 (device) такой запуск идёт из процесса com.dunehd.app, «START … from uid 1000» (устройство r25)212.
  5. Статус. tv188b r25: ненулевой статус → следующим действием становится действие из поля +0x1c данных действия со свойством command_status; ноль → ожидание потери фокуса оболочкой не дольше delay, и при результате 0 — снова действие из +0x1c (код r25)213. Ожидание: если фокус уже потерян — успех; если delay < 1 — сразу «timed-out» и 0; иначе опрос каждые 100 мс до delay секунд (код r25)214. В tv188b r24 (code) ненулевой статус даёт действие из +0x1c со свойством command_status (код r24)215, а ноль или пустая/пробельная cmd — ожидание фокуса с delay, после которого при результате 0 выполняется действие из +0x1c (код r24)216. В APK DMC — так же (код r24)217. Что +0x1c — это error_action, по коду — гипотеза (см. «Не проверено»); на r25 при статусе −1 выполнен именно error_action (устройство r25)182.
  6. Ветка dunehd_service (r25 и r24). popen, вывод читается целиком; для команды с am start статус — 999, если последняя непустая строка вывода начинается с Error, иначе 0: код возврата am не учитывается; для прочих команд — статус pclose, сбой popen — 998 (код r25)218. Только статус −1 отправляет ту же cmd в apk_helper (код r25)219. В tv188b r24 (code) popen-помощник накапливает вывод до EOF или ошибки select, записывает статус pclose, а при сбое popen — 998 (код r24)220; при успешном popen для am start он возвращает 999, если последний непустой сегмент длиннее 4 байт и начинается с Error, иначе 0, для прочих команд — статус pclose (код r24)221; исходная cmd повторно уходит в apk_helper только при статусе −1 (код r24)222.

На r25 (device) с am start настроек Android: при проверке на устройстве delay 0 — «activity launch status: 0», через 5 мс «timed-out», и поверх открывшихся настроек выполнился error_action (устройство r25)223; delay −1 и 10 — «shell app is already lost focus», error_action не выполнялся (устройство r25)224. В серии проверки на устройстве из четырёх запусков с delay 0 «timed-out» и error_action были один раз (устройство r25)225, а все четыре с −1 — «already lost focus» (устройство r25)226. Напомним: без wait_app_start_delay shell_ext передаёт delay −1 (код r25)176, а generic отдаёт 10 (код r24)227.

Проверка на устройстве (r25, device) уточнил это и проверил ветку dunehd_service:

  • Серия из восьми launch_ext_app, по четыре с delay 0 и −1: «activity launch status» 0 во всех восьми, «timed-out» — только в одном запуске (пятом, delay 0), в остальных семи — «already lost focus» (устройство r25)228: «timed-out» при delay 0 бывает не в каждом запуске.
  • cmd «/system/dunehd/dunehd_service do am start -n com.kb9.none/.Nope» (несуществующий компонент) пошла в ветку «run command»: pclose вернул 0, command status — 0, а ActivityTaskManager записал START несуществующего компонента — несуществующий компонент статус ветки не изменил (устройство r25)229.
  • cmd «/system/dunehd/dunehd_service do am start --user 0 -n com.android.tv.settings/com.android.tv.settings.MainSettings» открыла настройки: command status 0, «START … from uid 0», Displayed +105ms (устройство r25)230.
  • Та же am start --user 0 -n … без префикса dunehd_service ушла в apk_helper: «Unknown option: --user», activity launch status −1 и выполнился error_action (устройство r25)231.

Список приложений (app_data.json) строит ApplicationDataUpdater: activity пакета — leanback-, иначе обычная launcher-activity; пакет без неё в список не попадает (код r24, r25)232. На r25 файл перезаписывается только при смене MD5 или иконки, после записи ставится флаг update_epfs_if_needed_flag (код r24, r25)233.

Список приложений shell_ext r25 берёт из /tmp/applications/app_data.json, а на системах с двумя ОС — ещё из /flashdata/applications/atv_app_data.json (код r25)234. icon_url приложения — file://<icon> при абсолютном пути, для src=atv — файл в atv_icon_cache, без иконки — missing://; файл icons/<пакет>.png в каталоге плагина заменяет её на plugin_file://icons/<пакет>.png (код r25)235.

Образец: generic

run.php generic понимает только start_playback_app; на иную команду отвечает {error:{message:"Internal error 02 (<cmd>)"}}, всегда с кодом выхода 0 (код r24)236. Он берёт sup_id и deeplink первой публикации (код r24)237 и определяет пакет из package=… или component=пакет/… в deeplink, иначе по sup_id или домену (код r24)238.

  • Команда запуска (r25, код как в r24): для deeplink intent:…#Intent — am start '<deeplink>'; иначе am start, затем -p '<пакет>', если пакет известен, и -d '<deeplink>' (если FS_PREFIX пуст и ссылка http…) либо позиционный '<deeplink>' (код r25)239.
  • Установленность пакета проверяется по $FS_PREFIX/tmp/applications/app_data.json, а при флаге dual_system — сначала по atv_app_data.json (код r24)240.
  • Успешный ответ — {bin, package, wait_app_start_delay 10, title, indirect true, urls}; нет пакета — missing_app со ссылкой http://online.dune-hd.com/apk/generic/<sup_id>.txt (код r24)227.

rutube запускает am start -d 'rutube://rutube.ru/search?query=<запрос>' с пакетом ru.rutube.app (код r24)241. start_playback_app у youtube всегда возвращает ошибку «Illegal state Y03» (статус verified) (код r24)242.

10. Ошибки: что видит пользователь

Ситуация Что делает оболочка Claims
Описатель без bin или не-JSON пропускает с предупреждением в лог (код r24)67
Код выхода ≠ 0 или не-JSON на stdout результат команды null (код r24)82
start_playback_app: error.missing_app предлагает скачать и установить приложение (код r24)172
start_playback_app: другой error показывает error.message (код r24)172
start_playback_app: пакет не найден ошибка; на r25 (device) — «Не удалось запустить воспроизведение», launch_ext_app не выполняется (устройство r25, код r24)243
start_playback_app: статус запуска −1 (r25, device) error_action: «Не удалось запустить воспроизведение» (устройство r25)182
Длинный error.message (r25, device) одна строка с многоточием посередине (устройство r25)185
get_stream_url с error.message (r25, device) «Supplier failed to provide stream, reason: M» в shell_ext.log (устройство r25)141
Пустой онлайн-список файлов title_content_is_unavailable (stream_special) или title_files_not_found (код r24)244
stream_special, нет файлов, есть error error.action или error.message (код r24)144
get_stream_url: любая ошибка errmsg_failed_to_start_playback (код r24)148
get_stream_url: URL не по шаблону исключение «The 'url' is invalid…» (код r24)149
Трейлеры: status не done ответ поставщика игнорируется (код r24)160

Как показываются ключи %tr% в error.message: на r25 (device) ключ переведён (устройство r25)186; для r24 не проверялось.

11. История и «Продолжить»

Что известно по r24:

  • play_recent требует sup_id и movie_id, передаёт все входные поля wh_* в JSON sup_info для play_online; autoplay добавляет enter после открытия карточки (код r24)245.
  • play_recent явно читает wh_file_index (по умолчанию −1), wh_tags, wh_uid, wh_s, wh_e, wh_pos, wh_len (код r24)246.
  • find_recent принимает JSON uids/tags/eps и пишет в result_file найденное (код r24)247.
  • В VOD-API r24 у серии есть поле recent_uid (код r24)248, у PluginVodInfo — recent_plugin, recent_action_params, recent_group_by, recent_tags (код r24)249.
  • play_action получает supplier_info, если он есть (код r24)167.

В r25 плагин downloads строит вызов shell_ext entry/play_recent с wh_uid вида sup_id:movie_id:md5(file_path):uid (код r25)250. В public_actions shell_ext r25 появился update_on_recent_change (код r25)251.

11.1. r25: как история связывается с поставщиком (код)

Всё ниже — код shell_ext r25 (code), на устройстве не проверялось.

Чтение истории. Записи — JSON-массивы в файлах /config/watch_history/<N>.json; у записи без uid он равен url (код r25)252. Запись с action_plugin и action_params принимается всегда, без них нужна url (код r25)253. В памяти — не больше 2000 записей, лишние старые удаляются (код r25)254.

Чья запись. uid-URL (схема xxx://) относится к [local]; иначе поставщик — часть uid до первого : (код r25)255. Для карточки фильма берутся только записи с его movie_id и поставщиком [local] или из текущего списка, самая новая на ключ all и <s>x<e> (код r25)256. Прогресс — это len>0 и pos>=0 (код r25)257.

Кнопка поставщика. В диалоге выбора воспроизведения каждая кнопка play_online получает s, e, sup_id, и только кнопка поставщика последней записи истории — ещё sup_info (код r25)258. Без прогресса sup_info и «Продолжить» не получает ни одна кнопка (код r25)259. sup_info — JSON с sup_data и полями wh_uid, wh_s, wh_e, wh_pos, wh_len, wh_tags, wh_file_index и прочими из action_params записи (код r25)260. Обработчик play_online передаёт его дальше (код r25)261, и поставщик с play_action получает его в params.supplier_info (код r25)262. В r24 кнопки поставщиков sup_info не получали: wh_* шли только через play_recent (код r24)263.

Подписи. Кнопка «Продолжить» поставщика последней записи — button_continue__1 от common_caption поставщика (по умолчанию caption) (код r25)264. Суффикс с процентом пишется только у поставщика записи и только для недосмотренной записи (код r25)265. «Просмотрено» по воспроизведению — при пороге auto_watched_time_left до конца и auto_watched_percent (код r25)266; умолчания — 90% и 30s (код r25)267.

play_recent в r25 открывает карточку фильма в режиме продолжения и передаёт sup_info в play_online (код r25)268; поля wh_* уходят в sup_info все, без разбора по одному (код r25)269. Поставщик, которого больше нет в списке, даёт сообщение и вход в mdb-карточку вместо ошибки (код r25)270.

Запуск из «Недавнего». Для записи с action_plugin и action_params RecentHelper::run_witem r25 возвращает get_continue_by_wh_params_action с play_default_directly 0 (код r25)271; что именно та отправляет плагину по коду, — disputed, см. «Не проверено». На r25 (device) выбор записи «KB9 … #2» в «Последнем» сразу вызвал handle_user_input(recent) плагина с wh_uid kbp9:e1:2, wh_s/wh_e −1, wh_pos 7, wh_len 8, wh_file_index 1, autoplay 0, play_default_directly 0 и таймаутом 20 с (устройство r25)272.

Запись истории plugin VOD (r25, device). Запись получает uid из recent_uid серии, action_plugin — из recent_plugin, action_params — из recent_action_params (устройство r25)273. При проверке на устройстве по концу каждой из двух серий оболочка добавила такую запись — с index 0 и 1, без ключей url и video_id (устройство r25)274. Полный перечень полей по более раннему прогону (с video_id) — в «Расхождениях» guide/playback.md §6. История на r25 лежит в $FS_PREFIX/config/watch_history: файлы с шестизначными номерами, в каждом JSON-массив до 40 записей, новые дописываются в последний файл (устройство r25)275.

Что нужно записи, чтобы кнопка поставщика получила «Продолжить», и где хранится «Просмотрено» для не-URL uid — гипотезы, см. «Не проверено».

12. Отличия прошивок и классов устройств

Что r22 (tv188b 250815) r24 (tv188b 260827) r25 (tv188b 261021) tv175u r24 APK r24
Встроенные поставщики youtube (код r22)65 generic, rutube, youtube (код r24)276 generic (код r25)78 — generic, rutube, youtube (код r24)18
Регистрация youtube сам пишет в /tmp/movie_suppliers (код r22)65 shell_ext → movie_suppliers_update.sh (код r24)39 device: тот же скрипт, перезапуск при смене version_index (устройство r25)277 — —
Флаги API поставщиков — dunemdb_supplier_plugin_api_v2…v7, sup_api_v8 (код r24)278; v7, sup_api_v8, movie_suppliers_order добавлены после r22 (код r24)279 device: в /tmp/firmware_features.txt те же флаги и downloads (устройство r25)280 — —
Перечитывание описателей — флаг-файл (код r24)57 флаг или mtime каталога (код r25)58 — —
Контракт потоковых команд тот же, что r24 (код r22)281 (код r24)282 rtrim stdout (код r25)104; device: входы команд — §4 (устройство r25)283 — —
icon у трейлеров нет (код r22)284 есть (код r24)161 — — —
YouTube потоковый поставщик с get_stream_url (код r22)285 через приложение, launch_youtube (код r24)106 device: описатель с playback_type app (устройство r25)286 — —
rutube и expr — expr подменяется на country(ru) без rutube_integration (код r24)22 с rutube_integration включён, иначе решает expr (код r25)287; device: описатель с expr country(ru) (устройство r25)288 — —
fixed_trailer_files — ключ в описателе rutube (код r24)69 оболочка впервые читает ключ и берёт массив вместо поиска (код r25)162 — —
dl_capable — — новый ключ (код r25)289 — —
generic: HBO/Max — — com.wbd.hbomax / com.wbd.stream по стране (код r25)290 — —
Кнопка поставщика и история — wh_* только через play_recent (код r24)263 sup_info у кнопки поставщика последней записи (код r25)258 — —
Разбор am start — dune.apk с sharedUserId=android.uid.system (код r24, r25)190 apk_helper, а cmd с /system/dunehd/dunehd_service — popen (код r25)192; device: разбирает само приложение, без am и sh (устройство r25)187 — APK DMC: sharedUserId нет (код r24)191; только apk_helper, ветки popen нет (код r24)193

«—» значит, что в базе нет утверждения, а не что возможности нет. tv175u и APK по механизму поставщиков не разбирались; известно только, что dune_plugin.xml плагина dunemdb_supplier_generic в APK совпадает с tv175u той же сборки (код r24)291.

Ветки по классам устройств в коде r24 tv188b (это код одной прошивки, а не проверка на других классах):

  • confirm_install_app: install_from_market при is_limited_apk() (код r24)173;
  • generic: -d у am start только при пустом FS_PREFIX (код r25, тот же, что r24) (код r25)239, проверка atv_app_data.json при dual_system (код r24)240, замена com.netflix.ninja на com.netflix.mediaclient по HD_FW_APK/HD_APK (код r24)292;
  • имя плагина из пути bin распознаётся для каталогов flashdata, firmware_ext и persistfs (код r24)68.

В tv175u r24 dunelib/utils.php определяет is_limited_apk() = is_apk() && !is_fw_apk() по переменным HD_APK и HD_FW_APK (код r24)293. В APK firmware_features.txt содержит флаг apk и не содержит fw_apk (код r24)294.

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

  • fixed_trailer_files. Прежнее расхождение снято: claim r25 исправлен — ключ был и в описателе rutube r24 (код r24)69, а новым в r25 стало его чтение оболочкой (код r25)162.
  • По SDK PluginVodInfo::buffering_ms не реализован (SDK)295, а оболочка r24 задаёт его для поставщиков равным 3000 (код r24)152. На r25 (device) при VOD плагина-тестового плагина с buffering_ms=3000 плеер пишет «setting buffering to 3000ms» и «using special buffering 3000ms» (устройство r25)296; это наблюдение связано с SDK conflicts_with. Для VOD поставщиков на r24 claims ничего не говорят.
  • Код r24 при ошибке movie_suppliers_update.sh пишет в лог «E: command failed with status» (код r24)41, а на r25 (device) строки нет ни в одном /tmp/run/*.log, как и строк «params changed» и «Updating» (устройство r25)49. Версии разные, и в какой лог пишет async_worker, claims не говорят; связи conflicts_with нет.

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

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

Утверждение Статус Claim
Значение <movie_suppliers> в installed_plugins.xml оболочка берёт из params/movie_suppliers манифеста; на r25 значения совпали (устройство r25)35 inference, disputed (вывод r24)297
Умолчания описателя: playback_type = stream, play_action = '', caption = имя файла, supported_video_types = video, server_managed = false, location_handling = ignore, special_category = false, logo_width/height = 249/68 — верификатор: logo 100×100 при иконке icons/small/<id>.jpg, server_managed = true для id из Config code, disputed (код r24)298
Поиск файлов: без status или status != active — конец, иначе опрос get_file_search_state каждые 0,5 с до 60 с, при отмене stop_file_search — верификатор: цикл до 60 с только без экрана «Файлы» code, disputed (код r24)299
get_episodes не вызывается для фильма без сериала, для поставщика app и вне списка поставщиков фильма — верификатор: ещё и при повторном выборе того же поставщика для того же фильма (кэш) code, disputed (код r24)300
Команда generic: для intent:…#Intent — am start '<deeplink>', иначе am start -p '<пакет>' и deeplink — верификатор: -p только при непустом пакете; уточнённая форма — (код r25)239 code, disputed (код r24)301
На r24 global_actions generic не выполняются, потому что флаг movie_suppliers_update есть inference, disputed (вывод r24)302
firmware_feature(<имя>) проверяет наличие имени в /tmp/firmware_features.txt inference, disputed (вывод r24)303
Флаги dunemdb_supplier_plugin_api_vN, sup_api_v8 — версии API, которые сторонний плагин может требовать в метаданных inference (вывод r24)304
Глобальный ключ перевода строится как <имя плагина>_plugin_<ключ> inference (вывод r24)305
Сторонний поставщик получает publications, только если сервер dunemdb знает его id; на r25 у тестовых плагинов publications не было (устройство r25)120 inference (код r24)306
При do_file_search с fileId стоит ставить первым вариант этого fileId: следующую серию оболочка играет без выбора inference (вывод r24)307
Проверку URL проходят абсолютный путь и схема из строчных букв, «-», «_»; m3u8://, HTTP:// отвергаются inference (вывод r24)308
stream_special всегда играет первый файл после сортировки по order; на r25 так и было (устройство r25)146 inference, disputed (вывод r24)309
У stream_special url из do_file_search не используется, нужен get_stream_url; на r25 так и было (устройство r25)147 inference (код r24)310
Для трейлеров потокового поставщика url из do_file_search не используется; на r25 так и было (устройство r25)166 inference (код r24)311
Ошибку youtube r22 сообщал url «error», не проходящий проверку inference (вывод r22)312
В APK скрипты из data.zip без бита исполнения; надёжнее вызывать sh <путь> inference (вывод r24)313
В APK <FS-префикс>/tmp — отдельный каталог приложения; обращаться через $FS_PREFIX inference (вывод r24)314
Поле +0x1c данных действия — error_action (порядок ключей LaunchExtAppActionData) inference (вывод r24)315
delay ≤ 0: если в момент проверки оболочка ещё держит фокус, выполнится error_action, хотя activity стартовала; на r25 при проверке на устройстве при 0 так и было, при −1 — нет (устройство r25)316; в серии из восьми — «timed-out» один раз (delay 0) (устройство r25)228 inference, verified (вывод r24, r25)317
Команды generic: intent:… — intent целиком из URI; -p '<пакет>' '<deeplink>' — ACTION_VIEW, ограниченный пакетом inference (вывод r24, r25)318
В cmd не работают ;, &&, \|, $VAR и несколько команд подряд inference (вывод r24, r25)319
Неэкспортированная activity чужого пакета на tv188b запускается (android.uid.system), на ATV с APK DMC — нет inference (вывод r24, r25)320
На tv188b cmd «/system/dunehd/dunehd_service do am start …» уходит в системный am от root, где есть --user и нет ограничения exported (путь в popen — код, §9); r25, device: --user 0 сработал, «START … from uid 0» (устройство r25)230; exported не проверялся inference (вывод r24, r25)321
Пакет без launcher/leanback activity в app_data.json не попадает, и start_playback_app с ним кончится «app not found» inference (вывод r24, r25)322
«Продолжить» у кнопки поставщика требует в истории plugin VOD uid вида <sup_id>:…, movie_id нужного фильма, len > 0 и pos ≥ 0 inference (вывод r25)323
Код: get_continue_by_wh_params_action (r25) шлёт плагину action_plugin handle_user_input с action_params, wh_*, autoplay и play_default_directly (0/1), таймаут 20000 мс. r25, device: ветка с 0/0 подтверждена (§11.1) (устройство r25)272, значения 1 и wh_tags не проверены code, disputed (код r25)324
«Просмотрено» для записи поставщика с не-URL uid хранится только в watched_movies.txt inference (вывод r25)325

15. Не известно

Вопросы, на которые в базе нет ответа.

Вопрос Что есть Задача
Как показывается error.message на r24 и других прошивках r25 (device): длинный — одна строка с многоточием посередине (устройство r25)185, %tr% переводится (устройство r25)186; r24 — только «показывается error.message» (код r24)172 не заведена
Как часто delay ≤ 0 даёт ложный error_action (гонка с потерей фокуса) код ожидания r25 (код r25)214; по одному запуску (проверка на устройстве): 0 — ошибка (устройство r25)223, −1 — нет (устройство r25)326; в серии из восьми (по четыре с 0 и −1): при 0 — один раз из четырёх (устройство r25)225, при −1 — ни разу (устройство r25)226; «timed-out» всего один раз, при delay 0 (устройство r25)228. Частота на большей серии и на других устройствах неизвестна не заведена
Как разбирает am start и intent: прошивка 260214 и tv188b r24 r25 и APK DMC — код (§9) (код r25)327; tv188b r24 — код (код r24)328 (§9) не заведена
Можно ли из bin запустить неэкспортированную activity на tv188b и ATV гипотеза (см. «Не проверено»); на r25 запускались только com.android.tv.settings/.MainSettings (устройство r25)179 тестовый плагин с неэкспортированной activity — новая
Что возвращает ветка dunehd_service do am start на устройстве при ошибке am код r25 (код r25)218; r25, device: 0 и для настроек, и для несуществующего компонента (устройство r25)329; вывод с Error (статус 999) не наблюдался не заведена
Есть ли регистрация поставщиков на tv175u, APK и r22 так же, как на r24 плагины есть в APK (код r24)18 не заведена; нужна матрица
Откуда movie_id в записи истории plugin VOD и получит ли кнопка поставщика «Продолжить» uid, action_plugin, action_params — device (§11.1) (устройство r25)273; условия — гипотеза (см. «Не проверено») тестовый плагин plugin VOD с recent_uid <sup_id>:… — новая
Что проверяет pf_check перед play_action (код r24)71 не заведена
Конфигурация сервисов generic (services_effective_config.json, страна, порядок) (код r24)330 не заведена
Чем различаются версии API dunemdb_supplier_plugin_api_vN гипотеза (вывод r24)304 не заведена (живые сторонние поставщики)
Удаляет ли оболочка описатель стороннего плагина при его удалении встроенные удаляют сами (код r24)16 не заведена

    • fw-tv188b-260827-0003-r24--movie-suppliers.c004 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Плагин объявляет id своих поставщиков элементом манифеста : у dunemdb_supplier_rutube это rutube, у dunemdb_supplier_youtube — YouTube; у dunemdb_supplier_generic элемента нет
    • fw-tv188b-260827-0003-r24--movie-suppliers.c009 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · update_other_plugins: для каждого установленного плагина с непустым movie_suppliers строка делится по «-» на id, подпись каждого поставщика = его id, и вызывается do_movie_suppliers_update
    • fw-tv188b-260827-0003-r24--movie-suppliers.c010 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · do_movie_suppliers_update запускает «sh /bin/movie_suppliers_update.sh» с парами аргументов (через escape_shell_arg) — только если строка «version_index:id1-id2…» отличается от сохранённой в /flashdata/plugins_data/<плагин>/movie_suppliers_params.txt; после запуска строка записывается туда
    • fw-tv188b-260827-0003-r24--movie-suppliers.c007 · device · tv188b, android-dune-fw; прошивка 260827_0003_r24 · На устройстве (tv188b, 260827_0003_r24) в /tmp/run/installed_plugins.xml элемент movie_suppliers есть у сторонних плагинов: melange — aio, dunemdb_supplier_online_movies — online_movies-online_movies_manual, play_in_apps — 11 id через «-»

    ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c010 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · do_movie_suppliers_update запускает «sh /bin/movie_suppliers_update.sh» с парами аргументов (через escape_shell_arg) — только если строка «version_index:id1-id2…» отличается от сохранённой в /flashdata/plugins_data/<плагин>/movie_suppliers_params.txt; после запуска строка записывается туда
    • fw-tv188b-260827-0003-r24--movie-suppliers.c018 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · update_plugins выходит сразу, если не взведён ни installed_plugins_dirty, ни service_plugins_dirty; иначе вызывает update_service_plugins, а update_other_plugins (поставщики из movie_suppliers) — только при installed_plugins_dirty; в конце создаёт файл suppliers_prepared_path, только если его ещё нет
    • fw-tv188b-261021-0117-r25.c126 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 после замены version_index 1→2 прямо в dune_plugin.xml установленного плагина test_plugin6_sup и перезапуска приложения (am force-stop com.dunehd.app) movie_suppliers_update.sh запущен снова с теми же парами аргументов, а movie_suppliers_params.txt стал «2:--…».
    • fw-tv188b-261021-0117-r25.c174 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при трёх следующих запусках оболочки (события gui_start 13:35:32, 13:40:55 и 13:45:18) movie_suppliers_update.sh плагина test_plugin5_sup повторно не вызывался: в /tmp/test_plugin5/sup_update.txt одна запись — 13:24:29; version_index и список id не менялись.

    ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c011 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Код возврата movie_suppliers_update.sh только логируется («E: command failed with status»); movie_suppliers_params.txt записывается и при ошибке, так что повторного запуска до смены версии или списка id нет
    • fw-tv188b-261021-0117-r25.c127 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при коде выхода 3 у movie_suppliers_update.sh оболочка всё равно записала movie_suppliers_params.txt («1:kbp6_app_n-…»).
    • fw-tv188b-261021-0117-r25.c128 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при коде выхода 3 у movie_suppliers_update.sh описатели поставщиков всё равно скопированы в /tmp/movie_suppliers, и поставщики зарегистрированы (в shell_ext.log «sups I: (reg) … kbp6_…»).

    ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c013 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Все три встроенных movie_suppliers_update.sh пишут описатель поставщика (JSON) в $FS_PREFIX/flashdata/plugins_data/<имя плагина>/movie_suppliers/
    • fw-tv188b-260827-0003-r24--movie-suppliers.c012 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · После скрипта do_movie_suppliers_update копирует /flashdata/plugins_data/<плагин>/movie_suppliers/ в /tmp/movie_suppliers/, если содержимое отличается; пустой или отсутствующий файл — предупреждение и пропуск

    ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c021 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Описатель без ключа bin пропускается с предупреждением «invalid info, 'bin' missing»; не-JSON — тоже пропуск
    • fw-tv188b-261021-0117-r25.c176 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 описателя /tmp/movie_suppliers/ из пяти ключей — plugin, caption, supported_video_types, bin, playback_type — достаточно для регистрации: kbp5_special (stream_special) и kbp5_stream (stream) есть в строке «sups I: (reg)» shell_ext.log, и их bin вызывается.

    ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c024 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Допустимые значения: playback_type — stream, stream_special, app; location_handling — ignore, skip_unmatched_publications (константы Suppliers)
    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c047 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Для playback_type stream_special экран выбора файлов не открывается: movie_screen (фильм и эпизод) и season_screen вызывают Suppliers::process_special_stream_playback_type, которое сразу запускает воспроизведение
    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c025 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Для playback_type stream при показе списка оболочка ещё до выбора пользователя получает URL каждого файла: url из ответа do_file_search или вызов get_stream_url по file_id — и ставит его в очередь проверки программе /bin/media_check (строка на URL в stdin)
    • fw-tv188b-260827-0003-r24--movie-suppliers.c046 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Успешный ответ start_playback_app: bin (команда запуска), package, wait_app_start_delay, title; приложение ищется по package, не найдено — ошибка; запуск через ActionFactory::launch_ext_app

    ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c059 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Если у поставщика непустой play_action (ключ описателя: JSON-строка, объект или массив GUI-действия), онлайн-воспроизведение идёт не по playback_type: оболочка запускает встроенное действие pf_check с plugin_name = плагин поставщика, а play_action передаёт ему как следующее действие
    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c060 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В params действия play_action оболочка кладёт supplier_id, season, episode, callback_action (закодированное действие shell_ext play_online с ignore_play_action), series_type (series/single), publications (MediaURL::encode публикаций), supplier_info (если есть), lang, region и movie_str

    ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c001 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · movieInfo, который оболочка передаёт поставщику, строит MdbMovie::get_movie_info($sup_id, $ass_type): ключи movieExtId, supplierId, title, type, videoType есть всегда; year — только если year > 0; publications — только если для поставщика есть список публикаций
    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c002 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · movieInfo.movieExtId — строка «dunemdb:», к которой через запятую дописываются непустые внешние id: «,kinopoisk:», «,imdb:», «,tmdb:», «,tmdbtv:» (MdbMovie::get_ext_id)
    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c003 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · movieInfo.title — объект «код языка → название»: под кодом языка системы (lang_code) — название фильма, под en — оригинальное название (native_title), если оно не пустое, иначе то же название
    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c004 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · movieInfo.type — series (у фильма задан series_type) или single; movieInfo.videoType — video для ass_type 0, trailer для 1, bonus для 2 (тип поставщика add_material в movieInfo называется bonus)

    ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c046 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Успешный ответ start_playback_app: bin (команда запуска), package, wait_app_start_delay, title; приложение ищется по package, не найдено — ошибка; запуск через ActionFactory::launch_ext_app
    • fw-tv188b-261021-0117-r25.c136 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 строку «am start …» действия launch_ext_app приложение разбирает само, без запуска am или sh: apk_helper делит её на список аргументов (одинарные кавычки снимаются: «-p 'com.android.tv.settings' -a … -c …» → args(6) «-p, com.android.tv.settings, -a, …»), и activity стартует AndroidJavaUtils в процессе приложения com.dunehd.app.
    • fw-tv188b-261021-0117-r25--app-launch.c060 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Разборщик apk_helper в tv188b r25 (fcn.006f2b60) сравнивает результат fcn.006f2648(cmd) с «am start » (strncmp на 9 символов; иначе «[apk_helper] unsupported command (1): %s» и -1), делит остаток по пробелам, снимает кавычки '…' и "…" (внутри "…" обратная косая только пропускает следующий символ и остаётся в аргументе; незакрытая кавычка берёт остаток строки), выбрасывает пустые и пробельные аргументы и аргументы, начинающиеся с «>» или «2>»; пустой список даёт «[apk_helper] unsupported command (2): %s» и -1.
    • fw-tv188b-261021-0117-r25--app-launch.c077 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при проверке на устройстве launch_ext_app с delay 0 (am start настроек) дал «activity launch status: 0», через 4,968 мс — «general: wait for shell app loosing focus timed-out»; настройки открылись (Displayed +123ms), и поверх них выполнился error_action действия — диалог «KB7 error_action / delay=0».
    • fw-tv188b-261021-0117-r25--app-launch.c078 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при проверке на устройстве в серии из четырёх запусков launch_ext_app с delay 0 все дали «activity launch status: 0», но ровно один (n=5) — через 1,488 мс «wait for shell app loosing focus timed-out» и show_error KB9 error_action; в остальных трёх — «already lost focus». В n=5 настройки открылись (Displayed +129ms).

    ↩

    • fw-tv188b-261021-0117-r25--app-launch.c058 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В tv188b r25 обработчик launch_ext_app fcn.00560ee8 при ненулевом статусе запуска (apk_helper или ветки dunehd_service) делает следующим действием результат fcn.001436dc(поле +0x1c данных действия) и, если он не пуст, ставит ему свойство command_status = статус; при нулевом статусе ждёт потери фокуса fcn.00560a58(поле +8 delay, …) (c062): результат 0 → следующее действие снова из поля +0x1c, иначе вызывается fcn.003cb390(поле +0xc, поле +0x10) и при непустом поле +0x14 показывается тост («[gui_action] show toast: '%s'»).
    • fw-tv188b-261021-0117-r25--app-launch.c062 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Ожидание потери фокуса fcn.00560a58(delay, метка) в tv188b r25 — если оболочка уже без фокуса, «%s: shell app is already lost focus» и результат 1; если delay < 1 — сразу «%s: wait for shell app loosing focus timed-out» и 0; иначе каждые 100 мс (usleep(100000)) проверяет фокус до delay секунд — потеря фокуса даёт «%s: shell app lost focus in %.2fs» и ненулевой результат, истечение срока — «timed-out» и 0.
    • fw-tv188b-261021-0117-r25.c137 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при «activity launch status: -1» действие launch_ext_app из ответа start_playback_app выполнило свой error_action: сразу за этим в shell.log «running gui show_error(0, Не удалось запустить воспроизведение)», на экране это сообщение, приложение не открылось.

    ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c045 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ответ start_playback_app с error.missing_app (title, package, непустой urls; необязательно indirect, intro_dialog_urls) и !$repeat превращается в действие «скачать и установить приложение»; иначе показывается error.message, а если его нет — errmsg_failed_to_start_playback
    • fw-tv188b-260827-0003-r24--shell-ext--entry-handler.c038 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ветка confirm_install_app выбирает install_from_market при is_limited_apk(), иначе download_and_install_apk с JSON-декодированными app_urls и app_intro_dialog_urls.

    ↩

    • fw-tv188b-261021-0117-r25.c132 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 error.message ответа start_playback_app длиной 409 символов оболочка передала в show_error целиком, а диалог на экране показал его одной строкой, сокращённой посередине многоточием: видны начало («[000]-…») и конец («…[400] END»), отдельного заголовка нет.
    • fw-tv188b-261021-0117-r25.c141 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 error.message ответа start_playback_app «%tr%errmsg_failed_to_start_playback» показан переведённым: в shell_ext.log строка ещё «Supplier returned error: %tr%errmsg_failed_to_start_playback», а в shell.log show_error и на экране — «Не удалось запустить воспроизведение».

    ↩

    • fw-tv188b-261021-0117-r25.c179 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 команды поставщика из стороннего плагина (bin без cd) выполняются с uid 1000 и текущим каталогом /.
    • fw-tv188b-261021-0117-r25.c172 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 bin/movie_suppliers_update.sh плагина-поставщика выполняется с uid 1000 и переменной окружения FS_PREFIX=/data/data/com.dunehd.app.

    ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c036 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Оболочка вызывает поставщика командой « <команда>» через proc_open: входной объект — JSON в stdin, результат — JSON из stdout, stderr дописывается в /tmp/run/__supplier.log
    • fw-tv188b-260827-0003-r24--movie-suppliers.c039 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Наличие файла /tmp/suppliers_debug включает печать входа и выхода команд поставщика в лог оболочки
    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c074 · device · tv188b, android-dune-fw; прошивка 260827_0003_r24 · На tv188b r24 в /tmp/run есть логи поставщиков YouTube__supplier.log (70453 байт) и rutube__supplier.log (4797 байт) — stderr команд поставщиков действительно пишется в /tmp/run/__supplier.log
    • fw-tv188b-261021-0117-r25--movie-suppliers.c013 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В do_cmd r25 /tmp/suppliers_debug по-прежнему включает полный вход и выход, теперь с префиксами Input/Output ( bytes); без debug или force печатается только длина.
    • fw-tv188b-261021-0117-r25.c180 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 stderr команды поставщика дописывается в /tmp/run/__supplier.log: строки «kbp5 sup: id=… cmd=…», которые sup.sh пишет в stderr, есть в /tmp/run/kbp5_special__supplier.log и /tmp/run/kbp5_stream__supplier.log, по одной на каждый вызов.
    • fw-tv188b-261021-0117-r25.c140 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при существующем /tmp/suppliers_debug в /tmp/run/shell_ext.log для команд поставщиков печатаются полный вход и выход в виде «Input ( bytes): » и «Output ( bytes): » — и для start_playback_app тестового плагина, и для запросов поставщика YouTube.

    ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c035 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Перечитывание поставщиков: при наличии /tmp/movie_suppliers_changed.flag (reload_suppliers_if_changed); в первый раз ждёт файл suppliers_prepared_path до 30 раз по 0,1 с
    • fw-tv188b-261021-0117-r25.c052 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Suppliers::reload_if_changed (в r24 — reload_suppliers_if_changed) перечитывает поставщиков не только при наличии флага-файла, но и при смене mtime каталога /tmp/movie_suppliers
    • fw-tv188b-261021-0117-r25--movie-suppliers.c006 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Suppliers::reload_suppliers($mtime=-2) сохраняет переданный mtime в sups_mtime; при значении -2 предварительно читает mtime каталога DIR_PATH.

    ↩

  1. fw-tv188b-260827-0003-r24--movie-suppliers.c068 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Манифесты rutube и youtube в global_actions/uninstall удаляют свой описатель: /bin/rm -f /tmp/movie_suppliers/rutube и /tmp/movie_suppliers/YouTube ↩↩↩

    • fw-tv188b-260827-0003-r24--shell-ext--entry-handler.c106 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · play_recent требует sup_id и movie_id; передаёт все входные поля wh_* в JSON sup_info для play_online; autoplay добавляет действие enter после открытия карточки.
    • fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c074 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В r24 диалог выбора воспроизведения давал кнопкам play_online поставщиков только s, e и sup_id, без sup_info; wh_* доходили до поставщика лишь через entry/play_recent.
    • fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c060 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 диалог выбора воспроизведения строит для каждого поставщика (с дедупликацией по key_show_only_one) кнопку play_online с s, e, sup_id; только кнопке поставщика, чей id равен whi_sup_id последней записи истории, добавляется sup_info из get_wh_supplier_info.
    • fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c062 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · make_base_button_defs (r25) берёт whi_sup_id записи по ключу all или x только при наличии прогресса (with_progress); без прогресса ни одна кнопка поставщика не получает sup_info и подписи «Продолжить».

    ↩

  2. 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 ↩↩↩

  3. fw-tv188b-260827-0003-r24--movie-suppliers.c019 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Оболочка (shell_ext, класс Suppliers) читает описатели поставщиков из каталога /tmp/movie_suppliers; id поставщика — имя файла, категория — movies ↩

  4. fw-tv188b-260827-0003-r24--movie-suppliers.c033 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Поставщик предлагается для фильма, только если поддерживает тип материала; при пустом списке публикаций фильма у поставщика (кроме YouTube и server_ignored) и при отсутствии публикаций у server_managed — не предлагается ↩↩

  5. fw-tv188b-260827-0003-r24--movie-suppliers.c025 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · supported_video_types — список через «|»: video, trailer, add_material; они соответствуют типам материала ass_type 0, 1, 2 ↩↩

  6. fw-tv188b-260827-0003-r24--movie-suppliers.c029 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ключ expr описателя вычисляется Expr; ложь — поставщик отключается. Для id rutube expr принудительно country(ru), если не установлен плагин rutube_integration (иначе условия нет) ↩↩↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c027 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Поставщик не регистрируется, если существует файл /flashdata/plugins_data//movie_suppliers_disabled
    • fw-tv188b-260827-0003-r24--movie-suppliers.c028 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · dunestore создаёт или удаляет movie_suppliers_disabled при отключении/включении плагина, только если в installed_plugins у плагина movie_supplier_disable_capable == 1 и режим не ТВ; при применении пишет /tmp/movie_suppliers_changed.flag

    ↩

  7. fw-tv188b-260827-0003-r24--movie-suppliers.c022 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Файл с именем netflix в /tmp/movie_suppliers оболочка пропускает (комментарий «TODO: hack») ↩

  8. plg-dc-globaltv.c020 · code · unknown; прошивка — · Манифест содержит movie_supplier/disable_capable = yes. ↩

  9. fw-tv188b-260827-0003-r24--plugin-loader.c028 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · libduneshell.so содержит шаблон записи installed_plugins.xml: / с полями name, caption, path, version_index, version_id, patch_index, version, launch_capable, delete_capable (литерал 0), tv_epf_capable (1), movie_supplier_disable_capable (1), category, logo_url ↩

  10. fw-tv188b-260827-0003-r24--movie-suppliers.c031 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ключ langs: нет или any — подходит любому языку, иначе ищется слово языка интерфейса; при сортировке поставщики не-community идут раньше community, затем подходящие по языку ↩↩

  11. fw-tv188b-260827-0003-r24--movie-suppliers.c032 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Поставщики rutube и YouTube всегда считаются community и получают порядковые индексы 1001 и 1002 (UNKNOWN_SUP_INDEX = 1000) ↩

  12. fw-tv188b-261021-0117-r25--movie-suppliers.c003 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 Suppliers::get_movie_suppliers возвращает отображение id → bool: play_filter ограничивает набор, а main_play_filter отмечает true только внутри этого набора; без main_play_filter все значения false. ↩

  13. fw-tv188b-261021-0117-r25--movie-suppliers.c001 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Suppliers::get_video_sup_ids возвращает только video_supported: непустой key_show_only_one выдаётся один раз вместо id, иначе выдаётся id поставщика. ↩

  14. fw-tv188b-261021-0117-r25--movie-suppliers.c002 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Suppliers::get_supplier_by_unique_id возвращает первый в списке объект с совпавшим id или непустым key_show_only_one; при отсутствии совпадения — null. ↩

  15. fw-tv188b-260827-0003-r24--movie-suppliers.c004 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Плагин объявляет id своих поставщиков элементом манифеста : у dunemdb_supplier_rutube это rutube, у dunemdb_supplier_youtube — YouTube; у dunemdb_supplier_generic элемента нет ↩

  16. fw-tv188b-260827-0003-r24--movie-suppliers.c005 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · libduneshell.so содержит строку movie_suppliers и шаблон элемента %s рядом с шаблоном записи installed_plugins.xml ↩

  17. fw-tv188b-260827-0003-r24--movie-suppliers.c007 · device · tv188b, android-dune-fw; прошивка 260827_0003_r24 · На устройстве (tv188b, 260827_0003_r24) в /tmp/run/installed_plugins.xml элемент movie_suppliers есть у сторонних плагинов: melange — aio, dunemdb_supplier_online_movies — online_movies-online_movies_manual, play_in_apps — 11 id через «-» ↩

  18. fw-tv188b-261021-0117-r25.c171 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 в /tmp/run/installed_plugins.xml у стороннего плагина test_plugin5_sup есть элемент kbp5_stream-kbp5_special — то же значение, что в params/movie_suppliers его dune_plugin.xml. ↩↩

  19. fw-tv188b-261021-0117-r25.c221 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 плагин с type plain без params/program (тестовые плагины-поставщики test_plugin5_sup и test_plugin6_sup: в каталоге только dune_plugin.xml и bin/) регистрируется; его запись в /tmp/run/installed_plugins.xml — launch_capable 0 и movie_suppliers со значением params/movie_suppliers. ↩

  20. fw-tv188b-260827-0003-r24--movie-suppliers.c008 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · shell_ext (async_worker.php, get_all_installed_plugins) читает из installed_plugins.xml поля name, path, movie_suppliers и version_index каждого плагина ↩

  21. fw-tv188b-260827-0003-r24--movie-suppliers.c009 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · update_other_plugins: для каждого установленного плагина с непустым movie_suppliers строка делится по «-» на id, подпись каждого поставщика = его id, и вызывается do_movie_suppliers_update ↩

  22. fw-tv188b-260827-0003-r24--movie-suppliers.c010 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · do_movie_suppliers_update запускает «sh /bin/movie_suppliers_update.sh» с парами аргументов (через escape_shell_arg) — только если строка «version_index:id1-id2…» отличается от сохранённой в /flashdata/plugins_data/<плагин>/movie_suppliers_params.txt; после запуска строка записывается туда ↩↩↩

  23. fw-tv188b-260827-0003-r24--movie-suppliers.c018 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · update_plugins выходит сразу, если не взведён ни installed_plugins_dirty, ни service_plugins_dirty; иначе вызывает update_service_plugins, а update_other_plugins (поставщики из movie_suppliers) — только при installed_plugins_dirty; в конце создаёт файл suppliers_prepared_path, только если его ещё нет ↩

  24. fw-tv188b-260827-0003-r24--movie-suppliers.c011 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Код возврата movie_suppliers_update.sh только логируется («E: command failed with status»); movie_suppliers_params.txt записывается и при ошибке, так что повторного запуска до смены версии или списка id нет ↩↩↩

  25. fw-tv188b-261021-0117-r25.c125 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 movie_suppliers_update.sh плагина-поставщика test_plugin6_sup запущен с парами аргументов « » (подпись равна id) для всех восьми id в порядке их перечисления в params/movie_suppliers манифеста. ↩

  26. fw-tv188b-261021-0117-r25.c172 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 bin/movie_suppliers_update.sh плагина-поставщика выполняется с uid 1000 и переменной окружения FS_PREFIX=/data/data/com.dunehd.app. ↩

  27. fw-tv188b-261021-0117-r25.c173 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 после регистрации поставщиков файл $FS_PREFIX/flashdata/plugins_data/test_plugin5_sup/movie_suppliers_params.txt (26 байт) содержит «1:kbp5_stream-kbp5_special» — version_index плагина (1), двоеточие и список id из params/movie_suppliers. ↩

  28. fw-tv188b-261021-0117-r25.c174 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при трёх следующих запусках оболочки (события gui_start 13:35:32, 13:40:55 и 13:45:18) movie_suppliers_update.sh плагина test_plugin5_sup повторно не вызывался: в /tmp/test_plugin5/sup_update.txt одна запись — 13:24:29; version_index и список id не менялись. ↩

  29. fw-tv188b-261021-0117-r25.c126 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 после замены version_index 1→2 прямо в dune_plugin.xml установленного плагина test_plugin6_sup и перезапуска приложения (am force-stop com.dunehd.app) movie_suppliers_update.sh запущен снова с теми же парами аргументов, а movie_suppliers_params.txt стал «2:--…». ↩

  30. fw-tv188b-261021-0117-r25.c127 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при коде выхода 3 у movie_suppliers_update.sh оболочка всё равно записала movie_suppliers_params.txt («1:kbp6_app_n-…»). ↩

  31. fw-tv188b-261021-0117-r25.c128 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при коде выхода 3 у movie_suppliers_update.sh описатели поставщиков всё равно скопированы в /tmp/movie_suppliers, и поставщики зарегистрированы (в shell_ext.log «sups I: (reg) … kbp6_…»). ↩

  32. fw-tv188b-261021-0117-r25.c129 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 строк async_worker о регистрации поставщиков test_plugin6_sup — «Plugin test_plugin6_sup: params changed/not changed» и «Updating test_plugin6_sup: …» — нет ни в одном /tmp/run/*.log ни после первого запуска movie_suppliers_update.sh (код выхода 3), ни после повторного; «E: command failed with status» нет в логах /tmp/run, где упоминается тестовый плагин (shell.log, shell_ext.log). ↩↩

  33. fw-tv188b-260827-0003-r24--movie-suppliers.c014 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · movie_suppliers_update.sh generic обрабатывает аргументы парами (id, caption) в цикле и пишет по файлу на пару; rutube и youtube аргументы не читают, а id и caption у них зашиты в скрипт ↩

  34. fw-tv188b-260827-0003-r24--movie-suppliers.c013 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Все три встроенных movie_suppliers_update.sh пишут описатель поставщика (JSON) в $FS_PREFIX/flashdata/plugins_data/<имя плагина>/movie_suppliers/ ↩

  35. fw-tv188b-260827-0003-r24--movie-suppliers.c012 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · После скрипта do_movie_suppliers_update копирует /flashdata/plugins_data/<плагин>/movie_suppliers/ в /tmp/movie_suppliers/, если содержимое отличается; пустой или отсутствующий файл — предупреждение и пропуск ↩

  36. fw-tv188b-260827-0003-r24--movie-suppliers.c015 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · shell_ext/bin/run_async_worker.sh создаёт каталог $FS_PREFIX/tmp/movie_suppliers с правами 777 ↩

  37. fw-tv188b-261021-0117-r25.c175 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 описатели kbp5_special и kbp5_stream, которые movie_suppliers_update.sh тестового плагина пишет только в $FS_PREFIX/flashdata/plugins_data/test_plugin5_sup/movie_suppliers/, после регистрации есть и в /tmp/movie_suppliers/ с теми же размерами (253 и 243 байт) и временем 13:24. ↩

  38. fw-tv188b-261021-0117-r25.c199 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 (collect4) в $FS_PREFIX/flashdata/plugins_data/dunemdb_supplier_generic/movie_suppliers лежат описатели AppleTV, Ivi, Kinopoisk и Premier, а в /tmp/movie_suppliers файлов с этими id нет. ↩

  39. fw-tv188b-261021-0117-r25.c200 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 (collect4) movie_suppliers_params.txt есть в plugins_data у dunemdb_supplier_online_movies, dunemdb_supplier_rutube, dunemdb_supplier_youtube, melange и play_in_apps, а у dunemdb_supplier_generic и dune-hd.tv, у которых есть каталог movie_suppliers, его нет. ↩

  40. fw-tv188b-260827-0003-r24--movie-suppliers.c035 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Перечитывание поставщиков: при наличии /tmp/movie_suppliers_changed.flag (reload_suppliers_if_changed); в первый раз ждёт файл suppliers_prepared_path до 30 раз по 0,1 с ↩↩

  41. fw-tv188b-261021-0117-r25.c052 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Suppliers::reload_if_changed (в r24 — reload_suppliers_if_changed) перечитывает поставщиков не только при наличии флага-файла, но и при смене mtime каталога /tmp/movie_suppliers ↩↩

  42. fw-tv188b-261021-0117-r25--movie-suppliers.c006 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Suppliers::reload_suppliers($mtime=-2) сохраняет переданный mtime в sups_mtime; при значении -2 предварительно читает mtime каталога DIR_PATH. ↩

  43. fw-tv188b-260827-0003-r24--movie-suppliers.c028 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · dunestore создаёт или удаляет movie_suppliers_disabled при отключении/включении плагина, только если в installed_plugins у плагина movie_supplier_disable_capable == 1 и режим не ТВ; при применении пишет /tmp/movie_suppliers_changed.flag ↩

  44. fw-tv188b-260827-0003-r24--movie-suppliers.c016 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · update_service_plugins: для сервисов из конфигурации movie services, которые есть в эффективном списке и чей плагин (plugin_name) установлен с version_index > 0, собирает id поставщиков (service.suppliers[].id с caption, иначе id сервиса с caption сервиса) и вызывает do_movie_suppliers_update ↩

  45. fw-tv188b-260827-0003-r24--movie-suppliers.c017 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Файлы в /tmp/movie_suppliers с id скрытых сервисов (и их suppliers) update_service_plugins удаляет; при изменениях пишет флаг /tmp/movie_suppliers_changed.flag ↩

  46. fw-tv188b-260827-0003-r24--movie-suppliers.c048 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · dunemdb_supplier_generic в global_actions boot_end, install и update запускает bin/update_movie_suppliers.sh (type plugin_system) с условием if="not(firmware_feature(movie_suppliers_update))" ↩

  47. fw-tv188b-260827-0003-r24--movie-suppliers.c049 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · firmware_features.txt прошивки 260827_0003_r24 содержит флаги movie_suppliers_update и movie_suppliers_order ↩

  48. fw-tv188b-260827-0003-r24--movie-suppliers.c077 · code · tv188b, android-dune-fw; прошивка 250815_1012_r22 · В 250815_1012_r22 youtube регистрировался сам: global_actions boot_end/install/update с условием not(firmware_feature(movie_suppliers_update)) запускали bin/register_supplier.sh, писавший описатель прямо в $FS_PREFIX/tmp/movie_suppliers/YouTube ↩↩↩

  49. fw-tv188b-260827-0003-r24--movie-suppliers.c020 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Комментарий в suppliers.php описывает формат описателя: JSON с ключами plugin, caption, bin, supported_video_types ↩

  50. fw-tv188b-260827-0003-r24--movie-suppliers.c021 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Описатель без ключа bin пропускается с предупреждением «invalid info, 'bin' missing»; не-JSON — тоже пропуск ↩↩

  51. fw-tv188b-260827-0003-r24--movie-suppliers.c026 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Если в описателе нет plugin, имя плагина берётся из bin по шаблону /(flashdata|firmware_ext|persistfs)/plugins/<имя>/bin/, иначе unknown ↩↩

  52. fw-tv188b-260827-0003-r24--movie-suppliers.c064 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Описатель rutube: caption %tr%title_supplier, langs russian, supported_video_types video|trailer, playback_type app, fixed_trailer_files [search_trailers], icon_url plugin_file://%android_apps%/icons/rutube.png, expr country(ru) ↩↩↩↩

  53. fw-tv188b-260827-0003-r24--movie-suppliers.c024 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Допустимые значения: playback_type — stream, stream_special, app; location_handling — ignore, skip_unmatched_publications (константы Suppliers) ↩↩

  54. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c059 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Если у поставщика непустой play_action (ключ описателя: JSON-строка, объект или массив GUI-действия), онлайн-воспроизведение идёт не по playback_type: оболочка запускает встроенное действие pf_check с plugin_name = плагин поставщика, а play_action передаёт ему как следующее действие ↩↩↩↩↩↩

  55. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c061 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · movie_str — JSON полей MdbMovie без supplier_publications, active_video_pubs_by_sup_id и conn; seasons заменяются на season_numbers ({number, year, episodes_count}) и year2; при ключе описателя play_action_with_seasons у сериала полные сезоны пишутся в /sup_seasons.json, путь — в params.seasons_file ↩↩

  56. fw-tv188b-260827-0003-r24--movie-suppliers.c034 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · server_managed принудительно true для id из Config::$server_managed_suppliers, server_ignored — для id из Config::$server_ignored_suppliers (строки через запятую) ↩

  57. fw-tv188b-260827-0003-r24--movie-suppliers.c030 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ключи sticker_icon_url, logo_icon_url, special_category_icon_url: значение без схемы «xxx://» дополняется до plugin_file://%%/<значение>; по умолчанию logo — plugin_file://icons/transparent.aai, special_category — plugin_file://icons/genre_all.png ↩↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c064 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Описатель rutube: caption %tr%title_supplier, langs russian, supported_video_types video|trailer, playback_type app, fixed_trailer_files [search_trailers], icon_url plugin_file://%android_apps%/icons/rutube.png, expr country(ru)
    • fw-tv188b-261021-0117-r25.c054 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 suppliers.php впервые читает ключ описателя поставщика fixed_trailer_files (сам ключ был и в r24 — в описателе rutube): для трейлеров (ass_type 1) Suppliers берёт этот массив вместо запроса поиска файлов; не массив — пустой список

    ↩

    • 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
    • fw-tv188b-261021-0117-r25--movie-suppliers.c007 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Выбор dl-поставщика в reload_suppliers выполняется в цикле загрузки описателей до usort списка поставщиков по cmp_suppliers.

    ↩

  58. fw-tv188b-260827-0003-r24--movie-suppliers.c054 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Описатель generic: plugin dunemdb_supplier_generic, supported_video_types video, server_managed true, location_handling skip_unmatched_publications, playback_type app, special_category true, special_category_icon_url icons/category.png, sticker_icon_url icons/sticker_.png, logo_icon_url пустой ↩

  59. fw-tv188b-261021-0117-r25--movie-suppliers.c018 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Описатель generic r25 по-прежнему объявляет supported_video_types=video, playback_type=app, server_managed=true и location_handling=skip_unmatched_publications. ↩↩

  60. fw-tv188b-260827-0003-r24--movie-suppliers.c069 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Описатель YouTube: caption %tr%title_supplier, supported_video_types video|trailer|add_material, playback_type app, icon_url plugin_file://%dunemdb_supplier_youtube%/youtube.png, play_icon_url plugin_file://%android_apps%/icons/youtube.png ↩

  61. fw-tv188b-260827-0003-r24--movie-suppliers.c055 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · bin поставщиков generic и rutube — «cd <каталог bin> && $FS_PREFIX/firmware_ext/php/php-cgi -f ./run.php»; у youtube добавлен «-c <каталог bin>» (свой php.ini) ↩

  62. fw-tv188b-260827-0003-r24--movie-suppliers.c036 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Оболочка вызывает поставщика командой « <команда>» через proc_open: входной объект — JSON в stdin, результат — JSON из stdout, stderr дописывается в /tmp/run/__supplier.log ↩

  63. fw-tv188b-260827-0003-r24--movie-suppliers.c037 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ненулевой код выхода bin или не-JSON на stdout — результат команды null (ошибка) ↩↩

  64. fw-tv188b-260827-0003-r24--movie-suppliers.c038 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Лог /tmp/run/__supplier.log проверяется не чаще раза в 60 с и при размере ≥ 100000 байт переименовывается в .old ↩

  65. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c074 · device · tv188b, android-dune-fw; прошивка 260827_0003_r24 · На tv188b r24 в /tmp/run есть логи поставщиков YouTube__supplier.log (70453 байт) и rutube__supplier.log (4797 байт) — stderr команд поставщиков действительно пишется в /tmp/run/__supplier.log ↩

  66. fw-tv188b-261021-0117-r25.c177 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 оболочка запускает команду поставщика строкой « <команда>»: при bin «sh /data/data/com.dunehd.app/flashdata/plugins/test_plugin5_sup/bin/sup.sh kbp5_special» в shell_ext.log записано «Run: sh …/sup.sh kbp5_special do_file_search». ↩

  67. fw-tv188b-261021-0117-r25.c178 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 вход команды поставщик получает в stdin: JSON, который sup.sh сохранил из stdin для do_file_search kbp5_special, совпадает со строкой «Input (307 bytes): …» в shell_ext.log. ↩

  68. fw-tv188b-261021-0117-r25.c179 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 команды поставщика из стороннего плагина (bin без cd) выполняются с uid 1000 и текущим каталогом /. ↩

  69. fw-tv188b-261021-0117-r25.c180 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 stderr команды поставщика дописывается в /tmp/run/__supplier.log: строки «kbp5 sup: id=… cmd=…», которые sup.sh пишет в stderr, есть в /tmp/run/kbp5_special__supplier.log и /tmp/run/kbp5_stream__supplier.log, по одной на каждый вызов. ↩

  70. fw-tv188b-260827-0003-r24--movie-suppliers.c040 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Команды, которые оболочка передаёт bin поставщика: get_episodes, do_file_search, get_file_search_state, stop_file_search, get_stream_url, start_playback_app ↩↩

  71. fw-tv188b-260827-0003-r24--movie-suppliers.c041 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · get_episodes получает {movieInfo}; get_stream_url — {fileId}; start_playback_app — {movieInfo, assType, season, episode, fileId} ↩↩↩

  72. fw-tv188b-260827-0003-r24--movie-suppliers.c042 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · do_file_search при первом запуске получает movieInfo и, если заданы, season, episode, fileId, private, premiered; get_file_search_state и stop_file_search — пустой объект ↩↩

  73. fw-tv188b-261021-0117-r25.c181 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 get_episodes получает на вход только объект movieInfo (videoType video) — без season, episode и private. ↩

    • fw-tv188b-261021-0117-r25.c183 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 do_file_search серии получает, кроме movieInfo, ключи season и episode и значение private из ответа get_episodes («private":"kbp5-private»).
    • fw-tv188b-261021-0117-r25.c184 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 ключ premiered во входе do_file_search серии есть, только если он задан у этой серии в ответе get_episodes: для серии 1 (premiered 2020-01-01) он передан, для серии 2 без premiered — нет.

    ↩

  74. fw-tv188b-261021-0117-r25.c182 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 get_stream_url запускается как « get_stream_url» и получает на вход только {"fileId": }. ↩

  75. fw-tv188b-261021-0117-r25.c131 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 вход команды start_playback_app для фильма type single — JSON {movieInfo, assType:0, season:-1, episode:-1, fileId:null}; movieInfo содержит movieExtId, supplierId (id выбранного поставщика), title {ru, en}, year, type и videoType. ↩

  76. fw-tv188b-260827-0003-r24--movie-suppliers.c044 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Статусы поиска (константы Suppliers): active, suspended, done, stopped ↩

  77. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c024 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · На экране онлайн-файлов (OnlineFilesScreen) поиск асинхронный: пока status == active, оболочка сразу возвращает уже полученные файлы, не ждёт в цикле 60 с, и опрашивает get_file_search_state по таймеру экрана 500 мс ↩↩

  78. fw-tv188b-261021-0117-r25.c197 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 в шаге sup-next оболочка дважды вызвала у kbp5_stream do_file_search и в ту же секунду stop_file_search, затем get_stream_url, хотя sup.sh на do_file_search всегда отвечает status done; get_file_search_state не вызывался. ↩

  79. fw-tv188b-260827-0003-r24--movie-suppliers.c039 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Наличие файла /tmp/suppliers_debug включает печать входа и выхода команд поставщика в лог оболочки ↩

  80. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c043 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Команда get_stream_url вызывается как « get_stream_url» с {fileId}; её вход и выход всегда пишутся в лог оболочки (DEBUG input/output), независимо от /tmp/suppliers_debug ↩

  81. fw-tv188b-261021-0117-r25--movie-suppliers.c013 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В do_cmd r25 /tmp/suppliers_debug по-прежнему включает полный вход и выход, теперь с префиксами Input/Output ( bytes); без debug или force печатается только длина. ↩

  82. fw-tv188b-261021-0117-r25--movie-suppliers.c014 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 do_search_files передаёт в do_cmd force_debug_input=false и для первого do_file_search, и для последующих get_file_search_state. ↩

  83. fw-tv188b-261021-0117-r25--movie-suppliers.c015 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 do_start_playback_app вызывает do_cmd с force_debug_input=false и force_debug_output=true. ↩

  84. fw-tv188b-261021-0117-r25--movie-suppliers.c016 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 do_cmd обрезает завершающие пробельные символы stdout через rtrim до измерения длины, debug-печати и json_decode. ↩↩

  85. fw-tv188b-261021-0117-r25.c140 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при существующем /tmp/suppliers_debug в /tmp/run/shell_ext.log для команд поставщиков печатаются полный вход и выход в виде «Input ( bytes): » и «Output ( bytes): » — и для start_playback_app тестового плагина, и для запросов поставщика YouTube. ↩

  86. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c057 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · YouTube оболочка r24 воспроизводит сама, мимо команд поставщика: GuiHelper::get_play_youtube_file_action запускает URL plugin_launcher://{name=android_apps}{keep_position=1}{action_id=launch_youtube}{app_param_youtube_id=}, при поиске — с {app_param_search_query=<запрос>} ↩↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c041 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · get_episodes получает {movieInfo}; get_stream_url — {fileId}; start_playback_app — {movieInfo, assType, season, episode, fileId}
    • fw-tv188b-260827-0003-r24--movie-suppliers.c046 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Успешный ответ start_playback_app: bin (команда запуска), package, wait_app_start_delay, title; приложение ищется по package, не найдено — ошибка; запуск через ActionFactory::launch_ext_app

    ↩

  87. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c047 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Для playback_type stream_special экран выбора файлов не открывается: movie_screen (фильм и эпизод) и season_screen вызывают Suppliers::process_special_stream_playback_type, которое сразу запускает воспроизведение ↩

  88. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c025 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Для playback_type stream при показе списка оболочка ещё до выбора пользователя получает URL каждого файла: url из ответа do_file_search или вызов get_stream_url по file_id — и ставит его в очередь проверки программе /bin/media_check (строка на URL в stdin) ↩↩

  89. fw-tv188b-261021-0117-r25.c130 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при выборе в карточке фильма (type single) источника — поставщика с playback_type app — оболочка вызывала bin поставщика только с командой start_playback_app, по одному вызову на выбор; get_episodes, do_file_search и другие команды не вызывались. ↩

  90. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c001 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · movieInfo, который оболочка передаёт поставщику, строит MdbMovie::get_movie_info($sup_id, $ass_type): ключи movieExtId, supplierId, title, type, videoType есть всегда; year — только если year > 0; publications — только если для поставщика есть список публикаций ↩

  91. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c002 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · movieInfo.movieExtId — строка «dunemdb:», к которой через запятую дописываются непустые внешние id: «,kinopoisk:», «,imdb:», «,tmdb:», «,tmdbtv:» (MdbMovie::get_ext_id) ↩

  92. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c003 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · movieInfo.title — объект «код языка → название»: под кодом языка системы (lang_code) — название фильма, под en — оригинальное название (native_title), если оно не пустое, иначе то же название ↩

  93. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c004 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · movieInfo.type — series (у фильма задан series_type) или single; movieInfo.videoType — video для ass_type 0, trailer для 1, bonus для 2 (тип поставщика add_material в movieInfo называется bonus) ↩↩

    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c005 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Для видео (ass_type 0) movieInfo.publications берётся из active_video_pubs_by_sup_id, куда rebuild_supplier_pub_maps кладёт только непустые списки; если у фильма нет публикаций поставщика, ключа publications в movieInfo нет
    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c007 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Публикации берутся из ответа сервера dunemdb о фильме: поле suppliers — объект «id поставщика → {publications: [...]}»; публикация принимается, только если у неё есть id или deeplink и есть caption

    ↩

  94. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c007 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Публикации берутся из ответа сервера dunemdb о фильме: поле suppliers — объект «id поставщика → {publications: [...]}»; публикация принимается, только если у неё есть id или deeplink и есть caption ↩

  95. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c008 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Отбор публикаций по языку: сначала публикации без lang или с lang = языку системы, затем на других языках — видео любого языка, а прочие типы только на запасном языке (ru для uk; en для всех, кроме en); к caption каждой отобранной публикации дописывается « []» ↩

  96. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c009 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Каждой отобранной публикации оболочка добавляет поле sup_id (id поставщика), а при отсутствии type ставит type = video; после этого перестраивается active_video_pubs_by_sup_id ↩

  97. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c006 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Список публикаций поставщика для movieInfo фильтруется: null, если у фильма нет записи этого поставщика или поставщик server_ignored; остаются публикации нужного type (video/trailer/bonus); при location_handling = skip_unmatched_publications и известной стране отбрасываются публикации с непустым countries без этой страны ↩

  98. fw-tv188b-261021-0117-r25.c185 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 movieInfo во входе do_file_search новых сторонних поставщиков kbp5_stream и kbp5_special содержит только movieExtId, supplierId, title, year, type и videoType — ключа publications нет. ↩↩

  99. fw-tv188b-261021-0117-r25.c186 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 встроенный поставщик YouTube для того же фильма получает в movieInfo do_file_search ключ publications — список элементов с id, caption, lang, size, type и sup_id. ↩

  100. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c012 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ответ get_episodes кэшируется в статических полях Suppliers по паре (movieExtId фильма, id поставщика): для того же фильма и поставщика get_episodes повторно не запускается; кэш сбрасывает clear_cache, в том числе в reload_suppliers ↩

  101. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c013 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ответ get_episodes: при null, при наличии error (в лог пишется error.message) или без seasons список эпизодов пуст; необязательное поле private приводится к строке и потом передаётся в do_file_search как private ↩

  102. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c014 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Элемент seasons[] ответа get_episodes: number обязателен, числовой, от -1 до 99; episodes обязателен; иначе сезон пропускается («bad season»); необязательный title (строка) запоминается как название сезона ↩

  103. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c015 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Элемент seasons[].episodes[]: number обязателен, числовой, от 0 до 999, иначе эпизод пропускается; необязательные title и premiered (строки); premiered эпизода потом передаётся в do_file_search как premiered ↩

  104. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c017 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · CurrentMovieFiles считает сезоном только s от 0 до 99, эпизодом — e от 0 до 999; остальные значения (в том числе сезон -1 из get_episodes) означают «нет» (-2) ↩

  105. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c018 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Если в онлайн-списке есть хоть один сезон (0–99), открывается экран сезонов SeriesSeasonsScreen; иначе, если есть эпизоды без сезона, — экран эпизодов MovieEpisodesScreen с сезоном -1 ↩

  106. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c021 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Элемент files[] ответа do_file_search принимается, только если id задан и не состоит из одних пробелов и задан caption; если хотя бы у одного файла есть order, список сортируется по intval(order) (без order — в конец), при равенстве — strnatcmp по id ↩

  107. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c022 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Список видеофайлов эпизода считается полным только при status == done; при любом другом статусе (или без status) кэш помечается неполным (cached_video_ep_files_partial) и может быть запрошен снова ↩

  108. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c023 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Suppliers::get_video_files переводит файл поставщика во внутренний вид: path = caption, file_id = id, stream_url = url (если задан), order (по умолчанию PHP_INT_MAX/2), s и e (-2, если не заданы), ass_type 0, movie_id, sup_id ↩

  109. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c073 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Поле quality в files ответа do_file_search встроенные поставщики пишут (youtube и rutube r24 — «HD»), но оболочка r24 его нигде не читает: get_video_files и get_non_video_files строят объекты файлов из явного набора полей без quality, поэтому на выбор и подпись файла оно не влияет ↩

  110. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c020 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ответ do_file_search для видео: при null результат помечается неполным без файлов; при error оболочка запоминает объект error (message и необязательный action) и файлов нет; при redirect пишет в лог «Supplier redirected to external app» и файлов нет ↩

  111. fw-tv188b-261021-0117-r25--movie-suppliers.c012 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · OnlineFilesScreen::get_timer в r25 публичен и возвращает ActionFactory::timer(500). ↩

  112. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c029 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В списке онлайн-файлов показываются только файлы, для которых media_check уже вернул результат; файл, чья длительность не больше 1/10 длительности фильма, отбрасывается ↩

  113. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c030 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Проверенные файлы сортируются: сначала без ошибки media_check, затем по overall_rating по убыванию, затем по order поставщика, затем strnatcmp по file_id ↩

  114. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c031 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Подпись файла на экране строится из caption поставщика функцией hack_file_caption: если caption кончается выражением в скобках, остаётся только текст в последних скобках, а «A/B» в нём превращается в «A [B]»; перед подписью ставятся параметры из media_check (разрешение, битрейт, длительность) ↩

  115. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c026 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · OnlineFilesScreen::update_good_files вызывает Suppliers::get_stream_url_by_file_id без try/catch, а get_stream_url_by_file_id при любой ошибке (null, error, нет url, недопустимый url) бросает DuneException ↩

  116. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c027 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · При построении списка онлайн-файлов update_good_files для файла, у которого ещё нет cur_url_by_file_id[file_id], берёт url из file->stream_url, если он задан, иначе вызывает Suppliers::get_stream_url_by_file_id; она бросает DuneException, если ответа нет, в ответе есть error, нет url или url не прошёл preg_match('|^([a-z-_]*:/)?/|'). Вызов не обёрнут try/catch, поэтому ошибка хотя бы для одного такого файла прерывает построение всего списка онлайн-файлов (исключение перехватывает default_dune_plugin_fw::invoke_operation и возвращает is_error с error_action), а не только убирает этот файл ↩

  117. fw-tv188b-261021-0117-r25.c188 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 у поставщика kbp5_stream (playback_type stream) сразу после ответа do_file_search серии — в пределах 0,12 с, без выбора пользователя — оболочка по очереди вызвала get_stream_url для файлов без url: сначала f1, затем f2_err. ↩

  118. fw-tv188b-261021-0117-r25.c192 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 url вида http://… из ответа get_stream_url оболочка принимает и использует без изменений: «get_stream_url() result: http://127.0.0.1/plugins/test_plugin5/kbp5-no-media.mp4». ↩

  119. fw-tv188b-261021-0117-r25.c191 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 ответ get_stream_url {"error":{"message":M}} для второго файла (f2_err) при построении списка kbp5_stream даёт в shell_ext.log «Supplier failed to provide stream, reason: M» и в ту же миллисекунду «Error: DuneException caught: Error getting stream url, reason: M». ↩↩

  120. fw-tv188b-261021-0117-r25.c189 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 media_check пишет журнал проверки в /tmp/run/__media_check.log: в /tmp/run/kbp5_stream__media_check.log записан один запуск (13:42:42) с URL http://127.0.0.1/plugins/test_plugin5/kbp5-no-media.mp4, который get_stream_url вернул для f1. ↩

  121. fw-tv188b-261021-0117-r25.c190 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 shell_ext/bin/media_check вызывает /firmware/scripts/ffmpeg.sh, а такого файла на устройстве нет: «media_check: line 27: /firmware/scripts/ffmpeg.sh: No such file or directory», «ffmpeg finished with status 1». ↩

  122. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c048 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · stream_special без файлов: если в error ответа do_file_search есть action с handler_string_id, оболочка возвращает это GUI-действие; иначе показывает error.message, а без него — title_content_is_unavailable ↩↩

  123. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c049 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · stream_special выбирает файл с минимальным count($file->path) (комментарий «FIXME: temporarily workaround for dune-hd.tv records»), где path — это caption поставщика, и вызывает get_play_movie_action(online) без cur_stream_url ↩

  124. fw-tv188b-261021-0117-r25.c193 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 поставщик kbp5_special (playback_type stream_special) вернул в do_file_search серии два файла — s1 (order 1, подпись «KBP5 special first long caption (s1)») и s2 (order 2, подпись «S2»); через 0,3 с без выбора пользователя оболочка вызвала get_stream_url с fileId s1 — первым по order, хотя его подпись длиннее. ↩↩

  125. fw-tv188b-261021-0117-r25.c194 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 stream_special не использует url файла из ответа do_file_search: у s1 был url http://kbp5.invalid/not-used-s1, но оболочка запросила URL через get_stream_url и взяла его результат, а в url элемента stream_url пустой, file_id s1. ↩↩

  126. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c044 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ответ get_stream_url: null (сбой команды) — исключение «Error getting stream url»; объект error — error.message в лог и исключение; нет url — «The 'url' is missing…»; пользователь во всех случаях видит errmsg_failed_to_start_playback ↩↩

  127. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c045 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · URL из get_stream_url должен соответствовать регулярному выражению |^([a-z-_]*:/)?/|, иначе исключение «The 'url' is invalid in supplier get_stream_url response»; при успехе возвращается url как есть ↩↩

  128. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c037 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Внутренний playback_url поставщика — JSON с ключами movie_id, s, e, ass_type, sup_id, is_current, file_id, stream_url (Suppliers::pack_playback_url); unpack_playback_url — json_decode ↩

  129. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c038 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · MainVod::pack_playback_url дописывает к JSON «:», для видеотеки — «:movies» (MyCollectionVod::ID); MainVod::get_vod_stream_url отрезает id по последнему «:» и передаёт остаток дочернему VOD, а MyCollectionVod::get_vod_stream_url вызывает Suppliers::get_stream_url ↩

  130. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c039 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Серии VOD-описания поставщика добавляются с playback_url_is_stream_url = false; VOD-описание задаёт buffering_ms = 3000 и keep_playing_on_reenter = true ↩↩

    • doc-sdk-plugins--operations.c111 · doc · any-documented; прошивка — · PluginVodSeriesInfo::playback_url_is_stream_url: true — playback URL используется как stream URL; false — get_vod_stream_url() вызывается каждый раз, когда нужен stream URL
    • doc-sdk-plugins--operations.c116 · doc · any-documented; прошивка — · get_vod_stream_url() вызывается при каждом старте или возобновлении воспроизведения, если series[ndx]->playback_url_is_stream_url = false; параметром передаётся series[ndx]->playback_url

    ↩

  131. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c040 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Suppliers::get_stream_url: если is_current != 0 и stream_url в playback_url не пуст, возвращается этот URL без вызова поставщика; при неразбираемом playback_url — исключение «Internal error, code 11:06» ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c040 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Suppliers::get_stream_url: если is_current != 0 и stream_url в playback_url не пуст, возвращается этот URL без вызова поставщика; при неразбираемом playback_url — исключение «Internal error, code 11:06»
    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c043 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Команда get_stream_url вызывается как « get_stream_url» с {fileId}; её вход и выход всегда пишутся в лог оболочки (DEBUG input/output), независимо от /tmp/suppliers_debug

    ↩

  132. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c041 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Для не текущего эпизода (is_current == 0, следующая серия в плеере) оболочка заново ищет файлы этого s/e через do_file_search с fileId выбранного ранее файла, при пустом списке бросает «Empty file list», берёт первый файл списка и возвращает его url, а без url — вызывает get_stream_url с его id ↩

  133. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c034 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Suppliers::get_vod_info ищет выбранный файл по id в кэше файлов эпизода; не нашёл — «The video-file not found» и ошибка title_files_not_found; для фильма single или трейлера/бонуса VOD-описание содержит одну серию с id "-1" и playback_url (is_current = 1, file_id, stream_url = переданный URL) ↩

  134. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c035 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Для серии сериала VOD-описание содержит по серии на каждый эпизод выбранного сезона из ответа get_episodes; у текущего эпизода is_current = "1" и stream_url = переданный URL, у остальных is_current = "0", пустой stream_url и тот же file_id, что у выбранного файла ↩

  135. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c052 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Трейлеры (ass_type 1) и доп. материалы (2) собираются со всех поставщиков фильма этого типа: каждому — do_file_search только с movieInfo (без season/episode); null и error пропускаются, файлам нужен id и caption, к каждому дописывается sup_id; результат кэшируется на фильм ↩

  136. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c053 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Для трейлеров и доп. материалов ответ do_file_search со status, отличным от done, целиком игнорируется («lazy loading not supported yet»): поставщик должен отвечать сразу со status done ↩↩

  137. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c054 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Suppliers::get_non_video_files отдаёт экрану по каждому трейлеру caption, icon (необязательно), file_id, sup_id, ass_type; поле url поставщика сюда не переносится ↩↩

  138. fw-tv188b-261021-0117-r25.c054 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 suppliers.php впервые читает ключ описателя поставщика fixed_trailer_files (сам ключ был и в r24 — в описателе rutube): для трейлеров (ass_type 1) Suppliers берёт этот массив вместо запроса поиска файлов; не массив — пустой список ↩↩↩

  139. fw-tv188b-261021-0117-r25--movie-suppliers.c005 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 фиксированные трейлеры проходят общий отбор файлов: элемент без непустого id или без caption пропускается, принятому элементу добавляется sup_id. ↩

  140. fw-tv188b-261021-0117-r25.c187 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 в одном цикле запросов по фильму поставщики kbp5 с supported_video_types video|trailer получили do_file_search с videoType trailer, а YouTube (video|trailer|add_material) — с videoType trailer и bonus; среди сохранённых входов kbp5 шага sup-play videoType bonus нет. ↩

  141. fw-tv188b-261021-0117-r25.c195 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 трейлер t1, который kbp5_special и kbp5_stream вернули в do_file_search (videoType trailer) сразу со status done, оболочка включила в список трейлеров фильма: в parent_sel_state кнопки trailers есть item_id online:kbp5_special:t1:::KBP5 trailer и online:kbp5_stream:t1:::KBP5 trailer. ↩

  142. fw-tv188b-261021-0117-r25.c196 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при запуске трейлера t1, у которого в ответе do_file_search есть url, оболочка вызывает get_stream_url {"fileId":"t1"} и берёт его результат — и у kbp5_stream (stream), и у kbp5_special (stream_special); в url элемента stream_url пустой. ↩↩

  143. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c060 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В params действия play_action оболочка кладёт supplier_id, season, episode, callback_action (закодированное действие shell_ext play_online с ignore_play_action), series_type (series/single), publications (MediaURL::encode публикаций), supplier_info (если есть), lang, region и movie_str ↩↩↩

  144. fw-tv188b-260827-0003-r24--shell-ext.c060 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · MainEntryHandler: при наличии user_input->pf_error возвращает ActionFactory::fatal_error(); pf_checked читается из user_input только не на Android (на Android считается true) ↩

  145. fw-tv188b-260827-0003-r24--movie-suppliers.c046 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Успешный ответ start_playback_app: bin (команда запуска), package, wait_app_start_delay, title; приложение ищется по package, не найдено — ошибка; запуск через ActionFactory::launch_ext_app ↩

  146. fw-tv188b-260827-0003-r24--php-framework.c193 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · dune_api.php определяет класс LaunchExtAppActionData с ключами (8): cmd, ensure_playback_stopped, delay, package, version, msg_toast, params, error_action ↩

  147. fw-tv188b-260827-0003-r24--movie-suppliers.c047 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Если в ответе start_playback_app есть first_start_dialog.title, оболочка один раз (cookie _first_dialog_shown) показывает диалог с title и messages перед запуском ↩

  148. fw-tv188b-260827-0003-r24--movie-suppliers.c045 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ответ start_playback_app с error.missing_app (title, package, непустой urls; необязательно indirect, intro_dialog_urls) и !$repeat превращается в действие «скачать и установить приложение»; иначе показывается error.message, а если его нет — errmsg_failed_to_start_playback ↩↩↩↩

  149. fw-tv188b-260827-0003-r24--shell-ext--entry-handler.c038 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ветка confirm_install_app выбирает install_from_market при is_limited_apk(), иначе download_and_install_apk с JSON-декодированными app_urls и app_intro_dialog_urls. ↩↩

  150. fw-tv188b-260827-0003-r24--shell-ext--entry-handler.c095 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · При repeat и action_status=1 launch_playback_app проверяет наличие установленного пакета до 10 итераций с паузой 500000 мкс, иначе возвращает ошибку установки. ↩

  151. fw-tv188b-261021-0117-r25--app-launch.c004 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · При успешном ответе start_playback_app (r25) shell_ext ищет приложение get_app_by_package_name(package), затем find_app_by_old_package; не нашёл — показывает ошибку errmsg_failed_to_start_playback и ничего не запускает. ↩

  152. fw-tv188b-261021-0117-r25--app-launch.c006 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Перед запуском shell_ext r25 пропускает bin поставщика через finalize_launch_cmd(cmd, package_name, src) и возвращает launch_ext_app с ensure_playback_stopped=true, delay=wait_app_start_delay (по умолчанию -1), package из ответа и error_action — показ errmsg_failed_to_start_playback. ↩↩

  153. fw-tv188b-261021-0117-r25--app-launch.c012 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · finalize_launch_cmd (r25) меняет команду только при dual_system, src=atv, непустом пакете и начале «am start »: убирает « 2>&1» и одинарные кавычки и строит am start -n com.dunehd.app/com.dunehd.shell.HdmiInputActivity --ez atv true --es package "<пакет>" --es intent "<остаток>"; иначе возвращает cmd без изменений. ↩

  154. fw-tv188b-261021-0117-r25--app-launch.c003 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · ActionFactory::launch_ext_app в shell_ext (r25) принимает шесть параметров (cmd, ensure_playback_stopped, delay, package, msg_toast, error_action) и всегда кладёт все шесть ключей в данные действия; version и params в этой версии не передаются. ↩

  155. fw-tv188b-261021-0117-r25.c134 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 строки bin ответа start_playback_app «am start -n /», «am start --activity-clear-task -n /» и «am start 'intent:#Intent;component=/;end'» запустили указанную activity (com.android.tv.settings/.MainSettings): «activity launch status: 0», в logcat START и Displayed, на экране открылись настройки Android. ↩↩

  156. fw-tv188b-261021-0117-r25.c135 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 строку «am start 'intent:#Intent;component=/;end'» оболочка передала apk_helper одним аргументом (args(1), без кавычек), и ActivityManager запустил activity с act=android.intent.action.VIEW и cmp=/. ↩

  157. fw-tv188b-261021-0117-r25.c138 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 строка bin «am start -p 'com.android.tv.settings' -a android.intent.action.MAIN -c android.intent.category.LEANBACK_LAUNCHER» не открыла приложение: в logcat записан START {act=MAIN cat=[LEANBACK_LAUNCHER] pkg=com.android.tv.settings}, но «activity launch status: -1». ↩

  158. fw-tv188b-261021-0117-r25.c137 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при «activity launch status: -1» действие launch_ext_app из ответа start_playback_app выполнило свой error_action: сразу за этим в shell.log «running gui show_error(0, Не удалось запустить воспроизведение)», на экране это сообщение, приложение не открылось. ↩↩↩

  159. fw-tv188b-261021-0117-r25.c133 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 ответ start_playback_app с package несуществующего приложения (kb.probe6.nonexistent) дал в shell_ext.log «sup E: app not found for package: …», после чего оболочка выполнила plugin_show_error с «Не удалось запустить воспроизведение» и показала это сообщение; launch_ext_app не выполнялось. ↩

  160. fw-tv188b-261021-0117-r25.c139 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 ответ start_playback_app без ключа wait_app_start_delay дал действие launch_ext_app с «delay -1», а ответы с wait_app_start_delay 10 и 5 — delay 10 и 5; во всех случаях ensure_playback_stopped 1. ↩

  161. fw-tv188b-261021-0117-r25.c132 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 error.message ответа start_playback_app длиной 409 символов оболочка передала в show_error целиком, а диалог на экране показал его одной строкой, сокращённой посередине многоточием: видны начало («[000]-…») и конец («…[400] END»), отдельного заголовка нет. ↩↩↩

  162. fw-tv188b-261021-0117-r25.c141 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 error.message ответа start_playback_app «%tr%errmsg_failed_to_start_playback» показан переведённым: в shell_ext.log строка ещё «Supplier returned error: %tr%errmsg_failed_to_start_playback», а в shell.log show_error и на экране — «Не удалось запустить воспроизведение». ↩↩↩

  163. fw-tv188b-261021-0117-r25.c136 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 строку «am start …» действия launch_ext_app приложение разбирает само, без запуска am или sh: apk_helper делит её на список аргументов (одинарные кавычки снимаются: «-p 'com.android.tv.settings' -a … -c …» → args(6) «-p, com.android.tv.settings, -a, …»), и activity стартует AndroidJavaUtils в процессе приложения com.dunehd.app. ↩↩

  164. fw-tv188b-261021-0117-r25--app-launch.c022 · code · tv188b, android-dune-fw, android-atv; прошивка 261021_0117_r25, 260827_0003_r24, 260724_0207_r24 · Таблица строк classes.dex dune.apk r25 содержит имена опций am start — -a, -c, -d, -e, -f, -n, -p, -t, -D, -P, -R, -S, -W, --es, --esn, --ei, --eia, --el, --ela, --eu, --ez, --selector, --start-profiler, --grant-read/write-uri-permission, --exclude/include-stopped-packages, --debug-log-resolution, --receiver-registered-only, --receiver-replace-pending и 15 флагов --activity-*, — и сообщения «Error: Unknown option: », «No intent supplied», «Error making intent: %s», «Failed to create intent from args.», «Start activity from args: %s». В r24 и APK DMC набор этих строк тот же. ↩

  165. fw-tv188b-261021-0117-r25--app-launch.c023 · code · tv188b, android-dune-fw, android-atv; прошивка 261021_0117_r25, 260827_0003_r24, 260724_0207_r24 · Строки «--user» в таблице строк classes.dex нет ни в dune.apk tv188b r25 и r24, ни в APK DMC. ↩

  166. fw-tv188b-261021-0117-r25--app-launch.c018 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25, 260827_0003_r24 · dune.apk tv188b (r24 и r25) — пакет com.dunehd.app с android:sharedUserId="android.uid.system". ↩↩

  167. fw-tv188b-261021-0117-r25--app-launch.c019 · code · tv188b, android-atv; прошивка 260724_0207_r24 · APK DMC 260724_0207_r24 — тот же пакет com.dunehd.app, но в атрибутах нет android:sharedUserId. ↩↩

  168. fw-tv188b-261021-0117-r25--app-launch.c072 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В tv188b r25 нативный обработчик launch_ext_app (fcn.00560ee8 libduneshell.so), если ветка остановки воспроизведения не вернула управление раньше, для cmd, в которой есть непробельный символ, сравнивает начало cmd с «/system/dunehd/dunehd_service» (strncmp на 0x1d символов, ведущие пробелы не пропускаются): при совпадении печатает «gui_action D: run command '%s'» и передаёт cmd помощнику fcn.00560d20 (popen), иначе печатает «gui_action D: launch activity for command '%s'» и передаёт cmd разборщику apk_helper fcn.006f2b60; если помощник вернул −1, cmd дополнительно уходит в ветку launch activity. ↩↩

  169. fw-tv188b-261021-0117-r25--app-launch.c030 · code · android-atv; прошивка 260724_0207_r24 · В APK DMC обработчик launch_ext_app (fcn.0055bc50, печатает «[gui_action] cmd '%s', ensure_playback_stopped %d, delay: %d») при непустой cmd с непробельным символом печатает «gui_action D: launch activity for command '%s'» и передаёт cmd целиком разборщику apk_helper (fcn.006e5630); ветки «run command», вызова popen или system в функции нет — shell-команды через launch_ext_app в DMC не выполняются. ↩↩

  170. fw-tv188b-261021-0117-r25--app-launch--native.c002 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · На этапе обработки cmd в tv188b r24 обработчик launch_ext_app fcn.0054a368 при наличии непробельного символа в cmd сравнивает первые 0x1d байт исходной cmd с «/system/dunehd/dunehd_service»: совпадение направляет cmd в fcn.0054a1a0, иначе — в apk_helper fcn.006d4c9c; ведущие пробелы перед путём при этом сравнении не пропускаются. ↩

  171. fw-tv188b-261021-0117-r25--app-launch.c059 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В tv188b r25 обработчик launch_ext_app fcn.00560ee8 при cmd = NULL, пустой или только из пробельных символов ни apk_helper, ни fcn.00560d20 не вызывает и сразу переходит к ожиданию потери фокуса fcn.00560a58 — той же ветке, что при нулевом статусе запуска (c058). ↩

  172. fw-tv188b-261021-0117-r25--app-launch.c043 · code · android-atv; прошивка 260724_0207_r24 · В APK DMC обработчик launch_ext_app (fcn.0055bc50) при cmd = NULL, пустой или только из пробельных символов apk_helper не вызывает и сразу переходит к ожиданию потери фокуса оболочкой (fcn.0055b7c0) — той же ветке, что после успешного запуска (c038). ↩

  173. fw-tv188b-261021-0117-r25--app-launch--native.c003 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · На этапе обработки cmd в tv188b r24 обработчик fcn.0054a368 при cmd = NULL, пустой cmd или cmd только из пробельных символов переходит к ожиданию потери фокуса fcn.00549ed8 без вызова apk_helper и popen-помощника. ↩

  174. fw-tv188b-261021-0117-r25--app-launch.c060 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Разборщик apk_helper в tv188b r25 (fcn.006f2b60) сравнивает результат fcn.006f2648(cmd) с «am start » (strncmp на 9 символов; иначе «[apk_helper] unsupported command (1): %s» и -1), делит остаток по пробелам, снимает кавычки '…' и "…" (внутри "…" обратная косая только пропускает следующий символ и остаётся в аргументе; незакрытая кавычка берёт остаток строки), выбрасывает пустые и пробельные аргументы и аргументы, начинающиеся с «>» или «2>»; пустой список даёт «[apk_helper] unsupported command (2): %s» и -1. ↩

  175. fw-tv188b-261021-0117-r25--app-launch.c031 · code · android-atv; прошивка 260724_0207_r24 · Разборщик apk_helper в APK DMC (fcn.006e5630) пропускает пробельные символы в начале cmd, требует префикс «am start » (strncmp на 9 символов, иначе «[apk_helper] unsupported command (1): %s» и -1), делит остаток по пробелам, снимает кавычки '…' и "…" (внутри "…" обратная косая только пропускает следующий символ и остаётся в аргументе; незакрытая кавычка берёт остаток строки), выбрасывает пустые аргументы и аргументы, начинающиеся с «>» или «2>» (поэтому хвост « 2>&1» безвреден); пустой список даёт «[apk_helper] unsupported command (2): %s» и -1. ↩

  176. fw-tv188b-261021-0117-r25--app-launch.c064 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Помощник fcn.006f2648, которым apk_helper tv188b r25 (fcn.006f2b60) обрабатывает cmd перед проверкой «am start » и каждый остаток строки, пропускает ведущие ненулевые байты, для которых isspace возвращает ненулевое значение, и возвращает указатель на первый иной байт или конец строки; проверка префикса и разбор остатка идут по этой строке, поэтому ведущие пробелы cmd не мешают. ↩

  177. fw-tv188b-261021-0117-r25--app-launch.c061 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · apk_helper в tv188b r25 (fcn.006f2b60) при непустом списке аргументов печатает «[apk_helper] Starting activity from args(%d): %s» и вызывает fcn.00094884 — JNI-вызов Java-метода startActivityFromArgs с сигнатурой ([Ljava/lang/String;)Z (функция android_java_utils_start_activity_from_args); результат false → «[apk_helper] jni returned error status» и статус -1, true → 0. ↩

  178. fw-tv188b-261021-0117-r25--app-launch.c044 · code · android-atv; прошивка 260724_0207_r24 · apk_helper в APK DMC (fcn.006e5630) при непустом списке аргументов печатает «[apk_helper] Starting activity from args(%d): %s» и вызывает fcn.00092710 — JNI-вызов Java-метода startActivityFromArgs с сигнатурой ([Ljava/lang/String;)Z (функция android_java_utils_start_activity_from_args); результат false → «[apk_helper] jni returned error status» и статус -1, true → 0. ↩

  179. fw-tv188b-261021-0117-r25--app-launch.c045 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В tv188b r25 функции libduneshell.so fcn.006f2b60 (apk_helper), fcn.00094884 (JNI startActivityFromArgs), fcn.00560a58 (ожидание фокуса), fcn.00560d20 и fcn.005605f4 (popen-помощники) совпадают с fcn.006e5630, fcn.00092710, fcn.0055b7c0, fcn.0055ba88 и fcn.0055b35c APK DMC по размеру и последовательности инструкций (без учёта адресов; в JNI различается путь исходника в __assert2), а обработчик launch_ext_app fcn.00560ee8 (580 байт) отличается от fcn.0055bc50 DMC (492 байта) веткой dunehd_service (c072, c057). ↩

    • fw-tv188b-261021-0117-r25--app-launch--native.c007 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 apk_helper fcn.006d4c9c пропускает ведущие пробельные байты помощником fcn.006d4784 с isspace и требует префикс «am start » (strncmp на 9 байт); при несовпадении пишет «unsupported command (1)» и возвращает -1.
    • fw-tv188b-261021-0117-r25--app-launch--native.c008 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 apk_helper fcn.006d4c9c ищет разделитель некавыченных аргументов после «am start » как байт 0x20 и снимает парные одинарные либо двойные кавычки; внутри двойных кавычек обратная косая увеличивает шаг сканирования до 2, но сохраняется в передаваемом сегменте; при незакрытой кавычке берётся остаток строки.
    • fw-tv188b-261021-0117-r25--app-launch--native.c009 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 apk_helper fcn.006d4c9c не добавляет в список пустые и пробельные сегменты, а также сегменты, начинающиеся с «>» или «2>»; при пустом итоговом списке пишет «unsupported command (2)» и возвращает -1.

    ↩

  180. fw-tv188b-261021-0117-r25--app-launch--native.c010 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 apk_helper fcn.006d4c9c при непустом списке аргументов вызывает JNI-помощник fcn.00091b04, обращающийся к startActivityFromArgs с сигнатурой ([Ljava/lang/String;)Z; false даёт сообщение «jni returned error status» и статус -1, true — статус 0. ↩

    • fw-tv188b-261021-0117-r25--app-launch.c073 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Разбор опций IntentBuilder.doMakeIntent (dune.apk tv188b r25 и APK DMC) устроен так: понимает опции -a, -d, -t, -c, -p, -e/--es, --esn, --ei, --eu, --eia, --el, --ela, --ez, -n, -f, --grant-read/write-uri-permission, --exclude/include-stopped-packages, --debug-log-resolution, 15 --activity-*, --receiver-registered-only, --receiver-replace-pending, --selector; -D, -W и -S пропускает, -P, --start-profiler и -R съедают следующий аргумент; любая другая опция (в т. ч. --user) — IllegalArgumentException «Error: Unknown option: <опция>»; makeIntent ловит исключение, пишет «Error making intent: %s» (тег ApkHelper) и возвращает null, а startActivityFromArgs пишет «Failed to create intent from args.» и возвращает false.
    • fw-tv188b-261021-0117-r25--app-launch.c070 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 launch_ext_app с cmd «am start --user 0 -n …» ушёл в apk_helper, тот вернул «Unknown option: --user» и activity launch status −1; выполнился error_action (диалог «KB9 error_action»).

    ↩

  181. fw-tv188b-261021-0117-r25--app-launch.c047 · code · tv188b, android-dune-fw, android-atv; прошивка 261021_0117_r25, 260724_0207_r24 · IntentBuilder (dune.apk tv188b r25 и APK DMC) читает опции, пока очередной аргумент начинается с «-»; «--» завершает опции; короткая опция длиннее двух символов делится — «-nX» значит «-n X»; первый аргумент не с «-» — позиционный, после него doMakeIntent аргументов больше не читает (опции и прочее после позиционного молча игнорируются, ошибки нет). ↩

  182. fw-tv188b-261021-0117-r25--app-launch.c034 · code · tv188b, android-dune-fw, android-atv; прошивка 261021_0117_r25, 260724_0207_r24 · После опций IntentBuilder (dune.apk tv188b r25 и APK DMC) читает один позиционный аргумент — есть «:» → Intent.parseUri(arg, 1); есть «/» → new Intent("android.intent.action.MAIN") с категорией android.intent.category.LAUNCHER и компонентом ComponentName.unflattenFromString(arg); иначе → то же MAIN/LAUNCHER с setPackage(arg). Без позиционного аргумента intent собирается только из опций (с --selector — с базой MAIN/LAUNCHER), а если ни одна из -a, -d, -t, -c, -p, -n не задана для основного intent — IllegalArgumentException «No intent supplied». ↩

  183. fw-tv188b-261021-0117-r25--app-launch.c050 · code · tv188b, android-dune-fw, android-atv; прошивка 261021_0117_r25, 260724_0207_r24 · IntentBuilder (dune.apk tv188b r25 и APK DMC) сливает intent из опций с позиционным так — если опциями задан action (-a), категории позиционного intent (MAIN/LAUNCHER из форм «пакет» и «пакет/класс») удаляются; затем intentИзОпций.fillIn(позиционный, 72); extras — extras позиционного, поверх которых кладутся extras из опций (putAll, совпадающий ключ берётся из опций). Опции после --selector идут в отдельный intent, который ставится селектором основного (setSelector). ↩

  184. fw-tv188b-261021-0117-r25--app-launch.c046 · code · tv188b, android-dune-fw, android-atv; прошивка 261021_0117_r25, 260724_0207_r24 · Флаги intent в IntentBuilder (dune.apk tv188b r25 и APK DMC) — addFlags: --grant-read-uri-permission 0x1, --grant-write-uri-permission 0x2, --debug-log-resolution 0x8, --exclude-stopped-packages 0x10, --include-stopped-packages 0x20, --activity-task-on-home 0x4000, --activity-clear-task 0x8000, --activity-no-animation 0x10000, --activity-reorder-to-front 0x20000, --activity-no-user-action 0x40000, --activity-clear-when-task-reset 0x80000, --activity-launched-from-history 0x100000, --activity-reset-task-if-needed 0x200000, --activity-brought-to-front 0x400000, --activity-exclude-from-recents 0x800000, --activity-previous-is-top 0x1000000, --activity-clear-top 0x4000000, --activity-multiple-task 0x8000000, --activity-single-top и --receiver-replace-pending 0x20000000, --activity-no-history и --receiver-registered-only 0x40000000; -f <число> (Integer.decode, т. е. и 0x…) — setFlags, то есть заменяет все флаги, набранные до него. ↩

  185. fw-tv188b-261021-0117-r25--app-launch.c048 · code · tv188b, android-dune-fw, android-atv; прошивка 261021_0117_r25, 260724_0207_r24 · AndroidJavaUtils.startActivityFromArgs(String[]) (dune.apk tv188b r25 и APK DMC) пишет в лог «Start activity from args: %s» (аргументы через «, »), строит intent new IntentBuilder(args).makeIntent(); null → «Failed to create intent from args.» и false; иначе вызывает mainActivity.startActivity(intent) (метод NativeActivity) и возвращает true, а исключение ловит — «Failed to start activity: %s» и false. Флагов и полей intent сам метод не меняет. ↩

  186. fw-tv188b-261021-0117-r25--app-launch.c049 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 activity, запущенную через launch_ext_app (bin поставщика «am start -n …»), стартует процесс оболочки com.dunehd.app: в logcat «I/AndroidJavaUtils(): Start activity from args», а ActivityTaskManager пишет «START u0 {…} from uid 1000». ↩

  187. fw-tv188b-261021-0117-r25--app-launch.c058 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В tv188b r25 обработчик launch_ext_app fcn.00560ee8 при ненулевом статусе запуска (apk_helper или ветки dunehd_service) делает следующим действием результат fcn.001436dc(поле +0x1c данных действия) и, если он не пуст, ставит ему свойство command_status = статус; при нулевом статусе ждёт потери фокуса fcn.00560a58(поле +8 delay, …) (c062): результат 0 → следующее действие снова из поля +0x1c, иначе вызывается fcn.003cb390(поле +0xc, поле +0x10) и при непустом поле +0x14 показывается тост («[gui_action] show toast: '%s'»). ↩

  188. fw-tv188b-261021-0117-r25--app-launch.c062 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Ожидание потери фокуса fcn.00560a58(delay, метка) в tv188b r25 — если оболочка уже без фокуса, «%s: shell app is already lost focus» и результат 1; если delay < 1 — сразу «%s: wait for shell app loosing focus timed-out» и 0; иначе каждые 100 мс (usleep(100000)) проверяет фокус до delay секунд — потеря фокуса даёт «%s: shell app lost focus in %.2fs» и ненулевой результат, истечение срока — «timed-out» и 0. ↩↩

  189. fw-tv188b-261021-0117-r25--app-launch--native.c012 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 обработчик fcn.0054a368 при ненулевом статусе запуска записывает в выход следующего действия результат вызова помощника с полем +0x1c данных действия; если результат не NULL, задаёт ему свойство command_status, равное статусу запуска. ↩

  190. fw-tv188b-261021-0117-r25--app-launch--native.c013 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 обработчик fcn.0054a368 при нулевом статусе запуска либо пустой/пробельной cmd вызывает ожидание фокуса fcn.00549ed8 с полем +8 (delay): при результате 0 следующим действием становится результат помощника с полем +0x1c; при ненулевом результате вызывается помощник с полями +0xc/+0x10 и, если поле +0x14 не NULL, показывается тост. ↩

    • fw-tv188b-261021-0117-r25--app-launch.c038 · code · android-atv; прошивка 260724_0207_r24 · В APK DMC обработчик launch_ext_app (fcn.0055bc50) при ненулевом статусе apk_helper (в т. ч. -1) делает следующим действием копию действия из поля +0x1c данных действия и, если оно задано, ставит ему свойство command_status = статус; при нулевом статусе ждёт потери фокуса оболочкой — fcn.0055b7c0 с полем delay (+8, c053): результат 0 → следующее действие — снова из поля +0x1c, иначе вызывается fcn.003d0ec8(поле +0xc, поле +0x10) и при непустом поле +0x14 показывается тост («[gui_action] show toast: '%s'»). Какие это ключи LaunchExtAppActionData (error_action, package, version, msg_toast) — c055.
    • fw-tv188b-261021-0117-r25--app-launch.c053 · code · tv188b, android-atv; прошивка 260724_0207_r24 · Ожидание потери фокуса fcn.0055b7c0(delay, метка) в APK DMC — если оболочка уже без фокуса, «%s: shell app is already lost focus» и результат 1; если delay < 1 — сразу «%s: wait for shell app loosing focus timed-out» и 0; иначе каждые 100 мс (usleep(100000)) проверяет фокус до delay секунд — потеря фокуса даёт «%s: shell app lost focus in %.2fs» и ненулевой результат, истечение срока — «timed-out» и 0.

    ↩

    • fw-tv188b-261021-0117-r25--app-launch.c074 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В tv188b r25 помощник fcn.00560d20 всегда исполняет cmd через fcn.005605f4: popen(cmd, "r"), вывод читается целиком, затем pclose; при сбое popen печатается «[gui_action] popen(%s) failed: %s» и в статус пишется 998, иначе туда пишется статус pclose. Если cmd не начинается с «am start» и не содержит « am start», при нулевом статусе pclose fcn.00560d20 разбирает и логирует последнюю непустую строку вывода и возвращает 0, а при ненулевом — возвращает статус pclose без разбора.
    • fw-tv188b-261021-0117-r25--app-launch.c075 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В tv188b r25 fcn.00560d20 считает cmd «am start»-командой, если она начинается с «am start» (strncmp 8 символов) или содержит « am start» (strstr); при успешном popen для такой cmd статус pclose не учитывается: если последняя непустая строка вывода после разбора токенов и strip длиннее 4 символов и начинается с «Error», возвращается 999, иначе 0. При сбое popen возвращается 998; для cmd без этих условий при успешном popen возвращается статус pclose.

    ↩↩

  191. fw-tv188b-261021-0117-r25--app-launch.c057 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В tv188b r25 обработчик launch_ext_app fcn.00560ee8 после ветки dunehd_service при статусе -1 от fcn.00560d20 передаёт ту же cmd в apk_helper (печатает «gui_action D: launch activity for command '%s'», fcn.006f2b60) и дальше использует его статус; любой другой статус fcn.00560d20 (0, 998, 999, статус pclose) сразу идёт в общую обработку статуса запуска (c058). ↩

  192. fw-tv188b-261021-0117-r25--app-launch--native.c005 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 fcn.00549a70 вызывает popen(cmd, "r"), накапливает прочитанный вывод до EOF либо ошибки select и записывает статус pclose; если popen вернул NULL, записывает статус 998. ↩

  193. fw-tv188b-261021-0117-r25--app-launch--native.c006 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 fcn.0054a1a0 для cmd с началом «am start» (8 байт) или подстрокой « am start» при успешном popen возвращает 999, если последний непустой сегмент str_next_token после str_seg_strip длиннее 4 байт и начинается с «Error», иначе 0 независимо от статуса pclose; для остальных cmd возвращает статус pclose, а при сбое popen — 998. ↩

  194. fw-tv188b-261021-0117-r25--app-launch--native.c004 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 обработчик fcn.0054a368 после ветки dunehd_service повторно передаёт исходную cmd в apk_helper только при статусе -1 от fcn.0054a1a0; прочие статусы идут в общую обработку результата запуска. ↩

  195. fw-tv188b-261021-0117-r25--app-launch.c077 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при проверке на устройстве launch_ext_app с delay 0 (am start настроек) дал «activity launch status: 0», через 4,968 мс — «general: wait for shell app loosing focus timed-out»; настройки открылись (Displayed +123ms), и поверх них выполнился error_action действия — диалог «KB7 error_action / delay=0». ↩↩

    • fw-tv188b-261021-0117-r25--app-launch.c079 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при проверке на устройстве launch_ext_app с delay −1 (am start настроек) дал activity launch status 0, через 3,419 мс — «general: shell app is already lost focus»; настройки открылись (resumed MainSettings), error_action не выполнялся.
    • fw-tv188b-261021-0117-r25--app-launch.c080 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при проверке на устройстве launch_ext_app с delay 10 (am start настроек) дал activity launch status 0, через 5,243 мс — «general: shell app is already lost focus»; настройки открылись (Displayed +105ms), error_action не выполнялся.

    ↩

  196. fw-tv188b-261021-0117-r25--app-launch.c078 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при проверке на устройстве в серии из четырёх запусков launch_ext_app с delay 0 все дали «activity launch status: 0», но ровно один (n=5) — через 1,488 мс «wait for shell app loosing focus timed-out» и show_error KB9 error_action; в остальных трёх — «already lost focus». В n=5 настройки открылись (Displayed +129ms). ↩↩

  197. fw-tv188b-261021-0117-r25--app-launch.c081 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при проверке на устройстве все четыре запуска launch_ext_app с delay −1 в серии дали activity launch status 0 и «general: shell app is already lost focus», строк show_error не было; у n=2 интервал от статуса до сообщения — 6,953 мс, поэтому исторические 3–5 мс из req7 не являются постоянной границей. ↩↩

  198. fw-tv188b-260827-0003-r24--movie-suppliers.c061 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Нет пакета — generic отвечает error.missing_app (indirect true, urls http://online.dune-hd.com/apk/generic/.txt); иначе {bin, package, wait_app_start_delay 10, title, indirect true, urls} ↩↩

  199. fw-tv188b-261021-0117-r25--app-launch.c067 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 в серии из восьми launch_ext_app (по четыре с delay 0 и −1) «activity launch status» был 0 во всех восьми; «timed-out» — только в одном запуске (n=5, delay 0), в остальных семи — «already lost focus». ↩↩↩

  200. fw-tv188b-261021-0117-r25--app-launch.c068 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 launch_ext_app с cmd «/system/dunehd/dunehd_service do am start -n com.kb9.none/.Nope» пошёл в ветку «run command»: pclose вернул 0, command status — 0; ActivityTaskManager зафиксировал START несуществующего компонента. ↩

  201. fw-tv188b-261021-0117-r25--app-launch.c069 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 launch_ext_app с cmd «/system/dunehd/dunehd_service do am start --user 0 -n com.android.tv.settings/com.android.tv.settings.MainSettings» открыл настройки: command status 0, ActivityTaskManager — START from uid 0, Displayed +105ms. ↩↩

  202. fw-tv188b-261021-0117-r25--app-launch.c070 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 launch_ext_app с cmd «am start --user 0 -n …» ушёл в apk_helper, тот вернул «Unknown option: --user» и activity launch status −1; выполнился error_action (диалог «KB9 error_action»). ↩

  203. fw-tv188b-261021-0117-r25--app-launch.c041 · code · tv188b, android-dune-fw, android-atv; прошивка 261021_0117_r25, 260724_0207_r24 · ApplicationDataUpdater (dune.apk tv188b r25 и APK DMC) строит список приложений по PackageManager.getInstalledPackages(192): activity пакета — класс компонента getLeanbackLaunchIntentForPackage, а если его нет — getLaunchIntentForPackage (при SDK_INT ≥ 21; для com.google.android.tvlauncher — всегда com.google.android.tvlauncher.MainActivity); пакет с пустой activity в список не попадает (packageInfoToAppJson возвращает null); иконка сохраняется PNG в /icon_<пакет>.png (r25 — /tmp/applications/icon_cache, DMC — /flashdata/applications/icon_cache), её путь — поле icon, класс — поле activity; корень JSON — applications и generation_date. ↩

  204. fw-tv188b-261021-0117-r25--app-launch.c056 · code · tv188b, android-dune-fw, android-atv; прошивка 261021_0117_r25, 260724_0207_r24 · ApplicationDataUpdater.saveAppDataJson (dune.apk tv188b r25) пишет /tmp/applications/app_data.json и /tmp/applications/app_data.json.md5 (MD5 текста JSON до ключа "generation_date") только если MD5 изменился или изменилась какая-то иконка, и после записи кладёт «1» в /tmp/plugins/android_apps/update_epfs_if_needed_flag; в APK DMC тот же метод ещё копирует оба файла в /flashdata/applications/ (FS.copyUsingTmp). ↩

  205. fw-tv188b-261021-0117-r25--app-launch.c009 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Модель приложений (android_apps/model.php в shell_ext, r25) берёт список установленных приложений из /tmp/applications/app_data.json, а на системах с двумя ОС — ещё из /flashdata/applications/atv_app_data.json. ↩

  206. fw-tv188b-261021-0117-r25--app-launch.c011 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · icon_url приложения (r25) — file:// из app_data.json, если путь icon абсолютный; для src=atv — file:///flashdata/applications/atv_icon_cache/<имя файла>; без иконки — missing://; файл icons/.png в каталоге плагина заменяет её на plugin_file://icons/.png. ↩

  207. fw-tv188b-260827-0003-r24--movie-suppliers.c056 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · run.php generic понимает только команду start_playback_app; иная команда — {error:{message:"Internal error 02 ()"}}, пустой или не-JSON stdin — {error:{message:"Invalid data on standard input ()"}}; ответ — JSON в stdout, код выхода 0 ↩

  208. fw-tv188b-260827-0003-r24--movie-suppliers.c057 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · start_playback_app generic берёт sup_id и deeplink первой публикации movieInfo.publications ↩

  209. fw-tv188b-260827-0003-r24--movie-suppliers.c058 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · generic определяет пакет из deeplink (package=… или component=пакет/…); иначе по sup_id или домену ссылки: Ivi → ru.ivi.client, Kinopoisk → ru.kinopoisk.tv, Premier → gpm.tnt_premier, AppleTV → com.apple.atve.androidtv.appletv, FlixFling, HBOMax, Max, Joyn/JoynPlus, My5, Amazon ↩

  210. fw-tv188b-261021-0117-r25--app-launch.c008 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · generic r25 строит bin так же, как r24 — для deeplink с intent:…#Intent «am start ''», иначе «am start», затем « -p '<пакет>'» (если пакет известен) и « -d ''» (FS_PREFIX пуст и ссылка http…) либо позиционный « ''». ↩↩↩

  211. fw-tv188b-260827-0003-r24--movie-suppliers.c060 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Установленность пакета generic проверяет по $FS_PREFIX/tmp/applications/app_data.json, а при флаге dual_system в /tmp/firmware_features.txt — сначала по $FS_PREFIX/flashdata/applications/atv_app_data.json ↩↩

  212. fw-tv188b-260827-0003-r24--movie-suppliers.c067 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · rutube запускает «am start -d 'rutube://rutube.ru/search?query=<запрос>'» с пакетом ru.rutube.app; если пакета нет в app_data.json — error.missing_app с urls http://online.dune-hd.com/apk/rutube.txt ↩

  213. fw-tv188b-260827-0003-r24--movie-suppliers.c070 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · start_playback_app у youtube всегда возвращает ошибку «Illegal state Y03» ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c046 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Успешный ответ start_playback_app: bin (команда запуска), package, wait_app_start_delay, title; приложение ищется по package, не найдено — ошибка; запуск через ActionFactory::launch_ext_app
    • fw-tv188b-261021-0117-r25.c133 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 ответ start_playback_app с package несуществующего приложения (kb.probe6.nonexistent) дал в shell_ext.log «sup E: app not found for package: …», после чего оболочка выполнила plugin_show_error с «Не удалось запустить воспроизведение» и показала это сообщение; launch_ext_app не выполнялось.

    ↩

  214. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c019 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Если онлайн-список файлов фильма пуст («Zero number of files received»), оболочка показывает ошибку title_content_is_unavailable для поставщика stream_special и title_files_not_found для остальных ↩

  215. fw-tv188b-260827-0003-r24--shell-ext--entry-handler.c106 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · play_recent требует sup_id и movie_id; передаёт все входные поля wh_* в JSON sup_info для play_online; autoplay добавляет действие enter после открытия карточки. ↩

  216. fw-tv188b-260827-0003-r24--shell-ext--entry-handler.c167 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · play_recent явно читает wh_file_index (default=-1), wh_tags, wh_uid, wh_s, wh_e, wh_pos и wh_len до переноса всех wh_* в sup_info. ↩

    • fw-tv188b-260827-0003-r24--shell-ext--entry-handler.c103 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · find_recent принимает JSON uids/tags/eps и обязательные result_action/result_file; force_reload выбирает reload истории вместо ensure_loaded.
    • fw-tv188b-260827-0003-r24--shell-ext--entry-handler.c104 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · find_recent записывает в result_file JSON со словарями tags, uids и eps и возвращает result_action с action_status=1 при успешной записи или 0 при ошибке записи.

    ↩

  217. fw-tv188b-260827-0003-r24--php-framework.c255 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · dune_api.php определяет класс PluginVodSeriesInfo с ключами (7): name, playback_url, playback_url_is_stream_url, content_id, recent_uid, mdb_info, markers ↩

  218. fw-tv188b-260827-0003-r24--php-framework.c253 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · dune_api.php определяет класс PluginVodInfo с ключами (25): id, name, sub_name, description, poster_url, series, initial_series_ndx, initial_position_ms, buffering_ms, advert_mode, extra_menu_items, enter_menu_action, actions, timer, ip_address_required, valid_time_required, subtitles_osd_enabled, skip_dummy_player_on_error, keep_playing_on_reload, keep_playing_on_reenter, recent_plugin, recent_action_params, recent_group_by, recent_tags, params ↩

  219. 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. ↩

  220. fw-tv188b-261021-0117-r25.c040 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · shell_ext r25 добавляет public_actions home, update_movie_mark_after_file_mark (обработчик gui_common), favorite_movies, movies_by_url, movie_poster_changed, update_on_movie_change и update_on_recent_change (gui_common); clear_mc_indexing_results получил operation_timeout 300000 ↩

  221. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c044 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · WatchHistory r25 читает историю из файлов .json каталога /config/watch_history (естественный порядок имён), каждый — JSON-массив записей; записи с deleted=1 и неподходящие пропускаются, uid по умолчанию равен url, при e<0 ставится s=e=-1, при e>=0 без s или с s<0 — s=1. ↩

  222. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c046 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Запись истории с action_plugin и action_params r25 принимает всегда; без них нужна url со схемой, кроме tmpfs; file:// показывается только при истинном show_in_recent, а show_in_recent, если задан, решает и для прочих схем. ↩

  223. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c045 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · WatchHistory r25 хранит в памяти не более MAX_NUM_ITEMS=2000 записей: при превышении после добавления удаляются самые старые. ↩

  224. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c047 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · WatchHistory::whi_sup_id (r25) относит запись с uid-URL (схема по шаблону ^[a-z][a-z0-9_-]*://) к [local]; для прочих uid поставщик — часть до первого двоеточия, при отсутствии двоеточия или двоеточии в начале — null. ↩

  225. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c048 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · WatchHistory::get_movie_episode_items(movie_id) учитывает только записи с этим movie_id, чей whi_sup_id — [local] или id текущего поставщика, и для каждого ключа all и x берёт самую новую запись. ↩

  226. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c049 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · WatchHistory::with_progress требует len>0 и pos>=0; процент просмотра — round(pos*100/len). ↩

  227. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c060 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 диалог выбора воспроизведения строит для каждого поставщика (с дедупликацией по key_show_only_one) кнопку play_online с s, e, sup_id; только кнопке поставщика, чей id равен whi_sup_id последней записи истории, добавляется sup_info из get_wh_supplier_info. ↩↩

  228. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c062 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · make_base_button_defs (r25) берёт whi_sup_id записи по ключу all или x только при наличии прогресса (with_progress); без прогресса ни одна кнопка поставщика не получает sup_info и подписи «Продолжить». ↩

  229. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c063 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · MovieHelper::get_wh_supplier_info (r25) копирует action_params записи (или пустой объект), добавляет wh_uid, wh_s, wh_e (по умолчанию -1), wh_pos (-1), wh_len (0), wh_tags (JSON, если есть tags) и wh_file_index (если есть index) и возвращает JSON с sup_data и всеми wh_*-полями. ↩

  230. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c065 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Обработчик play_online/play_local MovieScreen r25 передаёт в do_get_play_action поле sup_info из user_input, а также ignore_play_action и play_default_directly; need_close_dialog (по умолчанию true) оборачивает результат в close_dialog_and_run. ↩

  231. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c064 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 MovieScreen для поставщика с play_action (без ignore_play_action) кладёт в params: supplier_id, season, episode, callback_action (play_online с ignore_play_action), series_type, publications и supplier_info, если sup_info передан (иначе удаляет ключ), а для online_dl — dl_context=1. ↩

  232. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c074 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В r24 диалог выбора воспроизведения давал кнопкам play_online поставщиков только s, e и sup_id, без sup_info; wh_* доходили до поставщика лишь через entry/play_recent. ↩↩

  233. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c061 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Для поставщика последней записи истории r25 формирует подпись кнопки «Продолжить» как T::t1(button_continue__1) от common_caption поставщика (по умолчанию caption), переведённой через tr2gilcf с plugin поставщика, и суффикс из get_play_action_suffix. ↩

  234. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c059 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · MovieHelper::get_play_action_suffix (r25) даёт подпись кнопки только если запись истории фильма по ключу all или x имеет прогресс и whi_sup_id равен поставщику кнопки; процент («NN%», без скобок) пишется лишь для не досмотренной записи, а для всего фильма с эпизодом подпись — «[S: E NN%]» или «[S: E]». ↩

  235. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c050 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · WatchHistory::is_fully_watched (r25) истинно для записи с прогрессом, если (без ignore_watched_map) её uid имеет действующую отметку в watched_files, либо одновременно до конца осталось не больше watched_secs_left секунд и процент не меньше watched_percent. ↩

  236. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c051 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Пороги «просмотрено» SystemConfig берёт из настроек auto_watched_percent и auto_watched_time_left; ConfigUtils r25 задаёт им значения по умолчанию 90% и 30s. ↩

  237. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c014 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 play_recent открывает карточку sup-фильма с флагом MOVIE_OPT_CONTINUE_MODE (и MOVIE_OPT_SINGLE_MODE при single_mode) и продолжением play_online с sup_info; при autoplay и play_default_directly сразу выполняет это продолжение, иначе — enter экрана фильма. ↩

  238. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c020 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 play_recent не читает wh_file_index, wh_tags, wh_uid, wh_s, wh_e, wh_pos, wh_len по отдельности: в sup_info для play_online уходят sup_data и все поля входа с префиксом wh_. ↩

  239. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c015 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · В r25 play_recent для поставщика, не найденного ни по id, ни по префиксу, вместо ошибки «Supplier deleted» показывает сообщение unable_to_continue_watching / supplier_not_available_anymore с продолжением — входом в mdb-карточку фильма. ↩

  240. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c070 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · RecentHelper::run_witem (r25) для записи с action_plugin и action_params возвращает get_continue_by_wh_params_action(witem, autoplay) — play_default_directly при этом 0. ↩

  241. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c095 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 выбор записи «KB9 … #2» в «Последнем» сразу вызвал handle_user_input(recent) плагина с wh_uid kbp9:e1:2, wh_s/wh_e −1, wh_pos 7, wh_len 8, wh_file_index 1, autoplay 0 и play_default_directly 0, таймаут 20 с. ↩↩

  242. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c087 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 запись истории plugin VOD получает uid из PluginVodSeriesInfo::recent_uid, action_plugin из PluginVodInfo::recent_plugin и action_params из PluginVodInfo::recent_action_params. ↩↩

  243. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c094 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 по концу каждой из двух серий plugin VOD (RUN_POSTPLAY_ACTIONS, eos: yes) оболочка добавила запись истории: uid kbp9:e1:1 и kbp9:e1:2, action_plugin/action_params, index 0/1, без ключей url и video_id. ↩

  244. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c084 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 история просмотра лежит в $FS_PREFIX/config/watch_history (/data/data/com.dunehd.app/config/watch_history; /config/watch_history в корне ФС нет): файлы с шестизначными номерами 000026.json … 000034.json (на 2026-10-28 было 000026…000033; 000034 появился 2026-10-29, файлы 000026–000033 остались), в каждом JSON-массив до 40 записей; новые записи дописываются в последний файл; рядом — cleared.txt, max_time.txt, timestamp, watched_files.txt, watched_movies.txt, sync_fixed, sync_fixed_v2. ↩

  245. fw-tv188b-260827-0003-r24.c029 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В прошивке 13 встроенных плагинов в /system/dunehd/firmware_ext/plugins/ (у каждого dune_plugin.xml): android_apps, bluray, bt_setup, dunemdb_supplier_generic, dunemdb_supplier_rutube, dunemdb_supplier_youtube, dunestore, ext_epg, kartina_tv_launcher, ktv_start, radiotime, shell_ext, widget ↩

    • fw-tv188b-261021-0117-r25.c125 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 movie_suppliers_update.sh плагина-поставщика test_plugin6_sup запущен с парами аргументов « » (подпись равна id) для всех восьми id в порядке их перечисления в params/movie_suppliers манифеста.
    • fw-tv188b-261021-0117-r25.c126 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 после замены version_index 1→2 прямо в dune_plugin.xml установленного плагина test_plugin6_sup и перезапуска приложения (am force-stop com.dunehd.app) movie_suppliers_update.sh запущен снова с теми же парами аргументов, а movie_suppliers_params.txt стал «2:--…».

    ↩

  246. fw-tv188b-260827-0003-r24.c025 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Список возможностей прошивки firmware_features.txt содержит 19 флагов, в т.ч. dunemdb_supplier_plugin_api_v2…v7, sup_api_v8, newgui2021, apk, fw_apk, drm_apps ↩

  247. fw-tv188b-260827-0003-r24.c040 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · По сравнению с 250815_1012_r22 в firmware_features.txt r24 добавлены флаги dunemdb_supplier_plugin_api_v7, sup_api_v8, movie_suppliers_order, lcfg_v2, light_stop ↩

  248. 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. ↩

  249. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c062 · code · tv188b, android-dune-fw; прошивка 250815_1012_r22 · В 250815_1012_r22 Suppliers (shell_ext/movies/suppliers.php) задаёт тот же контракт потоковых команд, что и r24: те же ограничения seasons/episodes в get_episodes, те же ключи playback_url (movie_id, s, e, ass_type, sup_id, is_current, file_id, stream_url), та же проверка url ответа get_stream_url ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c013 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ответ get_episodes: при null, при наличии error (в лог пишется error.message) или без seasons список эпизодов пуст; необязательное поле private приводится к строке и потом передаётся в do_file_search как private
    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c021 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Элемент files[] ответа do_file_search принимается, только если id задан и не состоит из одних пробелов и задан caption; если хотя бы у одного файла есть order, список сортируется по intval(order) (без order — в конец), при равенстве — strnatcmp по id
    • fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c044 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Ответ get_stream_url: null (сбой команды) — исключение «Error getting stream url»; объект error — error.message в лог и исключение; нет url — «The 'url' is missing…»; пользователь во всех случаях видит errmsg_failed_to_start_playback

    ↩

    • fw-tv188b-261021-0117-r25.c181 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 get_episodes получает на вход только объект movieInfo (videoType video) — без season, episode и private.
    • fw-tv188b-261021-0117-r25.c182 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 get_stream_url запускается как « get_stream_url» и получает на вход только {"fileId": }.

    ↩

  250. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c063 · code · tv188b, android-dune-fw; прошивка 250815_1012_r22 · В 250815_1012_r22 get_non_video_files не передаёт icon файла: в элементе только movie_id, sup_id, caption, match_confirmed, ass_type, file_id (в r24 добавлено icon) ↩

  251. fw-tv188b-260827-0003-r24--movie-suppliers.c078 · code · tv188b, android-dune-fw; прошивка 250815_1012_r22 · В 250815_1012_r22 youtube (version_index 33) объявлял supported_video_types trailer|add_material (без video) и обрабатывал команду get_stream_url ↩

  252. fw-tv188b-261021-0117-r25.c201 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 описатель /tmp/movie_suppliers/YouTube: plugin dunemdb_supplier_youtube, supported_video_types video|trailer|add_material, playback_type app, bin «cd …/firmware_ext/plugins/dunemdb_supplier_youtube/bin && …/firmware_ext/php/php-cgi -c … -f ./run.php», а также icon_url и play_icon_url. ↩

  253. fw-tv188b-261021-0117-r25.c051 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Suppliers r25 (movies/suppliers.php): поставщик rutube включается, если установлен плагин rutube_integration; в остальных случаях (и для rutube без плагина) решает ключ expr описателя: ложь — поставщик отключается ↩

  254. fw-tv188b-261021-0117-r25.c202 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 описатель /tmp/movie_suppliers/rutube: plugin dunemdb_supplier_rutube, langs russian, supported_video_types video|trailer, playback_type app, fixed_trailer_files с одним элементом search_trailers, icon_url и expr country(ru). ↩

  255. 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 ↩

  256. fw-tv188b-261021-0117-r25.c055 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · dunemdb_supplier_generic r25 (bin/run.php) для HBOMax/Max выбирает пакет com.wbd.hbomax с запасным com.wbd.stream (для страны US — наоборот), страну берёт из country_code_2 в /tmp/location_info.properties или /config/location_info.properties ↩

  257. fw-apk-260724-0207-r24.c047 · code · android-atv; прошивка 260724_0207_r24 · У пяти подписанных плагинов data.zip (dunemdb_supplier_generic, dunestore, ktv_start, shell_ext, widget) dune_plugin.sign отличается по sha256 от tv175u той же сборки, а dune_plugin_signer_id.txt и dune_plugin.xml совпадают ↩

  258. fw-tv188b-260827-0003-r24--movie-suppliers.c062 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · generic заменяет пакет com.netflix.ninja на com.netflix.mediaclient, если (HD_FW_APK или не HD_APK) и нет флагов whale_tv и dual_system ↩

  259. fw-tv175u-260724-0207-r24.c028 · code · tv175u, android; прошивка 260724_0207_r24 · dunelib/utils.php определяет is_android() (всегда true), is_apk() = getenv("HD_APK"), is_fw_apk() = getenv("HD_FW_APK") и is_limited_apk() = is_apk() && !is_fw_apk() ↩

  260. fw-apk-260724-0207-r24.c029 · code · android-atv; прошивка 260724_0207_r24 · firmware_features.txt в APK содержит флаг apk и не содержит fw_apk (18 флагов; в tv188b r24 есть оба, в tv175u r24 нет ни одного) ↩

  261. doc-sdk-plugins--operations.c107 · doc · any-documented; прошивка — · PluginVodInfo::buffering_ms (предбуферизация в мс) не реализован ↩

  262. fw-tv188b-261021-0117-r25.c287 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при старте VOD тестового плагина test_plugin6 с PluginVodInfo::buffering_ms=3000 оболочка пишет в shell.log «[player] setting buffering to 3000ms» и «[player] DEBUG: using special buffering 3000ms». ↩

  263. fw-tv188b-260827-0003-r24--movie-suppliers.c006 · inference, disputed · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Значение в /tmp/run/installed_plugins.xml оболочка берёт из params/movie_suppliers манифеста плагина ↩

  264. fw-tv188b-260827-0003-r24--movie-suppliers.c023 · code, disputed · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Значения по умолчанию ключей описателя: playback_type = stream, play_action = '', caption = имя файла, supported_video_types = video, server_managed = false (если ключа нет и id не входит в Config::$server_managed_suppliers; для id из этого списка — true), icon_url = '', location_handling = ignore, special_category = false, logo_width = 249, logo_height = 68; если logo_icon_url задан пустой строкой и есть icons/small/.jpg, logo_icon_url и logo_width/logo_height получают 100/100 ↩

  265. fw-tv188b-260827-0003-r24--movie-suppliers.c043 · code, disputed · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Поиск файлов считается законченным, если ответа нет, в нём нет status или status != active. Без actx оболочка опрашивает get_file_search_state каждые 0,5 с до 60 с (DO_FILE_SEARCH_TIMEOUT). С actx (экран «Файлы») do_search_files после первого ответа active сразу возвращается, а get_file_search_state вызывается по таймеру экрана 500 мс без 60-секундного предела внутри do_search_files. При отмене (actx->canceled) сначала выполняется текущий запрос (do_file_search, если поиск ещё не начат, иначе get_file_search_state), затем вызывается stop_file_search ↩

  266. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c011 · code, disputed · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Если check_movie_changed не сбросил кэш и cached_video_sup_id совпадает с sup_id (ensure_video_episodes для этого movieExtId и этого sup_id уже выполнялся, cached_movie_ext_id и cached_video_sup_id выставлены), ensure_video_episodes выходит сразу и get_episodes не вызывает. Иначе get_episodes не вызывается для фильма без series_type (single), для поставщика с playback_type app и если поставщик не входит в список поставщиков фильма (get_movie_sup_ids для видео); иначе вызывается с movieInfo для ass_type 0 ↩

  267. fw-tv188b-260827-0003-r24--movie-suppliers.c059 · code, disputed · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Команда запуска generic: для deeplink вида intent:…#Intent — «am start ''»; иначе «am start» и, только если $package непустой, « -p ''»; затем deeplink: « -d ''», если FS_PREFIX пуст и ссылка http…, иначе отдельным аргументом « ''» ↩

  268. fw-tv188b-260827-0003-r24--movie-suppliers.c050 · inference, disputed · tv188b, android-dune-fw; прошивка 260827_0003_r24 · На 260827_0003_r24 global_actions generic (boot_end/install/update) не выполняются, потому что флаг movie_suppliers_update есть; описатели generic строит shell_ext (update_service_plugins → movie_suppliers_update.sh) ↩

  269. fw-tv188b-260827-0003-r24--plugin-loader--manifest.c014 · inference, disputed · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Предикат firmware_feature(<имя>), вероятно, проверяет наличие имени в списке возможностей прошивки /tmp/firmware_features.txt: этот файл есть в strings оболочки, его же построчно читает PHP-библиотека прошивки (ConfigUtils::load_firmware_features, ещё и /tmp/ro_features.txt) и grep-ает скрипт dunemdb_supplier_generic ↩

  270. fw-tv188b-260827-0003-r24--movie-suppliers.c076 · inference · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Флаги dunemdb_supplier_plugin_api_v2…v7 и sup_api_v8 из firmware_features.txt — маркеры версий API поставщиков, которые сторонний плагин может требовать в dune_plugin_metadata.xml (firmware_features); чем версии различаются, в репозитории не найдено ↩↩

  271. fw-tv188b-260827-0003-r24--movie-suppliers.c075 · inference · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Глобальный ключ перевода плагина строится как <имя плагина>plugin<ключ из translations/dune_language_*.txt> (msg_search_trailer → dunemdb_supplier_youtube_plugin_msg_search_trailer) ↩

  272. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c010 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · movieInfo.publications появляется, только если get_supplier_pubs($sup_id, $ass_type) вернул не null: для ass_type 0 — если поставщик есть в active_video_pubs_by_sup_id (карта строится rebuild_supplier_pub_maps только из непустого do_get_supplier_pubs), для trailer/bonus — если isset(supplier_publications[$sup_id]), поставщик существует и не server_ignored; публикации фильтруются по типу (video/trailer/bonus), а при непустом country, location_handling=LOCATION_SKIP_UNMATCHED_PUBLICATIONS и непустом pub.countries — ещё и по countries. Иначе publications нет, и поставщик должен искать контент сам — по title, year, type и внешним id из movieExtId ↩

  273. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c042 · inference, disputed · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Поставщику с несколькими вариантами (озвучка, качество) стоит при do_file_search с fileId ставить первым в списке вариант, соответствующий этому fileId: при переходе к следующей серии оболочка без выбора пользователя играет первый файл ↩

  274. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c046 · inference · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Проверку URL проходят абсолютный путь («/tmp/www/dash.mpd») и URL со схемой из строчных латинских букв, «-» и «_» (http://, https://, http://mp4://…), а также пустая схема («://…»); схема с цифрами или заглавными буквами (например «m3u8://», «HTTP://») и пустая строка отвергаются ↩

  275. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c050 · inference, disputed · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Так как path — строка, count() для всех файлов даёт одно значение (в PHP 5.3.6 — 1), поэтому при непустом списке stream_special всегда играет первый файл списка (при наличии order — после сортировки по order) ↩

  276. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c051 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Для stream_special process_special_stream_playback_type при пустом списке файлов возвращает ошибку, иначе берёт файл с минимальным count(path) (строгое <, при равенстве — первый) и вызывает get_play_movie_action с online=true и cur_stream_url=''; get_play_file_online_action передаёт cur_stream_url в get_vod_info, тот кладёт stream_url='' в playback url (для single/ass_type!=0 — напрямую cur_stream_url, для серии — при is_current=1), get_stream_url пропускает preloaded только при is_current!=0 && stream_url!='', поэтому идёт в get_stream_url_by_file_id. url из ответа do_file_search для запускаемого stream_special-файла не используется; поставщик должен реализовать get_stream_url ↩

  277. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c056 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · Для трейлера потокового поставщика (ass_type != 0) url из do_file_search не используется: при выборе трейлера movie_screen уводит YouTube в do_play_youtube, поставщика с playback_type app — в launch_playback_app, а остальных вызывает get_play_file_online_action($movie, $file, $ass_type) без cur_stream_url; get_play_file_online_action передаёт cur_stream_url в get_vod_info, а тот для ass_type != 0 кладёт stream_url = cur_stream_url = ''; get_stream_url пропускает preloaded только при is_current != 0 && stream_url != '', поэтому вызывает get_stream_url_by_file_id — оболочка всегда запрашивает get_stream_url поставщика ↩

  278. fw-tv188b-260827-0003-r24--movie-suppliers--stream-protocol.c068 · inference · tv188b, android-dune-fw; прошивка 250815_1012_r22 · Ошибку получения ссылки youtube r22 сообщает не объектом error, а url «error», который не проходит проверку url оболочки, — пользователь видит errmsg_failed_to_start_playback ↩

  279. fw-apk-260724-0207-r24--data-deploy.c012 · inference · android-atv; прошивка 260724_0207_r24 · Вероятно, скрипты из data.zip после распаковки в APK не имеют бита исполнения, поэтому их запускают через sh (так записан RUN_WIDGET_PATH='sh /data/data/com.dunehd.app/…/run_widget.sh'); плагину в APK надёжнее вызывать скрипты прошивки как «sh <путь>», а не напрямую ↩

  280. fw-apk-260724-0207-r24--data-deploy.c029 · inference · android-atv; прошивка 260724_0207_r24 · Вероятно, в этом APK (ограниченный режим, не fw_apk) /tmp — отдельный каталог данных приложения, а не системный /tmp, а firmware/ и firmware_ext/ — копия из data.zip, а не ссылки на /system/dunehd; плагину в APK нужно обращаться к ним через $FS_PREFIX ↩

  281. fw-tv188b-261021-0117-r25--app-launch.c055 · inference · tv188b, android-atv; прошивка 260724_0207_r24 · Поля данных действия launch_ext_app в нативном коде APK DMC, вероятно, лежат в порядке ключей LaunchExtAppActionData (c001) — +0 cmd, +4 ensure_playback_stopped, +8 delay, +0xc package, +0x10 version, +0x14 msg_toast, +0x18 params, +0x1c error_action; кодом подтверждены только cmd, ensure_playback_stopped и delay (печатаются в «[gui_action] cmd …») и msg_toast (+0x14 печатается в «show toast»). ↩

    • fw-tv188b-261021-0117-r25--app-launch.c077 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при проверке на устройстве launch_ext_app с delay 0 (am start настроек) дал «activity launch status: 0», через 4,968 мс — «general: wait for shell app loosing focus timed-out»; настройки открылись (Displayed +123ms), и поверх них выполнился error_action действия — диалог «KB7 error_action / delay=0».
    • fw-tv188b-261021-0117-r25--app-launch.c079 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при проверке на устройстве launch_ext_app с delay −1 (am start настроек) дал activity launch status 0, через 3,419 мс — «general: shell app is already lost focus»; настройки открылись (resumed MainSettings), error_action не выполнялся.

    ↩

  282. fw-tv188b-261021-0117-r25--app-launch.c054 · inference · tv188b, android-atv, android-dune-fw; прошивка 260724_0207_r24, 261021_0117_r25 · Следствие для плагинов — если launch_ext_app получает delay ≤ 0 (у поставщика без wait_app_start_delay shell_ext ставит -1) и в момент проверки оболочка ещё держит фокус, ожидание сразу кончается «timed-out» и выполняется error_action, хотя activity стартовала («activity launch status: 0») — пользователь увидит ошибку («Не удалось запустить воспроизведение» у shell_ext); встроенные поставщики generic и rutube всегда отдают wait_app_start_delay 10. ↩

  283. fw-tv188b-261021-0117-r25--app-launch.c035 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25, 260827_0003_r24 · Команды generic под этим разборщиком, вероятно, работают так — «am start 'intent:…#Intent;…;end'» → intent из parseUri целиком (пакет и компонент — из самого URI); «am start -p '<пакет>' ''» → ACTION_VIEW на deeplink, ограниченный пакетом; при пустом FS_PREFIX вариант с -d даёт то же через data. ↩

  284. fw-tv188b-261021-0117-r25--app-launch.c032 · inference · tv188b, android-dune-fw, android-atv; прошивка 261021_0117_r25, 260827_0003_r24, 260724_0207_r24 · Поскольку строка не попадает в shell, в обычной cmd launch_ext_app (не через dunehd_service) не работают конструкции shell — ;, &&, |, $VAR, перенаправления кроме отброшенных «>…»/«2>…», — и несколько команд подряд; всё после «am start » становится аргументами IntentBuilder. ↩

  285. fw-tv188b-261021-0117-r25--app-launch.c037 · inference · tv188b, android-dune-fw, android-atv; прошивка 261021_0117_r25, 260827_0003_r24, 260724_0207_r24 · На tv188b оболочка работает с sharedUserId android.uid.system, поэтому запуск неэкспортированной activity чужого пакета через launch_ext_app, вероятно, проходит; в APK DMC на ATV (обычный uid) он, вероятно, падает SecurityException → startActivityFromArgs false → статус -1 → error_action. ↩

  286. fw-tv188b-261021-0117-r25--app-launch.c040 · inference, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25, 260827_0003_r24 · Гипотеза для плагинов на tv188b — cmd «/system/dunehd/dunehd_service do am start …» в launch_ext_app уходит в shell, то есть в системный am от имени демона dunehd_service (root), где есть --user и прочие опции, которых нет в IntentBuilder, и нет ограничения exported. ↩

  287. fw-tv188b-261021-0117-r25--app-launch.c042 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25, 260827_0003_r24 · Следствие — пакет без launcher/leanback activity (сервис, библиотека) в app_data.json не попадает, и для shell_ext его как будто нет — start_playback_app с таким package закончится «app not found», а generic вернёт error.missing_app. ↩

  288. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c088 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, для «Продолжить» у кнопки поставщика история plugin VOD должна содержать uid вида :…, movie_id нужного фильма и len>0 и pos>=0. ↩

  289. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c068 · code, disputed · tv188b, android-dune-fw; прошивка 261021_0117_r25 · MovieHelper::get_continue_by_wh_params_action (r25) отправляет плагину action_plugin записи handle_user_input с полями action_params, wh_*, autoplay и play_default_directly (0/1) и таймаутом 20000 мс. ↩

  290. fw-tv188b-261021-0117-r25--shell-ext--entry-handler.c055 · inference · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Вероятно, для записи поставщика или plugin VOD с не-URL uid и movie_id «Просмотрено» в r25 хранится только отметкой фильма в watched_movies.txt: get_movie_mark_files не даёт такому uid файловой отметки. ↩

  291. fw-tv188b-261021-0117-r25--app-launch.c079 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 при проверке на устройстве launch_ext_app с delay −1 (am start настроек) дал activity launch status 0, через 3,419 мс — «general: shell app is already lost focus»; настройки открылись (resumed MainSettings), error_action не выполнялся. ↩

    • fw-tv188b-261021-0117-r25--app-launch.c060 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Разборщик apk_helper в tv188b r25 (fcn.006f2b60) сравнивает результат fcn.006f2648(cmd) с «am start » (strncmp на 9 символов; иначе «[apk_helper] unsupported command (1): %s» и -1), делит остаток по пробелам, снимает кавычки '…' и "…" (внутри "…" обратная косая только пропускает следующий символ и остаётся в аргументе; незакрытая кавычка берёт остаток строки), выбрасывает пустые и пробельные аргументы и аргументы, начинающиеся с «>» или «2>»; пустой список даёт «[apk_helper] unsupported command (2): %s» и -1.
    • fw-tv188b-261021-0117-r25--app-launch.c073 · code · tv188b, android-dune-fw; прошивка 261021_0117_r25 · Разбор опций IntentBuilder.doMakeIntent (dune.apk tv188b r25 и APK DMC) устроен так: понимает опции -a, -d, -t, -c, -p, -e/--es, --esn, --ei, --eu, --eia, --el, --ela, --ez, -n, -f, --grant-read/write-uri-permission, --exclude/include-stopped-packages, --debug-log-resolution, 15 --activity-*, --receiver-registered-only, --receiver-replace-pending, --selector; -D, -W и -S пропускает, -P, --start-profiler и -R съедают следующий аргумент; любая другая опция (в т. ч. --user) — IllegalArgumentException «Error: Unknown option: <опция>»; makeIntent ловит исключение, пишет «Error making intent: %s» (тег ApkHelper) и возвращает null, а startActivityFromArgs пишет «Failed to create intent from args.» и возвращает false.

    ↩

    • fw-tv188b-261021-0117-r25--app-launch--native.c007 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 apk_helper fcn.006d4c9c пропускает ведущие пробельные байты помощником fcn.006d4784 с isspace и требует префикс «am start » (strncmp на 9 байт); при несовпадении пишет «unsupported command (1)» и возвращает -1.
    • fw-tv188b-261021-0117-r25--app-launch--native.c008 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 apk_helper fcn.006d4c9c ищет разделитель некавыченных аргументов после «am start » как байт 0x20 и снимает парные одинарные либо двойные кавычки; внутри двойных кавычек обратная косая увеличивает шаг сканирования до 2, но сохраняется в передаваемом сегменте; при незакрытой кавычке берётся остаток строки.
    • fw-tv188b-261021-0117-r25--app-launch--native.c009 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 apk_helper fcn.006d4c9c не добавляет в список пустые и пробельные сегменты, а также сегменты, начинающиеся с «>» или «2>»; при пустом итоговом списке пишет «unsupported command (2)» и возвращает -1.
    • fw-tv188b-261021-0117-r25--app-launch--native.c010 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · В tv188b r24 apk_helper fcn.006d4c9c при непустом списке аргументов вызывает JNI-помощник fcn.00091b04, обращающийся к startActivityFromArgs с сигнатурой ([Ljava/lang/String;)Z; false даёт сообщение «jni returned error status» и статус -1, true — статус 0.

    ↩

    • fw-tv188b-261021-0117-r25--app-launch.c069 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 launch_ext_app с cmd «/system/dunehd/dunehd_service do am start --user 0 -n com.android.tv.settings/com.android.tv.settings.MainSettings» открыл настройки: command status 0, ActivityTaskManager — START from uid 0, Displayed +105ms.
    • fw-tv188b-261021-0117-r25--app-launch.c068 · device · tv188b, android-dune-fw; прошивка 261021_0117_r25 · На tv188b r25 launch_ext_app с cmd «/system/dunehd/dunehd_service do am start -n com.kb9.none/.Nope» пошёл в ветку «run command»: pclose вернул 0, command status — 0; ActivityTaskManager зафиксировал START несуществующего компонента.

    ↩

    • fw-tv188b-260827-0003-r24--movie-suppliers.c016 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · update_service_plugins: для сервисов из конфигурации movie services, которые есть в эффективном списке и чей плагин (plugin_name) установлен с version_index > 0, собирает id поставщиков (service.suppliers[].id с caption, иначе id сервиса с caption сервиса) и вызывает do_movie_suppliers_update
    • fw-tv188b-260827-0003-r24--movie-suppliers.c052 · code · tv188b, android-dune-fw; прошивка 260827_0003_r24 · update_movie_suppliers.php читает /flashdata/movie_services/config.json (movie_services_config.services) и /config/services_effective_config.json (services); без любого из них завершается с ошибкой

    ↩