Не было нотификации о начале работы процесса 1с
Обновляем БГУ с 20.4 на 21.5 .
Когда дошли до Реорганизации информации табличка с измененными объектами "Изменение в структуре информации конфигурации" в которой кнопка "Принять" не активна, а в конце таблицы последний объект помечен красной звездочкой.
И конечно нажимая единственно доступную кнопку Отмена , мы не можем обновить конфигурацию.
Куда копать ?
(2) peterxx, хотела посмотреть какой объект , теперь вылетает при сравнении объектов (дошла до 81 %) , "1cv8.exe обнаружена ошибка. Приложение будет закрыто. Приносим извинения за неудобства."
Работает Касперский 13.0.1.4190.
Мне эта база досталась по наследству , что посмотреть кроме замочка ( он есть - вроде конфа неизмененная)?
Когда ухожу на обновление - выдается с 20.4 на 21.5 . Все как надо.
Ну для начала отключить Каспера, не похож он на доброе привидение, а потом, действительно скриншот, хотя бы.
(8) fktrc171, не тот скриншот, а с красной звездочкой. Это самое интересное. На всякий случай, такое бывает, когда некорректно пытаешься обновить уже существующие объекты в базе. Например меняешь тип реквизита в регистре накопления или сведений. Тогда обновлять тоже не дает, пока не удалишь существующие записи.
Почему-то у неизмененной конфы вылетает окно сравнения , проверила везде режим обновления - порядок из новой . говорю Выполнить , там далее "все не редактируется" и опять вдруг - приносим извинения.
Но что-то с базой надо делать . Ошибки - извинения постоянно вылетают при формировании отчетов - карточек счета , регламентных отчетов. Как лечить ?
(16) Так там же ясно причина указана: Записи регистра сведений стали неуникальными: СостояниеЭД.
Смотри что в регистре изменилось, скорее всего или реквизит удален какой-то, или подчинение регистратору изменено.
(16) fktrc171, Точно не редактировалась конфа?
замочек может быть по любому хоть на полной поддержке, хоть не на полной.
Проверьте Меню Конфигурация/Поддержка - что там стоит?
Конфигурация на поддержке с возможностью изменения или как?
Попробуйте проверить базу через C:\Program Files\1cv82\8.2.16.368\bin\chdbfl - может найдет и исправит ошибки, еще вариант через Администрирование - Тестирование и исправление. Только перед всем этим сделайте копию. Может косячные записи будут изменены и все обновится. Иначе руками их удалять, а потом перепроводить документы.
(23) Bukaska, все самое последнее.
(21) Bukaska, да, конфа на поддержке с возможностью изменения. Как это убрать ?
(24) не уверен, что поможет, но можно попробовать обновить конфой той же версии, которая полностью на поддержке и принять все изменения. То есть найти cf-файл 20.04 и обновить им Вашу базу, выбрав его, как файл обновления. Не забываем про бэкапы
(24) fktrc171, Вот в чем и дело.. раз стоит на поддержке с возможностью изменения, значит - конфу наверняка пилили.
Варианта два.
Или .. когда доходит дело до сравнения и объединения - ищете карандашик и смотрите что была за правка в регистре..
Если вы уверены что вы не пилили, что это глюк конфы(кста.. такое иногда бывает), то просто накатите файл конфигурации той же конфигурации, того же релиза. если выф уверены что конфа не правилась и не менялась
(27) fktrc171, Да.. Конфигурация/загрузить конфигурацию из файла.. Сначала свой релиз, что в данный момент, а потом если ошибка останется - то так же грузить файлов релиз постарше.
Впринципе в этом ничего страшного - накатывать файл конфигурации, вы же не на 10 релизов вперед накатываете, а постепенно.
Данная статья является анонсом новой функциональности.
Не рекомендуется использовать содержание данной статьи для освоения новой функциональности.
Полное описание новой функциональности будет приведено в документации к соответствующей версии.
Полный список изменений в новой версии приводится в файле v8Update.htm.
Планируется в версии 8.3.21
В версии 8.3.21 мы сделали ряд доработок, призванных сделать взаимодействие системы с пользователем более удобным для пользователя.
Помощь пользователю при ошибке при входе в систему
Если ошибка произошла при входе в систему, пользователю можно будет показать дополнительную информацию, которая сможет помочь ему решить возникшую проблему:
Ссылка на ресурс с информацией (например, на сайт, где описаны способы решения возникшей проблемы)
Ошибки, возникающие при входе в систему – одни из самых непростых в обработке. Такие ошибки, в частности, могут возникать из-за недоступности сервера 1С, и, значит, в этот момент с сервера нельзя получить данные о том, какую информацию показать пользователю. Поэтому описанную выше информацию можно записать для каждой базы в файл списка баз *.v8i – при неудачном входе в систему информация будет считана из этого файла (при доступности файла) и показана пользователю.
Есть варианты работы, когда файлы *.v8i недоступны – работа в облаке, удалённая работа и т.п. Поэтому эту информацию также можно настроить через стандартную обработку «Управление настройками отображения ошибок» (параметры «Текст помощи» и «Навигационная ссылка помощи») и сохранить в инфобазе. Если с клиента уже был ранее осуществлен успешный вход в систему – эти параметры считываются с сервера и кэшируется на клиенте.
Если клиент успешно связался с сервером и считал актуальные значения параметров «Текст помощи» и «Навигационная ссылка помощи», но далее при работе системы возникли проблемы при соединении с сервером – в диалоге попытки повторного подключения будут использованы последние считанные значения параметров.
Обратите внимание! Информация, записанная в файле *.v8i, и настройки параметров «Текст помощи» и «Навигационная ссылка помощи» - независимы друг от друга. В случае, если доступен файл *.v8i, но недоступен сервер 1С и на клиенте нет закэшированных значений параметров «Текст помощи» и «Навигационная ссылка помощи» – пользователю будет показана информация из файла *.v8i, в противном случае – информация из параметров «Текст помощи» и «Навигационная ссылка помощи».
Настройки подключения к базе
В файл списка баз (*.v8i) в свойства базы добавляется параметры:
StartupErrorHelpText (строка) – текст, отображаемый в диалоге ошибки до начала сеанса или диалоге попытки повторного подключения
StartupErrorHelpURL (строка) – ссылка на ресурс с информацией
Тонкий клиент
Проверьте сетевое соединение
Проверьте, что параметры подключения указаны верно
Если проблема возникла уже после начала работы с системой - на форме повтора попытки соединения с сервером отображаемый текст будет таким же, как и на таблице вверху, а полный текст можно посмотреть, нажав на ссылку «Показать подробности…».
Веб-клиент
При невозможности связаться с веб-сервером в браузере будет отображена страница с информацией об ошибке подключения, текстом, заданный в настройках, и текстом, полученным из запроса на адрес сервиса информации (т.е. фактически с той же информацией, что и в тонком клиенте):
Это будет работать при соблюдении нескольких условий:
На веб-сервер уже был осуществлен удачный вход из браузера (для кэширования на клиенте страницы, показывающей информацию об ошибке)
Браузер должен поддерживать технологию service-workers
Про сервер обработки ошибок при запуске
Выше мы упомянули параметр «Адрес сервиса обработки ошибок при запуске».
Если этот параметр задан, то при ошибках запуска по этому адресу клиент 1С сделает запрос дополнительной информации. А по этому адресу можно настроить веб-сервер, который будет отдавать более подробную информацию о текущей ситуации - информировать пользователей при возникновении неожиданных аварийных ситуаций и / или недоступности сервера и т.п. Например, можно отобразить пользователю текст “Мы уже работаем над проблемой. Работа сервера возобновится после 14:00”.
Для поддержки это сценария можно реализовывать совсем простой вариант: просто положить JSON-файл в папку и настроить веб-сервер (Apache, nginx, IIS) на отдачу этого файла. При возникновении проблем на сервере можно вписать в этот файл необходимый текст (userMessage) и настроить время, до которого этот текст будет отображаться на форме (в нашем примере – до 14:00).
Можно реализовывать и более сложные сценарии – например, отправлять информацию об ошибках при входе в систему на внутренний сервис техподдержки организации.
Отчет об ошибке
При формировании отчета об аварийном завершении добавляется возможность показа окна “О программе”.
Приветствую, камрады! Меня зовут Кирилл Сотников, я работаю в Центре Кибербезопасности и Защиты Ростелекома. И сегодня я хочу поделиться небольшим исследованием по отключению/обходу антивирусов и EDR в операционной системе Windows.
Введение
Исследование было бы невозможным без следующих материалов:
Blinding EDR On Windows – описание и внутреннее устройство системы нотификации о создании/завершении процессов и потоков и ее отключение.
Part 1: Fs Minifilter Hooking – описание и внутреннее устройство минифильтров файловой системы и их перехват.
Билли установил единые правила как для средств защиты, так и для вредоносного программного обеспечения на игровом поле ядра Windows, и все должны их соблюдать. А кто не соблюдает, тот получит BS0D на экране от Patchguard (конечно, его можно обойти, но это отдельная тема для обсуждения). Средства защиты точно будут соблюдать эти правила в режиме ядра.
Правил же для пользовательского режима не существует. Обладая соответствующими привилегиями (используя неправильные настройки безопасности или эксплуатируя ошибки), можно делать что угодно. Исключения составляют защищенные процессы, до которых тяжеловато дотянуться (но все же можно).
Рассмотрим, как работают средства защиты.
Принципы работы средств защиты
Все современные средства защиты работают в двух режимах: режиме ядра и режиме пользователя.
Режим ядра
Для контроля и обнаружения работы вредоносного программного обеспечения и аномальной активности операционная система предоставляет возможности регистрировать функции обработки событий, которые происходят в системе. Основные типы используемых событий:
события создания/завершения процессов;
события создания/завершения потоков;
события работы файловой системы: создание, удаление файлов, обращение к ним, получение списков файлов и директорий и т.д., так называемые минифильтры ФС.
Режим пользователя
В режиме пользователя средство защиты инжектирует свою DLL в недоверенный контролируемый процесс. Эта DLL осуществляет перехват опасных API функций, и на основании результата анализа принимается решение о вредоносности процесса.
События файловой системы используются для статического анализа файлов и принятия решения об их вредоносности, а события, связанные с созданием/завершением потоков и процессов, используются для динамического/поведенческого анализа процесса.
В данной статье я остановился на самой важной части средства защиты – его драйвере, который осуществляет регистрацию и обработку событий безопасности. Отключение от оповещения на эти события, позволяет заключить средство защиты в “песочницу”, в которой оно не будет видеть никаких событий происходящих в системе.
События создания/завершения процессов и потоков
За подписку на события создания/завершения процессов отвечают следующие функции NTAPI:
Важным параметром этих функций является NotifyRoutine (у первых двух функций) и NotifyInformation (у последней функции), который является адресом функции обратного вызова (callback-функции) обработчика событий.
После регистрации драйвером средства защиты callback-функции, отвечающей за обработку событий, всякий каждый раз, когда создается/завершается процесс, ему приходит уведомление. И драйвер может принять решение о разрешении его создания и инжекту своей DLL в этот процесс для динамического/поведенческого анализа.
Все три эти функции вызывают одну функцию – PspSetCreateProcessNotifyRoutine , которая осуществляет добавление/удаление из этой таблицы обработчика событий (рисунок 1).
Рисунок 1. Дизассемблерный листинг функции PspSetCreateProcessNotifyRoutine.
На рисунке 1 выделен фрагмент кода, который получает адрес этой таблицы. По этому адресу памяти мы видим массив указателей на callback-функции – обработчики событий создания/завершения процессов (рисунок 2).
Рисунок 2. Список адресов функций обработчиков событий создания/завершения процессов.
Зная, где находится этот массив, мы сможем повлиять на обработчики событий:
удалять их из списка путем обнуления указателя;
изменять указатель в списке;
отключить нотификацию легальным способом через NTAPI;
пропатчить саму функцию обработчика (например, инструкцией ret).
Их параметрами являются адреса callback-функций обработки событий создания/завершения потоков в системе.
Минифильтры файловой системы
Параметр const FLT_REGISTRATION *Registration , является указателем на структуру регистрации драйвера минифильтра.
В данной структуре находится поле структуры – const FLT_OPERATION_REGISTRATION *OperationRegistration .
Данное поле структуры является массивом еще одних структур FLT_OPERATION_REGISTRATION , каждый элемент которого описывает две callback-функции обработчика событий. А именно PreOperation – функции, которая выполняется перед выполнением этой операции на файловой системе и PostOperation – функции, которая выполняется после выполнения операции на файловой системе.
Именно эти callback-функции регистрируются средством защиты для мониторинга действий на файловой системе, действие которых далее и рассмотрим.
Из проведенного исследования 2 , стало известно, что в ядре эти функции обработчики представлены в виде двусвязного списка ( LIST_ENTRY ) структур CALLBACK_NODE в недокументированной структуре FLT_INSTANCE (рисунок 3).
Рисунок 3. Структура FLT_INSTANCE.
Одним из полей этой структуры является CallbackNodes – массив структур CALLBACK_NODE . Этот массив содержит адреса всех функций обратных вызовов, принадлежащие экземпляру минифильтра.
Для перечисления экземпляров драйверов минифильтров, т.е. для получения FLT_INSTANCE используется функция FltEnumerateInstances .
Рассмотрим структуру CALLBACK_NODE (рисунок 4):
Рисунок 4. Структура CALLBACK_NODE.
Поля данной структуры:
PreOperation и PostOperation – указывают, вызываются ли обратные вызовы до или после операции.
CallbackLinks – это двусвязный список структур CALLBACK_NODE (рисунок 5 и 6).
Взаимосвязь между структурами минифильтра, представлена на рисунке 5.
Рисунок 5. Взаимосвязь между структурами минифильтра
Или в обобщенном виде рисунок 6.
Рисунок 6. Двусвязный список CALLBACK_NODE
Поскольку структура FLT_INSTANCE является недокументированной, то соответственно тяжело найти смещение массива CALLBACK_NODE . Для получения этого смещения мы можем воспользоваться следующим методом.
Зарегистрируем собственный минифильтр с набором callback-функций, чтобы динамически найти смещение CallbackNodes . После нахождения массива CALLBACK_NODE мы можем просто перехватить PreOperation и PostOperation функции.
Практика
Для своего проекта я использовал два репозитория на GitHub, которые указаны в статьях 1 и 2 . В них по отдельности реализован почти весь наш функционал:
Нам осталось их объединить. За основу я взял первый проект и добавил в него файлы из второго проекта. Дополнительно пришлось заменить INF файл из второго проекта. Поскольку данный проект является минифильтром файловой системы, в нем находятся дополнительные секции описывающие параметры минифильтра и зависимости от драйвера FltMgr.
Соответственно для объединенного драйвера нужны одни точки входа для следующих функций:
DriverEntry – функция начальной инициализации драйвера;
DobroUnload – функция вызываемая при выгрузке драйвера;
DobroDeviceControl – функция обработки запросов из режима пользователя через функцию DeviceIoControl .
Дополнительно для выполнения нашего функционала я реализовал следующие функции:
FSH_GetListFilters – получение всех установленных минифильтров в файловой системе (возвращается пользователю по запросу в виде списке для отображения).
FSH_GetFSMinifilterByIndex – получение имени минифильтра по его индексу, когда пользователь выбирает индекс минифильтра, который нужно перехватить.
Для отключения нотификации минифильтра файловой системы средства защиты после перехвата PreOperation , функция перехватчик должна возвращать FLT_PREOP_SUCCESS_NO_CALLBACK и имеет следующий вид:
А для перехвата PostOperation , функция перехватчик имеет следующий вид:
Поскольку добавление нотификации о создании/завершении процесса, может быть выполнено одной из трех функций ( PsSetCreateProcessNotifyRoutine, PsSetCreateProcessNotifyRoutineEx, PsSetCreateProcessNotifyRoutineEx2 ), а у нас имеется только адрес функции, полученный из PspSetCreateProcessNotifyRoutine , по этому адресу невозможно определить тип функции. Для его удаления я просто выполнил перебор всех трех типов функций, и та, которая выполняется без ошибки, и есть наш тип нотификации:
После сборки проекта у нас должен получиться драйвер и клиентское приложение, которое управляет драйвером.
Установку и запуск драйвера можно выполнить с помощью следующих команд:
InfDefaultInstall.exe Dobro.inf – регистрация драйвера в SCM.
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\Dobro" /v "ImagePath" /t REG_EXPAND_SZ /d "\??\\Dobro.sys" /f – изменение пути до драйвера в реестре.
Sc start dobro – запуск драйвера.
Для тех, кто пользуется мышкой:
Правой клавишей на inf файл и в контекстном меню выбрать установить.
Затем в regedit.exe меняем значение ключа ImagePath , указывающего на путь до файла драйвера, находящегося в разделе реестра: HKLM\SYSTEM\CurrentControlSet\Services\Dobro .
Исследования я проводил на одном из антивирусов (разглашать название не буду). После проведения тестирования, дабы выяснить реакцию антивируса на снятие установленной им нотификации, выяснилось следующее.
Перехват нотификации минифильтра файловой системы позволил отключить антивирус от статического анализа файлов, т.е. теперь можно спокойно делать все что угодно на файловой системе, антивирус ничего не проверяет. Проверялось путем копирования на файловую систему импланта (т.н. Grunt) Covenant С2 – фреймворка для проведения тестирования на проникновение.
После удаления нотификации о создании/завершении процесса, стало невозможно ничего запустить, система впадает в "ступор" – это лечится перезагрузкой. Чтобы все было хорошо, необходимо сначала удалить нотификацию о создании/завершении потоков, а затем нотификацию о создании/завершении процессов. После этого антивирус работает как ни в чем не бывало, но уже не проверяя вновь запускаемые процессы и потоки путем инжектирования своей DLL для динамического – поведенческого анализа программ, позволяя запускать вредоносное программное обеспечение "без шума и пыли".
Проводя дальнейшее тестирование, выяснилось, что антивирус перестает обновляться, паникуя, что не может установить доверенное соединение с сервером. Видимо, при запуске процесса обновления антивирус должен получить нотификацию о создании своего процесса обновления, чтобы проконтролировать доверенность процесса обновления.
Чтобы все было стерильно, я решил добавить дополнительный функционал драйвера по перехвату функции нотификации о создании/завершении процессов и потоков и фильтрации по имени процесса. Когда создается новый процесс, мы проверяем его имя, если он принадлежит средству защите, то переправим нотификацию ему, если нет, ничего не делаем.
Я реализовал это так:
Удаляем нотификацию с помощью NTAPI PsSetCreateProcessNotifyRoutine или PsSetCreateProcessNotifyRoutineEx , или PsSetCreateProcessNotifyRoutineEx2 , в зависимости от типа, создаваемого средством защиты обработчика нотификации о создании/завершении процесса.
Создаем свой собственный обработчик нотификации о создании/завершении процесса соответствующей NTAPI ( PsSetCreateProcessNotifyRoutine или PsSetCreateProcessNotifyRoutineEx , или PsSetCreateProcessNotifyRoutineEx2 ).
В самом обработчике нотификации мы добавляем проверку на имя создаваемого процесса. Если процесс принадлежит средству защиты, то мы отправляем ему уведомление напрямую, путем вызова его функции по соответствующему указателю, иначе просто выходим из функции, ничего не делая.
После того как я реализовал перехват нотификации о создании/завершения процессов и потоков с фильтрацией по его имени, антивирус спокойно обновился – "в Багдаде все спокойно".
Таким образом, мы заключили антивирус в "песочницу", в которой он будет видеть только события связанные с собственной работой, а все остальные события не будут к нему приходить, путем:
отключения нотификации минифильтра файловой системы;
перехвата с фильтром по имени процесса нотификации о создании/завершении потоков;
перехвата с фильтром по имени процесса нотификации о создании/завершении процессов.
Основные функции драйвера, которые мы можем вызвать через клиентское приложение, представлены на рисунке 6.
Рисунок 6. Функционал драйвера.
В клиенте драйвера, помимо основных функций по снятию/перехвату/удалению нотификаций, реализована функция, тестирующая средство защиты путем создания нового процесса nslookup.exe и инжектирования в него шеллкода, который запускает notepad.exe.
Чтобы средство защиты сразу не "голосило" на этапе копирования в файловую систему, инжектирование осуществляется путем динамического получения адресов функций NtAllocateVirtualMemory, NtWriteVirtualMemory, NtCreateThreadEx из библиотеки NTDLL.DLL, при этом имена функций и имя библиотеки предварительно зашифрованы методом XOR ключом ‘$’. Ключ для расшифровки пользователь должен ввести вручную.
Что с запуском кода в ядре
В настоящее время проблем с подписью драйверов и выполнению кода в режиме ядра нет. Используем утекшие сертификаты или уязвимые злые драйвера.
Если вас заинтересовала эта тема, то советую почитать:
Лично я использовал утекшие сертификаты (если пошукать интернет, особенно китайские форумы, можно найти несколько сертификатов) для подписи драйвера с помощью утилиты TrustAsia.
Данную тему в настоящей статье развивать не будем.
Выводы
Какие я для себя сделал выводы:
Единые правила для ядра операционной системы Windows упрощают понимание внутреннего устройства и работы средств защиты и загоняют их в определенные рамки, которые можно обойти. Вредоносное программное обеспечение не скованно этими правилами, поэтому у него более широкая свобода действий.
То, что попало в ядро и выполняется там, считается доверенным и не проверяется.
21 апреля пользователи Сети начали сообщать о проблемах с работой всех сервисов 1С. Недоступны обновления, невозможно зайти в личный кабинет и на сервис ИТС, не работает ЭДО и 1С:отчётность. 25 числа необходимо подавать отчёт в налоговую, но его невозможно подготовить из-за сбоя.
В официальном Telegram-канале 1C:Франчайзи появилась информация, что доступ к сервисам пропал из-за DDoS-атаки на ресурсы 1С и часть сайтов компании.
По неподтверждённой информации, кроме 1C DDoS-атаке подверглись РАР и ФСС.
Информационная служба Хабра направила 1С запрос с просьбой дать официальный комментарий по ситуации. Как указали в компании:
«С 21 апреля происходят DDoS-атаки на различные сервисы для учёта и отчётности в организациях, в том числе на ресурсы 1С. Часть наших сайтов и сервисов была временно недоступна или работали медленно и неустойчиво. На данный момент восстановлено нормальное функционирование большинства интернет-ресурсов и сервисов 1С, включая 1С:ЭДО и 1С-Отчетность. DDoS-атаки продолжаются, технические специалисты 1С отслеживают ситуацию и принимают усилия для обеспечения нормального функционирования интернет-ресурсов и сервисов 1С. Угрозы для данных пользователей не наблюдается, они не пострадали и надёжно защищены».
Несмотря на заявление компании, пользователи Сети продолжают жаловаться на полное прекращение работы 1С. В частности, пользователь Хабра @nat_young рассказал, что со вчерашнего дня в работе сервисов практически ничего не изменилось.
У каждого тестировщика рано или поздно наступает неловкий момент. Обнаружился вредный баг и его необходимо локализовать. По закону подлости баг воспроизводится нестабильно, при непонятных шагах и только на некоторых устройствах. Есть логи, но они не информативны. Разработчик занимается новой функциональностью, он не может отвлечься от текущих задач, пока не будут найдены четкие шаги воспроизведения. Менеджер ждет исправления (надо быстрее, заказчик переживает).
Как внести ясность в такой ситуации? Некуда деваться, пора разбираться, что же там происходит «под капотом» приложения.
Конечно, можно перечитать всю доступную документацию для разработчиков, но вряд ли это время заложено в сроки проекта. Есть путь проще и продуктивнее: узнать у разработчика, что представляет из себя та функциональность, в которой возникает баг.
Понимая, из каких компонентов состоит приложение, вы сможете:
- Оптимальнее проектировать тест-кейсы (добавляя проверки, которые связаны с работой компонентов приложения).
- Увереннее локализовывать баги и понимать, что конкретно нужно проверить после их исправления.
- Обсуждать проблемы приложения с разработчиками, не плавая в непонятных терминах.
Предлагаю разобрать некоторые компоненты Андроид-системы и со стороны тестирования рассмотреть кейсы, которые надо проверять для них.
Давайте сразу оговорим, что определения в статье давались тестировщиком. Они не претендуют на истину в последней инстанции и могут содержать неточности. Комментарии и аргументированные замечания приветствуются.
В Андроиде все основано на работе процессов. Операционная система может завершить процесс, если он завис или появился новый с более высоким приоритетом. Когда пользователь видит результаты деятельности процесса, система воспринимает этот процесс как самый приоритетный. И при необходимости она будет закрывать его в последнюю очередь.
В процессах выполняется работа компонентов. Давайте начнем разбираться с таких компонентов, как активити и фрагменты, и рассмотрим кейсы, когда система может прекратить их работу.
Активити и фрагменты (activities and fragments)
С точки зрения тестировщика, активити можно воспринимать как экран, на котором отображаются элементы. Приложение состоит, как минимум, из одной активити. По сути, активити — это контейнер для UI-компонентов.
Если активити – это контейнер, то фрагменты – это UI-компоненты активити. Фрагмент тоже, в свою очередь, является контейнером для UI-компонентов.
Есть классная аналогия с браузером (спасибо разработчикам!) для более наглядного представления о том, как между собой связаны активити и фрагменты. Представим, что у нас открыто несколько окон одного браузера. Это несколько активити внутри одного приложения.
Внутри окна может быть открыто несколько вкладок. Это фрагменты внутри активити.
Фрагменты работают чуть быстрее, чем активити. Но на современных устройствах разница практически неощутима. В зависимости от того, каким образом решается задача, разработчик может написать приложение только на активити или на активити с использованием фрагментов.
Операционная система при управлении жизненным циклом приложения работает именно с активити приложения. Поэтому пока нас больше всего интересует жизненный цикл активити.
Пользователи запускают большое количество приложений, а значит, создается много процессов с активити. Каждый запущенный процесс съедает оперативную память устройства, и ее становится все меньше. Но Андроид тщательно следит за процессами и в случае нехватки ресурсов для выполнения более приоритетной работы закрывает те, которые менее приоритетны.
Давайте разберемся, в какой момент приложение «уязвимо» к таким решениям системы и как это может повлиять на его работоспособность.
Жизненный цикл активити
Для тех, кто не знал или знал, но забыл.
Жизненный цикл активити представлен следующими состояниями:
Теперь приведу примеры. Они покрывают основные кейсы, с которыми мы чаще всего сталкиваемся при тестировании.
Первый запуск приложения
При первом запуске приложения создается и загружается главная активити в приложении.
При переходе в состояние «Resumed» активити доступна для взаимодействия с пользователем. Все замечательно, проблем нет.
Переход с первого экрана на второй
Шаг 1: При переходе с первого экрана на второй активити первого экрана сначала встает на паузу. В этот момент могут выполняться такие действия, как сохранение введенных данных и остановка ресурсоемких операций (например, проигрывание анимаций). Это происходит довольно быстро и неощутимо для пользователя.
Шаг 2, 3, 4: Запускается активити второго экрана.
Шаг 5: Останавливается активити первого экрана. Также в случае, если Андроид в этот момент пытается освободить память, активити первого экрана дополнительно может перейти в состояние «Destroyed» (то есть уничтожиться).
Чтобы лучше понять, что из себя представляет состояние «Paused» давайте представим такую ситуацию: экран, поверх которого появился алерт. Мы не можем с ним взаимодействовать, но в то же время мы его видим.
Возврат со второго экрана на первый
При возврате со второго экрана на первый происходит почти то же самое, только первая активити не создается заново. Она подгружается из памяти (если, конечно, не была уничтожена системой). Вторая активити уничтожается после того, как была остановлена, так как она убирается из стека переходов.
Сворачивание и выход из приложения
При сворачивании приложения (например, по кнопке Home) активити останавливается.
Важно, чтобы при разворачивании приложения активити корректно восстановилась и данные сохранились.
На всех экранах стараемся проверять сворачивание-разворачивание приложения. Этот кейс особенно актуален на формах ввода. Согласитесь, будет обидно, если текст письма, который вы так старательно набирали, сотрется при банальном сворачивании приложения. Или форма, состоящая из множества полей, снова станет пустой.
При выходе из приложения (по аппаратной кнопке назад) помимо шага 1 и шага 2, выполняется шаг 3. Активити уничтожается и при следующем запуске приложения создается заново.
Поворот экрана
Один из значимых случаев, который плодит баги — это поворот экрана. Оказывается, при повороте экрана активити проходит полный жизненный цикл. А именно уничтожается и снова создается. И так при каждом повороте. Поэтому, опять же, проверяем поворот на каждом экране.
Поддержка горизонтальной ориентации экрана, с одной стороны, позволяет проверить корректность работы всех этапов активити, с другой стороны, значительно увеличивает количество тест-кейсов.
Многооконный режим
Начиная с Андроида 7 (с Андроида 6 как экспериментальная фича) стал доступен многооконный режим. Пользователи получили возможность видеть сразу несколько приложений на экране одновременно. При этом только то приложение, с которым пользователь сейчас взаимодействует, находится в состоянии «Resumed». Остальные устанавливаются в состояние «Paused».
Don’t keep activities (Не сохранять действия)
Надо ли проверять полный жизненный цикл активити, если приложение не поддерживает поворот экрана? Конечно, надо.
Если оперативная память давно не чистилась, ее не очень много, и в параллели с вашим приложением было запущено какое-нибудь ресурсоемкое приложение (например, PokemonGo), то шанс, что Андроид решит «прибить» процесс с вашей активити при переключении на другое приложение, возрастает.
Как проверить корректность работы приложения вручную, если оно не поддерживает поворот экрана? Довольно просто: установить галку «don’t keep activities» в настройках разработчика и перезапустить приложение.
В этом случае эмулируется ситуация, когда памяти не хватает и Андроид уничтожает все активити, с которыми пользователь сейчас не взаимодействует, оставляя только ту, что сейчас активна.
Это не значит, что галка должна всегда быть включенной при тестировании, но периодически смотреть приложение с опцией «don’t keep activities» полезно, чтобы пользователи со слабыми устройствами не сильно страдали и не ругали нас.
Broadcast receiver (широковещательный приемник)
Для обработки внешних событий используется компонент Broadcast receiver. Приложение может подписываться на события системы и других приложений. Андроид доставляет событие приложению-подписчику, даже если оно не запущено, и таким образом, может «мотивировать» его запуск.
При тестировании нам важно понимать, какие ожидаются события и как они обрабатываются.
Сервисы (Services)
Еще одна очень важная вещь в Андроиде — это сервисы. Они нужны для выполнения фоновых задач. При этом приложение не обязательно должно быть открыто пользователем в этот момент.
У сервисов есть несколько режимов работы. Пользователь может видеть, что сервис запущен, а может и совершенно не замечать его.
Если вы услышали волшебное слово «сервис» от разработчика, не поленитесь, выясните, какую логику работы заложили в него:
- Что делает сервис и в каком виде проявляет себя?
- Как ведет себя сервис, когда приложение не активно?
- Восстанавливается ли сервис после прерывания (входящего звонка, перезапуска телефона)?
Тут основной совет при проектировании тестовых сценариев — это обдумать пользовательские кейсы, когда работа сервиса может прерваться или начать конфликтовать с работой другого сервиса. Самые коварные ситуации: когда работа сервиса начинается, а пользователь этого не ждал. В этом случае полезно выяснить, что может спровоцировать запуск сервиса.
Еще один тип сервисов это sticky-сервисы. Если работа такого сервиса внезапно завершится, то спустя какое-то время sticky-сервис «возродится». Примечательно, что с каждым разом период до «возрождения» увеличивается, чтобы он меньше мешал работе системы. В некоторых приложениях примером sticky-сервиса может быть скачивание файлов на устройство. Возможно, вы замечали, если в «шторке» сбросить закачку, то спустя какое-то время она может восстановиться и продолжить скачивать файлы.
Самые важные сервисы — те, работу которых пользователь «ощущает» на себе и она для него важна. Они называются foreground-сервисы, и у них обязательно есть нотификация в «шторке», которую пользователь не может закрыть. Система их будет уничтожать в последнюю очередь, так как приоритет у таких сервисов самый высокий.
Например, музыкальный плеер. Если свернуть приложение и даже закрыть его, то плеер продолжает играть, пока пользователь не поставит его на паузу или не закроет. Или пока другое приложение или система не приостановит его работу. В частности, для музыкального плеера вариантов может быть много: входящий звонок, другое музыкальное приложение, звуковая нотификация.
Раз речь зашла о музыкальных плеерах, то стоит отметить такое понятие, как аудиофокус.
Аудиофокус
Представим, что при запуске нескольких аудиоплееров, они все будут играть одновременно. Вряд ли это кому-то понравится. Тут на помощь приходит аудиофокус, который запрашивается приложением у системы. В случае обычного запроса аудиофокуса система как бы оповещает все запущенные приложения: «Сейчас другое приложение будет говорить, помолчите, пожалуйста». Забавно, но это происходит именно в формате просьбы.
Если ваше приложение не очень вежливое, то оно спокойно может проигнорировать запрос. Наша задача – проверять эти ситуации.
Компромиссный режим запроса аудиофокуса называется «временным перехватом аудиофокуса». Это значит, что вашему приложению вернется аудиофокус, когда прервавшее его подаст системе сигнал, что аудиофокус освобожден.
Тестирование аудиофокуса очень важно, т.к. здесь все завязано на совести разработчиков и система не принимает особого участия в разрешении конфликтов. Ну а если баг все-таки вылезет к пользователям, то не сомневайтесь, они быстро вам об этом сообщат.
На этом, пожалуй, пока можно закончить. Конечно, есть еще много деталей и нет необходимости учитывать абсолютно все при тестировании. По моему опыту, тестировщику необходимо понимать из чего состоит приложение и как оно работает. Это дает возможность анализировать непростые баги, которые возникают на пересечении бизнес-логики приложения и особенностей работы операционной системы. Особенно если дело касается Андроида.
P.S. Во время написания статьи у нас возник спор. Как думаете вы, к какому роду относится слово "Активити"?
Читайте также: