Archive for the ‘system property’ Category

android: persist system property and factory reset

December 5, 2016

This post discusses persist system property and factory reset.

persist system property and data partition
android: persist system properties shows that after set persist system properties are saved in /data/property which is in data partition.

factory reset and data partition
android: methods to trigger factory reset shows that factory reset will format data partition.

persist system properties are not persist after factory reset
Since data partition are formatted during factory reset, factory reset will erase all persist property values saved in /data/properties. But as android: how system properties are loaded at boot time shows, it will not change the default persist property value loaded from system partition.

is it possible to keep persist data value after factory reset
The answer is negative.

In special cases, if we can root the device and have the boot.img, then hacking init.*.rc as blow code snippet could achieve this since the property is also saved in system partition. The post android: bootimg: modify ramdisk in boot.img demonstrates how to modify ramdisk in boot.img.

on property:persist.foo=1
   exec /system/bin/mount -o remount,rw /system
   # Assume /vendor is a symbolic link to /system/vendor
   write /vendor/build.prop "persist.foo=1"
   exec /system/bin/mount -o remount,ro /system

on property:persist.foo=0
   exec /system/bin/mount -o remount,rw /system
   rm /vendor/build.prop
   exec /system/bin/mount -o remount,ro /system

conclusion
The post discuss sustainability of persist system properties after factory reset.

android: persist system properties

December 5, 2016

This post discusses persist system properties.

testing environment
[ro.build.version.release]: [5.1]

what is persist system property
A persist system property is a system property with prefix “persist.”, such as below three items.

$ adb shell getprop
[persist.sys.sd.defaultpath]: [/storage/sdcard0]
[persist.sys.timezone]: [Asia/Calcutta]
[persist.sys.usb.config]: [mass_storage,adb]

where is a persist system property stored
All system property are stored at tmpfs /dev/__properties__ whose backend is memory. Thus, persist system properties are also stored at memory, too.

why is a persist system property persistent

  • Anyhow if a persist system property is set, init process will also create a /data/property/persist.foo accordingly.
  • According to android: how system properties are loaded at boot time, properties in /data/property/ will be loaded at boot time. Thus, persist properties are persistent.
  • $ adb shell setprop persist.foo 1
    $ adb shell cat /data/property/persist.foo
    1
    

    if a persist property is from /system/build.prop
    init process will load it into memory, /dev/__properties. But init process will not create a corresponding file within /data/property/.

    if a persist property from /system/build.prop is set

    • As above the property loaded from /system/build.prop is stored in memory but not saved in /data/property/ at boot time
    • If this persist property is set, no matter its value is updated or not, this property is saved in /data/property/.
    • After reboot, init process loads this property from /system/build.prop into /dev/__properties.
    • Then, init process loads the same persist property from files in /data/property/ and override the value of this property in /dev/__properties.

    conclusion
    A persist property could be loaded from /default.prop, /system/build.prop, …, and files under /data/property. But loading of persist properties only applies to /dev/__properties__ which is memory. Only setting persist property could create a file under /data/property/. Since property files under /data/property are loaded at last. Thus, its value could override the value loaded from other places.

android: how system properties are loaded at boot time

December 5, 2016

In android: read/write system properties, we discuss how to read/write system properties. This post further discussing how to system properties are loaded by init process at boot time.

testing environment
[ro.build.version.release]: [5.1]

where are system propertied stored
System properties are stored in tmpfs /dev/__properties__ whose backend is memory.

default system properties after boot
System properties are stored in memory which is released before shutdown. Thus, there are no properties initially in memory after boot. Then, init process loads properties from below files into /dev/__properties__.

#define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"
#define PROP_PATH_SYSTEM_BUILD     "/system/build.prop"
#define PROP_PATH_SYSTEM_DEFAULT   "/system/default.prop"
#define PROP_PATH_VENDOR_BUILD     "/vendor/build.prop"
#define PROP_PATH_LOCAL_OVERRIDE   "/data/local.prop"
#define PROP_PATH_FACTORY          "/factory/factory.prop"
#define PERSISTENT_PROPERTY_DIR  "/data/property"

how init process loads properties from ramdisk

  • Init process will will load /default.prop at first anyway.
  • These properties are loaded in all boot modes, including recovery mode.
  • /default.prop are determined at compile time.
    INFO("property init\n");
    property_load_boot_defaults();

    INFO("reading config file\n");
    init_parse_config_file("/init.rc");

    action_for_each_trigger("early-init", action_add_queue_tail);

    queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
    queue_builtin_action(keychord_init_action, "keychord_init");
    queue_builtin_action(console_init_action, "console_init");

    /* execute all the boot actions to get us started */
    action_for_each_trigger("init", action_add_queue_tail);
void property_load_boot_defaults(void)
{
    load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT, NULL);
}

