Уведомление пользователя ядра
Время от времени драйвер — или в этом отношении любой тип расширения ядра — возможно, должен передать некоторую информацию пользователю. При некоторых обстоятельствах этому, возможно, даже придется предложить пользователю выбирать среди двух или больше альтернатив. Например, драйвер USB мог бы мягко напомнить пользователю, что в следующий раз она должна демонтировать объем прежде физически разъединить его. Или драйвер массового хранения мог бы спросить пользователя, если он действительно уверен, что хочет повторно инициализировать устройство, давая ему опцию отменить работу.
Для этих ситуаций можно использовать Kernel-User Notification Center (KUNC). APIs средства KUNC позволяет Вам сделать следующее:
Поднимите диалоговое окно уведомления неблокирования.
Эти уведомления строго информативны и разрешают коду вызова сразу возвратиться. Нажатие единственной кнопки (назвал «OK») просто закрывает диалоговое окно.
Представьте диалоговое окно уведомления блокирования.
В этом экземпляре диалоговое окно имеет две или больше кнопки, каждый предлагающий пользователю различный выбор. Ваши блоки драйвера, пока пользователь не нажимает кнопку, и затем отвечает способом, надлежащим нажатой кнопке.
Запустите программу пространства пользователя или откройте предпочтительную область (Приложение установок системы).
Можно использовать этот API, чтобы позволить пользователю устанавливать элементы или конфигурировать драйвер.
Загрузите более сложный пользовательский интерфейс из пакета.
Пакет обычно является водительским расширением ядра, и загруженный элемент является списком свойств XML. Эта альтернатива позволяет элементы, такие как раскрывающиеся списки, переключатели, и текстовые поля, а также заголовки кнопки и настраиваемое сообщение. Поскольку выведенная на экран информация хранится в пакете, она может быть локализована.
APIs KUNC должен использоваться экономно. Необходимо отправить уведомления пространству пользователя только, когда важно, что пользователь знает об или реагирует на особую ситуацию, связанную с аппаратными средствами. Например, драйвер средств массовой информации не должен поднимать диалоговое окно уведомления, когда он встречается со сбойным блоком. Однако, если пользователь монтирует зашифрованный диск, драйвер должен обеспечить некоторый пользовательский интерфейс, позволяющий пользователю разблокировать диск.
Конечно, любая коммуникация, выполненная через средство KUNC, может только инициироваться расширением ядра. Если у Вас есть пользовательская программа, которая должна связаться с драйвером, необходимо использовать подходящую альтернативу, такую как предоставленный Apple интерфейс устройства, пользовательский пользовательский клиент, POSIX вызовы I/O или свойства I/O Registry.
APIs KUNC определяется в Kernel.framework/Headers/UserNotification/
.
Представление диалоговых окон уведомления
Для более простых форм уведомления APIs KUNC обеспечивает функцию, выводящую на экран диалоговое окно уведомления (KUNCNotificationDisplayNotice
) и функция, выводящая на экран предупредительное диалоговое окно (KUNCNotificationDisplayAlert
). Различие между уведомлением и предупреждением является прямым:
Уведомление (рисунок 5-1) используется просто для информирования пользователя о некоторой ситуации, связанной с аппаратными средствами; потому что это не требует ответа от пользователя, код вызова не блокируется. Если тайм-аут используется, никакая кнопка, уведомление имеет только одну кнопку или. Нажатие кнопки просто отклоняет диалоговое окно.
Предупреждение (рисунок 5-2) не только говорит пользователю о некотором событии, связанном с аппаратными средствами, но запрашивает пользователя сделать выбор среди двух или трех альтернатив, связанных с тем событием. Код, вызывая KUNC предупреждает функциональные блоки, пока пользователь не нажимает одну из кнопок для указания выбора; это тогда должно интерпретировать, какая кнопка была нажата и действие соответственно. Можно указать период тайм-аута, и если период истекает без пользователя, делающего выбор, KUNC закрывает диалоговое окно и возвращает действие по умолчанию (связанный с мигающей кнопкой).
KUNCUserNotificationDisplayNotice
и KUNCUserNotificationDisplayAlert
функции имеют подобные подписи, список параметров последнего, являющийся надмножеством формирователя. Перечисление 5-1 показывает прототип для KUNCUserNotificationDisplayNotice
.
Определение перечисления 5-1 KUNCUserNotificationDisplayNotice
kern_return_t |
KUNCUserNotificationDisplayNotice( |
int timeout, |
unsigned flags, |
char *iconPath, |
char *soundPath, |
char *localizationPath, |
char *alertHeader, |
char *alertMessage, |
char *defaultButtonTitle); |
Таблица 5-1 описывает параметры этой функции.
KUNCUserNotificationDisplayAlert
функция добавляет еще три параметра (Таблица 5-2).
Параметр | Описание |
---|---|
alternateButtonTitle | Заголовок альтернативной кнопки (например, «Отмена»). |
otherButtonTitle | Заголовок третьей кнопки. |
responseFlags | Постоянное представление кнопки щелкнуло: |
Перечисление 5-2 иллюстрирует, как Вы могли бы вызвать KUNCUserNotificationDisplayAlert
и (тривиально) интерпретируйте ответ. Если kern_return_t
возвращаемое значение не KERN_SUCCESS
, тогда вызов перестал работать по некоторым причинам; можно распечатать строку, описывающую причину с mach_error_string
функция.
Вызов перечисления 5-2 KUNCUserNotificationDisplayAlert
kern_return_t ret; |
unsigned int rf; |
ret = KUNCUserNotificationDisplayAlert( |
10, |
0, |
NULL, |
NULL, |
NULL, |
"Something's Gone Terribly Wrong!", |
"Do you want to do anything about it?", |
"Yes", // Default |
"No", // Alternative |
"Think About It", // Other |
&rf); |
if (ret == KERN_SUCCESS) { |
if (rf == kKUNCDefaultResponse) |
IOLog("Default button clicked"); |
else if (rf == kKUNCAlternateResponse) |
IOLog("Alternate button clicked"); |
else if (rf == kKUNCOtherResponse) |
IOLog("Other button clicked"); |
} |
Запуск исполнимых программ пространства пользователя
Ваш код ядра может использовать Центр Уведомления Пользователя ядра для запуска приложений. Можно, таким образом, затронуть участие пользователя в сложной установке, конфигурации, и других задачах, связанных с драйвером или другом расширении ядра. Можно использовать KUNC не только, чтобы запустить приложения, но и представить предпочтительные области и выполнить демонов или другой (не-GUI) инструменты.
Функция KUNC, которую Вы вызываете для запуска приложения, KUNCExecute
. Эта функция берет три параметра:
Путь к исполнимой программе (executionPath). Путь файловой системы к приложению или другой исполнимой программе. Форма пути обозначена третьим параметром (pathExecutionType).
Авторизация пользователя (openAsUser). Уровень авторизации пользователя, данный запущенное приложение. Это может быть любой как зарегистрированный пользователь (
kOpenAppAsConsoleUser
) или как корень (kOpenAppAsRoot
). Задачи разрешений на доступ пользователя root, такие как копирование к/System/Library
без потребности аутентифицировать; необходимо использовать доступ пользователя root рассудительно.Тип исполнимого пути (pathExecutionType). Форма исполнимого пути, указанного в первом параметре (executionPath). Параметр должен быть одной из следующих констант:
Постоянный
Описание
kOpenApplicationPath
Абсолютный путь к исполнимой программе. Для приложения это - двоичный файл в комплекте приложений
MacOS
каталог (например,/Applications/Foo.app/Contents/MacOS/Foo
).kOpenPreferencePanel
Имя предпочтения разделяет на области в
/System/Library/PreferencePanes
(например,ColorSync.prefPane
).kOpenApplication
Имя приложения (минус.
app
) в любом из системных расположений для приложений:/Applications
,/Network/Applications
, или~/Applications
.
Код, показанный в Перечислении 5-3, запускает текстовое приложение Редактирования и открывает интернет-предпочтительную область.
Перечисление 5-3 , Запускающее приложения от KEXT
kern_return_t ret; |
ret = KUNCExecute("/Applications/TextEdit.app/Contents/MacOS/TextEdit", kOpenAppAsRoot, kOpenApplicationPath); |
ret = KUNCExecute("Internet.prefPane", kOpenAppAsConsoleUser, kOpenPreferencePanel); |
Это обычно - хорошая идея поднять уведомление (функция KUNCUserNotificationDisplayNotice
) одновременно Вы запускаете приложение или открываете предпочтительную область для информирования пользователей, что они должны сделать с предпочтительной областью или приложением.
Представление связанных диалоговых окон
Диалоговые окна, создаваемые через KUNCUserNotificationDisplayNotice
и KUNCUserNotificationDisplayAlert
функции имеют ограниченный набор элементов пользовательского интерфейса для представления пользователям. Кроме заголовка, значка и сообщения, они разрешают до трех кнопок, и вот именно. Единственной информацией, которую они могут выявить, является выбор, сделанный через щелчок кнопки.
KUNCUserNotificationDisplayFromBundle
функция, однако, позволяет Вам представить намного более богатый набор средств управления пользовательским интерфейсом и собрать больше информации от пользователя. Элементы, которые Вы можете иметь на связанном диалоговом окне, включают следующее:
Заголовок, текст сообщения, звук и значок
До трех кнопок (значение по умолчанию, альтернатива, другой)
Текстовые поля, включая поля пароля
Раскрывающиеся списки
Флажки
Переключатели
Ваше расширение ядра может получить выборы, которые пользователи делают и любой текст, что они вводят и обрабатывают эту информацию соответственно.
Средства управления и поведение этих диалоговых окон уведомления пользователя ядра получены как XML-описания, сохраненные в файле в пакете (обычно сам пакет KEXT). На основании того, чтобы быть связанным XML-описания локализуемы. Можно также обновить их без потребности в том, чтобы перекомпилировать. XML-файл можно назвать чем-либо. Это состоит из произвольного числа элементов словаря, один каждый для диалогового окна, которое могло бы представить расширение ядра. Каждое диалоговое описание само является словарем, ключи которого могут быть любым из описанных в Таблице 5-3.
Ключ | Ввести | Описание |
---|---|---|
Заголовок | строка | Заголовок диалогового окна. |
Сообщение | строка | Текст сообщения в диалоговом окне. Текст может включать “%” заполнители, когда пакет загружается, заменяющиеся - разграниченные подстроки в tokenString параметре функции |
Заголовок кнопки OK | строка | Заголовок кнопки по умолчанию диалогового окна (обычно называл «OK»). Эта кнопка является одним самым близким к правому краю диалогового окна. |
Альтернативный заголовок кнопки | строка | Заголовок альтернативной кнопки диалогового окна (часто называемая «Отмена»). Эта кнопка является одним самым близким к левому краю диалогового окна. |
Другой заголовок кнопки | строка | Заголовок третьей допустимой кнопки, помещающейся между другими двумя кнопками. |
Значок URL | строка | Абсолютный путь POSIX, идентифицирующий файл, содержащий TIFF или ICNS, отображает для отображения рядом с текстом сообщения. |
Звуковой URL | строка | Абсолютный путь POSIX, идентифицирующий файл, содержащий звук для игры, когда диалоговое окно выведено на экран. Звуки в AIFF, WAV и форматах NeXT «.snd» поддерживаются. (В настоящее время нереализовываемый.) |
Локализация URL | строка | Абсолютный путь POSIX, идентифицирующий пакет, содержащий a |
Тайм-аут | строка | Число, указывающее число секунд перед диалоговым окном, автоматически отклонено. Если нуль будет указан, то диалоговое окно не испытает таймаут. |
Предупредительный уровень | строка | Берет «Остановку», «Уведомление» или «Предупреждение» для идентификации серьезности предупреждения. Каждому предупредительному уровню связали значок с ним. Если Вы не указываете предупредительный уровень, «Уведомление» становится значением по умолчанию. |
Блокирование сообщения | строка | Или «0» или «1». Если «1», диалоговое окно не имеет никаких кнопок независимо ни от кого указанного. |
Строки текстового поля | массив строк | Список меток для отображения чуть выше текстовых полей они идентифицируют. Посмотрите рисунок 5-3 для наблюдения размера и размещения этих полей. |
Поля пароля | массив строк | Одна или более идентификаций чисел, которые из текстовых полей (который должен также быть указан) являются полем пароля. Другими словами, каждое число является индексом в массив текстовых полей. Поле пароля выводит на экран “\•” поскольку каждый символ вводится в нем. |
Строки кнопки всплывающего меню | массив строк | Список заголовков для каждого элемента в кнопке всплывающего меню. |
Выбранный раскрывающийся | строка | Число (индекс), идентифицирующий элемент для отображения в кнопке всплывающего меню. Если это не указано, первый элемент выведен на экран. |
Строки переключателя | массив строк | Список заголовков для каждого переключателя для отображения. Переключатели выровненные вертикально. Только единственная кнопка может быть нажата. |
Выбранное радио | строка | Число (индекс), идентифицирующий переключатель для показа, как выбрано. |
Строки флажка | массив строк | Список заголовков для каждого флажка для отображения. Флажки выровненные вертикально. Могут быть установлены многократные флажки. |
Установленные флажки | массив строк | Число (индекс), идентифицирующий флажок (или флажки), которые выбраны. |
Как обозначено в описании Localization URL
свойство выше, можно получить доступ к локализованному тексту двумя способами. У Вас могут быть локализованные версии самого файла XML-описания. Или у Вас могут быть единственный файл XML-описания и a Localizable.strings
файл для каждой локализации. В последнем случае, Localization URL
свойство указывает на пакет, содержащий Localizable.strings
файлы и значения текстовых свойств в файле XML-описания являются ключами в Localizable.strings
.
Желанный аспект функции связанных уведомлений KUNC - то, что это является асинхронным. Когда Вы вызываете KUNCUserNotificationDisplayFromBundle
функционируйте для запроса диалогового окна, вызов сразу возвращается. Ваш код может продолжить делать другие вещи. KUNC обрабатывает поставку запроса к пространству пользователя, где диалоговое окно создано и выведено на экран. В течение его поездки запрос идентифицируется уведомлением ID, к которому Вы предоставили KUNCUserNotificationDisplayFromBundle
. Когда пользователь нажимает одну из диалоговых кнопок, функция обратного вызова, реализованная в Вашем KEXT, вызывается. Там можно идентифицировать запрос через его уведомление ID и обработать ответ пользователя.
Перечисление 5-4 показывает подпись KUNCUserNotificationDisplayFromBundle
функция.
Объявление перечисления 5-4 KUNCUserNotificationDisplayFromBundle
kern_return_t |
KUNCUserNotificationDisplayFromBundle( |
KUNCUserNotificationID notificationID, |
char *bundleIdentifier, |
char *fileName, |
char *fileExtension, |
char *messageKey, |
char *tokenString, |
KUNCUserNotificationCallBackcallback, |
int contextKey); |
Таблица 5-4 описывает параметры этой функции.
Параметр | Описание |
---|---|
notificationID | Значение типа |
bundleIdentifier | Расположение (указанный как абсолютный путь) пакета, содержащего файл с XML-описаниями диалоговых окон уведомления. Примером такого пути мог бы быть «/system/library/extensions/mydriver.kext». Следующие версии KUNC разрешат спецификацию пакета |
имя файла | Имя файла, от которого можно получить XML-описания диалоговых окон. Это имя должно опустить расширение файла. |
fileExtension | Расширение XML-файла, минус период; это может быть чем-либо, таким как «dict» или «xml». |
messageKey | Имя ключа XML, идентифицирующего диалоговое описание, Вы хотите иметь KUNC, получает от файла. |
tokenString | Строка, которая может содержать одну или более маркерных подстрок. Каждой подстрокой, разделяющейся от смежных подстрок символ, заменяют поочередно каждый “%” заполнитель в тексте сообщения диалогового окна (ключ XML «сообщение»). Вот пример: если текст сообщения является “Доступом запрещен после того, как % попытается получить доступ к % учетной записи”. и строка маркера «4@jdoe», выведенная на экран строка является “Доступом запрещен после 4 попыток получить доступ к учетной записи jdoe”. |
обратный вызов | Функция обратного вызова, вызывающаяся, когда пользователь нажимает одну из кнопок диалогового окна. Функция должна соответствовать |
contextKey | Любая контекстная информация Вы хотите обеспечить, чтобы помочь Вашему расширению ядра идентифицировать запрос уведомления (в дополнение к уведомлению ID). |
Последний шаг в реализации связанных уведомлений для Вашего расширения ядра должен реализовать функцию обратного вызова для обработки пользовательских ответов. Эта функция должна соответствовать KUNCUserNotificationCallback
прототип:
typedef void (*KUNCUserNotificationCallBack)( |
int contextKey, |
int responseFlags, |
void *xmlData); |
Несколько параметров могут казаться знакомыми. contextKey параметр является тем же значением, которое Вы передали в KUNCUserNotificationDisplayFromBundle
функционируйте, чтобы помочь идентифицировать запрос. responseFlags параметр содержит одну из констант, идентифицирующих диалоговую кнопку, которую нажал пользователь; эти константы обсуждены inPresenting Диалоговые окна Уведомления. То, что является новым, является xmlData параметром. Это - строковые данные XML, связанные с ответом пользователя; если пользователь ввел информацию (такую как имя пользователя и пароль) или выбрал раскрывающийся элемент, переключатель или флажок, Ваш код должен проанализировать XML и извлечь эту информацию.
При парсинге XML необходимо искать соответствующий элемент массива, который Вы передали в KUNC. Например, если у Вас есть поле имени пользователя и поле пароля, у Вас есть a Text Field Strings
массив с двумя элементами. Когда Вы анализируете xmlData параметр, первый элемент Text Field Strings
имя пользователя, вводимое пользователем; второй элемент является паролем. Точно так же Вы анализируете Selected Popup
массив для наблюдения, какой индекс в тот массив был выбран.
Чтобы проиллюстрировать, как Вы могли бы использовать APIs KUNC для связанных диалоговых окон уведомления, давайте продвинемся через несколько примеров. Вы создаете вызванный XML-файл Messages.dict
и помещенный это в Ваш локализованный KEXT’s .lproj
каталоги. Этот файл содержит ключ «Password Message»; Перечисление 5-5 показывает связанное XML-описание для этого ключа.
XML-описание перечисления 5-5 диалогового окна пароля
<key>Password Message</key> |
<dict> |
<key>Alternate Button Title</key> |
<string>Cancel</string> |
<key>OK Button Title</key> |
<string>OK</string> |
<key>Header</key> |
<string>Authentication Message</string> |
<key>Message</key> |
<string>Please enter a user name and password.</string> |
<key>Timeout</key> |
<string>0</string> |
<key>Alert Level</key> |
<string>Stop</string> |
<key>Text Field Strings</key> |
<array> |
<string>User Name:</string> |
<string>Password:</string> |
</array> |
<key>Password Fields</key> |
<array> |
<string>1</string> |
</array> |
<key>Blocking Message</key> |
<string>1</string> |
</dict> |
В коде Вашего расширения ядра Вы вызываете KUNCUserNotificationDisplayFromBundle
, указание “Пароля обменивается сообщениями” как клавиша сообщения (Перечисление 5-6).
Перечисление 5-6 , Выводящее на экран связанное диалоговое окно пароля
context = 2; |
ret = KUNCUserNotificationDisplayFromBundle(KUNCGetNotificationID(), |
"/tmp/ExampleDriver/ExampleDriver.kext", |
"Messages", |
"dict", |
"Password Message", |
"", |
MyKUNCBundleCallback, |
context); |
Когда этот код выполняется, диалоговое окно, показанное в Перечислении 5-6, появляется на экране пользователя, как на рисунке 5-3.
Конечно, у Вас могут быть еще более сложные диалоговые окна с соединением элементов пользовательского интерфейса. Перечисление 5-7 показывает XML-описание диалогового окна, включающего текст и поля пароля и переключатели.
XML-описание перечисления 5-7 диалогового окна с различными средствами управления
<key>Mixed Message</key> |
<dict> |
<key>OK Button Title</key> |
<string>OK</string> |
<key>Header</key> |
<string>Authorization</string> |
<key>Message</key> |
<string>Please log in at required level.</string> |
<key>Timeout</key> |
<string>20</string> |
<key>Alert Level</key> |
<string>Stop</string> |
<key>Text Field Strings</key> |
<array> |
<string>User Name:</string> |
<string>Password:</string> |
</array> |
<key>Password Fields</key> |
<array> |
<string>1</string> |
</array> |
<key>Radio Button Strings</key> |
<array> |
<string>User</string> |
<string>Local Admin</string> |
<string>Network Admin</string> |
</array> |
<key>Selected Radio</key> |
<string>1</string> |
</dict> |
Когда Ваше загруженное расширение ядра вызывает KUNCUserNotificationDisplayFromBundle
функция, предоставление на сей раз “Смешанное сообщение” как ключ словаря XML, диалоговое окно, показанное на рисунке 5-4, появляется на экране пользователя.