Monitorare l'utilizzo della memoria flash

Watchdog monitora l'utilizzo della memoria flash monitorando la quantità totale di scritture I/O del disco effettuate da tutte le app e i servizi utilizzando le statistiche I/O del disco per UID esposte dal kernel nella posizione "/proc/uid_io/stats". Quando un'app o un servizio supera la soglia di utilizzo eccessivo di I/O del disco, Watchdog esegue azioni sull'app o sul servizio. Le soglie di utilizzo eccessivo dell'I/O del disco e l'azione da intraprendere in caso di utilizzo eccessivo sono predefinite nella configurazione dell'utilizzo eccessivo dell'I/O del disco.

Soglie di uso eccessivo

  • Le soglie di utilizzo eccessivo dell'I/O del disco vengono applicate su base giornaliera, ovvero tutte le scritture effettuate da un'app/servizio vengono aggregate dall'inizio del giorno di calendario UTC corrente e confrontate con le soglie definite nelle configurazioni di utilizzo eccessivo.
  • Quando un veicolo viene avviato più volte in un determinato giorno, il modulo Watchdog memorizza le statistiche sull'utilizzo I/O del disco nella memoria flash e le aggrega dall'inizio del giorno di calendario UTC corrente.

Azioni di uso eccessivo

Quando un'app supera ripetutamente le soglie di utilizzo eccessivo di I/O del disco definite, Watchdog esegue le azioni definite nella configurazione di utilizzo eccessivo.

  • Tutte le app e i servizi del fornitore sono considerati critici per la stabilità complessiva del sistema, quindi non vengono interrotti in caso di utilizzo eccessivo dell'I/O del disco. Tuttavia, la configurazione di utilizzo eccessivo può definire un elenco di app e servizi del fornitore sicuri da terminare.
  • Tutte le app di terze parti possono essere terminate in modo sicuro.

Quando un'app o un servizio può essere terminato in modo sicuro, Watchdog disabilita l'app o il servizio con lo stato del componente PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED .

Configurazione da uso eccessivo

La configurazione di utilizzo eccessivo contiene le soglie e le azioni di utilizzo eccessivo dell'I/O del disco. Le configurazioni di utilizzo eccessivo predefinite sono definite nelle immagini del sistema e del fornitore e fornite con la build. I fornitori possono facoltativamente includere la configurazione del fornitore nell'immagine del fornitore. Quando la configurazione del fornitore non viene fornita, la configurazione di sistema viene utilizzata anche per le app e i servizi del fornitore.

Watchdog espone le API di sistema tramite CarWatchdogManager , che consente alle app o ai servizi dei fornitori di aggiornare la configurazione del fornitore in qualsiasi momento.

Definizione di configurazione di uso eccessivo

La configurazione di utilizzo eccessivo è suddivisa in base al tipo di componente, ad esempio sistema, fornitore e terze parti. Gli OEM devono aggiornare solo la configurazione del componente del fornitore.

Configurazione del fornitore

