Agregar propiedades del sistema

Esta página proporciona un método canónico para agregar o definir propiedades del sistema en Android, con pautas para refactorizar las propiedades del sistema existente. Asegúrese de usar las pautas cuando refactorice, a menos que tenga un problema de compatibilidad fuerte que indique lo contrario.

Fondo

Las propiedades del sistema se usan para varios propósitos porque son fáciles de usar. Aunque son similares a las variables globales en los lenguajes de programación, no hay un conjunto de requisitos de proceso formalizados o convenciones de nomenclatura que deba seguir al crearlos. Por lo tanto, las propiedades del sistema pueden ser difíciles de entender y mantener. Los pasos de esta página definen las propiedades del sistema y proporcionan pasos para agregarlas y mantenerlas.

Preparación: considerar alternativas

Determine si una propiedad del sistema es realmente lo que desea y si es su única opción. Las propiedades del sistema son recursos de todo el sistema que proporcionan ciertas ventajas. Son fáciles de usar y sus propiedades no dinámicas tienen una sobrecarga de rendimiento relativamente baja. Al usar las propiedades del sistema, no necesita usar la comunicación entre procesos (IPC), incluso si una propiedad del sistema se comparte entre varios procesos. Sin embargo, también pueden ser dañinos cuando se usan incorrectamente, de forma similar a las variables globales. El uso indebido de las propiedades del sistema ha dado lugar a que los usuarios no puedan acceder a las aplicaciones y se introduzcan vulnerabilidades de seguridad.

Considere las muchas alternativas a las propiedades del sistema que se presentan a continuación, para evaluar si alguna de ellas puede brindarle la solución que necesita.

Preferencias compartidas

Para una configuración persistente que sea local para una aplicación, use la interfaz de Shared Preferences , en lugar de las propiedades del sistema.

HAL

Cuando la fuente de la verdad para una configuración proviene de un componente de hardware en un dispositivo, la HAL debe proporcionar la información para ese componente. No configure HAL para escribir una propiedad del sistema para permitir que otros procesos la lean (o viceversa). En su lugar, defina un nuevo método HAL para acceder a la configuración. En otras palabras, no use las propiedades del sistema como un mecanismo de comunicación de canal lateral para las HAL.

Tenga en cuenta que no necesita una HAL nueva para este caso de uso, ya que es una opción costosa. Use esta sugerencia solo cuando tenga una HAL existente para abstraer el componente de hardware.

Archivo de configuración

Cuando los datos de configuración son estáticos pero complicados (en otras palabras, estructurados), considere usar XML u otros formatos similares para los datos de configuración. Asegúrese de que el esquema del archivo permanezca estable. Para los archivos XML, puede usar xsd_config para mantener estable el esquema y aprovechar un analizador XML generado automáticamente.

Servicio de encuadernación

Las propiedades del sistema se utilizan a menudo para compartir el estado dinámico de un subsistema con múltiples procesos. Dichos estados se pueden implementar dentro de un servicio de enlace (como un campo de objeto) y otros procesos pueden leer (o incluso modificar) el estado, utilizando llamadas de enlace al servicio. Esta es la solución preferida, ya que convertir el estado en una propiedad del sistema y otorgarle acceso directo requiere un proceso similar a este:

  1. Realice una comprobación de cordura en el estado.
  2. Realice un procesamiento posterior en el estado para que sea consumible.
  3. Realice una función de control de acceso detallada.
  4. Mantener el estado estructurado.

Completar este proceso con éxito es imposible o, en el mejor de los casos, muy difícil cuando se implementa un estado como propiedad del sistema. Por lo tanto, use la opción del servicio de enlace cuando los lectores del estado ya tengan acceso al servicio de enlace.

Paso 1: Definición de la propiedad del sistema

Cuando agrega una propiedad del sistema, decida un nombre para la propiedad y asóciela con un contexto de propiedad de SELinux. Si no hay un contexto existente apropiado, cree uno nuevo. El nombre se utiliza al acceder a la propiedad; el contexto de propiedad se utiliza para controlar la accesibilidad en términos de SELinux. Los nombres pueden ser cualquier cadena, pero AOSP recomienda que siga un formato estructurado para que queden claros.

