Split VR thermal config into separate file

1) move thermal config into vendor/ partition
2) VR hal will set properties to point to correct thermal-engine config
   and call init to restart thermal-engine with updated config
3) once thermal-engine died, init will restart thermal-engine with current
   active thermal config

Bug: 33275316
Test: on marlin with VR mode on/off
Change-Id: I31c1f573c6bb589b297e8706ad0667c280d7b417
diff --git a/device-common.mk b/device-common.mk
index 5e5a585..31d2fa9 100644
--- a/device-common.mk
+++ b/device-common.mk
@@ -378,7 +378,8 @@
     persist.sys.ssr.restart_level=venus,AR6320,slpi,modem,adsp
 
 PRODUCT_COPY_FILES += \
-    device/google/marlin/thermal-engine-marlin.conf:system/etc/thermal-engine.conf
+    device/google/marlin/thermal-engine-marlin.conf:$(TARGET_COPY_OUT_VENDOR)/etc/thermal-engine.conf \
+    device/google/marlin/thermal-engine-marlin-vr.conf:$(TARGET_COPY_OUT_VENDOR)/etc/thermal-engine-vr.conf
 
 $(call inherit-product-if-exists, hardware/qcom/msm8996/msm8996.mk)
 $(call inherit-product-if-exists, vendor/qcom/gpu/msm8996/msm8996-gpu-vendor.mk)
diff --git a/init.common.rc b/init.common.rc
index 67a02b3..7a8c607 100755
--- a/init.common.rc
+++ b/init.common.rc
@@ -460,7 +460,7 @@
    user root
    group root
 
-service thermal-engine /vendor/bin/thermal-engine
+service thermal-engine /vendor/bin/thermal-engine -c ${sys.qcom.thermalcfg:-/vendor/etc/thermal-engine.conf}
    class main
    user root
    group root system
diff --git a/sepolicy/hal_vr.te b/sepolicy/hal_vr.te
index af826af..f3f0546 100644
--- a/sepolicy/hal_vr.te
+++ b/sepolicy/hal_vr.te
@@ -1,3 +1,2 @@
-# connect to the thermal engine
-allow hal_vr thermal_socket:sock_file write;
-allow hal_vr thermal-engine:unix_stream_socket connectto;
+# interact with thermal_config
+set_prop(hal_vr, thermal_prop)
diff --git a/sepolicy/property.te b/sepolicy/property.te
index 05f8d45..b199635 100644
--- a/sepolicy/property.te
+++ b/sepolicy/property.te
@@ -5,3 +5,4 @@
 type mid_prop, property_type;
 type ssr_prop, property_type;
 type cnss_diag_prop, property_type;
+type thermal_prop, property_type;
diff --git a/sepolicy/property_contexts b/sepolicy/property_contexts
index a6d34e4..435b516 100644
--- a/sepolicy/property_contexts
+++ b/sepolicy/property_contexts
@@ -9,3 +9,5 @@
 ro.boot.mid                u:object_r:mid_prop:s0
 debug.ssrdump              u:object_r:ssr_prop:s0
 persist.sys.cnss.          u:object_r:cnss_diag_prop:s0
+sys.qcom.thermalcfg        u:object_r:thermal_prop:s0
+ctl.thermal-engine         u:object_r:thermal_prop:s0
diff --git a/sepolicy/system_server.te b/sepolicy/system_server.te
index bc4b3a9..0721afd 100644
--- a/sepolicy/system_server.te
+++ b/sepolicy/system_server.te
@@ -39,9 +39,7 @@
 set_prop(system_server, sensors_prop)
 
 # interact with thermal_config
-allow system_server thermal-engine:unix_stream_socket connectto;
-allow system_server thermal_socket:sock_file write;
-
+set_prop(system_server, thermal_prop)
 
 # rpm
 r_dir_file(system_server, debugfs_rpm)
diff --git a/thermal-engine-marlin-vr.conf b/thermal-engine-marlin-vr.conf
new file mode 100755
index 0000000..0b5fec2
--- /dev/null
+++ b/thermal-engine-marlin-vr.conf
@@ -0,0 +1,17 @@
+[SKIN_SHUTDOWN]
+algo_type monitor
+sampling 1000
+sensor emmc_therm
+thresholds           65000
+thresholds_clr       64000
+actions              shutdown
+action_info          1
+
+[VR-EMMC]
+algo_type       monitor
+sensor  emmc_therm
+sampling  1000
+thresholds        58000
+thresholds_clr    52000
+actions   cluster0+cluster1+gpu
+action_info        691200+691200+214000000
diff --git a/thermal-engine-marlin.conf b/thermal-engine-marlin.conf
index bdb6730..6769878 100755
--- a/thermal-engine-marlin.conf
+++ b/thermal-engine-marlin.conf
@@ -56,14 +56,3 @@
 set_point	7000
 set_point_clr	2000
 device_max_limit	400000000
