Уведомление пользователя ядра

Время от времени драйвер — или в этом отношении любой тип расширения ядра — возможно, должен передать некоторую информацию пользователю. При некоторых обстоятельствах этому, возможно, даже придется предложить пользователю выбирать среди двух или больше альтернатив. Например, драйвер USB мог бы мягко напомнить пользователю, что в следующий раз она должна демонтировать объем прежде физически разъединить его. Или драйвер массового хранения мог бы спросить пользователя, если он действительно уверен, что хочет повторно инициализировать устройство, давая ему опцию отменить работу.

Для этих ситуаций можно использовать Kernel-User Notification Center (KUNC). APIs средства KUNC позволяет Вам сделать следующее:

APIs KUNC должен использоваться экономно. Необходимо отправить уведомления пространству пользователя только, когда важно, что пользователь знает об или реагирует на особую ситуацию, связанную с аппаратными средствами. Например, драйвер средств массовой информации не должен поднимать диалоговое окно уведомления, когда он встречается со сбойным блоком. Однако, если пользователь монтирует зашифрованный диск, драйвер должен обеспечить некоторый пользовательский интерфейс, позволяющий пользователю разблокировать диск.

Конечно, любая коммуникация, выполненная через средство KUNC, может только инициироваться расширением ядра. Если у Вас есть пользовательская программа, которая должна связаться с драйвером, необходимо использовать подходящую альтернативу, такую как предоставленный Apple интерфейс устройства, пользовательский пользовательский клиент, POSIX вызовы I/O или свойства I/O Registry.

APIs KUNC определяется в Kernel.framework/Headers/UserNotification/.

Представление диалоговых окон уведомления

Для более простых форм уведомления APIs KUNC обеспечивает функцию, выводящую на экран диалоговое окно уведомления (KUNCNotificationDisplayNotice) и функция, выводящая на экран предупредительное диалоговое окно (KUNCNotificationDisplayAlert). Различие между уведомлением и предупреждением является прямым:

Рисунок 5-1  
A KUNC notice
KUNC noticeFigure 5-2
  предупреждение KUNC
A KUNC alert

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 описывает параметры этой функции.

Табличные 5-1  Параметры функции KUNCUserNotificationDisplayNotice

Параметр

Описание

тайм-аут

Секунды для протекания перед KUNC отклоняют диалоговое окно (и пользователь не нажимает кнопку по умолчанию). Если нуль указан, диалоговое окно автоматически не отклонено.

флаги

Флаги, представляющие предупредительный уровень (остановка, отметьте, предостерегите, или плоскость), и которые указывают, не должна ли появляться никакая кнопка по умолчанию. Эти флаги могут быть OR’d вместе. Проверьте константы, определенные в CFUserNotification Базовой Основы для констант для использования.

iconPath

Расположение файловой системы файла, содержащего значок ICNS или TIFF для отображения с текстом сообщения. Укажите абсолютный путь или NULL если нет никакого файла значка.

soundPath

