Testar vários usuários

Esta página descreve aspectos importantes do teste com vários usuários na Plataforma Android. Para saber mais sobre a implementação do suporte a vários usuários, consulte Suporte a vários usuários.

Caminhos de dispositivos

A tabela a seguir lista vários caminhos de dispositivo e como eles são resolvidos. Todos os valores na coluna Path são um armazenamento em sandbox específico do usuário. A história de armazenamento do Android mudou com o tempo. Leia a documentação do Armazenamento para mais informações.

Caminho Caminho do sistema (opcional) Objetivo
/data/user/{userId}/{app.path} /data/data Armazenamento de apps
/storage/emulated/{userId} /sdcard Armazenamento interno compartilhado
/data/media/{userId} none Dados de mídia do usuário (por exemplo, músicas, vídeos)
/data/system/users/{userId} none Configuração/estado do sistema por usuário

Acessível apenas por apps do sistema

Confira um exemplo de uso de um caminho específico do usuário:

# to access user 10's private application data for app com.bar.foo:
$ adb shell ls /data/user/10/com.bar.foo/

interações do adb entre usuários

Vários comandos adb são úteis ao lidar com vários usuários. Alguns desses comandos têm suporte apenas no Android 9 e versões mais recentes:

  • adb shell am instrument --user <userId> executa um teste de instrumentação em um usuário específico. Por padrão, essa opção usa o usuário atual.
  • O adb install --user <userId> instala um pacote para um usuário específico. Para garantir que um pacote seja instalado para todos os usuários, chame esse método para todos os usuários.
  • adb uninstall --user <userId> desinstala um pacote para um usuário específico. Chame sem a flag --user para desinstalar para todos os usuários.
  • adb shell am get-current-user recebe o ID do usuário atual (em primeiro plano).
  • adb shell pm list users recebe uma lista de todos os usuários existentes.
  • adb shell pm create-user cria um novo usuário e retorna o ID.
  • adb shell pm remove-user remove um usuário específico por ID.
  • adb shell pm disable --user <userId> desativa um pacote para um usuário específico.
  • adb shell pm enable --user <userId> ativa um pacote para um usuário específico.
  • adb shell pm list packages --user <userId> lista pacotes (-e para ativado, -d para desativado) para um usuário específico. Por padrão, ele sempre lista para o usuário do sistema.

As informações a seguir ajudam a explicar como o adb se comporta com vários usuários:

  • adb (ou o daemon adbd, mais precisamente) sempre é executado como o usuário do sistema (ID do usuário = 0) independente de qual usuário é atual. Portanto, caminhos de dispositivo que dependem do usuário (como /sdcard/) sempre são resolvidos como o usuário do sistema. Consulte Caminhos do dispositivo para mais detalhes.

  • Se um usuário padrão não for especificado, cada subcomando adb terá um usuário diferente. A prática recomendada é recuperar o ID do usuário com am get-current-user e, em seguida, usar explicitamente --user <userId> para qualquer comando compatível. As flags de usuário explícitas não eram compatíveis com todos os comandos até o Android 9.

  • O acesso aos caminhos /sdcard de usuários secundários é negado a partir do Android 9. Consulte Provedor de conteúdo para dados de vários usuários para saber como extrair arquivos durante o teste.

Provedor de conteúdo para dados de vários usuários

Como adb é executado como o usuário do sistema e os dados são isolados em um ambiente de teste no Android 9 e versões mais recentes, é necessário usar provedores de conteúdo para enviar ou extrair dados de teste de um usuário que não seja do sistema. Isso não é necessário se:

  • adbd está sendo executado como raiz (usando adb root), o que só é possível usando builds userdebug ou usereng.

  • Você está usando o ITestDevice do Trade Federation (Tradefed) para enviar ou receber os arquivos. Nesse caso, use caminhos /sdcard/ na configuração de teste. Por exemplo, consulte o código-fonte de pushFile em NativeDevice.java.

Quando um provedor de conteúdo está em execução no usuário secundário, é possível acessá-lo usando o comando adb shell content com o user, o uri e outros parâmetros especificados.

Alternativa para desenvolvedores de apps

Interaja com arquivos de teste usando adb content e uma instância de ContentProvider, em vez do comando push ou pull.

  1. Crie uma instância de ContentProvider hospedada pelo app que possa exibir e armazenar arquivos quando necessário. Use o armazenamento interno do app.
  2. Use os comandos adb shell content read ou write para enviar ou extrair os arquivos.

Solução alternativa para arquivos de mídia

Para enviar arquivos de mídia para a partição de mídia do cartão SD, use as APIs públicas MediaStore. Exemplo:

# push MVIMG_20190129_142956.jpg to /storage/emulated/10/Pictures
# step 1
$ adb shell content insert --user 10 --uri content://media/external/images/media/ --bind _display_name:s:foo.jpg

# step 2
$ adb shell content query --user 10 --projection _id --uri content://media/external/images/media/ --where "_display_name=\'foo.jpg\'"

# step 3
$ adb shell content write --user 10 --uri content://media/external/images/media/8022 < MVIMG_20190129_142956.jpg

Instalar um provedor de conteúdo genérico

Instale e use um provedor de conteúdo que leia e gravasse arquivos no caminho /sdcard específico do usuário.

Crie o TradefedContentProvider.apk a partir da origem usando make TradefedContentProvider:

```
# install content provider apk
$ adb install --user 10 -g TradefedContentProvider.apk

# pull some_file.txt
$ adb shell content read --user 10 --uri content://android.tradefed.contentprovider/sdcard/some_file.txt > local_file.txt

# push local_file.txt
$ adb shell content write --user 10 --uri content://android.tradefed.contentprovider/sdcard/some_file.txt < local_file.txt
```

Suporte a vários usuários da Trade Federation

O Tradefed é o arcabouço de teste oficial do Android. Esta seção resume alguns dos suportes integrados do Tradefed para cenários de teste com vários usuários.

Verificadores de status

Os verificadores de status do sistema (SSCs, na sigla em inglês) são executados antes dos preparadores de destino, e a limpeza deles é executada após esses preparadores.

UserChecker é definido explicitamente para ajudar os desenvolvedores a testar vários usuários. Ele rastreia se um teste mudou o estado dos usuários no dispositivo (por exemplo, criou usuários sem removê-los na desmontagem). Além disso, se user-cleanup for definido, ele tentará limpar automaticamente após o teste, além de fornecer erros úteis para que o teste possa ser corrigido.

<system_checker class="com.android.tradefed.suite.checker.UserChecker" >
    <option name="user-cleanup" value="true" />
</system_checker>

Preparador de destino

Os preparadores de destino normalmente são usados para configurar um dispositivo com uma configuração específica. No caso de testes com vários usuários, os preparadores podem ser usados para criar usuários de um tipo específico e alternar para outros usuários.

Para tipos de dispositivos que não têm um usuário secundário, é possível usar CreateUserPreparer para criar e alternar para um usuário secundário em AndroidTest.xml. No final do teste, o preparador retorna e exclui o usuário secundário.

<target_preparer
  class="com.google.android.tradefed.targetprep.CreateUserPreparer" >
</target_preparer>

Se o tipo de usuário que você quer já existe no dispositivo, use SwitchUserTargetPreparer para alternar para o usuário existente. Os valores comuns para user-type incluem system ou secondary.

<target_preparer
  class="com.android.tradefed.targetprep.SwitchUserTargetPreparer">
    <option name="user-type" value="secondary" />
</target_preparer>

Testes orientados pelo host

Em alguns casos, um teste precisa trocar de usuário dentro do teste. Não faça a troca em um framework de teste no dispositivo, como o UI Automator, porque o processo de teste pode ser encerrado a qualquer momento. Em vez disso, use um framework de teste do host, como o framework de teste do host da Tradefed, que dá acesso a ITestDevice, permitindo qualquer manipulação do usuário necessária.

Use UserChecker (descrito em Verificadores de status) para testes orientados pelo host que mudam o estado do usuário, porque ele garante que o teste seja limpo corretamente.