Nombre de la propiedad

Use este formato con la carcasa snake_case:

[{prefix}.]{group}[.{subgroup}]*.{name}[.{type}]

Use "" (omitido), ro (para propiedades configuradas solo una vez) o persist (para propiedades que persisten entre reinicios) para el prefix del elemento.

Advertencias

Use ro solo cuando esté seguro de que no necesita un prefix para poder escribir en el futuro. ** No especifique el prefijo ro . ** En su lugar, confíe en sepolicy para hacer que el prefix sea de solo lectura (en otras palabras, solo se puede escribir con init ).

Use persist solo cuando esté seguro de que el valor debe persistir entre reinicios y que usar las propiedades del sistema es su única opción. (Para obtener más información, consulte la sección Preparación ).

Google revisa estrictamente las propiedades del sistema que tienen propiedades ro o persist .

El término group se utiliza para agregar propiedades relacionadas. Está destinado a ser un nombre de subsistema similar en uso a audio o telephony . No utilice términos ambiguos o sobrecargados como sys , system , dev , default o config .

Es una práctica común usar el nombre del tipo de dominio de un proceso que tiene acceso exclusivo de lectura o escritura a las propiedades del sistema. Por ejemplo, para las propiedades del sistema a las que el proceso vold tiene acceso de escritura, es común usar vold (el nombre del tipo de dominio para el proceso) como nombre de grupo.

Si es necesario, agregue un subgroup para categorizar aún más las propiedades, pero evite términos ambiguos o sobrecargados para describir este elemento. (También puede tener más de un subgroup ).

Ya se han definido muchos nombres de grupos. Verifique el system/sepolicy/private/property_contexts y use nombres de grupos existentes donde sea posible, en lugar de crear otros nuevos. La siguiente tabla proporciona ejemplos de nombres de grupos utilizados con frecuencia.

Dominio Grupo (y subgrupo)
relacionados con bluetooth bluetooth
sysprops de kernel cmdline boot
sysprops que identifican una compilación build
relacionado con la telefonía telephony
relacionado con audio audio
gráficos relacionados graphics
relacionados con vold vold

A continuación se define el uso de name y type en el ejemplo de expresión regular anterior.

[{prefix}.]{group}[.{subgroup}]*.{name}[.{type}]

  • name identifica una propiedad del sistema dentro de un grupo.

  • type es un elemento opcional que aclara el tipo o la intención de la propiedad del sistema. Por ejemplo, en lugar de nombrar un sysprop como audio.awesome_feature_enabled o simplemente audio.awesome_feature , renómbrelo como audio.awesome_feature.enabled para reflejar el tipo de propiedad del sistema y la intención.

No hay una regla específica sobre cuál debe ser el tipo; estas son recomendaciones de uso:

  • enabled : se usa si el tipo es una propiedad booleana del sistema que se usa para activar o desactivar una función.
  • config : use si la intención es aclarar que la propiedad del sistema no representa un estado dinámico del sistema; representa un valor preconfigurado (por ejemplo, algo de solo lectura).
  • List : use si es una propiedad del sistema cuyo valor es una lista.
  • Timeoutmillis : use si es una propiedad del sistema para un valor de tiempo de espera en unidades de ms.

Ejemplos:

  • persist.radio.multisim.config
  • drm.service.enabled

Contexto de propiedad

El nuevo esquema de contexto de propiedades de SELinux permite una granularidad más fina y nombres más descriptivos. Similar a lo que se usa para los nombres de propiedad, AOSP recomienda el siguiente formato:

{group}[_{subgroup}]*_prop

Los términos se definen de la siguiente manera:

group y subgroup tienen el mismo significado definido para la expresión regular de ejemplo anterior. Por ejemplo, vold_config_prop significa propiedades que son configuraciones de un proveedor y deben ser establecidas por vendor_init , mientras que vold_status_prop o simplemente vold_prop significa propiedades que exponen el estado actual de vold .

