Armazenamento tradicional

Ícone do HAL de armazenamento externo do Android

O Android oferece suporte a dispositivos com armazenamento tradicional, que é definido como um sistema de arquivos sem distinção entre maiúsculas e minúsculas com classes e modos de permissão POSIX imutáveis. A noção de armazenamento tradicional inclui armazenamento emulado e portátil. O armazenamento portátil é definido como qualquer armazenamento externo que não seja adotado pelo sistema e, portanto, não seja formatado e criptografado ou vinculado a um dispositivo específico. Como o armazenamento externo tradicional oferece proteção mínima para dados armazenados, o código do sistema não deve armazenar dados sensíveis no armazenamento externo. Especificamente, os arquivos de configuração e de registro só podem ser armazenados no armazenamento interno, onde podem ser protegidos de forma eficaz.

Armazenamento externo para vários usuários

A partir do Android 4.2, os dispositivos podem oferecer suporte a vários usuários, e o armazenamento externo precisa atender às seguintes restrições:

  • Cada usuário precisa ter o próprio armazenamento externo principal isolado e não pode ter acesso ao armazenamento externo principal de outros usuários.
  • O caminho /sdcard precisa ser resolvido para o armazenamento externo principal correto específico do usuário com base no usuário em que um processo está sendo executado.
  • O armazenamento de arquivos OBB grandes no diretório Android/obb pode ser compartilhado entre vários usuários como uma otimização.
  • O armazenamento externo secundário não pode ser gravável por apps, exceto em diretórios específicos do pacote, conforme permitido pelas permissões sintetizadas.

A implementação da plataforma padrão desse recurso aproveita os namespaces do kernel do Linux para criar tabelas de montagem isoladas para cada processo bifurcado do Zygote e, em seguida, usa montagens de vinculação para oferecer o armazenamento externo principal correto específico do usuário nesse namespace particular.

Durante a inicialização, o sistema monta um único daemon FUSE de armazenamento externo emulado em EMULATED_STORAGE_SOURCE, que fica oculto dos apps. Depois que o Zygote se divide, ele vincula e monta o subdiretório específico do usuário abaixo do daemon FUSE para EMULATED_STORAGE_TARGET para que os caminhos de armazenamento externo sejam resolvidos corretamente para o app. Como um app não tem pontos de montagem acessíveis para o armazenamento de outros usuários, eles só podem acessar o armazenamento para o usuário em que ele foi iniciado.

Essa implementação também usa o recurso de kernel de subárvore compartilhada para propagar eventos de montagem do namespace raiz padrão para namespaces de apps, o que garante que recursos como contêineres ASEC e montagem de OBB continuem funcionando corretamente. Para fazer isso, ele monta os rootfs como compartilhados e, em seguida, os remonta como escravos depois que cada namespace Zygote é criado.

Vários dispositivos de armazenamento externo

No Android 4.4 e versões mais recentes, vários dispositivos de armazenamento externo são mostrados para os desenvolvedores por meio de Context.getExternalFilesDirs(), Context.getExternalCacheDirs() e Context.getObbDirs().

Os dispositivos de armazenamento externo exibidos por essas APIs precisam ser uma parte semipermanente do dispositivo (como um slot para cartão SD em um compartimento de bateria). Os desenvolvedores esperam que os dados armazenados nesses locais estejam disponíveis por longos períodos. Por esse motivo, dispositivos de armazenamento transitório (como unidades de armazenamento em massa USB) não podem ser exibidos por essas APIs.

A permissão WRITE_EXTERNAL_STORAGE só pode conceder acesso de gravação ao armazenamento externo principal de um dispositivo. Os apps não podem gravar em dispositivos de armazenamento externo secundários, exceto nos diretórios específicos do pacote, conforme permitido pelas permissões sintetizadas. A restrição de gravações dessa forma garante que o sistema possa limpar arquivos quando os aplicativos forem desinstalados.

Suporte a mídia USB

O Android 6.0 oferece suporte a dispositivos de armazenamento portáteis que são conectados ao dispositivo por um curto período, como pen drives USB. Quando um usuário insere um novo dispositivo portátil, a plataforma mostra uma notificação para que ele copie ou gerencie o conteúdo desse dispositivo.

No Android 6.0, qualquer dispositivo que não seja adotado é considerado portátil. Como o armazenamento portátil fica conectado por pouco tempo, a plataforma evita operações pesadas, como a verificação de mídia. Os apps de terceiros precisam passar pelo framework de acesso ao armazenamento para interagir com arquivos no armazenamento portátil. O acesso direto é bloqueado explicitamente por motivos de privacidade e segurança.