Расположение файловой системы файла, содержащего звук для игры, когда диалоговое окно выведено на экран. Звуки в AIFF, WAV и форматах NeXT «.snd» поддерживаются. Укажите абсолютный путь или NULL если нет никакого файла значка. (В настоящее время unimplemented.able

localizationPath

Расположение файловой системы пакета, содержащего a Localizable.strings файл как локализованный ресурс. Если это верно, текст и заголовки, указанные для диалогового окна, являются ключами к локализованным строкам в этом файле. Укажите абсолютный путь или NULL если существует нет Localizable.strings файл.

alertHeader

Достижение к диалоговому окну.

alertMessage

Сообщение диалогового окна.

defaultButtonTitle

Заголовок кнопки по умолчанию (единственная кнопка в этом диалоговом окне). Стандартный заголовок «OK» подходит для большинства ситуаций.

KUNCUserNotificationDisplayAlert функция добавляет еще три параметра (Таблица 5-2).

Таблица 5-2  Дополнительные параметры KUNCUserNotificationDisplayAlert

Параметр

Описание

alternateButtonTitle

Заголовок альтернативной кнопки (например, «Отмена»).

otherButtonTitle

Заголовок третьей кнопки.

responseFlags

Постоянное представление кнопки щелкнуло: kKUNCDefaultResponse, kKUNCAlternateResponse, kKUNCOtherResponse, kKUNCCancelResponse.

Перечисление 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. Эта функция берет три параметра:

Код, показанный в Перечислении 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.

Таблица 5-3  KUNC XML диалоговые свойства уведомления

Ключ

Ввести

Описание

Заголовок

строка

Заголовок диалогового окна.

Сообщение

строка

Текст сообщения в диалоговом окне. Текст может включать “%” заполнители, когда пакет загружается, заменяющиеся - разграниченные подстроки в tokenString параметре функции KUNCUserNotificationDisplayFromBundle. Посмотрите Таблицу 5-4 для этого и других параметров.

Заголовок кнопки OK

строка

Заголовок кнопки по умолчанию диалогового окна (обычно называл «OK»). Эта кнопка является одним самым близким к правому краю диалогового окна.

Альтернативный заголовок кнопки

строка

Заголовок альтернативной кнопки диалогового окна (часто называемая «Отмена»). Эта кнопка является одним самым близким к левому краю диалогового окна.

Другой заголовок кнопки

строка

Заголовок третьей допустимой кнопки, помещающейся между другими двумя кнопками.

Значок URL

строка

Абсолютный путь POSIX, идентифицирующий файл, содержащий TIFF или ICNS, отображает для отображения рядом с текстом сообщения.

Звуковой URL

строка

Абсолютный путь POSIX, идентифицирующий файл, содержащий звук для игры, когда диалоговое окно выведено на экран. Звуки в AIFF, WAV и форматах NeXT «.snd» поддерживаются. (В настоящее время нереализовываемый.)

Локализация URL

строка

Абсолютный путь POSIX, идентифицирующий пакет, содержащий a Localizable.strings файл, от которого можно получить локализованный текст. Если это свойство указано, все связанные с текстом значения в XML-описании, как предполагается, являются ключами к элементам в Localizable.strings.

Тайм-аут

строка

Число, указывающее число секунд перед диалоговым окном, автоматически отклонено. Если нуль будет указан, то диалоговое окно не испытает таймаут.

Предупредительный уровень

строка

Берет «Остановку», «Уведомление» или «Предупреждение» для идентификации серьезности предупреждения. Каждому предупредительному уровню связали значок с ним. Если Вы не указываете предупредительный уровень, «Уведомление» становится значением по умолчанию.

Блокирование сообщения

строка

Или «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 описывает параметры этой функции.

Табличные 5-4  параметры KUNCUserNotificationDisplayFromBundle

Параметр

Описание

notificationID

Значение типа KUNCUserNotificationID это идентифицирует диалоговый запрос. Вы получаете это значение через KUNCGetNotificationID функция.

bundleIdentifier

Расположение (указанный как абсолютный путь) пакета, содержащего файл с XML-описаниями диалоговых окон уведомления. Примером такого пути мог бы быть «/system/library/extensions/mydriver.kext».

Следующие версии KUNC разрешат спецификацию пакета CFBundleIdentifier вместо этого; это будет предпочтительным способом идентифицировать пакеты.

имя файла

Имя файла, от которого можно получить XML-описания диалоговых окон. Это имя должно опустить расширение файла.

fileExtension

Расширение XML-файла, минус период; это может быть чем-либо, таким как «dict» или «xml».

messageKey

Имя ключа XML, идентифицирующего диалоговое описание, Вы хотите иметь KUNC, получает от файла.

tokenString

Строка, которая может содержать одну или более маркерных подстрок. Каждой подстрокой, разделяющейся от смежных подстрок символ, заменяют поочередно каждый “%” заполнитель в тексте сообщения диалогового окна (ключ XML «сообщение»).

Вот пример: если текст сообщения является “Доступом запрещен после того, как % попытается получить доступ к % учетной записи”. и строка маркера «4@jdoe», выведенная на экран строка является “Доступом запрещен после 4 попыток получить доступ к учетной записи jdoe”.

обратный вызов

Функция обратного вызова, вызывающаяся, когда пользователь нажимает одну из кнопок диалогового окна. Функция должна соответствовать KUNCUserNotificationCallback прототип.

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-3  диалоговое окно пароля
The password dialog

Конечно, у Вас могут быть еще более сложные диалоговые окна с соединением элементов пользовательского интерфейса. Перечисление 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, появляется на экране пользователя.

  Дисплей рисунка 5-4 смешанного диалогового окна управления
Display of a mixed control dialog