Al nombrar un contexto de propiedad, elija nombres que reflejen el uso general de las propiedades. En particular, evite los siguientes tipos de términos:

  • Términos que parecen demasiado generales y ambiguos, como sys , system , default .
  • Términos que codifican directamente la accesibilidad: como exported , apponly , ro , public , private .

Prefiere usos de nombres como vold_config_prop a exported_vold_prop o vold_vendor_writable_prop , etc.

Escribe

Un tipo de propiedad puede ser uno de los siguientes, como se indica en la tabla.

Escribe Definición
booleano true o 1 para verdadero, false o 0 para falso
Entero entero de 64 bits con signo
Entero sin signo entero de 64 bits sin signo
Doble punto flotante de precisión doble
Cuerda cualquier cadena UTF-8 válida
enumeración los valores pueden ser cualquier cadena UTF-8 válida sin espacios en blanco
Lista de arriba Se utiliza una coma ( , ) como delimitador
La lista de enteros [1, 2, 3] se almacena como 1,2,3

Internamente, todas las propiedades se almacenan como cadenas. Puede aplicar el tipo especificándolo como un archivo property_contexts . Para obtener más información, consulte property_contexts en el paso 3 .

Paso 2: Determinación de los niveles de accesibilidad requeridos

Hay cuatro macros auxiliares que definen una propiedad.

Tipo de accesibilidad Sentido
system_internal_prop Propiedades que se usan solo en /system
system_restricted_prop Propiedades que se leen fuera de /system , pero no se escriben
system_vendor_config_prop Propiedades que se leen fuera de /system y escritas solo por vendor_init
system_public_prop Propiedades que se leen y escriben fuera de /system

Alcance el acceso a las propiedades del sistema lo más limitado posible. En el pasado, el acceso amplio ha dado lugar a roturas de aplicaciones y vulnerabilidades de seguridad. Tenga en cuenta las siguientes preguntas al determinar el alcance:

  • ¿Es necesario conservar esta propiedad del sistema? (si es así, ¿por qué?)
  • ¿Qué proceso debería tener acceso de lectura a esta propiedad?
  • ¿Qué proceso debería tener acceso de escritura a esta propiedad?

Utilice las preguntas anteriores y el siguiente árbol de decisiones como herramientas para determinar un ámbito de acceso adecuado.

Decision tree for determining the scope of access

Figura 1. Árbol de decisión para determinar el alcance del acceso a las propiedades del sistema

Paso 3: Agregarlo al sistema/sepolicy

Al acceder a sysprop, SELinux controla la accesibilidad de los procesos. Después de determinar qué nivel de accesibilidad se requiere, defina contextos de propiedad en system/sepolicy , junto con reglas adicionales allow y neverallow sobre qué procesos pueden (y no pueden) leer o escribir.

Primero, defina el contexto de la propiedad en el archivo system/sepolicy/public/property.te . Si la propiedad es interna del sistema, defínala en el archivo system/sepolicy/private/property.te . Utilice una de las system_[accessibility]_prop([context]) que proporciona la accesibilidad necesaria para la propiedad de su sistema. Este es un ejemplo para el system/sepolicy/public/property.te :

system_public_prop(audio_foo_prop)
system_vendor_config_prop(audio_bar_prop)

Ejemplo para agregar en el system/sepolicy/private/property.te :

system_internal_prop(audio_baz_prop)

En segundo lugar, conceda acceso de lectura y (o) escritura al contexto de la propiedad. Utilice las macros set_prop y get_prop para otorgar acceso, ya sea en el system/sepolicy/public/{domain}.te o system/sepolicy/private/{domain}.te . Use private siempre que sea posible; public es adecuado solo si la macro set_prop o get_prop afecta a cualquier dominio fuera del dominio principal.

Ejemplo, en el system/sepolicy/private/audio.te :

set_prop(audio, audio_foo_prop)
set_prop(audio, audio_bar_prop)

