Eliminación de paquetes para el usuario del sistema

Este artículo describe cómo mejorar el rendimiento identificando y eliminando paquetes que no son necesarios para el usuario del SISTEMA.

Deshabilitar paquetes innecesarios

En Automoción, el Usuario del SISTEMA no tiene cabeza , lo que significa que el Usuario del SISTEMA no está destinado a ser utilizado o acceder directamente por un ser humano. Como resultado, muchas aplicaciones y servicios no necesitan ejecutarse en el usuario del SISTEMA y se pueden desactivar para mejorar el rendimiento. Por lo tanto, se proporciona una opción para eliminar aplicaciones innecesarias para el usuario del SISTEMA (Usuario 0).

En este artículo, se discuten dos tipos de Usuarios:

  • SISTEMA . Siempre Usuario 0
  • COMPLETO . Usuario que está destinado a ser utilizado por un ser humano (un usuario que no es del SISTEMA), Usuario 10+

androide 11

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

  0  - disable whitelist (install all system packages; no logging)
  1  - enforce (only install system packages if they are whitelisted)
  2  - log (log non-whitelisted packages)
  4  - any package not mentioned in the whitelist file is implicitly whitelisted on all users
  8  - same as 4, but just for the SYSTEM user
  16 - ignore OTAs (don't install system packages during OTAs)
  Common scenarios:
  - to enable feature (fully enforced) for a complete allowlist: 1
  - to enable feature for an incomplete allowlist (so use implicit allowlist mode): 5
  - to enable feature but implicitly allowlist for SYSTEM user to ease local development: 9
  - to disable feature completely if it had never been enabled: 16
  - to henceforth disable feature and try to undo its previous effects: 0

Asegúrese de instalar el archivo XML en el directorio sysconfig del dispositivo (este es el mismo directorio que contiene el archivo MAKE (.mk) utilizado para crear la imagen del sistema para el dispositivo). Cuando asigne 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 característica en Android 9 y Android 10:

  1. Superponga la configuración config_systemUserPackagesBlacklistSupported de frameworks/base/core/res/res/values/config.xml y configúrela en true . Cuando la función está activada, de forma predeterminada, todos los paquetes deben instalarse tanto para el usuario del SISTEMA como para el usuario COMPLETO.
  2. Cree un archivo config.xml que enumere qué paquetes deben deshabilitarse 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. Agregue una línea a device.mk para copiar el archivo en la carpeta de destino del dispositivo system/etc/sysconfig/ . Por ejemplo:
    PRODUCT_COPY_FILES += <full path to the config file>:system/etc/sysconfig/<new denylist config file>.xml
    

Verificar el resultado

Para verificar el resultado, ejecute:

$ 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

Premisa

Para determinar si se debe instalar un paquete en el usuario del SISTEMA, examine el archivo 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 aplicación, que incluyen todas las actividades, servicios, receptores de transmisión, y proveedores de contenido. Para obtener más información, consulte Descripción general del manifiesto de la aplicación .

Deshabilitar flujo de trabajo de paquetes

Figura 1. Flujo de trabajo para deshabilitar paquetes

Nivel 1, Nivel de aplicación

1. Compruebe si la aplicación (o los componentes de la aplicación) se declaran como singleton

Si la aplicación es un singleton , el sistema instanciará la aplicación solo en el usuario del SISTEMA. Es probable que la aplicación estuviera destinada a ser una aplicación multiusuario. Para obtener más información acerca de las aplicaciones para múltiples usuarios, consulte Creación de aplicaciones para múltiples usuarios.

  1. Verifique el manifiesto de Android para android:singleUser="true" .
  2. Si es verdadero , lista de permitidos. Necesario para el usuario del SISTEMA.
  3. Si es falso , continuar. Verifique otros criterios antes de eliminar.

2. Compruebe si la aplicación requiere acceso de almacenamiento protegido

Muchos servicios de arranque del sistema a menudo se basan en el almacenamiento cifrado de dispositivo (DE) en lugar del almacenamiento cifrado de credenciales (CE). Además, las aplicaciones del sistema que reconocen el arranque directo también dependen del almacenamiento cifrado del dispositivo. Para obtener más información sobre las aplicaciones compatibles con el inicio directo, consulte Compatibilidad con el inicio directo en las aplicaciones del sistema .

  1. Verifique el manifiesto de Android para android:defaultToDeviceProtectedStorage="true" , ​​que es necesario para numerosos servicios de arranque del sistema.
  2. Si es verdadero , lista de permitidos.
  3. Si es falso , continuar.

Nivel 2, Componentes de la aplicación

Actividades

Para obtener más información sobre las actividades, consulte Introducción a las actividades .

una. Compruebe si la aplicación solo contiene actividades

Las actividades están orientadas a la interfaz de usuario. Dado que el Usuario del SISTEMA no tiene cabeza en Automoción, ningún ser humano debe interactuar con el Usuario del SISTEMA. Como resultado, si la aplicación solo contiene actividades, lo más probable es que la aplicación no sea relevante para el usuario del SISTEMA.

Consulte por prioridad y privilegio especial.

  1. En caso afirmativo , quizás sea necesario para el usuario del SISTEMA.
  2. Si la respuesta es No , no incluir en la lista blanca al usuario del SISTEMA.

Por ejemplo, Compatibility Test Suite (CTS) ( com.android.cts.priv.ctsshim ) contiene solo actividades, y las actividades se definen para probar los filtros de intenciones. Sin embargo, dado que tiene un alto privilegio, debe instalarse para el usuario del SISTEMA con fines de prueba.

Servicio

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

b. Compruebe si el servicio está declarado como privado y no se puede acceder desde otras aplicaciones

Si el servicio se declara como privado , otros paquetes no utilizarán el servicio. Busque android:exported="false" . Si el servicio se declara como privado o no se puede acceder a él desde otras aplicaciones, entonces no puede ser vinculado por otras aplicaciones. Por lo tanto, el Paso C y el Paso D a continuación son irrelevantes. Como resultado, este componente no proporcionaría más pistas sobre si el usuario del SISTEMA necesita o no el servicio.

  1. En caso afirmativo , marque el siguiente componente.
  2. Si la respuesta es No , continúe revisando este componente.

C. Compruebe si las aplicaciones instaladas en el usuario del SISTEMA pueden vincularse a este servicio

Verifique los paquetes incluidos en la lista de permitidos en el Nivel 1 e identifique los servicios a los que están vinculados. Rastree desde el filtro de intención en este servicio y startService en otros paquetes.

Si este servicio está vinculado a las aplicaciones instaladas en el usuario del SISTEMA (por ejemplo, com.android.car.companiondevicesupport está en la lista de permitidos para ejecutarse en el usuario del SISTEMA), entonces incluya el servicio en la lista de permitidos.

  1. En caso afirmativo , lista de permitidos.
  2. Si la respuesta es No , continúe revisando este componente.

d. Verifique si el servicio está vinculado desde otras aplicaciones y declarado para ejecutarse en primer plano

Busque startForeground . Esto significa que las personas estarían interactuando con la aplicación en primer plano. Lo más probable es que este servicio no sea necesario para el usuario del SISTEMA y no es necesario incluirlo en la lista de permitidos.

  1. En caso afirmativo , no incluir en la lista de permitidos.
  2. Si la respuesta es No , continúe revisando el siguiente componente.

mi. Compruebe si el servicio está definido para ejecutarse en el proceso del sistema

En AndroidManifest, busque android:process="system" .
Si el servicio se define intencionalmente para ejecutarse en el proceso del sistema, significa que se ejecutará explícitamente en el mismo proceso que el servicio del sistema y debe incluirse en la lista de permitidos para ejecutarse 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 en eliminarse, lo que implica la criticidad de los servicios definidos con dicho atributo. Para obtener más información sobre el diseño de asignación de memoria de Android, consulteLow-memory killer .

  1. En caso afirmativo , no incluir en la lista de permitidos.
  2. Si la respuesta es No , continúe revisando otros componentes.

Por ejemplo, el paquete com.android.networkstack.inprocess debe incluirse en la lista de permitidos, 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, consulte Proveedores de contenido.

F. Compruebe si la aplicación instalada en el usuario del SISTEMA depende de este proveedor

Verifique los paquetes incluidos en la lista de permitidos en el Nivel 1 y verifique de qué proveedores dependen. Si una aplicación que se ejecuta en el usuario del SISTEMA (por ejemplo, com.android.car.companiondevicesupport está en la lista de permitidos para ejecutarse en el usuario del SISTEMA) y depende de este proveedor de contenido, asegúrese de que este proveedor de contenido también esté en la lista de permitidos.

  1. En caso afirmativo , lista de permitidos.
  2. Si no , no incluir en la lista de permitidos.

Por ejemplo, si com.android.car.EXAMPLE contiene proveedores únicos ( SystemActionsContentProvider y ManagedProvisioningActionsContentProvider ), debe incluirse en la lista de permitidos para el usuario del SISTEMA. Luego, si com.android.car.EXAMPLE depende de android.webkit para WebViewFactoryProvider , com.android.webview debe estar en la lista de permitidos para el usuario del SISTEMA dado que carga el android.webkit .

Tutorial del paquete de muestra

El siguiente ejemplo muestra cómo evaluar 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>