- PVSM.RU - https://www.pvsm.ru -
Сейчас вы снова убедитесь, что знание языка С сопоставимо с навыками самообороны, поскольку в современном мире мега-корпораций и победившего киберпанка на простых пользователей всем и давно наплевать.
Как и все нормальные люди, я временами смотрю фильмы, сериалы и длинные видео на ноутбуке и чтобы тот случайно не ушел в сон во время просмотра — включаю на нем «режим презентации».
Поскольку за последние годы все кино переместилось в веб, большую часть времени теперь используется не программа-видеоплеер, а обычный браузер Chrome/Chromium.
После одного из обновлений, стал замечать, что браузер-то оборзел научился самостоятельно перехватывать засыпание ноутбука, блокировку экрана и запуск скринсейвера во время просмотра видео, без всяких «режимов презентации».
Затем такое поведение появилось и на обычных сайтах — без видимого видео или аудио-контента.
Без каких-либо сообщений, запросов и подтверждений на подобные действия.
Затем ноутбук впервые разрядился в ноль, будучи оставленным с открытой страницей какого-то левого сайта, ни suspend ни hibernate внезапно не сработали.
После пятой по счету подставы с перехватом управления, автор окончально огорчился с такой наглости, достал любимый топор компилятор и стал изучать проблему в деталях.
Первым делом я полез в поисковик, убедиться что проблема — не результат осеннего обострения или моего специфического окружения, в котором половина системы это разнообразные компиляторы и средства разработки, а другая — горы исходного кода.
Оказалось что сия дичь действительно массовая [1] и хорошо известная [2]:
Хотя в статье речь пойдет о Xfce [3], аналогичным обазом ведут себя все «большие» окружения — KDE, Gnome, Cinnamon [4] и так далее:

Отдельная «шутка юмора» — попытка [5] втащить поддержку такого поведения в.. Sway [6]:
Monitor dbus and inhibit swayidle when Firefox or Chromium request it
Хотя любители тайловых менеджеров — особая раса сверхлюдей, понять мотивы которых обывателю не дано, так что не буду даже пытаться.
Разумеется по этой проблеме есть давно заведенный тикет в трекере [7], с длиннющей перепиской, с приложенными дампами памяти и техническими деталями, открытый уже 11 лет:
Помимо означенного тикета в публичном трекере Ubuntu, где тусуются в основном простые пользователи, нашелся еще один, не менее эпичный тикет [8] в трекере самого Chromium, висящий там аж с 2013 года:

Если прокрутить в самый низ страницы, можно заметить статус «Fixed» и битую ссылку на коммит (поскольку трекер переехал), суть которого — легализация специального API [9] для управления блокировкой экрана и засыпанием.. прямо из кода на странице!
Примерно такого:
// The wake lock sentinel.
let wakeLock = null;
// Function that attempts to request a screen wake lock.
const requestWakeLock = async () => {
try {
wakeLock = await navigator.wakeLock.request();
wakeLock.addEventListener('release', () => {
console.log('Screen Wake Lock released:', wakeLock.released);
});
console.log('Screen Wake Lock released:', wakeLock.released);
} catch (err) {
console.error(`${err.name}, ${err.message}`);
}
};
// Request a screen wake lock…
await requestWakeLock();
// …and release it again after 5s.
window.setTimeout(() => {
wakeLock.release();
wakeLock = null;
}, 5000);
Как тебе такое, Илон Маск?
Повторяю для тех, кто еще не понял и не осознал:
любая веб-макака, верстающая на полставки
порносайты, ныне может с помощью специального кода на странице заставить браузер Chrome заблокировать засыпание вашего ноутбука.
И защитить от такого может лишь знание языка С и эта замечательная статья.
Прежде чем «карать и патчить» очередную оборзевшую программу, стоит рассказать широкой аудитории как вся эта кухня вообще работает, хотя‑бы для осознания печальных реалий.
Есть одна неведомая штука в Linux-системах, под названием systemd [10]:
systemd is a suite of basic building blocks for a Linux system. It provides a system and service manager that runs as PID 1 and starts the rest of the system.
Описание, взятое с официального сайта, столь расплывчато не потому, что это перевод с языка рептилоидов, как могло показаться. Просто такого рода системные сервисы крайне непросто описать простыми словами, доступными обывателю.
Для примера, вот так выглядит набор системных сервисов Windows:
У замечательного systemd с недавних пор появился абсолютно «сказочный» функционал, созданный для перехвата управления процессами засыпания и выключения системы:
systemd 183 and newer include a logic to inhibit system shutdowns and sleep states. This is implemented as part of systemd-logind.daemon(8) [11]
Отключаемый [12], разумеется.
Но только с последствиями, вроде сломанного процесса автоматического засыпания из менеджеров управления питанием.
И риском загнуть систему целиком при обновлении, поскольку например менеджеры пакетов выставляют подобную блокировку при установке пакета.
Можете конечно попробовать заблокировать механизм
inhibitв systemd, но все последствия — на вас и вашей совести.
Мы же пойдем немного другим, менее радикальным путем.
Этой командой можно посмотреть список запущенных перехватчиков:
systemd-inhibit --list
В моей системе (Linux Manjaro) вывод выглядит следующим образом:

