Quita paquetes para el usuario del sistema

En este artículo, se describe cómo mejorar el rendimiento identificando y quitando paquetes que no son necesarios para el usuario del sistema.

Inhabilita paquetes innecesarios

En Automotive, el usuario del sistema es sin interfaz gráfica, lo que significa que el Usuario del Sistema no está diseñado para que lo utilice un ser humano. Como resultado, muchas apps y servicios no necesitan ejecutarse en la cuenta de usuario pueden inhabilitarse para mejorar el rendimiento. Por lo tanto, existe una opción para quitar apps innecesarias para el Usuario del sistema (Usuario 0).

En esta página, se analizan dos tipos de usuarios:

  • SISTEMA. Siempre Usuario 0
  • COMPLETO. Usuario diseñado para que lo use una persona (un usuario que no es del sistema) Usuario mayor de 10 años

Android 11

En Android 11, cambias la configuración config_userTypePackageWhitelistMode Las marcas se pueden combinar. En este caso, 5 equivale a 1. más 4 (una combinación de las marcas 1 y 4)

Marca Descripción
0 Inhabilitar la lista de entidades permitidas instalar todos los paquetes del sistema; sin registro.
1 Aplicar. Instala paquetes del sistema solo cuando están incluidos en la lista de entidades permitidas.
2 Registra paquetes que no estén incluidos en la lista de entidades permitidas.
4 Los paquetes que no se mencionan en el archivo de la lista de entidades permitidas se incluyen de forma implícita en la lista de entidades permitidas de todos los usuarios.
8 Igual que 4 para el usuario del sistema.
16 Ignora las OTA . No instales paquetes del sistema durante actualizaciones inalámbricas.
Considera estas situaciones comunes.
  • Para habilitar una función en una lista de entidades permitidas completa, 1 (aplicada completamente)
  • Para habilitar una función en una lista de entidades permitidas incompleta, 5
  • Para habilitar una función para que el usuario de SYSTEM facilite el desarrollo local, 9 (lista de entidades permitidas implícita)
  • Para inhabilitar una función como si nunca se hubiera habilitado, 16
  • Para inhabilitar una función y deshacer todos los efectos anteriores, 0

Asegúrate de instalar el archivo en formato XML en el directorio sysconfig del dispositivo. (este es el mismo directorio que contiene el archivo makefile (`.mk`) que se usa para compilar la imagen del sistema del dispositivo). Cuando le asignes un nombre al archivo XML, incluya la ubicación en la que se define el paquete en la compilación. Por ejemplo, preinstalled-packages-product-car-CAR_PRODUCT_NAME.xml.

<!- this package will be installed for both FULL and SYSTEM user -->
    <install-in-user-type package="com.android.bluetooth"->
        <install-in user-type="FULL" /->
        <install-in user-type="SYSTEM" /->
    </install-in-user-type->

<!- this package will only be installed for both FULL user -->
    <install-in-user-type package="com.android.car.calendar"->
        <install-in user-type="FULL" >
    </install-in-user-type->

Android 9 y Android 10

Para configurar esta función en Android 9 y Android 10, haz lo siguiente:

  1. Superpone el config_systemUserPackagesBlacklistSupported config desde frameworks/base/core/res/res/values/config.xml y establece a true. Cuando la función está activada, de forma predeterminada, todos los paquetes se debe instalar tanto para el Usuario del sistema como para el Usuario COMPLETO.
  2. Crea un archivo config.xml en el que se enumeren los paquetes que se deben inhabilitado para el Usuario del sistema. Por ejemplo:
    <config>
        <!-- This package will be uninstalled for the system user -->
        <system-user-blacklisted-app package="com.google.car.calendar" />
    </config>
    
  3. Agrega una línea a device.mk para copiar el archivo en el dispositivo. la carpeta de destino system/etc/sysconfig/. Por ejemplo:
    PRODUCT_COPY_FILES += <full path to the config file>:system/etc/sysconfig/<new denylist config file>.xml
    

Verifica el resultado

Para verificar el resultado, ejecuta el siguiente comando:

$ adb shell dumpsys user | grep PACKAGE_SUBSTRING
$ adb shell pm list packages --user USER_ID PACKAGE_SUBSTRING
$ adb shell cmd user report-system-user-package-whitelist-problems

Establecimiento

