Monitorar o uso de memória flash

O watchdog monitora o uso da memória flash rastreando a quantidade total de gravações de E/S de disco feitas por todos os apps e serviços usando as estatísticas de E/S de disco por UID expostas pelo kernel no local "/proc/uid_io/stats". Quando um app ou serviço excede o limite de uso excessivo de E/S de disco, o Watchdog realiza ações no app ou serviço. Os limites de uso excessivo de E/S de disco e a ação a ser realizada em caso de uso excessivo são predefinidos na configuração de uso excessivo de E/S de disco.

Limites de uso excessivo

  • Os limites de uso excessivo de E/S de disco são aplicados diariamente, ou seja, todas as gravações feitas por um app/serviço são agregadas desde o início do dia de calendário UTC atual e verificadas em relação aos limites definidos nas configurações de uso excessivo.
  • Quando um veículo é iniciado várias vezes em um determinado dia, o módulo Watchdog armazena as estatísticas de uso de E/S de disco no flash e as agrega desde o início do dia atual do calendário UTC.

Ações por uso excessivo

Quando um app excede repetidamente os limites de uso excessivo de E/S de disco definidos, o Watchdog executa as ações definidas na configuração de uso excessivo.

  • Todos os apps e serviços do fornecedor são considerados essenciais para a estabilidade geral do sistema. Por isso, eles não são encerrados em caso de uso excessivo de E/S do disco. No entanto, a configuração de uso excessivo pode definir uma lista de apps e serviços de fornecedores seguros para encerramento.
  • Todos os apps de terceiros podem ser encerrados com segurança.

Quando um app ou serviço pode ser encerrado com segurança, o Watchdog desativa o app ou serviço com o estado do componente PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED .

Configuração de uso excessivo

A configuração de uso excessivo contém os limites e as ações de uso excessivo de E/S do disco. As configurações de uso excessivo padrão são definidas nas imagens do sistema e do fornecedor e enviadas com o build. Os fornecedores podem incluir a configuração na imagem do fornecedor. Quando a configuração do fornecedor não é fornecida, a configuração do sistema também é usada para os apps e serviços do fornecedor.

O Watchdog expõe APIs do sistema usando CarWatchdogManager, que permite que apps ou serviços de fornecedores atualizem a configuração do fornecedor a qualquer momento.

Definição de configuração de uso excessivo

A configuração de uso excessivo é dividida pelo tipo de componente, por exemplo, sistema, fornecedor e terceiros. Os OEMs precisam atualizar apenas a configuração do componente do fornecedor.

Configuração do fornecedor

A configuração do fornecedor define os limites e as ações de uso excessivo de E/S de disco para todos os apps e serviços do fornecedor, além de todos os mapas e apps de mídia. A configuração contém os campos de configuração abaixo.

  • Prefixos de pacotes do fornecedor. Todos os pacotes instalados na partição do fornecedor são considerados pacotes do fornecedor. Além desses pacotes, os fornecedores podem classificar pacotes pré-instalados como pacotes do fornecedor adicionando os prefixos de pacote à configuração prefixos de pacote do fornecedor. Esta configuração não aceita expressões regulares.
  • Pacotes com segurança para encerrar. Os fornecedores podem especificar quais pacotes do fornecedor podem ser encerrados com segurança adicionando os nomes completos dos pacotes à configuração safe-to-terminate packages.
  • Mapeamentos de categorias de aplicativos. Os fornecedores podem mapear qualquer pacote (incluindo pacotes de terceiros) para uma das duas categorias de apps compatíveis: apps de mapa e de mídia. Esse mapeamento é feito para fornecer mapas e apps de mídia com limites de uso excessivo de E/S de disco mais altos, porque esses apps tendem a fazer o download e gravar mais dados no disco do que outros tipos de apps.
  • Limites no nível do componente. Define limites genéricos para todos os pacotes do fornecedor (ou seja, pacotes não cobertos por Limites específicos do pacote ou Limites específicos da categoria do aplicativo). Os fornecedores precisam definir limites no nível do componente que não sejam iguais a zero ao definir a configuração de uso excessivo de E/S de disco.
  • Limites específicos do pacote. Os fornecedores podem definir limites especiais para pacotes específicos. Os mapeamentos precisam conter os nomes completos dos pacotes. Os limites definidos nessa configuração têm precedência sobre os limites definidos em outras configurações para um determinado pacote.
  • Limites específicos de categorias de aplicativos. Os fornecedores podem definir limites especiais para determinadas categorias de apps. As categorias de apps precisam estar em uma das opções aceitas: apps de mapas e mídia. Os limites definidos nessa configuração são mapeados para pacotes específicos usando mapeamentos de categoria de aplicativos.
  • Limites do sistema. Os fornecedores não precisam especificar essa configuração.

As configurações de prefixos de pacotes do fornecedor, pacotes seguros para encerramento, limites no nível do componente e limites específicos do pacote só podem ser atualizadas pela configuração do fornecedor para apps e serviços do fornecedor. A configuração de limites específicos da categoria do aplicativo só pode ser atualizada pela configuração do fornecedor para todos os apps de mídia e mapas.

Os limites de uso excessivo contêm a quantidade de bytes permitida para gravação durante:

  • Um modo de primeiro plano de app ou serviço em comparação com o modo de segundo plano
  • Modo de garagem do sistema

Essa classificação permite que os apps e serviços em primeiro plano do usuário gravem mais dados do que os apps e serviços em segundo plano. No modo garagem, apps e serviços tendem a fazer o download de atualizações. Portanto, cada um deles precisa de um limite maior do que os apps e serviços em execução em outros modos.

Configurações do sistema e de terceiros

Os OEMs não devem atualizar o sistema e as configurações de terceiros.

  • A configuração do sistema define limites e ações de uso excessivo de E/S para apps e serviços do sistema.
    • Essa configuração também pode atualizar os mapeamentos de categoria de aplicativo. Portanto, esse campo de configuração é compartilhado entre as configurações do sistema e do fornecedor.
  • A configuração de terceiros define limites para todos os apps de terceiros. Todos os apps que não são pré-instalados no sistema são apps de terceiros.
    • Todos os apps de terceiros recebem os mesmos limites (por exemplo, nenhum deles recebe limites especiais), exceto apps de mapas e mídia, cujos limites são definidos pela configuração do fornecedor.
    • Os limites de uso excessivo de E/S de disco abaixo são os limites padrão para apps de terceiros. Esses limites são enviados com a imagem do sistema.
      • 3 GiB de gravação no modo de primeiro plano do app.
      • 2 GiB de gravação no modo de app em segundo plano.
      • 4 GiB de gravação no modo garagem do sistema.
    • Esses são os limites básicos. Esses limites são atualizados à medida que mais informações são coletadas sobre o uso de E/S em disco.

Uso excessivo do formato XML de configuração

A configuração padrão do fornecedor pode ser colocada (opcional) no local /vendor/etc/automotive/watchdog/resource_overuse_configuration.xml na imagem do build. Quando essa configuração não é especificada, a definida pelo sistema também é aplicada aos apps e serviços do fornecedor.

O arquivo XML precisa conter apenas uma tag para cada campo de configuração. A configuração de uso excessivo de E/S precisa ser definida no arquivo XML. Todos os valores de limite precisam ser especificados na unidade MiB.

Confira abaixo um exemplo de configuração 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>

Atualizar a configuração de uso excessivo por APIs do sistema CarWatchdogManager

A configuração XML acima só pode ser fornecida na imagem de build. Se um OEM decidir atualizar a configuração no dispositivo após o lançamento de um build, ele poderá usar as APIs abaixo para fazer mudanças na configuração no dispositivo.

  • Conceda a permissão Car.PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG ao autor da chamada.
  • Precisa usar as configurações atuais para atualizar e definir as novas configurações. Use a API CarWatchdogManager.getResourceOveruseConfigurations para receber as configurações atuais. Se as configurações atuais não forem usadas, todas as configurações (incluindo as do sistema e de terceiros) serão substituídas, o que não é recomendado.
  • Atualize as configurações atuais com as mudanças delta e defina as novas configurações. Não atualize as configurações do sistema e do componente de terceiros.
  • Use a API CarWatchdogManager.setResourceOveruseConfigurations para definir as novas configurações.
  • Para receber e definir as configurações de uso excessivo de E/S do disco, use a flag CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO.

Confira um exemplo de implementação que atualiza as configurações de uso excessivo de recursos:

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();
}

Apps que monitoram o uso excessivo de recursos

Os apps do fornecedor e de terceiros podem detectar notificações de uso excessivo de recursos específicos do app do Watchdog ou consultar CarWatchdogManager para as estatísticas de uso excessivo de recursos específicos do app nos últimos 30 dias.

Detectar notificações de uso excessivo de recursos

Os apps podem implementar um listener de uso excessivo de recursos e registrar o listener com CarWatchdogManager para receber notificações específicas do app quando excederem 80% ou 100% dos limites de uso excessivo de E/S de disco. Os apps podem usar essas notificações para:

  • Registre as estatísticas de uso excessivo de E/S de disco para análise off-line. Os desenvolvedores de apps podem usar esse registro para depurar o problema de uso excessivo de E/S de disco.
  • Reduza as gravações de E/S de disco até que os contadores de uso excessivo sejam redefinidos.

Cliente Java

  1. Implementar o listener herdando 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. Registre a instância do listener chamando 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. Cancele o registro da instância do listener quando o app terminar de detectar:
    private void removeResourceOveruseListener() {
        CarWatchdogManager manager =
                (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE);
        mCarWatchdogManager.removeResourceOveruseListener(
              mListenerImpl);
    }
    

Cliente nativo

  1. Inclua carwatchdog_aidl_interface-ndk_platform na dependência shared_libs da regra de build.

    Android.bp

    cc_binary {
        name: "sample_native_client",
        srcs: [
            "src/*.cpp"
        ],
        shared_libs: [
            "carwatchdog_aidl_interface-ndk_platform",
            "libbinder_ndk",
        ],
        vendor: true,
    }
    
  2. A política SELinux foi adicionada para permitir que o domínio de serviço do fornecedor use o binder (macro binder_user) e adicione o domínio de serviço do fornecedor ao domínio de cliente carwatchdog (carwatchdog_client_domain macro). Confira o código abaixo para sample_client.te e 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. Implemente o listener de uso excessivo de recursos herdando BnResourceOveruseListener. Substitua BnResourceOveruseListener::onOveruse para processar notificações de uso excessivo de recursos.

    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. Inicie um pool de linhas de execução de vinculação e registre o listener de uso excessivo de recursos com o servidor de monitoramento. O servidor de watchdog está registrado com o nome de serviço 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);
    }
    

Consultar estatísticas de uso excessivo de recursos

Os apps podem consultar o CarWatchdogManager para as estatísticas de uso excessivo de E/S específicas do app para os 30 dias mais recentes.

Cliente Java

Use CarWatchdogManager.getResourceOveruseStats para conferir as estatísticas de uso excessivo de recursos. Transmita a flag CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO para receber as estatísticas de uso excessivo de E/S do disco.

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()
}

Cliente nativo

Use CarWatchdogServer.getResourceOveruseStats para conferir as estatísticas de uso excessivo de recursos. Transmita o tipo enumerado ResourceType.IO para buscar estatísticas de uso excessivo de E/S de disco.

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
      }
}

Experiência do usuário com uso excessivo de recursos

As seções a seguir descrevem a experiência do usuário quando o uso excessivo de recursos ocorre.

