Armazenamento com escopo

O armazenamento com escopo limita o acesso do aplicativo ao armazenamento externo. No Android 11 ou superior, os aplicativos direcionados à API 30 ou superior devem usar o armazenamento com escopo. Anteriormente no Android 10, os aplicativos podiam desativar o armazenamento com escopo.

Restrições de acesso ao aplicativo

O objetivo do armazenamento com escopo é proteger a privacidade do aplicativo e dos dados do usuário. Isso inclui proteger as informações do usuário (como metadados de fotos), impedir que aplicativos modifiquem ou excluam arquivos do usuário sem permissão explícita e proteger documentos confidenciais do usuário baixados para Download ou outras pastas.

Os aplicativos que usam armazenamento com escopo podem ter os seguintes níveis de acesso (o acesso real é específico da implementação).

  • Acesso de leitura e gravação em seus próprios arquivos sem permissões
  • Acesso de leitura aos arquivos de mídia de outros aplicativos com permissão READ_EXTERNAL_STORAGE
  • O acesso de gravação aos arquivos de mídia de outros aplicativos é permitido apenas com o consentimento direto do usuário (exceções concedidas ao System Gallery e aplicativos qualificados para acesso a todos os arquivos)
  • Sem acesso de leitura ou gravação aos diretórios de dados de aplicativos externos de outros aplicativos

Usando armazenamento com escopo com FUSE

O Android 11 ou superior oferece suporte a Filesystem in Userspace (FUSE), que permite que o módulo MediaProvider examine as operações de arquivo no espaço do usuário e bloqueie o acesso a arquivos com base na política para permitir , negar ou editar acesso. Os aplicativos no armazenamento com escopo que usam o FUSE obtêm os recursos de privacidade do armazenamento com escopo e a capacidade de acessar arquivos usando um caminho de arquivo direto (mantendo as APIs de arquivo funcionando nos aplicativos).

O Android 10 impôs regras de armazenamento com escopo em acessos a arquivos pelo MediaProvider, mas não para acesso direto ao caminho do arquivo (por exemplo, usando APIs de arquivos e APIs do NDK) devido ao esforço necessário para interceptar chamadas do kernel. Como resultado, os aplicativos no armazenamento com escopo não podiam acessar arquivos usando um caminho de arquivo direto. Essa restrição afetou a capacidade de adaptação dos desenvolvedores de aplicativos, pois exigia alterações substanciais de código para reescrever o acesso da API de arquivo à API MediaProvider.

FUSE e SDCardFS

O suporte do Android 11 para FUSE não está relacionado à descontinuação do SDCardFS , mas fornece uma alternativa ao Media Store para dispositivos que usavam SDCardFS anteriormente. Dispositivos:

  • A inicialização com o Android 11 ou superior usando o kernel 5.4 ou superior não pode usar o SDCardFS.
  • A atualização para o Android 11 ou superior pode hospedar o FUSE em cima do SDCardFS para interceptar as operações de arquivo e atender às metas de privacidade.

Ajuste de desempenho do FUSE

O Android suportava anteriormente o FUSE no Android 7 ou inferior, no qual o armazenamento externo era montado como FUSE. Devido a problemas de desempenho e impasse com essa implementação do FUSE, o Android 8 introduziu o SDCardFS. O Android 11 reintroduz o suporte para FUSE usando uma implementação aprimorada e melhor testada de libfuse que pode ser ajustada para resolver os problemas de desempenho no Android 7 ou inferior.

O ajuste do FUSE inclui os seguintes ajustes:

  • Ignorando o FUSE para os diretórios Android/data e Android/obb para melhorar o desempenho de aplicativos de jogos que dependem desses diretórios.
  • Otimizações (como ajustar as proporções de leitura antecipada e suja do sistema de arquivos FUSE) para manter o desempenho das leituras e a reprodução de mídia suave.
  • Usando o cache de write-back do FUSE.
  • Permissões de cache para reduzir IPCs ao servidor do sistema.
  • Otimizações para aplicativos com acesso a todos os arquivos para agilizar as operações em massa.

Os ajustes de ajuste acima podem produzir desempenho comparável entre dispositivos FUSE e não-FUSE. Por exemplo, testar um Pixel 2 ajustado usando FUSE e um Pixel 2 usando o Media Store encontrou desempenho de leitura sequencial comparável (por exemplo, reprodução de vídeo) entre o acesso ao caminho do arquivo e o Media Store. No entanto, as gravações sequenciais foram um pouco piores com o FUSE, e as leituras e gravações aleatórias podem ser até duas vezes mais lentas.

