Обзор функций и API

Android 15 предлагает отличные функции и API для разработчиков. В следующих разделах обобщаются эти функции, чтобы помочь вам начать работу с соответствующими API.

Подробный список добавленных, измененных и удаленных API можно найти в отчете о различиях API . Подробную информацию о добавленных API см. в справочнике по API Android . Для Android 15 найдите API, добавленные на уровне API 35. Чтобы узнать об областях, в которых изменения платформы могут повлиять на ваши приложения, обязательно ознакомьтесь с изменениями в поведении Android 15 для приложений, которые нацелен на Android 15 и для всех приложений .

Камера и медиа

Android 15 включает в себя множество функций, которые улучшают работу камеры и мультимедиа, а также дают вам доступ к инструментам и оборудованию, которые помогут авторам воплотить свои идеи в жизнь на Android.

Дополнительные сведения о новейших функциях и решениях для разработчиков мультимедиа и камер Android см. в докладе Google I/O «Создание современных мультимедийных возможностей и камер Android» .

Усиление при слабом освещении

В Android 15 представлен Low Light Boost — режим автоматической экспозиции, доступный как для Камеры 2 , так и для расширения камеры для ночного режима . Low Light Boost регулирует экспозицию потока предварительного просмотра в условиях низкой освещенности. Это отличается от того, как расширение камеры для ночного режима создает неподвижные изображения, поскольку ночной режим объединяет серию фотографий для создания единого улучшенного изображения. Хотя ночной режим очень хорошо работает для создания неподвижного изображения, он не может создавать непрерывный поток кадров, а режим Low Light Boost может. Таким образом, Low Light Boost обеспечивает такие возможности камеры, как:

  • Предоставление улучшенного предварительного просмотра изображения, чтобы пользователи могли лучше кадрировать свои снимки при слабом освещении.
  • Сканирование QR-кодов при слабом освещении

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

Приложения могут записывать поток предварительного просмотра в условиях низкой освещенности, чтобы сохранить более яркое видео.

Для получения дополнительной информации см. «Усиление при слабом освещении» .

Управление камерой в приложении

В Android 15 добавлено расширение для большего контроля над оборудованием камеры и ее алгоритмами на поддерживаемых устройствах:

  • Расширенные настройки мощности вспышки позволяют точно контролировать интенсивность вспышки как в режиме SINGLE , так и в режиме TORCH при съемке изображений.

HDR-контроль высоты

Android 15 выбирает запас HDR, соответствующий возможностям основного устройства и разрядности панели. Для страниц с большим количеством контента SDR, таких как приложение для обмена сообщениями, отображающее одну миниатюру HDR, такое поведение может в конечном итоге отрицательно повлиять на воспринимаемую яркость контента SDR. Android 15 позволяет управлять запасом HDR с помощью setDesiredHdrHeadroom чтобы обеспечить баланс между SDR и HDR-контентом.

Яркость элементов пользовательского интерфейса SDR на левом экране кажется более однородной, чем яркость на правом экране, что имитирует возможные проблемы с запасом при смешивании контента HDR и SDR. Регулируя запас HDR, вы можете добиться лучшего баланса между SDR и HDR-контентом.

Контроль громкости

Android 15 introduces support for the CTA-2075 loudness standard to help you avoid audio loudness inconsistencies and ensure users don't have to constantly adjust volume when switching between content. The system leverages known characteristics of the output devices (headphones and speaker) along with loudness metadata available in AAC audio content to intelligently adjust the audio loudness and dynamic range compression levels.

To enable this feature, you need to ensure loudness metadata is available in your AAC content and enable the platform feature in your app. For this, you instantiate a LoudnessCodecController object by calling its create factory method with the audio session ID from the associated AudioTrack; this automatically starts applying audio updates. You can pass an OnLoudnessCodecUpdateListener to modify or filter loudness parameters before they are applied on the MediaCodec.

// Media contains metadata of type MPEG_4 OR MPEG_D
val mediaCodec = 
val audioTrack = AudioTrack.Builder()
                                .setSessionId(sessionId)
                                .build()
...
// Create new loudness controller that applies the parameters to the MediaCodec
try {
   val lcController = LoudnessCodecController.create(mSessionId)
   // Starts applying audio updates for each added MediaCodec
}

AndroidX media3 ExoPlayer will also be updated to use the LoudnessCodecController APIs for a seamless app integration.

Виртуальные устройства MIDI 2.0

В Android 13 добавлена ​​поддержка подключения к устройствам MIDI 2.0 с помощью USB , которые обмениваются данными с помощью универсальных пакетов MIDI (UMP). Android 15 расширяет поддержку UMP на виртуальные MIDI-приложения , позволяя приложениям композиции управлять приложениями синтезатора как виртуальным устройством MIDI 2.0 так же, как если бы они работали с устройством USB MIDI 2.0.

Более эффективное программное декодирование AV1

логотип dav1d

dav1d , популярный программный декодер AV1 от VideoLAN, доступен для устройств Android, которые не поддерживают декодирование AV1 аппаратно. dav1d почти в 3 раза более производительен, чем устаревший программный декодер AV1, что позволяет воспроизводить HD AV1 большему количеству пользователей, включая некоторые устройства низкого и среднего уровня.

Ваше приложение должно согласиться на использование dav1d, вызвав его по имени "c2.android.av1-dav1d.decoder" . В последующем обновлении dav1d станет программным декодером AV1 по умолчанию. Эта поддержка стандартизирована и перенесена на устройства Android 11, которые получают обновления системы Google Play.

Производительность и инструменты разработчика

Хотя большая часть нашей работы по повышению вашей производительности сосредоточена вокруг таких инструментов, как Android Studio , Jetpack Compose и библиотеки Android Jetpack , мы всегда ищем способы в платформе, которые помогут вам легче реализовать свое видение.

