diff --git a/a20/BoardConfig.mk b/a20/BoardConfig.mk
index 041f193..7fcf84c 100644
--- a/a20/BoardConfig.mk
+++ b/a20/BoardConfig.mk
@@ -7,7 +7,7 @@ TARGET_OTA_ASSERT_DEVICE := a20,a20dd
TARGET_KEYMASTER_VARIANT := samsung
# Kernel
-TARGET_KERNEL_CONFIG := exynos7885-a20_permissive_defconfig
+TARGET_KERNEL_CONFIG := exynos7885-a20_enforcing_defconfig
# Display
TARGET_SCREEN_DENSITY := 411
diff --git a/a20/aosp_a20.mk b/a20/aosp_a20.mk
deleted file mode 100644
index 51d1c6d..0000000
--- a/a20/aosp_a20.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-$(call inherit-product, device/samsung/a20/full_a20.mk)
-
-# Inherit some common Lineage stuff.
-$(call inherit-product, vendor/aosp/config/common_full_phone.mk)
-
-PRODUCT_NAME := aosp_a20
-TARGET_FACE_UNLOCK_SUPPORTED := true
-
-TARGET_SUPPORTS_GOOGLE_RECORDER := true
-TARGET_INCLUDE_STOCK_ARCORE := true
-TARGET_INCLUDE_LIVE_WALLPAPERS := true
-# Set bootanimation resolution to 7200p
-TARGET_BOOT_ANIMATION_RES := 720
diff --git a/a20/overlay/frameworks/base/core/res/res/values/config.xml b/a20/overlay/frameworks/base/core/res/res/values/config.xml
index e86fc95..2e82fe8 100644
--- a/a20/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/a20/overlay/frameworks/base/core/res/res/values/config.xml
@@ -1,597 +1,63 @@
+
+
+
+
- true
- true
- false
- M62,0l-3.8,0l-3.9,0.2l-3.9,0.4l-4,0.8l-3.9,1.2l-3.8,1.6l-3.7,2l-3.4,2.4l-3.1,2.8l-2.9,3l-2.7,3.1l-2.6,3.1 l-2.7,2.8C12.5,28,6.2,30.3,0,30.3c-6.3,0-12.5-2.3-17.5-6.8l-2.7-2.8l-2.6-3.1l-2.7-3.1l-2.9-3l-3.2-2.8 L-35,6.2l-3.7-2l-3.8-1.6l-3.9-1.2l-4-0.8L-54.3,0.2L-58.2,0L-62,0Z @dp
- true
- true
- true
- true
- 2000
- 4000
-
- - 10
- - 11
- - 15
- - 17
- - 19
- - 25
- - 30
- - 34
- - 38
- - 44
- - 49
- - 67
- - 82
- - 90
- - 102
- - 108
- - 148
- - 183
- - 247
- - 304
- - 350
- - 391
- - 420
- - 420
- - 450
- - 500
- - 550
- - 575
- - 600
-
-
- - 10
- - 80
- - 162
- - 190
- - 255
-
-
- - 1
- - 2
- - 3
- - 4
- - 5
- - 6
- - 7
- - 8
- - 9
- - 10
- - 15
- - 20
- - 25
- - 50
- - 100
- - 300
- - 500
- - 1000
- - 1500
- - 2000
- - 3000
- - 4000
- - 4999
- - 5000
- - 10000
- - 20000
- - 30000
- - 40000
-
-
- - 0
- - 1
- - 2
- - 3
- - 4
- - 5
- - 6
- - 7
- - 8
- - 9
- - 10
- - 11
- - 12
- - 13
- - 14
- - 15
- - 16
- - 17
- - 18
- - 19
- - 20
- - 21
- - 22
- - 23
- - 24
- - 25
- - 26
- - 27
- - 28
- - 29
- - 30
- - 31
- - 32
- - 33
- - 34
- - 35
- - 36
- - 37
- - 38
- - 39
- - 40
- - 41
- - 42
- - 43
- - 44
- - 45
- - 46
- - 47
- - 48
- - 49
- - 50
- - 51
- - 52
- - 53
- - 54
- - 55
- - 56
- - 57
- - 58
- - 59
- - 60
- - 61
- - 62
- - 63
- - 64
- - 65
- - 66
- - 67
- - 68
- - 69
- - 70
- - 71
- - 72
- - 73
- - 74
- - 75
- - 76
- - 77
- - 78
- - 79
- - 80
- - 81
- - 82
- - 83
- - 84
- - 85
- - 86
- - 87
- - 88
- - 89
- - 90
- - 91
- - 92
- - 93
- - 94
- - 95
- - 96
- - 97
- - 98
- - 99
- - 100
- - 101
- - 102
- - 103
- - 104
- - 105
- - 106
- - 107
- - 108
- - 109
- - 110
- - 111
- - 112
- - 113
- - 114
- - 115
- - 116
- - 117
- - 118
- - 119
- - 120
- - 121
- - 122
- - 123
- - 124
- - 125
- - 126
- - 127
- - 128
- - 129
- - 130
- - 131
- - 132
- - 133
- - 134
- - 135
- - 136
- - 137
- - 138
- - 139
- - 140
- - 141
- - 142
- - 143
- - 144
- - 145
- - 146
- - 147
- - 148
- - 149
- - 150
- - 151
- - 152
- - 153
- - 154
- - 155
- - 156
- - 157
- - 158
- - 159
- - 160
- - 161
- - 162
- - 163
- - 164
- - 165
- - 166
- - 167
- - 168
- - 169
- - 170
- - 171
- - 172
- - 173
- - 174
- - 175
- - 176
- - 177
- - 178
- - 179
- - 180
- - 181
- - 182
- - 183
- - 184
- - 185
- - 186
- - 187
- - 188
- - 189
- - 190
- - 191
- - 192
- - 193
- - 194
- - 195
- - 196
- - 197
- - 198
- - 199
- - 200
- - 201
- - 202
- - 203
- - 204
- - 205
- - 206
- - 207
- - 208
- - 209
- - 210
- - 211
- - 212
- - 213
- - 214
- - 215
- - 216
- - 217
- - 218
- - 219
- - 220
- - 221
- - 222
- - 223
- - 224
- - 225
- - 226
- - 227
- - 228
- - 229
- - 230
- - 231
- - 232
- - 233
- - 234
- - 235
- - 236
- - 237
- - 238
- - 239
- - 240
- - 241
- - 242
- - 243
- - 244
- - 245
- - 246
- - 247
- - 248
- - 249
- - 250
- - 251
- - 252
- - 253
- - 254
- - 255
-
-
- - 2
- - 3
- - 4
- - 6
- - 7
- - 8
- - 9
- - 10
- - 12
- - 13
- - 14
- - 15
- - 16
- - 18
- - 19
- - 20
- - 22
- - 24
- - 25
- - 26
- - 28
- - 29
- - 31
- - 32
- - 34
- - 35
- - 36
- - 38
- - 39
- - 41
- - 42
- - 44
- - 45
- - 46
- - 48
- - 49
- - 51
- - 52
- - 54
- - 55
- - 57
- - 58
- - 60
- - 61
- - 62
- - 64
- - 65
- - 67
- - 68
- - 70
- - 71
- - 72
- - 74
- - 75
- - 77
- - 78
- - 80
- - 81
- - 83
- - 84
- - 86
- - 87
- - 88
- - 90
- - 91
- - 93
- - 94
- - 95
- - 97
- - 98
- - 100
- - 101
- - 103
- - 104
- - 105
- - 107
- - 109
- - 110
- - 111
- - 113
- - 114
- - 116
- - 117
- - 119
- - 120
- - 121
- - 123
- - 124
- - 126
- - 127
- - 129
- - 130
- - 131
- - 133
- - 135
- - 136
- - 137
- - 139
- - 140
- - 142
- - 143
- - 145
- - 146
- - 147
- - 149
- - 150
- - 152
- - 153
- - 155
- - 156
- - 157
- - 159
- - 161
- - 162
- - 163
- - 165
- - 166
- - 168
- - 169
- - 171
- - 172
- - 173
- - 175
- - 176
- - 178
- - 179
- - 181
- - 182
- - 183
- - 186
- - 188
- - 189
- - 191
- - 193
- - 195
- - 197
- - 198
- - 201
- - 202
- - 204
- - 206
- - 208
- - 210
- - 212
- - 214
- - 216
- - 217
- - 219
- - 221
- - 223
- - 225
- - 226
- - 229
- - 230
- - 232
- - 234
- - 236
- - 238
- - 240
- - 242
- - 244
- - 245
- - 247
- - 249
- - 251
- - 253
- - 254
- - 257
- - 258
- - 260
- - 262
- - 264
- - 266
- - 268
- - 270
- - 272
- - 273
- - 275
- - 277
- - 279
- - 281
- - 282
- - 285
- - 286
- - 288
- - 290
- - 292
- - 294
- - 296
- - 298
- - 300
- - 301
- - 303
- - 305
- - 307
- - 309
- - 310
- - 313
- - 314
- - 316
- - 318
- - 320
- - 322
- - 324
- - 326
- - 327
- - 329
- - 331
- - 333
- - 335
- - 337
- - 338
- - 341
- - 342
- - 344
- - 346
- - 348
- - 350
- - 352
- - 354
- - 355
- - 357
- - 359
- - 361
- - 363
- - 365
- - 366
- - 369
- - 370
- - 372
- - 374
- - 376
- - 378
- - 379
- - 382
- - 383
- - 385
- - 387
- - 389
- - 391
- - 393
- - 395
- - 397
- - 398
- - 400
- - 402
- - 404
- - 406
- - 407
- - 410
- - 411
- - 413
- - 415
- - 417
- - 419
- - 420
-
+
+ M 0,0 H -67.42857142857143 V 30.85714285714286 H 67.42857142857143 V 0 H 0 Z @dp
+ @*android:string/config_mainBuiltInDisplayCutout
+
+ false
+
+
+
+ - 0:2:15
+
+
+
+ 4
+
+
+ true
+
+
+ true
+
+
+ 2
diff --git a/a20/overlay/frameworks/base/core/res/res/values/dimens.xml b/a20/overlay/frameworks/base/core/res/res/values/dimens.xml
index faac598..a7eb53e 100644
--- a/a20/overlay/frameworks/base/core/res/res/values/dimens.xml
+++ b/a20/overlay/frameworks/base/core/res/res/values/dimens.xml
@@ -1,6 +1,13 @@
+
24.0dip
+
+
31.0dip
+
+
40px
diff --git a/a20/overlay/frameworks/base/core/res/res/xml/power_profile.xml b/a20/overlay/frameworks/base/core/res/res/xml/power_profile.xml
index c7305a5..af4faa2 100644
--- a/a20/overlay/frameworks/base/core/res/res/xml/power_profile.xml
+++ b/a20/overlay/frameworks/base/core/res/res/xml/power_profile.xml
@@ -70,6 +70,7 @@
- 3.79
- 23
- 4000
+ - 4000
- 1
- 65
- 265
diff --git a/a20e/AndroidProducts.mk b/a20e/AndroidProducts.mk
deleted file mode 100644
index e2a2656..0000000
--- a/a20e/AndroidProducts.mk
+++ /dev/null
@@ -1,2 +0,0 @@
-PRODUCT_MAKEFILES := \
- $(LOCAL_DIR)/aosp_a20e.mk
diff --git a/a20e/BoardConfig.mk b/a20e/BoardConfig.mk
index eaee2d3..ae229a6 100644
--- a/a20e/BoardConfig.mk
+++ b/a20e/BoardConfig.mk
@@ -7,7 +7,7 @@ TARGET_OTA_ASSERT_DEVICE := a20e,a20edd
TARGET_KEYMASTER_VARIANT := samsung
# Kernel
-TARGET_KERNEL_CONFIG := exynos7885-a20e_permissive_defconfig
+TARGET_KERNEL_CONFIG := exynos7885-a20e_enforcing_defconfig
# Display
TARGET_SCREEN_DENSITY := 320
diff --git a/a20e/aosp_a20e.mk b/a20e/aosp_a20e.mk
deleted file mode 100644
index 95ff5b7..0000000
--- a/a20e/aosp_a20e.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-$(call inherit-product, device/samsung/a20e/full_a20e.mk)
-
-# Inherit some common Lineage stuff.
-$(call inherit-product, vendor/aosp/config/common_full_phone.mk)
-
-PRODUCT_NAME := aosp_a20e
-TARGET_FACE_UNLOCK_SUPPORTED := true
-
-TARGET_SUPPORTS_GOOGLE_RECORDER := true
-TARGET_INCLUDE_STOCK_ARCORE := true
-TARGET_INCLUDE_LIVE_WALLPAPERS := true
-# Set bootanimation resolution to 7200p
-TARGET_BOOT_ANIMATION_RES := 720
diff --git a/universal7885-common/SamsungParts/Android.mk b/universal7885-common/SamsungParts/Android.mk
new file mode 100644
index 0000000..8afc52d
--- /dev/null
+++ b/universal7885-common/SamsungParts/Android.mk
@@ -0,0 +1,35 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+ androidx.preference_preference
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_PACKAGE_NAME := SamsungParts
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
+LOCAL_PRIVATE_PLATFORM_APIS := true
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_USE_AAPT2 := true
+
+LOCAL_RESOURCE_DIR := \
+ $(LOCAL_PATH)/res \
+ $(TOP)/packages/resources/devicesettings/res
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include frameworks/base/packages/SettingsLib/common.mk
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := SamsungParts.rc
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/init
+include $(BUILD_PREBUILT)
diff --git a/universal7885-common/SamsungParts/AndroidManifest.xml b/universal7885-common/SamsungParts/AndroidManifest.xml
new file mode 100644
index 0000000..775a676
--- /dev/null
+++ b/universal7885-common/SamsungParts/AndroidManifest.xml
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/SamsungParts.rc b/universal7885-common/SamsungParts/SamsungParts.rc
new file mode 100644
index 0000000..37ce7e4
--- /dev/null
+++ b/universal7885-common/SamsungParts/SamsungParts.rc
@@ -0,0 +1,11 @@
+on property:sys.boot_completed=1
+ chmod 664 /sys/devices/platform/11500000.mali/tmu
+ chown system system /sys/devices/platform/11500000.mali/tmu
+ chmod 664 /sys/class/camera/flash/torch_brightness_lvl
+ chown system system /sys/class/camera/flash/torch_brightness_lvl
+ chmod 664 /sys/class/camera/flash/torch_brightness_lvl_enable
+ chown system system /sys/class/camera/flash/torch_brightness_lvl_enable
+ chmod 664 /sys/devices/platform/battery/power_supply/battery/batt_slate_mode
+ chmod system system /sys/devices/platform/battery/power_supply/battery/batt_slate_mode
+ chmod 644 /sys/class/sec/switch/afc_disable
+ chmod system system /sys/class/sec/switch/afc_disable
diff --git a/universal7885-common/SamsungParts/res/drawable/action_presets.xml b/universal7885-common/SamsungParts/res/drawable/action_presets.xml
new file mode 100644
index 0000000..5e9b32c
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/action_presets.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/action_reset.xml b/universal7885-common/SamsungParts/res/drawable/action_reset.xml
new file mode 100644
index 0000000..28e7f8f
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/action_reset.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_battery.xml b/universal7885-common/SamsungParts/res/drawable/ic_battery.xml
new file mode 100644
index 0000000..c19f744
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_battery.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_bolt.xml b/universal7885-common/SamsungParts/res/drawable/ic_bolt.xml
new file mode 100644
index 0000000..cd399f0
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_bolt.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_cabc.xml b/universal7885-common/SamsungParts/res/drawable/ic_cabc.xml
new file mode 100644
index 0000000..47a7d03
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_cabc.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_custom_seekbar_minus.xml b/universal7885-common/SamsungParts/res/drawable/ic_custom_seekbar_minus.xml
new file mode 100644
index 0000000..28777b8
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_custom_seekbar_minus.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_custom_seekbar_plus.xml b/universal7885-common/SamsungParts/res/drawable/ic_custom_seekbar_plus.xml
new file mode 100644
index 0000000..a1873f4
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_custom_seekbar_plus.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_custom_seekbar_reset.xml b/universal7885-common/SamsungParts/res/drawable/ic_custom_seekbar_reset.xml
new file mode 100644
index 0000000..3c6dbc9
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_custom_seekbar_reset.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_device.xml b/universal7885-common/SamsungParts/res/drawable/ic_device.xml
new file mode 100644
index 0000000..27c2f82
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_device.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_doze.xml b/universal7885-common/SamsungParts/res/drawable/ic_doze.xml
new file mode 100644
index 0000000..da13cfb
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_doze.xml
@@ -0,0 +1,8 @@
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_fps_info.xml b/universal7885-common/SamsungParts/res/drawable/ic_fps_info.xml
new file mode 100644
index 0000000..8e51c14
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_fps_info.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_gpu.xml b/universal7885-common/SamsungParts/res/drawable/ic_gpu.xml
new file mode 100644
index 0000000..95f0f7b
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_gpu.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_hand.xml b/universal7885-common/SamsungParts/res/drawable/ic_hand.xml
new file mode 100644
index 0000000..5f56669
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_hand.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_hbm.xml b/universal7885-common/SamsungParts/res/drawable/ic_hbm.xml
new file mode 100644
index 0000000..3a9bdeb
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_hbm.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_headphone.xml b/universal7885-common/SamsungParts/res/drawable/ic_headphone.xml
new file mode 100644
index 0000000..f8200af
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_headphone.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_led.xml b/universal7885-common/SamsungParts/res/drawable/ic_led.xml
new file mode 100644
index 0000000..75376d2
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_led.xml
@@ -0,0 +1,11 @@
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_qs_log.xml b/universal7885-common/SamsungParts/res/drawable/ic_qs_log.xml
new file mode 100644
index 0000000..7e77021
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_qs_log.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_speaker_cleaner_icon.xml b/universal7885-common/SamsungParts/res/drawable/ic_speaker_cleaner_icon.xml
new file mode 100644
index 0000000..4ef1f6d
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_speaker_cleaner_icon.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/ic_vibrate.xml b/universal7885-common/SamsungParts/res/drawable/ic_vibrate.xml
new file mode 100644
index 0000000..a07910c
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/ic_vibrate.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/drawable/switchbar_background.xml b/universal7885-common/SamsungParts/res/drawable/switchbar_background.xml
new file mode 100644
index 0000000..29cde77
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/drawable/switchbar_background.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/layout/preference_custom_seekbar.xml b/universal7885-common/SamsungParts/res/layout/preference_custom_seekbar.xml
new file mode 100644
index 0000000..16940fb
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/layout/preference_custom_seekbar.xml
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/layout/switch_bar.xml b/universal7885-common/SamsungParts/res/layout/switch_bar.xml
new file mode 100644
index 0000000..f3e9a6d
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/layout/switch_bar.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/raw/clear_speaker_sound.mp3 b/universal7885-common/SamsungParts/res/raw/clear_speaker_sound.mp3
new file mode 100644
index 0000000..79093f3
Binary files /dev/null and b/universal7885-common/SamsungParts/res/raw/clear_speaker_sound.mp3 differ
diff --git a/universal7885-common/SamsungParts/res/values/arrays.xml b/universal7885-common/SamsungParts/res/values/arrays.xml
new file mode 100644
index 0000000..d7b4fe7
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/values/arrays.xml
@@ -0,0 +1,11 @@
+
+
+
+ - @string/battery_max_capa
+ - @string/battery_chrged_up_to
+ - @string/battery_chrged_up_to_mah
+ - @string/battery_current
+ - @string/battery_status
+ - @string/battery_temp
+
+
\ No newline at end of file
diff --git a/universal7885-common/SamsungParts/res/values/attrs.xml b/universal7885-common/SamsungParts/res/values/attrs.xml
new file mode 100644
index 0000000..44f9b1b
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/values/attrs.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/values/colors.xml b/universal7885-common/SamsungParts/res/values/colors.xml
new file mode 100644
index 0000000..fcdd84d
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/values/colors.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+ #66000000
+ #FFFF6700
+
+
diff --git a/universal7885-common/SamsungParts/res/values/strings.xml b/universal7885-common/SamsungParts/res/values/strings.xml
new file mode 100644
index 0000000..26a055d
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/values/strings.xml
@@ -0,0 +1,94 @@
+
+
+
+
+ SamsungParts
+ Device specific tweaks
+
+
+ Display
+
+
+ Logs
+ Options
+ Action failed because of missing superuser access
+
+
+ FPS info overlay
+ Show overlay with current frames per second
+
+
+ Speaker
+
+
+ Clear speaker
+ Play a 30-second audio to clear the speaker
+ Run this feature once or twice if you find that your speaker is lightly blocked by dust. Set media volume to maximum.\n\nIf the speaker is blocked heavily, run this feature 2–5 times while shaking your device with the speaker facing downwards.
+
+
+ Eureka Kernel Features
+
+
+ FlashLight Brightness
+ Adjust FlashLight Brightness
+ Samsung\'s OneUI Has An Option to Adjust
+ Flashlight Brightness. AOSP doesn\'t have this feature.\n\n
+ Use this feature to adjust low or high flashlight brightness. Ranges from 0 to 10.
+
+
+ GPU
+
+
+ Exynos GPU (Mali) Throttling
+ Disable/Enable GPU Throttling
+
+
+ SELinux Status
+ Click here to see current SELinux status
+
+ Info
+
+
+ Battery
+ FastCharge Settings
+ Charging Settings
+ Enable/Disable Charging here.
+ Battery Info and Settings
+ Enable/Disable Fastcharge Feature
+ Manage FastCharge Feature here.
+ Battery Misc Info
+ Section for geeks
+
+ Battery Max Capacity (mAh)
+ Battery Status
+ Battery Charged Up To (%)
+ Battery Charged Up To (mAh)
+ Battery Current Temperature
+ Battery Current (mA)
+
+
+ On
+
+
+ Off
+
+
+ Value: %s
+ Default
+ Default value: %s\nLong press to set
+ Default value is set
+
+
diff --git a/universal7885-common/SamsungParts/res/values/styles.xml b/universal7885-common/SamsungParts/res/values/styles.xml
new file mode 100644
index 0000000..25ec94e
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/values/styles.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/xml/battery_settings.xml b/universal7885-common/SamsungParts/res/xml/battery_settings.xml
new file mode 100644
index 0000000..756636b
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/xml/battery_settings.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/xml/clear_speaker_settings.xml b/universal7885-common/SamsungParts/res/xml/clear_speaker_settings.xml
new file mode 100644
index 0000000..eb7ce77
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/xml/clear_speaker_settings.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/xml/flashlight_settings.xml b/universal7885-common/SamsungParts/res/xml/flashlight_settings.xml
new file mode 100644
index 0000000..121c3a9
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/xml/flashlight_settings.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/res/xml/preferences_samsung_parts.xml b/universal7885-common/SamsungParts/res/xml/preferences_samsung_parts.xml
new file mode 100644
index 0000000..e84c564
--- /dev/null
+++ b/universal7885-common/SamsungParts/res/xml/preferences_samsung_parts.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/BootReceiver.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/BootReceiver.java
new file mode 100644
index 0000000..b643bf9
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/BootReceiver.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 The Xiaomi-SM6250 Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.eurekateam.samsungextras;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+
+import androidx.preference.PreferenceManager;
+
+import com.eurekateam.samsungextras.utils.FileUtilsWrapper;
+
+
+public class BootReceiver extends BroadcastReceiver {
+ public void onReceive(Context context, Intent intent) {
+
+ SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
+
+ boolean fpsenabled = sharedPrefs.getBoolean(DeviceSettings.PREF_KEY_FPS_INFO, false);
+ if (fpsenabled) {
+ context.startService(new Intent(context, FPSInfoService.class));
+ }
+ boolean gpuenabled = sharedPrefs.getBoolean(DeviceSettings.PREF_GPUEXYNOS, false);
+ if (!gpuenabled){
+ FileUtilsWrapper.writeLine(GlobalConstants.TMU_SYSFS, "0");
+ }
+ }
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/DeviceSettings.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/DeviceSettings.java
new file mode 100644
index 0000000..0d726f5
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/DeviceSettings.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2020 The Xiaomi-SM6250 Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.eurekateam.samsungextras;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.Toast;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragment;
+import androidx.preference.PreferenceManager;
+import androidx.preference.SwitchPreference;
+
+import com.eurekateam.samsungextras.battery.BatteryActivity;
+import com.eurekateam.samsungextras.flashlight.FlashLightActivity;
+import com.eurekateam.samsungextras.speaker.ClearSpeakerActivity;
+import com.eurekateam.samsungextras.utils.FileUtilsWrapper;
+import com.eurekateam.samsungextras.utils.SystemProperties;
+
+public class DeviceSettings extends PreferenceFragment implements
+ Preference.OnPreferenceChangeListener {
+ public static final String PREF_KEY_FPS_INFO = "fps_info";
+ private static final String PREF_CLEAR_SPEAKER = "clear_speaker_settings";
+ private static final String PREF_FLASHLIGHT = "flashlight_settings";
+ public static final String PREF_GPUEXYNOS = "gpuexynos_settings";
+ private static final String PREF_SELINUX = "selinux_settings";
+ public static final String PREF_BATTERY = "battery_settings";
+
+ public DeviceSettings() {
+ }
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ setPreferencesFromResource(R.xml.preferences_samsung_parts, rootKey);
+ Context mContext = this.getContext();
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
+ Preference mClearSpeakerPref = findPreference(PREF_CLEAR_SPEAKER);
+ assert mClearSpeakerPref != null;
+ mClearSpeakerPref.setOnPreferenceClickListener(preference -> {
+ Intent intent = new Intent(getActivity().getApplicationContext(), ClearSpeakerActivity.class);
+ startActivity(intent);
+ return true;
+ });
+
+ SwitchPreference mFpsInfo = findPreference(PREF_KEY_FPS_INFO);
+ assert mFpsInfo != null;
+ mFpsInfo.setChecked(prefs.getBoolean(PREF_KEY_FPS_INFO, false));
+ mFpsInfo.setOnPreferenceChangeListener(this);
+
+ SwitchPreference mGPUExynos = findPreference(PREF_GPUEXYNOS);
+ assert mGPUExynos != null;
+ if (FileUtilsWrapper.isFileReadable(GlobalConstants.TMU_SYSFS)) {
+ Log.d(GlobalConstants.TAG, "onCreatePreferences: "
+ + (GlobalConstants.TMU_SYSFS) + " readable, value " +
+ FileUtilsWrapper.readOneLine(GlobalConstants.TMU_SYSFS));
+ mGPUExynos.setChecked(
+ FileUtilsWrapper.readOneLine(GlobalConstants.TMU_SYSFS).equals("1"));
+ }else {
+ Log.w(GlobalConstants.TAG, "onCreatePreferences: "
+ + (GlobalConstants.TMU_SYSFS) + " not readable");
+ mGPUExynos.setEnabled(false);
+ }
+ mGPUExynos.setOnPreferenceChangeListener(this);
+
+ Preference mSELinux = findPreference(PREF_SELINUX);
+ assert mSELinux != null;
+ mSELinux.setOnPreferenceClickListener(preference -> {
+ boolean selinux_enforcing = SystemProperties.getenforce();
+ Toast.makeText(getContext(), selinux_enforcing ?
+ "SELinux is in enforcing state." :
+ "SELinux is in permissive state.",
+ Toast.LENGTH_SHORT).show();
+ return true;
+ });
+ Preference mFlashLight = findPreference(PREF_FLASHLIGHT);
+ mFlashLight.setOnPreferenceClickListener(preference -> {
+ Intent intent = new Intent(getActivity().getApplicationContext(), FlashLightActivity.class);
+ startActivity(intent);
+ return true;
+ });
+ Preference mFastCharge = findPreference(PREF_BATTERY);
+ assert mFastCharge != null;
+ mFastCharge.setOnPreferenceClickListener(preference -> {
+ Intent intent = new Intent(getActivity().getApplicationContext(), BatteryActivity.class);
+ startActivity(intent);
+ return true;
+ });
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object value) {
+ final String key = preference.getKey();
+ switch (key) {
+ case PREF_KEY_FPS_INFO:
+ boolean fps_enabled = (Boolean) value;
+ Intent fpsinfo = new Intent(this.getContext(), FPSInfoService.class);
+ if (fps_enabled) {
+ this.getContext().startService(fpsinfo);
+ } else {
+ this.getContext().stopService(fpsinfo);
+ }
+ break;
+ case PREF_GPUEXYNOS:
+ boolean gpu_enabled = (Boolean) value;
+ Log.d(GlobalConstants.TAG, "onPreferenceChange: Writing " +
+ gpu_enabled + " to " + GlobalConstants.TMU_SYSFS);
+ FileUtilsWrapper.writeLine(GlobalConstants.TMU_SYSFS, gpu_enabled ? "1" : "0");
+ Toast.makeText(getContext(), gpu_enabled ? "GPU Throttling is now enabled."
+ : "GPU Throttling is now disabled.",
+ Toast.LENGTH_SHORT).show();
+ default:
+ break;
+ }
+ return true;
+ }
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/DeviceSettingsActivity.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/DeviceSettingsActivity.java
new file mode 100644
index 0000000..4e4abc4
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/DeviceSettingsActivity.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 The Xiaomi-SM6250 Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.eurekateam.samsungextras;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.MenuItem;
+
+public class DeviceSettingsActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+
+ Fragment fragment = getFragmentManager().findFragmentById(android.R.id.content);
+ DeviceSettings mDeviceSettingsFragment;
+ if (fragment == null) {
+ mDeviceSettingsFragment = new DeviceSettings();
+ getFragmentManager().beginTransaction()
+ .add(android.R.id.content, mDeviceSettingsFragment)
+ .commit();
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/FPSInfoService.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/FPSInfoService.java
new file mode 100644
index 0000000..ac20356
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/FPSInfoService.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2020 The Xiaomi-SM6250 Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.eurekateam.samsungextras;
+
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Typeface;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.service.dreams.DreamService;
+import android.service.dreams.IDreamManager;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.WindowManager;
+
+public class FPSInfoService extends Service {
+ private View mView;
+ private Thread mCurFPSThread;
+ private static SurfaceFlingerFPS surfaceFlingerFPS;
+ private final String TAG = "FPSInfoService";
+ private String mFps = null;
+
+ private IDreamManager mDreamManager;
+
+ private class FPSView extends View {
+ private final Paint mOnlinePaint;
+ private final float mAscent;
+ private int mMaxWidth = 0;
+
+ private int mNeededWidth;
+ private int mNeededHeight;
+
+ private boolean mDataAvail;
+
+ private final Handler mCurFPSHandler = new Handler(Looper.getMainLooper()) {
+ public void handleMessage(Message msg) {
+ if (msg.obj == null || msg.what != 1) {
+ return;
+ }
+ String msgData = (String) msg.obj;
+ mFps = msgData + " FPS";
+ mDataAvail = true;
+ updateDisplay();
+ }
+ };
+
+ FPSView(Context c) {
+ super(c);
+ float density = c.getResources().getDisplayMetrics().density;
+ int paddingPx = Math.round(5 * density);
+ setPadding(paddingPx, paddingPx, paddingPx, paddingPx);
+ setBackgroundColor(Color.argb(0x60, 0, 0, 0));
+
+ final int textSize = Math.round(12 * density);
+
+ Typeface typeface = Typeface.create("monospace", Typeface.NORMAL);
+
+ mOnlinePaint = new Paint();
+ mOnlinePaint.setTypeface(typeface);
+ mOnlinePaint.setAntiAlias(true);
+ mOnlinePaint.setTextSize(textSize);
+ mOnlinePaint.setColor(Color.WHITE);
+ mOnlinePaint.setShadowLayer(5.0f, 0.0f, 0.0f, Color.BLACK);
+
+ mAscent = mOnlinePaint.ascent();
+ mOnlinePaint.descent();
+
+ updateDisplay();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mCurFPSHandler.removeMessages(1);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ setMeasuredDimension(resolveSize(mNeededWidth, widthMeasureSpec),
+ resolveSize(mNeededHeight, heightMeasureSpec));
+ }
+
+ private String getFPSInfoString() {
+ return mFps;
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (!mDataAvail) {
+ return;
+ }
+
+ final int LEFT = getWidth() - 1;
+
+ int y = mPaddingTop - (int) mAscent;
+
+ String s = getFPSInfoString();
+ canvas.drawText(s, LEFT - mPaddingLeft - mMaxWidth,
+ y - 1, mOnlinePaint);
+ }
+
+ void updateDisplay() {
+ if (!mDataAvail) {
+ return;
+ }
+
+ if (mOnlinePaint != null) {
+ mMaxWidth = (int) mOnlinePaint.measureText(mFps);
+ }
+
+ int neededWidth = mPaddingLeft + mPaddingRight + mMaxWidth;
+ int neededHeight = mPaddingTop + mPaddingBottom + 40;
+ if (neededWidth != mNeededWidth || neededHeight != mNeededHeight) {
+ mNeededWidth = neededWidth;
+ mNeededHeight = neededHeight;
+ requestLayout();
+ } else {
+ invalidate();
+ }
+ }
+
+ public Handler getHandler() {
+ return mCurFPSHandler;
+ }
+ }
+
+ /**
+ * Thead to monitor fps
+ */
+ protected static class CurFPSThread extends Thread {
+ private boolean mInterrupt = false;
+ private final Handler mHandler;
+
+ public CurFPSThread(Handler handler) {
+ mHandler = handler;
+ }
+
+ public void interrupt() {
+ mInterrupt = true;
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (!mInterrupt) {
+ sleep(500);
+ new StringBuilder();
+ String fpsVal = String.valueOf(Math.round(surfaceFlingerFPS.getFps()));
+ mHandler.sendMessage(mHandler.obtainMessage(1, fpsVal));
+ }
+ } catch (InterruptedException ignored) {
+ }
+ }
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ mView = new FPSView(this);
+ WindowManager.LayoutParams params = new WindowManager.LayoutParams(
+ WindowManager.LayoutParams.WRAP_CONTENT,
+ WindowManager.LayoutParams.WRAP_CONTENT,
+ WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
+ WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
+ PixelFormat.TRANSLUCENT);
+ params.y = 50;
+ params.gravity = Gravity.START | Gravity.TOP;
+ params.setTitle("FPS Info");
+ surfaceFlingerFPS = SurfaceFlingerFPS.getInstance();
+ startThread();
+
+ mDreamManager = IDreamManager.Stub.asInterface(
+ ServiceManager.checkService(DreamService.DREAM_SERVICE));
+ IntentFilter screenStateFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
+ screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
+ registerReceiver(mScreenStateReceiver, screenStateFilter);
+
+ WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
+ wm.addView(mView, params);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ stopThread();
+ ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mView);
+ mView = null;
+ unregisterReceiver(mScreenStateReceiver);
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ private final BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
+ Log.d(TAG, "ACTION_SCREEN_ON " + isDozeMode());
+ if (!isDozeMode()) {
+ startThread();
+ mView.setVisibility(View.VISIBLE);
+ }
+ } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
+ Log.d(TAG, "ACTION_SCREEN_OFF");
+ mView.setVisibility(View.GONE);
+ stopThread();
+ }
+ }
+ };
+
+ /**
+ * Find is the device is in doze mode
+ * @return true if device is in doze mode, else false
+ */
+ private boolean isDozeMode() {
+ try {
+ if (mDreamManager != null && mDreamManager.isDreaming()) {
+ return true;
+ }
+ } catch (RemoteException e) {
+ return false;
+ }
+ return false;
+ }
+
+ private void startThread() {
+ Log.d(TAG, "started CurFPSThread");
+ mCurFPSThread = new CurFPSThread(mView.getHandler());
+ surfaceFlingerFPS.start();
+ mCurFPSThread.start();
+ }
+
+ private void stopThread() {
+ if (mCurFPSThread != null && mCurFPSThread.isAlive()) {
+ Log.d(TAG, "stopping CurFPSThread");
+ surfaceFlingerFPS.stop();
+ mCurFPSThread.interrupt();
+ try {
+ mCurFPSThread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ mCurFPSThread = null;
+ }
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/FPSTileService.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/FPSTileService.java
new file mode 100644
index 0000000..392c7f4
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/FPSTileService.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 Xiaomi-SM6250 Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.eurekateam.samsungextras;
+
+import android.app.ActivityManager;
+import android.content.Intent;
+import android.service.quicksettings.Tile;
+import android.service.quicksettings.TileService;
+
+// TODO: Add FPS drawables
+public class FPSTileService extends TileService {
+
+ private boolean isShowing = false;
+
+ public FPSTileService() { }
+
+ @Override
+ public void onStartListening() {
+ super.onStartListening();
+ ActivityManager manager =
+ (ActivityManager) getSystemService(ACTIVITY_SERVICE);
+ for (ActivityManager.RunningServiceInfo service :
+ manager.getRunningServices(Integer.MAX_VALUE)) {
+ if (FPSInfoService.class.getName().equals(
+ service.service.getClassName())) {
+ isShowing = true;
+ }
+ }
+ updateTile();
+ }
+
+ @Override
+ public void onClick() {
+ Intent fpsinfo = new Intent(this, FPSInfoService.class);
+ if (!isShowing)
+ this.startService(fpsinfo);
+ else
+ this.stopService(fpsinfo);
+ isShowing = !isShowing;
+ updateTile();
+ }
+
+ /**
+ * Update tile
+ */
+ private void updateTile() {
+ final Tile tile = getQsTile();
+ tile.setState(isShowing ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
+ tile.updateTile();
+ }
+
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/GlobalConstants.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/GlobalConstants.java
new file mode 100644
index 0000000..4d3c06d
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/GlobalConstants.java
@@ -0,0 +1,26 @@
+package com.eurekateam.samsungextras;
+
+public class GlobalConstants {
+ /**
+ * Global Variables
+ */
+ public static final String FLASHLIGHT_SYSFS = "/sys/class/camera/flash/" +
+ "torch_brightness_lvl";
+ public static final String FLASHLIGHT_SYSFS_ENABLE = "/sys/class/camera/" +
+ "flash/torch_brightness_lvl_enable";
+ public static final String TMU_SYSFS = "/sys/devices/platform/11500000.mali/tmu";
+ public static final String TAG = "SamsungExtras";
+ public static final String FASTCHARGE_SYSFS = "/sys/class/sec/switch/afc_disable";
+ public static final String CHARGE_DISABLE_SYSFS = "/sys/devices/platform/battery/" +
+ "power_supply/battery/batt_slate_mode";
+ public static final String BATTERY_CAPACITY_MAX_SYSFS = "/sys/devices/platform/battery/"
+ + "power_supply/battery/charge_full";
+ public static final String BATTERY_TEMP_SYSFS = "/sys/devices/platform/battery/"
+ + "power_supply/battery/batt_temp";
+ public static final String BATTERY_CAPACITY_CURRENT_SYSFS = "/sys/devices/platform/battery/"
+ + "power_supply/battery/capacity";
+ public static final String BATTERY_CURRENT_SYSFS = "/sys/devices/platform/battery/"
+ + "power_supply/battery/current_now";
+ public static final String BATTERY_TIME_TO_FULL_SYSFS = "/sys/devices/platform/battery/"
+ + "power_supply/battery/time_to_full_now";
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/SamsungPartsTile.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/SamsungPartsTile.java
new file mode 100644
index 0000000..94fb2ed
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/SamsungPartsTile.java
@@ -0,0 +1,20 @@
+package com.eurekateam.samsungextras;
+
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.service.quicksettings.TileService;
+
+public class SamsungPartsTile extends TileService {
+ @Override
+ public void onClick() {
+ try {
+ Intent intent = new Intent(this, DeviceSettingsActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivityAndCollapse(intent);
+ } catch (ActivityNotFoundException ignored) {
+ // At this point, the app is most likely hidden and set to only open from Settings
+ Intent intent = new Intent(this, DeviceSettings.class);
+ startActivityAndCollapse(intent);
+ }
+ }
+}
\ No newline at end of file
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/Startup.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/Startup.java
new file mode 100644
index 0000000..6ce2eb7
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/Startup.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 The OmniROM Project
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+package com.eurekateam.samsungextras;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+
+import androidx.preference.PreferenceManager;
+
+public class Startup extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(final Context context, final Intent bootintent) {
+ boolean enabled;
+ SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
+ enabled = sharedPrefs.getBoolean(DeviceSettings.PREF_KEY_FPS_INFO, false);
+ if (enabled) {
+ context.startService(new Intent(context, FPSInfoService.class));
+ }
+ }
+
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/SurfaceFlingerFPS.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/SurfaceFlingerFPS.java
new file mode 100644
index 0000000..3694222
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/SurfaceFlingerFPS.java
@@ -0,0 +1,182 @@
+package com.eurekateam.samsungextras;
+
+
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.ServiceManager;
+
+/*
+ * Copyright (C) 2020-2021 Samsung Electronics Co. Ltd
+ * This Class is based on Samsung's OneUI 3.1
+ * /system/frameworks/gamesdk.jar
+ */
+public class SurfaceFlingerFPS {
+ private double mFps;
+ private final Object mLock;
+ private long mPrevFPSCheckStartTime;
+ private int mPrevFlipCount;
+ private double mPrevFps;
+ public boolean running;
+ private long mPrevPrevCheckStartTime;
+ private int mPrevPrevFlipCount;
+ private volatile boolean mSkipUpdate;
+ private volatile boolean mStopThread;
+ private ThreadGetFlip mThread;
+
+ private SurfaceFlingerFPS() {
+ this.mThread = null;
+ this.mStopThread = false;
+ this.mSkipUpdate = false;
+ this.mLock = new Object();
+ this.mFps = 0.0d;
+ this.mPrevFps = 0.0d;
+ this.mPrevFlipCount = 0;
+ this.mPrevFPSCheckStartTime = 0;
+ this.mPrevPrevFlipCount = 0;
+ this.mPrevPrevCheckStartTime = 0;
+ }
+
+ /**
+ * Starts the thread
+ */
+ public void start() {
+ synchronized (this) {
+ if (this.mThread == null || this.mStopThread) {
+ this.mStopThread = false;
+ ThreadGetFlip threadGetFlip = new ThreadGetFlip();
+ this.mThread = threadGetFlip;
+ threadGetFlip.start();
+ running = true;
+ }
+ }
+ }
+
+ /**
+ * Stops the thread
+ */
+ public void stop() {
+ synchronized (this) {
+ this.mStopThread = true;
+ if (this.mThread != null) {
+ this.mThread.interrupt();
+ }
+ this.mThread = null;
+ running = false;
+ }
+ }
+
+ /**
+ * Check if the fps monitor is able to start
+ * @return true if able to start, else false
+ */
+ private boolean isAvailable() {
+ return this.mStopThread || this.mThread == null;
+ }
+
+ private void updateCurrentFps() {
+ try {
+ synchronized (this.mLock) {
+ this.mSkipUpdate = true;
+ long curTime = System.currentTimeMillis();
+ int curFlipCount = getFlipCount();
+ if (curTime - this.mPrevFPSCheckStartTime < 200) {
+ this.mFps = ((double) (curFlipCount - this.mPrevPrevFlipCount)) / (((double) (curTime - this.mPrevPrevCheckStartTime)) / 1000.0d);
+ } else {
+ this.mFps = ((double) (curFlipCount - this.mPrevFlipCount)) / (((double) (curTime - this.mPrevFPSCheckStartTime)) / 1000.0d);
+ }
+ if (this.mFps < 1.0d) {
+ this.mFps = this.mPrevFps;
+ }
+ this.mPrevFlipCount = curFlipCount;
+ this.mPrevFPSCheckStartTime = curTime;
+ this.mPrevFps = this.mFps;
+ this.mSkipUpdate = false;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Gets the fps value from internal thread
+ * @return fps value in Double
+ */
+ public double getFps() {
+ if (isAvailable()) {
+ return -999.0d;
+ }
+ updateCurrentFps();
+ return this.mFps;
+ }
+
+ /**
+ * Gets the flip count from SurfaceFlinger Service
+ * @return flip count
+ */
+ private int getFlipCount() {
+ int flipCount = -1;
+ try {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ try {
+ IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
+ data.writeInterfaceToken("android.ui.ISurfaceComposer");
+ if (surfaceFlinger != null && surfaceFlinger.transact(1013, data, reply, 0)) {
+ flipCount = reply.readInt();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ data.recycle();
+ reply.recycle();
+ } catch (Exception e2) {
+ e2.printStackTrace();
+ }
+ return flipCount;
+ }
+
+ /* access modifiers changed from: private */
+
+ public void updateFlipCountRecord() {
+ try {
+ synchronized (this.mLock) {
+ this.mPrevPrevCheckStartTime = this.mPrevFPSCheckStartTime;
+ this.mPrevPrevFlipCount = this.mPrevFlipCount;
+ this.mPrevFPSCheckStartTime = System.currentTimeMillis();
+ this.mPrevFlipCount = getFlipCount();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /* access modifiers changed from: private */
+ /* loaded from: classes.dex */
+ public class ThreadGetFlip extends Thread {
+ private ThreadGetFlip() {
+ }
+
+ @Override // java.lang.Thread, java.lang.Runnable
+ public void run() {
+ while (!SurfaceFlingerFPS.this.mStopThread) {
+ if (!SurfaceFlingerFPS.this.mSkipUpdate) {
+ SurfaceFlingerFPS.this.updateFlipCountRecord();
+ try {
+ Thread.sleep(300);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Gets an instance of this class
+ * @return new instance
+ */
+ public static SurfaceFlingerFPS getInstance(){
+ return new SurfaceFlingerFPS();
+ }
+
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/battery/BatteryActivity.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/battery/BatteryActivity.java
new file mode 100644
index 0000000..b3a7bb1
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/battery/BatteryActivity.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 Paranoid Android
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.eurekateam.samsungextras.battery;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.MenuItem;
+
+import androidx.fragment.app.FragmentActivity;
+
+public class BatteryActivity extends FragmentActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+
+ Fragment fragment = getFragmentManager().findFragmentById(android.R.id.content);
+ BatteryFragment batteryFragment;
+ if (fragment == null) {
+ batteryFragment = new BatteryFragment();
+ getFragmentManager().beginTransaction()
+ .add(android.R.id.content, batteryFragment)
+ .commit();
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/battery/BatteryFragment.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/battery/BatteryFragment.java
new file mode 100644
index 0000000..77c6bb7
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/battery/BatteryFragment.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2020 Paranoid Android
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.eurekateam.samsungextras.battery;
+
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.widget.Toast;
+
+import androidx.preference.ListPreference;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragment;
+import androidx.preference.SwitchPreference;
+
+import com.eurekateam.samsungextras.GlobalConstants;
+import com.eurekateam.samsungextras.R;
+import com.eurekateam.samsungextras.utils.FileUtilsWrapper;
+
+public class BatteryFragment extends PreferenceFragment implements
+ Preference.OnPreferenceChangeListener {
+ private static final String PREF_FASTCHARGE = "fastcharge_pref";
+ private static final String PREF_CHARGE = "charge_pref";
+ private static final String BATTERY_INFO = "battery_info";
+ private SwitchPreference mFastChargePref;
+ private SwitchPreference mChargePref;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ addPreferencesFromResource(R.xml.battery_settings);
+ mFastChargePref = findPreference(PREF_FASTCHARGE);
+ assert mFastChargePref != null;
+ mFastChargePref.setOnPreferenceChangeListener(this);
+ mFastChargePref.setEnabled(FileUtilsWrapper.
+ fileExists(GlobalConstants.FASTCHARGE_SYSFS));
+ if (FileUtilsWrapper.isFileReadable(GlobalConstants.FLASHLIGHT_SYSFS)){
+ Log.d(GlobalConstants.TAG, "onCreatePreferences: " +
+ GlobalConstants.FASTCHARGE_SYSFS + " readable, value " +
+ FileUtilsWrapper.readOneLine(GlobalConstants.FASTCHARGE_SYSFS));
+ mFastChargePref.setChecked(FileUtilsWrapper.readOneLine
+ (GlobalConstants.FASTCHARGE_SYSFS).equals("0"));
+ }else{
+ Log.w(GlobalConstants.TAG, "onCreatePreferences: " +
+ GlobalConstants.FLASHLIGHT_SYSFS + " not readable");
+ mFastChargePref.setEnabled(false);
+ }
+ mChargePref = findPreference(PREF_CHARGE);
+ assert mChargePref != null;
+ mChargePref.setOnPreferenceChangeListener(this);
+ mChargePref.setEnabled(FileUtilsWrapper.
+ fileExists(GlobalConstants.CHARGE_DISABLE_SYSFS));
+ if (FileUtilsWrapper.isFileReadable(GlobalConstants.CHARGE_DISABLE_SYSFS)){
+ Log.d(GlobalConstants.TAG, "onCreatePreferences: " +
+ GlobalConstants.CHARGE_DISABLE_SYSFS + " readable, value " +
+ FileUtilsWrapper.readOneLine(GlobalConstants.CHARGE_DISABLE_SYSFS));
+ mChargePref.setChecked(FileUtilsWrapper.readOneLine
+ (GlobalConstants.CHARGE_DISABLE_SYSFS).equals("0"));
+ }else{
+ Log.w(GlobalConstants.TAG, "onCreatePreferences: " +
+ GlobalConstants.FLASHLIGHT_SYSFS + " not readable");
+ mFastChargePref.setEnabled(false);
+ }
+ ListPreference mBatteryInfo = findPreference(BATTERY_INFO);
+ CharSequence[] items = {
+ Integer.parseInt(FileUtilsWrapper.readOneLine(GlobalConstants.BATTERY_CAPACITY_MAX_SYSFS)) / 1000 + " mAh",
+ FileUtilsWrapper.readOneLine(GlobalConstants.BATTERY_CAPACITY_CURRENT_SYSFS) + " %",
+ Float.parseFloat(FileUtilsWrapper.readOneLine(GlobalConstants.BATTERY_CAPACITY_MAX_SYSFS)) *
+ Float.parseFloat(FileUtilsWrapper.readOneLine(GlobalConstants.BATTERY_CAPACITY_CURRENT_SYSFS)) / 100000 + " mAh" ,
+ FileUtilsWrapper.readOneLine(GlobalConstants.BATTERY_CURRENT_SYSFS) + " mAh",
+ Integer.parseInt(FileUtilsWrapper.readOneLine(GlobalConstants.BATTERY_CURRENT_SYSFS)) >= 0
+ ? "Charging" : "Discharging",
+ Float.parseFloat(FileUtilsWrapper.readOneLine(GlobalConstants.BATTERY_TEMP_SYSFS)) / 10 + " \u2103",
+ };
+ assert mBatteryInfo != null;
+ mBatteryInfo.setEntryValues(items);
+ mBatteryInfo.setOnPreferenceChangeListener((preference, newValue) -> {
+ Toast.makeText(getContext(), (String) newValue, Toast.LENGTH_SHORT).show();
+ return true;
+ });
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mFastChargePref) {
+ Boolean value = (Boolean) newValue;
+ Log.d(GlobalConstants.TAG, "onPreferenceChange: writing " + value + " to " +
+ GlobalConstants.FASTCHARGE_SYSFS);
+ FileUtilsWrapper.writeLine(GlobalConstants.FASTCHARGE_SYSFS, value ? "0" : "1");
+ mFastChargePref.setChecked(FileUtilsWrapper.readOneLine
+ (GlobalConstants.FASTCHARGE_SYSFS).equals("0"));
+ return true;
+ }else if (preference == mChargePref){
+ Boolean value = (Boolean) newValue;
+ Log.d(GlobalConstants.TAG, "onPreferenceChange: writing " + value
+ + " to " + GlobalConstants.CHARGE_DISABLE_SYSFS);
+ FileUtilsWrapper.writeLine(GlobalConstants.CHARGE_DISABLE_SYSFS, value ? "0" : "1");
+ mChargePref.setChecked(FileUtilsWrapper.readOneLine
+ (GlobalConstants.CHARGE_DISABLE_SYSFS).equals("0"));
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/flashlight/FlashLightActivity.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/flashlight/FlashLightActivity.java
new file mode 100644
index 0000000..91cd4bf
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/flashlight/FlashLightActivity.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 Paranoid Android
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.eurekateam.samsungextras.flashlight;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.MenuItem;
+
+import androidx.fragment.app.FragmentActivity;
+
+public class FlashLightActivity extends FragmentActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+
+ Fragment fragment = getFragmentManager().findFragmentById(android.R.id.content);
+ FlashLightFragment flashLightFragment;
+ if (fragment == null) {
+ flashLightFragment = new FlashLightFragment();
+ getFragmentManager().beginTransaction()
+ .add(android.R.id.content, flashLightFragment)
+ .commit();
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/flashlight/FlashLightFragment.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/flashlight/FlashLightFragment.java
new file mode 100644
index 0000000..3c5337b
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/flashlight/FlashLightFragment.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 Paranoid Android
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.eurekateam.samsungextras.flashlight;
+
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragment;
+
+import com.eurekateam.samsungextras.GlobalConstants;
+import com.eurekateam.samsungextras.R;
+import com.eurekateam.samsungextras.preferences.CustomSeekBarPreference;
+import com.eurekateam.samsungextras.utils.FileUtilsWrapper;
+import com.eurekateam.samsungextras.utils.SystemProperties;
+
+public class FlashLightFragment extends PreferenceFragment implements
+ Preference.OnPreferenceChangeListener {
+ private static int divideprefix = 21;
+ private static final String PREF_FLASHLIGHT = "flashlight_pref";
+ private CustomSeekBarPreference mFlashLightPref;
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ addPreferencesFromResource(R.xml.flashlight_settings);
+ if (SystemProperties.read("ro.product.device").contains("a10")){
+ divideprefix = 1;
+ }
+ mFlashLightPref = findPreference(PREF_FLASHLIGHT);
+ assert mFlashLightPref != null;
+ mFlashLightPref.setOnPreferenceChangeListener(this);
+ mFlashLightPref.setMax(10);
+ mFlashLightPref.setMin(0);
+ mFlashLightPref.setEnabled(FileUtilsWrapper.
+ fileExists(GlobalConstants.FLASHLIGHT_SYSFS));
+ if (FileUtilsWrapper.isFileReadable(GlobalConstants.FLASHLIGHT_SYSFS)){
+ Log.d(GlobalConstants.TAG, "onCreatePreferences: " +
+ GlobalConstants.FLASHLIGHT_SYSFS + " readable, value " +
+ Integer.parseInt(
+ FileUtilsWrapper.readOneLine(GlobalConstants.FLASHLIGHT_SYSFS)));
+ mFlashLightPref.setValue(Integer.parseInt(
+ FileUtilsWrapper.readOneLine(GlobalConstants.FLASHLIGHT_SYSFS))
+ / divideprefix);
+ }else{
+ Log.w(GlobalConstants.TAG, "onCreatePreferences: " +
+ GlobalConstants.FLASHLIGHT_SYSFS + " not readable");
+ mFlashLightPref.setEnabled(false);
+ }
+
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mFlashLightPref) {
+ Integer value = (Integer) newValue;
+ Log.d(GlobalConstants.TAG, "onPreferenceChange: writing 1 to " +
+ GlobalConstants.FLASHLIGHT_SYSFS_ENABLE);
+ FileUtilsWrapper.writeLine(GlobalConstants.FLASHLIGHT_SYSFS_ENABLE, "1");
+ Log.d(GlobalConstants.TAG, "onPreferenceChange: writing " + value
+ + " to " + GlobalConstants.FLASHLIGHT_SYSFS);
+ FileUtilsWrapper.writeLine(GlobalConstants.FLASHLIGHT_SYSFS, String.valueOf(value));
+ mFlashLightPref.setValue(value, true);
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/CustomSeekBarPreference.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/CustomSeekBarPreference.java
new file mode 100644
index 0000000..b458d74
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/CustomSeekBarPreference.java
@@ -0,0 +1,328 @@
+package com.eurekateam.samsungextras.preferences;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.PorterDuff;
+import androidx.core.content.res.TypedArrayUtils;
+import androidx.preference.*;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.eurekateam.samsungextras.R;
+
+public class CustomSeekBarPreference extends Preference implements SeekBar.OnSeekBarChangeListener,
+ View.OnClickListener, View.OnLongClickListener {
+ protected final String TAG = getClass().getName();
+ private static final String APP_NS = "http://schemas.android.com/apk/res-auto";
+ protected static final String ANDROIDNS = "http://schemas.android.com/apk/res/android";
+
+ protected int mInterval = 1;
+ protected boolean mShowSign = false;
+ protected String mUnits = "";
+ protected boolean mContinuousUpdates = false;
+
+ protected int mMinValue = 1;
+ protected int mMaxValue = 256;
+ protected boolean mDefaultValueExists = false;
+ protected int mDefaultValue;
+
+ protected int mValue;
+
+ protected TextView mValueTextView;
+ protected ImageView mResetImageView;
+ protected ImageView mMinusImageView;
+ protected ImageView mPlusImageView;
+ protected SeekBar mSeekBar;
+
+ protected boolean mTrackingTouch = false;
+ protected int mTrackingValue;
+
+ public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomSeekBarPreference);
+ try {
+ mShowSign = a.getBoolean(R.styleable.CustomSeekBarPreference_showSign, mShowSign);
+ String units = a.getString(R.styleable.CustomSeekBarPreference_units);
+ if (units != null)
+ mUnits = " " + units;
+ mContinuousUpdates = a.getBoolean(R.styleable.CustomSeekBarPreference_continuousUpdates, mContinuousUpdates);
+ } finally {
+ a.recycle();
+ }
+
+ try {
+ String newInterval = attrs.getAttributeValue(APP_NS, "interval");
+ if (newInterval != null)
+ mInterval = Integer.parseInt(newInterval);
+ } catch (Exception e) {
+ Log.e(TAG, "Invalid interval value", e);
+ }
+ mMinValue = attrs.getAttributeIntValue(APP_NS, "min", mMinValue);
+ mMaxValue = attrs.getAttributeIntValue(ANDROIDNS, "max", mMaxValue);
+ if (mMaxValue < mMinValue)
+ mMaxValue = mMinValue;
+ String defaultValue = attrs.getAttributeValue(ANDROIDNS, "defaultValue");
+ mDefaultValueExists = defaultValue != null && !defaultValue.isEmpty();
+ if (mDefaultValueExists) {
+ mDefaultValue = getLimitedValue(Integer.parseInt(defaultValue));
+ mValue = mDefaultValue;
+ } else {
+ mValue = mMinValue;
+ }
+
+ mSeekBar = new SeekBar(context, attrs);
+ setLayoutResource(R.layout.preference_custom_seekbar);
+ }
+
+ public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public CustomSeekBarPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, TypedArrayUtils.getAttr(context,
+ androidx.preference.R.attr.preferenceStyle,
+ android.R.attr.preferenceStyle));
+ }
+
+ public CustomSeekBarPreference(Context context) {
+ this(context, null);
+ }
+
+ @Override
+ public void onBindViewHolder(PreferenceViewHolder holder) {
+ super.onBindViewHolder(holder);
+ try
+ {
+ // move our seekbar to the new view we've been given
+ ViewParent oldContainer = mSeekBar.getParent();
+ ViewGroup newContainer = (ViewGroup) holder.findViewById(R.id.seekbar);
+ if (oldContainer != newContainer) {
+ // remove the seekbar from the old view
+ if (oldContainer != null) {
+ ((ViewGroup) oldContainer).removeView(mSeekBar);
+ }
+ // remove the existing seekbar (there may not be one) and add ours
+ newContainer.removeAllViews();
+ newContainer.addView(mSeekBar, ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+ }
+ } catch (Exception ex) {
+ Log.e(TAG, "Error binding view: " + ex.toString());
+ }
+
+ mSeekBar.setMax(getSeekValue(mMaxValue));
+ mSeekBar.setProgress(getSeekValue(mValue));
+ mSeekBar.setEnabled(isEnabled());
+
+ mValueTextView = (TextView) holder.findViewById(R.id.value);
+ mResetImageView = (ImageView) holder.findViewById(R.id.reset);
+ mMinusImageView = (ImageView) holder.findViewById(R.id.minus);
+ mPlusImageView = (ImageView) holder.findViewById(R.id.plus);
+
+ updateValueViews();
+
+ mSeekBar.setOnSeekBarChangeListener(this);
+ mResetImageView.setOnClickListener(this);
+ mMinusImageView.setOnClickListener(this);
+ mPlusImageView.setOnClickListener(this);
+ mResetImageView.setOnLongClickListener(this);
+ mMinusImageView.setOnLongClickListener(this);
+ mPlusImageView.setOnLongClickListener(this);
+ }
+
+ protected int getLimitedValue(int v) {
+ return v < mMinValue ? mMinValue : (v > mMaxValue ? mMaxValue : v);
+ }
+
+ protected int getSeekValue(int v) {
+ return 0 - Math.floorDiv(mMinValue - v, mInterval);
+ }
+
+ protected String getTextValue(int v) {
+ return (mShowSign && v > 0 ? "+" : "") + String.valueOf(v) + mUnits;
+ }
+
+ protected void updateValueViews() {
+ if (mValueTextView != null) {
+ mValueTextView.setText(getContext().getString(R.string.custom_seekbar_value,
+ (!mTrackingTouch || mContinuousUpdates ? getTextValue(mValue) +
+ (mDefaultValueExists && mValue == mDefaultValue ? " (" +
+ getContext().getString(R.string.custom_seekbar_default_value) + ")" : "")
+ : getTextValue(mTrackingValue))));
+ }
+ if (mResetImageView != null) {
+ if (!mDefaultValueExists || mValue == mDefaultValue || mTrackingTouch)
+ mResetImageView.setVisibility(View.INVISIBLE);
+ else
+ mResetImageView.setVisibility(View.VISIBLE);
+ }
+ if (mMinusImageView != null) {
+ if (mValue == mMinValue || mTrackingTouch) {
+ mMinusImageView.setClickable(false);
+ mMinusImageView.setColorFilter(getContext().getColor(R.color.disabled_text_color),
+ PorterDuff.Mode.MULTIPLY);
+ } else {
+ mMinusImageView.setClickable(true);
+ mMinusImageView.clearColorFilter();
+ }
+ }
+ if (mPlusImageView != null) {
+ if (mValue == mMaxValue || mTrackingTouch) {
+ mPlusImageView.setClickable(false);
+ mPlusImageView.setColorFilter(getContext().getColor(R.color.disabled_text_color), PorterDuff.Mode.MULTIPLY);
+ } else {
+ mPlusImageView.setClickable(true);
+ mPlusImageView.clearColorFilter();
+ }
+ }
+ }
+
+ protected void changeValue(int newValue) {
+ // for subclasses
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ int newValue = getLimitedValue(mMinValue + (progress * mInterval));
+ if (mTrackingTouch && !mContinuousUpdates) {
+ mTrackingValue = newValue;
+ updateValueViews();
+ } else if (mValue != newValue) {
+ // change rejected, revert to the previous value
+ if (!callChangeListener(newValue)) {
+ mSeekBar.setProgress(getSeekValue(mValue));
+ return;
+ }
+ // change accepted, store it
+ changeValue(newValue);
+ persistInt(newValue);
+
+ mValue = newValue;
+ updateValueViews();
+ }
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ mTrackingValue = mValue;
+ mTrackingTouch = true;
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ mTrackingTouch = false;
+ if (!mContinuousUpdates)
+ onProgressChanged(mSeekBar, getSeekValue(mTrackingValue), false);
+ notifyChanged();
+ }
+
+ @Override
+ public void onClick(View v) {
+ int id = v.getId();
+ if (id == R.id.reset) {
+ Toast.makeText(getContext(), getContext().getString(R.string.custom_seekbar_default_value_to_set, getTextValue(mDefaultValue)),
+ Toast.LENGTH_LONG).show();
+ } else if (id == R.id.minus) {
+ setValue(mValue - mInterval, true);
+ } else if (id == R.id.plus) {
+ setValue(mValue + mInterval, true);
+ }
+ }
+
+ @Override
+ public boolean onLongClick(View v) {
+ int id = v.getId();
+ if (id == R.id.reset) {
+ setValue(mDefaultValue, true);
+ //Toast.makeText(getContext(), getContext().getString(R.string.custom_seekbar_default_value_is_set),
+ // Toast.LENGTH_LONG).show();
+ } else if (id == R.id.minus) {
+ setValue(mMaxValue - mMinValue > mInterval * 2 && mMaxValue + mMinValue < mValue * 2 ? Math.floorDiv(mMaxValue + mMinValue, 2) : mMinValue, true);
+ } else if (id == R.id.plus) {
+ setValue(mMaxValue - mMinValue > mInterval * 2 && mMaxValue + mMinValue > mValue * 2 ? -1 * Math.floorDiv(-1 * (mMaxValue + mMinValue), 2) : mMaxValue, true);
+ }
+ return true;
+ }
+
+ // dont need too much shit about initial and default values
+ // its all done in constructor already
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ if (restoreValue)
+ mValue = getPersistedInt(mValue);
+ }
+
+ @Override
+ public void setDefaultValue(Object defaultValue) {
+ if (defaultValue instanceof Integer)
+ setDefaultValue((Integer) defaultValue, mSeekBar != null);
+ else
+ setDefaultValue(defaultValue == null ? (String) null : defaultValue.toString(), mSeekBar != null);
+ }
+
+ public void setDefaultValue(int newValue, boolean update) {
+ newValue = getLimitedValue(newValue);
+ if (!mDefaultValueExists || mDefaultValue != newValue) {
+ mDefaultValueExists = true;
+ mDefaultValue = newValue;
+ if (update)
+ updateValueViews();
+ }
+ }
+
+ public void setDefaultValue(String newValue, boolean update) {
+ if (mDefaultValueExists && (newValue == null || newValue.isEmpty())) {
+ mDefaultValueExists = false;
+ if (update)
+ updateValueViews();
+ } else if (newValue != null && !newValue.isEmpty()) {
+ setDefaultValue(Integer.parseInt(newValue), update);
+ }
+ }
+
+ public void setMax(int max) {
+ mMaxValue = max;
+ mSeekBar.setMax(mMaxValue - mMinValue);
+ }
+
+ public void setMin(int min) {
+ mMinValue = min;
+ mSeekBar.setMax(mMaxValue - mMinValue);
+ }
+
+ public void setValue(int newValue) {
+ mValue = getLimitedValue(newValue);
+ if (mSeekBar != null) mSeekBar.setProgress(getSeekValue(mValue));
+ }
+
+ public void setValue(int newValue, boolean update) {
+ newValue = getLimitedValue(newValue);
+ if (mValue != newValue) {
+ if (update)
+ mSeekBar.setProgress(getSeekValue(newValue));
+ else
+ mValue = newValue;
+ }
+ }
+
+ public int getValue() {
+ return mValue;
+ }
+
+ // need some methods here to set/get other attrs at runtime,
+ // but who really need this ...
+
+ public void refresh(int newValue) {
+ // this will ...
+ setValue(newValue, mSeekBar != null);
+ }
+}
\ No newline at end of file
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/SecureSettingCustomSeekBarPreference.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/SecureSettingCustomSeekBarPreference.java
new file mode 100644
index 0000000..4f8a46e
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/SecureSettingCustomSeekBarPreference.java
@@ -0,0 +1,29 @@
+package com.eurekateam.samsungextras.preferences;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.eurekateam.samsungextras.preferences.SecureSettingsStore;
+
+public class SecureSettingCustomSeekBarPreference extends com.eurekateam.samsungextras.preferences.CustomSeekBarPreference {
+
+ public SecureSettingCustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
+ }
+
+ public SecureSettingCustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
+ }
+
+ public SecureSettingCustomSeekBarPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
+ }
+
+ public SecureSettingCustomSeekBarPreference(Context context) {
+ super(context);
+ setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
+ }
+}
\ No newline at end of file
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/SecureSettingListPreference.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/SecureSettingListPreference.java
new file mode 100644
index 0000000..17aa9fb
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/SecureSettingListPreference.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 AICP
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.eurekateam.samsungextras.preferences;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+
+import androidx.preference.ListPreference;
+
+public class SecureSettingListPreference extends ListPreference {
+ private boolean mAutoSummary = false;
+
+ public SecureSettingListPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
+ }
+
+ public SecureSettingListPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
+ }
+
+ public SecureSettingListPreference(Context context) {
+ super(context);
+ setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
+ }
+
+ @Override
+ public void setValue(String value) {
+ super.setValue(value);
+ if (mAutoSummary || TextUtils.isEmpty(getSummary())) {
+ setSummary(getEntry(), true);
+ }
+ }
+
+ @Override
+ public void setSummary(CharSequence summary) {
+ setSummary(summary, false);
+ }
+
+ private void setSummary(CharSequence summary, boolean autoSummary) {
+ mAutoSummary = autoSummary;
+ super.setSummary(summary);
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ // This is what default ListPreference implementation is doing without respecting
+ // real default value:
+ //setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue);
+ // Instead, we better do
+ setValue(restoreValue ? getPersistedString((String) defaultValue) : (String) defaultValue);
+ }
+
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/SecureSettingSwitchPreference.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/SecureSettingSwitchPreference.java
new file mode 100644
index 0000000..aa49f83
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/SecureSettingSwitchPreference.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 The CyanogenMod project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.eurekateam.samsungextras.preferences;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.util.AttributeSet;
+
+import androidx.preference.SwitchPreference;
+
+public class SecureSettingSwitchPreference extends SwitchPreference {
+ public SecureSettingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
+ }
+
+ public SecureSettingSwitchPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
+ }
+
+ public SecureSettingSwitchPreference(Context context) {
+ super(context);
+ setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
+ }
+
+ @Override
+ protected boolean persistBoolean(boolean value) {
+ if (shouldPersist()) {
+ if (value == getPersistedBoolean(!value)) {
+ // It's already there, so the same as persisting
+ return true;
+ }
+ Settings.Secure.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean getPersistedBoolean(boolean defaultReturnValue) {
+ if (!shouldPersist()) {
+ return defaultReturnValue;
+ }
+ return Settings.Secure.getInt(getContext().getContentResolver(),
+ getKey(), defaultReturnValue ? 1 : 0) != 0;
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setChecked(Settings.Secure.getString(getContext().getContentResolver(), getKey()) != null ? getPersistedBoolean(isChecked())
+ : (Boolean) defaultValue);
+ }
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/SecureSettingsStore.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/SecureSettingsStore.java
new file mode 100644
index 0000000..5b7eb91
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/preferences/SecureSettingsStore.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2017 AICP
+ * Copyright (C) 2018 CarbonROM
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.eurekateam.samsungextras.preferences;
+
+import android.content.ContentResolver;
+import android.preference.PreferenceDataStore;
+import android.provider.Settings;
+
+public class SecureSettingsStore extends androidx.preference.PreferenceDataStore
+ implements PreferenceDataStore {
+
+ private final ContentResolver mContentResolver;
+
+ public SecureSettingsStore(ContentResolver contentResolver) {
+ mContentResolver = contentResolver;
+ }
+
+ public boolean getBoolean(String key, boolean defValue) {
+ return getInt(key, defValue ? 1 : 0) != 0;
+ }
+
+ public float getFloat(String key, float defValue) {
+ return Settings.Secure.getFloat(mContentResolver, key, defValue);
+ }
+
+ public int getInt(String key, int defValue) {
+ return Settings.Secure.getInt(mContentResolver, key, defValue);
+ }
+
+ public long getLong(String key, long defValue) {
+ return Settings.Secure.getLong(mContentResolver, key, defValue);
+ }
+
+ public String getString(String key, String defValue) {
+ String result = Settings.Secure.getString(mContentResolver, key);
+ return result == null ? defValue : result;
+ }
+
+ public void putBoolean(String key, boolean value) {
+ putInt(key, value ? 1 : 0);
+ }
+
+ public void putFloat(String key, float value) {
+ Settings.Secure.putFloat(mContentResolver, key, value);
+ }
+
+ public void putInt(String key, int value) {
+ Settings.Secure.putInt(mContentResolver, key, value);
+ }
+
+ public void putLong(String key, long value) {
+ Settings.Secure.putLong(mContentResolver, key, value);
+ }
+
+ public void putString(String key, String value) {
+ Settings.Secure.putString(mContentResolver, key, value);
+ }
+
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/speaker/ClearSpeakerActivity.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/speaker/ClearSpeakerActivity.java
new file mode 100644
index 0000000..10280a5
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/speaker/ClearSpeakerActivity.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 Paranoid Android
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.eurekateam.samsungextras.speaker;
+
+import androidx.fragment.app.FragmentActivity;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.MenuItem;
+
+public class ClearSpeakerActivity extends FragmentActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+
+ Fragment fragment = getFragmentManager().findFragmentById(android.R.id.content);
+ ClearSpeakerFragment clearSpeakerFragment;
+ if (fragment == null) {
+ clearSpeakerFragment = new ClearSpeakerFragment();
+ getFragmentManager().beginTransaction()
+ .add(android.R.id.content, clearSpeakerFragment)
+ .commit();
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == android.R.id.home) {
+ finish();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/speaker/ClearSpeakerFragment.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/speaker/ClearSpeakerFragment.java
new file mode 100644
index 0000000..3cdbc51
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/speaker/ClearSpeakerFragment.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2020 Paranoid Android
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.eurekateam.samsungextras.speaker;
+
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceFragment;
+import androidx.preference.SwitchPreference;
+
+import com.eurekateam.samsungextras.R;
+
+import java.io.IOException;
+
+public class ClearSpeakerFragment extends PreferenceFragment implements
+ Preference.OnPreferenceChangeListener {
+
+ private static final String TAG = ClearSpeakerFragment.class.getSimpleName();
+
+ private static final String PREF_CLEAR_SPEAKER = "clear_speaker_pref";
+
+ private AudioManager mAudioManager;
+ private Handler mHandler;
+ private MediaPlayer mMediaPlayer;
+ private SwitchPreference mClearSpeakerPref;
+
+ @Override
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+ addPreferencesFromResource(R.xml.clear_speaker_settings);
+
+ mClearSpeakerPref = findPreference(PREF_CLEAR_SPEAKER);
+ mClearSpeakerPref.setOnPreferenceChangeListener(this);
+
+ mHandler = new Handler();
+ mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mClearSpeakerPref) {
+ boolean value = (Boolean) newValue;
+ if (value) {
+ if (startPlaying()) {
+ mHandler.removeCallbacksAndMessages(null);
+ mHandler.postDelayed(this::stopPlaying, 30000);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void onStop() {
+ stopPlaying();
+ super.onStop();
+ }
+
+ /**
+ * Start playing speaker-clearing audio
+ * @return true on success, else false
+ */
+ public boolean startPlaying() {
+ mAudioManager.setParameters("status_earpiece_clean=on");
+ mMediaPlayer = new MediaPlayer();
+ getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC);
+ mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+ mMediaPlayer.setLooping(true);
+ try {
+ try (AssetFileDescriptor file = getResources().openRawResourceFd(R.raw.clear_speaker_sound)) {
+ mMediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
+ }
+ mClearSpeakerPref.setEnabled(false);
+ mMediaPlayer.setVolume(1.0f, 1.0f);
+ mMediaPlayer.prepare();
+ mMediaPlayer.start();
+ } catch (IOException ioe) {
+ Log.e(TAG, "Failed to play speaker clean sound!", ioe);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Stops and invalidates
+ */
+ public void stopPlaying() {
+ if (mMediaPlayer != null) {
+ mMediaPlayer.stop();
+ mMediaPlayer.reset();
+ mMediaPlayer.release();
+ }
+ mAudioManager.setParameters("status_earpiece_clean=off");
+ mClearSpeakerPref.setEnabled(true);
+ mClearSpeakerPref.setChecked(false);
+ }
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/utils/FileUtilsWrapper.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/utils/FileUtilsWrapper.java
new file mode 100644
index 0000000..be7b825
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/utils/FileUtilsWrapper.java
@@ -0,0 +1,120 @@
+package com.eurekateam.samsungextras.utils;
+
+/*
+ * Copyright (C) 2016 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import android.os.FileUtils;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+
+
+public final class FileUtilsWrapper {
+ private static final String TAG = "FileUtils";
+
+ /**
+ * Reads the first line of text from the given file.
+ * Reference {@link FileUtils} for clarification on what a line is
+ *
+ */
+ public static String readOneLine(String fileName){
+ try {
+ return FileUtils.readTextFile(new File(fileName),0,null)
+ .replaceAll("[\n]","");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+ /**
+ * Writes the given value into the given file
+ *
+ */
+ public static void writeLine(String fileName, String value){
+ try {
+ FileUtils.stringToFile(fileName,value);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Checks whether the given file exists
+ *
+ * @return true if exists, false if not
+ */
+ public static boolean fileExists(String fileName) {
+ final File file = new File(fileName);
+ return file.exists();
+ }
+
+ /**
+ * Checks whether the given file is readable
+ *
+ * @return true if readable, false if not
+ */
+ public static boolean isFileReadable(String fileName) {
+ final File file = new File(fileName);
+ return file.exists() && file.canRead();
+ }
+
+ /**
+ * Checks whether the given file is writable
+ *
+ * @return true if writable, false if not
+ */
+ public static boolean isFileWritable(String fileName) {
+ final File file = new File(fileName);
+ return file.exists() && file.canWrite();
+ }
+
+ /**
+ * Deletes an existing file
+ *
+ * @return true if the delete was successful, false if not
+ */
+ public static boolean delete(String fileName) {
+ final File file = new File(fileName);
+ boolean ok = false;
+ try {
+ ok = file.delete();
+ } catch (SecurityException e) {
+ Log.w(TAG, "SecurityException trying to delete " + fileName, e);
+ }
+ return ok;
+ }
+
+ /**
+ * Renames an existing file
+ *
+ * @return true if the rename was successful, false if not
+ */
+ public static boolean rename(String srcPath, String dstPath) {
+ final File srcFile = new File(srcPath);
+ final File dstFile = new File(dstPath);
+ boolean ok = false;
+ try {
+ ok = srcFile.renameTo(dstFile);
+ } catch (SecurityException e) {
+ Log.w(TAG, "SecurityException trying to rename " + srcPath + " to " + dstPath, e);
+ } catch (NullPointerException e) {
+ Log.e(TAG, "NullPointerException trying to rename " + srcPath + " to " + dstPath, e);
+ }
+ return ok;
+ }
+}
diff --git a/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/utils/SystemProperties.java b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/utils/SystemProperties.java
new file mode 100644
index 0000000..20b1afe
--- /dev/null
+++ b/universal7885-common/SamsungParts/src/com/eurekateam/samsungextras/utils/SystemProperties.java
@@ -0,0 +1,75 @@
+package com.eurekateam.samsungextras.utils;
+
+import android.util.Log;
+
+import com.eurekateam.samsungextras.GlobalConstants;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+public class SystemProperties {
+
+ /**
+ * To read a prop using getprop
+ * @param propName the prop name to get
+ * @return the prop's value, empty string is not found
+ */
+ public static String read(String propName) {
+ Process process = null;
+ BufferedReader bufferedReader = null;
+
+ String TAG = GlobalConstants.TAG;
+ try {
+ String GETPROP_EXECUTABLE_PATH = "/system/bin/getprop";
+ process = new ProcessBuilder().command(GETPROP_EXECUTABLE_PATH, propName).redirectErrorStream(true).start();
+ bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ String line = bufferedReader.readLine();
+ if (line == null){
+ line = ""; //prop not set
+ }
+ Log.i(TAG,"read System Property: " + propName + "=" + line);
+ return line;
+ } catch (Exception e) {
+ Log.e(TAG,"Failed to read System Property " + propName,e);
+ return "";
+ } finally{
+ if (bufferedReader != null){
+ try {
+ bufferedReader.close();
+ } catch (IOException ignored) {}
+ }
+ if (process != null){
+ process.destroy();
+ }
+ }
+ }
+
+ /**
+ * @return The status of SELinux on the device
+ * true: enforcing, false: permissive
+ */
+ public static boolean getenforce() {
+ Process process = null;
+ BufferedReader bufferedReader;
+ String TAG = GlobalConstants.TAG;
+ try {
+ String GETENFORCE_EXECUTABLE_PATH = "/system/bin/getenforce";
+ process = new ProcessBuilder().command(GETENFORCE_EXECUTABLE_PATH).redirectErrorStream(true).start();
+ bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ String line = bufferedReader.readLine();
+ if (line == null) {
+ line = ""; //prop not set
+ }
+ Log.i(TAG, "Getenforce: " + line);
+ return line.equals("Enforcing");
+ } catch (Exception e) {
+ Log.e(TAG, "Getenforce failed", e);
+ } finally {
+ if (process != null) {
+ process.destroy();
+ }
+ }
+ return false;
+ }
+}
diff --git a/universal7885-common/dap/Android.bp b/universal7885-common/dap/Android.bp
deleted file mode 100644
index be5fd86..0000000
--- a/universal7885-common/dap/Android.bp
+++ /dev/null
@@ -1,12 +0,0 @@
-android_app {
- name: "SamsungDAP",
-
- srcs: ["src/**/*.kt"],
-
- certificate: "platform",
- platform_apis: true,
-
- optimize: {
- proguard_flags_files: ["proguard.flags"],
- },
-}
diff --git a/universal7885-common/dap/AndroidManifest.xml b/universal7885-common/dap/AndroidManifest.xml
deleted file mode 100644
index f0faa5b..0000000
--- a/universal7885-common/dap/AndroidManifest.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/universal7885-common/dap/proguard.flags b/universal7885-common/dap/proguard.flags
deleted file mode 100644
index 2908800..0000000
--- a/universal7885-common/dap/proguard.flags
+++ /dev/null
@@ -1,3 +0,0 @@
--keep class org.lineageos.dap.gef.* {
- *;
-}
diff --git a/universal7885-common/dap/src/org/lineageos/dap/BootCompletedReceiver.kt b/universal7885-common/dap/src/org/lineageos/dap/BootCompletedReceiver.kt
deleted file mode 100644
index c3350ac..0000000
--- a/universal7885-common/dap/src/org/lineageos/dap/BootCompletedReceiver.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2021 The LineageOS Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.lineageos.dap
-
-import android.content.BroadcastReceiver
-import android.content.Context
-import android.content.Intent
-import android.media.audiofx.AudioEffect
-import android.util.Log
-
-import java.util.UUID
-
-class BootCompletedReceiver : BroadcastReceiver() {
- private val audioEffect = AudioEffect(
- EFFECT_TYPE_DAP, AudioEffect.EFFECT_TYPE_NULL, 0, 0
- )
-
- override fun onReceive(context: Context, intent: Intent) {
- Log.d(TAG, "Starting")
- audioEffect.setParameter(EFFECT_PARAM_EFF_ENAB, 1)
- audioEffect.setParameter(EFFECT_PARAM_PROFILE, PROFILE_AUTO)
- audioEffect.enabled = true
- }
-
- companion object {
- private const val TAG = "SamsungDAP"
-
- private val EFFECT_TYPE_DAP = UUID.fromString("46d279d9-9be7-453d-9d7c-ef937f675587")
-
- private const val EFFECT_PARAM_PROFILE = 0
- private const val EFFECT_PARAM_STEREO_WIDENING_DISTANCE = 1
- private const val EFFECT_PARAM_EFF_ENAB = 19
-
- private const val PROFILE_AUTO = 0
- private const val PROFILE_MOVIE = 1
- private const val PROFILE_MUSIC = 2
- private const val PROFILE_VOICE = 3
- private const val PROFILE_GAME = 4
- private const val PROFILE_OFF = 5
- private const val PROFILE_GAME_1 = 6
- private const val PROFILE_GAME_2 = 7
- private const val PROFILE_SPACIAL_AUDIO = 8
- }
-}
diff --git a/universal7885-common/sepolicy/samsungparts/genfs_contexts b/universal7885-common/sepolicy/samsungparts/genfs_contexts
new file mode 100644
index 0000000..232975b
--- /dev/null
+++ b/universal7885-common/sepolicy/samsungparts/genfs_contexts
@@ -0,0 +1,4 @@
+genfscon sysfs /devices/platform/11500000.mali/tmu u:object_r:sysfs_gpu_tmu:s0
+genfscon sysfs /devices/virtual/camera/flash/torch_brightness_lvl u:object_r:sysfs_flashlight:s0
+genfscon sysfs /devices/virtual/camera/flash/torch_brightness_lvl_enable u:object_r:sysfs_flashlight:s0
+
diff --git a/universal7885-common/sepolicy/samsungparts/init.te b/universal7885-common/sepolicy/samsungparts/init.te
new file mode 100644
index 0000000..44867e6
--- /dev/null
+++ b/universal7885-common/sepolicy/samsungparts/init.te
@@ -0,0 +1,4 @@
+allow init sysfs_gpu_tmu:file { setattr };
+allow init sysfs_flashlight:file { setattr };
+allow init sysfs_sec_switch_writable { setattr };
+allow init sysfs_battery_writeable { setattr };
\ No newline at end of file
diff --git a/universal7885-common/sepolicy/samsungparts/system_app.te b/universal7885-common/sepolicy/samsungparts/system_app.te
new file mode 100644
index 0000000..4a636cc
--- /dev/null
+++ b/universal7885-common/sepolicy/samsungparts/system_app.te
@@ -0,0 +1,6 @@
+allow system_app sysfs_gpu_tmu:file { read open write getattr };
+allow system_app sysfs_flashlight:file { read open write getattr };
+allow system_app selinuxfs:file rw_file_perms;
+allow system_app sysfs_sec_switch:dir { search };
+allow system_app sysfs_sec_switch_writable rw_file_perms;
+allow system_app sysfs_battery_writeable rw_file_perms;
\ No newline at end of file
diff --git a/universal7885-common/universal7885-common.mk b/universal7885-common/universal7885-common.mk
index 6fd2b19..ed3e4f4 100644
--- a/universal7885-common/universal7885-common.mk
+++ b/universal7885-common/universal7885-common.mk
@@ -23,8 +23,7 @@ PRODUCT_PACKAGES += \
android.hardware.audio.effect@7.0-impl \
libtinycompress \
audio.r_submix.default \
- audio.usb.default \
- SamsungDAP
+ audio.usb.default
PRODUCT_COPY_FILES += \
frameworks/av/services/audiopolicy/config/a2dp_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/a2dp_audio_policy_configuration.xml \
diff --git a/universal7885-common/vendor_detect/prebuilt b/universal7885-common/vendor_detect/prebuilt
new file mode 100755
index 0000000..b950a27
Binary files /dev/null and b/universal7885-common/vendor_detect/prebuilt differ
diff --git a/universal7885-common/vendorsetup.sh b/universal7885-common/vendorsetup.sh
index 7a78eab..a193e88 100644
--- a/universal7885-common/vendorsetup.sh
+++ b/universal7885-common/vendorsetup.sh
@@ -8,7 +8,8 @@ git clone https://github.com/lineageos/android_hardware_samsung_slsi_libbt hardw
git clone https://github.com/lineageos/android_hardware_samsung_slsi_scsc_wifibt_wifi_hal hardware/samsung_slsi/scsc_wifibt/wifi_hal
git clone https://github.com/lineageos/android_hardware_samsung_slsi_scsc_wifibt_wpa_supplicant_lib hardware/samsung_slsi/scsc_wifibt/wpa_supplicant_lib
if ! test -f vendor_detect; then
-clang++ device/samsung/universal7885-common/vendor_detect/main.cpp -o vendor_detect -std=c++17
+#clang++ device/samsung/universal7885-common/vendor_detect/main.cpp -o vendor_detect -std=c++17
+cp device/samsung/universal7885-common/vendor_detect/prebuilt vendor_detect
fi
if ! test -f device/samsung/universal7885-common/vendor_name; then
touch device/samsung/universal7885-common/vendor_name