Ejemplo, en el system/sepolicy/public/domain.te :

get_prop(domain, audio_bar_prop)

En tercer lugar, agregue algunas reglas de nunca permitir para reducir aún más la accesibilidad que abarca la macro. Por ejemplo, suponga que ha utilizado system_restricted_prop porque los procesos del proveedor deben leer las propiedades de su sistema. Si el acceso de lectura no es requerido por todos los procesos del proveedor, y solo lo requiere un determinado conjunto de procesos (como, por ejemplo, vendor_init ), prohíba los procesos del proveedor que no necesitan el acceso de lectura.

Utilice la siguiente sintaxis para restringir el acceso de escritura y lectura:

Para restringir el acceso de escritura:

neverallow [domain] [context]:property_service set;

Para restringir el acceso de lectura:

neverallow [domain] [context]:file no_rw_file_perms;

Coloque las reglas neverallow en el system/sepolicy/private/{domain}.te si la regla neverallow está vinculada a un dominio específico. Para reglas nunca permitidas más amplias, use dominios generales como estos cuando sea apropiado:

  • system/sepolicy/private/property.te
  • system/sepolicy/private/coredomain.te
  • system/sepolicy/private/domain.te

En el system/sepolicy/private/audio.te coloca lo siguiente:

neverallow {
    domain -init -audio
} {audio_foo_prop audio_bar_prop}:property_service set;

En el system/sepolicy/private/property.te , coloque lo siguiente:

neverallow {
    domain -coredomain -vendor_init
} audio_prop:file no_rw_file_perms;

Tenga en cuenta que {domain -coredomain} captura todos los procesos del proveedor. Por lo tanto {domain -coredomain -vendor_init} significa "todos los procesos de proveedores excepto vendor_init ".

Finalmente, asocie una propiedad del sistema con el contexto de la propiedad. Esto garantiza que el acceso otorgado y las reglas de nunca permitir que se aplican a los contextos de propiedad se aplican a las propiedades reales. Para hacer esto, agregue una entrada al archivo property_contexts , un archivo que describe la asignación entre las propiedades del sistema y los contextos de propiedad. En este archivo, puede especificar una sola propiedad o un prefijo para que las propiedades se asignen a un contexto.

Esta es la sintaxis para mapear una sola propiedad:

[property_name] u:object_r:[context_name]:s0 exact [type]

Esta es la sintaxis para mapear un prefijo:

[property_name_prefix] u:object_r:[context_name]:s0 prefix [type]

Opcionalmente, puede especificar el tipo de propiedad, que puede ser uno de los siguientes:

  • bool
  • int
  • uint
  • double
  • enum [list of possible values...]
  • string (Usar string para las propiedades de la lista).

Asegúrese de que cada entrada tenga su tipo designado siempre que sea posible, ya que el type se aplica al establecer la property . El siguiente ejemplo muestra cómo escribir una asignación:

# binds a boolean property "ro.audio.status.enabled"
# to the context "audio_foo_prop"
ro.audio.status.enabled u:object_r:audio_foo_prop:s0 exact bool

# binds a boolean property "vold.decrypt.status"
# to the context "vold_foo_prop"
# The property can only be set to one of these: on, off, unknown
vold.decrypt.status u:object_r:vold_foo_prop:s0 exact enum on off unknown

# binds any properties starting with "ro.audio.status."
# to the context "audio_bar_prop", such as
# "ro.audio.status.foo", or "ro.audio.status.bar.baz", and so on.
ro.audio.status. u:object_r:audio_bar_prop:s0 prefix

Cuando una entrada exacta y una entrada de prefijo entran en conflicto, la entrada exacta tiene prioridad. Para obtener más ejemplos, consulte system/sepolicy/private/property_contexts .

Paso 4: Determinación de los requisitos de estabilidad