Обратите внимание, что самого браузера Chrome в списке нет, зато есть xfce4-power-manager — менеджер управления питанием из Xfce, который принимает входящие запросы на перехват и решает что делать дальше.
Остальные сервисы обрабатывают только события засыпания (sleep).
Так что наша цель это xfce4-power-manager , именно туда мы сейчас и залезем, для нанесения правок.
xfce4-power-manager — по большей части фоновое приложение, автоматически запускаемое при старте среды Xfce. Но в отличие от прошлого поциента [13], тут есть некоторый интерфейс и взаимодействие с пользователем, которое происходит с помощью иконки в трее:

По нажатию правой кнопки мыши, появится меню со списком дерзких приложений, которые в данный момент перехватывают управление питанием:

Так что ответственный за весь этот электронный беспредел был наконец четко определен.
Исходный код менеджера управления питанием находится в основном репозитории [14] Xfce, исправляемая версия должна совпадать с установленной локально, чтобы не словить феерические проблемы совместимости.
Автор использовал версию 4.20 [15], установленную на момент написания статьи.
Место предстоящей правки — файл xfpm-inhibit.c [16], в который вынесена вся логика по обработке перехватов (inhibit).
Нас интересует метод
xfpm_inhibit_inhibit,строка 370 [17], где начинается обработка входящего запроса на перехват управления.
Код метода небольшой, поэтому привожу его целиком:
static gboolean
xfpm_inhibit_inhibit (XfpmInhibit *inhibit,
GDBusMethodInvocation *invocation,
const gchar *IN_appname,
const gchar *IN_reason,
gpointer user_data)
{
const gchar *sender;
guint cookie;
if (IN_appname == NULL || IN_reason == NULL)
{
g_dbus_method_invocation_return_error (invocation,
XFPM_ERROR,
XFPM_ERROR_INVALID_ARGUMENTS,
_("Invalid arguments"));
return TRUE;
}
sender = g_dbus_method_invocation_get_sender (invocation);
cookie = xfpm_inhibit_add_application (inhibit, IN_appname, sender);
XFPM_DEBUG ("Inhibit send application name=%s reason=%s sender=%s",
IN_appname, IN_reason, sender);
xfpm_inhibit_has_inhibit_changed (inhibit);
xfpm_dbus_monitor_add_unique_name (inhibit->priv->monitor,
G_BUS_TYPE_SESSION, sender);
xfpm_power_management_inhibit_complete_inhibit (user_data,
invocation, cookie);
return TRUE;
}
Обратите внимание на вызов метода XFPM_DEBUG, содержащего текст отладочного сообщения. Все подобные сообщения становятся видны только если запустить xfce4-power-manager с ключом --debug.
Именно так и было найдено место будущей правки, после сообщения в консоли:
xfpm_inhibit_inhibit(): Inhibit send application name=/usr/lib/chromium/chromium reason=Video Wake Lock sender=:1.459
Что мы имеем в итоге:
есть единственная точка входа (метод) в менеджере управления питанием, с которой начинается регистрация перехватчика управления;
метод принимает на вход название приложения (полный путь), посягнувшего на такой перехват.
Думаю не надо иметь высшее техническое образование, чтобы догадаться как будет выглядеть финальное решение:
if (strstr(IN_appname,"chrom") != NULL ) {
XFPM_DEBUG ("Chrome уходи!");
return TRUE;
}
Для не знающих и не владеющих:
метод strstr [18] проверяет на входжение слова «chrom» в названии дерзкого приложения, которое отправило запрос на перехват управления питанием, если оно там есть — происходит немедленный выход из этого метода, а запрос игнорируется.
Вот так, всего лишь 4 строчки на С, вставленные в нужном месте, сразу после проверки на пустоту [19] обламывают рога оборзевшему браузеру, созданному мировой корпорацией, которая решила, что «мы знаем как лучше».
Так это выглядит в действии после наложения моего «кровавого» патча:
Теперь поговорим о печальном — о сборке всего этого цирка с конями.
Проект xfce4-power-manager это уже существенная часть Xfce, чтобы собрать его из исходников и заставить работать — придется постараться.
Во-первых, не стоит забирать исходники непосредственно из репозитория, поскольку в проекте используется кодогенерация и в этом случае придется заниматься еще и ей, устанавливая дополнительные пакеты в систему.
Куда проще скачать готовый архив [20] со специально подготовленными исходниками релизной версии.
Напоминаю что мы патчим версию 4.20.
Во-вторых, придется установить в систему довольно много библиотек и утилит для разработки:
Gtk+ and Glib headers, in some distributions called the -devel packages
Xfce 4.20 requires Gtk+ 3.24 and Glib-2.0 >= 2.72 (See also: 4.20 dependencies [22])
Same version for gmodule-2.0, gobject-2.0, gthread-2.0, gio-2.0 and gdbus
gdk-pixbuf-2.0 >= 2.42.8
gobject-introspection >= 1.72
gtk-layer-shell 0.7.0
pkgconfig
Это не весь список, тут [23] внизу страницы находится специальная таблица с описанием зависимостей между компонентами Xfce, часть из которых также придется установить.
Таков путь джедая, что поделать.
Распаковываем скачанный архив с исходниками и запускаем скрипт configure:
tar xvjf ~/Downloads/xfce4-power-manager-4.20.0.tar.bz2
cd fce4-power-manager-4.20.0
./configure --disable-wayland
Поскольку автор не использует Wayland — тут отключена зависимость от него при сборке, но если вам оно актуально, придется установить дополнительные библиотеки:
wayland 1.20
wayland-protocols 1.25
Добавляем описанный выше блок в файл src/xfpm-inhibit.c и наконец запускаем сборку:
make
Если сборка завершится успешно, в каталоге src будет готовый бинарник с патчем, проверить который можно так:
pkill -f xfce4-power-manager
./src/xfce4-power-manager --debug
Дальше открываем в Chrome любую страницу с видео [24] и смотрим выдаваемые сообщения:
Разумеется, после такого патча вам придется вручную включать и отключать режим презентации (Presentation mode [25]) при просмотре длинных роликов в браузере, зато процесс будет полностью контролируемым.
Также подобным образом можно «обламывать рога» и другим интересным приложениям, дерзнувшим покуситься на управление питанием — с недавних пор за подобным неблаговидным делом был замечен и Firefox.
Грустно наблюдать (в который уж раз), как некогда хороший софт, по мере роста популярности скатывается в полное УГ отрицание пользовательского опыта и начинает считать своих пользователей полными идиотами:
неотключаемые опции, неизменяемое поведение и просто наглая ложь — все это стало, к великому сожалению, постоянными спутниками самого популярного браузера на планете.
И лишь владение языком С и навыки системного программирования все еще позволяют ставить на место оборзевшие программы — изучайте же инженерное дело настоящим образом!
В одной из следующих статей расскажу о патчах для самого браузера Chrome: «как убрать detach вкладок при таскании», «как вернуть пустую страницу для новой вкладки» и многое другое — следите за анонсами на нашем канале [26].
Менее цензурный оригинал [27] статьи как обычно в нашем блоге.
Автор: alex0x08
Источник [28]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/linux/437927
Ссылки в тексте:
[1] массовая: https://askubuntu.com/questions/1051688/how-to-stop-chrome-from-making-suspend-inhibits
[2] известная: https://unix.stackexchange.com/questions/451413/disabling-chromium-xfce-power-management-inhibition
[3] Xfce: https://xfce.org/
[4] Cinnamon: https://github.com/linuxmint/Cinnamon/issues/13219
[5] попытка: https://github.com/loops/idlehack
[6] Sway: https://github.com/madic-creates/Sway-DE
[7] тикет в трекере: https://bugs.launchpad.net/ubuntu/+source/gnome-session/+bug/1600622
[8] эпичный тикет: https://issues.chromium.org/issues/40324240#comment74
[9] специального API: https://developer.chrome.com/docs/capabilities/web-apis/wake-lock
[10] systemd: https://systemd.io/
[11] systemd-logind.daemon(8): http://www.freedesktop.org/software/systemd/man/systemd-logind.service.html
[12] Отключаемый: https://unix.stackexchange.com/questions/574481/preventing-systemd-inhibit-in-linux
[13] прошлого поциента: https://blog.0x08.ru/xfce-display-settings-dialog
[14] основном репозитории: https://gitlab.xfce.org/xfce/xfce4-power-manager/
[15] 4.20: https://gitlab.xfce.org/xfce/xfce4-power-manager/-/tree/xfce4-power-manager-4.20.0?ref_type=tags
[16] xfpm-inhibit.c: https://gitlab.xfce.org/xfce/xfce4-power-manager/-/blob/xfce4-power-manager-4.20.0/src/xfpm-inhibit.c?ref_type=tags
[17] 370: https://gitlab.xfce.org/xfce/xfce4-power-manager/-/blob/xfce4-power-manager-4.20.0/src/xfpm-inhibit.c?ref_type=tags#L370
[18] strstr: https://en.cppreference.com/w/c/string/byte/strstr
[19] проверки на пустоту: https://gitlab.xfce.org/xfce/xfce4-power-manager/-/blob/xfce4-power-manager-4.20.0/src/xfpm-inhibit.c?ref_type=tags#L379
[20] скачать готовый архив: https://archive.xfce.org/src/xfce/xfce4-power-manager/4.20/
[21] A working GNU toolchain: http://en.wikipedia.org/wiki/GNU_toolchain
[22] 4.20 dependencies: https://wiki.xfce.org/releng/4.20/roadmap#changes_in_dependencies
[23] тут: https://docs.xfce.org/xfce/building#obtaining_the_xfce_source_code
[24] страницу с видео: http://pkill%20-9%20xfce4-power-manager%20./src/xfce4-power-manager%20--debug
[25] Presentation mode: https://docs.xfce.org/xfce/xfce4-power-manager/panel-plugin
[26] нашем канале: https://t.me/alex0x09
[27] оригинал: https://blog.0x08.ru/chrome-xfce-very-scary-movie
[28] Источник: https://habr.com/ru/articles/971828/?utm_source=habrahabr&utm_medium=rss&utm_campaign=971828
Нажмите здесь для печати.