Para determinar si se debe instalar un paquete en el usuario del sistema, examina el AndroidManifest.xml del paquete, ubicado en la raíz de la fuente del proyecto, incluidos los atributos de la aplicación y los componentes de la que incluyen todas las actividades, servicios, receptores de emisión y contenido proveedores. Para obtener más información, consulta Aplicación Descripción general del manifiesto

Inhabilitar el flujo de trabajo de paquetes

Figura 1: Inhabilitar el flujo de trabajo de paquetes

Nivel 1, nivel de la app

1. Verifica si la app (o sus componentes) se declararon como singleton

Si la app es una singleton el sistema creará una instancia de la app solo en el Usuario del sistema. Es probable que la app estaba diseñada para ser una app multiusuario. Obtén más información sobre el reconocimiento multiusuario , consulta Cómo compilar apps con reconocimiento de multiusuario.

  1. Revisa el manifiesto de Android para android:singleUser="true".
  2. Si el valor es true, incluye en la lista de entidades permitidas. Necesaria para el usuario del sistema.
  3. Si es false, continúa. Consulta otros criterios antes de quitarlos.

2. Cómo comprobar si la app requiere acceso al almacenamiento protegido

Muchos servicios de inicio del sistema a menudo dependen del almacenamiento encriptado por dispositivo (DE) de almacenamiento encriptado por credenciales (CE). Además, las apps del sistema que son directas también dependen del almacenamiento encriptado por dispositivo. Para obtener más información iniciar apps compatibles con el inicio, consulta Asistencia Inicio directo en apps del sistema

  1. Consulta el manifiesto de Android para android:defaultToDeviceProtectedStorage="true", que es necesaria para varios servicios de arranque del sistema.
  2. Si el valor es true, incluye en la lista de entidades permitidas.
  3. Si es false, continúa.

Nivel 2, componentes de la app

Actividades

Para obtener más información sobre las actividades, consulta Introducción. en Actividades.

a. Cómo comprobar si la app solo contiene actividades

Las actividades están orientadas a la interfaz de usuario. Como el usuario del sistema no tiene interfaz gráfica Automotive, ninguna persona debe interactuar con el Usuario del Sistema. Como resultado, si la app solo contiene actividades, lo más probable es que no sea relevante para el Usuario del sistema

Comprueba la prioridad y el privilegio especial.

  1. Si la respuesta es , es posible que sea necesaria para el usuario del sistema.
  2. Si la respuesta es No, no incluyas en la lista de entidades permitidas el usuario del sistema.

Por ejemplo, el Conjunto de pruebas de compatibilidad (CTS) (com.android.cts.priv.ctsshim) contiene solo actividades. Las actividades se definen para probar los filtros de intents. Sin embargo, como tiene una alta , debe instalarse para el Usuario del sistema con fines de prueba.

Servicio

Para obtener más información sobre los servicios, consulta Descripción general de los servicios.

b. Comprueba si el servicio se declaró como privado y si no se puede acceder a él desde otras apps

Si el servicio se declara como privado, los demás paquetes no usarán el elemento servicio. Busca android:exported="false". Si se declara el servicio como privado o no se puede acceder a él desde otras aplicaciones, no se puede vincular otras apps. Por lo tanto, los pasos C y D que aparecen a continuación son irrelevantes. Como resultado, este componente no proporcionará más pistas sobre si el servicio es necesario o no para el usuario del sistema.

  1. Si la respuesta es , verifica el siguiente componente.
  2. Si la respuesta es No, continúa verificando este componente.

c. Verifica si las apps instaladas en el usuario del sistema pueden vincularse a este servicio

Busca paquetes en la lista de entidades permitidas del nivel 1 y, luego, identifica los servicios para los cuales están vinculados. Haz un seguimiento del filtro de intents en este servicio y startService en otros paquetes.

Si este servicio está vinculado a apps instaladas en el Usuario del sistema (por ejemplo, com.android.car.companiondevicesupport está incluido en la lista de entidades permitidas para ejecutarse en Usuario del sistema) y, luego, agrega el servicio a la lista de entidades permitidas.

  1. Si la respuesta es , incluye en la lista de entidades permitidas.
  2. Si la respuesta es No, continúa verificando este componente.

d. Verifica si el servicio está vinculado a otras apps y se declaró para ejecutarse en primer plano