La estabilidad es otro aspecto de las propiedades del sistema y difiere de la accesibilidad. La estabilidad se trata de si una propiedad del sistema se puede cambiar o no (por ejemplo, renombrada o incluso eliminada) en el futuro. Esto es particularmente importante ya que el sistema operativo Android se vuelve modular. Con Treble, las particiones de sistema, proveedor y producto se pueden actualizar de forma independiente. Con Mainline, algunas partes del sistema operativo se modularizan como módulos actualizables (en APEX o APK).

Si una propiedad del sistema se usa en piezas de software actualizables, por ejemplo, en particiones del sistema y del proveedor, debe ser estable. Sin embargo, si se usa solo dentro, por ejemplo, de un módulo principal específico, puede cambiar su nombre, tipo o contexto de propiedad e incluso eliminarlo.

Haga las siguientes preguntas para determinar la estabilidad de una propiedad del sistema:

  • ¿Esta propiedad del sistema está destinada a ser configurada por socios (o configurada de manera diferente por dispositivo)? Si es así, debe ser estable.
  • ¿Esta propiedad del sistema definida por AOSP está destinada a escribirse o leerse desde el código (no el proceso) que existe en particiones que no son del sistema, como vendor.img o product.img ? Si es así, debe ser estable.
  • ¿Se accede a esta propiedad del sistema a través de los módulos de Mainline o a través de un módulo de Mainline y la parte no actualizable de la plataforma? Si es así, debe ser estable.

Para las propiedades estables del sistema, defina formalmente cada una como una API y use la API para acceder a la propiedad del sistema, como se explica en el paso 6 .

Paso 5: Configuración de propiedades en el momento de la compilación

Establezca propiedades en el momento de la compilación con variables de archivos MAKE. Técnicamente, los valores se hornean en {partition}/build.prop . Luego, init lee {partition}/build.prop para establecer las propiedades. Hay dos conjuntos de tales variables: PRODUCT_{PARTITION}_PROPERTIES y TARGET_{PARTITION}_PROP .

PRODUCT_{PARTITION}_PROPERTIES contiene una lista de valores de propiedad. La sintaxis es {prop}={value} o {prop}?={value} .

{prop}={value} es una asignación normal que asegura que {prop} se establece en {value} ; solo una asignación de este tipo es posible por una sola propiedad.

{prop}?={value} es una asignación opcional; {prop} se establece en {value} solo si no hay asignaciones {prop}={value} . Si existen múltiples asignaciones opcionales, la primera gana.

# sets persist.traced.enable to 1 with system/build.prop
PRODUCT_SYSTEM_PROPERTIES += persist.traced.enable=1

# sets ro.zygote to zygote32 with system/build.prop
# but only when there are no other assignments to ro.zygote
# optional are useful when giving a default value to a property
PRODUCT_SYSTEM_PROPERTIES += ro.zygote?=zygote32

# sets ro.config.low_ram to true with vendor/build.prop
PRODUCT_VENDOR_PROPERTIES += ro.config.low_ram=true

TARGET_{PARTITION}_PROP contiene una lista de archivos, que se emite directamente a {partition}/build.prop . Cada archivo contiene una lista de pares {prop}={value} .

# example.prop

ro.cp_system_other_odex=0
ro.adb.secure=0
ro.control_privapp_permissions=disable

# emits example.prop to system/build.prop
TARGET_SYSTEM_PROP += example.prop

Para obtener más detalles, consulte build/make/core/sysprop.mk .

Paso 6: acceder a las propiedades en tiempo de ejecución

Por supuesto, las propiedades se pueden leer y escribir en tiempo de ejecución.

guiones de inicio

Los archivos de script de inicio (generalmente archivos *.rc) pueden leer una propiedad por ${prop} o ${prop:-default} , pueden establecer una acción que se ejecuta cada vez que una propiedad se convierte en un valor específico y pueden escribir las propiedades usando setprop dominio.

# when persist.device_config.global_settings.sys_traced becomes 1,
# set persist.traced.enable to 1
on property:persist.device_config.global_settings.sys_traced=1
    setprop persist.traced.enable 1

# when security.perf_harden becomes 0,
# write /proc/sys/kernel/sample_rate to the value of
# debug.sample_rate. If it's empty, write -100000 instead
on property:security.perf_harden=0
    write /proc/sys/kernel/sample_rate ${debug.sample_rate:-100000}