Обновления OpenJDK 17

В Android 15 продолжается работа по обновлению основных библиотек Android, чтобы они соответствовали функциям последних выпусков OpenJDK LTS.

Включены следующие ключевые функции и улучшения:

Эти API обновляются на более чем миллиарде устройств под управлением Android 12 (уровень API 31) и более поздних версий посредством обновлений системы Google Play , поэтому вы можете использовать новейшие функции программирования.

Улучшения PDF

Android 15 includes substantial improvements to the PdfRenderer APIs. Apps can incorporate advanced features such as rendering password-protected files, annotations, form editing, searching, and selection with copy. Linearized PDF optimizations are supported to speed local PDF viewing and reduce resource use. The Jetpack PDF library uses these APIs to simplify adding PDF viewing capabilities to your app.

The latest updates to PDF rendering include features such as searching an embedded PDF file.

The PdfRenderer has been moved to a module that can be updated using Google Play system updates independent of the platform release, and we're supporting these changes back to Android 11 (API level 30) by creating a compatible pre-Android 15 version of the API surface, called PdfRendererPreV.

Усовершенствования автоматического переключения языка

В Android 14 добавлено распознавание нескольких языков в аудио на устройстве с автоматическим переключением между языками, но это может привести к пропаданию слов, особенно когда языки переключаются с меньшей паузой между двумя произнесениями. В Android 15 добавлены дополнительные элементы управления, которые помогают приложениям настроить это переключение в соответствии со своими сценариями использования. EXTRA_LANGUAGE_SWITCH_INITIAL_ACTIVE_DURATION_TIME_MILLIS ограничивает автоматическое переключение началом аудиосеанса, а EXTRA_LANGUAGE_SWITCH_MATCH_SWITCHES деактивирует переключение языка после определенного количества переключений. Эти параметры особенно полезны, если вы ожидаете, что во время сеанса будет говориться на одном языке, который должен определяться автоматически.

Улучшен API переменных шрифтов OpenType.

В Android 15 улучшено удобство использования переменного шрифта OpenType. Вы можете создать экземпляр FontFamily из переменного шрифта без указания осей веса с помощью API buildVariableFamily . Средство визуализации текста переопределяет значение оси wght , чтобы оно соответствовало отображаемому тексту.

Использование API значительно упрощает код для создания Typeface :

Котлин

val newTypeface = Typeface.CustomFallbackBuilder(
            FontFamily.Builder(
                Font.Builder(assets, "RobotoFlex.ttf").build())
                    .buildVariableFamily())
    .build()

Ява

Typeface newTypeface = Typeface.CustomFallbackBuilder(
            new FontFamily.Builder(
                new Font.Builder(assets, "RobotoFlex.ttf").build())
                    .buildVariableFamily())
    .build();

Раньше для создания того же Typeface требовалось гораздо больше кода:

Котлин

val oldTypeface = Typeface.CustomFallbackBuilder(
            FontFamily.Builder(
                Font.Builder(assets, "RobotoFlex.ttf")
                    .setFontVariationSettings("'wght' 400")
                    .setWeight(400)
                    .build())
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 100")
                        .setWeight(100)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 200")
                        .setWeight(200)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 300")
                        .setWeight(300)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 500")
                        .setWeight(500)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 600")
                        .setWeight(600)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 700")
                        .setWeight(700)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 800")
                        .setWeight(800)
                        .build()
                )
                .addFont(
                    Font.Builder(assets, "RobotoFlex.ttf")
                        .setFontVariationSettings("'wght' 900")
                        .setWeight(900)
                        .build()
                ).build()
        ).build()

Ява

Typeface oldTypeface = new Typeface.CustomFallbackBuilder(
    new FontFamily.Builder(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 400")
            .setWeight(400)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 100")
            .setWeight(100)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 200")
            .setWeight(200)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 300")
            .setWeight(300)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 500")
            .setWeight(500)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 600")
            .setWeight(600)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 700")
            .setWeight(700)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 800")
            .setWeight(800)
            .build()
    )
    .addFont(
        new Font.Builder(assets, "RobotoFlex.ttf")
            .setFontVariationSettings("'wght' 900")
            .setWeight(900)
            .build()
    )
    .build()
).build();

Вот пример того, как отображается Typeface созданный с использованием старого и нового API:

Пример того, как отличается рендеринг шрифтов с использованием новых и старых API

В этом примере Typeface , созданный с помощью старого API, не имеет возможности создавать точные веса шрифтов для экземпляров Font 350, 450, 550 и 650, поэтому средство визуализации возвращается к ближайшему весу. Таким образом, в этом случае вместо 350 отображается 300, вместо 450 отображается 400 и так далее. Напротив, Typeface , созданный с помощью новых API, динамически создает экземпляр Font для заданного веса, поэтому точные веса отображаются также для 350, 450, 550 и 650.

Детальный контроль разрыва строки

Starting in Android 15, a TextView and the underlying line breaker can preserve the given portion of text in the same line to improve readability. You can take advantage of this line break customization by using the <nobreak> tag in string resources or createNoBreakSpan. Similarly, you can preserve words from hyphenation by using the <nohyphen> tag or createNoHyphenationSpan.

For example, the following string resource doesn't include a line break, and renders with the text "Pixel 8 Pro." breaking in an undesirable place:

<resources>
    <string name="pixel8pro">The power and brains behind Pixel 8 Pro.</string>
</resources>

In contrast, this string resource includes the <nobreak> tag, which wraps the phrase "Pixel 8 Pro." and prevents line breaks:

<resources>
    <string name="pixel8pro">The power and brains behind <nobreak>Pixel 8 Pro.</nobreak></string>
</resources>