As medições de desempenho podem mudar de dispositivo para dispositivo e entre casos de uso específicos. Como as APIs do MediaProvider oferecem o desempenho mais consistente, os desenvolvedores de aplicativos preocupados com o desempenho devem usar as APIs do MediaProvider para seus aplicativos.

Mitigação do impacto no desempenho do FUSE

O impacto no desempenho do FUSE é limitado apenas a usuários pesados ​​de arquivos armazenados em armazenamento compartilhado externo. O armazenamento privado externo (que inclui os diretórios android/data e android/obb ) é ignorado pelo FUSE, enquanto o armazenamento interno (como /data/data , onde muitos aplicativos armazenam dados para mantê-los criptografados e seguros) não é montado no FUSE.

  • Aplicativos que são usuários leves de armazenamento externo compartilhado geralmente interagem com um conjunto limitado de arquivos (normalmente menos de 100 arquivos). Esses aplicativos se beneficiam das otimizações existentes de operações comuns de leitura e gravação e não devem ter nenhum impacto no desempenho relacionado ao FUSE no Android 11.

  • Os aplicativos que são usuários pesados ​​de armazenamento externo compartilhado normalmente executam operações de arquivo em massa, como listar ou remover um diretório com 1.000 arquivos ou criar ou excluir um diretório com um milhão de arquivos no sistema de arquivos. As operações de arquivos em massa podem ser afetadas pelo FUSE no Android 11, mas se esses aplicativos estiverem qualificados para a permissão MANAGE_EXTERNAL_STORAGE , eles se beneficiarão das otimizações de desempenho incluídas na atualização de outubro de 2020.

Para evitar a sobrecarga de desempenho do FUSE, os aplicativos podem armazenar dados em armazenamento privado externo ou usar APIs em massa na classe ContentProvider para ignorar o FUSE e obter um caminho otimizado para desempenho. Além disso, a atualização de outubro de 2020 para o componente do sistema MediaProvider inclui otimizações de desempenho para gerenciadores de arquivos e aplicativos semelhantes (como backup/restauração, antivírus) que possuem a permissão MANAGE_EXTERNAL_STORAGE .

Privacidade sobre o desempenho

Em dispositivos que foram ajustados para o FUSE, as jornadas do usuário mais críticas têm o mesmo desempenho entre o Android 10 e o Android 11. No entanto, ao testar benchmarks em um conjunto de operações de arquivo, o Android 11 pode ter um desempenho pior que o Android 10. Para padrões de acesso a arquivos que executam pior no Android 11 (por exemplo, leituras ou gravações aleatórias), recomendamos o uso de APIs MediaProvider para fornecer aos aplicativos um modo de acesso não FUSE, que é a opção com melhor desempenho e desempenho consistente.

Atualizações do MediaProvider e do FUSE

O comportamento do componente do sistema MediaProvider difere entre as versões do Android.

  • No Android 10 e inferior, SDCardFS era o sistema de arquivos e o MediaProvider fornecia uma interface para coleções de arquivos (por exemplo, imagens, vídeos, arquivos de música etc.). Quando um aplicativo criava um arquivo usando a API de arquivo, ele poderia solicitar ao MediaProvider para verificar o arquivo e gravá-lo no banco de dados.

  • No Android 11 ou superior, o SDCardFS está obsoleto e o MediaProvider se torna o manipulador do sistema de arquivos (para FUSE) para armazenamento externo, tornando consistente o sistema de arquivos no armazenamento externo e o banco de dados MediaProvider. Como o manipulador de espaço do usuário para o sistema de arquivos FUSE, o MediaProvider pode interceptar chamadas do kernel e garantir que as operações de arquivo sejam seguras para a privacidade.

No Android 11 e superior, o MediaProvider também é um componente modular do sistema (um módulo Mainline) que pode ser atualizado fora das versões do Android. Isso significa que os problemas de desempenho, privacidade ou segurança encontrados no MediaProvider podem ser corrigidos e entregues pelo ar a partir da Google Play Store ou de outros mecanismos fornecidos por parceiros. Qualquer coisa no escopo do que é esperado de um manipulador FUSE também é atualizável, permitindo atualizações para corrigir regressões e bugs de desempenho do FUSE.