Comandos de shell getprop y setprop

Puede utilizar los comandos de shell getprop o setprop , respectivamente, para leer o escribir las propiedades. Para obtener más detalles, invoque getprop --help o setprop --help .

$ adb shell getprop ro.vndk.version
$
$ adb shell setprop security.perf_harden 0

Sysprop como API para C++/Java

Con sysprop como API, puede definir las propiedades del sistema y usar API generadas automáticamente que son concretas y escritas. Establecer el scope con Public también hace que las API generadas estén disponibles para los módulos a través de los límites y garantiza la estabilidad de la API. Aquí hay una muestra de un archivo .sysprop , un módulo Android.bp y código C++ y Java que los usa.

# AudioProps.sysprop
# module becomes static class (Java) / namespace (C++) for serving API
module: "android.sysprop.AudioProps"
# owner can be Platform or Vendor or Odm
owner: Platform
# one prop defines one property
prop {
    prop_name: "ro.audio.volume.level"
    type: Integer
    scope: Public
    access: ReadWrite
    api_name: "volume_level"
}
…

// Android.bp
sysprop_library {
    name: "AudioProps",
    srcs: ["android/sysprop/AudioProps.sysprop"],
    property_owner: "Platform",
}

// Both java and cc module can link against sysprop_library
java_library {
    static_libs: ["AudioProps"],
    …
}

cc_binary {
    static_libs: ["AudioProps"],
    …
}

// Java codes accessing generated API
// get volume. use 50 as the default value.
int vol = android.sysprop.AudioProps.volume_level().orElse(50);
// add 10 to the volume level.
android.sysprop.AudioProps.volume_level(vol + 10);

// C++ codes accessing generated API
// get volume. use 50 as the default value.
int vol = android::sysprop::AudioProps::volume_level().value_or(50);
// add 10 to the volume level.
android::sysprop::AudioProps::volume_level(vol + 10);

Para obtener más información, consulte Implementación de propiedades del sistema como API .

Funciones y métodos de propiedad de bajo nivel de C/C++ y Java

Utilice Sysprop como API, aunque las funciones C/C++ de bajo nivel o los métodos Java de bajo nivel estén disponibles para usted. Prefiere el uso de Sysprop sobre ellos siempre que puedas.

libc , libbase y libcutils ofrecen funciones de propiedad del sistema C++. libc tiene la API subyacente, mientras que las funciones libbase y libcutils son contenedores. Si es posible, use las funciones de libbase libbase; son los más convenientes y los binarios del host pueden usar las funciones de libbase . Para obtener más detalles, consulte sys/system_properties.h ( libc ), android-base/properties.h ( libbase ) y cutils/properties.h ( libcutils ).

La clase android.os.SystemProperties ofrece métodos de propiedad del sistema Java.

Apéndice: Adición de propiedades específicas del proveedor

Los socios (incluidos los Googlers que trabajan en el contexto del desarrollo de Pixel) desean definir las propiedades del sistema específicas del hardware (o del dispositivo). Las propiedades específicas del proveedor son propiedades de socios que son exclusivas de su propio hardware o dispositivo, no de la plataforma. Como estos dependen del hardware o del dispositivo, están destinados a usarse dentro de las particiones /vendor o /odm .

Desde Project Treble, las propiedades de la plataforma y las propiedades del proveedor se han dividido por completo para evitar que entren en conflicto. A continuación, se describe cómo definir las propiedades del proveedor y se indica qué propiedades del proveedor se deben usar siempre.

Espacio de nombres en nombres de propiedad y contexto

Todas las propiedades de los proveedores deben comenzar con uno de los siguientes prefijos para evitar la colisión entre ellas y las propiedades de otras particiones.

  • ctl.odm.
  • ctl.vendor.
  • ctl.start$odm.
  • ctl.start$vendor.
  • ctl.stop$odm.
  • ctl.stop$vendor.
  • init.svc.odm.
  • init.svc.vendor.
  • ro.odm.
  • ro.vendor.
  • odm.
  • persist.odm.
  • persist.vendor.
  • vendor.