The difference in how these strings are rendered is shown in the following images:

Layout for a line of text where the phrase "Pixel 8 Pro." isn't wrapped using a <nobreak> tag.
Layout for the same line of text where the phrase "Pixel 8 Pro." is wrapped using a <nobreak> tag.

Архивирование приложений

В прошлом году Android и Google Play объявили о поддержке архивирования приложений , что позволяет пользователям освободить место за счет частичного удаления с устройства нечасто используемых приложений, опубликованных с помощью Android App Bundle в Google Play. Android 15 включает поддержку архивирования и разархивирования приложений на уровне ОС, что упрощает реализацию этой функции для всех магазинов приложений.

Приложения с разрешением REQUEST_DELETE_PACKAGES могут вызывать метод requestArchive PackageInstaller , чтобы запросить архивирование установленного пакета приложения, при этом APK и все кэшированные файлы удаляются, но пользовательские данные сохраняются. Архивированные приложения возвращаются как отображаемые приложения через API LauncherApps ; пользователи увидят сообщение пользовательского интерфейса, указывающее на то, что эти приложения заархивированы. Если пользователь нажмет на заархивированное приложение, ответственный установщик получит запрос на его разархивирование , а процесс восстановления можно будет отслеживать с помощью широковещательной рассылки ACTION_PACKAGE_ADDED .

Включите режим 16 КБ на устройстве, используя параметры разработчика.

Включите параметр разработчика «Загрузка с размером страницы 16 КБ», чтобы загрузить устройство в режиме 16 КБ.

Начиная с Android 15 QPR1, вы можете использовать опцию разработчика , доступную на некоторых устройствах, для загрузки устройства в режиме 16 КБ и выполнения тестирования на устройстве.

Этот вариант разработчика доступен на следующих устройствах:

  • Pixel 8 и 8 Pro (с Android 15 QPR1 или более поздней версии)

    Предупреждение . Из-за известной проблемы с Android 15 QPR2 Beta 3 сенсорный экран не работает на устройствах Pixel 8 после установки Android 15 QPR2 Beta 3 и загрузки устройства в режиме 16 КБ. Эта проблема не затрагивает устройства Pixel 8 Pro.

  • Pixel 8a (с Android 15 QPR1 или более поздней версии)

    Предупреждение . Из-за известной проблемы с Android 15 QPR2 Beta 3 сенсорный экран не работает на устройствах Pixel 8a после установки Android 15 QPR2 Beta 3 и загрузки устройства в режиме 16 КБ.

  • Pixel 9, 9 Pro и 9 Pro XL (с Android 15 QPR2 Beta 2 или более поздней версии)

Графика

В Android 15 реализованы новейшие графические улучшения, включая ANGLE и дополнения к графической системе Canvas.

Модернизация доступа к графическому процессору Android

Логотип Вулкан

Аппаратное обеспечение Android значительно изменилось с первых дней, когда основная ОС работала на одном процессоре, а доступ к графическим процессорам осуществлялся с использованием API-интерфейсов, основанных на конвейерах с фиксированными функциями. Графический API Vulkan® доступен в NDK начиная с Android 7.0 (уровень API 24) с абстракцией более низкого уровня, которая лучше отражает современное аппаратное обеспечение графического процессора, лучше масштабируется для поддержки нескольких ядер ЦП и обеспечивает снижение нагрузки на драйвер ЦП, что приводит к улучшению производительность приложения. Vulkan поддерживается всеми современными игровыми движками.

Vulkan — предпочтительный интерфейс Android для графического процессора. Поэтому Android 15 включает ANGLE в качестве дополнительного уровня для запуска OpenGL® ES поверх Vulkan. Переход на ANGLE позволит стандартизировать реализацию Android OpenGL для улучшения совместимости и, в некоторых случаях, повышения производительности. Вы можете проверить стабильность и производительность вашего приложения OpenGL ES с помощью ANGLE, включив опцию разработчика в «Настройки» -> «Система» -> «Параметры разработчика» -> «Экспериментально: включить ANGLE на Android 15».

Android ANGLE на дорожной карте Vulkan

Дорожная карта предстоящих изменений в API-интерфейсах графического процессора Android.

В рамках оптимизации нашего стека графических процессоров в дальнейшем мы будем поставлять ANGLE в качестве системного драйвера GL на большее количество новых устройств, при этом в будущем ожидается, что OpenGL/ES будет доступен только через ANGLE. При этом мы планируем продолжить поддержку OpenGL ES на всех устройствах .

Рекомендуемые следующие шаги

Используйте параметры разработчика, чтобы выбрать драйвер ANGLE для OpenGL ES и протестировать свое приложение. Для новых проектов мы настоятельно рекомендуем использовать Vulkan для C/C++.

Улучшения для холста

Android 15 продолжает модернизацию графической системы Android Canvas с дополнительными возможностями:

  • Matrix44 предоставляет матрицу 4x4 для преобразования координат, которую следует использовать, когда вы хотите манипулировать холстом в 3D.
  • clipShader пересекает текущий клип с указанным шейдером, а clipOutShader устанавливает для клипа разницу между текущим клипом и шейдером, каждый из которых рассматривает шейдер как альфа-маску. Это позволяет эффективно рисовать сложные формы.

Производительность и батарея

Android по-прежнему стремится помочь вам улучшить производительность и качество ваших приложений. В Android 15 представлены API, которые помогают повысить эффективность выполнения задач в вашем приложении, оптимизировать производительность приложения и собирать информацию о ваших приложениях.

Рекомендации по эффективному использованию батареи, отладке использования сети и энергопотребления, а также подробную информацию о том, как мы повышаем эффективность использования батареи при фоновой работе в Android 15 и последних версиях Android, см. в статье «Повышение эффективности использования батареи при фоновой работе на Android» от Google I/. О.

