Add recovery support for perf experiments.
This change establishes a place for perf experiments and adds a
script to delay experiments for recovery purposes. For more info
see go/pixel-perf-experiment-whatif.
Bug: 365855872
Test: build/flash, set .Perf__experiments_delay_seconds=10, verify that vendor.perf.allow_experiments=1 after 10 seconds
Flag: NONE controlled by Mendel instead
Change-Id: I78db482542066d5d5646d8c303dbe88054cfe66d
Signed-off-by: Dmitry Skiba <dskiba@google.com>
diff --git a/performance/experiments/Android.bp b/performance/experiments/Android.bp
new file mode 100644
index 0000000..a2f7ebe
--- /dev/null
+++ b/performance/experiments/Android.bp
@@ -0,0 +1,10 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+sh_binary {
+ name: "pixel-experiments-recovery.sh",
+ src: "pixel-experiments-recovery.sh",
+ vendor: true,
+ init_rc: ["pixel-experiments-recovery.rc"],
+}
diff --git a/performance/experiments/experiments.mk b/performance/experiments/experiments.mk
new file mode 100644
index 0000000..b52d0e6
--- /dev/null
+++ b/performance/experiments/experiments.mk
@@ -0,0 +1,3 @@
+BOARD_VENDOR_SEPOLICY_DIRS += device/google/gs-common/performance/experiments/sepolicy
+
+PRODUCT_PACKAGES += pixel-experiments-recovery.sh
diff --git a/performance/experiments/pixel-experiments-recovery.rc b/performance/experiments/pixel-experiments-recovery.rc
new file mode 100644
index 0000000..a8247c3
--- /dev/null
+++ b/performance/experiments/pixel-experiments-recovery.rc
@@ -0,0 +1,17 @@
+# pixel-experiments-recovery.sh waits Perf__experiments_delay_seconds and sets
+# vendor.perf.allow_experiments=1, triggering experiments.
+service pixel-experiments-recovery /vendor/bin/pixel-experiments-recovery.sh \
+ ${vendor.pixel.system.phenotype.Perf__experiments_delay_seconds}
+ class main
+ user root
+ group root system
+ oneshot
+ disabled
+
+# vendor.pixel.system.phenotype.Perf__xxx properties are set sometime after the
+# device is unlocked for the first time. The check for sys.boot_completed is not
+# strictly needed, but will prevent surprises if for some reason the property
+# is set early.
+on property:sys.boot_completed=1 && \
+ property:vendor.pixel.system.phenotype.Perf__experiments_delay_seconds=*
+ restart pixel-experiments-recovery
diff --git a/performance/experiments/pixel-experiments-recovery.sh b/performance/experiments/pixel-experiments-recovery.sh
new file mode 100755
index 0000000..188222e
--- /dev/null
+++ b/performance/experiments/pixel-experiments-recovery.sh
@@ -0,0 +1,15 @@
+#!/vendor/bin/sh
+
+# This script delays experiments by the specified amount of seconds. The delay is not needed for
+# the normal operation, but becomes essential for the rare case (which "should not happen") where
+# an experiment causes really bad issues (e.g. crashes the kernel). In such case the delay gives
+# GMSCore an opportunity to fetch fresh experiments snapshot (with the bad experiment disabled).
+#
+# See go/pixel-perf-experiment-whatif for more info.
+
+delay_seconds="$1"
+
+if [ -n "$delay_seconds" ]; then
+ sleep "$delay_seconds"
+ /vendor/bin/setprop vendor.perf.allow_experiments 1
+fi
diff --git a/performance/experiments/sepolicy/file_contexts b/performance/experiments/sepolicy/file_contexts
new file mode 100644
index 0000000..7364807
--- /dev/null
+++ b/performance/experiments/sepolicy/file_contexts
@@ -0,0 +1 @@
+/vendor/bin/pixel-experiments-recovery\.sh u:object_r:pixel-experiments-recovery-sh_exec:s0
diff --git a/performance/experiments/sepolicy/pixel-experiments-recovery.sh.te b/performance/experiments/sepolicy/pixel-experiments-recovery.sh.te
new file mode 100644
index 0000000..2da555b
--- /dev/null
+++ b/performance/experiments/sepolicy/pixel-experiments-recovery.sh.te
@@ -0,0 +1,10 @@
+# Rules for pixel-experiments-recovery.sh
+
+type pixel-experiments-recovery-sh, domain;
+type pixel-experiments-recovery-sh_exec, exec_type, vendor_file_type, file_type;
+
+init_daemon_domain(pixel-experiments-recovery-sh)
+
+# Allow "setprop vendor.perf.allow_experiments".
+allow pixel-experiments-recovery-sh vendor_toolbox_exec:file { execute_no_trans };
+set_prop(pixel-experiments-recovery-sh, vendor_perf_allow_experiments_prop)
diff --git a/performance/experiments/sepolicy/property.te b/performance/experiments/sepolicy/property.te
new file mode 100644
index 0000000..e43312c
--- /dev/null
+++ b/performance/experiments/sepolicy/property.te
@@ -0,0 +1,3 @@
+# Properties shared between experiments.
+
+vendor_internal_prop(vendor_perf_allow_experiments_prop)
diff --git a/performance/experiments/sepolicy/property_contexts b/performance/experiments/sepolicy/property_contexts
new file mode 100644
index 0000000..50de9c1
--- /dev/null
+++ b/performance/experiments/sepolicy/property_contexts
@@ -0,0 +1 @@
+vendor.perf.allow_experiments u:object_r:vendor_perf_allow_experiments_prop:s0