Tenga en cuenta que ro.hardware. está permitido como prefijo, pero solo por compatibilidad. No lo use para propiedades normales.

Todos los siguientes ejemplos usan uno de los prefijos enumerados anteriormente:

  • vendor.display.primary_red
  • persist.vendor.faceauth.use_disk_cache
  • ro.odm.hardware.platform

Todos los contextos de propiedad de proveedor deben comenzar con vendor_ . Esto también es por compatibilidad. Los siguientes son ejemplos:

  • vendor_radio_prop .
  • vendor_faceauth_prop .
  • vendor_usb_prop .

Es responsabilidad del proveedor nombrar y mantener las propiedades, así que siga el formato sugerido en el Paso 2 , además de los requisitos de los espacios de nombres del proveedor.

Reglas de SEPolicy específicas del proveedor y property_contexts

Al igual que las propiedades de la plataforma, las propiedades del proveedor se pueden definir mediante una de las siguientes macros.

Tipo de accesibilidad Sentido
vendor_internal_prop Propiedades que se usan solo en /vendor
vendor_restricted_prop Propiedades que se leen fuera de /vendor , pero no se escriben
vendor_public_prop Propiedades que se leen y escriben fuera de /vendor

Coloque las reglas específicas del proveedor que defina en el directorio BOARD_VENDOR_SEPOLICY_DIRS . Por ejemplo, suponga que está definiendo una propiedad faceauth de proveedor en coral.

En el archivo BoardConfig.mk (o en cualquier BoardConfig.mk incluidos), coloque lo siguiente:

BOARD_VENDOR_SEPOLICY_DIRS := device/google/coral-sepolicy

En el archivo device/google/coral-sepolicy/private/property.te , pon lo siguiente:

vendor_internal_prop(vendor_faceauth_prop)

En el archivo device/google/coral-sepolicy/private/property_contexts , coloca lo siguiente:

vendor.faceauth.trace u:object_r:vendor_faceauth_prop:s0 exact bool

Limitaciones de las propiedades del proveedor

Debido a que las particiones del sistema y del producto no pueden depender del proveedor, nunca permita que se acceda a las propiedades del proveedor desde las particiones system , system-ext o product .

Apéndice: Cambio de nombre de propiedades existentes

Cuando deba desaprobar una propiedad y pasar a una nueva, use Sysprop como API para cambiar el nombre de sus propiedades existentes. Esto mantiene la compatibilidad con versiones anteriores al especificar tanto el nombre heredado como el nuevo nombre de propiedad. Específicamente, puede establecer el nombre heredado por el campo legacy_prop_name en el archivo .sysprop . La API generada intenta leer prop_name y usa legacy_prop_name si prop_name no existe.

Por ejemplo, los siguientes pasos cambian el nombre de awesome_feature_foo_enabled a foo.awesome_feature.enabled .

En el archivo foo.sysprop (en Java)

module: "android.sysprop.foo"
owner: Platform
prop {
    api_name: "is_awesome_feature_enabled"
    type: Boolean
    scope: Public
    access: Readonly
    prop_name: "foo.awesome_feature.enabled"
    legacy_prop_name: "awesome_feature_foo_enabled"
}

En código C++

// is_awesome_feature_enabled() reads "foo.awesome_feature.enabled".
// If it doesn't exist, reads "awesome_feature_foo_enabled" instead
using android::sysprop::foo;

bool enabled = foo::is_awesome_feature_enabled().value_or(false);

Tenga en cuenta las siguientes advertencias:

  • Primero, no puede cambiar el tipo de sysprop. Por ejemplo, no puede convertir una propiedad int en una propiedad de string . Solo puedes cambiar el nombre.

  • En segundo lugar, solo la API de lectura recurre al nombre heredado. La API de escritura no retrocede. Si el sysprop es grabable, no puede cambiarle el nombre.