how init process loads properties from system partition
In below context, to trigger an action means to add an action to the action queue of init process.

  • init process reads config file such as init.rc or init.project.rc.
  • init process triggers actions, such as early-init, and late-init
  • In late-init action, init process triggers file system related actions, then load_all_props_action action, and then android boot related actions.
  • load_all_props_action action is executed after file system related actions. Thus, system partition has already been mounted.
  • In load_all_props_action action, init process loads properties from /system/build.prop, /system/default.prop, /vendor/build.prop.
  • *.prop files in system partition are determined at compile time.
    INFO("property init\n");
    property_load_boot_defaults();

    INFO("reading config file\n");
    init_parse_config_file("/init.rc");

    action_for_each_trigger("early-init", action_add_queue_tail);

    queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
    queue_builtin_action(keychord_init_action, "keychord_init");
    queue_builtin_action(console_init_action, "console_init");

    /* execute all the boot actions to get us started */
    action_for_each_trigger("init", action_add_queue_tail);
# Mount filesystems and start core system services.
on late-init
    trigger early-fs
    trigger fs
    trigger post-fs
    trigger post-fs-data

    # Load properties from /system/ + /factory after fs mount. Place
    # this in another action so that the load will be scheduled after the prior
    # issued fs triggers have completed.
    trigger load_all_props_action

    # Remove a file to wake up anything waiting for firmware.
    trigger firmware_mounts_complete

    trigger early-boot
    trigger boot
void load_persist_props(void)
{
    load_override_properties();
    /* Read persistent properties after all default values have been loaded. */
    load_persistent_properties();
}

void load_all_props(void)
{
    load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL);
    load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT, NULL);
    load_properties_from_file(PROP_PATH_VENDOR_BUILD, NULL);
    load_properties_from_file(PROP_PATH_FACTORY, "ro.*");

    load_override_properties();

    /* Read persistent properties after all default values have been loaded. */
    load_persistent_properties();
}

how init process loads properties from data partition

  • load_all_props_action action is executed after file system related actions. Thus, data partition has already been mounted.
  • In load_all_props_action action, init process loads properties from /data/local.prop and persist properties in /data/property/
  • /data/local.prop is load when ro.debuggable property are true. Thus, it is only loaded for debug build.
  • /data/local.prop and persist properties in /data/property/ could be updated at runtime
void load_persist_props(void)
{
    load_override_properties();
    /* Read persistent properties after all default values have been loaded. */
    load_persistent_properties();
}

void load_all_props(void)
{
    load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL);
    load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT, NULL);
    load_properties_from_file(PROP_PATH_VENDOR_BUILD, NULL);
    load_properties_from_file(PROP_PATH_FACTORY, "ro.*");

    load_override_properties();

    /* Read persistent properties after all default values have been loaded. */
    load_persistent_properties();
}
static void load_override_properties() {
#ifdef ALLOW_LOCAL_PROP_OVERRIDE
    char debuggable[PROP_VALUE_MAX];
    int ret;

    ret = property_get("ro.debuggable", debuggable);
    if (ret && (strcmp(debuggable, "1") == 0)) {
        load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE, NULL);
    }
#endif /* ALLOW_LOCAL_PROP_OVERRIDE */
}

conclusion
This post discuss how init process loads properties from different places at boot time.

android: read/write system properties

December 5, 2016

This post discusses how to read and write Android system properties.

what is system properties
It’s system wide properties for system and application to know what they are supposed to do.

testing environment

  • android release: 5.1
  • $abb shell getprop
    [ro.build.version.release]: [5.1]
    
  • android studio plugin for gradle: 2.2.2
  • buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:2.2.2'
    
            // NOTE: Do not place your application dependencies here; they belong
            // in the individual module build.gradle files
        }
    }
    

read/write system properties from adb shell

$ adb shell setprop example.property 1
$ adb shell getprop example.property
1

read/write system properties from native code

#define PROP_NAME_MAX   32
#define PROP_VALUE_MAX  92

/* Look up a system property by name, copying its value and a
** \0 terminator to the provided pointer.  The total bytes
** copied will be no greater than PROP_VALUE_MAX.  Returns
** the string length of the value.  A property that is not
** defined is identical to a property with a length 0 value.
*/
int __system_property_get(const char *name, char *value);

/* Set a system property by name.
**/
int __system_property_set(const char *key, const char *value);

read/write system properties from Java application
android.os.SystemProperties provides methods to read and write properties. However it’s not included by default. Thus, we need to add layoutlib.jar into prjoect’s dependencies.

  • add layoutlib.jar in dependencies
  • dependencies {
        compile fileTree(include: ['*.jar'], dir: 'libs')
        androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
            exclude group: 'com.android.support', module: 'support-annotations'
        })
        compile 'com.android.support:appcompat-v7:24.2.1'
        compile 'com.google.code.gson:gson:2.6.2'
        testCompile 'junit:junit:4.12'
        provided files(android.sdkDirectory.path + "/platforms/" + android.compileSdkVersion + "/data/layoutlib.jar")
    }
    
  • import android.os.SystemProperties package
  • import android.os.SystemProperties;
    
  • set property
  • SystemProperties.set(property_name);
    
  • get property
  • SystemProperties.get(property_name, default_val);
    

conclusion
This post discusses how to read and write android system properties in shell, native code, and Java code.