La configurazione del fornitore definisce le soglie e le azioni di utilizzo eccessivo dell'I/O del disco per tutte le app e i servizi del fornitore e per tutte le mappe e le app multimediali. La configurazione contiene i campi di configurazione seguenti.

  • Vendor package prefixes . Tutti i pacchetti installati nella partizione del fornitore sono considerati pacchetti del fornitore. Oltre a questi pacchetti, i fornitori possono classificare i pacchetti preinstallati come pacchetti del fornitore aggiungendo i prefissi del pacchetto alla configurazione vendor package prefixes . Questa configurazione non accetta espressioni regolari.
  • Safe-to-terminate packages . I fornitori possono specificare quali pacchetti del fornitore possono essere terminati in modo sicuro aggiungendo i nomi completi dei pacchetti alla configurazione safe-to-terminate packages .
  • Application category mappings . I fornitori possono associare qualsiasi pacchetto (compresi i pacchetti di terze parti) a una delle due categorie di app supportate: app Mappa e Multimedia. Questa mappatura viene eseguita per fornire alle mappe e alle app multimediali soglie di utilizzo eccessivo di I/O del disco più elevate perché queste app tendono a scaricare e scrivere più dati su disco rispetto ad altri tipi di app.
  • Component level thresholds . Definisce soglie generiche per tutti i pacchetti del fornitore (ovvero, i pacchetti non coperti dalle Package specific thresholds o Application category specific thresholds ottengono queste soglie). I fornitori devono definire soglie a livello di componente diverse da zero quando definiscono la configurazione di utilizzo eccessivo dell'I/O del disco.
  • Package specific thresholds . I fornitori possono definire soglie speciali per pacchetti fornitore specifici. Le mappature dovrebbero contenere i nomi completi dei pacchetti. Le soglie definite in questa configurazione hanno la precedenza sulle soglie definite in altre configurazioni per un determinato pacchetto.
  • Application category specific thresholds . I fornitori possono specificare soglie speciali per categorie di app specifiche. Le categorie delle app devono essere una delle categorie supportate: app Mappe e multimediali. Le soglie definite in questa configurazione vengono mappate a pacchetti specifici utilizzando Application category mappings .
  • System-wide thresholds . I fornitori non devono specificare questa configurazione.

Vendor package prefixes , Safe-to-terminate packages , delle Component level thresholds e Package specific thresholds sono aggiornabili solo dalla configurazione del fornitore per le app e i servizi del fornitore. La configurazione Application category specific thresholds può essere aggiornata solo dalla configurazione del fornitore per tutte le mappe e le app multimediali.

Le soglie di utilizzo eccessivo contengono la quantità di byte che è possibile scrivere durante

  • Una modalità in primo piano dell'app/servizio rispetto alla modalità in background
  • e la modalità garage del sistema.

Questa classificazione consente alle app/servizi in primo piano rivolti all'utente di scrivere più dati rispetto alle app/servizi in background. In modalità Garage, le app e i servizi tendono a scaricare gli aggiornamenti, quindi ciascuno necessita di una soglia più elevata rispetto alle app e ai servizi in esecuzione in altre modalità.

Configurazioni di sistema e di terze parti

Gli OEM non devono aggiornare il sistema e le configurazioni di terze parti.

  • La configurazione del sistema definisce le soglie e le azioni di utilizzo eccessivo di I/O per le app e i servizi di sistema.
    • Questa configurazione può anche aggiornare le Application category mappings . Pertanto, questo campo di configurazione è condiviso tra le configurazioni del sistema e del fornitore.
  • La configurazione di terze parti definisce le soglie per tutte le app di terze parti. Tutte le app che non sono preinstallate nel sistema sono app di terze parti.
    • Tutte le app di terze parti ricevono le stesse soglie (ad esempio, nessuna app di terze parti riceve soglie speciali) ad eccezione delle mappe e delle app multimediali, le cui soglie sono definite dalla configurazione del fornitore.
    • Le soglie di utilizzo eccessivo di I/O del disco riportate di seguito sono le soglie predefinite per le app di terze parti. Queste soglie vengono fornite con l'immagine del sistema.
      • 3 GiB di scrittura nella modalità in primo piano dell'app.
      • 2 GiB di scrittura in modalità background dell'app.
      • 4 GiB scrivono in modalità garage di sistema.
    • Queste sono le soglie di base. Queste soglie vengono aggiornate man mano che comprendiamo meglio l'utilizzo dell'I/O del disco.

Utilizzo eccessivo del formato XML di configurazione

La configurazione predefinita del fornitore può essere posizionata (questo è facoltativo ) nella posizione /vendor/etc/automotive/watchdog/resource_overuse_configuration.xml nell'immagine build. Quando questa configurazione non è specificata, la configurazione definita dal sistema viene applicata anche alle app e ai servizi del fornitore.

Il file XML deve contenere solo un tag per ciascun campo di configurazione. La configurazione dell'uso eccessivo di I/O deve essere definita nel file XML. Tutti i valori di soglia devono essere specificati nell'unità MiB.

Di seguito viene fornita una configurazione XML di esempio:

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