API-интерфейс ApplicationStartInfo

В предыдущих версиях Android запуск приложений был чем-то вроде загадки. В вашем приложении было сложно определить, началось ли оно с холодного, теплого или горячего состояния. Также было сложно узнать, сколько времени ваше приложение тратило на различных этапах запуска: разветвление процесса, вызов onCreate , рисование первого кадра и многое другое. Когда был создан экземпляр вашего класса Application , у вас не было возможности узнать, запускается ли приложение с широковещательной рассылки, поставщика контента, задания, резервной копии, завершения загрузки, сигнала тревоги или Activity .

API ApplicationStartInfo в Android 15 предоставляет все это и многое другое. Вы даже можете добавить в поток свои собственные временные метки, чтобы собирать данные о времени в одном месте. Помимо сбора метрик, вы можете использовать ApplicationStartInfo , чтобы напрямую оптимизировать запуск приложения; например, вы можете исключить дорогостоящее создание экземпляров библиотек, связанных с пользовательским интерфейсом, в классе Application , когда ваше приложение запускается из-за широковещательной рассылки.

Подробная информация о размере приложения

Начиная с Android 8.0 (уровень API 26), Android включает API StorageStats.getAppBytes , который суммирует установленный размер приложения как одно число байтов, которое представляет собой сумму размера APK, размера файлов, извлеченных из APK, и файлы, созданные на устройстве, такие как предварительно скомпилированный код (AOT). Это число не очень информативно с точки зрения того, как ваше приложение использует хранилище.

В Android 15 добавлен API StorageStats.getAppBytesByDataType([type]) , который позволяет вам получить представление о том, как ваше приложение использует все это пространство, включая разделение файлов APK, код, связанный с AOT и ускорением, метаданные dex, библиотеки и управляемые профили.

Профилирование, управляемое приложением

Android 15 includes the ProfilingManager class, which lets you collect profiling information from within your app such as heap dumps, heap profiles, stack sampling, and more. It provides a callback to your app with a supplied tag to identify the output file, which is delivered to your app's files directory. The API does rate limiting to minimize the performance impact.

To simplify constructing profiling requests in your app, we recommend using the corresponding Profiling AndroidX API, available in Core 1.15.0-rc01 or higher.

Улучшения базы данных SQLite

Android 15 introduces SQLite APIs that expose advanced features from the underlying SQLite engine that target specific performance issues that can manifest in apps. These APIs are included with the update of SQLite to version 3.44.3.

