Какое состояние NetworkManager на самом деле получил ваш уведомитель?
Одно и то же целое число означает «отключено» в одном перечислении и «середина настройки» в другом. Сопоставьте тип состояния с объектом, прежде чем копировать условие.
Состояние четыре порождает уведомление в одном API и означает нечто иное в другом, а код не показывает никакой разницы. Каждое значение состояния в NetworkManager принадлежит именованному перечислению, и перечисления расходятся в том, что значит данное число. Поэтому копирование целого числа из работающего фрагмента в другой обратный вызов — не перенос поведения, а совпадение, которое ждёт поломки. Сначала найдите тип, и число станет читаемым.
Число без типа — это только слух
Здесь важны два перечисления. Одно описывает активное соединение в целом: неизвестно, активация, активно, деактивация, отключено. Другое описывает именно VPN-соединение, и в нём больше остановок на пути, включая подготовку, настройку соединения, конфигурацию IP и запрос аутентификации, прежде чем что-либо активируется. Их нумерация в обоих случаях начинается с нуля, а затем расходится, поэтому значение, означающее «отключено» в общем перечислении, попадает куда-то в середину последовательности VPN. Ни один заголовок не ошибочен; они отвечают на разные вопросы.
Используйте символьную константу из установленного заголовка или привязки, а не литерал. Имя переживает перенумерацию; целое число — нет.
Следите за одним соединением, а не за машиной
Начните с UUID профиля, который вас интересует, и объекта активного соединения, созданного этой активацией. Состояние устройства или состояние другого туннеля не является заменой, даже когда оба меняются в один и тот же момент. Храните идентичность объекта вместе с наблюдением, чтобы более поздний отчёт мог сказать, какой профиль его породил. У машины много состояний; уведомление касается одного из них.
Затем решите, что должно означать уведомление. Соединение, так и не дошедшее до активации, — это сбой настройки, а сеанс, который был активен, а затем исчез, — это потеря. Они заслуживают разных слов.
Скажите, какой переход вы сообщаете
Сохраните предыдущее состояние и сравните его с новым, вместо того чтобы проверять новое значение изолированно. Переход в неудачное состояние и переход из активного состояния — разные события, даже когда оба заканчиваются ничем не подключённым. Запишите рядом строку причины, потому что часто это единственная часть, на которую пользователь может повлиять.
Намеренное отключение — не неисправность. Если уведомление не может отличить его, оно научит людей игнорировать его.
Держите наблюдатель живым
Повторный опрос не должен поднимать ещё одно предупреждение для состояния, которое не изменилось. Это единственное правило убирает большую часть шума, который создают такие уведомители.
Обработайте и случай, когда менеджер перезапускается или наблюдаемый объект заменяется. Наблюдатель, привязанный к устаревшей идентичности, замолкает ровно в тот момент, когда происходит что-то интересное, а тишина выглядит как здоровье. Заново обнаружьте текущий объект после изменения присутствия менеджера и запишите, когда произошло повторное обнаружение. Иначе журнал показывает туннель, который просто перестал отчитываться.
Доставьте уведомление туда, где находится пользователь
Привилегированный системный обратный вызов не наследует службу уведомлений сеанса рабочего стола. Сообщение, отправленное из обработчика уровня root, может исчезнуть без ошибки, что даёт уведомитель, который работает при ручной проверке и никогда на практике. Доставляйте в сеанс, которому принадлежит рабочий стол, или позвольте собственному клиенту рабочего стола поднять уведомление.
Предпочитайте существующее уведомление клиента, если оно уже покрывает случай, потому что два уведомителя на одно событие — это проблема поддержки, а не избыточность. Храните в записи поддержки время события, профиль и причину, а пароли и полные профили держите вне её. Помните, что такое уведомление: отчёт о наблюдаемом состоянии, а не механизм принуждения, потому что блокировка трафика при отсутствии туннеля — отдельная политика со своей реализацией.