Aggiorna la configurazione dell'uso eccessivo tramite le API del sistema CarWatchdogManager

La configurazione XML precedente può essere fornita solo nell'immagine build. Se un OEM sceglie di aggiornare la configurazione sul dispositivo dopo il rilascio di una build, può utilizzare le seguenti API per apportare modifiche alla configurazione sul dispositivo.

  • Concedere l'autorizzazione Car.PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG al chiamante.
  • È necessario utilizzare le configurazioni esistenti per aggiornare e impostare le nuove configurazioni. Utilizza l'API CarWatchdogManager.getResourceOveruseConfigurations per ottenere le configurazioni esistenti. Se le configurazioni esistenti non vengono utilizzate, tutte le configurazioni (incluse quelle di sistema e di terze parti) verranno sovrascritte, operazione sconsigliata.
  • Aggiorna le configurazioni esistenti con le modifiche delta e imposta le nuove configurazioni. Non aggiornare le configurazioni del sistema e dei componenti di terze parti.
  • Utilizza l'API CarWatchdogManager.setResourceOveruseConfigurations per impostare le nuove configurazioni.
  • Per ottenere e impostare le configurazioni di utilizzo eccessivo dell'I/O del disco, utilizzare il flag CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO .

Ecco un'implementazione di esempio che aggiorna le configurazioni dell'uso eccessivo delle risorse:

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

App che monitorano l'utilizzo eccessivo delle risorse

Le app dei fornitori e di terze parti possono ascoltare le notifiche di utilizzo eccessivo delle risorse specifiche dell'app da Watchdog o eseguire il polling CarWatchdogManager per le statistiche sull'utilizzo eccessivo delle risorse specifiche dell'app negli ultimi 30 giorni.

Ascolta le notifiche sull'uso eccessivo delle risorse

Le app possono implementare un listener di utilizzo eccessivo delle risorse e registrare il listener con CarWatchdogManager per ricevere notifiche specifiche dell'app quando superano l'80% o il 100% delle soglie di utilizzo eccessivo di I/O del disco. Le app possono utilizzare queste notifiche per:

  • Registra le statistiche sull'uso eccessivo di I/O del disco per l'analisi offline. Gli sviluppatori di app possono utilizzare questa registrazione per eseguire il debug del problema di utilizzo eccessivo di I/O del disco.
  • Ridurre le scritture I/O del disco fino al ripristino dei contatori di utilizzo eccessivo.

Cliente Java

  1. Implementa il listener ereditando 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. Registra l'istanza del listener chiamando 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. Annulla la registrazione dell'istanza del listener quando l'app ha terminato l'ascolto di:
    private void removeResourceOveruseListener() {
        CarWatchdogManager manager =
                (CarWatchdogManager) car.getCarManager(Car.CAR_WATCHDOG_SERVICE);
        mCarWatchdogManager.removeResourceOveruseListener(
              mListenerImpl);
    }
    

Cliente nativo

  1. Includi carwatchdog_aidl_interface-ndk_platform nella dipendenza shared_libs della regola di compilazione.

    Android.bp

    cc_binary {
        name: "sample_native_client",
        srcs: [
            "src/*.cpp"
        ],
        shared_libs: [
            "carwatchdog_aidl_interface-ndk_platform",
            "libbinder_ndk",
        ],
        vendor: true,
    }
    
  2. Aggiungere la policy SELinux per consentire al dominio del servizio del fornitore di utilizzare binder (macro binder_user ) e aggiungere il dominio del servizio del fornitore al dominio del client carwatchdog (carwatchdog_client_domain macro) . Vedi il codice seguente per 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. Implementa il listener di utilizzo eccessivo delle risorse ereditando BnResourceOveruseListener . Sostituisci BnResourceOveruseListener::onOveruse per gestire le notifiche di utilizzo eccessivo delle risorse.

    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. Avviare un pool di thread del raccoglitore e registrare il listener di utilizzo eccessivo delle risorse con il server watchdog. Il server watchdog è registrato con il nome del servizio 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);
    }
    

