Problema de Inicialização no Android 13 ao Configurar IP Estático e Desligamento Abrupto

Descrição do Problema

Ao configurar um IP estático em um dispositivo Android 13 e ocorrer um desligamento abrupto (perda de energia), o dispositivo fica travado na animação de inicialização, não conseguindo acessar a área de trabalho.

Análise de Logs

Ao capturar os logs do sistema durante a inicialização problemática, observamos as seguintes mensagens críticas:

08-13 11:26:42.455  2803  2803 I EthernetServiceImpl: Starting Ethernet service
08-13 11:26:42.457  2803  2924 D ConnectivityService: Got NetworkProvider Messenger for EthernetNetworkFactory
08-13 11:26:42.458  2803  2803 E IpConfigStore: Bad version on IP configuration file, ignore read
08-13 11:26:42.460  2803  2803 E System  : ******************************************
08-13 11:26:42.461  2803  2803 E System  : ************ Failure starting system services
08-13 11:26:42.461  2803  2803 E System  : java.lang.RuntimeException: Failed to boot service com.android.server.ConnectivityServiceInitializer: onBootPhase threw an exception during phase 500

A exceção principal identificada foi:

Caused by: java.lang.NullPointerException: Attempt to read from field 'int android.util.ArrayMap.mSize' on a null object reference in method 'void android.util.ArrayMap.putAll(android.util.ArrayMap)'
	at android.util.ArrayMap.putAll(ArrayMap.java:705)
	at com.android.server.ethernet.EthernetConfigStore.loadConfigFileLocked(EthernetConfigStore.java:112)

Compreendendo as Fases de Inicialização do Android

O Android organiza a inicialização do sistema em várias fases distintas, sendo cada uma responsável por serviços específicos:

Fase Constante Descrição
100 PHASE_WAIT_FOR_DEFAULT_DISPLAY Aguardo pelo display padrão
480 PHASE_LOCK_SETTINGS_READY Disponibilidade de dados de configurações de bloqueio
500 PHASE_SYSTEM_SERVICES_READY Serviços do sistema podem chamar serviços centrais
520 PHASE_DEVICE_SPECIFIC_SERVICES_READY Serviços específicos do dispositivo disponíveis
550 PHASE_ACTIVITY_MANAGER_READY Serviços podem transmitir Intents
600 PHASE_THIRD_PARTY_APPS_CAN_START Aplicativos de terceiros podem iniciar
1000 PHASE_BOOT_COMPLETED Inicialização concluída

O problema ocorre na fase 500 (PHASE_SYSTEM_SERVICES_READY), onde o serviço de conectividade tenta inicializar. Quando qualquer serviço falha nesta fase, uma exceção é lançada e a inicialização é interrompida, causando o travamento na animação de inicialização.

Causa Raiz do Problema

O arquivo de configuração de IP (ipconfig.txt) é corrompido devido ao desligamento abrupto. O sistema operacional mantém dados em buffer de memória durante operações de escrita. Quando há perda de energia antes que os dados sejam sincronizados com o disco, o arquivo fica incompleto ou corrompido.

O código em IpConfigStore.java verifica a versão do arquivo de configuração:

int version = in.readInt();
if (version != 3 && version != 2 && version != 1) {
    loge("Bad version on IP configuration file, ignore read");
    return null; // Retorna null causando NullPointerException
}

Esta verificação falha quando o arquivo está corrompido, retornando null que subsequentemente causa o NullPointerException ao tentar operar no ArrayMap.

Soluções Propostas

Solução 1: Substituir o Arquivo de Configuração

Localize e substitua o arquivo ipconfig.txt corromipdo:

/data/misc/apexdata/com.android.tethering/misc/ethernet/ipconfig.txt

Solução 2: Remover e Recriar Configuração

Execute a remoção do arquivo corrompido e configure novamente o IP estático através de um broadcast receiver:

rm -rf /data/misc/apexdata/com.android.tethering/misc/ethernet/ipconfig.txt

Solução 3: Modificação no Código Fonte

Modifique IpConfigStore.java para retornar um mapa vazio em vez de null:

public static ArrayMap<String, IpConfiguration> readIpConfigurations(
        InputStream inputStream) {
    ArrayMap<String, IpConfiguration> networks = new ArrayMap<>();
    DataInputStream in = null;
    try {
        in = new DataInputStream(inputStream);

        int version = in.readInt();
        if (version != 3 && version != 2 && version != 1) {
            loge("Bad version on IP configuration file, ignore read");
            return networks; // Alteração: retorna mapa vazio em vez de null
        }
    } catch (Exception e) {
        loge("Error reading IP configurations: " + e);
        return networks;
    }
    // ... continuação do código
}

Solução 4: Alterar Sistema de Arquivos

Para dispositivos que utilizam a partição de dados em formato F2FS, considere converter para EXT4, que possui melhor proteção contra perda de dados em desligamentos abruptos.

No arquivo fstab, realize as seguintes modificações:

# Alterar de f2fs para ext4
/dev/block/by-name/userdata /data ext4 discard,noatime,nosuid,nodev,noauto_da_alloc,data=ordered,user_xattr,barrier=1 latemount,wait,formattable,check,fileencryption=software,quota,reservedsize=128M,checkpoint=block

Conclusão

O problema ocorre devido à falha na sincronização do buffer de memória com o disco durante desligamentos abruptos. A solução mais robusta envolve modificar o sistema de arquivos da partição de dados de F2FS para EXT4, garantindo maior integridade dos dados. Alternativamente, as modificações no código fonte fornecem uma solução imediata para permitir a inicialização do dispositivo mesmo quando o arquivo de configuração está corrompido.

Tags: android ethernet ip-estatico boot system-server

Publicado em 6-25 04:32