Developers should consult best practices for SQLite performance to get the most out of their SQLite database, especially when working with large databases or when running latency-sensitive queries.

  • Read-only deferred transactions: when issuing transactions that are read-only (don't include write statements), use beginTransactionReadOnly() and beginTransactionWithListenerReadOnly(SQLiteTransactionListener) to issue read-only DEFERRED transactions. Such transactions can run concurrently with each other, and if the database is in WAL mode, they can run concurrently with IMMEDIATE or EXCLUSIVE transactions.
  • Row counts and IDs: APIs were added to retrieve the count of changed rows or the last inserted row ID without issuing an additional query. getLastChangedRowCount() returns the number of rows that were inserted, updated, or deleted by the most recent SQL statement within the current transaction, while getTotalChangedRowCount() returns the count on the current connection. getLastInsertRowId() returns the rowid of the last row to be inserted on the current connection.
  • Raw statements: issue a raw SQlite statement, bypassing convenience wrappers and any additional processing overhead that they may incur.

Обновления Android Dynamic Performance Framework

В Android 15 мы продолжаем наши инвестиции в Android Dynamic Performance Framework (ADPF) — набор API-интерфейсов, которые позволяют играм и приложениям, требующим высокой производительности, более непосредственно взаимодействовать с энерго- и тепловыми системами устройств Android. На поддерживаемых устройствах в Android 15 добавлены возможности ADPF:

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

Чтобы узнать больше о том, как использовать ADPF в ваших приложениях и играх, перейдите к документации .

,

В Android 15 мы продолжаем наши инвестиции в Android Dynamic Performance Framework (ADPF) — набор API-интерфейсов, которые позволяют играм и приложениям, требующим высокой производительности, более непосредственно взаимодействовать с энерго- и тепловыми системами устройств Android. На поддерживаемых устройствах в Android 15 добавлены возможности ADPF:

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

Чтобы узнать больше о том, как использовать ADPF в ваших приложениях и играх, перейдите к документации .

,

В Android 15 мы продолжаем наши инвестиции в Android Dynamic Performance Framework (ADPF) — набор API-интерфейсов, которые позволяют играм и приложениям, требующим высокой производительности, более непосредственно взаимодействовать с энерго- и тепловыми системами устройств Android. На поддерживаемых устройствах в Android 15 добавлены возможности ADPF:

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

Чтобы узнать больше о том, как использовать ADPF в ваших приложениях и играх, перейдите к документации .

Конфиденциальность

Android 15 включает в себя множество функций, которые помогают разработчикам приложений защищать конфиденциальность пользователей.

Обнаружение записи экрана

Android 15 adds support for apps to detect that they are being recorded. A callback is invoked whenever the app transitions between being visible or invisible within a screen recording. An app is considered visible if activities owned by the registering process's UID are being recorded. This way, if your app is performing a sensitive operation, you can inform the user that they're being recorded.

val mCallback = Consumer<Int> { state ->
  if (state == SCREEN_RECORDING_STATE_VISIBLE) {
    // We're being recorded
  } else {
    // We're not being recorded
  }
}

override fun onStart() {
   super.onStart()
   val initialState =
      windowManager.addScreenRecordingCallback(mainExecutor, mCallback)
   mCallback.accept(initialState)
}

override fun onStop() {
    super.onStop()
    windowManager.removeScreenRecordingCallback(mCallback)
}

Расширенные возможности IntentFilter

Android 15 builds in support for more precise Intent resolution through UriRelativeFilterGroup, which contains a set of UriRelativeFilter objects that form a set of Intent matching rules that must each be satisfied, including URL query parameters, URL fragments, and blocking or exclusion rules.

These rules can be defined in the AndroidManifest XML file with the <uri-relative-filter-group> tag, which can optionally include an android:allow tag. These tags can contain <data> tags that use existing data tag attributes as well as the android:query and android:fragment attributes.

Here's an example of the AndroidManifest syntax:

<intent-filter android:autoVerify="true">
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.BROWSABLE" />
  <category android:name="android.intent.category.DEFAULT" />
  <data android:scheme="http" />
  <data android:scheme="https" />
  <data android:host="astore.com" />
  <uri-relative-filter-group>
    <data android:pathPrefix="/auth" />
    <data android:query="region=na" />
  </uri-relative-filter-group>
  <uri-relative-filter-group android:allow="false">
    <data android:pathPrefix="/auth" />
    <data android:query="mobileoptout=true" />
  </uri-relative-filter-group>
  <uri-relative-filter-group android:allow="false">
    <data android:pathPrefix="/auth" />
    <data android:fragmentPrefix="faq" />
  </uri-relative-filter-group>
</intent-filter>

Личное пространство

The private space can be unlocked and locked to show or hide sensitive apps on a device.

Private space lets users create a separate space on their device where they can keep sensitive apps away from prying eyes, under an additional layer of authentication. The private space uses a separate user profile. The user can choose to use the device lock or a separate lock factor for the private space.

Apps in the private space show up in a separate container in the launcher, and are hidden from the recents view, notifications, settings, and from other apps when the private space is locked. User-generated and downloaded content (such as media or files) and accounts are separated between the private space and the main space. The system sharesheet and the photo picker can be used to give apps access to content across spaces when the private space is unlocked.

Users can't move existing apps and their data into the private space. Instead, users select an install option in the private space to install an app using whichever app store they prefer. Apps in the private space are installed as separate copies from any apps in the main space (new copies of the same app).

When a user locks the private space, the profile is stopped. While the profile is stopped, apps in the private space are no longer active and can't perform foreground or background activities, including showing notifications.

We recommend that you test your app with private space to make sure your app works as expected, especially if your app falls into one of the following categories:

Запросить последний выбор пользователя для доступа к выбранным фотографиям

Приложения теперь могут выделять только те фотографии и видео, которые были выбраны последними, если предоставлен частичный доступ к медиа-разрешениям. Эта функция может улучшить взаимодействие с пользователем в приложениях, которые часто запрашивают доступ к фотографиям и видео. Чтобы использовать эту функцию в своем приложении, включите аргумент QUERY_ARG_LATEST_SELECTION_ONLY при запросе MediaStore через ContentResolver .

Котлин

val externalContentUri = MediaStore.Files.getContentUri("external")

val mediaColumns = arrayOf(
   FileColumns._ID,
   FileColumns.DISPLAY_NAME,
   FileColumns.MIME_TYPE,
)

val queryArgs = bundleOf(
   // Return only items from the last selection (selected photos access)
   QUERY_ARG_LATEST_SELECTION_ONLY to true,
   // Sort returned items chronologically based on when they were added to the device's storage
   QUERY_ARG_SQL_SORT_ORDER to "${FileColumns.DATE_ADDED} DESC",
   QUERY_ARG_SQL_SELECTION to "${FileColumns.MEDIA_TYPE} = ? OR ${FileColumns.MEDIA_TYPE} = ?",
   QUERY_ARG_SQL_SELECTION_ARGS to arrayOf(
       FileColumns.MEDIA_TYPE_IMAGE.toString(),
       FileColumns.MEDIA_TYPE_VIDEO.toString()
   )
)

Ява

Uri externalContentUri = MediaStore.Files.getContentUri("external");

String[] mediaColumns = {
    FileColumns._ID,
    FileColumns.DISPLAY_NAME,
    FileColumns.MIME_TYPE
};

Bundle queryArgs = new Bundle();
queryArgs.putBoolean(MediaStore.QUERY_ARG_LATEST_SELECTION_ONLY, true);
queryArgs.putString(MediaStore.QUERY_ARG_SQL_SORT_ORDER, FileColumns.DATE_ADDED + " DESC");
queryArgs.putString(MediaStore.QUERY_ARG_SQL_SELECTION, FileColumns.MEDIA_TYPE + " = ? OR " + FileColumns.MEDIA_TYPE + " = ?");
queryArgs.putStringArray(MediaStore.QUERY_ARG_SQL_SELECTION_ARGS, new String[] {
    String.valueOf(FileColumns.MEDIA_TYPE_IMAGE),
    String.valueOf(FileColumns.MEDIA_TYPE_VIDEO)
});

Песочница конфиденциальности на Android

Android 15 включает новейшие расширения Android Ad Services, включая последнюю версию Privacy Sandbox для Android . Это дополнение является частью нашей работы по разработке технологий, которые улучшают конфиденциальность пользователей и обеспечивают эффективную персонализированную рекламу для мобильных приложений. На нашей странице «Песочница конфиденциальности» вы найдете дополнительную информацию о предварительной версии и бета-версиях Privacy Sandbox для разработчиков Android, которые помогут вам начать работу.

Здоровье Connect

Android 15 объединяет новейшие расширения Health Connect от Android — безопасной и централизованной платформы для управления и обмена данными о здоровье и фитнесе, собранными приложениями. В этом обновлении добавлена ​​поддержка дополнительных типов данных о фитнесе , питании , температуре кожи, планах тренировок и многом другом.

Отслеживание температуры кожи позволяет пользователям хранить и передавать более точные данные о температуре с носимого или другого устройства отслеживания.

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

Узнайте больше о последних обновлениях Health Connect в Android в докладе «Создание адаптируемого опыта с помощью Android Health» от Google I/O.

,

Android 15 объединяет новейшие расширения Health Connect от Android — безопасной и централизованной платформы для управления и обмена данными о здоровье и фитнесе, собранными приложениями. В этом обновлении добавлена ​​поддержка дополнительных типов данных о фитнесе , питании , температуре кожи, планах тренировок и многом другом.

Отслеживание температуры кожи позволяет пользователям хранить и передавать более точные данные о температуре с носимого или другого устройства слежения.

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

Узнайте больше о последних обновлениях Health Connect в Android в докладе «Создание адаптируемого опыта с помощью Android Health» от Google I/O.

Совместное использование экрана приложения

Android 15 поддерживает совместное использование экрана приложения, поэтому пользователи могут делиться или записывать только окно приложения, а не весь экран устройства. Эта функция, впервые включенная в Android 14 QPR2, включает обратные вызовы MediaProjection , которые позволяют вашему приложению настраивать процесс совместного использования экрана приложения. Обратите внимание, что для приложений, предназначенных для Android 14 (уровень API 34) или выше, требуется согласие пользователя для каждого сеанса захвата MediaProjection .

Пользовательский опыт и системный интерфейс

Android 15 предоставляет разработчикам приложений и пользователям больше контроля и гибкости в настройке устройства в соответствии со своими потребностями.

Чтобы узнать больше о том, как использовать последние улучшения в Android 15 для улучшения пользовательского опыта вашего приложения, ознакомьтесь с докладом Google I/O «Улучшите пользовательский интерфейс вашего Android-приложения» .

Более расширенный предварительный просмотр виджетов с помощью Generated Previews API

До Android 15 единственным способом обеспечить предварительный просмотр средства выбора виджетов было указание статического изображения или ресурса макета . Эти предварительные просмотры часто существенно отличаются от внешнего вида фактического виджета, когда он размещен на главном экране. Кроме того, статические ресурсы невозможно создавать с помощью Jetpack Glance, поэтому разработчику Glance приходилось делать снимок экрана своего виджета или создавать макет XML, чтобы иметь предварительный просмотр виджета.

В Android 15 добавлена ​​поддержка созданных предварительных просмотров. Это означает, что поставщики виджетов приложений могут создавать RemoteViews для использования в качестве предварительного просмотра средства выбора вместо статического ресурса.

Приложения могут предоставлять удаленные представления средству выбора виджетов, чтобы они могли обновлять содержимое средства выбора, чтобы оно было более репрезентативным для того, что увидит пользователь.

Нажмите API

Приложения могут предоставлять сгенерированные предварительные просмотры через push API. Приложения могут предоставлять предварительные просмотры в любой момент своего жизненного цикла и не получают явного запроса от хоста на предоставление предварительных просмотров. Предварительные просмотры сохраняются в AppWidgetService , и хосты могут запрашивать их по требованию. В следующем примере загружается ресурс макета виджета XML и устанавливается его в качестве предварительного просмотра:

AppWidgetManager.getInstance(appContext).setWidgetPreview(
   ComponentName(
       appContext,
       SociaLiteAppWidgetReceiver::class.java
   ),
   AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
   RemoteViews("com.example", R.layout.widget_preview)
)

Ожидаемый поток:

  1. В любой момент поставщик виджетов вызывает setWidgetPreview . Предоставленные предварительные просмотры сохраняются в AppWidgetService вместе с другой информацией поставщика.
  2. setWidgetPreview уведомляет узлы об обновленной предварительной версии через обратный вызов AppWidgetHost.onProvidersChanged . В ответ хост виджета перезагружает всю информацию о своем провайдере.
  3. При отображении предварительного просмотра виджета хост проверяет AppWidgetProviderInfo.generatedPreviewCategories и, если выбранная категория доступна, вызывает AppWidgetManager.getWidgetPreview , чтобы вернуть сохраненный предварительный просмотр для этого провайдера.

Когда вызывать setWidgetPreview

Поскольку обратный вызов для предоставления предварительного просмотра отсутствует, приложения могут отправлять предварительные просмотры в любой момент их работы. Частота обновления предварительного просмотра зависит от варианта использования виджета.

В следующем списке описаны две основные категории вариантов использования предварительной версии:

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

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

Картинка в картинке

Android 15 introduces changes in Picture-in-Picture (PiP) ensuring an even smoother transition when entering into PiP mode. This will be beneficial for apps having UI elements overlaid on top of their main UI, which goes into PiP.

Developers use the onPictureInPictureModeChanged callback to define logic that toggles the visibility of the overlaid UI elements. This callback is triggered when the PiP enter or exit animation is completed. Beginning in Android 15, the PictureInPictureUiState class includes another state.

With this UI state, apps targeting Android 15 (API level 35) will observe the Activity#onPictureInPictureUiStateChanged callback being invoked with isTransitioningToPip() as soon as the PiP animation starts. There are many UI elements that are not relevant for the app when it is in PiP mode, for example views or layout that include information such as suggestions, upcoming video, ratings, and titles. When the app goes to PiP mode, use the onPictureInPictureUiStateChanged callback to hide these UI elements. When the app goes to full screen mode from the PiP window, use onPictureInPictureModeChanged callback to unhide these elements, as shown in the following examples:

override fun onPictureInPictureUiStateChanged(pipState: PictureInPictureUiState) {
        if (pipState.isTransitioningToPip()) {
          // Hide UI elements
        }
    }
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean) {
        if (isInPictureInPictureMode) {
          // Unhide UI elements
        }
    }

