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.