Busca startForeground. Esto significa que las personas interactuarían con la aplicación en primer plano. Lo más probable es que este servicio no sea necesario para Usuario del sistema, y no es necesario que se lo incluya en la lista de entidades permitidas.

  1. Si la respuesta es , no incluyas en la lista de entidades permitidas.
  2. Si la respuesta es No, continúa verificando el siguiente componente.

e. Comprueba si el servicio está definido para ejecutarse en el proceso del sistema

En AndroidManifest, busca android:process="system".
Si el servicio se define intencionalmente para que se ejecute en el proceso del sistema, entonces significa que se ejecutará explícitamente en el mismo proceso que el servicio del sistema deben estar incluidos en la lista de entidades permitidas para que se ejecuten en el Usuario del sistema. Como parte de la memoria de Android de asignación y los servicios del sistema son algunos de los últimos procesos lo que implica la importancia de los servicios definidos con un atributo de este tipo. Para Para obtener más información sobre el diseño de asignación de memoria de Android, consulta Baja memoria. rendimiento.

  1. Si la respuesta es , no incluyas en la lista de entidades permitidas.
  2. Si la respuesta es No, continúa revisando otros componentes.

Por ejemplo, el paquete com.android.networkstack.inprocess debe tener incluido en la lista de entidades permitidas ya que contiene RegularMaintenanceJobService, que tiene la etiqueta android:process="system".

Proveedor de contenido

Para obtener más información sobre los proveedores de contenido, consulta Proveedores de contenido.

f. Comprueba si la app instalada en el usuario del sistema depende de este proveedor

Busca paquetes en la lista de entidades permitidas del nivel 1 y comprueba qué proveedores de las que dependen. Si una app que se ejecuta en el Usuario del sistema (por ejemplo, com.android.car.companiondevicesupport está incluido en la lista de entidades permitidas para ejecutarse en Usuario del sistema) y depende de este proveedor de contenido, asegúrate de que este contenido proveedor también está en la lista de entidades permitidas.

  1. Si la respuesta es , incluye en la lista de entidades permitidas.
  2. Si la respuesta es No, no incluyas en la lista de entidades permitidas.

Por ejemplo, si com.android.car.EXAMPLE contiene singleton proveedores (SystemActionsContentProvider y ManagedProvisioningActionsContentProvider), debe ser incluidos en la lista de entidades permitidas del usuario del sistema. Luego, si com.android.car.EXAMPLE depende de android.webkit para WebViewFactoryProvider entonces, com.android.webview debe estar en la lista de entidades permitidas del usuario del sistema dado que carga android.webkit.

Explicación del paquete de muestra

En el siguiente ejemplo, se muestra cómo evaluar el AndroidManifest.xml de un paquete:

<?xml version="1.0" encoding="utf-8"?>
<!-- 1. Search in the entire manifest for singleUser attribute.
No. Move to step 2 -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.android.providers.calendar"
        android:sharedUserId="android.uid.calendar">
    We can ignore the entire permission section
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    ...
    <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
<!-- 2. Look for defaultToDeviceProtectedStorage in application's attribute.
No. Continue evaluating app components. -->
    <application android:label="@string/calendar_storage"
                 android:allowBackup="false"
                 android:icon="@drawable/app_icon"
                 android:usesCleartextTraffic="false">
<!-- a. Contain only activities?
No. Continue to evaluate components other than activities. -->
        <provider android:name="CalendarProvider2" android:authorities="com.android.calendar"
                <!-- b. Is this component exported?
                Yes. Continue evaluating this component.
                f. App on u0 might depend on this? Search for CalendarProvider2 in dumpsys, shows ContentProviderRecord{b710923 u0 com.android.providers.calendar/.CalendarProvider2}
                Yes. Whitelist for system user. -->
                android:label="@string/provider_label"
                android:multiprocess="false"
                android:exported="true"
                android:readPermission="android.permission.READ_CALENDAR"
                android:writePermission="android.permission.WRITE_CALENDAR" />

<activity android:name="CalendarContentProviderTests" android:label="Calendar Content Provider" android:exported="false"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.UNIT_TEST" /> </intent-filter> </activity> <!-- Not service/content provider. Ignore. --> <receiver android:name="CalendarProviderBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="com.android.providers.calendar.intent.CalendarProvider2"/> <category android:name="com.android.providers.calendar"/> </intent-filter> <intent-filter> <action android:name="android.intent.action.EVENT_REMINDER"/> <data android:scheme="content" /> </intent-filter> </receiver> <service android:name="CalendarProviderIntentService"/> </application> </manifest>