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 armazenamento com escopo. Anteriormente, no Android 10, os aplicativos podiam cancelar o armazenamento com escopo definido.

Restrições de acesso a aplicativos

O objetivo do armazenamento com escopo definido é proteger a privacidade dos dados do aplicativo e 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 aos seus próprios arquivos sem permissões
  • Acesso de leitura a 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 só é permitido com o consentimento direto do usuário (exceções concedidas à Galeria do Sistema e aos 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

Use armazenamento com escopo definido com FUSE

O Android 11 ou superior oferece suporte a Filesystem in Userspace (FUSE), que permite que o módulo MediaProvider examine 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 redigir o 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 direto de arquivo (mantendo as APIs de arquivos funcionando nos aplicativos).

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

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

Ajuste de desempenho do FUSE

Anteriormente, o Android suportava FUSE no Android 7 ou inferior, no qual o armazenamento externo era montado como FUSE. Devido a problemas de desempenho e impasse com a implementação do FUSE, o Android 8 introduziu o SDCardFS. O Android 11 reintroduz o suporte para FUSE usando uma implementação aprimorada e mais bem testada do 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 taxas 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 armazenamento em cache para reduzir IPCs no 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 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 MediaProvider oferecem o desempenho mais consistente, os desenvolvedores de aplicativos preocupados com o desempenho devem usar APIs MediaProvider em seus aplicativos.

Mitigar o impacto no desempenho do FUSE

O impacto no desempenho do FUSE é limitado apenas a usuários frequentes de arquivos armazenados em armazenamento externo compartilhado . 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.

  • Os 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 sofrer nenhum impacto no desempenho relacionado ao FUSE no Android 11.

  • Os aplicativos que são usuários frequentes de armazenamento externo compartilhado geralmente executam operações de arquivos 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 forem elegíveis 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 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 com desempenho otimizado. 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 acima do desempenho

Em dispositivos ajustados para FUSE, as jornadas de 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 do que o Android 10. Para padrões de acesso a arquivos com desempenho 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 melhor opção e com 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 versões anteriores, o 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 File, ele poderia solicitar ao MediaProvider que verificasse o arquivo e o registrasse 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 o sistema de arquivos no armazenamento externo e o banco de dados MediaProvider consistentes. Como manipulador de espaço de usuário para o sistema de arquivos FUSE, o MediaProvider pode interceptar chamadas de kernel e garantir que as operações de arquivo sejam protegidas em termos de privacidade.

No Android 11 e versões posteriores, 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 problemas de desempenho, privacidade ou segurança encontrados no MediaProvider podem ser corrigidos e entregues remotamente na Google Play Store ou em outros mecanismos fornecidos por parceiros. Qualquer coisa no escopo esperado de um manipulador FUSE também é atualizável, permitindo atualizações para corrigir regressões e bugs de desempenho do FUSE.