This quick visibility toggle of irrelevant UI elements (for a PiP window) helps ensure a smoother and flicker-free PiP enter animation.

Улучшенные правила «Не беспокоить»

AutomaticZenRule lets apps customize Attention Management (Do Not Disturb) rules and decide when to activate or deactivate them. Android 15 greatly enhances these rules with the goal of improving the user experience. The following enhancements are included:

  • Adding types to AutomaticZenRule, allowing the system to apply special treatment to some rules.
  • Adding an icon to AutomaticZenRule, helping to make the modes be more recognizable.
  • Adding a triggerDescription string to AutomaticZenRule that describes the conditions on which the rule should become active for the user.
  • Added ZenDeviceEffects to AutomaticZenRule, allowing rules to trigger things like grayscale display, night mode, or dimming the wallpaper.

Установите VibrationEffect для каналов уведомлений.

Android 15 supports setting rich vibrations for incoming notifications by channel using NotificationChannel.setVibrationEffect, so your users can distinguish between different types of notifications without having to look at their device.

Чип строки состояния медиапроекции и автоматическая остановка

Медиа-проекция может раскрыть личную информацию пользователя. Новый, заметный чип строки состояния информирует пользователей о любой текущей проекции экрана. Пользователи могут коснуться чипа, чтобы остановить трансляцию экрана, совместное использование или запись. Кроме того, для более интуитивно понятного взаимодействия с пользователем любое текущее проецирование экрана теперь автоматически останавливается при блокировке экрана устройства.

Чип строки состояния для совместного использования экрана, трансляции и записи.

Большие экраны и форм-факторы

Android 15 предоставляет вашим приложениям поддержку, позволяющую максимально эффективно использовать форм-факторы Android, включая большие экраны, раскладные и складные устройства.

Улучшена многозадачность на большом экране.

Android 15 дает пользователям больше возможностей для многозадачности на устройствах с большим экраном. Например, пользователи могут сохранить свои любимые комбинации приложений с разделенным экраном для быстрого доступа и закрепить панель задач на экране для быстрого переключения между приложениями. Это означает, что обеспечение адаптивности вашего приложения важнее, чем когда-либо.

Google I/O проводит сеансы по созданию адаптивных приложений для Android и созданию пользовательского интерфейса с помощью адаптивной библиотеки Material 3, которые могут вам помочь, а в нашей документации есть дополнительные сведения, которые помогут вам проектировать для больших экранов .

Поддержка обложки экрана

Ваше приложение может объявить свойство , которое Android 15 использует, чтобы позволить вашему Application или Activity отображаться на небольших верхних экранах поддерживаемых переворачивающихся устройств. Эти экраны слишком малы, чтобы их можно было рассматривать как совместимые цели для запуска приложений Android, но ваше приложение может согласиться на их поддержку, что сделает ваше приложение доступным в большем количестве мест.

Возможности подключения

Android 15 обновляет платформу, предоставляя вашему приложению доступ к новейшим достижениям в области связи и беспроводных технологий.

Спутниковая поддержка

Android 15 продолжает расширять поддержку платформы для спутниковой связи и включает в себя некоторые элементы пользовательского интерфейса, обеспечивающие единообразный пользовательский опыт в сфере спутниковой связи.

Приложения могут использовать ServiceState.isUsingNonTerrestrialNetwork() для определения того, когда устройство подключено к спутнику, что дает им больше информации о том, почему все сетевые службы могут быть недоступны. Кроме того, Android 15 обеспечивает поддержку приложений SMS и MMS, а также предустановленных приложений RCS для использования спутниковой связи для отправки и получения сообщений.

Уведомление появляется при подключении устройства к спутнику.

Более плавная работа с NFC

Android 15 работает над тем, чтобы сделать процесс оплаты одним касанием более простым и надежным, продолжая при этом поддерживать надежную экосистему приложений Android NFC. На поддерживаемых устройствах приложения могут запрашивать NfcAdapter для перехода в режим наблюдения , в котором устройство прослушивает, но не отвечает устройствам чтения NFC, отправляя на обработку объекты PollingFrame службы NFC приложения. Объекты PollingFrame можно использовать для аутентификации перед первой связью со считывателем NFC, что во многих случаях позволяет выполнить транзакцию одним касанием.

Кроме того, приложения могут зарегистрировать фильтр на поддерживаемых устройствах, чтобы они могли получать уведомления об активности цикла опроса, что обеспечивает бесперебойную работу с несколькими приложениями, поддерживающими NFC.

Роль кошелька

Android 15 introduces a Wallet role that allows tighter integration with the user's preferred wallet app. This role replaces the NFC default contactless payment setting. Users can manage the Wallet role holder by navigating to Settings > Apps > Default Apps.

The Wallet role is used when routing NFC taps for AIDs registered in the payment category. Taps always go to the Wallet role holder unless another app that is registered for the same AID is running in the foreground.

This role is also used to determine where the Wallet Quick Access tile should go when activated. When the role is set to "None", the Quick Access tile isn't available and payment category NFC taps are only delivered to the foreground app.

Безопасность

Android 15 помогает повысить безопасность вашего приложения, защитить данные вашего приложения, а также предоставляет пользователям большую прозрачность и контроль над своими данными. Дополнительную информацию о том, что мы делаем для улучшения защиты пользователей и защиты вашего приложения от новых угроз, см. в докладе «Защита безопасности пользователей на Android» от Google I/O.

Интегрируйте диспетчер учетных данных с автозаполнением

