Мониторинг использования флэш-памяти

Watchdog контролирует использование флэш-памяти, отслеживая общее количество дисковых операций ввода-вывода, выполненных всеми приложениями и службами, используя статистику дискового ввода-вывода по каждому UID, предоставляемую ядром в расположении `/proc/uid_io/stats`. Когда приложение или служба превышает пороговое значение избыточного использования дискового ввода-вывода, Watchdog предпринимает действия в отношении приложения или службы. Пороговые значения избыточного использования дискового ввода-вывода и действие, предпринимаемое при избыточном использовании, предопределены в конфигурации избыточного использования дискового ввода-вывода.

Пороги чрезмерного использования

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

Действия по чрезмерному использованию

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

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

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

Конфигурация чрезмерного использования

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

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

Определение конфигурации чрезмерного использования

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

Конфигурация поставщика

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

  • Префиксы пакетов поставщиков . Все пакеты, установленные в разделе поставщиков, считаются пакетами поставщиков. В дополнение к этим пакетам поставщики могут классифицировать предустановленные пакеты как пакеты поставщиков, добавляя префиксы пакетов в конфигурацию префиксов пакетов поставщиков . Эта конфигурация не принимает регулярные выражения.
  • Пакеты, безопасные для завершения . Поставщики могут указать, какие пакеты поставщиков можно безопасно завершить, добавив полные имена пакетов в конфигурацию пакетов, безопасных для завершения .
  • Сопоставление категорий приложений . Поставщики могут сопоставлять любой пакет (включая сторонние пакеты) с одной из двух поддерживаемых категорий приложений — приложениями карт и мультимедиа. Это сопоставление выполняется для предоставления картам и мультимедиа-приложениям более высоких порогов избыточного использования дискового ввода-вывода, поскольку эти приложения, как правило, загружают и записывают больше данных на диск, чем другие типы приложений.
  • Пороги уровня компонентов . Определяет общие пороги для всех пакетов поставщиков (то есть пакеты, не охваченные порогами, специфичными для пакетов или порогами, специфичными для категорий приложений, получают эти пороги). Поставщики должны определять ненулевые пороги уровня компонентов при определении конфигурации избыточного использования дискового ввода-вывода.
  • Пороги, специфичные для пакетов . Поставщики могут определять специальные пороги для определенных пакетов поставщиков. Сопоставления должны содержать полные имена пакетов. Пороги, определенные в этой конфигурации, имеют приоритет над порогами, определенными в других конфигурациях для данного пакета.
  • Пороги, специфичные для категории приложений . Поставщики могут указывать специальные пороги для определенных категорий приложений. Категории приложений должны быть одной из поддерживаемых категорий — приложения «Карты» и «Медиа». Пороги, определенные в этой конфигурации, сопоставляются с определенными пакетами с помощью сопоставлений категорий приложений .
  • Системные пороги . Поставщики не должны указывать эту конфигурацию.

Префиксы пакетов поставщиков , пакеты Safe-to-terminate , пороги уровня компонентов и конфигурации порогов, специфичных для пакетов, могут обновляться только конфигурацией поставщика для приложений и служб поставщика. Конфигурация порогов, специфичных для категории приложений, может обновляться только конфигурацией поставщика для всех карт и медиаприложений.

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

  • Режим приложения или службы переднего плана и фоновый режим
  • Системный гаражный режим

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

Системные и сторонние конфигурации

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

  • Конфигурация системы определяет пороговые значения чрезмерного использования ввода-вывода и действия для системных приложений и служб.
    • Эта конфигурация также может обновлять сопоставления категорий приложений . Таким образом, это поле конфигурации является общим для системных и вендорских конфигураций.
  • Конфигурация сторонних приложений определяет пороговые значения для всех сторонних приложений. Все приложения, которые не предустановлены в системе, являются сторонними приложениями.
    • Все сторонние приложения получают одинаковые пороговые значения (например, ни одно стороннее приложение не получает специальные пороговые значения), за исключением карт и мультимедийных приложений, пороговые значения которых определяются конфигурацией поставщика.
    • Нижеприведенные пороги избыточного использования дискового ввода-вывода являются порогами по умолчанию для сторонних приложений. Эти пороги поставляются с образом системы.
      • Запись 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-клиент

  1. Реализуйте прослушиватель, унаследовав 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()
                }
          }
    }
  2. Зарегистрируйте экземпляр прослушивателя, вызвав 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);
    }
  3. Отмените регистрацию экземпляра прослушивателя, когда приложение завершит прослушивание:
    private void removeResourceOveruseListener() {
        CarWatchdogManager manager =
                (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE);
        mCarWatchdogManager.removeResourceOveruseListener(
              mListenerImpl);
    }

Собственный клиент

  1. Включите 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,
    }
  2. Добавьте политику SELinux, чтобы разрешить домену службы поставщика использовать binder (макрос 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
  3. Реализуйте прослушиватель чрезмерного использования ресурсов, унаследовав 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();
    }
  4. Запустите пул потоков binder и зарегистрируйте прослушиватель перерасхода ресурсов на сервере watchdog. Сервер watchdog зарегистрирован под именем службы 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 overlay с помощью watchdogUserPackageSettingsResetDays , максимум до 180 дней. Чтобы узнать больше, см. Изменение значения ресурсов приложения во время выполнения . Следующий пример тега overlay можно включить в 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. Список приложений, завершенных из-за чрезмерного использования ресурсов.

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

Если приложение или служба многократно перегружает дисковый ввод-вывод (например, записывает данные на диск сверх заданных пороговых значений) в течение определенного периода времени и может быть безопасно завершена из-за перерасхода ресурсов, пользователь получает уведомление после того, как транспортное средство переходит в состояние, в котором разрешено отвлечение водителя.

Первое уведомление пользователя (во время поездки) публикуется как всплывающее уведомление, а остальные уведомления публикуются в центре уведомлений.

Например, когда приложение многократно перегружает дисковый ввод-вывод, пользователь получает следующее уведомление:

  • Когда пользователь нажимает кнопку «Приоритет приложения» , открывается страница настроек приложения, на которой пользователь может включить или выключить параметр «Приоритет производительности приложения» .
  • Когда пользователь нажимает кнопку «Отключить приложение» , приложение отключается до тех пор, пока пользователь не запустит его или не включит на странице настроек приложения.
  • Для неустановимых приложений кнопка Disable app заменяется кнопкой Uninstall app . Когда пользователь нажимает кнопку Uninstall app , открывается страница настроек приложения, с которой пользователь может удалить приложение.

Рекомендация по внедрению пусковой установки

Когда приложения отключены из-за чрезмерного использования ресурсов, они исчезают из приложения запуска по умолчанию, поскольку CarService обновляет включенное состояние приложений как PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED . OEM-производители должны обновить встроенную реализацию запуска, чтобы отображать эти приложения как обычно, чтобы пользователи могли использовать их при необходимости. См. следующие рекомендации на основе выпуска сборки.

Выпуск Android SC V2