Watchdog контролирует использование флэш-памяти, отслеживая общее количество операций записи на диск, выполняемых всеми приложениями и службами, используя статистику по каждому UID, предоставляемую ядром в каталоге `/proc/uid_io/stats`. Когда приложение или служба превышает пороговое значение использования дискового ввода-вывода, Watchdog принимает меры. Пороговые значения использования дискового ввода-вывода и действия, предпринимаемые при превышении этого порогового значения, предопределены в конфигурации управления использованием дискового ввода-вывода.
Пороги чрезмерного использования
- Пороговые значения перерасхода дискового ввода-вывода применяются ежедневно, то есть все записи, выполненные приложением/службой, суммируются с начала текущего календарного дня UTC и проверяются на соответствие пороговым значениям, определенным в конфигурациях перерасхода.
- Если транспортное средство запускается несколько раз в день, модуль Watchdog сохраняет статистику использования дискового ввода-вывода во флэш-памяти и объединяет ее с начала текущего календарного дня UTC.
Действия по чрезмерному использованию
Когда приложение неоднократно превышает заданные пороговые значения чрезмерного использования дискового ввода-вывода, Watchdog предпринимает действия, заданные в конфигурации чрезмерного использования.
- Все приложения и службы поставщика считаются критически важными для общей стабильности системы, поэтому их работа не завершается при чрезмерной нагрузке на диск. Однако конфигурация чрезмерной нагрузки может определить список приложений и служб поставщика, которые можно безопасно завершить.
- Все сторонние приложения можно безопасно завершить.
Когда приложение или служба могут быть безопасно завершены, Watchdog отключает приложение или службу с помощью состояния компонента приложения PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
.
Конфигурация чрезмерного использования
Конфигурация избыточного использования содержит пороговые значения и действия, необходимые для превышения допустимого уровня использования дискового ввода-вывода. Конфигурации избыточного использования по умолчанию определены в образах системы и поставщика и поставляются вместе со сборкой. Поставщики могут дополнительно включить конфигурацию поставщика в образ поставщика. Если конфигурация поставщика не указана, для приложений и служб поставщика также используется системная конфигурация.
Watchdog предоставляет системные API через CarWatchdogManager
, что позволяет приложениям или службам поставщиков обновлять конфигурацию поставщика в любое время.
Определение конфигурации чрезмерного использования
Конфигурация избыточного использования разделяется по типу компонента, например, системный, вендорный и сторонний. OEM-производители должны обновлять только конфигурацию компонента поставщика.
Конфигурация поставщика
Конфигурация поставщика определяет пороговые значения перегрузки дискового ввода-вывода и соответствующие действия для всех приложений и служб поставщика, а также всех картографических и медиаприложений. Конфигурация содержит следующие поля конфигурации.
- Префиксы пакетов поставщика . Все пакеты, установленные в разделе поставщика, считаются пакетами поставщика. Помимо этих пакетов, поставщики могут классифицировать предустановленные пакеты как пакеты поставщика, добавляя префиксы пакетов в конфигурацию префиксов пакетов поставщика . Эта конфигурация не поддерживает регулярные выражения.
- Пакеты, работа которых безопасна для завершения . Поставщики могут указать, какие пакеты поставщиков можно безопасно завершить, добавив полные имена пакетов в конфигурацию пакетов, которые можно завершить безопасно .
- Сопоставление категорий приложений . Поставщики могут сопоставить любой пакет (включая сторонние) с одной из двух поддерживаемых категорий приложений — приложениями карт и мультимедиа. Это сопоставление выполняется для того, чтобы обеспечить более высокие пороги перегрузки дискового ввода-вывода для приложений карт и мультимедиа, поскольку эти приложения, как правило, загружают и записывают на диск больше данных, чем другие типы приложений.
- Пороговые значения на уровне компонентов . Определяет общие пороговые значения для всех пакетов поставщика (то есть, эти пороговые значения применяются к пакетам, не охватываемым пороговыми значениями, специфичными для пакетов или для категорий приложений ). Поставщики должны определять ненулевые пороговые значения на уровне компонентов при определении конфигурации избыточного использования дискового ввода-вывода.
- Пороговые значения для конкретных пакетов . Поставщики могут определять специальные пороговые значения для пакетов конкретных поставщиков. Сопоставления должны содержать полные названия пакетов. Пороговые значения, заданные в этой конфигурации, имеют приоритет над пороговыми значениями, заданными в других конфигурациях для данного пакета.
- Пороговые значения, специфичные для категорий приложений . Поставщики могут указывать специальные пороговые значения для определённых категорий приложений. Категории приложений должны относиться к одной из поддерживаемых категорий — «Карты» и «Медиа». Пороговые значения, определённые в этой конфигурации, сопоставляются с определёнными пакетами с помощью сопоставлений категорий приложений .
- Пороговые значения для всей системы . Поставщики не должны указывать эту конфигурацию.
Конфигурации префиксов пакетов поставщика , пакетов Safe-to-terminate , пороговых значений на уровне компонентов и пороговых значений, специфичных для пакетов, обновляются только конфигурацией поставщика для приложений и служб поставщика. Конфигурация пороговых значений, специфичных для категорий приложений, обновляется только конфигурацией поставщика для всех картографических и медиаприложений.
Пороги переиспользования содержат количество байтов, разрешенных к записи в течение:
- Режим переднего плана приложения или службы и фоновый режим
- Системный гаражный режим
Эта классификация позволяет активным приложениям и службам, работающим на переднем плане, записывать больше данных, чем фоновым приложениям и службам. В режиме Garage приложения и службы, как правило, загружают обновления, поэтому для каждого из них требуется более высокий порог, чем для приложений и служб, работающих в других режимах.
Системные и сторонние конфигурации
Производителям оригинального оборудования не следует обновлять конфигурацию системы и сторонних производителей.
- Конфигурация системы определяет пороговые значения чрезмерного использования ввода-вывода и действия для системных приложений и служб.
- Эта конфигурация также может обновлять сопоставления категорий приложений . Таким образом, это поле конфигурации является общим для системных и вендорских конфигураций.
- Конфигурация сторонних приложений определяет пороговые значения для всех сторонних приложений. Все приложения, не предустановленные в системе, считаются сторонними.
- Все сторонние приложения получают одинаковые пороговые значения (например, ни одно стороннее приложение не получает специальные пороговые значения), за исключением карт и мультимедийных приложений, пороговые значения которых определяются конфигурацией поставщика.
- Приведенные ниже пороговые значения перегрузки дискового ввода-вывода являются пороговыми значениями по умолчанию для сторонних приложений. Эти пороговые значения поставляются вместе с образом системы.
- Запись 3 ГиБ в активном режиме приложения.
- Запись 2 ГиБ в фоновом режиме приложения.
- Запись 4 ГиБ в режиме системного гаража.
- Это базовые пороговые значения. Они обновляются по мере получения новых данных об использовании дискового ввода-вывода.
Формат XML конфигурации чрезмерного использования
Конфигурацию поставщика по умолчанию можно разместить ( необязательно ) в файле /vendor/etc/automotive/watchdog/resource_overuse_configuration.xml
в образе сборки. Если эта конфигурация не указана, для приложений и служб поставщика также применяется системная конфигурация.
XML-файл должен содержать только один тег для каждого поля конфигурации. Конфигурация перегрузки ввода-вывода должна быть определена в XML-файле. Все пороговые значения должны быть указаны в мибибайтах (MiB).
Пример XML-конфигурации представлен ниже:
<resourceOveruseConfiguration version="1.0"> <componentType>VENDOR</componentType> <!-- List of safe to kill vendor packages. --> <safeToKillPackages> <package>com.vendor.package.A</package> <package>com.vendor.package.B</package> </safeToKillPackages> <!-- List of vendor package prefixes. --> <vendorPackagePrefixes> <packagePrefix>com.vendor.package</packagePrefix> </vendorPackagePrefixes> <!-- List of unique package names to app category mappings. --> <packagesToAppCategoryTypes> <packageAppCategory type="MEDIA">com.vendor.package.A</packageAppCategory> <packageAppCategory type="MAPS">com.google.package.B</packageAppCategory> <packageAppCategory type="MEDIA">com.third.party.package.C</packageAppCategory> </packagesToAppCategoryTypes> <ioOveruseConfiguration> <!-- Thresholds in MiB for all vendor packages that don't have package specific thresholds. --> <componentLevelThresholds> <state id="foreground_mode">1024</state> <state id="background_mode">512</state> <state id="garage_mode">3072</state> </componentLevelThresholds> <packageSpecificThresholds> <!-- IDs must be unique --> <perStateThreshold id="com.vendor.package.C"> <state id="foreground_mode">400</state> <state id="background_mode">100</state> <state id="garage_mode">200</state> </perStateThreshold> <perStateThreshold id="com.vendor.package.D"> <state id="foreground_mode">1024</state> <state id="background_mode">500</state> <state id="garage_mode">2048</state> </perStateThreshold> </packageSpecificThresholds> <!-- Application category specific thresholds. --> <appCategorySpecificThresholds> <!-- One entry per supported application category --> <perStateThreshold id="MEDIA"> <state id="foreground_mode">600</state> <state id="background_mode">700</state> <state id="garage_mode">1024</state> </perStateThreshold> <perStateThreshold id="MAPS"> <state id="foreground_mode">800</state> <state id="background_mode">900</state> <state id="garage_mode">2048</state> </perStateThreshold> </appCategorySpecificThresholds> </ioOveruseConfiguration> </resourceOveruseConfiguration>
Обновление конфигурации чрезмерного использования через системные API CarWatchdogManager
Приведённая выше XML-конфигурация может быть предоставлена только в образе сборки. Если OEM-производитель решит обновить конфигурацию устройства после выпуска сборки, он может использовать следующие API для внесения изменений в конфигурацию устройства.
- Предоставьте вызывающему абоненту разрешение
Car.PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG
. - Для обновления и установки новых конфигураций необходимо использовать существующие. Для получения существующих конфигураций используйте API
CarWatchdogManager.getResourceOveruseConfigurations
. Если существующие конфигурации не используются, все конфигурации (включая системные и сторонние) будут перезаписаны, что не рекомендуется. - Обновите существующие конфигурации, внеся изменения, и установите новые. Не обновляйте конфигурации системы и сторонних компонентов.
- Используйте API
CarWatchdogManager.setResourceOveruseConfigurations
для установки новых конфигураций. - Для получения и настройки конфигураций чрезмерного использования дискового ввода-вывода используйте флаг
CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO
.
Вот пример реализации, который обновляет конфигурации чрезмерного использования ресурсов:
void updateResourceOveruseConfigurations() { CarWatchdogManager manager = (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE); List<ResourceOveruseConfiguration> resourceOveruseConfigurations = manager.getResourceOveruseConfigurations( CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO); List<ResourceOveruseConfiguration> newResourceOveruseConfigurations = new List<>(); ResourceOveruseConfiguration vendorConfiguration; for(ResourceOveruseConfiguration config : resourceOveruseConfigurations) { // Do not update the configurations of the system and third-party component types. if (config.getComponentType() != ResourceOveruseConfiguration.COMPONENT_TYPE_VENDOR) { newResourceOveruseConfigurations.add(config); continue; } vendorConfiguration = config; } if (vendorConfiguration == null) { ResourceOveruseConfiguration.Builder vendorConfigBuilder = new ResourceOveruseConfiguration.Builder(); initializeConfig(vendorConfigBuilder); newResourceOveruseConfigurations.add(vendorConfigBuilder.build()); } else { ResourceOveruseConfiguration newVendorConfig = updateConfig(vendorConfiguration); newResourceOveruseConfigurations.add(newVendorConfig); } int result = manager.setResourceOveruseConfigurations( newResourceOveruseConfigurations, if (result != CarWatchdogManager.RETURN_CODE_SUCCESS) { // Failed to set the resource overuse configurations. } } /** Sets the delta between the old configuration and the new configuration. */ ResourceOveruseConfiguration updateConfig( ResourceOveruseConfiguration oldConfiguration) { // Replace com.vendor.package.A with com.vendor.package.B in the safe-to-kill list. List<String> safeToKillPackages = oldConfiguration.getSafeToKillPackages(); safeToKillPackages.remove("com.vendor.package.A"); safeToKillPackages.add("com.vendor.package.B"); ResourceOveruseConfiguration.Builder configBuilder = new ResourceOveruseConfiguration.Builder( oldConfiguration.getComponentType(), safeToKillPackages, oldConfiguration.getVendorPackagePrefixes(), oldConfiguration.getPackagesToAppCategoryTypes()); configBuilder.addVendorPackagePrefixes("com.vendor."); configBuilder.addPackagesToAppCategoryTypes("com.vendor.package.B", ResourceOveruseConfiguration.APPLICATION_CATEGORY_TYPE_MAPS); IoOveruseConfiguration oldIoConfiguration = oldConfiguration.getIoOveruseConfiguration(); IoOveruseConfiguration.Builder ioConfigBuilder = new IoOveruseConfiguration.Builder( oldIoConfiguration.getComponentLevelThresholds(), oldIoConfiguration.getPackageSpecificThresholds(), oldIoConfiguration.getAppCategorySpecificThresholds(), oldIoConfiguration.getSystemWideThresholds()); // Define the amount of bytes based on the flash memory specification, expected lifetime, // and estimated average amount of bytes written by a package during different modes. ioConfigBuilder.addPackageSpecificThresholds("com.vendor.package.B", new PerStateBytes(/* foregroundModeBytes= */ 2 * 1024 * 1024 * 1024, /* backgroundModeBytes= */ 500 * 1024 * 1024, /* garageModeBytes= */ 3 * 1024 * 1024 * 1024)); return configBuilder.setIoOveruseConfiguration(ioConfigBuilder.build()).build(); }
Приложения отслеживают чрезмерное использование ресурсов
Приложения поставщиков и сторонних поставщиков могут прослушивать уведомления о чрезмерном использовании ресурсов конкретного приложения от Watchdog или опрашивать CarWatchdogManager
для получения статистики чрезмерного использования ресурсов конкретного приложения за последние 30 дней.
Прислушивайтесь к уведомлениям о чрезмерном использовании ресурсов
Приложения могут реализовать прослушиватель перерасхода ресурсов и зарегистрировать его в CarWatchdogManager
, чтобы получать специальные уведомления о превышении 80% или 100% пороговых значений перерасхода дискового ввода-вывода. Приложения могут использовать эти уведомления для:
- Регистрируйте статистику чрезмерного использования дискового ввода-вывода для офлайн-анализа. Разработчики приложений могут использовать эту статистику для устранения проблемы чрезмерного использования дискового ввода-вывода.
- Уменьшите количество операций записи на диск, пока счетчики чрезмерного использования не будут сброшены.
Java-клиент
- Реализуйте прослушиватель, унаследовав
CarWatchdogManager.ResourceOveruseListener
:class ResourceOveruseListenerImpl implements CarWatchdogManager.ResourceOveruseListener { @Override public void onOveruse( @NonNull ResourceOveruseStats resourceOveruseStats) { // 1. Log/Upload resource overuse metrics. // 2. Reduce writes until the counters reset. IoOveruseStats ioOveruseStats = resourceOveruseStats.getIoOveruseStats(); // Stats period - [ioOveruseStats.getStartTime(), ioOveruseStats.getStartTime() // + ioOveruseStats.getDurationInSeconds()] // Total I/O overuses - ioOveruseStats.getTotalOveruses() // Total bytes written - ioOveruseStats.getTotalBytesWritten() // Remaining write bytes for the current UTC calendar day - // ioOveruseStats.getRemainingWriteBytes() } } }
- Зарегистрируйте экземпляр прослушивателя, вызвав
CarWatchdogManager.addResourceOveruseListener
private void addResourceOveruseListener() { CarWatchdogManager manager = (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE); // Choose a proper executor to handle resource overuse notifications. Executor executor = mContext.getMainExecutor(); manager.addResourceOveruseListener( executor, CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO, mListenerImpl); }
- Отмените регистрацию экземпляра прослушивателя, когда приложение завершит прослушивание:
private void removeResourceOveruseListener() { CarWatchdogManager manager = (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE); mCarWatchdogManager.removeResourceOveruseListener( mListenerImpl); }
Собственный клиент
- Включите
carwatchdog_aidl_interface-ndk_platform
в зависимостьshared_libs
правила сборки.Android.bp
cc_binary { name: "sample_native_client", srcs: [ "src/*.cpp" ], shared_libs: [ "carwatchdog_aidl_interface-ndk_platform", "libbinder_ndk", ], vendor: true, }
- Добавьте политику SELinux, чтобы разрешить домену службы поставщика использовать связующее звено (макрос
binder_user
), и добавьте домен службы поставщика в клиентский доменcarwatchdog
(carwatchdog_client_domain macro)
. См. код ниже дляsample_client.te
иfile_contexts
.sample_client.te
type sample_client, domain; type sample_client_exec, exec_type, file_type, vendor_file_type; carwatchdog_client_domain(sample_client) init_daemon_domain(sample_client) binder_use(sample_client)
file_contexts
/vendor/bin/sample_native_client u:object_r:sample_client_exec:s0
- Реализуйте прослушиватель чрезмерного использования ресурсов, унаследовав
BnResourceOveruseListener
. ПереопределитеBnResourceOveruseListener::onOveruse
для обработки уведомлений о чрезмерном использовании ресурсов.ResourceOveruseListenerImpl.h
class ResourceOveruseListenerImpl : public BnResourceOveruseListener { public: ndk::ScopedAStatus onOveruse( ResourceOveruseStats resourceOveruseStats) override; private: void initialize(); void terminate(); std::shared_ptr<ICarWatchdog> mWatchdogServer; std::shared_ptr<IResourceOveruseListener> mListener; }
ResourceOveruseListenerImpl.cpp
ndk::ScopedAStatus ResourceOveruseListenerImpl::onOveruse( ResourceOveruseStats resourceOveruseStats) { // 1. Log/Upload resource overuse metrics. // 2. Reduce writes until the counters reset. if (stats.getTag() != ResourceOveruseStats::ioOveruseStats) { // Received resourceOveruseStats doesn't contain I/O overuse stats. } const IoOveruseStats& ioOveruseStats = stats.get(); // Stats period - [ioOveruseStats.startTime, // ioOveruseStats.startTime + ioOveruseStats.durationInSeconds] // Total I/O overuses - ioOveruseStats.totalOveruses // Total bytes written - ioOveruseStats.writtenBytes // Remaining write bytes for the current UTC calendar day - // ioOveruseStats.remainingWriteBytes return ndk::ScopedAStatus::ok(); }
- Запустите пул потоков Binder и зарегистрируйте прослушиватель перерасхода ресурсов на сервере сторожевого таймера. Сервер сторожевого таймера зарегистрирован под именем службы
android.automotive.watchdog.ICarWatchdog/default
.main.cpp
int main(int argc, char** argv) { ABinderProcess_setThreadPoolMaxThreadCount(1); ABinderProcess_startThreadPool(); std::shared_ptr<ResourceOveruseListenerImpl> listener = ndk::SharedRefBase::make<ResourceOveruseListenerImpl>(); // The listener is added in initialize(). listener->initialize(); ... Run service ... // The listener is removed in terminate(). listener->terminate(); }
ResourceOveruseListenerImpl.cpp
void ResourceOveruseListener::initialize() { ndk::SpAIBinder binder(AServiceManager_getService( "android.automotive.watchdog.ICarWatchdog/default")); std::shared_ptr<ICarWatchdog> server = ICarWatchdog::fromBinder(binder); mWatchdogServer = server; std::shared_ptr<IResourceOveruseListener> listener = IResourceOveruseListener::fromBinder(this->asBinder()); mWatchdogServer->addResourceOveruseListener( std::vector<int>{ResourceType.IO}, listener); mListener = listener; } void ResourceOveruseListener::terminate() { mWatchdogServer->removeResourceOveruseListener(mListener); }
Статистика чрезмерного использования ресурсов опроса
Приложения могут опрашивать CarWatchdogManager для получения статистики ATS по чрезмерному использованию ввода-вывода для конкретного приложения за последние 30 дней.
Java-клиент
Используйте CarWatchdogManager.getResourceOveruseStats
для получения статистики перерасхода ресурсов. Передайте флаг CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO
для получения статистики перерасхода дискового ввода-вывода.
private void getResourceOveruseStats() { CarWatchdogManager manager = (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE); // Returns resource overuse stats with I/O overuse stats for the past // 7 days. Stats are available for up to the past 30 days. ResourceOveruseStats resourceOveruseStats = mCarWatchdogManager.getResourceOveruseStats( CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO, CarWatchdogManager.STATS_PERIOD_PAST_7_DAYS); IoOveruseStats ioOveruseStats = resourceOveruseStats.getIoOveruseStats(); // Stats period - [ioOveruseStats.getStartTime(), ioOveruseStats.getStartTime() // + ioOveruseStats.getDurationInSeconds()] // Total I/O overuses - ioOveruseStats.getTotalOveruses() // Total bytes written - ioOveruseStats.getTotalBytesWritten() // Remaining write bytes for the UTC calendar day - // ioOveruseStats.getRemainingWriteBytes() }
Собственный клиент
Используйте CarWatchdogServer.getResourceOveruseStats
для получения статистики перерасхода ресурсов. Передайте перечисление ResourceType.IO
для получения статистики перерасхода дискового ввода-вывода.
void getResourceOveruseStats() { ndk::SpAIBinder binder(AServiceManager_getService( "android.automotive.watchdog.ICarWatchdog/default")); std::shared_ptr<ICarWatchdog> server = ICarWatchdog::fromBinder(binder); // Returns the stats only for the current UTC calendar day. const std::vector<ResourceOveruseStats> resourceOveruseStats; ndk::ScopedAStatus status = server.getResourceOveruseStats( std::vector<int>{ResourceType.IO}, &resourceOveruseStats); if (!status.isOk()) { // Failed to get the resource overuse stats. return; } for (const auto& stats : resourceOveruseStats) { if (stats.getTag() != ResourceOveruseStats::ioOveruseStats) { continue; } const IoOveruseStats& ioOveruseStats = stats.get(); // Stats period - [ioOveruseStats.startTime, // ioOveruseStats.startTime + ioOveruseStats.durationInSeconds] // Total I/O overuses - ioOveruseStats.totalOveruses // Total bytes written - ioOveruseStats.writtenBytes // Remaining write bytes for the current UTC calendar day - // ioOveruseStats.remainingWriteBytes } }
Пользовательский опыт чрезмерного использования ресурсов
В следующих разделах описывается опыт пользователя в случае чрезмерного использования ресурсов.
Приоритет настроек производительности приложения
На странице настроек приложения находятся настройки Prioritize app performance
(см. изображение ниже), которые позволяют пользователям отдавать приоритет производительности приложения по сравнению с производительностью системы и долгосрочными показателями производительности оборудования. Этот параметр доступен только для приложений, которые можно безопасно завершить при превышении допустимого уровня использования ресурсов. В противном случае этот параметр отключен. Если этот параметр отключен (настройка по умолчанию), приложение может быть завершено при превышении допустимого уровня использования ресурсов. В противном случае приложение не завершается при превышении допустимого уровня использования ресурсов.
Когда пользователь включает этот параметр, появляется следующее диалоговое окно подтверждения, описывающее последствия включения параметра:
По истечении 90 дней этот параметр автоматически сбрасывается до значения по умолчанию. Срок действия можно изменить с помощью приложения-наложения RRO, используя watchdogUserPackageSettingsResetDays
, но не более чем до 180 дней. Подробнее см. в разделе Изменение значения ресурсов приложения во время выполнения . Следующий пример тега наложения можно включить в AndroidManifest.xml
:
<overlay android:priority="<insert-value>" android:targetPackage="com.android.car.updatable" android:targetName="CarServiceCustomization" android:resourcesMap="@xml/overlays" />
В res/values/config.xml
:
<resources> <integer name="watchdogUserPackageSettingsResetDays">value</integer> </resources>
В res/xml/overlays.xml
:
<overlay> <item target="integer/watchdogUserPackageSettingsResetDays" value="@integer/watchdogUserPackageSettingsResetDays" /> </overlay>
Настройка приложений, влияющих на производительность
Приложение «Настройки» содержит раздел «Приложения, влияющие на производительность» (см. рис. 1). При нажатии на него отображается список приложений, доступ к которым ограничен из-за чрезмерного использования флеш-памяти и которые негативно влияют на производительность системы. Это соответствует требованию CDD 3.5.1 [C-1-1] .
Рисунок 1. Приложения, влияющие на производительность.
Приложения, работа которых была прекращена из-за чрезмерного использования ресурсов, перечислены здесь (см. рис. 2). Перечисленным приложениям можно назначить приоритет. Подробнее см. в разделе «Настройка приоритета производительности приложений» .
Рисунок 2. Список приложений, закрытых из-за чрезмерного использования ресурсов.
Уведомление пользователя
Когда приложение или служба неоднократно чрезмерно использует дисковый ввод-вывод (например, записывает данные на диск сверх заданных пороговых значений) в течение определенного периода времени и может быть безопасно завершено из-за чрезмерного использования ресурсов, пользователь уведомляется об этом после того, как транспортное средство переходит в состояние, разрешающее отвлечение водителя.
Первое уведомление пользователя (во время поездки) публикуется как предварительное уведомление, а остальные уведомления публикуются в центре уведомлений.
Например, когда приложение неоднократно чрезмерно использует дисковый ввод-вывод, пользователь получает следующее уведомление:
- Когда пользователь нажимает кнопку «Приоритизировать приложение» , открывается страница настроек приложения, на которой пользователь может включить или выключить параметр «Приоритизировать производительность приложения» .
- Когда пользователь нажимает кнопку «Отключить приложение» , приложение отключается до тех пор, пока пользователь не запустит его или не включит его на странице настроек приложения.
- Для приложений, которые можно удалить, кнопка «Отключить приложение» заменена на кнопку «Удалить приложение» . При нажатии на кнопку «Удалить приложение» открывается страница настроек приложения, где пользователь может удалить его.
Рекомендация по внедрению пусковой установки
Когда приложения отключаются из-за чрезмерного использования ресурсов, они исчезают из панели запуска по умолчанию, поскольку CarService обновляет состояние включения приложений как PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
. OEM-производители должны обновить встроенную реализацию панели запуска, чтобы эти приложения отображались в обычном режиме, чтобы пользователи могли использовать их при необходимости. См. следующие рекомендации, основанные на версии сборки.
Выпуск Android SC V2
- Реализация средства запуска должна использовать флаг
MATCH_DISABLED_UNTIL_USED_COMPONENTS
при получении списка пакетов для отображения в средстве запуска. - Когда пользователь щелкает приложение, находящееся в состоянии
PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
, приложение запуска должно включить приложение, установив включенное состояние следующим образом: