En esta página, se describe cómo mejorar el rendimiento mediante la identificación y eliminación de paquetes que no son necesarios para el usuario del sistema.
Inhabilita paquetes innecesarios
En Automotive, el usuario del sistema no tiene interfaz gráfica, lo que significa que una persona no debe usarlo ni acceder directamente a él. Como resultado, muchas apps y servicios no necesitan ejecutarse en el usuario del sistema y se pueden inhabilitar para mejorar el rendimiento. Por lo tanto, se proporciona una opción para quitar las apps innecesarias para el usuario del sistema (Usuario 0).
En esta página, se analizan dos tipos de usuarios:
- SISTEMA. Siempre el usuario 0
- FULL. Usuario que está 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, cambia la configuración config_userTypePackageWhitelistMode
. Las marcas se pueden combinar. En este caso, 5
equivale a 1
más 4
(una combinación de marcas 1
y 4
).
Marca | Descripción |
---|---|
0 |
Inhabilitar la lista de entidades permitidas Instala 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 |
Cualquier paquete que no se mencione en el archivo de la lista de entidades permitidas se incluirá de forma implícita en la lista de entidades permitidas para todos los usuarios. |
8 |
Igual que 4 , para el usuario del sistema. |
16 |
Ignora las OTA. No instales paquetes del sistema durante las actualizaciones inalámbricas. |
Considera estas situaciones comunes:
- Para habilitar una función para una lista de entidades permitidas completa,
1
(aplicación forzosa completa) - 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, usa9
(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
Instala el archivo XML en el directorio sysconfig
del dispositivo (es el mismo que contiene el archivo makefile (.mk
) que se usó para compilar la imagen del sistema del dispositivo). Cuando asignes un nombre al archivo en formato XML, incluye 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:
- Superpone la configuración de
config_systemUserPackagesBlacklistSupported
deframeworks/base/core/res/res/values/config.xml
y configúrala entrue
. Cuando la función está activada, de manera predeterminada, se deben instalar todos los paquetes tanto para el usuario del sistema como para el usuario FULL. - Crea un archivo
config.xml
que enumere los paquetes que se deben inhabilitar 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>
- Agrega una línea a
device.mk
para copiar el archivo en la carpeta de destinosystem/etc/sysconfig/
del dispositivo, 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 un paquete se debe instalar en el usuario del sistema, examina el archivo AndroidManifest.xml
del paquete ubicado en la raíz de la fuente del proyecto, incluidos los atributos y los componentes de la app, que incluyen todas las actividades, los servicios, los receptores de emisión y los proveedores de contenido. Para obtener más información, consulta Descripción general del manifiesto de la app.
Figura 1: Inhabilita el flujo de trabajo de paquetes.
Nivel 1, nivel de la app
1. Verifica si la app (o sus componentes) se declaró como un singleton
Si la app es un singleton, el sistema crea una instancia de la app solo en el usuario del sistema. Es probable que la app se haya diseñado para varios usuarios. Para obtener más información sobre las apps para varios usuarios, consulta Cómo compilar apps para varios usuarios.
- Busca
android:singleUser="true"
en el manifiesto de Android. - Si es
true
, se agrega a la lista de entidades permitidas. Necesaria para el usuario del sistema. - Si es
false
, continúa. Verifica 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) en lugar del almacenamiento encriptado por credenciales (CE). Además, las apps del sistema que son compatibles con el inicio directo también dependen del almacenamiento encriptado del dispositivo. Para obtener más información sobre las apps que admiten el inicio directo, consulta Cómo admitir el inicio directo en las apps del sistema.
- Verifica el manifiesto de Android en busca de
android:defaultToDeviceProtectedStorage="true"
, que es necesario para varios servicios de inicio del sistema. - Si es
true
, inclúyelo en la lista de entidades permitidas. - Si es
false
, continúa.
Nivel 2, componentes de la app
Actividades
Para obtener más información sobre las actividades, consulta Introducción a las 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 en Automotive, ninguna persona debe interactuar con él. Como resultado, si la app solo contiene actividades, es probable que sea irrelevante para el usuario del sistema.
Verifica si hay privilegios especiales y de prioridad:
- Si se muestra Yes, es posible que el usuario del sistema lo necesite.
- Si la respuesta es No, no incluyas una lista de entidades permitidas para el usuario del sistema.
Por ejemplo, el Compatibility Test Suite (CTS) (com.android.cts.priv.ctsshim
) solo contiene actividades, y las actividades se definen para probar filtros de intents. Sin embargo, como CTS tiene un privilegio alto, 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 lo usarán. Busca android:exported="false"
. Si el servicio se declara como privado o no se puede acceder a él desde otras apps, no se puede vincular a otras apps. Por lo tanto, los pasos c y d a continuación son irrelevantes. Como resultado, este componente no proporcionaría más sugerencias sobre si el servicio es necesario para el usuario del sistema.
- Si la respuesta es Sí, verifica el siguiente componente.
- Si la respuesta es No, continúa verificando este componente.
c. Verifica si el usuario de las apps instaladas en el sistema se puede vincular a este servicio
Busca paquetes en la lista de entidades permitidas del nivel 1 y, luego, identifica los servicios
a los que están vinculados. Genera un registro desde el 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á en la lista de entidades permitidas para ejecutarse en el usuario del sistema), agrega el servicio a la lista de entidades permitidas:
- Si la respuesta es Sí, agrégalo a la lista de entidades permitidas.
- Si la respuesta es No, continúa verificando este componente.
d. Verifica si el servicio está vinculado desde otras apps y se declaró para que se ejecute en primer plano
Busca startForeground
. Esto significa que las personas interactuarían con la app en primer plano. Lo más probable es que este servicio no sea necesario para el usuario del sistema y que no esté incluido en la lista de entidades permitidas:
- Si la respuesta es Sí, no incluyas el dominio en la lista de entidades permitidas.
- 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 el archivo AndroidManifest, busca android:process="system"
.
Si el servicio se define de forma intencional para que se ejecute en el proceso del sistema, se ejecutará en el mismo proceso que el servicio del sistema y debería incluirse en la lista de entidades permitidas para que se ejecute en el usuario del sistema. Como parte del diseño de asignación de memoria de Android, los servicios del sistema son algunos de los últimos procesos que se cancelan, lo que implica la criticidad de los servicios definidos con ese atributo. Para obtener más información sobre el diseño de asignación de memoria de Android, consulta Eliminador de poca memoria.
- Si la respuesta es Sí, no lo incluyas en la lista de entidades permitidas.
- Si la respuesta es No, continúa verificando otros componentes.
Por ejemplo, el paquete com.android.networkstack.inprocess
debe estar en la lista de entidades permitidas porque 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 sistema del usuario depende de este proveedor
Busca paquetes incluidos en la lista de entidades permitidas del nivel 1 y verifica de qué proveedores
dependen. Si una app que se ejecuta en el usuario del sistema (por ejemplo,
com.android.car.companiondevicesupport
está incluida en la lista de entidades permitidas para ejecutarse en el
usuario del sistema) y depende de este proveedor de contenido, asegúrate de que este también
esté incluido en la lista de entidades permitidas.
- Si la respuesta es Sí, incluye en la lista de entidades permitidas.
- Si la respuesta es No, no la incluyas en la lista de entidades permitidas.
Por ejemplo, si com.android.car.EXAMPLE
contiene proveedores singleton (SystemActionsContentProvider
y ManagedProvisioningActionsContentProvider
), debería estar incluido en la lista de entidades permitidas del usuario del sistema. Luego, si com.android.car.EXAMPLE
depende de android.webkit
para WebViewFactoryProvider
, com.android.webview
debe estar en la lista de entidades permitidas para el usuario del sistema, ya 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>