Начиная с Android 15, разработчики могут связывать определенные представления, такие как поля имени пользователя или пароля, с запросами диспетчера учетных данных , что упрощает предоставление индивидуального пользовательского опыта во время процесса входа. Когда пользователь фокусируется на одном из этих представлений, соответствующий запрос отправляется в Credential Manager. Полученные учетные данные объединяются между поставщиками и отображаются в резервных пользовательских интерфейсах автозаполнения, таких как встроенные или раскрывающиеся предложения. Библиотека Jetpack androidx.credentials является предпочтительной конечной точкой для разработчиков и скоро будет доступна для дальнейшего улучшения этой функции в Android 15 и более поздних версиях.

Интегрируйте регистрацию и вход в систему одним касанием с биометрическими подсказками.

Credential Manager интегрирует биометрические запросы в процессы создания учетных данных и входа в систему , устраняя необходимость для поставщиков управлять биометрическими запросами. В результате поставщикам учетных данных необходимо сосредоточиться только на результатах потоков создания и получения, дополненных результатами биометрического потока. Этот упрощенный процесс обеспечивает более эффективный и оптимизированный процесс создания и поиска учетных данных.

Управление ключами для сквозного шифрования

Мы представляем E2eeContactKeysManager в Android 15, который упрощает сквозное шифрование (E2EE) в ваших приложениях Android, предоставляя API на уровне ОС для хранения криптографических открытых ключей.

E2eeContactKeysManager предназначен для интеграции с приложением контактов платформы, чтобы предоставить пользователям централизованный способ управления и проверки открытых ключей своих контактов.

Проверки разрешений для URI контента

В Android 15 представлен набор API, которые выполняют проверку разрешений для URI контента:

  • Context.checkContentUriPermissionFull : выполняет полную проверку разрешений для URI контента.
  • Атрибут манифеста Activity requireContentUriPermissionFromCaller : обеспечивает соблюдение указанных разрешений для предоставленных URI контента при запуске действия.
  • Класс ComponentCaller для вызывающих Activity : представляет приложение, запустившее действие.

Доступность

В Android 15 добавлены функции, улучшающие доступность для пользователей.

Улучшенный шрифт Брайля

В Android 15 мы позволили TalkBack поддерживать дисплеи Брайля, использующие стандарт HID, как через USB, так и через защищенный Bluetooth.

Этот стандарт, очень похожий на тот, который используется в мышах и клавиатурах, со временем поможет Android поддерживать более широкий спектр дисплеев Брайля.

Интернационализация

В Android 15 добавлены функции и возможности, которые улучшают взаимодействие с пользователем при использовании устройства на разных языках.

Переменный шрифт CJK

Начиная с Android 15, файл шрифта для китайского, японского и корейского (CJK) языков NotoSansCJK теперь является переменным шрифтом. Вариативные шрифты открывают возможности для творческой типографики на языках CJK. Дизайнеры могут исследовать более широкий спектр стилей и создавать визуально яркие макеты, которые раньше было трудно или невозможно реализовать.

Как переменный шрифт для китайского, японского и корейского (CJK) языков отображается при разной ширине шрифта.

Межсимвольное обоснование

Начиная с Android 15, текст можно выравнивать с использованием межбуквенного интервала с помощью JUSTIFICATION_MODE_INTER_CHARACTER . Выравнивание между словами было впервые представлено в Android 8.0 (уровень API 26), а выравнивание между символами предоставляет аналогичные возможности для языков, которые используют символ пробела для сегментации, таких как китайский, японский и другие.

Макет японского текста с использованием JUSTIFICATION_MODE_NONE .
Макет текста на английском языке с использованием JUSTIFICATION_MODE_NONE .


Макет японского текста с использованием JUSTIFICATION_MODE_INTER_WORD .
Макет текста на английском языке с использованием JUSTIFICATION_MODE_INTER_WORD .


Макет японского текста с использованием JUSTIFICATION_MODE_INTER_CHARACTER .
Макет текста на английском языке с использованием JUSTIFICATION_MODE_INTER_CHARACTER .

Автоматическая настройка разрыва строки

Android started supporting phrase-based line breaks for Japanese and Korean in Android 13 (API level 33). However, while phrase-based line breaks improve the readability of short lines of text, they don't work well for long lines of text. In Android 15, apps can apply phrase-based line breaks only for short lines of text, using the LINE_BREAK_WORD_STYLE_AUTO option. This option selects the best word style option for the text.

For short lines of text, phrase-based line breaks are used, functioning the same as LINE_BREAK_WORD_STYLE_PHRASE, as shown in the following image:

For short lines of text, LINE_BREAK_WORD_STYLE_AUTO applies phrase-based line breaks to improve the readability of the text. This is the same as applying LINE_BREAK_WORD_STYLE_PHRASE.

For longer lines of text, LINE_BREAK_WORD_STYLE_AUTO uses a no line-break word style, functioning the same as LINE_BREAK_WORD_STYLE_NONE, as shown in the following image:

For long lines of text, LINE_BREAK_WORD_STYLE_AUTO applies no line-break word style to improve the readability of the text. This is the same as applying LINE_BREAK_WORD_STYLE_NONE.

Дополнительный японский шрифт Hentaigana

В Android 15 по умолчанию включен файл шрифта для старой японской хираганы (известной как хентайгана). Уникальные формы символов хентайганы могут придать особый шарм произведениям искусства или дизайну, а также помогают сохранить точную передачу и понимание древних японских документов.

Стиль символов и текста для японского шрифта Hentaigana.

VideoLAN cone Copyright (c) 1996-2010 VideoLAN. This logo or a modified version may be used or modified by anyone to refer to the VideoLAN project or any product developed by the VideoLAN team, but does not indicate endorsement by the project.

Vulkan and the Vulkan logo are registered trademarks of the Khronos Group Inc.

OpenGL is a registered trademark and the OpenGL ES logo is a trademark of Hewlett Packard Enterprise used by permission by Khronos.