Sondaggio delle statistiche sull'uso eccessivo delle risorse

Le app possono eseguire il polling di CarWatchdogManager per le statistiche ATS di utilizzo eccessivo di I/O specifiche dell'app per gli ultimi 30 giorni.

Cliente Java

Utilizza CarWatchdogManager.getResourceOveruseStats per ottenere le statistiche sull'uso eccessivo delle risorse. Passa il flag CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO per ottenere le statistiche di utilizzo eccessivo dell'I/O del 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

Utilizza CarWatchdogServer.getResourceOveruseStats per ottenere le statistiche sull'uso eccessivo delle risorse. Passa l'enumerazione ResourceType.IO per recuperare le statistiche sull'uso eccessivo di I/O del 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
      }
}

Utilizzo eccessivo delle risorse UX

Dai priorità all'impostazione delle prestazioni dell'app

La pagina Impostazioni app contiene le impostazioni Prioritize app performance (vedi l'immagine seguente), che consentono all'utente di dare priorità alle prestazioni di un'app rispetto al sistema e alle prestazioni dell'hardware a lungo termine. Questa impostazione è disponibile solo per le app che possono essere terminate in modo sicuro in caso di utilizzo eccessivo delle risorse. Altrimenti, questa impostazione sarà disattivata. Quando questa impostazione è disattivata (impostazione predefinita) per un'app, l'app può essere terminata in caso di utilizzo eccessivo delle risorse. In caso contrario, l'app non verrà terminata in caso di utilizzo eccessivo delle risorse.

Quando l'utente attiva questa impostazione, la seguente finestra di dialogo di conferma descrive le implicazioni dell'attivazione dell'impostazione.

Dopo 90 giorni, questa impostazione viene ripristinata automaticamente ai valori predefiniti. Il limite giornaliero può essere modificato con un'app overlay RRO utilizzando watchdogUserPackageSettingsResetDays , fino a un massimo di 180 giorni. Per ulteriori informazioni, consulta Modificare il valore delle risorse di un'app in fase di esecuzione . Il seguente tag overlay di esempio può essere incluso in AndroidManifest.xml :

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

In res/values/config.xml :

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

In res/xml/overlays.xml :

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

Notifica all'utente

Quando un'app o un servizio utilizza ripetutamente l'I/O del disco (ad esempio, scrive dati su disco oltre le soglie definite) entro un certo periodo ed è sicuro che possa essere terminato in caso di utilizzo eccessivo delle risorse, l'utente viene avvisato dopo che il veicolo entra nella modalità di autorizzazione conducente -stato di distrazione.

La prima notifica all'utente (durante un viaggio) viene pubblicata come notifica di avvertimento e le altre notifiche vengono pubblicate nel centro notifiche.

Ad esempio, quando un'app utilizza ripetutamente l'I/O del disco, l'utente riceve la seguente notifica:

  • Quando l'utente fa clic sul pulsante Dai priorità all'app , viene avviata la pagina delle impostazioni dell'app, in cui l'utente può attivare o disattivare l'impostazione Dai priorità alle prestazioni dell'app .
  • Quando l'utente fa clic sul pulsante Disattiva app , l'app viene disabilitata finché l'utente non la avvia o la abilita nella pagina delle impostazioni dell'app.
  • Per le app non installabili, il pulsante Disattiva app viene sostituito con il pulsante Disinstalla app . Quando l'utente fa clic sul pulsante Disinstalla app , viene avviata la pagina Impostazioni dell'app, dalla quale l'utente può disinstallare l'app.

Raccomandazione per l'implementazione del launcher

Quando le app vengono disabilitate a causa di un utilizzo eccessivo delle risorse, le app scompaiono dall'app di avvio predefinita perché CarService aggiorna lo stato abilitato delle app come PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED . Gli OEM devono aggiornare l'implementazione del launcher integrato per visualizzare queste app come insolite, in modo che gli utenti possano utilizzarle se necessario. Vedi i seguenti consigli in base alla versione della build.

Versione Android SC V2