Priorizar a configuração de desempenho do app

A página Configurações do app contém configurações para Prioritize app performance (veja a imagem abaixo), o que permite que os usuários priorizem o desempenho de um app em relação ao sistema e o desempenho de hardware de longo prazo. Essa configuração está disponível apenas para apps que podem ser encerrados com segurança por uso excessivo de recursos. Caso contrário, a configuração será desativada. Quando essa configuração está desativada (a configuração padrão) para um app, ele pode ser encerrado em caso de uso excessivo de recursos. Caso contrário, o app não será encerrado em caso de uso excessivo de recursos.

Quando o usuário ativa essa configuração, a caixa de diálogo de confirmação abaixo descreve as implicações da ativação dela:

Após 90 dias, essa configuração é redefinida automaticamente para o padrão. O limite de dias pode ser modificado com um app de sobreposição de RRO usando watchdogUserPackageSettingsResetDays, até um máximo de 180 dias. Para saber mais, consulte Mudar o valor dos recursos de um app no momento da execução. A seguinte tag de sobreposição de exemplo pode ser incluída em AndroidManifest.xml:

<overlay android:priority="<insert-value>"
      android:targetPackage="com.android.car.updatable"
      android:targetName="CarServiceCustomization"
      android:resourcesMap="@xml/overlays" />

Em res/values/config.xml:

<resources>
  <integer name="watchdogUserPackageSettingsResetDays">value</integer>
</resources>

Em res/xml/overlays.xml:

<overlay>
  <item target="integer/watchdogUserPackageSettingsResetDays" value="@integer/watchdogUserPackageSettingsResetDays" />
</overlay>

Configuração de apps que afetam o desempenho

O app Configurações contém uma seção Apps que afetam o desempenho (consulte a Figura 1). Ao tocar nele, uma lista de apps que foram restritos devido ao uso excessivo de memória flash e que afetam negativamente o desempenho do sistema é mostrada. Isso segue o requisito 3.5.1 do CDD [C-1-1].

Apps que afetam o desempenho

Figura 1. Apps que afetam o desempenho.

Os apps encerrados devido ao uso excessivo de recursos estão listados aqui (Figura 2). Os apps listados podem ser priorizados. Para saber mais, consulte Priorizar a configuração de desempenho do app.

Lista de apps encerrados devido ao uso excessivo de recursos

Figura 2. Lista de apps encerrados devido ao uso excessivo de recursos.

Notificação do usuário

Quando um app ou serviço usa repetidamente a E/S de disco (por exemplo, grava dados no disco além dos limites definidos) em um determinado período e pode ser encerrado com segurança em caso de uso excessivo de recursos, o usuário é notificado depois que o veículo entra no estado de distração do motorista.

A primeira notificação do usuário (durante uma viagem) é postada como uma notificação de aviso, e as outras são postadas na central de notificações.

Por exemplo, quando um app usa repetidamente E/S de disco, o usuário recebe esta notificação:

  • Quando o usuário clica no botão Priorizar app, a página de configurações do app é iniciada, e o usuário pode ativar ou desativar a configuração Priorizar desempenho do app.
  • Quando o usuário clica no botão Desativar app, o app fica desativado até que o usuário o inicie ou o ative na página de configurações do app.
  • Para apps que não podem ser desinstalados, o botão Desativar app é substituído pelo botão Desinstalar app. Quando o usuário clica no botão Desinstalar app, a página de configurações do app é aberta, e o usuário pode desinstalá-lo.

Recomendação para implementação do acesso rápido

Quando os apps são desativados devido ao uso excessivo de recursos, eles desaparecem do app de acesso rápido padrão porque o CarService atualiza o estado ativado dos apps como PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED. Os OEMs precisam atualizar a implementação do iniciador integrado para mostrar esses apps como incomuns, para que os usuários possam usá-los, se necessário. Confira as recomendações a seguir com base na versão do build.

Versão SC V2 do Android