-
-[VR-EMMC]
-algo_type       monitor
-disable 1
-sensor  emmc_therm
-sampling  1000
-thresholds        58000
-thresholds_clr    52000
-actions   cluster0+cluster1+gpu
-action_info        691200+691200+214000000
-
diff --git a/vr/Android.mk b/vr/Android.mk
index 1c033c8..537ffce 100644
--- a/vr/Android.mk
+++ b/vr/Android.mk
@@ -16,7 +16,6 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/../thermal-engine
 LOCAL_SRC_FILES := vr.c
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SHARED_LIBRARIES := liblog libcutils
diff --git a/vr/vr.c b/vr/vr.c
index ef63e69..18d4e53 100644
--- a/vr/vr.c
+++ b/vr/vr.c
@@ -17,344 +17,35 @@
 #define LOG_TAG "VrHALImpl"
 
 #include <cutils/log.h>
-
-#include <dlfcn.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
+#include <cutils/properties.h>
 
 #include <hardware/vr.h>
 #include <hardware/hardware.h>
 
-#include "thermal_client.h"
-
-
-static void *dlhandle;
-static int (*p_thermal_client_config_query)(char *, struct config_instance **);
-static int (*p_thermal_client_config_set)(struct config_instance *, unsigned int);
-static void (*p_thermal_client_config_cleanup)(struct config_instance *, unsigned int);
-
-static int max_string_size = 36;
-static int error_state = 0; //global error state - don't do anything if set!
-
-// List thermal configs in format {name, algo_type}
-// This list is manually synced with the thermal config
-#define NUM_NON_VR_CONFIGS 4
-static char *non_vr_thermal_configs[NUM_NON_VR_CONFIGS][2] =
-    {{"SKIN-HIGH-FLOOR",     "ss"},
-     {"SKIN-MID-FLOOR",      "ss"},
-     {"SKIN-LOW-FLOOR",      "ss"},
-     {"VIRTUAL-SS-GPU-SKIN", "ss"}};
-#define NUM_VR_CONFIGS 1
-static char *vr_thermal_configs[NUM_VR_CONFIGS][2] =
-    {{"VR-EMMC",     "monitor"}};
-
-#define DEBUG 0
-
-/**
- * Debug function for printing out a log instance
- */
-static void log_config_instance(struct config_instance *instance ){
-    ALOGI("logging config_instance 0x%p", instance);
-    ALOGI("config_instance: cfg_desc = %s", instance->cfg_desc);
-    ALOGI("config_instance: algo_type = %s", instance->algo_type);
-    ALOGI("config_instance: fields_mask = 0x%x", instance->fields_mask);
-    ALOGI("config_instance: num_fields = %u", instance->num_fields);
-    for (uint32_t i = 0; i < instance->num_fields; i++) {
-        ALOGI("config_instance: field_data[%d]", i);
-        ALOGI("\tfield_name = %s", instance->fields[i].field_name);
-        ALOGI("\tdata_type = %u", instance->fields[i].data_type);
-        ALOGI("\tnum_data = %u", instance->fields[i].num_data);
-        switch (instance->fields[i].data_type){
-          case FIELD_INT: ALOGI("\tdata = %d", *(int*)(instance->fields[i].data)); break;
-          case FIELD_STR: ALOGI("\tdata = %s", (char*)(instance->fields[i].data)); break;
-          default: ALOGI("\tdata = 0x%p", instance->fields[i].data); break;
-        }
+static void restart_thermal_engine() {
+    if (property_set("ctl.restart", "thermal-engine")) {
+        ALOGE("%s: couldn't set a system property, "
+              "ctl.restart.", __FUNCTION__);
     }
 }
 
-/**
- * Debug function for printing out all instances of "ss" and "monitor" algos
- */
-static void query_thermal_config(){
-    struct config_instance *instances;
-
-    int num_configs = (*p_thermal_client_config_query)("ss", &instances);
-    if (num_configs <= 0) {
-        return;
-    }
-    for (int i = 0; i < num_configs; i++) {
-        log_config_instance(&(instances[i]));
-    }
-    if (num_configs > 0) {
-        (*p_thermal_client_config_cleanup)(instances,num_configs);
-    }
-
-    num_configs = (*p_thermal_client_config_query)("monitor", &instances);
-    if (num_configs <= 0) {
-        return;
-    }
-    for (int i = 0; i < num_configs; i++) {
-        log_config_instance(&(instances[i]));
-    }
-    if (num_configs > 0) {
-        (*p_thermal_client_config_cleanup)(instances,num_configs);
-    }
-}
-
-/**
- * Load the thermal client library
- * returns 0 on success
- */
-static int load_thermal_client(void)
-{
-    char *thermal_client_so = "vendor/lib64/libthermalclient.so";
-
-    dlhandle = dlopen(thermal_client_so, RTLD_NOW | RTLD_LOCAL);
-    if (dlhandle) {
-        dlerror();
-        p_thermal_client_config_query = (int (*) (char *, struct config_instance **))
-            dlsym(dlhandle, "thermal_client_config_query");
-        if (dlerror()) {
-            ALOGE("Unable to load thermal_client_config_query");
-            goto error_handle;
-        }
-
-        p_thermal_client_config_set = (int (*) (struct config_instance *, unsigned int))
-            dlsym(dlhandle, "thermal_client_config_set");
-        if (dlerror()) {
-            ALOGE("Unable to load thermal_client_config_set");
-            goto error_handle;
-        }
-
-        p_thermal_client_config_cleanup = (void (*) (struct config_instance *, unsigned int))
-            dlsym(dlhandle, "thermal_client_config_cleanup");
-        if (dlerror()) {
-            ALOGE("Unable to load thermal_client_config_cleanup");
-            goto error_handle;
-        }
-    } else {
-        ALOGE("unable to open %s", thermal_client_so);
-        return -1;
-    }
-
-    return 0;
-
-error_handle:
-    ALOGE("Error opening functions from %s", thermal_client_so);
-    p_thermal_client_config_query = NULL;
-    p_thermal_client_config_set = NULL;
-    p_thermal_client_config_cleanup = NULL;
-    dlclose(dlhandle);
-    dlhandle = NULL;
-    return -1;
-}
-
-/**
- *  Allocate a new struct config_instance for modifying the disable field
- */
-static struct config_instance *allocate_config_instance(){
-    struct config_instance *config = (struct config_instance *)malloc(sizeof(struct config_instance));
-    memset(config, 0, sizeof(*config));
-
-    config->cfg_desc = (char *)malloc(sizeof(char)*max_string_size);
-    memset(config->cfg_desc, 0, sizeof(char)*max_string_size);
-
-    config->algo_type = (char *)malloc(sizeof(char)*max_string_size);
-    memset(config->algo_type, 0, sizeof(char) * max_string_size);
-
-    config->fields = (struct field_data *)malloc(sizeof(struct field_data));
-    memset(config->fields, 0, sizeof(*config->fields));
-
-    config->fields[0].field_name = (char*)malloc(sizeof(char)*max_string_size);
-    memset(config->fields[0].field_name, 0, sizeof(char)*max_string_size);
-
-    config->fields[0].data = (void*)malloc(sizeof(int));
-
-    return config;
-}
-/**
- *  Free the config_instance as allocated in allocate_config_instance
- */
-static void free_config_instance(struct config_instance *config){
-
-    free(config->fields[0].data);
-    free(config->fields[0].field_name);
-    free(config->fields);
-    free(config->algo_type);
-    free(config->cfg_desc);
-    free(config);
-}
-
-/**
- *  disable a thermal config
- *  returns 1 on success, anything else is a failure
- */
-static int disable_config(char *config_name, char *algo_type){
-    int result = 0;
-    if (error_state) {
-        return 0;
-    }
-    struct config_instance *config = allocate_config_instance();
-    strlcpy(config->cfg_desc, config_name, max_string_size);
-    strlcpy(config->algo_type, algo_type, max_string_size);
-    strlcpy(config->fields[0].field_name, "disable", max_string_size);
-
-    config->fields_mask |= DISABLE_FIELD;
-    config->num_fields = 1;
-    config->fields[0].data_type = FIELD_INT;
-    config->fields[0].num_data = 1;
-    *(int*)(config->fields[0].data) = 1; //DISABLE
-
-
-    result = (*p_thermal_client_config_set)(config, 1);
-    if (DEBUG) {
-        ALOGE("disable profile: name = %s, algo_type = %s, success = %d", config_name, algo_type, result);
-    }
-    free_config_instance(config);
-
-    return result;
-}
-
-/**
- *  enable a thermal config
- *  returns 1 on success, anything else is failure
- */
-static int enable_config(char *config_name, char *algo_type){
-    int result = 0;
-    if (error_state) {
-        return 0;
-    }
-    struct config_instance *config = allocate_config_instance();
-    strlcpy(config->cfg_desc, config_name, max_string_size);
-    strlcpy(config->algo_type, algo_type, max_string_size);
-    strlcpy(config->fields[0].field_name, "disable", max_string_size);
-
-    config->fields_mask |= DISABLE_FIELD;
-    config->num_fields = 1;
-    config->fields[0].data_type = FIELD_INT;
-    config->fields[0].num_data = 1;
-    *(int*)(config->fields[0].data) = 0;  //ENABLE
-
-    result = (*p_thermal_client_config_set)(config, 1);
-    if (DEBUG) {
-        ALOGE("enable profile: name = %s, algo_type = %s, success = %d",
-          config_name, algo_type, result);
-    }
-
-    free_config_instance(config);
-
-    return result;
-}
-
-/**
- * Call this if there is a compoenent-fatal error
- * Attempts to clean up any outstanding thermal config state
- */
-static void error_cleanup(){
-    //disable VR configs, best-effort so ignore return values
-    for (unsigned int i = 0; i < NUM_VR_CONFIGS; i++) {
-        disable_config(vr_thermal_configs[i][0], vr_thermal_configs[i][1]);
-    }
-
-    // enable non-VR profile, best-effort so ignore return values
-    for (unsigned int i = 0; i < NUM_NON_VR_CONFIGS; i++) {
-        enable_config(non_vr_thermal_configs[i][0], non_vr_thermal_configs[i][1]);
-    }
-
-    // set global error flag
-    error_state = 1;
-}
-
-/*
- * Set global display/GPU/scheduler configuration to used for VR apps.
- */
-static void set_vr_thermal_configuration() {
-    int result = 1;
-    if (error_state) {
-        return;
-    }
-
-    //disable non-VR configs
-    for (unsigned int i = 0; i < NUM_NON_VR_CONFIGS; i++) {
-        result = disable_config(non_vr_thermal_configs[i][0], non_vr_thermal_configs[i][1]);
-        if (result != 1) {
-            goto error;
-        }
-    }
-
-    //enable VR configs
-    for (unsigned int i = 0; i < NUM_VR_CONFIGS; i++) {
-        result = enable_config(vr_thermal_configs[i][0], vr_thermal_configs[i][1]);
-        if (result != 1) {
-            goto error;
-        }
-    }
-
-    if (DEBUG) {
-        query_thermal_config();
-    }
-
-    return;
-
-error:
-    error_cleanup();
-    return;
-}
-
-/*
- * Reset to default global display/GPU/scheduler configuration.
- */
-static void unset_vr_thermal_configuration() {
-    int result = 1;
-    if (error_state) {
-        return;
-    }
-
-    //disable VR configs
-    for (unsigned int i = 0; i < NUM_VR_CONFIGS; i++) {
-        result = disable_config(vr_thermal_configs[i][0], vr_thermal_configs[i][1]);
-        if (result != 1) {
-            goto error;
-        }
-    }
-
-    // enable non-VR profile
-    for (unsigned int i = 0; i < NUM_NON_VR_CONFIGS; i++) {
-        result = enable_config(non_vr_thermal_configs[i][0], non_vr_thermal_configs[i][1]);
-        if (result != 1) {
-            goto error;
-        }
-    }
-
-    if (DEBUG) {
-        query_thermal_config();
-    }
-
-    return;
-
-error:
-    error_cleanup();
-    return;
-}
-
 static void vr_init(struct vr_module *module) {
-    int success = load_thermal_client();
-    if (success != 0) {
-        ALOGE("failed to load thermal client");
-        error_state = 1;
-    }
+    // NOOP
 }
 
 static void vr_set_vr_mode(struct vr_module *module, bool enabled) {
     if (enabled) {
-        set_vr_thermal_configuration();
+        if (property_set("sys.qcom.thermalcfg", "/vendor/etc/thermal-engine-vr.conf")) {
+            ALOGE("%s: couldn't set a system property, "
+                  "sys.qcom.thermalcfg.", __FUNCTION__);
+        }
     } else {
-        unset_vr_thermal_configuration();
+        if (property_set("sys.qcom.thermalcfg", "/vendor/etc/thermal-engine.conf")) {
+            ALOGE("%s: couldn't set a system property, "
+                  "sys.qcom.thermalcfg.", __FUNCTION__);
+        }
     }
+    restart_thermal_engine();
 }
 
 static struct hw_module_methods_t vr_module_methods = {