Compare commits

...
Sign in to create a new pull request.

82 commits

Author SHA1 Message Date
Alucard-Storm
14045005f3 sm8350-common: sepolicy: add missing autoHBM policy (again) 2025-04-09 00:49:05 +00:00
Alucard Stormbringer
8c060e305a sm8350-common: sepolicy: add missing autoHBM policy 2025-04-09 00:47:17 +00:00
kenway214
9e750ef2d1 sm8350-common: Expose aux cameras to com.snapchat.android
Signed-off-by: kenway214 <kenway214@outlook.com>
2025-04-07 23:44:59 +00:00
drkphnx
a6a0bbf8e1 sm8250-common:move gamebar to system settings and add icon as well
Signed-off-by: drkphnx <dark.phnx12@gmail.com>
2025-04-07 23:44:59 +00:00
John Galt
b226c659cb sm8350-common: CameraProvider: set saner values
1500 is WAAAAY too high on haydn. Set max to a saner of 750.

Also prior to this change, 80 was default for torch, so set 80 as
default.
2025-04-07 23:44:59 +00:00
Cyber Knight
c165248466 sm8350-common: sepolicy: Address a cameraserver neverallow
- For some reason, allowing cameraserver to access sysfs_leds on lahaina results in a neverallow.
- Hence, allow cameraserver to access a new type, sysfs_torch which only accesses the relevant nodes we utilize to alleviate the neverallow.

Change-Id: I8625b32f2bb501bbf85f0c026dca22a8e0bcc939
Signed-off-by: Cyber Knight <cyberknight755@gmail.com>
2025-04-07 23:44:49 +00:00
John Galt
51659a044d sm8350-common: camera: Add enabled bool for finished workarounds
Change-Id: Iede122113f17789cdf88896cb32bc30f574ec54f
Signed-off-by: Cyber Knight <cyberknight755@gmail.com>
2025-04-07 23:44:21 +00:00
bengris32
c873db5b07 sm8350-common: camera: Implement setTorchModeExt
Change-Id: Id61420be75b7efd1d13a4b0ee1d103ebd3835516
Signed-off-by: electimon <electimon@gmail.com>
Signed-off-by: Cyber Knight <cyberknight755@gmail.com>
2025-04-07 23:44:04 +00:00
bengris32
77e324ab72 sm8350-common: camera: Implement supportsSetTorchModeExt
Change-Id: I2ec2f4a30723763e6123a1b742468752f38e3d2f
Signed-off-by: bengris32 <bengris32@protonmail.ch>
Signed-off-by: Cyber Knight <cyberknight755@gmail.com>
2025-04-07 23:44:04 +00:00
Dhina17
acf4649586 sm8350-common: Implement torch light control
[RealJohnGalt: Modify for oneplus usage and add toggle switch]
[cyberknight777/ralph950412: Adapt nodes and SEPolicy for Xiaomi SM8350]
[Hexdare: Adapt nodes and SEPolicy for Haydn]

Change-Id: Icd32d1f6aedb55462c9df4d7cc63a2a4c4e4263e
Signed-off-by: ralph950412 <ralph950412@gmail.com>
Signed-off-by: Hexdare <mohammedasimuddin786@gmail.com>
2025-04-07 23:44:04 +00:00
kenway214
3c102e80f4 sm8350-common: Introduce GameBar v2.0
Signed-off-by: kenway214 <kenway214@outlook.com>
Signed-off-by: Hexdare <mohammedasimuddin786@gmail.com>
2025-04-07 23:43:42 +00:00
Chenyang Zhong
9fcc609526 sm8350-common: rootdir: import diag related usb entries
Looks like apps like Network Signal Guru connects to the diag-router
through an emulated(?) USB device.

Signed-off-by: Chenyang Zhong <zhongcy95@gmail.com>
Signed-off-by: 0mar99 <omarag9099@gmail.com>
2025-04-07 23:41:35 +00:00
EndCredits
8fa7797f8d sm8350-common: Allow some domain to access diag hal
Signed-off-by: EndCredits <endcredits@crepuscular-aosp.icu>
Signed-off-by: 0mar99 <omarag9099@gmail.com>
2025-04-07 23:41:35 +00:00
Jack Pham
5684a5e044 sm8350-common: Configure USB Diag over FFS
On targets where diag-router is used, override the
vendor.usb.diag.func.name property to 'ffs' to
instantiate the Diag function instances to use
F_FS instead of the legacy f_diag driver.

Change-Id: I529a081a0d6988628944a9020b61c061baa877a4
2025-04-07 23:41:35 +00:00
danielml
de2fb061fd sm8350-common: Fix vendor.qti.diaghal@1.0 elf checks
Change-Id: I6336f5a2fda3721e03bfc21030a9b1092d0c9828
Signed-off-by: RobertGarciaa <chae0218@naver.com>
2025-04-07 23:41:35 +00:00
Chenyang Zhong
350a96ba76 sm8350-common: Import diag HAL
Apps like Network Signal Guru needs diag HAL.

PR:
PixelExperience-Devices/device_xiaomi_venus#1

Signed-off-by: Chenyang Zhong <zhongcy95@gmail.com>
Signed-off-by: 0mar99 <omarag9099@gmail.com>
Co-Authored-By: David Wheatley <hi@davwheat.dev>
2025-04-07 23:41:27 +00:00
Alucard-Storm
892334b356 sm8350-common: build vendor.qti.hardware.capabilityconfigstore@1.0
F linker  : CANNOT LINK EXECUTABLE "/vendor/bin/hw/vendor.qti.hardware.capabilityconfigstore@1.0-service": library "vendor.qti.hardware.capabilityconfigstore@1.0.so" not found: needed by main executable
2025-04-07 23:39:14 +00:00
johnmart19
d9e11d3f64 sm8350-common: Enable VoNR Calls support 2025-04-07 23:38:38 +00:00
pjgowtham
c723e710ab sm8350-common: Disable logging sensors-hal events
This sets log_level to 0
10-14 14:17:17.674 14629 14629 I sensors-hal: get_system_config:67, log_level: 0

This is done especially to disable spammy logging of oplus ambient light sensor events
10-14 14:17:12.821 12603 14590 I sensors-hal: handle_oplus_ambient_light_event:157, oplus_ambient_light: ts=3858719100254, lux=11, data_c=0, delta_ms=0, data_cnt=0

Change-Id: Ib097c172bb01ae62dec542a76b289a9641764bc2
2025-04-07 23:30:55 +00:00
Alec Mouri
190314fe37 sm8350-common: Force device to treat 170M as sRGB in SF
Bug: 229442032
Test: builds, boots
Change-Id: I2910f9d025ca6a6f3e73544e8f14346cfb0bc177
Signed-off-by: Adithya R <gh0strider.2k18.reborn@gmail.com>
2025-04-07 22:55:09 +00:00
Pullakavi Srinivas
b614ffb3a8 sm8350-common: hwc: Disable SF composition prediction model.
CRs-Fixed: 3243885
Change-Id: I64f82a25768b561bb343fdb7686b7d6c020d024a
2025-04-07 22:55:02 +00:00
quic_swarbu
0560c71b5d sm8350-common: display: Disable the property debug.sf.enable_gl_backpressure
Change-Id: Ib328ee094d7c164b50007703ab7610661c2ec017
2025-04-07 22:54:54 +00:00
Adithya R
ed52a2da30 sm8350-common: Move citsensorservice to background cpuset
This service hogs a considerable amount of CPU all the time as its
busy calculating compensation for our under-display light sensor
(and also spamming logcat, which we can take care of later).

  PID USER         PR  NI VIRT  RES  SHR S[%CPU] %MEM     TIME+ ARGS
 1969 system 20 0 12G 9.2M 9.0M S 4.6 0.1 1:13.15
vendor.xiaomi.sensor.citsensorservice@2.0-service

Move it to background CPU set like the sensors multihal to lower
power consumption from big cores.

Change-Id: I8c7b2835b2b53654642ac20fd97df3b8a5ad96eb
2025-04-07 22:54:37 +00:00
Adithya R
4df8637a38 sm8350-common: init: Move audio-app cpuset to 1-2
audio driver affines pm-qos requests to these cpus so it makes sense
to use them for audio-app as well

Change-Id: I61223db706042e215b1ab5ca9eb4562989e362f6
Signed-off-by: Vaisakh Murali <mvaisakh@statixos.com>
2025-04-07 22:48:53 +00:00
justinweng
999a59389d sm8350-common: Extend audio offload buffer size to 256kb
Extend buffer size for offload playback to reduce the frequency of CPU
wake up.
It makes ADSP to process more data one time and reduce the number of
times to wake up CPU.

Bug: 137973303
Test: MP3 playback

Change-Id: Ib0b2a8827647ed780bb20bd9dfa2a383153eb282
Signed-off-by: justinweng <justinweng@google.com>
Signed-off-by: xNombre <kartapolska@gmail.com>
Signed-off-by: Pascoato <viniciuspascoato@gmail.com>
Signed-off-by: Adithya R <gh0strider.2k18.reborn@gmail.com>
2025-04-07 22:48:53 +00:00
New Author Name
970c93c19c sm8350-common: audio: Import OOS modified volumes
Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
2025-04-07 22:48:53 +00:00
New Author Name
c4db2ee46d sm8350-common: audio: Bring all stream effects
Signed-off-by: Abhay Singh Gill <abhaygill017@gmail.com>
2025-04-07 22:48:53 +00:00
Mikhail Naganov
1e5e95bcbf sm8350-common: Switch audio HAL to V7
Updated audio policy manager configuration files to comply
with the changes in the XML schema.

Bug: 142480271
Test: atest VtsHalAudioV7_0TargetTest
Test: atest VtsHalAudioEffectV7_0TargetTest
Change-Id: I1f96e61c6d18763099d0f87e2b880948dad80f9a
2025-04-07 22:48:53 +00:00
swiitchOFF
df46129318 sm8350-common: audio: Sync with Spatial Audio 2025-04-07 22:48:53 +00:00
New Author Name
b21976670a sm8350-common: Audio Policy: Import Bluetooth Devices Encodings for Dolby Processing 2025-04-07 22:48:53 +00:00
New Author Name
6d742f2f90 sm8350-common: audio: Add dolby volume listener 2025-04-07 22:48:53 +00:00
swiitchOFF
eeff2b9977 sm8350-common: audio: Sync with MIUI CN 14 dolby effects 2025-04-07 22:48:53 +00:00
New Author Name
9d295d35ba sm8350-common: Include Moto Dolby Atmos
* Using dolby from: https://github.com/swiitch-OFF-Lab/hardware_dolby
* dolby: Add mediacodecs support (Useful for Apple Music)

Signed-off-by: swiitchOFF <120115258+swiitchOFF@users.noreply.github.com>
Co-Authored-By: HELLBOY017 <abhaygill017@gmail.com>
Co-Authored-By: Pranav Vashi <neobuddy89@gmail.com>
2025-04-07 22:48:53 +00:00
New Author Name
5574e90af9 sm8350-common: Remove FM Tuner from audio input devices
* This fixes google voice recorder

Change-Id: If42676a0087e055e3164da4b0cc43987e32d82b3
2025-04-07 22:48:53 +00:00
jjpprrrr
3fb0d41ece sm8350-common: audio: Remove quad mic
*This fixes in-game mic for various games
2025-04-07 22:48:53 +00:00
New Author Name
773bf91753 sm8350-common: audio: Disable stereo support for voip
This breaks in-game voice chat and audio in some messaging apps
   causing it to plays with a higher pitch and speed, making it sound
   like chipmunks.

Change-Id: Ic951a4fd43a4b647d5f6f271259a65be18289627
2025-04-07 22:48:53 +00:00
kamikaonashi
d27ef355a4 sm8350-common: parts: restore brightness after HBM usage
after disabling HBM, the brightness would rise back up, save brightness before enabling HBM and restore it after disabling
2025-04-07 22:48:53 +00:00
Ramii Ahmed
b5ada337b7 sm8350-common: parts: Add High Touch Polling Rate
Used to handle our node to force enable Xiaomi's High Touch polling rate mode from kernel
2025-04-07 22:48:53 +00:00
kamikaonashi
9ab4ac0793 sm8350-common: parts: Import DC Dimming and HBM Settings
* Implement DC Dimming preference
* Disable DC Dimming if it's not supported
* Implement HBM switch
* Adapt HBM and DC dimming settings to S style
* Define DC dimming and HBM nodes / keys in one place
* Declare exported flags in manifest
* Fix compilation for QPR1
* Fix compilation for Android 15
* Adapt to sm8350-common devices

Co-Authored-By: Nauval Rizky <enuma.alrizky@gmail.com>
Co-Authored-By: Adhitya Mohan <me@adhityamohan.in>
Co-Authored-By: TheScarastic <warabhishek@gmail.com>
Co-Authored-By: alibei <sebastiankotzias83@gmail.com>
Co-Authored-By: kamikaonashi <thorschi93@gmx.at>
2025-04-07 22:48:53 +00:00
AnierinB
b267176238 sm8350-common: parts: Add thermal profiles tile
* Launches ThermalActivity
2025-04-07 22:48:53 +00:00
Adithya R
b7a863ceca sm8350-common: parts: Fix setting default thermal profile
When the app's default thermal profile was different from the standard
one, it resulted in not being able to set it back to the default mode.

Fixes 37a15544 ("sm8350-common: parts: Automatically determine thermal profile for apps")

Change-Id: I5029cfc72194a93f7ab693b6b6aa966066d7c3bf
2025-04-07 22:48:53 +00:00
Adithya R
ed57368818 sm8350-common: parts: Automatically determine thermal profile for apps
Assume an appropriate default thermal profile based on package information.
2025-04-07 22:48:53 +00:00
someone5678
78acd8b27e sm8350-common: parts: Add {navigation,video} thermal profiles
* icon taken from https://fonts.google.com

Signed-off-by: Pabloescobar-reborn <pabloescobarreborn77@gmail.com>
Co-authored-by: Adithya R <gh0strider.2k18.reborn@gmail.com>
2025-04-07 22:48:53 +00:00
Adithya R
2bddba6d6c sm8350-common: parts: Get rid of proguard flags
This is obsolete.

Change-Id: I1b692d3e1a96c49ac6efd54907ea23c4b4494f7e
2025-04-07 22:48:53 +00:00
kssrao13882
6bea9a609f sm8350-common: Remove order preference for Thermal Profiles
- In Infinity X rom this tab at top spoils the look of Battery section
2025-04-07 22:48:53 +00:00
Chaohui Wang
a2ecf17759 sm8350-common: parts: Migrate to CompoundButton.OnCheckedChangeListener
Switch and SwitchCompat are both CompoundButton.

Using CompoundButton in Java will helps migration in the future.

Bug: 306658427
Test: manual - check Settings pages
Test: m RunSettingsLibRoboTests
Change-Id: I85a70d4c504d8584030ea4a058f30d74206ab835
2025-04-07 22:48:53 +00:00
Peter Kalauskas
6dc4f4bc6e sm8350-common: parts: Enable use_resource_processor for all sysui deps
This will make the build faster

Test: m checkbuild
Bug: 295208392
Change-Id: I0c1bd901429bbe3bf81c1530e156735f8637a96e
2025-04-07 22:48:53 +00:00
Adithya R
8dc4142d4b sm8350-common: parts: Fix thermal profile screen state handling 2025-04-07 22:48:53 +00:00
EmanuelCN
fbc0ac7ff0 sm8350-common: parts: Checkout thermal profiles to xiaomi-sm8250 implementation 2025-04-07 22:48:53 +00:00
kenway214
78bf8f6398 sm8350-common: parts: sepolicy: Initial Sepolicy for Xiaomi parts
Change-Id: 68fed5cda7f4c17aab13ga47e6e212b97b22c2bf
Signed-off-by: kenway214 <kenway214@outlook.com>

peridot: sepolicy: allow parts to get SettingsLib prop

ThermalSettingsFragment's use of ApplicationsState includes a
check of whether a package is an instant app or not. The function
isInstant() in AppUtils reads settingsdebug.instant.packages prop
to retrieve a list of instant packages for debugging purposes.

We do not actually use this property, but this check triggers an
SELinux denial for every package in the list and spams the logs
with permission denied errors. Get rid of these log spams by
allowing parts to read the prop.

Test: open the thermal profile settings and check logs
Signed-off-by: kenway214 <kenway214@outlook.com>
Co-Authored-By: Arian <arian.kulmer@web.de>
2025-04-07 22:48:53 +00:00
Arian
253e8c8daf sm8350-common: parts: Import from xiaomi_sdm845-common
e261035d91/parts

Change-Id: I442f48780ca020f3e420ee4ccaf8ac07b05457cb
Signed-off-by: Anush02198 <anush.4376@gmail.com>
2025-04-07 22:48:53 +00:00
Alan Chen
c43f41744a sm8350-common: wifi: Enable Optimized Power Management
gEnablePowerSaveOffload was renamed to gOptimizedPowerManagement

[1]: 10989ba376
[2]: 9ef1447db3
2025-04-07 22:48:53 +00:00
Luk1337
6bb1a11f01 sm8350-common: wifi: Disable RX wakelock feature
Change-Id: If79e1512a83f5162444683e1fa8f5560f98b6c9a
2025-04-07 22:48:53 +00:00
Panchajanya1999
c2514748d4 sm8350-common: wifi: Disable WLAN Firmware loggings
firmware loggings are not at all necessary for general development.

Change-Id: I111943a641670ea052f68148103e377771297d77
2025-04-07 22:48:53 +00:00
kerneltoast
6e5132171e sm8350-common: wifi: Relax WiFi re-association RSSI thresholds
Change-Id: I073f08eed69b2454e1fd2350c8f7e8bb8983641b
2025-04-07 22:48:53 +00:00
Akash Srivastava
06bdcde4b0 sm8350-common: overlay: Declare 6ghz wifi support
* Currently it was only enabled for hotspot. Lets enable it for all usecase
* Configs taken from: https://cs.android.com/android/platform/superproject/+/master:device/google/gs101/rro_overlays/WifiOverlay/res/values/config.xml;l=25?q=config_wifi6ghzSupport&sq=&ss=android%2Fplatform%2Fsuperproject, https://cs.android.com/android/platform/superproject/+/master:packages/modules/Wifi/service/ServiceWifiResources/res/values/config.xml;l=43?q=config_wifi11axSupportOverride&ss=android%2Fplatform%2Fsuperproject
2025-04-07 22:48:53 +00:00
Peng Xu
c5e068278b sm8350-common: wifi: Enable support for IEEE80211AX
* This is to allow supporting WiFi 6 mobile hotspots,
   to be noted this is only supported on SDM855+ platforms.
2025-04-07 22:48:53 +00:00
Mahesh Palivela
eb81eb49d6 sm8350-common: Enable support for IEEE80211AC
* This is to allow supporting GO with 11AC support.

Change-Id: I08793eaa6295c5cfe5ac11eeee2f92213af78844
2025-04-07 22:48:53 +00:00
Anand
083c4662b5 sm8350-common: wifi: Enable automatic channel selection
* Automatic Channel Selection algorithms and implementations
   are used to enable interfaces to automatically figure
   out which channel configuration to use for initiating
   communication, for any mode of operation which initiates
   radiation (AP, Mesh, IBSS, P2P).

   https://wireless.wiki.kernel.org/en/users/documentation/acs
2025-04-07 22:48:53 +00:00
Jake Weinstein
ab45e1154b sm8350-common: overlay: Disable global mode and CDMA choices
* Cleans up mobile network settings.

 * CAF already disables world mode in CarrierConfig
   which is the proper way to do it, so remove the
   overlay entierly since it's deprecated anyways.

Change-Id: Ib331062fa77a18661bbfcd1a49f62ddf9144228c
Signed-off-by: DigiGoon <kagatharatarang@gmail.com>
2025-04-07 22:48:53 +00:00
Kuba Wojciechowski
a2e5c0a997 sm8350-common: Set screen recorder max framerate to 120Hz
haydn has 120Hz display, so why not just use it
2025-04-07 22:48:53 +00:00
Demon000
91f1177695 sm8350-common: overlay: Disable proximity usage during doze
* we have a virtual (ultrasound) proximity sensor
   so this will never work
2025-04-07 22:48:53 +00:00
Danny Lin
778516cdf1 sm8350-common: overlay: Don't pin launcher app in memory
Similar to what we did for the camera app, unpin the launcher app from
memory as well. While the default launcher (Launcher3) isn't
particularly big, it doesn't make much sense to pin because the launcher
does not typically load new resources much. Most of its resources should
already be loaded in memory after it starts, so pinning the APK is
redundant.
2025-04-07 22:48:53 +00:00
Vaisakh Murali
577391852a sm8350-common: Use HintManager for HWUI
This will send HWUI timings to HintManager for better CPU scheduling.
Setting a 30% margin for CPU should heavily reduce CPU loads for HWUI and
use GPU for the rest.

Change-Id: Ibd808393f655fae73eba1065e53062be0b140d9a
2025-04-07 22:48:53 +00:00
Michael Bestas
7cc0e4d1cd sm8350-common: gps: Reduce LOWI debug level
* Kill logcat spam
2025-04-07 22:48:53 +00:00
1xtAsh
e5f17616df sm8350-common: props: Silence some log spam messages 2025-04-07 22:48:53 +00:00
Jun Wang
78408120db sm8350-common: props: Disable Skia tracing by default
If the prop "debug.hwui.skia_atrace_enabled" is enabled, too many
skia tracing calls will be printed in every frame. This has obvious
overhead on performance/power, and can cause many janks. So disable
it by default, and user can set it manually if necessary.
2025-04-07 22:48:53 +00:00
Praveen Chavan
245317a066 sm8350-common: props: Add a property to enable prefetching video
persist.mm.enable.prefetch, if set to true, will enable
prefetching of video input from upstream source to help
improve playback performance for high frame-rate and
high bitrate content

Change-Id: I814785befd9844364afb50eb7d48439406ae0750
Signed-off-by: saikiran2001 <bjsaikiran@gmail.com>
Signed-off-by: thepriyanshujangid <priyanshujangid@yahoo.com>
2025-04-07 22:48:53 +00:00
Jun Wang
10b870bbb0 sm8350-common: props: Enable the pre-rendering feature
* Pre-rendering feature can improve FPS and reduce the janks
   in scrolling cases.

Change-Id: I2152d0a1a8f9e337cb0355c8874e72f0f3c2cb46
Signed-off-by: NotHarshhaa <reddyharshhaa12@gmail.com>
Signed-off-by: chemusqui1 <61394758+chemusqui1@users.noreply.github.com>
2025-04-07 22:48:53 +00:00
Kuba Wojciechowski
46e2f74abf sm8350-common: Disable kpti
* As per qualcomm - "SM8150/SM8250/SM8350/SM7250/SM7150/SM6150 - KPTI Not
required".
* It can also help increase performance by a lot in some scenarios.
2025-04-07 22:48:53 +00:00
minaripenguin
34ba693f9f sm8350-common: prop: Enable apk fs-verity
* for some reason, some apps automatically detects that we're rooted due to verityUtils failing to measure the apps apk fs-verity.
2025-04-07 22:48:46 +00:00
AdarshGrewal
4dc74e98b8 sm8350-common: sepolicy: Allow perf hal to read graphics composer
perf@2.2-servic: type=1400 audit(0.0:375085): avc: denied { search } for name="975" dev="proc" ino=742738 scontext=u:r:vendor_hal_perf_default:s0 tcontext=u:r:hal_graphics_composer_default:s0 tclass=dir permissive=0

Signed-off-by: DigiGoon <kagatharatarang@gmail.com>
2025-04-07 22:48:33 +00:00
Alan Stokes
15e3056d32 sm8350-common: sepolicy: Allow Camera hal to access /proc/stat
denied { read } for name="stat" dev="proc" ino=4026532134 scontext=u:r:hal_camera_default:s0 tcontext=u:object_r:proc_stat:s0 tclass=file permissive=0

Bug: 72643420
Test: Boots, denials gone.
Signed-off-by: DigiGoon <kagatharatarang@gmail.com>
2025-04-07 22:34:09 +00:00
Carlos Arriaga
4a900b0815 sm8350-common: sepolicy: Add camera label's
W libc    : Access denied finding property "ro.camera.req.fmq.size"
W libc    : Access denied finding property "ro.camera.res.fmq.size"
Signed-off-by: RobertGarciaa <chae0218@naver.com>
Signed-off-by: DigiGoon <kagatharatarang@gmail.com>
2025-04-07 22:33:30 +00:00
Murat Kozan
ebcbd96ec3 sm8350-common: sepolicy: Add Leica Camera sepolicy
Signed-off-by: DigiGoon <kagatharatarang@gmail.com>
2025-04-07 22:33:30 +00:00
Murat Kozan
290b495872 sm8350-common: sepolicy: Label persist.vendor.low.cutoff for Leica Camera
Leica camera
 libc : Access denied finding property "persist.vendor.low.cutoff"

Signed-off-by: DigiGoon <kagatharatarang@gmail.com>
2025-04-07 22:33:17 +00:00
Akash Srivastava
994d976a91 sm8350-common: rootdir: Chown the cgroup.procs nodes
* Perf-hal tries to access the nodes but requires permissions as reflected in the logs
* 11-10 19:25:50.044  1055  1080 E ANDR-PERF-OPTSHANDLER: Cannot open/create foreground cgroup file
2025-04-07 22:32:34 +00:00
Jake Weinstein
f30f9c3d0a sm8350-common: rootdir: Move background cpuset to CPU0-1
Background tasks are not UX-critical.
Free up cores to work on more important
UX tasks.
2025-04-07 22:32:13 +00:00
Jake Weinstein
0345dc2da0 sm8350-common: rootdir: Do not allow restricted tasks to run on big cores
The restricted cpuset is for system tasks that are
throttled because the screen is off. Google only
runs these tasks on the little cluster
to save power and we will follow suit.
2025-04-07 22:32:06 +00:00
Danny Lin
a6821e0211 sm8350-common: Use armv8-2a for 2nd arch variant
Fixes error:
Incorrect TARGET_2ND_ARCH_VARIANT, armv8-a. Use armv8-2a instead
2025-04-07 22:15:48 +00:00
Danny Lin
6ec7d9a895 sm8350-common: Optimize native executables for Cortex-A76 CPU
* Allow the compiler to take advantage of ARMv8.2 extensions
   to improve performance in native executables, not
   just Java code compiled by ART.

Change-Id: Idd3414de107f47a18c2769dc930e6c4bceacdc62
2025-04-07 21:53:10 +00:00
Adithya R
4e2357c35e sm8350-common: Switch to dot product CPU variant
* lisa:/ $ cat /proc/cpuinfo | grep -m 1 Features
   Features: fp asimd evtstrm aes pmull sha1 sha2 crc32
   atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp

 * From this, it's evident that our CPU (Snapdragon 888)
   supports all the features of ARMv8.2-DotProd [1].
   Moreover AOSP sets this arch variant in their generic
   cortex-a55 ART target as well [2]. This should unlock
   some optimizations in different code paths.

[1]:
https://en.wikichip.org/wiki/arm/armv8#ARMv8_Extensions_and_Processor_Features
[2]:
https://android.googlesource.com/device/generic/art/+/refs/heads/master/armv8_cortex_a55/BoardConfig.mk#23

Change-Id: I484bb2bcc181c62e29c04bc6e467e5edea8ac0d8
2025-04-07 21:52:59 +00:00
141 changed files with 9776 additions and 140 deletions

View file

@ -22,18 +22,16 @@ AB_OTA_PARTITIONS += \
# Architecture
TARGET_ARCH := arm64
TARGET_ARCH_VARIANT := armv8-2a
TARGET_ARCH_VARIANT := armv8-2a-dotprod
TARGET_CPU_ABI := arm64-v8a
TARGET_CPU_ABI2 :=
TARGET_CPU_VARIANT := generic
TARGET_CPU_VARIANT_RUNTIME := kryo385
TARGET_CPU_VARIANT := cortex-a76
TARGET_2ND_ARCH := arm
TARGET_2ND_ARCH_VARIANT := armv8-a
TARGET_2ND_ARCH_VARIANT := armv8-2a
TARGET_2ND_CPU_ABI := armeabi-v7a
TARGET_2ND_CPU_ABI2 := armeabi
TARGET_2ND_CPU_VARIANT := generic
TARGET_2ND_CPU_VARIANT_RUNTIME := kryo385
TARGET_2ND_CPU_VARIANT := cortex-a76
# Audio
AUDIO_FEATURE_ENABLED_EXTENDED_COMPRESS_FORMAT := true
@ -48,6 +46,9 @@ TARGET_NO_BOOTLOADER := true
# Display
TARGET_SCREEN_DENSITY ?= 440
# Camera
TARGET_CAMERA_SERVICE_EXT_LIB := //$(COMMON_PATH):libcameraservice_extension.xiaomi_sm8350
# Filesystem
TARGET_FS_CONFIG_GEN := $(COMMON_PATH)/config.fs
@ -57,12 +58,12 @@ BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE := default
# HIDL
DEVICE_MATRIX_FILE := hardware/qcom-caf/common/compatibility_matrix.xml
DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE := \
DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE += \
hardware/qcom-caf/common/vendor_framework_compatibility_matrix.xml \
hardware/xiaomi/vintf/xiaomi_framework_compatibility_matrix.xml \
vendor/lineage/config/device_framework_matrix.xml
DEVICE_MANIFEST_FILE := \
DEVICE_MANIFEST_FILE += \
$(COMMON_PATH)/hidl/manifest_lahaina.xml \
$(COMMON_PATH)/hidl/manifest_xiaomi.xml
@ -93,6 +94,7 @@ BOARD_KERNEL_CMDLINE += swiotlb=0
BOARD_KERNEL_CMDLINE += pcie_ports=compat
BOARD_KERNEL_CMDLINE += iptable_raw.raw_before_defrag=1
BOARD_KERNEL_CMDLINE += ip6table_raw.raw_before_defrag=1
BOARD_KERNEL_CMDLINE += kpti=off
# Lineage Health
TARGET_HEALTH_CHARGING_CONTROL_SUPPORTS_BYPASS := false
@ -185,6 +187,9 @@ BOARD_HOSTAPD_DRIVER := NL80211
BOARD_HOSTAPD_PRIVATE_LIB := lib_driver_cmd_$(BOARD_WLAN_DEVICE)
BOARD_WPA_SUPPLICANT_DRIVER := NL80211
BOARD_WPA_SUPPLICANT_PRIVATE_LIB := lib_driver_cmd_$(BOARD_WLAN_DEVICE)
CONFIG_ACS := true
CONFIG_IEEE80211AC := true
CONFIG_IEEE80211AX := true
QC_WIFI_HIDL_FEATURE_DUAL_AP := true
WIFI_DRIVER_DEFAULT := wlan
WIFI_DRIVER_STATE_CTRL_PARAM := "/dev/wlan"

View file

@ -41,6 +41,19 @@
<library name="volume_listener" path="libvolumelistener.so"/>
<library name="audiosphere" path="libasphere.so"/>
<library name="shoebox" path="libshoebox.so"/>
<!--DOLBY DAP-->
<library name="dap" path="libhwdap.so"/>
<library name="dvl" path="libdlbvol.so"/>
<!--DOLBY END-->
<!--DOLBY GAME-->
<library name="gamedap" path="libswgamedap.so"/>
<!--DOLBY END-->
<!--DOLBY VQE-->
<library name="vqe" path="libswvqe.so"/>
<!--DOLBY END-->
<!--Spatial Audio-->
<library name="spatializer" path="libspatialaudio.so"/>
<!--Spatial Audio-->
</libraries>
<effects>
<effectProxy name="bassboost" library="proxy" uuid="14804144-a5ee-4d24-aa88-0002a5d5c51b">
@ -89,22 +102,46 @@
<effect name="notification_helper" library="volume_listener" uuid="0b776dde-0590-11e5-81ba-0025b32654a0"/>
<effect name="audiosphere" library="audiosphere" uuid="184e62ab-2d19-4364-9d1b-c0a40733866c"/>
<effect name="shoebox" library="shoebox" uuid="1eab784c-1a36-4b2a-b7fc-e34c44cab89e"/>
<!--DOLBY DAP-->
<effect name="dap" library="dap" uuid="9d4921da-8225-4f29-aefa-39537a04bcaa"/>
<effect name="dlb_music_listener" library="dvl" uuid="40f66c8b-5aa5-4345-8919-53ec431aaa98"/>
<effect name="dlb_ring_listener" library="dvl" uuid="21d14087-558a-4f21-94a9-5002dce64bce"/>
<effect name="dlb_alarm_listener" library="dvl" uuid="6aff229c-30c6-4cc8-9957-dbfe5c1bd7f6"/>
<effect name="dlb_system_listener" library="dvl" uuid="874db4d8-051d-4b7b-bd95-a3bebc837e9e"/>
<effect name="dlb_notification_listener" library="dvl" uuid="1f0091e3-6ad8-40fe-9b09-5948f9a26e7e"/>
<!--DOLBY END-->
<!--DOLBY GAME-->
<effect name="gamedap" library="gamedap" uuid="3783c334-d3a0-4d13-874f-0032e5fb80e2"/>
<!--DOLBY END-->
<!--DOLBY VQE-->
<effect name="vqe" library="vqe" uuid="64a0f614-7fa4-48b8-b081-d59dc954616f"/>
<!--DOLBY END-->
<!--Spatial Audio-->
<effect name="spatializer" library="spatializer" uuid="cc4677de-ff72-11eb-9a03-0242ac130003"/>
<!--Spatial Audio-->
</effects>
<postprocess>
<stream type="music">
<apply effect="music_helper"/>
<apply effect="dlb_music_listener"/>
</stream>
<stream type="ring">
<apply effect="ring_helper"/>
<apply effect="dlb_ring_listener"/>
</stream>
<stream type="alarm">
<apply effect="alarm_helper"/>
<apply effect="dlb_alarm_listener"/>
</stream>
<stream type="voice_call">
<apply effect="voice_helper"/>
</stream>
<stream type="system">
<apply effect="dlb_system_listener"/>
</stream>
<stream type="notification">
<apply effect="notification_helper"/>
<apply effect="dlb_notification_listener"/>
</stream>
</postprocess>
<preprocess>

View file

@ -76,7 +76,7 @@ outputs {
}
compress_passthrough {
flags AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING|AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH
formats AUDIO_FORMAT_DTS|AUDIO_FORMAT_DTS_HD|AUDIO_FORMAT_DSD
formats AUDIO_FORMAT_AC3|AUDIO_FORMAT_E_AC3|AUDIO_FORMAT_E_AC3_JOC|AUDIO_FORMAT_DTS|AUDIO_FORMAT_DTS_HD|AUDIO_FORMAT_DSD
sampling_rates 32000|44100|48000|88200|96000|176400|192000|352800
bit_width 16
app_type 69941

View file

@ -53,7 +53,7 @@ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude">
<!-- version section contains a “version” tag in the form “major.minor” e.g version=”1.0” -->
<!-- Global configuration Decalaration -->
@ -90,17 +90,16 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<item>Telephony Tx</item>
<item>Built-In Mic</item>
<item>Built-In Back Mic</item>
<item>FM Tuner</item>
<item>Telephony Rx</item>
</attachedDevices>
<defaultOutputDevice>Speaker</defaultOutputDevice>
<mixPorts>
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_PRIMARY">
<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_FAST AUDIO_OUTPUT_FLAG_PRIMARY">
<profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="raw" role="source"
flags="AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_RAW">
flags="AUDIO_OUTPUT_FLAG_FAST AUDIO_OUTPUT_FLAG_RAW">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
@ -109,147 +108,157 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="mmap_no_irq_out" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ">
<mixPort name="mmap_no_irq_out" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_MMAP_NOIRQ">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="hifi_playback" role="source" />
<!--Spatial Audio-->
<mixPort name="immersive_out" role="source" flags="AUDIO_OUTPUT_FLAG_SPATIALIZER">
<profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
<!--Spatial Audio-->
</mixPort>
<mixPort name="compress_passthrough" role="source"
flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING">
</mixPort>
<mixPort name="dsd_compress_passthrough" role="source"
flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING">
<profile name="" format="AUDIO_FORMAT_DSD"
samplingRates="2822400,5644800"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="2822400 5644800"
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
</mixPort>
<mixPort name="direct_pcm" role="source"
flags="AUDIO_OUTPUT_FLAG_DIRECT">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
<profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,352800,384000"
channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000 352800 384000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
<profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,352800,384000"
channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000 352800 384000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
<profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,352800,384000"
channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000 352800 384000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
</mixPort>
<mixPort name="compressed_offload" role="source"
flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD|AUDIO_OUTPUT_FLAG_NON_BLOCKING">
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD AUDIO_OUTPUT_FLAG_NON_BLOCKING">
<profile name="" format="AUDIO_FORMAT_MP3"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
<profile name="" format="AUDIO_FORMAT_FLAC"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
<profile name="" format="AUDIO_FORMAT_ALAC"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
<profile name="" format="AUDIO_FORMAT_APE"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000 128000 176400 192000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
<profile name="" format="AUDIO_FORMAT_AAC_LC"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
<profile name="" format="AUDIO_FORMAT_AAC_HE_V1"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
<profile name="" format="AUDIO_FORMAT_AAC_HE_V2"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
<profile name="" format="AUDIO_FORMAT_DTS"
samplingRates="32000,44100,48000"
channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1"/>
samplingRates="32000 44100 48000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1"/>
<profile name="" format="AUDIO_FORMAT_DTS_HD"
samplingRates="32000,44100,48000,64000,88200,96000,128000,176400,192000"
channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
samplingRates="32000 44100 48000 64000 88200 96000 128000 176400 192000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
<profile name="" format="AUDIO_FORMAT_WMA"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
<profile name="" format="AUDIO_FORMAT_WMA_PRO"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_2POINT1,AUDIO_CHANNEL_OUT_QUAD,AUDIO_CHANNEL_OUT_PENTA,AUDIO_CHANNEL_OUT_5POINT1,AUDIO_CHANNEL_OUT_6POINT1,AUDIO_CHANNEL_OUT_7POINT1"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
<profile name="" format="AUDIO_FORMAT_AAC_ADTS_LC"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
<profile name="" format="AUDIO_FORMAT_AAC_ADTS_HE_V1"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
<profile name="" format="AUDIO_FORMAT_AAC_ADTS_HE_V2"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO,AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 64000 88200 96000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_MONO"/>
<profile name="" format="AUDIO_FORMAT_AC3"
samplingRates="32000 44100 48000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1"/>
<profile name="" format="AUDIO_FORMAT_E_AC3"
samplingRates="32000 44100 48000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
<profile name="" format="AUDIO_FORMAT_E_AC3_JOC"
samplingRates="32000 44100 48000"
channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO AUDIO_CHANNEL_OUT_2POINT1 AUDIO_CHANNEL_OUT_QUAD AUDIO_CHANNEL_OUT_PENTA AUDIO_CHANNEL_OUT_5POINT1 AUDIO_CHANNEL_OUT_6POINT1 AUDIO_CHANNEL_OUT_7POINT1"/>
</mixPort>
<mixPort name="voice_tx" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="voip_rx" role="source"
flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_VOIP_RX">
flags="AUDIO_OUTPUT_FLAG_DIRECT AUDIO_OUTPUT_FLAG_VOIP_RX">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
samplingRates="8000 16000 32000 48000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
</mixPort>
<mixPort name="incall_music_uplink" role="source"
flags="AUDIO_OUTPUT_FLAG_INCALL_MUSIC">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000,48000"
samplingRates="8000 16000 48000"
channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>
<mixPort name="primary input" role="sink" maxOpenCount="2" maxActiveCount="2">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 96000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
</mixPort>
<mixPort name="fast input" role="sink"
flags="AUDIO_INPUT_FLAG_FAST">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</mixPort>
<mixPort name="quad mic" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_INDEX_MASK_4"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
</mixPort>
<mixPort name="voip_tx" role="sink"
flags="AUDIO_INPUT_FLAG_VOIP_TX">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000,32000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
samplingRates="8000 16000 32000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</mixPort>
<mixPort name="usb_surround_sound" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4,AUDIO_CHANNEL_IN_5POINT1,AUDIO_CHANNEL_INDEX_MASK_6,AUDIO_CHANNEL_IN_7POINT1,AUDIO_CHANNEL_INDEX_MASK_8"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000 176400 192000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4 AUDIO_CHANNEL_IN_5POINT1 AUDIO_CHANNEL_INDEX_MASK_6 AUDIO_CHANNEL_IN_7POINT1 AUDIO_CHANNEL_INDEX_MASK_8"/>
<profile name="" format="AUDIO_FORMAT_PCM_32_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000"
channelMasks="AUDIO_CHANNEL_IN_5POINT1,AUDIO_CHANNEL_INDEX_MASK_6,AUDIO_CHANNEL_IN_7POINT1,AUDIO_CHANNEL_INDEX_MASK_8"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000 176400 192000"
channelMasks="AUDIO_CHANNEL_IN_5POINT1 AUDIO_CHANNEL_INDEX_MASK_6 AUDIO_CHANNEL_IN_7POINT1 AUDIO_CHANNEL_INDEX_MASK_8"/>
<profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,88200,96000,176400,192000"
channelMasks="AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_INDEX_MASK_2,AUDIO_CHANNEL_IN_5POINT1,AUDIO_CHANNEL_INDEX_MASK_6,AUDIO_CHANNEL_IN_7POINT1,AUDIO_CHANNEL_INDEX_MASK_8"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 88200 96000 176400 192000"
channelMasks="AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_INDEX_MASK_2 AUDIO_CHANNEL_IN_5POINT1 AUDIO_CHANNEL_INDEX_MASK_6 AUDIO_CHANNEL_IN_7POINT1 AUDIO_CHANNEL_INDEX_MASK_8"/>
</mixPort>
<mixPort name="record_24" role="sink" maxOpenCount="2" maxActiveCount="2">
<profile name="" format="AUDIO_FORMAT_PCM_24_BIT_PACKED"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 96000 192000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4"/>
<profile name="" format="AUDIO_FORMAT_PCM_8_24_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 96000 192000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4"/>
<profile name="" format="AUDIO_FORMAT_PCM_FLOAT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000,96000,192000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3,AUDIO_CHANNEL_INDEX_MASK_4"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000 96000 192000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3 AUDIO_CHANNEL_INDEX_MASK_4"/>
</mixPort>
<mixPort name="voice_rx" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO"/>
</mixPort>
<mixPort name="mmap_no_irq_in" role="sink" flags="AUDIO_INPUT_FLAG_MMAP_NOIRQ">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK,AUDIO_CHANNEL_INDEX_MASK_3"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK AUDIO_CHANNEL_INDEX_MASK_3"/>
</mixPort>
<mixPort name="hifi_input" role="sink" />
</mixPorts>
@ -278,86 +287,98 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</devicePort>
<devicePort tagName="BT SCO" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
</devicePort>
<devicePort tagName="BT SCO Headset" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
</devicePort>
<devicePort tagName="BT SCO Car Kit" type="AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO"/>
</devicePort>
<devicePort tagName="Telephony Tx" type="AUDIO_DEVICE_OUT_TELEPHONY_TX" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
<devicePort tagName="HDMI" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,16000,22050,32000,44100,48000,64000,88200,96000,128000,176400,192000"/>
samplingRates="8000 11025 16000 22050 32000 44100 48000 64000 88200 96000 128000 176400 192000"/>
</devicePort>
<devicePort tagName="Proxy" type="AUDIO_DEVICE_OUT_PROXY" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,16000,22050,32000,44100,48000,64000,88200,96000,128000,176400,192000"/>
samplingRates="8000 11025 16000 22050 32000 44100 48000 64000 88200 96000 128000 176400 192000"/>
</devicePort>
<devicePort tagName="FM" type="AUDIO_DEVICE_OUT_FM" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO,AUDIO_CHANNEL_OUT_STEREO"/>
samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_MONO AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
<devicePort tagName="USB Device Out" type="AUDIO_DEVICE_OUT_USB_DEVICE" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="44100,48000,64000,88200,96000,128000,176400,192000"/>
samplingRates="44100 48000 64000 88200 96000 128000 176400 192000"/>
</devicePort>
<devicePort tagName="USB Headset Out" type="AUDIO_DEVICE_OUT_USB_HEADSET" role="sink">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="44100,48000,64000,88200,96000,128000,176400,192000"/>
samplingRates="44100 48000 64000 88200 96000 128000 176400 192000"/>
</devicePort>
<!-- Input devices declaration, i.e. Source DEVICE PORT -->
<devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
<devicePort tagName="Built-In Back Mic" type="AUDIO_DEVICE_IN_BACK_MIC" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
<devicePort tagName="FM Tuner" type="AUDIO_DEVICE_IN_FM_TUNER" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
<devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,11025,12000,16000,22050,24000,32000,44100,48000"
channelMasks="AUDIO_CHANNEL_IN_MONO,AUDIO_CHANNEL_IN_STEREO,AUDIO_CHANNEL_IN_FRONT_BACK"/>
samplingRates="8000 11025 12000 16000 22050 24000 32000 44100 48000"
channelMasks="AUDIO_CHANNEL_IN_MONO AUDIO_CHANNEL_IN_STEREO AUDIO_CHANNEL_IN_FRONT_BACK"/>
</devicePort>
<devicePort tagName="BT SCO Headset Mic" type="AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
samplingRates="8000 16000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</devicePort>
<devicePort tagName="Telephony Rx" type="AUDIO_DEVICE_IN_TELEPHONY_RX" role="source">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/>
</devicePort>
<devicePort tagName="USB Device In" type="AUDIO_DEVICE_IN_USB_DEVICE" role="source">
</devicePort>
<devicePort tagName="USB Headset In" type="AUDIO_DEVICE_IN_USB_HEADSET" role="source">
</devicePort>
<!-- Custom Bluetooth Ports Declarations for Dolby Processing -->
<devicePort tagName="BT A2DP Out" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP" role="sink"
encodedFormats="AUDIO_FORMAT_LDAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_AAC AUDIO_FORMAT_SBC">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="44100 48000 88200 96000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
<devicePort tagName="BT A2DP Headphones" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES" role="sink"
encodedFormats="AUDIO_FORMAT_LDAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_AAC AUDIO_FORMAT_SBC">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="44100 48000 88200 96000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
<devicePort tagName="BT A2DP Speaker" type="AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER" role="sink"
encodedFormats="AUDIO_FORMAT_LDAC AUDIO_FORMAT_APTX AUDIO_FORMAT_APTX_HD AUDIO_FORMAT_AAC AUDIO_FORMAT_SBC">
<profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
samplingRates="44100 48000 88200 96000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</devicePort>
</devicePorts>
<!-- route declaration, i.e. list all available sources for a given sink -->
<routes>
<route type="mix" sink="Earpiece"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out"/>
<route type="mix" sink="Speaker"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out"/>
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,immersive_out"/>
<route type="mix" sink="Wired Headset"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,dsd_compress_passthrough"/>
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,dsd_compress_passthrough,immersive_out"/>
<route type="mix" sink="Wired Headphones"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,dsd_compress_passthrough"/>
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,dsd_compress_passthrough,immersive_out"/>
<route type="mix" sink="Line"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out"/>
<route type="mix" sink="HDMI"
@ -367,27 +388,25 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<route type="mix" sink="FM"
sources="primary output"/>
<route type="mix" sink="BT SCO"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,immersive_out"/>
<route type="mix" sink="BT SCO Headset"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,immersive_out"/>
<route type="mix" sink="BT SCO Car Kit"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx"/>
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,immersive_out"/>
<route type="mix" sink="USB Device Out"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback"/>
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback,immersive_out"/>
<route type="mix" sink="USB Headset Out"
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback"/>
sources="primary output,raw,deep_buffer,direct_pcm,compressed_offload,voip_rx,mmap_no_irq_out,hifi_playback,immersive_out"/>
<route type="mix" sink="Telephony Tx"
sources="voice_tx,incall_music_uplink"/>
<route type="mix" sink="voice_rx"
sources="Telephony Rx"/>
<route type="mix" sink="primary input"
sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic,FM Tuner,Telephony Rx"/>
sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,BT SCO Headset Mic,Telephony Rx"/>
<route type="mix" sink="usb_surround_sound"
sources="USB Device In,USB Headset In"/>
<route type="mix" sink="fast input"
sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,Wired Headset Mic"/>
<route type="mix" sink="quad mic"
sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,Wired Headset Mic"/>
<route type="mix" sink="voip_tx"
sources="Built-In Mic,Built-In Back Mic,BT SCO Headset Mic,USB Device In,USB Headset In,Wired Headset Mic"/>
<route type="mix" sink="record_24"
@ -395,6 +414,14 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<route type="mix" sink="mmap_no_irq_in"
sources="Built-In Mic,Built-In Back Mic,Wired Headset Mic,USB Device In,USB Headset In"/>
<route type="mix" sink="hifi_input" sources="USB Device In,USB Headset In" />
<!-- Custom Bluetooth Routes Declaration for Dolby Processing -->
<route type="mix" sink="BT A2DP Out"
sources="primary output,deep_buffer,compressed_offload,voip_rx,immersive_out"/>
<route type="mix" sink="BT A2DP Headphones"
sources="primary output,deep_buffer,compressed_offload,voip_rx,immersive_out"/>
<route type="mix" sink="BT A2DP Speaker"
sources="primary output,deep_buffer,compressed_offload,voip_rx,immersive_out"/>
</routes>
</module>
@ -420,7 +447,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</module>
<!-- Bluetooth Audio HAL -->
<xi:include href="/vendor/etc/bluetooth_audio_policy_configuration.xml"/>
<xi:include href="/vendor/etc/bluetooth_audio_policy_configuration_7_0.xml"/>
<!-- Remote Submix Audio HAL -->
<xi:include href="/vendor/etc/r_submix_audio_policy_configuration.xml"/>

View file

@ -0,0 +1,348 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2015 The Android Open Source 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.
-->
<!-- Volume section defines a volume curve for a given use case and device category.
It contains a list of points of this curve expressing the attenuation in Millibels for a given
volume index from 0 to 100.
<volume stream=”AUDIO_STREAM_MUSIC” deviceCategory=””>
<point>0,-9600</point>
<point>100,0</point>
</volume>
-->
<volumes>
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_HEADSET">
<point>0,-4200</point>
<point>33,-2800</point>
<point>66,-1400</point>
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_A2DP">
<point>0,-4200</point>
<point>33,-2800</point>
<point>66,-1400</point>
<point>100,0</point>
</volume>
<!-- Qinhui.Gu@PSW.MM.AudioServer.Policy, 2019/12/11, add USB_HEADSET device category for tuning separately -->
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_USB_HEADSET">
<point>0,-4200</point>
<point>33,-2800</point>
<point>66,-1400</point>
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_SPEAKER">
<point>0,-2400</point>
<point>33,-1600</point>
<point>66,-800</point>
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EARPIECE">
<point>0,-2400</point>
<point>33,-1600</point>
<point>66,-800</point>
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_HEADSET">
<point>1,-3000</point>
<point>33,-2600</point>
<point>66,-2200</point>
<point>100,-1800</point>
</volume>
<!-- #ifdef
//YaJun.Li@MM.AudioServer.Policy, 2019/08/21,modify for voip and a2dp volume -->
<volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_A2DP">
<point>1,-3000</point>
<point>33,-2600</point>
<point>66,-2200</point>
<point>100,-1800</point>
</volume>
<!-- Qinhui.Gu@PSW.MM.AudioServer.Policy, 2019/12/11, add USB_HEADSET device category for tuning separately -->
<volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_USB_HEADSET">
<point>1,-3000</point>
<point>33,-2600</point>
<point>66,-2200</point>
<point>100,-1800</point>
</volume>
<!-- #endif -->
<volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_SPEAKER"
ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EARPIECE"
ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_HEADSET"
ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_A2DP"
ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_USB_HEADSET"
ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_SPEAKER">
<point>1,-4050</point>
<point>33,-2950</point>
<point>66,-2100</point>
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EARPIECE"
ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA">
<!--yanweibo 20180405 sync device ring volume with speaker for call info brocaste!-->
<point>1,-2970</point>
<point>33,-2010</point>
<point>66,-1020</point>
<point>100,0</point>
<!--modify end!-->
</volume>
<volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_HEADSET">
<point>1,-6300</point>
<point>20,-3600</point>
<point>60,-2300</point>
<point>100,-500</point>
</volume>
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_A2DP"
ref="DEFAULT_MEDIA_VOLUME_CURVE_A2DP"/>
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_USB_HEADSET"
ref="DEFAULT_MEDIA_VOLUME_CURVE_USB_HEADSET"/>
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER"
ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EARPIECE"
ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_HEADSET"
ref="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_A2DP"
ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_USB_HEADSET"
ref="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_SPEAKER">
<!--#ifdef
rich.yu@MM.Audio, 2020/06/12, fix alarm volume can not set to 0
<point>0,-2970</point>-->
<point>1,-2970</point>
<!--#endif /**/-->
<point>33,-2010</point>
<point>66,-1020</point>
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EARPIECE"
ref="DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_HEADSET"
ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_A2DP"
ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_USB_HEADSET"
ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_SPEAKER">
<point>1,-2970</point>
<point>33,-2010</point>
<point>66,-1020</point>
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EARPIECE"
ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_HEADSET">
<!--#ifdef
zhangrun@MM.Audio 2019/08/02, [GCEQ-3989],Improve the minimum volume of the bt-sco voip call
<point>0,-4200</point>
<point>33,-2800</point>
<point>66,-1400</point> -->
<point>0,-2400</point>
<point>33,-1600</point>
<point>66,-800</point>
<!--#endif /**/-->
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_A2DP">
<!--#ifdef
zhangrun@MM.Audio 2019/08/02, [GCEQ-3989],Improve the minimum volume of the bt-sco voip call
<point>0,-4200</point>
<point>33,-2800</point>
<point>66,-1400</point> -->
<point>0,-2400</point>
<point>33,-1600</point>
<point>66,-800</point>
<!--#endif /**/-->
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_USB_HEADSET">
<!--#ifdef
zhangrun@MM.Audio 2019/08/02, [GCEQ-3989],Improve the minimum volume of the bt-sco voip call
<point>0,-4200</point>
<point>33,-2800</point>
<point>66,-1400</point> -->
<point>0,-2400</point>
<point>33,-1600</point>
<point>66,-800</point>
<!--#endif /**/-->
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_SPEAKER">
<point>0,-2400</point>
<point>33,-1600</point>
<point>66,-800</point>
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EARPIECE">
<point>0,-4200</point>
<point>33,-2800</point>
<point>66,-1400</point>
<point>100,0</point>
</volume>
<volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_HEADSET">
<point>1,-3000</point>
<point>33,-2600</point>
<point>66,-2200</point>
<point>100,-1800</point>
</volume>
<volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_A2DP">
<point>1,-3000</point>
<point>33,-2600</point>
<point>66,-2200</point>
<point>100,-1800</point>
</volume>
<volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_USB_HEADSET">
<point>1,-3000</point>
<point>33,-2600</point>
<point>66,-2200</point>
<point>100,-1800</point>
</volume>
<volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_SPEAKER"
ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EARPIECE"
ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_HEADSET">
<point>1,-3000</point>
<point>33,-2600</point>
<point>66,-2200</point>
<point>100,-1800</point>
</volume>
<volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_A2DP">
<point>1,-3000</point>
<point>33,-2600</point>
<point>66,-2200</point>
<point>100,-1800</point>
</volume>
<volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_USB_HEADSET">
<point>1,-3000</point>
<point>33,-2600</point>
<point>66,-2200</point>
<point>100,-1800</point>
</volume>
<volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_SPEAKER">
<!-- modified by yanweibo increase dtmf volume ref="DEFAULT_SYSTEM_VOLUME_CURVE"/ !-->
<point>1,-3000</point>
<point>33,-2400</point>
<point>66,-1800</point>
<point>100,-1000</point>
</volume>
<volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EARPIECE"
ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_HEADSET"
ref="SILENT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_A2DP"
ref="SILENT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_USB_HEADSET"
ref="SILENT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_SPEAKER"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EARPIECE"
ref="SILENT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="SILENT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="SILENT_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_HEADSET"
ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_A2DP"
ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_USB_HEADSET"
ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_SPEAKER"
ref="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EARPIECE"
ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ASSISTANT" deviceCategory="DEVICE_CATEGORY_HEADSET"
ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ASSISTANT" deviceCategory="DEVICE_CATEGORY_A2DP"
ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ASSISTANT" deviceCategory="DEVICE_CATEGORY_USB_HEADSET"
ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ASSISTANT" deviceCategory="DEVICE_CATEGORY_SPEAKER"
ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ASSISTANT" deviceCategory="DEVICE_CATEGORY_EARPIECE"
ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ASSISTANT" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_ASSISTANT" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_HEADSET"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_A2DP"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_USB_HEADSET"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_SPEAKER"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EARPIECE"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_HEADSET"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_A2DP"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_USB_HEADSET"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_SPEAKER"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EARPIECE"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
ref="FULL_SCALE_VOLUME_CURVE"/>
<volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
ref="FULL_SCALE_VOLUME_CURVE"/>
</volumes>

View file

@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2015 The Android Open Source 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.
-->
<!-- Default Volume Tables included by Audio Policy Configuration file -->
<!-- Full Default Volume table for all device category -->
<volumes>
<reference name="FULL_SCALE_VOLUME_CURVE">
<!-- Full Scale reference Volume Curve -->
<point>0,0</point>
<point>100,0</point>
</reference>
<reference name="SILENT_VOLUME_CURVE">
<point>0,-9600</point>
<point>100,-9600</point>
</reference>
<reference name="DEFAULT_SYSTEM_VOLUME_CURVE">
<!-- Default System reference Volume Curve -->
<point>1,-2400</point>
<point>33,-1800</point>
<point>66,-1200</point>
<point>100,-600</point>
</reference>
<reference name="DEFAULT_MEDIA_VOLUME_CURVE">
<!-- Default Media reference Volume Curve -->
<point>1,-5800</point>
<point>20,-4000</point>
<point>60,-1700</point>
<point>100,0</point>
</reference>
<reference name="DEFAULT_MEDIA_VOLUME_CURVE_USB_HEADSET">
<point>1,-6100</point>
<point>20,-4000</point>
<point>60,-1650</point>
<point>100,0</point>
</reference>
<reference name="DEFAULT_MEDIA_VOLUME_CURVE_A2DP">
<point>1,-5800</point>
<point>20,-4000</point>
<point>60,-1700</point>
<point>100,0</point>
</reference>
<reference name="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE">
<!--Default Volume Curve -->
<point>1,-4950</point>
<point>33,-3350</point>
<point>66,-1700</point>
<point>100,0</point>
</reference>
<reference name="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE">
<!-- Default is Speaker Media Volume Curve -->
<!--#ifdef
dujie@MM.Audio, 2020/07/06, reduce the minimum volume loudness -->
<point>1,-5300</point>
<point>20,-3300</point>
<point>60,-1000</point>
<point>100,0</point>
<!--#endif /**/-->
</reference>
<reference name="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE">
<!--Default Volume Curve -->
<point>1,-4950</point>
<point>33,-3350</point>
<point>66,-1700</point>
<point>100,0</point>
</reference>
<reference name="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE">
<!-- Default is Ext Media System Volume Curve -->
<point>1,-5800</point>
<point>20,-4000</point>
<point>60,-2100</point>
<point>100,-1000</point>
</reference>
<reference name="DEFAULT_HEARING_AID_VOLUME_CURVE">
<!-- Default Hearing Aid Volume Curve -->
<point>1,-12700</point>
<point>20,-8000</point>
<point>60,-4000</point>
<point>100,0</point>
</reference>
<!-- **************************************************************** -->
<!-- Non-mutable default volume curves: -->
<!-- * first point is always for index 0 -->
<!-- * attenuation is small enough that stream can still be heard -->
<reference name="DEFAULT_NON_MUTABLE_VOLUME_CURVE">
<!-- Default non-mutable reference Volume Curve -->
<!-- based on DEFAULT_MEDIA_VOLUME_CURVE -->
<point>0,-5800</point>
<point>20,-4000</point>
<point>60,-1700</point>
<point>100,0</point>
</reference>
<reference name="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE">
<!--Default non-mutable Volume Curve for headset -->
<!-- based on DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE -->
<point>0,-4950</point>
<point>33,-3350</point>
<point>66,-1700</point>
<point>100,0</point>
</reference>
<reference name="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE">
<!-- Default non-mutable Speaker Volume Curve -->
<!-- based on DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE -->
<point>0,-5800</point>
<point>20,-4000</point>
<point>60,-1700</point>
<point>100,0</point>
</reference>
<reference name="DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE">
<!--Default non-mutable Volume Curve -->
<!-- based on DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE -->
<point>0,-4950</point>
<point>33,-3350</point>
<point>66,-1700</point>
<point>100,0</point>
</reference>
<reference name="DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE">
<!-- Default non-mutable Ext Media System Volume Curve -->
<!-- based on DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE -->
<point>0,-5800</point>
<point>20,-4000</point>
<point>60,-2100</point>
<point>100,-1000</point>
</reference>
<reference name="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE">
<!-- Default non-mutable Hearing Aid Volume Curve -->
<!-- based on DEFAULT_HEARING_AID_VOLUME_CURVE -->
<point>0,-12700</point>
<point>20,-8000</point>
<point>60,-4000</point>
<point>100,0</point>
</reference>
</volumes>

22
camera/Android.bp Normal file
View file

@ -0,0 +1,22 @@
//
// Copyright (C) 2022 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.
cc_library_static {
name: "libcameraservice_extension.xiaomi_sm8350",
srcs: ["CameraProviderExtension.cpp"],
include_dirs: [
"frameworks/av/services/camera/libcameraservice/common"
],
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (C) 2024 LibreMobileOS Foundation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "CameraProviderExtension.h"
#include <fstream>
#define TORCH_BRIGHTNESS "brightness"
#define TORCH_MAX_BRIGHTNESS "max_brightness"
#define TOGGLE_SWITCH "/sys/devices/platform/soc/c440000.qcom,spmi/spmi-0/spmi0-02/c440000.qcom,spmi:qcom,pm8350c@2:qcom,flash_led@ee00/leds/led:switch_1/brightness"
static std::string kTorchLedPath = "/sys/devices/platform/soc/c440000.qcom,spmi/spmi-0/spmi0-02/c440000.qcom,spmi:qcom,pm8350c@2:qcom,flash_led@ee00/leds/led:torch_1";
/**
* Write value to path and close file.
*/
template <typename T>
static void set(const std::string& path, const T& value) {
std::ofstream file(path);
file << value;
}
/**
* Read value from the path and close file.
*/
template <typename T>
static T get(const std::string& path, const T& def) {
std::ifstream file(path);
T result;
file >> result;
return file.fail() ? def : result;
}
bool supportsTorchStrengthControlExt() {
return true;
}
bool supportsSetTorchModeExt() {
return false;
}
int32_t getTorchDefaultStrengthLevelExt() {
return 80;
}
int32_t getTorchMaxStrengthLevelExt() {
// In our device, both LEDs has same maximum value
// so get from one.
auto node = kTorchLedPath + "/" + TORCH_MAX_BRIGHTNESS;
return 750;
}
int32_t getTorchStrengthLevelExt() {
// We write same value in the both LEDs,
// so get from one.
auto node = kTorchLedPath + "/" + TORCH_BRIGHTNESS;
return get(node, 0);
}
void setTorchStrengthLevelExt(int32_t torchStrength, bool enabled) {
set(TOGGLE_SWITCH, 0);
auto node = kTorchLedPath + "/" + TORCH_BRIGHTNESS;
set(node, torchStrength);
if (enabled)
set(TOGGLE_SWITCH, 255);
}
void setTorchModeExt(bool enabled) {
int32_t strength = getTorchDefaultStrengthLevelExt();
setTorchStrengthLevelExt(enabled ? strength : 0, enabled);
}

View file

@ -41,8 +41,8 @@ PRODUCT_PACKAGES += \
audio.usb.default
PRODUCT_PACKAGES += \
android.hardware.audio@6.0-impl \
android.hardware.audio.effect@6.0-impl \
android.hardware.audio@7.0-impl \
android.hardware.audio.effect@7.0-impl \
android.hardware.audio.service \
android.hardware.soundtrigger@2.3-impl
@ -65,9 +65,11 @@ PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/audio/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/sku_yupik/audio_policy_configuration.xml
PRODUCT_COPY_FILES += \
frameworks/av/services/audiopolicy/config/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
frameworks/av/services/audiopolicy/config/bluetooth_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_audio_policy_configuration.xml \
frameworks/av/services/audiopolicy/config/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
$(LOCAL_PATH)/audio/audio_policy_volumes.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_volumes.xml \
$(LOCAL_PATH)/audio/default_volume_tables.xml:$(TARGET_COPY_OUT_VENDOR)/etc/default_volume_tables.xml \
PRODUCT_COPY_FILES += \
frameworks/av/services/audiopolicy/config/bluetooth_audio_policy_configuration_7_0.xml:$(TARGET_COPY_OUT_VENDOR)/etc/bluetooth_audio_policy_configuration_7_0.xml \
frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/r_submix_audio_policy_configuration.xml \
frameworks/av/services/audiopolicy/config/usb_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/usb_audio_policy_configuration.xml \
frameworks/native/data/etc/android.hardware.audio.low_latency.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.audio.low_latency.xml \
@ -125,9 +127,18 @@ PRODUCT_COPY_FILES += \
frameworks/native/data/etc/android.hardware.camera.full.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.camera.full.xml \
frameworks/native/data/etc/android.hardware.camera.raw.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.camera.raw.xml
# Config Store
PRODUCT_PACKAGES += \
vendor.qti.hardware.capabilityconfigstore@1.0 \
vendor.qti.hardware.capabilityconfigstore@1.0.vendor
# DebugFS
PRODUCT_SET_DEBUGFS_RESTRICTIONS := true
# Device-specific settings
PRODUCT_PACKAGES += \
XiaomiParts
# Display
PRODUCT_PACKAGES += \
android.hardware.graphics.mapper@3.0-impl-qti-display \
@ -141,6 +152,9 @@ PRODUCT_PACKAGES += \
PRODUCT_COPY_FILES += \
hardware/qcom-caf/sm8350/display/config/snapdragon_color_libs_config.xml:$(TARGET_COPY_OUT_VENDOR)/etc/snapdragon_color_libs_config.xml
# Dolby
$(call inherit-product, hardware/dolby/dolby.mk)
# DRM
PRODUCT_PACKAGES += \
android.hardware.drm-service.clearkey

View file

@ -40,6 +40,7 @@ lib_fixups: lib_fixups_user_type = {
'libmmosal',
'vendor.qti.hardware.wifidisplaysession@1.0',
'vendor.qti.imsrtpservice@3.0',
'vendor.qti.diaghal@1.0',
): lib_fixup_vendor_suffix,
}

View file

@ -22,7 +22,7 @@
# Log level
# EL_LOG_OFF = 0, EL_ERROR = 1, EL_WARNING = 2, EL_INFO = 3, EL_DEBUG = 4, EL_VERBOSE = 5, EL_LOG_ALL = 100
LOWI_LOG_LEVEL = 3
LOWI_LOG_LEVEL = 2
LOWI_USE_LOWI_LP = 0
LOWI_HE_RTT_SUPPORT = 1
LOWI_USE_NLMSG_FOR_CAPS = 1

View file

@ -39,7 +39,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<hal format="hidl">
<name>android.hardware.audio</name>
<transport>hwbinder</transport>
<version>6.0</version>
<version>7.0</version>
<interface>
<name>IDevicesFactory</name>
<instance>default</instance>
@ -48,7 +48,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<hal format="hidl">
<name>android.hardware.audio.effect</name>
<transport>hwbinder</transport>
<version>6.0</version>
<version>7.0</version>
<interface>
<name>IEffectsFactory</name>
<instance>default</instance>

View file

@ -103,6 +103,7 @@
-->
<MediaCodecs>
<Include href="media_codecs_dolby_audio.xml" />
<Settings>
<Domain name="telephony" enabled="true" />
<Setting name="max-video-encoder-input-buffers" value="11" />

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016-2023 crDroid Android 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.
-->
<resources>
<!-- If not zero, limits the internal screen recorder's framerate to the set value. -->
<integer name="config_screenRecorderMaxFramerate">120</integer>
</resources>

View file

@ -203,9 +203,6 @@
<item>"/system/bin/surfaceflinger"</item>
</string-array>
<!-- Should the pinner service pin the Home application? -->
<bool name="config_pinnerHomeApp">true</bool>
<!-- Enable doze mode
ComponentName of a dream to show whenever the system would otherwise have gone to sleep. -->
<string translatable="false" name="config_dozeComponent">com.android.systemui/com.android.systemui.doze.DozeService</string>

View file

@ -55,6 +55,9 @@
<item>0</item>
</integer-array>
<!-- Whether usage of the proximity sensor during doze is supported -->
<bool name="doze_proximity_sensor_supported">false</bool>
<!-- Preferred max refresh rate at keyguard, if supported by the display. -->
<integer name="config_keyguardMaxRefreshRate">60</integer>
</resources>

View file

@ -15,6 +15,9 @@
-->
<resources>
<!-- Device specific doze package -->
<string name="config_customDozePackage" translatable="false">org.lineageos.settings/org.lineageos.settings.doze.DozeSettingsActivity</string>
<!-- The number of vibration intensity levels supported by the device.
Note that this should correspond to the ability to vary the vibration amplitude, with

20
parts/Android.bp Normal file
View file

@ -0,0 +1,20 @@
//
// Copyright (C) 2017-2020 The LineageOS Project
//
// SPDX-License-Identifier: Apache-2.0
//
android_app {
name: "XiaomiParts",
srcs: ["src/**/*.java"],
certificate: "platform",
platform_apis: true,
system_ext_specific: true,
privileged: true,
static_libs: [
"org.lineageos.settings.resources",
],
}

259
parts/AndroidManifest.xml Normal file
View file

@ -0,0 +1,259 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015-2016 The CyanogenMod Project
2017-2018 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.lineageos.settings"
xmlns:tools="http://schemas.android.com/tools"
android:versionCode="1"
android:versionName="1.0"
android:sharedUserId="android.uid.system">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
<protected-broadcast android:name="com.android.systemui.doze.pulse" />
<uses-sdk
android:minSdkVersion="24"
android:targetSdkVersion="30"/>
<application
android:label="@string/device_settings_app_name"
android:persistent="true"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true"
android:theme="@style/Theme.SubSettingsBase">
<receiver android:name=".BootCompletedReceiver">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<activity
android:name=".doze.DozeSettingsActivity"
android:label="@string/ambient_display_title">
</activity>
<service android:name=".doze.DozeService"
android:permission="XiaomiDozeService">
</service>
<activity
android:name=".thermal.ThermalActivity"
android:label="@string/thermal_title">
<intent-filter>
<action android:name="com.android.settings.action.IA_SETTINGS" />
</intent-filter>
<meta-data
android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.battery" />
<meta-data
android:name="com.android.settings.summary"
android:resource="@string/thermal_summary" />
</activity>
<service
android:name=".thermal.ThermalService"
android:permission="ThermalService">
</service>
<activity
android:name=".touchsampling.TouchSamplingSettingsActivity"
android:label="@string/htsr_enable_title"
android:theme="@style/Theme.SubSettingsBase"
android:exported="false">
<intent-filter>
<action android:name="com.android.settings.action.IA_SETTINGS" />
</intent-filter>
<meta-data
android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.display" />
<meta-data
android:name="com.android.settings.summary"
android:resource="@string/htsr_enable_summary" />
</activity>
<service
android:name=".touchsampling.TouchSamplingTileService"
android:icon="@drawable/ic_htsr"
android:label="@string/htsr_enable_title"
android:exported="true"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
<activity
android:name=".speaker.ClearSpeakerActivity"
android:label="@string/clear_speaker_title">
<intent-filter>
<action android:name="com.android.settings.action.IA_SETTINGS" />
</intent-filter>
<meta-data
android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.sound" />
<meta-data
android:name="com.android.settings.summary"
android:resource="@string/clear_speaker_summary" />
</activity>
<activity
android:name=".refreshrate.RefreshActivity"
android:label="@string/refresh_title"
android:exported="false">
<intent-filter>
<action android:name="com.android.settings.action.IA_SETTINGS" />
</intent-filter>
<meta-data
android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.display" />
<meta-data
android:name="com.android.settings.summary"
android:resource="@string/refresh_summary" />
</activity>
<service
android:name=".refreshrate.RefreshService"
android:exported="true"
android:permission="RefreshService">
</service>
<service
android:name=".thermal.ThermalTileService"
android:icon="@drawable/ic_thermal"
android:label="@string/thermal_title"
android:exported="true"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action
android:name="android.service.quicksettings.action.QS_TILE"/>
</intent-filter>
</service>
<service
android:name=".display.DcDimmingTileService"
android:exported="true"
android:icon="@drawable/ic_dc_tile"
android:label="@string/dc_dimming_enable_title"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action
android:name="android.service.quicksettings.action.QS_TILE"/>
</intent-filter>
</service>
<activity
android:name=".display.DcDimmingSettingsActivity"
android:label="@string/dc_dimming_enable_title"
android:exported="true"
android:theme="@style/Theme.SubSettingsBase">
<intent-filter>
<action android:name="com.android.settings.action.IA_SETTINGS" />
</intent-filter>
<meta-data
android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.display" />
<meta-data
android:name="com.android.settings.summary"
android:resource="@string/dc_dimming_enable_summary" />
</activity>
<activity
android:name=".hbm.HBMActivity"
android:label="@string/hbm_fragment_title"
android:exported="false"
android:theme="@style/Theme.SubSettingsBase">
<intent-filter>
<action android:name="com.android.settings.action.IA_SETTINGS" />
</intent-filter>
<meta-data
android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.display" />
<meta-data
android:name="com.android.settings.summary"
android:resource="@string/hbm_fragment_summary" />
</activity>
<activity
android:name=".hbm.HBMFragment" />
<service
android:name=".hbm.AutoHBMService"
android:exported="false" />
<service
android:name=".hbm.HBMModeTileService"
android:icon="@drawable/ic_hbm_tile"
android:label="@string/hbm_mode_title"
android:exported="true"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action
android:name="android.service.quicksettings.action.QS_TILE"/>
</intent-filter>
</service>
<!-- GameBar Overlay -->
<activity
android:name=".gameoverlay.GameOverlaySettingsActivity"
android:label="@string/game_overlay_title"
android:theme="@style/Theme.SubSettingsBase"
android:exported="true">
<intent-filter>
<action android:name="com.android.settings.action.IA_SETTINGS" />
</intent-filter>
<meta-data
android:name="com.android.settings.category"
android:value="com.android.settings.category.ia.system" />
<meta-data
android:name="com.android.settings.summary"
android:resource="@string/game_overlay_summary" />
<meta-data
android:name="com.android.settings.icon"
android:resource="@drawable/ic_gamebar" />
</activity>
<!-- GameBar Overlay Tile Service -->
<service
android:name=".gameoverlay.GameOverlayTileService"
android:label="@string/game_overlay_tile_label"
android:icon="@drawable/ic_gamebar_overlay_tile"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
android:exported="true">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
<meta-data
android:name="android.service.quicksettings.TOGGLEABLE_TILE"
android:value="true" />
</service>
<!-- GameBar BootReceiver -->
<receiver
android:name="org.lineageos.settings.gameoverlay.GameOverlayBootReceiver"
android:exported="true"
android:enabled="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
</manifest>

View file

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#000"
android:pathData="M20 4H4C2.9 4 2 4.9 2 6v12c0 1.1 0.9 2 2 2h16c1.1 0 2-0.9 2-2V6c0-1.1-0.9-2-2-2zm0 14H4V6h16v12z"/>
<path
android:fillColor="#000"
android:pathData="M8.29 15.71c-0.49-0.49-0.88-1.06-1.14-1.7c-0.26-0.64-0.4-1.32-0.4-2.01c0-1.35 0.52-2.69 1.53-3.72L7.05 7.05C5.68 8.41 5 10.21 5 12s0.68 3.59 2.06 4.94l1.23-1.23zM12 15.5c1.93 0 3.5-1.57 3.5-3.5S13.93 8.5 12 8.5S8.5 10.07 8.5 12s1.57 3.5 3.5 3.5zm0-5c0.83 0 1.5 0.67 1.5 1.5s-0.67 1.5-1.5 1.5s-1.5-0.67-1.5-1.5s0.67-1.5 1.5-1.5zm3.72 5.22l1.23 1.23C18.32 15.59 19 13.79 19 12s-0.68-3.59-2.06-4.94l-1.23 1.23c0.49 0.49 0.88 1.06 1.14 1.7c0.26 0.64 0.4 1.32 0.4 2.01c0 1.35-0.52 2.69-1.53 3.72z"/>
</vector>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018-2021 crDroid Android 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24.0dp"
android:height="24.0dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0" >
<path
android:fillColor="?android:attr/colorControlNormal"
android:pathData="M19,13H5V11H19V13Z" />
</vector>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018-2021 crDroid Android 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24.0dp"
android:height="24.0dp"
android:viewportWidth="48.0"
android:viewportHeight="48.0" >
<path
android:fillColor="?android:attr/colorControlNormal"
android:pathData="M38.0,26.0L26.0,26.0l0.0,12.0l-4.0,0.0L22.0,26.0L10.0,26.0l0.0,-4.0l12.0,0.0L22.0,10.0l4.0,0.0l0.0,12.0l12.0,0.0l0.0,4.0z" />
</vector>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018-2021 crDroid Android 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24.0dp"
android:height="24.0dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0" >
<path
android:fillColor="?android:attr/colorControlNormal"
android:pathData="M12.5,8C9.85,8 7.45,9 5.6,10.6L2,7V16H11L7.38,12.38C8.77,11.22 10.54,10.5 12.5,10.5C16.04,10.5 19.05,12.81 20.1,16L22.47,15.22C21.08,11.03 17.15,8 12.5,8Z" />
</vector>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#fff" android:pathData="M14,8.5A1.5,1.5 0 0,0 12.5,10A1.5,1.5 0 0,0 14,11.5A1.5,1.5 0 0,0 15.5,10A1.5,1.5 0 0,0 14,8.5M14,12.5A1.5,1.5 0 0,0 12.5,14A1.5,1.5 0 0,0 14,15.5A1.5,1.5 0 0,0 15.5,14A1.5,1.5 0 0,0 14,12.5M10,17A1,1 0 0,0 9,18A1,1 0 0,0 10,19A1,1 0 0,0 11,18A1,1 0 0,0 10,17M10,8.5A1.5,1.5 0 0,0 8.5,10A1.5,1.5 0 0,0 10,11.5A1.5,1.5 0 0,0 11.5,10A1.5,1.5 0 0,0 10,8.5M14,20.5A0.5,0.5 0 0,0 13.5,21A0.5,0.5 0 0,0 14,21.5A0.5,0.5 0 0,0 14.5,21A0.5,0.5 0 0,0 14,20.5M14,17A1,1 0 0,0 13,18A1,1 0 0,0 14,19A1,1 0 0,0 15,18A1,1 0 0,0 14,17M21,13.5A0.5,0.5 0 0,0 20.5,14A0.5,0.5 0 0,0 21,14.5A0.5,0.5 0 0,0 21.5,14A0.5,0.5 0 0,0 21,13.5M18,5A1,1 0 0,0 17,6A1,1 0 0,0 18,7A1,1 0 0,0 19,6A1,1 0 0,0 18,5M18,9A1,1 0 0,0 17,10A1,1 0 0,0 18,11A1,1 0 0,0 19,10A1,1 0 0,0 18,9M18,17A1,1 0 0,0 17,18A1,1 0 0,0 18,19A1,1 0 0,0 19,18A1,1 0 0,0 18,17M18,13A1,1 0 0,0 17,14A1,1 0 0,0 18,15A1,1 0 0,0 19,14A1,1 0 0,0 18,13M10,12.5A1.5,1.5 0 0,0 8.5,14A1.5,1.5 0 0,0 10,15.5A1.5,1.5 0 0,0 11.5,14A1.5,1.5 0 0,0 10,12.5M10,7A1,1 0 0,0 11,6A1,1 0 0,0 10,5A1,1 0 0,0 9,6A1,1 0 0,0 10,7M10,3.5A0.5,0.5 0 0,0 10.5,3A0.5,0.5 0 0,0 10,2.5A0.5,0.5 0 0,0 9.5,3A0.5,0.5 0 0,0 10,3.5M10,20.5A0.5,0.5 0 0,0 9.5,21A0.5,0.5 0 0,0 10,21.5A0.5,0.5 0 0,0 10.5,21A0.5,0.5 0 0,0 10,20.5M3,13.5A0.5,0.5 0 0,0 2.5,14A0.5,0.5 0 0,0 3,14.5A0.5,0.5 0 0,0 3.5,14A0.5,0.5 0 0,0 3,13.5M14,3.5A0.5,0.5 0 0,0 14.5,3A0.5,0.5 0 0,0 14,2.5A0.5,0.5 0 0,0 13.5,3A0.5,0.5 0 0,0 14,3.5M14,7A1,1 0 0,0 15,6A1,1 0 0,0 14,5A1,1 0 0,0 13,6A1,1 0 0,0 14,7M21,10.5A0.5,0.5 0 0,0 21.5,10A0.5,0.5 0 0,0 21,9.5A0.5,0.5 0 0,0 20.5,10A0.5,0.5 0 0,0 21,10.5M6,5A1,1 0 0,0 5,6A1,1 0 0,0 6,7A1,1 0 0,0 7,6A1,1 0 0,0 6,5M3,9.5A0.5,0.5 0 0,0 2.5,10A0.5,0.5 0 0,0 3,10.5A0.5,0.5 0 0,0 3.5,10A0.5,0.5 0 0,0 3,9.5M6,9A1,1 0 0,0 5,10A1,1 0 0,0 6,11A1,1 0 0,0 7,10A1,1 0 0,0 6,9M6,17A1,1 0 0,0 5,18A1,1 0 0,0 6,19A1,1 0 0,0 7,18A1,1 0 0,0 6,17M6,13A1,1 0 0,0 5,14A1,1 0 0,0 6,15A1,1 0 0,0 7,14A1,1 0 0,0 6,13Z" />
</vector>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M23.5,17L18.5,22L15,18.5L16.5,17L18.5,19L22,15.5L23.5,17M12,9A3,3 0 0,1 15,12A3,3 0 0,1 12,15A3,3 0 0,1 9,12A3,3 0 0,1 12,9M12,4.5C17,4.5 21.27,7.61 23,12C22.75,12.65 22.44,13.26 22.08,13.85C21.5,13.5 20.86,13.25 20.18,13.12L20.82,12C19.17,8.64 15.76,6.5 12,6.5C8.24,6.5 4.83,8.64 3.18,12C4.83,15.36 8.24,17.5 12,17.5L13.21,17.43C13.07,17.93 13,18.46 13,19V19.46L12,19.5C7,19.5 2.73,16.39 1,12C2.73,7.61 7,4.5 12,4.5Z" />
</vector>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M17,19V5H7V19H17M17,1A2,2 0 0,1 19,3V21A2,2 0 0,1 17,23H7C5.89,23 5,22.1 5,21V3C5,1.89 5.89,1 7,1H17M9,7H15V9H9V7M9,11H13V13H9V11Z" />
</vector>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M14.3,16L13.6,14H10.4L9.7,16H7.8L11,7H13L16.2,16H14.3M20,8.69V4H15.31L12,0.69L8.69,4H4V8.69L0.69,12L4,15.31V20H8.69L12,23.31L15.31,20H20V15.31L23.31,12L20,8.69M10.85,12.65H13.15L12,9L10.85,12.65Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M12,8A4,4 0 0,0 8,12A4,4 0 0,0 12,16A4,4 0 0,0 16,12A4,4 0 0,0 12,8M12,18A6,6 0 0,1 6,12A6,6 0 0,1 12,6A6,6 0 0,1 18,12A6,6 0 0,1 12,18M20,8.69V4H15.31L12,0.69L8.69,4H4V8.69L0.69,12L4,15.31V20H8.69L12,23.31L15.31,20H20V15.31L23.31,12L20,8.69Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000" android:pathData="M12,18V6A6,6 0 0,1 18,12A6,6 0 0,1 12,18M20,15.31L23.31,12L20,8.69V4H15.31L12,0.69L8.69,4H4V8.69L0.69,12L4,15.31V20H8.69L12,23.31L15.31,20H20V15.31Z"/>
</vector>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24.0dp"
android:height="24.0dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#FF000000"
android:pathData="M7,6H17A6,6 0 0,1 23,12A6,6 0 0,1 17,18C15.22,18 13.63,17.23 12.53,16H11.47C10.37,17.23 8.78,18 7,18A6,6 0 0,1 1,12A6,6 0 0,1 7,6M6,9V11H4V13H6V15H8V13H10V11H8V9H6M15.5,12A1.5,1.5 0 0,0 14,13.5A1.5,1.5 0 0,0 15.5,15A1.5,1.5 0 0,0 17,13.5A1.5,1.5 0 0,0 15.5,12M18.5,9A1.5,1.5 0 0,0 17,10.5A1.5,1.5 0 0,0 18.5,12A1.5,1.5 0 0,0 20,10.5A1.5,1.5 0 0,0 18.5,9Z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="40dp"
android:height="40dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M189,800Q129,800 86.5,757Q44,714 42,653Q42,644 43,635Q44,626 46,617L130,281Q144,227 187,193.5Q230,160 285,160L675,160Q730,160 773,193.5Q816,227 830,281L914,617Q916,626 917.5,635.5Q919,645 919,654Q919,715 875.5,757.5Q832,800 771,800Q729,800 693,778Q657,756 639,718L611,660Q606,650 596,645Q586,640 575,640L385,640Q374,640 364,645Q354,650 349,660L321,718Q303,756 267,778Q231,800 189,800ZM540.12,433.33Q554.33,433.33 563.83,423.72Q573.33,414.1 573.33,399.88Q573.33,385.67 563.72,376.17Q554.1,366.67 539.88,366.67Q525.67,366.67 516.17,376.28Q506.67,385.9 506.67,400.12Q506.67,414.33 516.28,423.83Q525.9,433.33 540.12,433.33ZM620.12,353.33Q634.33,353.33 643.83,343.72Q653.33,334.1 653.33,319.88Q653.33,305.67 643.72,296.17Q634.1,286.67 619.88,286.67Q605.67,286.67 596.17,296.28Q586.67,305.9 586.67,320.12Q586.67,334.33 596.28,343.83Q605.9,353.33 620.12,353.33ZM620.12,513.33Q634.33,513.33 643.83,503.72Q653.33,494.1 653.33,479.88Q653.33,465.67 643.72,456.17Q634.1,446.67 619.88,446.67Q605.67,446.67 596.17,456.28Q586.67,465.9 586.67,480.12Q586.67,494.33 596.28,503.83Q605.9,513.33 620.12,513.33ZM700.12,433.33Q714.33,433.33 723.83,423.72Q733.33,414.1 733.33,399.88Q733.33,385.67 723.72,376.17Q714.1,366.67 699.88,366.67Q685.67,366.67 676.17,376.28Q666.67,385.9 666.67,400.12Q666.67,414.33 676.28,423.83Q685.9,433.33 700.12,433.33ZM340.08,496.67Q351.67,496.67 359.17,489.11Q366.67,481.56 366.67,470L366.67,426.67L410,426.67Q421.56,426.67 429.11,419.09Q436.67,411.51 436.67,399.92Q436.67,388.33 429.11,380.83Q421.56,373.33 410,373.33L366.67,373.33L366.67,330Q366.67,318.44 359.09,310.89Q351.51,303.33 339.92,303.33Q328.33,303.33 320.83,310.89Q313.33,318.44 313.33,330L313.33,373.33L270,373.33Q258.44,373.33 250.89,380.91Q243.33,388.49 243.33,400.08Q243.33,411.67 250.89,419.17Q258.44,426.67 270,426.67L313.33,426.67L313.33,470Q313.33,481.56 320.91,489.11Q328.49,496.67 340.08,496.67Z"/>
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="#000"
android:pathData="M11,4V1H13V4ZM11,23V20H13V23ZM20,13V11H23V13ZM1,13V11H4V13ZM18.7,6.7 L17.3,5.3 19.05,3.5 20.5,4.95ZM4.95,20.5 L3.5,19.05 5.3,17.3 6.7,18.7ZM19.05,20.5 L17.3,18.7 18.7,17.3 20.5,19.05ZM5.3,6.7 L3.5,4.95 4.95,3.5 6.7,5.3ZM12,18Q9.5,18 7.75,16.25Q6,14.5 6,12Q6,9.5 7.75,7.75Q9.5,6 12,6Q14.5,6 16.25,7.75Q18,9.5 18,12Q18,14.5 16.25,16.25Q14.5,18 12,18ZM12,16Q13.675,16 14.838,14.837Q16,13.675 16,12Q16,10.325 14.838,9.162Q13.675,8 12,8Q10.325,8 9.163,9.162Q8,10.325 8,12Q8,13.675 9.163,14.837Q10.325,16 12,16ZM12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Z"/>
</vector>

View file

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#000"
android:pathData="M20.22,10l-4.15,0.01c-0.16,-0.01 -0.31,0.02 -0.45,0.08l-0.59,0.26L13.2,6.25c-0.56,-1.26 -2.04,-1.83 -3.3,-1.27s-1.83,2.04 -1.27,3.3l3.3,7.45l-1.87,0.39c-0.19,0.05 -0.99,0.27 -1.36,1.21L8,19.19l6.78,2.67c0.49,0.19 1.05,0.18 1.53,-0.04l5.99,-2.65c0.89,-0.4 1.37,-1.38 1.13,-2.32l-1.36,-5.34C21.85,10.65 21.1,10.04 20.22,10zM21.49,17.34L15.5,20l-4.92,-1.96l4.18,-0.88l-4.3,-9.7c-0.11,-0.25 0,-0.55 0.25,-0.66c0.25,-0.11 0.55,0 0.66,0.25l2.5,5.65l1.61,-0.71L20.13,12L21.49,17.34zM2.06,5.56L1,4.5L4.5,1L8,4.5L6.94,5.56L5.32,3.94C5.11,4.76 5,5.62 5,6.5c0,2.42 0.82,4.65 2.2,6.43L6.13,14C4.49,11.95 3.5,9.34 3.5,6.5c0,-0.92 0.1,-1.82 0.3,-2.68L2.06,5.56z"/>
</vector>

View file

@ -0,0 +1,11 @@
<!-- drawable/ic_info_outline.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#000"
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z" />
</vector>

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorAccent">
<path
android:fillColor="#ff000000"
android:pathData="M17 1.01L7 1C5.9 1 5 1.9 5 3v4h2V3h10v18H7v-4H5v4c0 1.1 0.9 2 2 2h10c1.1 0 2-0.9 2-2V3c0-1.1-0.9-1.99-2-1.99Z"/>
<path
android:fillColor="#ff000000"
android:pathData="M1 8v1.56h1.56v6.22H4.1V8H1Z"/>
<path
android:fillColor="#ff000000"
android:pathData="M4.89 8v1.56H8v1.55H6.44c-0.4 0-0.8 0.17-1.1 0.46-0.29 0.29-0.45 0.68-0.45 1.1v3.1h4.67v-1.55H6.44v-1.55H8c0.41 0 0.8-0.17 1.1-0.46 0.3-0.3 0.46-0.69 0.46-1.1V9.56c0-0.42-0.17-0.81-0.46-1.1C8.8 8.16 8.41 8 8 8H4.89Z"/>
<path
android:fillColor="#ff000000"
android:strokeColor="#ff000000"
android:strokeWidth="1"
android:pathData="M11.89 9.06h-0.5v0.5 4.66 0.5h0.5 1.55 0.5v-0.5-4.66-0.5h-0.5-1.55ZM11.14 8.8c0.2-0.2 0.47-0.31 0.75-0.31h1.55c0.28 0 0.55 0.11 0.75 0.3 0.2 0.2 0.31 0.48 0.31 0.76v4.66c0 0.28-0.11 0.55-0.3 0.75-0.2 0.2-0.48 0.3-0.76 0.3H11.9c-0.28 0-0.55-0.1-0.75-0.3-0.2-0.2-0.3-0.47-0.3-0.75V9.56c0-0.28 0.1-0.55 0.3-0.75Z"/>
</vector>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorAccent">
<path
android:fillColor="#ff000000"
android:pathData="M6.55 8c-0.4 0-0.8 0.16-1.1 0.46C5.17 8.75 5 9.14 5 9.56v4.66c0 0.4 0.16 0.8 0.46 1.1 0.29 0.29 0.68 0.45 1.1 0.45H8.1c0.41 0 0.8-0.16 1.1-0.46 0.29-0.29 0.45-0.68 0.45-1.1v-1.55c0-0.41-0.16-0.8-0.45-1.1-0.3-0.29-0.69-0.45-1.1-0.45H6.55V9.55h3.11V8h-3.1Zm0 4.66h1.56v1.56H6.55v-1.56Z"/>
<path
android:fillColor="#ff000000"
android:pathData="M12 8c-0.42 0-0.81 0.16-1.1 0.46-0.3 0.29-0.46 0.68-0.46 1.1v4.66c0 0.4 0.16 0.8 0.45 1.1 0.3 0.29 0.69 0.45 1.1 0.45h1.56c0.4 0 0.8-0.16 1.1-0.46 0.29-0.29 0.45-0.68 0.45-1.1V9.56c0-0.4-0.16-0.8-0.46-1.1C14.35 8.17 13.96 8 13.54 8H12Zm0 1.55h1.55v4.67h-1.56V9.55Z"/>
<path
android:fillColor="#ff000000"
android:pathData="M17 1.01L7 1C5.9 1 5 1.9 5 3v4h2V3h10v18H7v-4H5v4c0 1.1 0.9 2 2 2h10c1.1 0 2-0.9 2-2V3c0-1.1-0.9-1.99-2-1.99Z"/>
</vector>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorAccent">
<path
android:fillColor="#ff000000"
android:pathData="M17 3.01V15l2 2V3.01c0-1.1-0.9-1.99-2-1.99L7 1C6 0.99 5 1.99 5 2.99L7 5V3.01h10Zm4.2 18.19L19 19.01l-2-2-10-10-2-2-2.19-2.19L1.4 4.23 5 7.84v13.17c0 1.1 0.9 2 2 2h10c0.85 0 1.58-0.55 1.87-1.3l0.91 0.91 1.41-1.42ZM17 21.01H7L17 21v-0.99 1Zm-10 0V9.84l10 10.17V21L7 21.01Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<!-- drawable/music_clef_bass.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
<path android:fillColor="#000" android:pathData="M18.5 5A1.5 1.5 0 1 1 17 6.5A1.5 1.5 0 0 1 18.5 5M18.5 11A1.5 1.5 0 1 1 17 12.5A1.5 1.5 0 0 1 18.5 11M10 4A5 5 0 0 0 5 9V10A2 2 0 1 0 7.18 8A3 3 0 0 1 10 6A4 4 0 0 1 14 10C14 13.59 11.77 16.19 7 18.2L7.76 20.04C13.31 17.72 16 14.43 16 10A6 6 0 0 0 10 4Z" />
</vector>

View file

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M17 3H21V5H17V3M17 7H21V9H17V7M17 11H21V13H17.75L17 12.1V11M21 15V17H19C19 16.31 18.9 15.63 18.71 15H21M7 3V5H3V3H7M7 7V9H3V7H7M7 11V12.1L6.25 13H3V11H7M3 15H5.29C5.1 15.63 5 16.31 5 17H3V15M15 13V5C15 3.34 13.66 2 12 2S9 3.34 9 5V13C6.79 14.66 6.34 17.79 8 20S12.79 22.66 15 21 17.66 16.21 16 14C15.72 13.62 15.38 13.28 15 13M12 4C12.55 4 13 4.45 13 5V8H11V5C11 4.45 11.45 4 12 4Z" />
</vector>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<group
android:scaleX="5.50297"
android:scaleY="5.52411"
android:translateX="-59.0634"
android:translateY="-57.934">
<path
android:fillColor="?android:attr/colorAccent"
android:fillType="evenOdd"
android:pathData="M10.961 13.514c0 -1.078 0.874 -1.952 1.953 -1.952 0.555 0 1.057 0.232 1.412 0.604l-0.583 0.141c-0.236 -0.162 -0.522 -0.257 -0.829 -0.257 -0.809 0 -1.465 0.655 -1.465 1.464l0 0c0 0.135 -0.109 0.244 -0.244 0.244 -0.134 0 -0.244 -0.109 -0.244 -0.244l0 0zm3.417 0c0 -0.094 -0.009 -0.185 -0.026 -0.274l0.429 -0.297c0.055 0.181 0.085 0.373 0.085 0.571 0 0.135 -0.109 0.244 -0.244 0.244 -0.135 0 -0.244 -0.109 -0.244 -0.244l0 0zm-0.02 -1.097c0.102 -0.028 0.212 0.022 0.256 0.121 0.045 0.101 0.007 0.219 -0.085 0.275l0 0 -1.313 0.833c-0.011 0.008 -0.023 0.016 -0.035 0.023l-0.001 0 0 0c-0.013 0.008 -0.025 0.014 -0.039 0.02 -0.226 0.101 -0.491 0 -0.592 -0.226 -0.101 -0.225 0 -0.491 0.226 -0.592 0.026 -0.012 0.052 -0.021 0.079 -0.027l1.504 -0.427 0 0z"
android:strokeLineJoin="round"
android:strokeMiterLimit="1.41421" />
</group>
</vector>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="?android:attr/colorAccent"
android:pathData="M2.546,5.862C4.557,2.772 8.042,0.727 12,0.727C15.958,0.727 19.443,2.772 21.454,5.862C21.584,5.947 21.674,6.086 21.694,6.246C22.697,7.931 23.273,9.899 23.273,12C23.273,18.222 18.222,23.273 12,23.273C5.778,23.273 0.727,18.222 0.727,12C0.727,9.899 1.303,7.931 2.306,6.246C2.326,6.086 2.416,5.947 2.546,5.862ZM7.784,18.049L5.229,18.049C6.602,19.585 8.49,20.651 10.62,20.977C9.503,20.219 8.537,19.221 7.784,18.049ZM18.771,18.049L16.31,18.049C15.564,19.211 14.608,20.202 13.503,20.957C15.583,20.61 17.424,19.555 18.771,18.049ZM13.235,18.049L10.86,18.049C11.207,18.703 11.606,19.307 12.047,19.852C12.488,19.307 12.888,18.703 13.235,18.049ZM6.086,13.083L2.983,13.083C3.101,14.074 3.379,15.016 3.79,15.882L6.713,15.882C6.393,15.001 6.178,14.062 6.086,13.083ZM21.017,13.083L18.008,13.083C17.916,14.062 17.702,15.001 17.382,15.882L20.21,15.882C20.621,15.016 20.899,14.074 21.017,13.083ZM14.67,13.083L9.424,13.083C9.503,14.057 9.689,14.997 9.962,15.882L14.132,15.882C14.406,14.997 14.591,14.057 14.67,13.083ZM6.78,7.939L3.877,7.939C3.418,8.854 3.109,9.858 2.983,10.917L6.086,10.917C6.184,9.872 6.422,8.871 6.78,7.939ZM20.123,7.939L17.315,7.939C17.672,8.871 17.91,9.872 18.008,10.917L21.017,10.917C20.891,9.858 20.582,8.854 20.123,7.939ZM14.076,7.939L10.019,7.939C9.714,8.877 9.509,9.877 9.424,10.917L14.67,10.917C14.585,9.877 14.38,8.877 14.076,7.939ZM10.62,3.023C8.574,3.336 6.751,4.333 5.393,5.772L7.901,5.772C8.637,4.677 9.56,3.742 10.62,3.023ZM13.503,3.043C14.551,3.759 15.465,4.687 16.193,5.772L18.607,5.772C17.276,4.361 15.499,3.376 13.503,3.043ZM12.047,4.148C11.647,4.643 11.281,5.187 10.957,5.772L13.138,5.772C12.814,5.187 12.448,4.643 12.047,4.148Z" />
</vector>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<group
android:scaleX="0.879929"
android:scaleY="0.883309"
android:translateX="1.44085"
android:translateY="0.746289">
<path
android:fillColor="?android:attr/colorAccent"
android:fillType="evenOdd"
android:pathData="M20.764 21.26l-17.528 0c-1.07 0 -1.939 -0.868 -1.939 -1.939l0 -11.324c0 -1.07 0.869 -1.939 1.939 -1.939l4.534 0C7.982 5.01 8.91 4.22 10.02 4.22l3.96 0c1.11 0 2.037 0.79 2.25 1.838l4.534 0c1.07 0 1.939 0.869 1.939 1.939l0 11.324c0 1.071 -0.869 1.939 -1.939 1.939zM12 8.646c2.767 0 5.013 2.246 5.013 5.013 0 2.767 -2.246 5.013 -5.013 5.013 -2.767 0 -5.013 -2.246 -5.013 -5.013 0 -2.767 2.246 -5.013 5.013 -5.013zM3.674 7.257c0.624 0 1.131 0.507 1.131 1.131 0 0.624 -0.507 1.131 -1.131 1.131 -0.624 0 -1.131 -0.507 -1.131 -1.131 0 -0.624 0.507 -1.131 1.131 -1.131z"
android:strokeLineJoin="round"
android:strokeMiterLimit="1.41421" />
</group>
</vector>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<group
android:scaleX="1.05866"
android:scaleY="1.05866"
android:translateX="-0.652026"
android:translateY="-0.703971">
<path
android:fillColor="?android:attr/colorAccent"
android:fillType="evenOdd"
android:pathData="M11.066 10.383l0 -2.773 -2.033 -2.033c-0.364 -0.365 -0.364 -0.956 0 -1.321 0.365 -0.364 0.956 -0.364 1.321 0l0.712 0.713 0 -1.111c0 -0.515 0.419 -0.934 0.934 -0.934 0.515 0 0.934 0.419 0.934 0.934l0 1.111 0.712 -0.713c0.365 -0.364 0.956 -0.364 1.321 0 0.364 0.365 0.364 0.956 0 1.321l-2.033 2.033 0 2.773 2.401 -1.387 0.744 -2.777c0.134 -0.498 0.646 -0.794 1.144 -0.66 0.498 0.133 0.794 0.646 0.66 1.143L17.622 7.676 18.584 7.12c0.447 -0.257 1.018 -0.104 1.276 0.342 0.258 0.446 0.104 1.018 -0.342 1.276l-0.962 0.555 0.973 0.261c0.498 0.133 0.794 0.646 0.661 1.144 -0.134 0.497 -0.646 0.793 -1.144 0.66L16.269 10.614 13.868 12l2.401 1.386 2.777 -0.744c0.498 -0.133 1.01 0.163 1.144 0.66 0.133 0.498 -0.163 1.011 -0.661 1.144l-0.973 0.261 0.962 0.555c0.446 0.258 0.6 0.83 0.342 1.276 -0.258 0.446 -0.829 0.599 -1.276 0.342l-0.962 -0.556 0.261 0.974c0.134 0.497 -0.162 1.01 -0.66 1.143 -0.498 0.134 -1.01 -0.162 -1.144 -0.66l-0.744 -2.777 -2.401 -1.387 0 2.886 2.033 2.034c0.364 0.364 0.364 0.956 0 1.32 -0.365 0.365 -0.956 0.365 -1.321 0l-0.712 -0.712 0 0.997c0 0.515 -0.419 0.934 -0.934 0.934 -0.515 0 -0.934 -0.419 -0.934 -0.934l0 -0.997 -0.712 0.712c-0.365 0.365 -0.956 0.365 -1.321 0 -0.364 -0.364 -0.364 -0.956 0 -1.32l2.033 -2.034 0 -2.886 -2.499 1.443 -0.744 2.778C7.689 18.335 7.177 18.631 6.679 18.498 6.181 18.365 5.885 17.852 6.019 17.354L6.28 16.381 5.416 16.88C4.969 17.137 4.398 16.984 4.14 16.538 3.882 16.092 4.036 15.52 4.482 15.262L5.346 14.764 4.372 14.503C3.875 14.369 3.579 13.857 3.712 13.359 3.846 12.861 4.358 12.565 4.856 12.699L7.633 13.443 10.132 12 7.633 10.557 4.856 11.301C4.358 11.435 3.846 11.139 3.712 10.641 3.579 10.143 3.875 9.631 4.372 9.497L5.346 9.236 4.482 8.738C4.036 8.48 3.882 7.908 4.14 7.462 4.398 7.016 4.969 6.863 5.416 7.12L6.28 7.619 6.019 6.646C5.885 6.148 6.181 5.635 6.679 5.502 7.177 5.369 7.689 5.665 7.823 6.162l0.744 2.778 2.499 1.443z"
android:strokeLineJoin="round"
android:strokeMiterLimit="1.41421" />
</group>
</vector>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<group
android:scaleX="0.0930942"
android:scaleY="0.0934518"
android:translateX="19.4408"
android:translateY="9.49012">
<path
android:fillColor="?android:attr/colorAccent"
android:pathData="M0 57.121c-22.463 -12.601 -36.159 -9.862 -42.734 0 -6.574 9.862 -20.819 24.106 -42.186 6.574 -10.987 -9.015 -22.91 -21.121 -31.769 -31.918 -17.532 -21.367 -3.287 -35.612 6.575 -42.186 9.861 -6.575 12.601 -20.272 0 -42.734 -12.601 -22.463 -33.421 -16.437 -33.421 -16.437 0 0 -22.462 6.575 -32.324 48.213 -8.889 37.534 35.637 88.416 44.502 98.083 0 0 57.942 56.011 99.581 46.149 41.638 -9.861 48.212 -32.324 48.212 -32.324 0 0 6.027 -20.819 -16.436 -33.42"
android:strokeLineJoin="round"
android:strokeMiterLimit="1.41421" />
</group>
</vector>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<group
android:scaleX="0.921041"
android:scaleY="0.924579"
android:translateX="0.752324"
android:translateY="0.893459">
<path
android:fillColor="?android:attr/colorAccent"
android:fillType="evenOdd"
android:pathData="M10.228 14.833c-0.006 0 -0.894 0.008 -1.83 1.069 -0.716 0.812 -1.981 2.473 -3.218 3.16 -0.07 0.041 -0.143 0.078 -0.218 0.111 -0.311 0.143 -0.619 0.217 -0.913 0.192l-0.015 0C3.63 19.362 3.252 19.254 2.924 19.066 1.702 18.44 1.782 17.099 1.782 17.099c0 -0.07 0.004 -0.139 0.01 -0.206C1.847 15.696 2.143 9.661 2.563 8.549 3.102 6.316 5.114 4.656 7.51 4.656l9.423 0c2.478 0 4.545 1.775 4.997 4.123 0.383 1.539 0.65 6.984 0.702 8.114 0.006 0.067 0.009 0.136 0.009 0.206 0 0 0.081 1.341 -1.142 1.967 -0.327 0.188 -0.706 0.296 -1.109 0.299l-0.015 0c-0.294 0.025 -0.602 -0.049 -0.914 -0.192 -0.074 -0.033 -0.147 -0.07 -0.218 -0.111 -1.236 -0.687 -2.502 -2.348 -3.217 -3.16 -0.936 -1.061 -1.824 -1.069 -1.83 -1.069l-3.968 0zM8.247 6.379c1.935 0 3.507 1.571 3.507 3.507 0 1.935 -1.572 3.507 -3.507 3.507 -1.936 0 -3.507 -1.572 -3.507 -3.507 0 -1.936 1.571 -3.507 3.507 -3.507zm9.138 4.16c0.454 0 0.823 0.369 0.823 0.823 0 0.454 -0.369 0.823 -0.823 0.823 -0.454 0 -0.823 -0.369 -0.823 -0.823 0 -0.454 0.369 -0.823 0.823 -0.823zm-8.421 0.07l0 0.814c0 0.399 -0.324 0.723 -0.723 0.723 -0.399 0 -0.723 -0.324 -0.723 -0.723l0 -0.814 -0.815 0C6.304 10.609 5.98 10.285 5.98 9.886 5.98 9.487 6.304 9.163 6.703 9.163l0.815 0 0 -0.815c0 -0.399 0.324 -0.723 0.723 -0.723 0.399 0 0.723 0.324 0.723 0.723l0 0.815 0.815 0c0.399 0 0.723 0.324 0.723 0.723 0 0.399 -0.324 0.722 -0.723 0.723l-0.815 0zm10.72 -0.723c0 0.454 -0.369 0.823 -0.823 0.823 -0.454 0 -0.823 -0.369 -0.823 -0.823 0 -0.455 0.369 -0.823 0.823 -0.823 0.454 0 0.823 0.368 0.823 0.823zm-2.952 0c0 0.454 -0.369 0.823 -0.823 0.823 -0.455 0 -0.823 -0.369 -0.823 -0.823 0 -0.455 0.368 -0.823 0.823 -0.823 0.454 0 0.823 0.368 0.823 0.823zm0.653 -2.3c0.454 0 0.823 0.369 0.823 0.824 0 0.454 -0.369 0.823 -0.823 0.823 -0.454 0 -0.823 -0.369 -0.823 -0.823 0 -0.455 0.369 -0.824 0.823 -0.824z"
android:strokeLineJoin="round"
android:strokeMiterLimit="1.41421" />
</group>
</vector>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?android:attr/colorAccent"
android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"
android:strokeWidth="1"/>
</vector>

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<group
android:scaleX="1.20862"
android:scaleY="1.21327"
android:translateX="-0.686496"
android:translateY="-0.544151">
<path
android:fillColor="?android:attr/colorAccent"
android:fillType="evenOdd"
android:pathData="M13.29 18.046l-8.091 0c-1.277 0 -2.315 -1.037 -2.315 -2.315l0 -4.631c0 -1.277 1.038 -2.315 2.315 -2.315l8.091 0c1.272 0 2.305 1.027 2.315 2.296l1.307 -0.754c0.065 -0.038 0.135 -0.067 0.21 -0.086l0.002 0 0 0 0 0 0 0c0.062 -0.015 0.126 -0.023 0.188 -0.023l0.001 0 0.003 0c0.146 0.001 0.283 0.041 0.401 0.11 0.11 0.065 0.205 0.156 0.276 0.272 0.043 0.071 0.076 0.15 0.096 0.233l0 0.002c0.014 0.059 0.02 0.119 0.02 0.178l0 0.001 0 4.803 0 0.001c0 0.059 -0.006 0.119 -0.02 0.178l0 0.001 0 0 0 0 0 0.001c-0.02 0.084 -0.053 0.162 -0.096 0.233 -0.071 0.116 -0.166 0.208 -0.276 0.272 -0.118 0.07 -0.255 0.11 -0.401 0.11l0 0 0 0 -0.003 0 -0.001 0c-0.062 0 -0.126 -0.007 -0.188 -0.023l0 0 0 0 0 0 -0.002 0c-0.075 -0.018 -0.145 -0.047 -0.21 -0.085L15.605 15.75c-0.01 1.269 -1.043 2.296 -2.315 2.296zm-1.773 -4.63c0 -0.107 -0.027 -0.214 -0.083 -0.313l0 0 0 0 -0.001 -0.002 -0.001 0C11.409 13.06 11.381 13.023 11.349 12.988 11.305 12.94 11.254 12.9 11.198 12.869L7.919 10.975C7.867 10.945 7.811 10.922 7.752 10.908l-0.001 -0.001 0 0 0 0 0 0C7.702 10.895 7.652 10.889 7.602 10.889l0 0 -0.002 0 -0.001 0 0 0C7.484 10.89 7.376 10.921 7.283 10.976 7.196 11.027 7.12 11.099 7.064 11.191 7.03 11.247 7.004 11.309 6.989 11.375l0 0.001 0 0 0 0 0 0.001c-0.011 0.046 -0.016 0.094 -0.016 0.141l0 0 0 3.795 0 0.001c0 0.047 0.005 0.094 0.016 0.141l0 0.001c0.015 0.066 0.041 0.128 0.075 0.185 0.056 0.091 0.132 0.163 0.219 0.214 0.093 0.055 0.201 0.087 0.316 0.087l0.003 0 0 0c0.05 0 0.1 -0.006 0.149 -0.018l0 0 0 0 0 0 0.001 0c0.059 -0.015 0.115 -0.038 0.167 -0.068l3.279 -1.893c0.056 -0.032 0.107 -0.072 0.151 -0.119 0.032 -0.035 0.06 -0.073 0.083 -0.113l0.001 -0.001 0.001 -0.001 0 -0.001 0 0c0.056 -0.098 0.083 -0.206 0.083 -0.312zM6.026 4.848c0.955 0 1.731 0.776 1.731 1.731C7.757 7.535 6.981 8.31 6.026 8.31 5.07 8.31 4.295 7.535 4.295 6.579 4.295 5.624 5.07 4.848 6.026 4.848Zm4.986 -2.216c1.567 0 2.839 1.272 2.839 2.839 0 1.567 -1.272 2.839 -2.839 2.839 -1.567 0 -2.839 -1.272 -2.839 -2.839 0 -1.567 1.272 -2.839 2.839 -2.839z"
android:strokeLineJoin="round"
android:strokeMiterLimit="1.41421" />
</group>
</vector>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?android:attr/colorAccent"
android:pathData="M18,4l2,4h-3l-2,-4h-2l2,4h-3l-2,-4H8l2,4H7L5,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V4h-4z"
android:strokeWidth="1"/>
</vector>

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/game_overlay_fragment"
android:name="org.lineageos.settings.gameoverlay.GameOverlayFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/game_overlay_root"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#80000000"
android:padding="8dp"
android:orientation="vertical">
</LinearLayout>

View file

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017-2021 crDroid Android 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/activatedBackgroundIndicator"
android:clipToPadding="false">
<include layout="@layout/settingslib_icon_frame"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingTop="16dp"
android:paddingBottom="16dp">
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceListItem"
android:ellipsize="marquee" />
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@android:id/title"
android:layout_alignStart="@android:id/title"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="10"
android:ellipsize="end" />
<RelativeLayout
android:id="@+id/value_frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@android:id/summary"
android:layout_alignStart="@android:id/title" >
<TextView
android:id="@+id/value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="1"
android:ellipsize="end" />
<ImageView
android:id="@+id/reset"
android:src="@drawable/ic_custom_seekbar_reset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_toEndOf="@id/value"
android:layout_centerVertical="true" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/seekbar_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/value_frame"
android:layout_alignStart="@android:id/title" >
<ImageView
android:id="@+id/minus"
android:src="@drawable/ic_custom_seekbar_minus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true" />
<ImageView
android:id="@+id/plus"
android:src="@drawable/ic_custom_seekbar_plus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true" />
<LinearLayout
android:id="@+id/seekbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_toEndOf="@id/minus"
android:layout_toStartOf="@id/plus"
android:layout_centerVertical="true" />
</RelativeLayout>
</RelativeLayout>
<!-- Preference should place its actual preference widget here. -->
<LinearLayout android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="end|center_vertical"
android:paddingStart="16dp"
android:orientation="vertical" />
</LinearLayout>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 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.
-->
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/refresh_rv_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingBottom="4dp"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingTop="4dp">
<ImageView
android:id="@+id/app_icon"
android:layout_width="@android:dimen/app_icon_size"
android:layout_height="@android:dimen/app_icon_size"
android:layout_marginEnd="8dp"
android:contentDescription="@null"
android:scaleType="centerInside" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/app_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:ellipsize="marquee"
android:singleLine="true"
android:textAlignment="viewStart"
android:textAppearance="@android:style/TextAppearance.Material.Medium"
android:textColor="?android:attr/textColorPrimary" />
<Spinner
android:id="@+id/app_mode"
android:layout_marginTop="2dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<ImageView
android:id="@+id/state"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="8dp"
android:scaleType="centerInside"
android:src="@drawable/ic_refresh_default" />
</LinearLayout>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 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.
-->
<androidx.recyclerview.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/thermal_rv_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingBottom="4dp"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingTop="4dp">
<ImageView
android:id="@+id/app_icon"
android:layout_width="@android:dimen/app_icon_size"
android:layout_height="@android:dimen/app_icon_size"
android:layout_marginEnd="8dp"
android:contentDescription="@null"
android:scaleType="centerInside" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/app_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="2dp"
android:ellipsize="marquee"
android:singleLine="true"
android:textAlignment="viewStart"
android:textAppearance="@android:style/TextAppearance.Material.Medium"
android:textColor="?android:attr/textColorPrimary" />
<Spinner
android:id="@+id/app_mode"
android:layout_marginTop="2dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<ImageView
android:id="@+id/state"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="8dp"
android:scaleType="centerInside"
android:src="@drawable/ic_thermal_default" />
</LinearLayout>

Binary file not shown.

119
parts/res/values/arrays.xml Normal file
View file

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<resources>
<string-array name="doze_brightness_level">
<item>@string/doze_brightness_low</item>
<item>@string/doze_brightness_high</item>
<item>@string/doze_brightness_adaptive</item>
</string-array>
<string-array name="doze_brightness_level_mode">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
<!-- Update Interval -->
<string-array name="fps_overlay_update_interval_entries">
<item>Every 500ms</item>
<item>Every second</item>
<item>Every 2 seconds</item>
<item>Every 5 seconds</item>
</string-array>
<string-array name="fps_overlay_update_interval_values">
<item>500</item>
<item>1000</item>
<item>2000</item>
<item>5000</item>
</string-array>
<!-- Position -->
<string-array name="fps_overlay_position_entries">
<item>Top Left</item>
<item>Top Center</item>
<item>Top Right</item>
<item>Bottom Left</item>
<item>Bottom Center</item>
<item>Bottom Right</item>
<item>Custom Draggable</item>
</string-array>
<string-array name="fps_overlay_position_values">
<item>top_left</item>
<item>top_center</item>
<item>top_right</item>
<item>bottom_left</item>
<item>bottom_center</item>
<item>bottom_right</item>
<item>draggable</item>
</string-array>
<!-- Overlay color -->
<string-array name="fps_overlay_color_entries">
<item>White</item>
<item>Crimson</item>
<item>Fruit Salad</item>
<item>Royal Blue</item>
<item>Amber</item>
<item>Teal</item>
<item>Electric Violet</item>
<item>Magenta</item>
</string-array>
<string-array name="fps_overlay_color_values">
<item>#FFFFFF</item>
<item>#DC143C</item>
<item>#4CAF50</item>
<item>#4169E1</item>
<item>#FFBF00</item>
<item>#008080</item>
<item>#8A2BE2</item>
<item>#FF1493</item>
</string-array>
<!-- Overlay format -->
<string-array name="game_overlay_format_entries">
<item>Full</item>
<item>Minimal</item>
</string-array>
<string-array name="game_overlay_format_values">
<item>full</item>
<item>minimal</item>
</string-array>
<!-- Split Mode -->
<string-array name="game_overlay_split_mode_entries">
<item>Side-by-Side</item>
<item>Stacked</item>
</string-array>
<string-array name="game_overlay_split_mode_values">
<item>side_by_side</item>
<item>stacked</item>
</string-array>
<!-- Long press timeouts -->
<string-array name="game_overlay_longpress_entries">
<item>1 second</item>
<item>3 seconds</item>
<item>5 seconds</item>
<item>10 seconds</item>
</string-array>
<string-array name="game_overlay_longpress_values">
<item>1000</item>
<item>3000</item>
<item>5000</item>
<item>10000</item>
</string-array>
</resources>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016-2021 crDroid Android 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.
-->
<resources>
<!-- Base attributes available to CustomSeekBarPreference. -->
<declare-styleable name="CustomSeekBarPreference">
<attr name="defaultValueText" format="string" />
<attr name="interval" format="integer" />
<attr name="showSign" format="boolean" />
<attr name="units" format="string|reference" />
<attr name="continuousUpdates" format="boolean" />
</declare-styleable>
</resources>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="custom_seekbar_value">Value: <xliff:g id="v">%s</xliff:g></string>
<string name="custom_seekbar_default_value">by default</string>
<string name="custom_seekbar_default_value_to_set">Default value: <xliff:g id="v">%s</xliff:g>\nLong tap to set</string>
<string name="custom_seekbar_default_value_is_set">Default value is set</string>
</resources>

View file

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 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.
-->
<resources>
<!-- Thermal profiles -->
<string name="thermal_title">Thermal profiles</string>
<string name="thermal_summary">Adjust per-app thermal profiles for optimum performance</string>
<string name="thermal_default">No optimization</string>
<string name="thermal_benchmark">Performance</string>
<string name="thermal_browser">Browser</string>
<string name="thermal_camera">Camera</string>
<string name="thermal_dialer">Dialer</string>
<string name="thermal_gaming">Gaming</string>
<string name="thermal_navigation">Navigation</string>
<string name="thermal_streaming">Streaming</string>
<string name="thermal_video">Video</string>
<!-- Per-app refresh rate -->
<string name="refresh_title">Per-app refresh rate</string>
<string name="refresh_summary">Set the maximum refresh rate for a specific application</string>
<string name="refresh_default">Default</string>
<string name="refresh_standard">60Hz</string>
<string name="refresh_extreme">120Hz</string>
<!-- Doze Strings -->
<string name="doze_brightness_low">Low brightness</string>
<string name="doze_brightness_high">High brightness</string>
<string name="doze_brightness_adaptive">Adaptive brightness</string>
<string name="doze_brightness_title">Doze brightness level</string>
<string name="doze_brightness_summary">Brightness level of doze pulse screen (% of max allowed brightness)</string>
<!-- Clear Speaker -->
<string name="clear_speaker_title">Clear speaker</string>
<string name="clear_speaker_summary">Play a 30-second audio to clear the speaker</string>
<string name="clear_speaker_description">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.</string>
<!-- HBM settings -->
<string name="hbm_fragment_title">High brightness mode</string>
<string name="hbm_fragment_summary">Settings for HBM</string>
<string name="hbm_mode_title">HBM</string>
<string name="hbm_mode_summary">Enable peak luminance</string>
<string name="auto_hbm_title">Automatic HBM</string>
<string name="auto_hbm_summary">Enable peak luminance based on sunlight</string>
<string name="auto_hbm_threshold_title"></string>
<string name="auto_hbm_threshold_summary">threshold (lux)</string>
<string name="hbm_disable_time_title"></string>
<string name="hbm_disable_time_summary">disable delay (seconds)</string>
<string name="hbm_mode_warning">Long time usage of High brightness mode may damage your display</string>
<!-- DC dimming settings -->
<string name="dc_dimming_enable_title">DC Dimming</string>
<string name="dc_dimming_enable_summary">Reduces eye strain in low light conditions</string>
<string name="dc_dimming_enable_summary_not_supported">DC Dimming is currently not supported by the kernel</string>
<!-- High Touch Polling -->
<string name="htsr_title">Touch Responsiveness</string>
<string name="htsr_enable_title">Increase Touch Responsiveness</string>
<string name="htsr_enable_summary">Increases touch polling rate to decrease latency</string>
<string name="htsr_enable_summary_not_supported">Increase Touch Responsiveness is currently not supported by the kernel</string>
<!-- GameBar Overlay -->
<string name="game_overlay_title">GameBar</string>
<string name="game_overlay_summary">Enable the system overlay (FPS, Temp, etc.)</string>
<string name="overlay_permission_required">Overlay permission is required</string>
<string name="overlay_permission_granted">Overlay permission granted</string>
<string name="overlay_permission_denied">Overlay permission denied</string>
<string name="game_overlay_tile_label">GameBar</string>
<string name="game_overlay_tile_description">Toggle the game overlay</string>
</resources>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/clear_speaker_title">
<SwitchPreference
android:key="clear_speaker_pref"
android:title="@string/clear_speaker_title"
android:icon="@drawable/ic_clear_speaker"
android:summary="@string/clear_speaker_summary"/>
<com.android.settingslib.widget.FooterPreference
android:key="footer_preference"
android:title="@string/clear_speaker_description"
android:selectable="false" />
</PreferenceScreen>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The CyanogenMod Project
2018-2019 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/dc_dimming_enable_title">
<SwitchPreference
android:key="dc_dimming_enable"
android:defaultValue="false"
android:icon="@drawable/ic_dcdimming"
android:title="@string/dc_dimming_enable_title"
android:summary="@string/dc_dimming_enable_summary" />
</PreferenceScreen>

View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The CyanogenMod Project
2018-2019 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/ambient_display_title">
<com.android.settingslib.widget.MainSwitchPreference
android:defaultValue="false"
android:key="doze_enable"
android:title="@string/ambient_display_enable_title" />
<SwitchPreference
android:key="always_on_display"
android:disableDependentsState="true"
android:icon="@drawable/ic_doze_aod"
android:title="@string/ambient_display_always_on_title"
android:summary="@string/ambient_display_always_on_summary"
android:persistent="false" />
<ListPreference
android:key="doze_brightness"
android:defaultValue="2"
android:title="@string/doze_brightness_title"
android:summary="@string/doze_brightness_summary"
android:entries="@array/doze_brightness_level"
android:entryValues="@array/doze_brightness_level_mode" />
</PreferenceScreen>

View file

@ -0,0 +1,221 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto">
<SwitchPreference
android:key="game_overlay_enable"
android:title="Enable GameBar Overlay"
android:summary="@string/game_overlay_summary"
android:defaultValue="false" />
<PreferenceCategory
android:title="Overlay Features"
android:dependency="game_overlay_enable">
<SwitchPreference
android:key="game_overlay_fps_enable"
android:title="FPS Overlay"
android:summary="Show current FPS on screen"
android:defaultValue="false" />
<SwitchPreference
android:key="game_overlay_temp_enable"
android:title="Device Temperature"
android:summary="Show device (battery) temperature"
android:defaultValue="false" />
<SwitchPreference
android:key="game_overlay_cpu_usage_enable"
android:title="CPU Usage"
android:summary="Show current CPU usage percentage"
android:defaultValue="false" />
<SwitchPreference
android:key="game_overlay_cpu_clock_enable"
android:title="CPU Clock Speeds"
android:summary="Show current CPU clock speeds for each core"
android:defaultValue="false" />
<SwitchPreference
android:key="game_overlay_cpu_temp_enable"
android:title="CPU Temperature"
android:summary="Show CPU temperature (thermal_zone0)"
android:defaultValue="false" />
<SwitchPreference
android:key="game_overlay_ram_enable"
android:title="RAM Usage"
android:summary="Show current RAM usage in MB"
android:defaultValue="false" />
<SwitchPreference
android:key="game_overlay_gpu_usage_enable"
android:title="GPU Usage"
android:summary="Show GPU usage percentage"
android:defaultValue="false" />
<SwitchPreference
android:key="game_overlay_gpu_clock_enable"
android:title="GPU Clock Speed"
android:summary="Show current GPU clock frequency"
android:defaultValue="false" />
<SwitchPreference
android:key="game_overlay_gpu_temp_enable"
android:title="GPU Temperature"
android:summary="Show current GPU temperature"
android:defaultValue="false" />
</PreferenceCategory>
<PreferenceCategory
android:title="Customization"
android:dependency="game_overlay_enable">
<SeekBarPreference
android:key="game_overlay_text_size"
android:title="Text Size"
android:summary="Adjust the size of overlay text"
android:defaultValue="16"
android:max="32"
android:min="12" />
<SeekBarPreference
android:key="game_overlay_background_alpha"
android:title="Background Transparency"
android:summary="Adjust the transparency of the background"
android:defaultValue="128"
android:max="255"
android:min="0" />
<SeekBarPreference
android:key="game_overlay_corner_radius"
android:title="Overlay Corner Radius"
android:summary="Adjust how rounded the overlay corners should be"
android:defaultValue="16"
android:max="100"
android:min="0" />
<SeekBarPreference
android:key="game_overlay_padding"
android:title="Overlay Padding"
android:summary="Adjust the space around the stats"
android:defaultValue="12"
android:max="64"
android:min="0" />
<SeekBarPreference
android:key="game_overlay_item_spacing"
android:title="Item Spacing"
android:summary="Adjust spacing between overlay lines"
android:defaultValue="8"
android:max="50"
android:min="0" />
<ListPreference
android:key="game_overlay_update_interval"
android:title="Update Interval"
android:summary="Set how often the overlay values update"
android:defaultValue="1000"
android:entries="@array/fps_overlay_update_interval_entries"
android:entryValues="@array/fps_overlay_update_interval_values" />
<ListPreference
android:key="game_overlay_title_color"
android:title="Stat Title Color"
android:summary="Color for 'FPS', 'Temp', 'CPU', etc. text"
android:defaultValue="#FFFFFF"
android:entries="@array/fps_overlay_color_entries"
android:entryValues="@array/fps_overlay_color_values" />
<ListPreference
android:key="game_overlay_value_color"
android:title="Stat Value Color"
android:summary="Color for numeric stats (e.g., '29', '32.0°C')"
android:defaultValue="#4CAF50"
android:entries="@array/fps_overlay_color_entries"
android:entryValues="@array/fps_overlay_color_values" />
<ListPreference
android:key="game_overlay_position"
android:title="Overlay Position"
android:summary="Select the position of the overlay on screen"
android:defaultValue="top_left"
android:entries="@array/fps_overlay_position_entries"
android:entryValues="@array/fps_overlay_position_values" />
<ListPreference
android:key="game_overlay_format"
android:title="Overlay Format"
android:summary="Choose between Full or Minimal display"
android:defaultValue="full"
android:entries="@array/game_overlay_format_entries"
android:entryValues="@array/game_overlay_format_values" />
</PreferenceCategory>
<PreferenceCategory
android:title="Split Config"
android:dependency="game_overlay_enable">
<ListPreference
android:key="game_overlay_split_mode"
android:title="Split Mode"
android:summary="Choose Side-by-Side or Stacked arrangement"
android:defaultValue="stacked"
android:entries="@array/game_overlay_split_mode_entries"
android:entryValues="@array/game_overlay_split_mode_values" />
</PreferenceCategory>
<PreferenceCategory
android:title="Overlay Gesture Controls"
android:dependency="game_overlay_enable">
<SwitchPreference
android:key="game_overlay_single_tap_toggle"
android:title="Enable Single Tap to Toggle"
android:summary="Tap once to switch between full and minimal overlay formats"
android:defaultValue="false" />
<SwitchPreference
android:key="game_overlay_doubletap_capture"
android:title="Enable Double Tap to Capture"
android:summary="Double-tap overlay to start/stop capture logs"
android:defaultValue="false" />
<SwitchPreference
android:key="game_overlay_longpress_enable"
android:title="Enable Long Press"
android:summary="Long-press overlay to access Gamebar settings"
android:defaultValue="false" />
<ListPreference
android:key="game_overlay_longpress_timeout"
android:title="Long Press Duration"
android:summary="Set the duration required to long-press the overlay"
android:defaultValue="1000"
android:entries="@array/game_overlay_longpress_entries"
android:entryValues="@array/game_overlay_longpress_values"
android:dependency="game_overlay_longpress_enable" />
</PreferenceCategory>
<PreferenceCategory
android:title="Capture Logs"
android:dependency="game_overlay_enable">
<Preference
android:key="game_overlay_capture_start"
android:title="Start Logging"
android:summary="Begin capturing FPS and performance data in real-time" />
<Preference
android:key="game_overlay_capture_stop"
android:title="Stop Logging"
android:summary="Stop capturing FPS and performance data in real-time" />
<Preference
android:key="game_overlay_capture_export"
android:title="Export GameBar Log Data"
android:summary="Save the captured FPS and performance data as a CSV file" />
</PreferenceCategory>
</PreferenceScreen>

View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2021 The Evolution X Project
Copyright (C) 2018-2021 crDroid Android 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.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/org.lineageos.settings.HBMFragment"
android.title="@string/hbm_fragment_title">
<PreferenceCategory>
<SwitchPreference
android:key="hbm"
android:title="@string/hbm_mode_title"
android:summary="@string/hbm_mode_summary"
android:defaultValue="false" />
<SwitchPreference
android:key="auto_hbm"
android:title="@string/auto_hbm_title"
android:summary="@string/auto_hbm_summary" />
<org.lineageos.settings.hbm.AutoHBMThresholdPreference
android:key="auto_hbm_threshold"
android:title="@string/auto_hbm_threshold_title"
android:summary="@string/auto_hbm_threshold_summary" />
<org.lineageos.settings.hbm.AutoHBMTimePreference
android:key="hbm_disable_time"
android:title="@string/hbm_disable_time_title"
android:summary="@string/hbm_disable_time_summary" />
<Preference
android:icon="@drawable/ic_info_outline"
android:summary="@string/hbm_mode_warning"
android:persistent="false" />
</PreferenceCategory>
</PreferenceScreen>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The CyanogenMod Project
2018-2019 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/htsr_title">
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="htsr_enable"
android:summary="@string/htsr_enable_summary"
android:title="@string/htsr_enable_title" />
</PreferenceScreen>

View file

@ -0,0 +1,59 @@
/*
* Copyright (C) 2015 The CyanogenMod Project
* 2017-2019 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.settings;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.content.SharedPreferences;
import android.os.SystemProperties;
import androidx.preference.PreferenceManager;
import org.lineageos.settings.doze.DozeUtils;
import org.lineageos.settings.thermal.ThermalUtils;
import org.lineageos.settings.refreshrate.RefreshUtils;
import org.lineageos.settings.utils.FileUtils;
public class BootCompletedReceiver extends BroadcastReceiver {
private static final boolean DEBUG = false;
private static final String TAG = "XiaomiParts";
private static final String DC_DIMMING_ENABLE_KEY = "dc_dimming_enable";
private static final String DC_DIMMING_NODE = "/sys/devices/platform/soc/soc:qcom,dsi-display-primary/dimlayer_exposure";
private static final String HTSR_ENABLE_KEY = "htsr_enable";
private static final String HTSR_FILE = "/sys/devices/virtual/touch/touch_dev/bump_sample_rate";
@Override
public void onReceive(final Context context, Intent intent) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
if (DEBUG)
Log.d(TAG, "Received boot completed intent");
DozeUtils.onBootCompleted(context);
ThermalUtils.startService(context);
RefreshUtils.startService(context);
// Touch Sampling
boolean HTSREnabled = sharedPrefs.getBoolean(HTSR_ENABLE_KEY, false);
FileUtils.writeLine(HTSR_FILE, HTSREnabled ? "1" : "0");
// DC Dimming
FileUtils.enableService(context);
boolean dcDimmingEnabled = sharedPrefs.getBoolean(DC_DIMMING_ENABLE_KEY, false);
FileUtils.writeLine(DC_DIMMING_NODE, dcDimmingEnabled ? "1" : "0");
}
}

View file

@ -0,0 +1,90 @@
/*
* Copyright (C) 2025 kenway215
*
* 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.settings;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.service.quicksettings.TileService;
import android.util.Log;
import java.util.HashMap;
import java.util.Map;
import org.lineageos.settings.gameoverlay.GameOverlaySettingsActivity;
import org.lineageos.settings.gameoverlay.GameOverlayTileService;
public final class TileHandlerActivity extends Activity {
private static final String TAG = "TileHandlerActivity";
// Map QS Tile services to their corresponding activity
private static final Map<String, Class<?>> TILE_ACTIVITY_MAP = new HashMap<>();
static {
TILE_ACTIVITY_MAP.put(GameOverlayTileService.class.getName(), GameOverlaySettingsActivity.class);
}
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Intent intent = getIntent();
if (intent == null || !TileService.ACTION_QS_TILE_PREFERENCES.equals(intent.getAction())) {
Log.e(TAG, "Invalid or null intent received");
finish();
return;
}
final ComponentName qsTile = intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME);
if (qsTile == null) {
Log.e(TAG, "No QS tile component found in intent");
finish();
return;
}
final String qsName = qsTile.getClassName();
final Intent targetIntent = new Intent();
// Check if the tile is mapped to an activity
if (TILE_ACTIVITY_MAP.containsKey(qsName)) {
targetIntent.setClass(this, TILE_ACTIVITY_MAP.get(qsName));
Log.d(TAG, "Launching settings activity for QS tile: " + qsName);
} else {
// Default: Open app settings for the QS tile's package
final String packageName = qsTile.getPackageName();
if (packageName == null) {
Log.e(TAG, "QS tile package name is null");
finish();
return;
}
targetIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
targetIntent.setData(Uri.fromParts("package", packageName, null));
Log.d(TAG, "Opening app info for package: " + packageName);
}
// Ensure proper navigation behavior
targetIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_CLEAR_TASK |
Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(targetIntent);
finish();
}
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 2015-2016 The CyanogenMod Project
* 2017,2021-2022 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.settings.display;
import android.os.Bundle;
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
public class DcDimmingSettingsActivity extends CollapsingToolbarBaseActivity {
private static final String TAG_DCDIMMING = "dcdimming";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(com.android.settingslib.collapsingtoolbar.R.id.content_frame,
new DcDimmingSettingsFragment(), TAG_DCDIMMING).commit();
}
}

View file

@ -0,0 +1,102 @@
/*
* Copyright (C) 2018 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.settings.display;
import android.content.Context;
import android.os.Bundle;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import androidx.preference.SwitchPreference;
import android.provider.Settings;
import org.lineageos.settings.R;
import org.lineageos.settings.utils.FileUtils;
import java.io.File;
public class DcDimmingSettingsFragment extends PreferenceFragment implements
OnPreferenceChangeListener {
private SwitchPreference mDcDimmingPreference;
private static final String DC_DIMMING_ENABLE_KEY = "dc_dimming_enable";
private static final String DC_DIMMING_NODE = "/sys/devices/platform/soc/soc:qcom,dsi-display-primary/dimlayer_exposure";
private static final String HBM = "/sys/devices/platform/soc/soc:qcom,dsi-display-primary/hbm";
private static final String HBM_KEY = "hbm";
private File hbmFile;
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.dcdimming_settings, rootKey);
mDcDimmingPreference = findPreference(DC_DIMMING_ENABLE_KEY);
if (FileUtils.fileExists(DC_DIMMING_NODE)) {
mDcDimmingPreference.setEnabled(true);
mDcDimmingPreference.setOnPreferenceChangeListener(this);
} else {
mDcDimmingPreference.setSummary(R.string.dc_dimming_enable_summary_not_supported);
mDcDimmingPreference.setEnabled(false);
}
hbmFile = new File(HBM);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (DC_DIMMING_ENABLE_KEY.equals(preference.getKey())) {
boolean enabled = (boolean) newValue;
FileUtils.writeLine(DC_DIMMING_NODE, enabled ? "1" : "0");
if (enabled) {
disableHBM();
}
updateHBMPreference(!enabled);
}
return true;
}
private void disableHBM() {
// Disable HBM mode
FileUtils.writeLine(HBM, "0");
// Make HBM mode path read-only
hbmFile.setReadOnly();
// Update HBM mode UI tile
updateHBMUI(false);
}
private void updateHBMUI(boolean enabled) {
Intent intent = new Intent("org.lineageos.settings.hbm.UPDATE_TILE");
intent.putExtra("enabled", enabled);
getActivity().sendBroadcast(intent);
// Update HBM preference UI
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
sharedPrefs.edit().putBoolean(HBM_KEY, enabled).apply();
updateHBMPreference(enabled);
}
private void updateHBMPreference(boolean enabled) {
// Update HBM preference UI
if (mDcDimmingPreference != null) {
mDcDimmingPreference.setChecked(enabled);
}
}
}

View file

@ -0,0 +1,125 @@
/*
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
*
*/
package org.lineageos.settings.display;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
import androidx.preference.PreferenceManager;
import android.provider.Settings;
import org.lineageos.settings.utils.FileUtils;
import java.io.File;
public class DcDimmingTileService extends TileService {
public static final String DC_DIMMING_ENABLE_KEY = "dc_dimming_enable";
private static final String DC_DIMMING_NODE = "/sys/devices/platform/soc/soc:qcom,dsi-display-primary/dimlayer_exposure";
private static final String HBM = "/sys/devices/platform/soc/soc:qcom,dsi-display-primary/hbm";
private static final String HBM_KEY = "hbm";
private File hbmFile;
private BroadcastReceiver screenStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = sharedPrefs.edit();
editor.putBoolean(DC_DIMMING_ENABLE_KEY, false);
editor.apply();
updateUI(false);
disableHBM();
}
}
};
private void updateUI(boolean enabled) {
final Tile tile = getQsTile();
tile.setState(enabled ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
tile.updateTile();
}
private void disableHBM() {
// Disable HBM mode
FileUtils.writeLine(HBM, "0");
// Make HBM mode path read-only
hbmFile.setReadOnly();
// Update HBM mode UI tile
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
Editor editor = sharedPrefs.edit();
editor.putBoolean(HBM_KEY, false);
editor.apply();
updateHBMUI(false);
}
private void updateHBMUI(boolean enabled) {
Intent intent = new Intent("org.lineageos.settings.hbm.UPDATE_TILE");
intent.putExtra("enabled", enabled);
sendBroadcast(intent);
}
@Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(screenStateReceiver, filter);
hbmFile = new File(HBM);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(screenStateReceiver);
}
@Override
public void onStartListening() {
super.onStartListening();
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
updateUI(sharedPrefs.getBoolean(DC_DIMMING_ENABLE_KEY, false));
}
@Override
public void onStopListening() {
super.onStopListening();
}
@Override
public void onClick() {
super.onClick();
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
final boolean enabled = !(sharedPrefs.getBoolean(DC_DIMMING_ENABLE_KEY, false));
FileUtils.writeLine(DC_DIMMING_NODE, enabled ? "1" : "0");
if (enabled) {
disableHBM();
} else {
hbmFile.setWritable(true);
}
sharedPrefs.edit().putBoolean(DC_DIMMING_ENABLE_KEY, enabled).apply();
updateUI(enabled);
}
}

View file

@ -0,0 +1,80 @@
/*
* 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.settings.doze;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class AodSensor implements SensorEventListener {
private static final boolean DEBUG = false;
private static final String TAG = "AodSensor";
private SensorManager mSensorManager;
private Sensor mSensor;
private Context mContext;
private ExecutorService mExecutorService;
public AodSensor(Context context) {
mContext = context;
mSensorManager = mContext.getSystemService(SensorManager.class);
mSensor = DozeUtils.getSensor(mSensorManager, "xiaomi.sensor.aod");
mExecutorService = Executors.newSingleThreadExecutor();
}
private Future<?> submit(Runnable runnable) { return mExecutorService.submit(runnable); }
@Override
public void onSensorChanged(SensorEvent event) {
if (DEBUG) {
Log.d(TAG, "Got sensor event: " + event.values[0]);
}
if (event.values[0] == 3 || event.values[0] == 5) {
DozeUtils.setDozeMode(DozeUtils.DOZE_MODE_LBM);
} else if (event.values[0] == 4) {
DozeUtils.setDozeMode(DozeUtils.DOZE_MODE_HBM);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
/* Empty */
}
protected void enable() {
if (DEBUG) {
Log.d(TAG, "Enabling");
}
submit(() -> {
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
});
}
protected void disable() {
if (DEBUG) {
Log.d(TAG, "Disabling");
}
submit(() -> { mSensorManager.unregisterListener(this, mSensor); });
}
}

View file

@ -0,0 +1,92 @@
/*
* Copyright (C) 2015 The CyanogenMod Project
* 2017-2018 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.settings.doze;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
public class DozeService extends Service {
private static final String TAG = "DozeService";
private static final boolean DEBUG = false;
private AodSensor mAodSensor;
@Override
public void onCreate() {
if (DEBUG)
Log.d(TAG, "Creating service");
mAodSensor = new AodSensor(this);
IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mScreenStateReceiver, screenStateFilter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (DEBUG)
Log.d(TAG, "Starting service");
return START_STICKY;
}
@Override
public void onDestroy() {
if (DEBUG)
Log.d(TAG, "Destroying service");
super.onDestroy();
this.unregisterReceiver(mScreenStateReceiver);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void onDisplayOn() {
if (DEBUG)
Log.d(TAG, "Display on");
if (DozeUtils.isDozeAutoBrightnessEnabled(this)) {
mAodSensor.disable();
}
}
private void onDisplayOff() {
if (DEBUG)
Log.d(TAG, "Display off");
if (DozeUtils.isDozeAutoBrightnessEnabled(this)) {
mAodSensor.enable();
}
}
private BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
onDisplayOn();
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
onDisplayOff();
}
}
};
}

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 2015-2016 The CyanogenMod Project
* 2017,2021-2022 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.settings.doze;
import android.os.Bundle;
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
public class DozeSettingsActivity extends CollapsingToolbarBaseActivity {
private static final String TAG_DOZE = "doze";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(com.android.settingslib.collapsingtoolbar.R.id.content_frame,
new DozeSettingsFragment(), TAG_DOZE).commit();
}
}

View file

@ -0,0 +1,156 @@
/*
* Copyright (C) 2015 The CyanogenMod Project
* 2017-2019 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.settings.doze;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragment;
import androidx.preference.SwitchPreference;
import com.android.settingslib.widget.MainSwitchPreference;
import org.lineageos.settings.R;
import org.lineageos.settings.utils.FileUtils;
public class DozeSettingsFragment extends PreferenceFragment
implements OnPreferenceChangeListener, OnCheckedChangeListener {
private MainSwitchPreference mSwitchBar;
private SwitchPreference mAlwaysOnDisplayPreference;
private ListPreference mDozeBrightnessPreference;
private Handler mHandler = new Handler();
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.doze_settings);
SharedPreferences prefs =
getActivity().getSharedPreferences("doze_settings", Activity.MODE_PRIVATE);
if (savedInstanceState == null && !prefs.getBoolean("first_help_shown", false)) {
showHelp();
}
boolean dozeEnabled = DozeUtils.isDozeEnabled(getActivity());
mSwitchBar = (MainSwitchPreference) findPreference(DozeUtils.DOZE_ENABLE);
mSwitchBar.addOnSwitchChangeListener(this);
mSwitchBar.setChecked(dozeEnabled);
mAlwaysOnDisplayPreference = (SwitchPreference) findPreference(DozeUtils.ALWAYS_ON_DISPLAY);
mAlwaysOnDisplayPreference.setEnabled(dozeEnabled);
mAlwaysOnDisplayPreference.setChecked(DozeUtils.isAlwaysOnEnabled(getActivity()));
mAlwaysOnDisplayPreference.setOnPreferenceChangeListener(this);
mDozeBrightnessPreference = (ListPreference) findPreference(DozeUtils.DOZE_BRIGHTNESS_KEY);
mDozeBrightnessPreference.setEnabled(
dozeEnabled && DozeUtils.isAlwaysOnEnabled(getActivity()));
mDozeBrightnessPreference.setOnPreferenceChangeListener(this);
// Hide AOD and doze brightness if not supported and set all its dependents otherwise
if (!DozeUtils.alwaysOnDisplayAvailable(getActivity())) {
getPreferenceScreen().removePreference(mAlwaysOnDisplayPreference);
getPreferenceScreen().removePreference(mDozeBrightnessPreference);
} else {
if (!FileUtils.isFileWritable(DozeUtils.DOZE_MODE_PATH)) {
getPreferenceScreen().removePreference(mDozeBrightnessPreference);
} else {
DozeUtils.updateDozeBrightnessIcon(getContext(), mDozeBrightnessPreference);
}
}
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (DozeUtils.ALWAYS_ON_DISPLAY.equals(preference.getKey())) {
DozeUtils.enableAlwaysOn(getActivity(), (Boolean) newValue);
if (!(Boolean) newValue) {
mDozeBrightnessPreference.setValue(DozeUtils.DOZE_BRIGHTNESS_LBM);
DozeUtils.setDozeMode(DozeUtils.DOZE_BRIGHTNESS_LBM);
}
mDozeBrightnessPreference.setEnabled((Boolean) newValue);
} else if (DozeUtils.DOZE_BRIGHTNESS_KEY.equals(preference.getKey())) {
if (!DozeUtils.DOZE_BRIGHTNESS_AUTO.equals((String) newValue)) {
DozeUtils.setDozeMode((String) newValue);
}
}
mHandler.post(() -> {
DozeUtils.checkDozeService(getActivity());
DozeUtils.updateDozeBrightnessIcon(getContext(), mDozeBrightnessPreference);
});
return true;
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
DozeUtils.enableDoze(getActivity(), isChecked);
DozeUtils.checkDozeService(getActivity());
mSwitchBar.setChecked(isChecked);
if (!isChecked) {
DozeUtils.enableAlwaysOn(getActivity(), false);
mAlwaysOnDisplayPreference.setChecked(false);
mDozeBrightnessPreference.setValue(DozeUtils.DOZE_BRIGHTNESS_LBM);
DozeUtils.updateDozeBrightnessIcon(getContext(), mDozeBrightnessPreference);
}
mAlwaysOnDisplayPreference.setEnabled(isChecked);
mDozeBrightnessPreference.setEnabled(
isChecked && DozeUtils.isAlwaysOnEnabled(getActivity()));
}
public static class HelpDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.doze_settings_help_title)
.setMessage(R.string.doze_settings_help_text)
.setNegativeButton(R.string.dialog_ok, (dialog, which) -> dialog.cancel())
.create();
}
@Override
public void onCancel(DialogInterface dialog) {
getActivity()
.getSharedPreferences("doze_settings", Activity.MODE_PRIVATE)
.edit()
.putBoolean("first_help_shown", true)
.commit();
}
}
private void showHelp() {
HelpDialogFragment fragment = new HelpDialogFragment();
fragment.show(getFragmentManager(), "help_dialog");
}
}

View file

@ -0,0 +1,155 @@
/*
* Copyright (C) 2015 The CyanogenMod Project
* 2017-2019 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.settings.doze;
import static android.provider.Settings.Secure.DOZE_ALWAYS_ON;
import static android.provider.Settings.Secure.DOZE_ENABLED;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import androidx.preference.ListPreference;
import androidx.preference.PreferenceManager;
import org.lineageos.settings.R;
import org.lineageos.settings.utils.FileUtils;
public final class DozeUtils {
private static final String TAG = "DozeUtils";
private static final boolean DEBUG = false;
private static final String DOZE_INTENT = "com.android.systemui.doze.pulse";
protected static final String DOZE_ENABLE = "doze_enable";
protected static final String ALWAYS_ON_DISPLAY = "always_on_display";
protected static final String DOZE_BRIGHTNESS_KEY = "doze_brightness";
protected static final String DOZE_MODE_PATH =
"/sys/devices/platform/soc/soc:qcom,dsi-display-primary/doze_mode";
protected static final String DOZE_MODE_HBM = "1";
protected static final String DOZE_MODE_LBM = "0";
protected static final String DOZE_BRIGHTNESS_LBM = "0";
protected static final String DOZE_BRIGHTNESS_HBM = "1";
protected static final String DOZE_BRIGHTNESS_AUTO = "2";
public static void onBootCompleted(Context context) {
checkDozeService(context);
restoreDozeModes(context);
}
public static void startService(Context context) {
if (DEBUG)
Log.d(TAG, "Starting service");
context.startServiceAsUser(new Intent(context, DozeService.class), UserHandle.CURRENT);
}
protected static void stopService(Context context) {
if (DEBUG)
Log.d(TAG, "Stopping service");
context.stopServiceAsUser(new Intent(context, DozeService.class), UserHandle.CURRENT);
}
public static void checkDozeService(Context context) {
if (isDozeEnabled(context)
&& (isAlwaysOnEnabled(context) || sensorsEnabled(context))) {
startService(context);
} else {
stopService(context);
}
}
private static void restoreDozeModes(Context context) {
if (isAlwaysOnEnabled(context) && !isDozeAutoBrightnessEnabled(context)) {
setDozeMode(PreferenceManager.getDefaultSharedPreferences(context).getString(
DOZE_BRIGHTNESS_KEY, String.valueOf(DOZE_BRIGHTNESS_LBM)));
}
}
protected static boolean enableDoze(Context context, boolean enable) {
return Settings.Secure.putInt(context.getContentResolver(), DOZE_ENABLED, enable ? 1 : 0);
}
public static boolean isDozeEnabled(Context context) {
return Settings.Secure.getInt(context.getContentResolver(), DOZE_ENABLED, 1) != 0;
}
protected static boolean enableAlwaysOn(Context context, boolean enable) {
return Settings.Secure.putIntForUser(context.getContentResolver(), DOZE_ALWAYS_ON,
enable ? 1 : 0, UserHandle.USER_CURRENT);
}
protected static boolean isAlwaysOnEnabled(Context context) {
final boolean enabledByDefault = context.getResources().getBoolean(
com.android.internal.R.bool.config_dozeAlwaysOnEnabled);
return Settings.Secure.getIntForUser(context.getContentResolver(), DOZE_ALWAYS_ON,
alwaysOnDisplayAvailable(context) && enabledByDefault ? 1 : 0,
UserHandle.USER_CURRENT)
!= 0;
}
protected static boolean alwaysOnDisplayAvailable(Context context) {
return new AmbientDisplayConfiguration(context).alwaysOnAvailable();
}
protected static boolean setDozeMode(String value) {
return FileUtils.writeLine(DOZE_MODE_PATH, value);
}
protected static boolean isDozeAutoBrightnessEnabled(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getString(DOZE_BRIGHTNESS_KEY, DOZE_BRIGHTNESS_LBM)
.equals(DOZE_BRIGHTNESS_AUTO);
}
public static boolean sensorsEnabled(Context context) {
return isDozeAutoBrightnessEnabled(context);
}
protected static Sensor getSensor(SensorManager sm, String type) {
for (Sensor sensor : sm.getSensorList(Sensor.TYPE_ALL)) {
if (type.equals(sensor.getStringType())) {
return sensor;
}
}
return null;
}
protected static void updateDozeBrightnessIcon(Context context, ListPreference preference) {
switch (PreferenceManager.getDefaultSharedPreferences(context).getString(
DOZE_BRIGHTNESS_KEY, DOZE_BRIGHTNESS_LBM)) {
case DozeUtils.DOZE_BRIGHTNESS_LBM:
preference.setIcon(R.drawable.ic_doze_brightness_low);
break;
case DozeUtils.DOZE_BRIGHTNESS_HBM:
preference.setIcon(R.drawable.ic_doze_brightness_high);
break;
case DozeUtils.DOZE_BRIGHTNESS_AUTO:
preference.setIcon(R.drawable.ic_doze_brightness_auto);
break;
}
}
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (C) 2025 kenway214
*
* 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.settings.gameoverlay;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Log;
import java.lang.reflect.Method;
import java.util.List;
public class ForegroundAppDetector {
private static final String TAG = "ForegroundAppDetector";
public static String getForegroundPackageName(Context context) {
String pkg = tryGetRunningTasks(context);
if (pkg != null) {
return pkg;
}
pkg = tryReflectActivityTaskManager();
if (pkg != null) {
return pkg;
}
return "Unknown";
}
private static String tryGetRunningTasks(Context context) {
try {
if (context.checkSelfPermission("android.permission.GET_TASKS")
== PackageManager.PERMISSION_GRANTED) {
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
if (tasks != null && !tasks.isEmpty()) {
ActivityManager.RunningTaskInfo top = tasks.get(0);
if (top.topActivity != null) {
return top.topActivity.getPackageName();
}
}
} else {
Log.w(TAG, "GET_TASKS permission not granted to this system app?");
}
} catch (Exception e) {
Log.e(TAG, "tryGetRunningTasks error: ", e);
}
return null;
}
private static String tryReflectActivityTaskManager() {
try {
Class<?> atmClass = Class.forName("android.app.ActivityTaskManager");
Method getServiceMethod = atmClass.getDeclaredMethod("getService");
getServiceMethod.setAccessible(true);
Object atmService = getServiceMethod.invoke(null);
Method getTasksMethod = atmService.getClass().getMethod("getTasks", int.class);
@SuppressWarnings("unchecked")
List<?> taskList = (List<?>) getTasksMethod.invoke(atmService, 1);
if (taskList != null && !taskList.isEmpty()) {
Object firstTask = taskList.get(0);
Class<?> rtiClass = firstTask.getClass();
Method getTopActivityMethod = rtiClass.getDeclaredMethod("getTopActivity");
Object compName = getTopActivityMethod.invoke(firstTask);
if (compName != null) {
Method getPackageNameMethod = compName.getClass().getMethod("getPackageName");
String pkgName = (String) getPackageNameMethod.invoke(compName);
return pkgName;
}
}
} catch (Exception e) {
Log.e(TAG, "tryReflectActivityTaskManager error: ", e);
}
return null;
}
}

View file

@ -0,0 +1,132 @@
/*
* Copyright (C) 2025 kenway214
*
* 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.settings.gameoverlay;
import android.os.Environment;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class GameDataExport {
private static GameDataExport sInstance;
public static synchronized GameDataExport getInstance() {
if (sInstance == null) {
sInstance = new GameDataExport();
}
return sInstance;
}
private boolean mCapturing = false;
private final List<String[]> mStatsRows = new ArrayList<>();
private static final String[] CSV_HEADER = {
"DateTime",
"PackageName",
"FPS",
"Battery_Temp",
"CPU_Usage",
"CPU_Temp",
"GPU_Usage",
"GPU_Clock",
"GPU_Temp"
};
private GameDataExport() {
}
public void startCapture() {
mCapturing = true;
mStatsRows.clear();
mStatsRows.add(CSV_HEADER);
}
public void stopCapture() {
mCapturing = false;
}
public boolean isCapturing() {
return mCapturing;
}
public void addOverlayData(String dateTime,
String packageName,
String fps,
String batteryTemp,
String cpuUsage,
String cpuTemp,
String gpuUsage,
String gpuClock,
String gpuTemp) {
if (!mCapturing) return;
String[] row = {
dateTime,
packageName,
fps,
batteryTemp,
cpuUsage,
cpuTemp,
gpuUsage,
gpuClock,
gpuTemp
};
mStatsRows.add(row);
}
public void exportDataToCsv() {
if (mStatsRows.size() <= 1) {
return;
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
File outFile = new File(Environment.getExternalStorageDirectory(), "GameBar_log_" + timeStamp + ".csv");
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(outFile, true));
for (String[] row : mStatsRows) {
bw.write(toCsvLine(row));
bw.newLine();
}
bw.flush();
} catch (IOException ignored) {
} finally {
if (bw != null) {
try { bw.close(); } catch (IOException ignored) {}
}
}
}
private String toCsvLine(String[] columns) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < columns.length; i++) {
sb.append(columns[i]);
if (i < columns.length - 1) {
sb.append(",");
}
}
return sb.toString();
}
}

View file

@ -0,0 +1,776 @@
/*
* Copyright (C) 2025 kenway214
*
* 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.settings.gameoverlay;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.drawable.GradientDrawable;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.preference.PreferenceManager;
import org.lineageos.settings.R;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class GameOverlay {
private static GameOverlay sInstance;
public static synchronized GameOverlay getInstance(Context context) {
if (sInstance == null) {
sInstance = new GameOverlay(context.getApplicationContext());
}
return sInstance;
}
private static final String FPS_PATH = "/sys/class/drm/sde-crtc-0/measured_fps";
private static final String BATTERY_TEMP_PATH= "/sys/class/power_supply/battery/temp";
private static final String PREF_KEY_X = "game_overlay_x";
private static final String PREF_KEY_Y = "game_overlay_y";
private final Context mContext;
private final WindowManager mWindowManager;
private final Handler mHandler;
private View mOverlayView;
private LinearLayout mRootLayout;
private WindowManager.LayoutParams mLayoutParams;
private boolean mIsShowing = false;
private int mTextSizeSp = 16;
private int mBackgroundAlpha = 128;
private int mCornerRadius = 16;
private int mPaddingDp = 12;
private String mTitleColorHex = "#FFFFFF";
private String mValueColorHex = "#FFFFFF";
private String mPosition = "top_left";
private String mSplitMode = "stacked";
private String mOverlayFormat = "full";
private int mUpdateIntervalMs = 1000;
private boolean mDraggable = false;
private boolean mShowBatteryTemp= false;
private boolean mShowCpuUsage = false;
private boolean mShowCpuClock = false;
private boolean mShowCpuTemp = false;
private boolean mShowRam = false;
private boolean mShowFps = false;
private boolean mShowGpuUsage = false;
private boolean mShowGpuClock = false;
private boolean mShowGpuTemp = false;
private boolean mLongPressEnabled = false;
private long mLongPressThresholdMs = 1000;
private boolean mPressActive = false;
private float mDownX, mDownY;
private static final float TOUCH_SLOP = 20f;
private GestureDetector mGestureDetector;
private boolean mDoubleTapCaptureEnabled = false;
private boolean mSingleTapToggleEnabled = false;
private GradientDrawable mBgDrawable;
private int mItemSpacingDp = 8;
private final Runnable mLongPressRunnable = new Runnable() {
@Override
public void run() {
if (mPressActive) {
openOverlaySettings();
mPressActive = false;
}
}
};
private final Runnable mUpdateRunnable = new Runnable() {
@Override
public void run() {
if (mIsShowing) {
updateStats();
mHandler.postDelayed(this, mUpdateIntervalMs);
}
}
};
private GameOverlay(Context context) {
mContext = context;
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mHandler = new Handler(Looper.getMainLooper());
mBgDrawable = new GradientDrawable();
applyBackgroundStyle();
}
public void applyPreferences() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
mShowFps = prefs.getBoolean("game_overlay_fps_enable", false);
mShowBatteryTemp = prefs.getBoolean("game_overlay_temp_enable", false);
mShowCpuUsage = prefs.getBoolean("game_overlay_cpu_usage_enable", false);
mShowCpuClock = prefs.getBoolean("game_overlay_cpu_clock_enable", false);
mShowCpuTemp = prefs.getBoolean("game_overlay_cpu_temp_enable", false);
mShowRam = prefs.getBoolean("game_overlay_ram_enable", false);
mShowGpuUsage = prefs.getBoolean("game_overlay_gpu_usage_enable", false);
mShowGpuClock = prefs.getBoolean("game_overlay_gpu_clock_enable", false);
mShowGpuTemp = prefs.getBoolean("game_overlay_gpu_temp_enable", false);
mDoubleTapCaptureEnabled = prefs.getBoolean("game_overlay_doubletap_capture", false);
mSingleTapToggleEnabled = prefs.getBoolean("game_overlay_single_tap_toggle", false);
updateSplitMode(prefs.getString("game_overlay_split_mode", "stacked"));
updateTextSize(prefs.getInt("game_overlay_text_size", 16));
updateBackgroundAlpha(prefs.getInt("game_overlay_background_alpha", 128));
updateCornerRadius(prefs.getInt("game_overlay_corner_radius", 16));
updatePadding(prefs.getInt("game_overlay_padding", 12));
updateTitleColor(prefs.getString("game_overlay_title_color", "#FFFFFF"));
updateValueColor(prefs.getString("game_overlay_value_color", "#4CAF50"));
updateOverlayFormat(prefs.getString("game_overlay_format", "full"));
updateUpdateInterval(prefs.getString("game_overlay_update_interval", "1000"));
updatePosition(prefs.getString("game_overlay_position", "top_left"));
int spacing = prefs.getInt("game_overlay_item_spacing", 8);
updateItemSpacing(spacing);
mLongPressEnabled = prefs.getBoolean("game_overlay_longpress_enable", false);
String lpTimeoutStr = prefs.getString("game_overlay_longpress_timeout", "1000");
try {
long lpt = Long.parseLong(lpTimeoutStr);
setLongPressThresholdMs(lpt);
} catch (NumberFormatException ignored) {}
}
public void show() {
if (mIsShowing) return;
applyPreferences();
mLayoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
);
if ("draggable".equals(mPosition)) {
mDraggable = true;
loadSavedPosition(mLayoutParams);
if (mLayoutParams.x == 0 && mLayoutParams.y == 0) {
mLayoutParams.gravity = Gravity.TOP | Gravity.START;
mLayoutParams.x = 0;
mLayoutParams.y = 100;
}
} else {
mDraggable = false;
applyPosition(mLayoutParams, mPosition);
}
mOverlayView = new LinearLayout(mContext);
mOverlayView.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
));
mRootLayout = (LinearLayout) mOverlayView;
applySplitMode();
applyBackgroundStyle();
applyPadding();
mGestureDetector = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
if (mDoubleTapCaptureEnabled) {
if (GameDataExport.getInstance().isCapturing()) {
GameDataExport.getInstance().stopCapture();
Toast.makeText(mContext, "Capture Stopped", Toast.LENGTH_SHORT).show();
} else {
GameDataExport.getInstance().startCapture();
Toast.makeText(mContext, "Capture Started", Toast.LENGTH_SHORT).show();
}
return true;
}
return super.onDoubleTap(e);
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (mSingleTapToggleEnabled) {
mOverlayFormat = "full".equals(mOverlayFormat) ? "minimal" : "full";
Toast.makeText(mContext, "Overlay Format: " + mOverlayFormat, Toast.LENGTH_SHORT).show();
updateStats();
return true;
}
return super.onSingleTapConfirmed(e);
}
});
mOverlayView.setOnTouchListener((v, event) -> {
if (mGestureDetector != null && mGestureDetector.onTouchEvent(event)) {
return true;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mDraggable) {
initialX = mLayoutParams.x;
initialY = mLayoutParams.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
}
if (mLongPressEnabled) {
mPressActive = true;
mDownX = event.getRawX();
mDownY = event.getRawY();
mHandler.postDelayed(mLongPressRunnable, mLongPressThresholdMs);
}
return true;
case MotionEvent.ACTION_MOVE:
if (mLongPressEnabled && mPressActive) {
float dx = Math.abs(event.getRawX() - mDownX);
float dy = Math.abs(event.getRawY() - mDownY);
if (dx > TOUCH_SLOP || dy > TOUCH_SLOP) {
mPressActive = false;
mHandler.removeCallbacks(mLongPressRunnable);
}
}
if (mDraggable) {
int deltaX = (int) (event.getRawX() - initialTouchX);
int deltaY = (int) (event.getRawY() - initialTouchY);
mLayoutParams.x = initialX + deltaX;
mLayoutParams.y = initialY + deltaY;
mWindowManager.updateViewLayout(mOverlayView, mLayoutParams);
}
return true;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (mLongPressEnabled && mPressActive) {
mPressActive = false;
mHandler.removeCallbacks(mLongPressRunnable);
}
if (mDraggable) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
prefs.edit()
.putInt(PREF_KEY_X, mLayoutParams.x)
.putInt(PREF_KEY_Y, mLayoutParams.y)
.apply();
}
return true;
}
return false;
});
mWindowManager.addView(mOverlayView, mLayoutParams);
mIsShowing = true;
startUpdates();
}
private int initialX, initialY;
private float initialTouchX, initialTouchY;
public void hide() {
if (!mIsShowing) return;
mHandler.removeCallbacksAndMessages(null);
if (mOverlayView != null) {
mWindowManager.removeView(mOverlayView);
mOverlayView = null;
}
mIsShowing = false;
}
private void updateStats() {
if (!mIsShowing || mRootLayout == null) return;
mRootLayout.removeAllViews();
List<View> statViews = new ArrayList<>();
// 1) FPS
float fpsVal = parseFps();
String fpsStr = fpsVal >= 0 ? String.format(Locale.getDefault(), "%.1f", fpsVal) : "N/A";
if (mShowFps) {
statViews.add(createStatLine("FPS", fpsStr));
}
// 2) Battery temp
String batteryTempStr = "N/A";
if (mShowBatteryTemp) {
String tmp = readLine(BATTERY_TEMP_PATH);
if (tmp != null && !tmp.isEmpty()) {
try {
int raw = Integer.parseInt(tmp.trim());
float c = raw / 10f;
batteryTempStr = String.format(Locale.getDefault(), "%.1f", c);
} catch (NumberFormatException ignored) {}
}
statViews.add(createStatLine("Temp", batteryTempStr + "°C"));
}
// 3) CPU usage
String cpuUsageStr = "N/A";
if (mShowCpuUsage) {
cpuUsageStr = GameOverlayCpuInfo.getCpuUsage();
String display = "N/A".equals(cpuUsageStr) ? "N/A" : cpuUsageStr + "%";
statViews.add(createStatLine("CPU", display));
}
// 4) CPU freq
if (mShowCpuClock) {
List<String> freqs = GameOverlayCpuInfo.getCpuFrequencies();
if (!freqs.isEmpty()) {
statViews.add(buildCpuFreqView(freqs));
}
}
// 5) CPU temp
String cpuTempStr = "N/A";
if (mShowCpuTemp) {
cpuTempStr = GameOverlayCpuInfo.getCpuTemp();
statViews.add(createStatLine("CPU Temp", "N/A".equals(cpuTempStr) ? "N/A" : cpuTempStr + "°C"));
}
// 6) RAM usage
String ramStr = "N/A";
if (mShowRam) {
ramStr = GameOverlayMemInfo.getRamUsage();
statViews.add(createStatLine("RAM", "N/A".equals(ramStr) ? "N/A" : ramStr + " MB"));
}
// 7) GPU usage
String gpuUsageStr = "N/A";
if (mShowGpuUsage) {
gpuUsageStr = GameOverlayGpuInfo.getGpuUsage();
statViews.add(createStatLine("GPU", "N/A".equals(gpuUsageStr) ? "N/A" : gpuUsageStr + "%"));
}
// 8) GPU clock
String gpuClockStr = "N/A";
if (mShowGpuClock) {
gpuClockStr = GameOverlayGpuInfo.getGpuClock();
statViews.add(createStatLine("GPU Freq", "N/A".equals(gpuClockStr) ? "N/A" : gpuClockStr + "MHz"));
}
// 9) GPU temp
String gpuTempStr = "N/A";
if (mShowGpuTemp) {
gpuTempStr = GameOverlayGpuInfo.getGpuTemp();
statViews.add(createStatLine("GPU Temp", "N/A".equals(gpuTempStr) ? "N/A" : gpuTempStr + "°C"));
}
if ("side_by_side".equals(mSplitMode)) {
mRootLayout.setOrientation(LinearLayout.HORIZONTAL);
if ("minimal".equals(mOverlayFormat)) {
for (int i = 0; i < statViews.size(); i++) {
mRootLayout.addView(statViews.get(i));
if (i < statViews.size() - 1) {
mRootLayout.addView(createDotView());
}
}
} else {
for (View view : statViews) {
mRootLayout.addView(view);
}
}
} else {
mRootLayout.setOrientation(LinearLayout.VERTICAL);
for (View view : statViews) {
mRootLayout.addView(view);
}
}
if (GameDataExport.getInstance().isCapturing()) {
String dateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(new Date());
String pkgName = ForegroundAppDetector.getForegroundPackageName(mContext);
GameDataExport.getInstance().addOverlayData(
dateTime,
pkgName, // PackageName
fpsStr, // FPS
batteryTempStr, // Battery_Temp
cpuUsageStr, // CPU_Usage
cpuTempStr, // CPU_Temp
gpuUsageStr, // GPU_Usage
gpuClockStr, // GPU_Clock
gpuTempStr // GPU_Temp
);
}
if (mLayoutParams != null) {
mWindowManager.updateViewLayout(mOverlayView, mLayoutParams);
}
}
private View buildCpuFreqView(List<String> freqs) {
LinearLayout freqContainer = new LinearLayout(mContext);
freqContainer.setOrientation(LinearLayout.HORIZONTAL);
int spacingPx = dpToPx(mContext, mItemSpacingDp);
LinearLayout.LayoutParams outerLp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
outerLp.setMargins(spacingPx, spacingPx/2, spacingPx, spacingPx/2);
freqContainer.setLayoutParams(outerLp);
if ("full".equals(mOverlayFormat)) {
TextView labelTv = new TextView(mContext);
labelTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextSizeSp);
try {
labelTv.setTextColor(Color.parseColor(mTitleColorHex));
} catch (Exception e) {
labelTv.setTextColor(Color.WHITE);
}
labelTv.setText("CPU Freq ");
freqContainer.addView(labelTv);
}
LinearLayout verticalFreqs = new LinearLayout(mContext);
verticalFreqs.setOrientation(LinearLayout.VERTICAL);
for (String freqLine : freqs) {
LinearLayout lineLayout = new LinearLayout(mContext);
lineLayout.setOrientation(LinearLayout.HORIZONTAL);
TextView freqTv = new TextView(mContext);
freqTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextSizeSp);
try {
freqTv.setTextColor(Color.parseColor(mValueColorHex));
} catch (Exception e) {
freqTv.setTextColor(Color.WHITE);
}
freqTv.setText(freqLine);
lineLayout.addView(freqTv);
LinearLayout.LayoutParams lineLp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
lineLp.setMargins(spacingPx, spacingPx/4, spacingPx, spacingPx/4);
lineLayout.setLayoutParams(lineLp);
verticalFreqs.addView(lineLayout);
}
freqContainer.addView(verticalFreqs);
return freqContainer;
}
private LinearLayout createStatLine(String title, String rawValue) {
LinearLayout lineLayout = new LinearLayout(mContext);
lineLayout.setOrientation(LinearLayout.HORIZONTAL);
if ("full".equals(mOverlayFormat)) {
TextView tvTitle = new TextView(mContext);
tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextSizeSp);
try {
tvTitle.setTextColor(Color.parseColor(mTitleColorHex));
} catch (Exception e) {
tvTitle.setTextColor(Color.WHITE);
}
tvTitle.setText(title.isEmpty() ? "" : title + " ");
TextView tvValue = new TextView(mContext);
tvValue.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextSizeSp);
try {
tvValue.setTextColor(Color.parseColor(mValueColorHex));
} catch (Exception e) {
tvValue.setTextColor(Color.WHITE);
}
tvValue.setText(rawValue);
lineLayout.addView(tvTitle);
lineLayout.addView(tvValue);
} else {
TextView tvMinimal = new TextView(mContext);
tvMinimal.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextSizeSp);
try {
tvMinimal.setTextColor(Color.parseColor(mValueColorHex));
} catch (Exception e) {
tvMinimal.setTextColor(Color.WHITE);
}
tvMinimal.setText(rawValue);
lineLayout.addView(tvMinimal);
}
int spacingPx = dpToPx(mContext, mItemSpacingDp);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
lp.setMargins(spacingPx, spacingPx/2, spacingPx, spacingPx/2);
lineLayout.setLayoutParams(lp);
return lineLayout;
}
private View createDotView() {
TextView dotView = new TextView(mContext);
dotView.setTextSize(TypedValue.COMPLEX_UNIT_SP, mTextSizeSp);
try {
dotView.setTextColor(Color.parseColor(mValueColorHex));
} catch (Exception e) {
dotView.setTextColor(Color.WHITE);
}
dotView.setText(" . ");
return dotView;
}
private float parseFps() {
String line = readLine(FPS_PATH);
if (line != null && line.startsWith("fps:")) {
String[] parts = line.split("\\s+");
if (parts.length >= 2) {
try {
return Float.parseFloat(parts[1].trim());
} catch (NumberFormatException ignored) {}
}
}
return -1f;
}
public void setShowBatteryTemp(boolean show) { mShowBatteryTemp = show; }
public void setShowCpuUsage(boolean show) { mShowCpuUsage = show; }
public void setShowCpuClock(boolean show) { mShowCpuClock = show; }
public void setShowCpuTemp(boolean show) { mShowCpuTemp = show; }
public void setShowRam(boolean show) { mShowRam = show; }
public void setShowFps(boolean show) { mShowFps = show; }
public void setShowGpuUsage(boolean show) { mShowGpuUsage = show; }
public void setShowGpuClock(boolean show) { mShowGpuClock = show; }
public void setShowGpuTemp(boolean show) { mShowGpuTemp = show; }
public void updateTextSize(int sp) {
mTextSizeSp = sp;
}
public void updateCornerRadius(int radius) {
mCornerRadius = radius;
applyBackgroundStyle();
}
public void updateBackgroundAlpha(int alpha) {
mBackgroundAlpha = alpha;
applyBackgroundStyle();
}
public void updatePadding(int dp) {
mPaddingDp = dp;
applyPadding();
}
public void updateTitleColor(String hex) {
mTitleColorHex = hex;
}
public void updateValueColor(String hex) {
mValueColorHex = hex;
}
public void updateOverlayFormat(String format) {
mOverlayFormat = format;
if (mIsShowing) {
updateStats();
}
}
public void updateItemSpacing(int dp) {
mItemSpacingDp = dp;
if (mIsShowing) {
updateStats();
}
}
private void applyBackgroundStyle() {
int color = Color.argb(mBackgroundAlpha, 0, 0, 0);
mBgDrawable.setColor(color);
mBgDrawable.setCornerRadius(mCornerRadius);
if (mOverlayView != null) {
mOverlayView.setBackground(mBgDrawable);
}
}
private void applyPadding() {
if (mRootLayout != null) {
int px = dpToPx(mContext, mPaddingDp);
mRootLayout.setPadding(px, px, px, px);
}
}
public void updatePosition(String pos) {
mPosition = pos;
if (mIsShowing && mOverlayView != null && mLayoutParams != null) {
if ("draggable".equals(mPosition)) {
mDraggable = true;
loadSavedPosition(mLayoutParams);
if (mLayoutParams.x == 0 && mLayoutParams.y == 0) {
mLayoutParams.gravity = Gravity.TOP | Gravity.START;
mLayoutParams.x = 0;
mLayoutParams.y = 100;
}
} else {
mDraggable = false;
applyPosition(mLayoutParams, mPosition);
}
mWindowManager.updateViewLayout(mOverlayView, mLayoutParams);
}
}
public void updateSplitMode(String mode) {
mSplitMode = mode;
if (mIsShowing && mOverlayView != null) {
applySplitMode();
updateStats();
}
}
public void updateUpdateInterval(String intervalStr) {
try {
mUpdateIntervalMs = Integer.parseInt(intervalStr);
} catch (NumberFormatException e) {
mUpdateIntervalMs = 1000;
}
if (mIsShowing) {
startUpdates();
}
}
public void setLongPressEnabled(boolean enabled) {
mLongPressEnabled = enabled;
}
public void setLongPressThresholdMs(long ms) {
mLongPressThresholdMs = ms;
}
public void setDoubleTapCaptureEnabled(boolean enabled) {
mDoubleTapCaptureEnabled = enabled;
}
public void setSingleTapToggleEnabled(boolean enabled) {
mSingleTapToggleEnabled = enabled;
}
private void startUpdates() {
mHandler.removeCallbacksAndMessages(null);
mHandler.post(mUpdateRunnable);
}
private void applySplitMode() {
if (mRootLayout == null) return;
if ("side_by_side".equals(mSplitMode)) {
mRootLayout.setOrientation(LinearLayout.HORIZONTAL);
} else {
mRootLayout.setOrientation(LinearLayout.VERTICAL);
}
}
private void loadSavedPosition(WindowManager.LayoutParams lp) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
int savedX = prefs.getInt(PREF_KEY_X, Integer.MIN_VALUE);
int savedY = prefs.getInt(PREF_KEY_Y, Integer.MIN_VALUE);
if (savedX != Integer.MIN_VALUE && savedY != Integer.MIN_VALUE) {
lp.gravity = Gravity.TOP | Gravity.START;
lp.x = savedX;
lp.y = savedY;
}
}
private void applyPosition(WindowManager.LayoutParams lp, String pos) {
switch (pos) {
case "top_left":
lp.gravity = Gravity.TOP | Gravity.START;
lp.x = 0;
lp.y = 100;
break;
case "top_center":
lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
lp.y = 100;
break;
case "top_right":
lp.gravity = Gravity.TOP | Gravity.END;
lp.x = 0;
lp.y = 100;
break;
case "bottom_left":
lp.gravity = Gravity.BOTTOM | Gravity.START;
lp.x = 0;
lp.y = 100;
break;
case "bottom_center":
lp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
lp.y = 100;
break;
case "bottom_right":
lp.gravity = Gravity.BOTTOM | Gravity.END;
lp.x = 0;
lp.y = 100;
break;
default:
lp.gravity = Gravity.TOP | Gravity.START;
lp.x = 0;
lp.y = 100;
break;
}
}
private String readLine(String path) {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
} catch (IOException e) {
return null;
}
}
private void openOverlaySettings() {
try {
Intent intent = new Intent(mContext, GameOverlaySettingsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
} catch (Exception e) {
}
}
private static int dpToPx(Context context, int dp) {
float scale = context.getResources().getDisplayMetrics().density;
return Math.round(dp * scale);
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (C) 2025 kenway214
*
* 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.settings.gameoverlay;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import androidx.preference.PreferenceManager;
public class GameOverlayBootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (Intent.ACTION_BOOT_COMPLETED.equals(action)
|| Intent.ACTION_LOCKED_BOOT_COMPLETED.equals(action)) {
restoreOverlayState(context);
}
}
private void restoreOverlayState(Context context) {
var prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean enabled = prefs.getBoolean("game_overlay_enable", false);
GameOverlay overlay = GameOverlay.getInstance(context);
if (!enabled) {
overlay.hide();
return;
}
overlay.applyPreferences();
overlay.show();
}
}

View file

@ -0,0 +1,130 @@
/*
* Copyright (C) 2025 kenway214
*
* 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.settings.gameoverlay;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class GameOverlayCpuInfo {
private static long sPrevIdle = -1;
private static long sPrevTotal = -1;
private static final String CPU_TEMP_PATH = "/sys/class/thermal/thermal_zone0/temp";
public static String getCpuUsage() {
String line = readLine("/proc/stat");
if (line == null || !line.startsWith("cpu ")) return "N/A";
String[] parts = line.split("\\s+");
if (parts.length < 8) return "N/A";
try {
long user = Long.parseLong(parts[1]);
long nice = Long.parseLong(parts[2]);
long system = Long.parseLong(parts[3]);
long idle = Long.parseLong(parts[4]);
long iowait = Long.parseLong(parts[5]);
long irq = Long.parseLong(parts[6]);
long softirq = Long.parseLong(parts[7]);
long steal = parts.length > 8 ? Long.parseLong(parts[8]) : 0;
long total = user + nice + system + idle + iowait + irq + softirq + steal;
if (sPrevTotal != -1 && total != sPrevTotal) {
long diffTotal = total - sPrevTotal;
long diffIdle = idle - sPrevIdle;
long usage = 100 * (diffTotal - diffIdle) / diffTotal;
sPrevTotal = total;
sPrevIdle = idle;
return String.valueOf(usage);
} else {
sPrevTotal = total;
sPrevIdle = idle;
return "N/A";
}
} catch (NumberFormatException e) {
return "N/A";
}
}
public static List<String> getCpuFrequencies() {
List<String> result = new ArrayList<>();
String cpuDirPath = "/sys/devices/system/cpu/";
java.io.File cpuDir = new java.io.File(cpuDirPath);
java.io.File[] files = cpuDir.listFiles((dir, name) -> name.matches("cpu\\d+"));
if (files == null || files.length == 0) {
return result;
}
List<java.io.File> cpuFolders = new ArrayList<>();
Collections.addAll(cpuFolders, files);
cpuFolders.sort(Comparator.comparingInt(GameOverlayCpuInfo::extractCpuNumber));
for (java.io.File cpu : cpuFolders) {
String freqPath = cpu.getAbsolutePath() + "/cpufreq/scaling_cur_freq";
String freqStr = readLine(freqPath);
if (freqStr != null && !freqStr.isEmpty()) {
try {
int khz = Integer.parseInt(freqStr.trim());
int mhz = khz / 1000;
result.add(cpu.getName() + ": " + mhz + " MHz");
} catch (NumberFormatException e) {
result.add(cpu.getName() + ": N/A");
}
} else {
result.add(cpu.getName() + ": offline or frequency not available");
}
}
return result;
}
public static String getCpuTemp() {
String line = readLine(CPU_TEMP_PATH);
if (line == null) return "N/A";
line = line.trim();
try {
float raw = Float.parseFloat(line);
float c = raw / 1000f;
return String.format("%.1f", c);
} catch (NumberFormatException e) {
return "N/A";
}
}
private static int extractCpuNumber(java.io.File cpuFolder) {
String name = cpuFolder.getName().replace("cpu", "");
try {
return Integer.parseInt(name);
} catch (NumberFormatException e) {
return -1;
}
}
private static String readLine(String path) {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
} catch (IOException e) {
return null;
}
}
}

View file

@ -0,0 +1,358 @@
/*
* Copyright (C) 2025 kenway214
*
* 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.settings.gameoverlay;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.widget.Toast;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SeekBarPreference;
import androidx.preference.SwitchPreference;
import org.lineageos.settings.R;
public class GameOverlayFragment extends PreferenceFragmentCompat {
private GameOverlay mOverlay;
private SwitchPreference mMasterSwitch;
private SwitchPreference mFpsSwitch;
private SwitchPreference mBatteryTempSwitch;
private SwitchPreference mCpuUsageSwitch;
private SwitchPreference mCpuClockSwitch;
private SwitchPreference mCpuTempSwitch;
private SwitchPreference mRamSwitch;
private SwitchPreference mGpuUsageSwitch;
private SwitchPreference mGpuClockSwitch;
private SwitchPreference mGpuTempSwitch;
private Preference mCaptureStartPref;
private Preference mCaptureStopPref;
private Preference mCaptureExportPref;
private SwitchPreference mDoubleTapCapturePref;
private SwitchPreference mSingleTapTogglePref;
private SwitchPreference mLongPressEnablePref;
private ListPreference mLongPressTimeoutPref;
private SeekBarPreference mTextSizePref;
private SeekBarPreference mBgAlphaPref;
private SeekBarPreference mCornerRadiusPref;
private SeekBarPreference mPaddingPref;
private SeekBarPreference mItemSpacingPref;
private ListPreference mUpdateIntervalPref;
private ListPreference mTextColorPref;
private ListPreference mTitleColorPref;
private ListPreference mValueColorPref;
private ListPreference mPositionPref;
private ListPreference mSplitModePref;
private ListPreference mOverlayFormatPref;
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.game_overlay_preferences, rootKey);
mOverlay = GameOverlay.getInstance(getContext());
mMasterSwitch = findPreference("game_overlay_enable");
mFpsSwitch = findPreference("game_overlay_fps_enable");
mBatteryTempSwitch = findPreference("game_overlay_temp_enable");
mCpuUsageSwitch = findPreference("game_overlay_cpu_usage_enable");
mCpuClockSwitch = findPreference("game_overlay_cpu_clock_enable");
mCpuTempSwitch = findPreference("game_overlay_cpu_temp_enable");
mRamSwitch = findPreference("game_overlay_ram_enable");
mGpuUsageSwitch = findPreference("game_overlay_gpu_usage_enable");
mGpuClockSwitch = findPreference("game_overlay_gpu_clock_enable");
mGpuTempSwitch = findPreference("game_overlay_gpu_temp_enable");
mCaptureStartPref = findPreference("game_overlay_capture_start");
mCaptureStopPref = findPreference("game_overlay_capture_stop");
mCaptureExportPref = findPreference("game_overlay_capture_export");
mDoubleTapCapturePref = findPreference("game_overlay_doubletap_capture");
mSingleTapTogglePref = findPreference("game_overlay_single_tap_toggle");
mLongPressEnablePref = findPreference("game_overlay_longpress_enable");
mLongPressTimeoutPref = findPreference("game_overlay_longpress_timeout");
mTextSizePref = findPreference("game_overlay_text_size");
mBgAlphaPref = findPreference("game_overlay_background_alpha");
mCornerRadiusPref = findPreference("game_overlay_corner_radius");
mPaddingPref = findPreference("game_overlay_padding");
mItemSpacingPref = findPreference("game_overlay_item_spacing");
mUpdateIntervalPref = findPreference("game_overlay_update_interval");
mTextColorPref = findPreference("game_overlay_text_color");
mTitleColorPref = findPreference("game_overlay_title_color");
mValueColorPref = findPreference("game_overlay_value_color");
mPositionPref = findPreference("game_overlay_position");
mSplitModePref = findPreference("game_overlay_split_mode");
mOverlayFormatPref = findPreference("game_overlay_format");
if (mMasterSwitch != null) {
mMasterSwitch.setOnPreferenceChangeListener((pref, newValue) -> {
boolean enabled = (boolean) newValue;
if (enabled) {
if (Settings.canDrawOverlays(getContext())) {
mOverlay.applyPreferences();
mOverlay.show();
} else {
Toast.makeText(getContext(), R.string.overlay_permission_required, Toast.LENGTH_SHORT).show();
return false;
}
} else {
mOverlay.hide();
}
return true;
});
}
if (mFpsSwitch != null) {
mFpsSwitch.setOnPreferenceChangeListener((pref, newValue) -> {
mOverlay.setShowFps((boolean) newValue);
return true;
});
}
if (mBatteryTempSwitch != null) {
mBatteryTempSwitch.setOnPreferenceChangeListener((pref, newValue) -> {
mOverlay.setShowBatteryTemp((boolean) newValue);
return true;
});
}
if (mCpuUsageSwitch != null) {
mCpuUsageSwitch.setOnPreferenceChangeListener((pref, newValue) -> {
mOverlay.setShowCpuUsage((boolean) newValue);
return true;
});
}
if (mCpuClockSwitch != null) {
mCpuClockSwitch.setOnPreferenceChangeListener((pref, newValue) -> {
mOverlay.setShowCpuClock((boolean) newValue);
return true;
});
}
if (mCpuTempSwitch != null) {
mCpuTempSwitch.setOnPreferenceChangeListener((pref, newValue) -> {
mOverlay.setShowCpuTemp((boolean) newValue);
return true;
});
}
if (mRamSwitch != null) {
mRamSwitch.setOnPreferenceChangeListener((pref, newValue) -> {
mOverlay.setShowRam((boolean) newValue);
return true;
});
}
if (mGpuUsageSwitch != null) {
mGpuUsageSwitch.setOnPreferenceChangeListener((pref, newValue) -> {
mOverlay.setShowGpuUsage((boolean) newValue);
return true;
});
}
if (mGpuClockSwitch != null) {
mGpuClockSwitch.setOnPreferenceChangeListener((pref, newValue) -> {
mOverlay.setShowGpuClock((boolean) newValue);
return true;
});
}
if (mGpuTempSwitch != null) {
mGpuTempSwitch.setOnPreferenceChangeListener((pref, newValue) -> {
mOverlay.setShowGpuTemp((boolean) newValue);
return true;
});
}
if (mCaptureStartPref != null) {
mCaptureStartPref.setOnPreferenceClickListener(pref -> {
GameDataExport.getInstance().startCapture();
Toast.makeText(getContext(), "Started logging Data", Toast.LENGTH_SHORT).show();
return true;
});
}
if (mCaptureStopPref != null) {
mCaptureStopPref.setOnPreferenceClickListener(pref -> {
GameDataExport.getInstance().stopCapture();
Toast.makeText(getContext(), "Stopped logging Data", Toast.LENGTH_SHORT).show();
return true;
});
}
if (mCaptureExportPref != null) {
mCaptureExportPref.setOnPreferenceClickListener(pref -> {
GameDataExport.getInstance().exportDataToCsv();
Toast.makeText(getContext(), "Exported log data to file", Toast.LENGTH_SHORT).show();
return true;
});
}
if (mDoubleTapCapturePref != null) {
mDoubleTapCapturePref.setOnPreferenceChangeListener((pref, newValue) -> {
mOverlay.setDoubleTapCaptureEnabled((boolean) newValue);
return true;
});
}
if (mSingleTapTogglePref != null) {
mSingleTapTogglePref.setOnPreferenceChangeListener((pref, newValue) -> {
mOverlay.setSingleTapToggleEnabled((boolean) newValue);
return true;
});
}
if (mLongPressEnablePref != null) {
mLongPressEnablePref.setOnPreferenceChangeListener((pref, newValue) -> {
mOverlay.setLongPressEnabled((boolean) newValue);
return true;
});
}
if (mLongPressTimeoutPref != null) {
mLongPressTimeoutPref.setOnPreferenceChangeListener((pref, newValue) -> {
if (newValue instanceof String) {
long ms = Long.parseLong((String) newValue);
mOverlay.setLongPressThresholdMs(ms);
}
return true;
});
}
if (mTextSizePref != null) {
mTextSizePref.setOnPreferenceChangeListener((pref, newValue) -> {
if (newValue instanceof Integer) {
mOverlay.updateTextSize((Integer) newValue);
}
return true;
});
}
if (mBgAlphaPref != null) {
mBgAlphaPref.setOnPreferenceChangeListener((pref, newValue) -> {
if (newValue instanceof Integer) {
mOverlay.updateBackgroundAlpha((Integer) newValue);
}
return true;
});
}
if (mCornerRadiusPref != null) {
mCornerRadiusPref.setOnPreferenceChangeListener((pref, newValue) -> {
if (newValue instanceof Integer) {
mOverlay.updateCornerRadius((Integer) newValue);
}
return true;
});
}
if (mPaddingPref != null) {
mPaddingPref.setOnPreferenceChangeListener((pref, newValue) -> {
if (newValue instanceof Integer) {
mOverlay.updatePadding((Integer) newValue);
}
return true;
});
}
if (mItemSpacingPref != null) {
mItemSpacingPref.setOnPreferenceChangeListener((pref, newValue) -> {
if (newValue instanceof Integer) {
mOverlay.updateItemSpacing((Integer) newValue);
}
return true;
});
}
if (mUpdateIntervalPref != null) {
mUpdateIntervalPref.setOnPreferenceChangeListener((pref, newValue) -> {
if (newValue instanceof String) {
mOverlay.updateUpdateInterval((String) newValue);
}
return true;
});
}
if (mTextColorPref != null) {
mTextColorPref.setOnPreferenceChangeListener((pref, newValue) -> true);
}
if (mTitleColorPref != null) {
mTitleColorPref.setOnPreferenceChangeListener((pref, newValue) -> {
if (newValue instanceof String) {
mOverlay.updateTitleColor((String) newValue);
}
return true;
});
}
if (mValueColorPref != null) {
mValueColorPref.setOnPreferenceChangeListener((pref, newValue) -> {
if (newValue instanceof String) {
mOverlay.updateValueColor((String) newValue);
}
return true;
});
}
if (mPositionPref != null) {
mPositionPref.setOnPreferenceChangeListener((pref, newValue) -> {
if (newValue instanceof String) {
mOverlay.updatePosition((String) newValue);
}
return true;
});
}
if (mSplitModePref != null) {
mSplitModePref.setOnPreferenceChangeListener((pref, newValue) -> {
if (newValue instanceof String) {
mOverlay.updateSplitMode((String) newValue);
}
return true;
});
}
if (mOverlayFormatPref != null) {
mOverlayFormatPref.setOnPreferenceChangeListener((pref, newValue) -> {
if (newValue instanceof String) {
mOverlay.updateOverlayFormat((String) newValue);
}
return true;
});
}
}
@Override
public void onResume() {
super.onResume();
if (!hasUsageStatsPermission(requireContext())) {
requestUsageStatsPermission();
}
}
private boolean hasUsageStatsPermission(Context context) {
android.app.AppOpsManager appOps = (android.app.AppOpsManager)
context.getSystemService(Context.APP_OPS_SERVICE);
if (appOps == null) return false;
int mode = appOps.checkOpNoThrow(
android.app.AppOpsManager.OPSTR_GET_USAGE_STATS,
android.os.Process.myUid(),
context.getPackageName()
);
return (mode == android.app.AppOpsManager.MODE_ALLOWED);
}
private void requestUsageStatsPermission() {
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
startActivity(intent);
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (C) 2025 kenway214
*
* 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.settings.gameoverlay;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class GameOverlayGpuInfo {
private static final String GPU_USAGE_PATH = "/sys/class/kgsl/kgsl-3d0/gpu_busy_percentage";
private static final String GPU_CLOCK_PATH = "/sys/class/kgsl/kgsl-3d0/gpuclk";
private static final String GPU_TEMP_PATH = "/sys/class/kgsl/kgsl-3d0/temp";
public static String getGpuUsage() {
String line = readLine(GPU_USAGE_PATH);
if (line == null) {
return "N/A";
}
line = line.replace("%", "").trim();
try {
int val = Integer.parseInt(line);
return String.valueOf(val);
} catch (NumberFormatException e) {
return "N/A";
}
}
public static String getGpuClock() {
String line = readLine(GPU_CLOCK_PATH);
if (line == null) {
return "N/A";
}
line = line.trim();
try {
long hz = Long.parseLong(line);
long mhz = hz / 1_000_000;
return String.valueOf(mhz);
} catch (NumberFormatException e) {
return "N/A";
}
}
public static String getGpuTemp() {
String line = readLine(GPU_TEMP_PATH);
if (line == null) {
return "N/A";
}
line = line.trim();
try {
float raw = Float.parseFloat(line);
float c = raw / 1000f;
return String.format("%.1f", c);
} catch (NumberFormatException e) {
return "N/A";
}
}
private static String readLine(String path) {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
} catch (IOException e) {
return null;
}
}
}

View file

@ -0,0 +1,65 @@
/*
* Copyright (C) 2025 kenway214
*
* 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.settings.gameoverlay;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class GameOverlayMemInfo {
public static String getRamUsage() {
long memTotal = 0;
long memAvailable = 0;
try (BufferedReader br = new BufferedReader(new FileReader("/proc/meminfo"))) {
String line;
while ((line = br.readLine()) != null) {
if (line.startsWith("MemTotal:")) {
memTotal = parseMemValue(line);
} else if (line.startsWith("MemAvailable:")) {
memAvailable = parseMemValue(line);
}
if (memTotal > 0 && memAvailable > 0) {
break;
}
}
} catch (IOException e) {
return "N/A";
}
if (memTotal == 0) {
return "N/A";
}
long usedKb = (memTotal - memAvailable);
long usedMb = usedKb / 1024;
return String.valueOf(usedMb);
}
private static long parseMemValue(String line) {
String[] parts = line.split("\\s+");
if (parts.length < 3) {
return 0;
}
try {
return Long.parseLong(parts[1]);
} catch (NumberFormatException e) {
return 0;
}
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (C) 2025 kenway214
*
* 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.settings.gameoverlay;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.widget.Toast;
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
import org.lineageos.settings.R;
public class GameOverlaySettingsActivity extends CollapsingToolbarBaseActivity {
private static final int OVERLAY_PERMISSION_REQUEST_CODE = 1234;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_overlay);
setTitle(getString(R.string.game_overlay_title));
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, OVERLAY_PERMISSION_REQUEST_CODE);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == OVERLAY_PERMISSION_REQUEST_CODE) {
if (Settings.canDrawOverlays(this)) {
Toast.makeText(this, R.string.overlay_permission_granted, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, R.string.overlay_permission_denied, Toast.LENGTH_SHORT).show();
}
}
}
}

View file

@ -0,0 +1,73 @@
/*
* Copyright (C) 2025 kenway214
*
* 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.settings.gameoverlay;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
import androidx.preference.PreferenceManager;
import org.lineageos.settings.R;
public class GameOverlayTileService extends TileService {
private GameOverlay mOverlay;
@Override
public void onCreate() {
super.onCreate();
mOverlay = GameOverlay.getInstance(this);
}
@Override
public void onStartListening() {
super.onStartListening();
boolean enabled = PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean("game_overlay_enable", false);
updateTileState(enabled);
}
@Override
public void onClick() {
super.onClick();
boolean currentlyEnabled = PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean("game_overlay_enable", false);
boolean newState = !currentlyEnabled;
PreferenceManager.getDefaultSharedPreferences(this)
.edit()
.putBoolean("game_overlay_enable", newState)
.commit();
updateTileState(newState);
if (newState) {
mOverlay.show();
} else {
mOverlay.hide();
}
}
private void updateTileState(boolean enabled) {
Tile tile = getQsTile();
if (tile == null) return;
tile.setState(enabled ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
tile.setLabel(getString(R.string.game_overlay_tile_label));
tile.setContentDescription(getString(R.string.game_overlay_tile_description));
tile.updateTile();
}
}

View file

@ -0,0 +1,165 @@
package org.lineageos.settings.hbm;
import android.app.KeyguardManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.IBinder;
import android.os.PowerManager;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
import org.lineageos.settings.utils.FileUtils;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class AutoHBMService extends Service {
private static final String HBM = "/sys/devices/platform/soc/soc:qcom,dsi-display-primary/hbm_enabled";
private static final String BACKLIGHT = "/sys/class/backlight/panel0-backlight/brightness";
private static boolean mAutoHBMActive = false;
private ExecutorService mExecutorService;
private SensorManager mSensorManager;
private Sensor mLightSensor;
private SharedPreferences mSharedPrefs;
private boolean dcDimmingEnabled;
private int mStoredBrightness = -1;
public void activateLightSensorRead() {
submit(() -> {
mSensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
mSensorManager.registerListener(mSensorEventListener, mLightSensor, SensorManager.SENSOR_DELAY_NORMAL);
});
}
public void deactivateLightSensorRead() {
submit(() -> {
mSensorManager.unregisterListener(mSensorEventListener);
mAutoHBMActive = false;
enableHBM(false);
});
}
private void enableHBM(boolean enable) {
if (enable) {
// Store current brightness before enabling HBM
if (mStoredBrightness == -1) {
mStoredBrightness = Settings.System.getInt(getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS, 255);
}
FileUtils.writeLine(HBM, "1");
FileUtils.writeLine(BACKLIGHT, "2047");
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 255);
} else {
FileUtils.writeLine(HBM, "0");
// Restore brightness when disabling HBM
if (mStoredBrightness != -1) {
FileUtils.writeLine(BACKLIGHT, String.valueOf(mStoredBrightness));
Settings.System.putInt(getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS, mStoredBrightness);
mStoredBrightness = -1;
}
}
}
private boolean isCurrentlyEnabled() {
return FileUtils.getFileValueAsBoolean(HBM, false);
}
private SensorEventListener mSensorEventListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
float lux = event.values[0];
KeyguardManager km =
(KeyguardManager) getSystemService(getApplicationContext().KEYGUARD_SERVICE);
boolean keyguardShowing = km.inKeyguardRestrictedInputMode();
float luxThreshold = Float.parseFloat(mSharedPrefs.getString(HBMFragment.KEY_AUTO_HBM_THRESHOLD, "20000"));
long timeToDisableHBM = Long.parseLong(mSharedPrefs.getString(HBMFragment.KEY_HBM_DISABLE_TIME, "1"));
if (lux > luxThreshold) {
if ((!mAutoHBMActive || !isCurrentlyEnabled()) && !keyguardShowing && !dcDimmingEnabled) {
mAutoHBMActive = true;
enableHBM(true);
}
}
if (lux < luxThreshold) {
if (mAutoHBMActive) {
mExecutorService.submit(() -> {
try {
Thread.sleep(timeToDisableHBM * 1000);
} catch (InterruptedException ignored) {
}
if (lux < luxThreshold) {
mAutoHBMActive = false;
enableHBM(false);
}
});
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// do nothing
}
};
private BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
activateLightSensorRead();
} else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
deactivateLightSensorRead();
}
}
};
@Override
public void onCreate() {
mExecutorService = Executors.newSingleThreadExecutor();
IntentFilter screenStateFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mScreenStateReceiver, screenStateFilter);
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm.isInteractive()) {
activateLightSensorRead();
}
}
private Future<?> submit(Runnable runnable) {
return mExecutorService.submit(runnable);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mScreenStateReceiver);
deactivateLightSensorRead();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
package org.lineageos.settings.hbm;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.AttributeSet;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceViewHolder;
public class AutoHBMThresholdPreference extends CustomSeekBarPreference {
private static int mMinVal = 0;
private static int mMaxVal = 60000;
private static int mDefVal = 20000;
public AutoHBMThresholdPreference(Context context, AttributeSet attrs) {
super(context, attrs);
mInterval = 1000;
mShowSign = false;
mUnits = "";
mContinuousUpdates = false;
mMinValue = mMinVal;
mMaxValue = mMaxVal;
mDefaultValueExists = true;
mDefaultValue = mDefVal;
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
mValue = Integer.parseInt(sharedPrefs.getString(HBMFragment.KEY_AUTO_HBM_THRESHOLD, "20000"));
setPersistent(false);
}
@Override
protected void changeValue(int newValue) {
SharedPreferences.Editor prefChange = PreferenceManager.getDefaultSharedPreferences(getContext()).edit();
prefChange.putString(HBMFragment.KEY_AUTO_HBM_THRESHOLD, String.valueOf(newValue)).commit();
}
}

View file

@ -0,0 +1,46 @@
/*
* Copyright (C) 2016 The OmniROM Project
2023 The Evolution X Project
* SPDX-License-Identifier: GPL-2.0-or-later
*/
package org.lineageos.settings.hbm;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceViewHolder;
public class AutoHBMTimePreference extends CustomSeekBarPreference {
private static int mMinVal = 1;
private static int mMaxVal = 10;
private static int mDefVal = 1;
public AutoHBMTimePreference(Context context, AttributeSet attrs) {
super(context, attrs);
mInterval = 1;
mShowSign = false;
mUnits = "";
mContinuousUpdates = false;
mMinValue = mMinVal;
mMaxValue = mMaxVal;
mDefaultValueExists = true;
mDefaultValue = mDefVal;
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getContext());
mValue = Integer.parseInt(sharedPrefs.getString(HBMFragment.KEY_HBM_DISABLE_TIME, "1"));
setPersistent(false);
}
@Override
protected void changeValue(int newValue) {
SharedPreferences.Editor prefChange = PreferenceManager.getDefaultSharedPreferences(getContext()).edit();
prefChange.putString(HBMFragment.KEY_HBM_DISABLE_TIME, String.valueOf(newValue)).commit();
}
}

View file

@ -0,0 +1,367 @@
/*
* Copyright (C) 2016-2021 crDroid Android 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.settings.hbm;
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 org.lineageos.settings.R;
public class CustomSeekBarPreference extends Preference implements SeekBar.OnSeekBarChangeListener {
protected final String TAG = getClass().getName();
private static final String SETTINGS_NS = "http://schemas.android.com/apk/res/com.android.settings";
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 = 0;
protected int mMaxValue = 100;
protected boolean mDefaultValueExists = false;
protected int mDefaultValue;
protected boolean mDefaultValueTextExists = false;
protected String mDefaultValueText;
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);
String defaultValueText = a.getString(R.styleable.CustomSeekBarPreference_defaultValueText);
mDefaultValueTextExists = defaultValueText != null && !defaultValueText.isEmpty();
if (mDefaultValueTextExists) {
mDefaultValueText = defaultValueText;
}
} finally {
a.recycle();
}
try {
String newInterval = attrs.getAttributeValue(SETTINGS_NS, "interval");
if (newInterval != null)
mInterval = Integer.parseInt(newInterval);
} catch (Exception e) {
Log.e(TAG, "Invalid interval value", e);
}
mMinValue = attrs.getAttributeIntValue(SETTINGS_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 onDependencyChanged(Preference dependency, boolean disableDependent) {
super.onDependencyChanged(dependency, disableDependent);
this.setShouldDisableView(true);
if (mSeekBar != null)
mSeekBar.setEnabled(!disableDependent);
if (mResetImageView != null)
mResetImageView.setEnabled(!disableDependent);
if (mPlusImageView != null)
mPlusImageView.setEnabled(!disableDependent);
if (mMinusImageView != null)
mMinusImageView.setEnabled(!disableDependent);
}
@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(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getContext(), getContext().getString(R.string.custom_seekbar_default_value_to_set, getTextValue(mDefaultValue)),
Toast.LENGTH_LONG).show();
}
});
mResetImageView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
setValue(mDefaultValue, true);
return true;
}
});
mMinusImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setValue(mValue - mInterval, true);
}
});
mMinusImageView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
setValue(mMaxValue - mMinValue > mInterval * 2 && mMaxValue + mMinValue < mValue * 2 ? Math.floorDiv(mMaxValue + mMinValue, 2) : mMinValue, true);
return true;
}
});
mPlusImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
setValue(mValue + mInterval, true);
}
});
mPlusImageView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
setValue(mMaxValue - mMinValue > mInterval * 2 && mMaxValue + mMinValue > mValue * 2 ? -1 * Math.floorDiv(-1 * (mMaxValue + mMinValue), 2) : mMaxValue, true);
return true;
}
});
}
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) {
if (mDefaultValueTextExists && mDefaultValueExists && v == mDefaultValue) {
return mDefaultValueText;
}
return (mShowSign && v > 0 ? "+" : "") + String.valueOf(v) + mUnits;
}
protected void updateValueViews() {
if (mValueTextView != null) {
if (!mTrackingTouch || mContinuousUpdates) {
if (mDefaultValueTextExists && mDefaultValueExists && mValue == mDefaultValue) {
mValueTextView.setText(mDefaultValueText + " (" +
getContext().getString(R.string.custom_seekbar_default_value) + ")");
} else {
mValueTextView.setText(getContext().getString(R.string.custom_seekbar_value, getTextValue(mValue)) +
(mDefaultValueExists && mValue == mDefaultValue ? " (" +
getContext().getString(R.string.custom_seekbar_default_value) + ")" : ""));
}
} else {
if (mDefaultValueTextExists && mDefaultValueExists && mTrackingValue == mDefaultValue) {
mValueTextView.setText("[" + mDefaultValueText + "]");
} else {
mValueTextView.setText(getContext().getString(R.string.custom_seekbar_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
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 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;
}
public void refresh(int newValue) {
// this will ...
setValue(newValue, mSeekBar != null);
}
}

View file

@ -0,0 +1,45 @@
/*
* Copyright (C) 2017 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 <http://www.gnu.org/licenses/>.
*
*/
package org.lineageos.settings.hbm;
import android.app.Fragment;
import android.os.Bundle;
import androidx.preference.PreferenceFragment;
import androidx.preference.PreferenceManager;
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
public class HBMActivity extends CollapsingToolbarBaseActivity {
private HBMFragment mHBMFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Fragment fragment = getFragmentManager().findFragmentById(com.android.settingslib.collapsingtoolbar.R.id.content_frame);
if (fragment == null) {
mHBMFragment = new HBMFragment();
getFragmentManager().beginTransaction()
.add(com.android.settingslib.collapsingtoolbar.R.id.content_frame, mHBMFragment)
.commit();
} else {
mHBMFragment = (HBMFragment) fragment;
}
}
}

View file

@ -0,0 +1,80 @@
/*
* Copyright (C) 2016 The OmniROM Project
* Copyright (C) 2018-2021 crDroid Android Project
* Copyright (C) 2019-2022 Evolution X 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 <http://www.gnu.org/licenses/>.
*
*/
package org.lineageos.settings.hbm;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragment;
import androidx.preference.PreferenceManager;
import androidx.preference.TwoStatePreference;
import org.lineageos.settings.utils.FileUtils;
import org.lineageos.settings.R;
public class HBMFragment extends PreferenceFragment
implements Preference.OnPreferenceChangeListener {
private static final String TAG = HBMFragment.class.getSimpleName();
public static final String KEY_HBM_SWITCH = "hbm";
public static final String KEY_AUTO_HBM_SWITCH = "auto_hbm";
public static final String KEY_AUTO_HBM_THRESHOLD = "auto_hbm_threshold";
public static final String KEY_HBM_DISABLE_TIME = "hbm_disable_time";
private static TwoStatePreference mHBMModeSwitch;
private static TwoStatePreference mAutoHBMSwitch;
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this.getContext());
addPreferencesFromResource(R.xml.hbm_settings);
// HBM
mHBMModeSwitch = (TwoStatePreference) findPreference(KEY_HBM_SWITCH);
mHBMModeSwitch.setOnPreferenceChangeListener(new HBMModeSwitch(getContext()));
// AutoHBM
mAutoHBMSwitch = (TwoStatePreference) findPreference(KEY_AUTO_HBM_SWITCH);
mAutoHBMSwitch.setOnPreferenceChangeListener(this);
mAutoHBMSwitch.setChecked(PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean(HBMFragment.KEY_AUTO_HBM_SWITCH, false));
}
public static boolean isAUTOHBMEnabled(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(HBMFragment.KEY_AUTO_HBM_SWITCH, false);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference == mAutoHBMSwitch) {
Boolean enabled = (Boolean) newValue;
SharedPreferences.Editor prefChange = PreferenceManager.getDefaultSharedPreferences(getContext()).edit();
prefChange.putBoolean(KEY_AUTO_HBM_SWITCH, enabled).commit();
FileUtils.enableService(getContext());
return true;
}
return false;
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
*
*/
package org.lineageos.settings.hbm;
import android.provider.Settings;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.PreferenceManager;
import org.lineageos.settings.utils.FileUtils;
import org.lineageos.settings.display.*;
public class HBMModeSwitch implements OnPreferenceChangeListener {
private static final String HBM = "/sys/devices/platform/soc/soc:qcom,dsi-display-primary/hbm_enabled";
private static final String BACKLIGHT = "/sys/class/backlight/panel0-backlight/brightness";
private Context mContext;
public HBMModeSwitch(Context context) {
mContext = context;
}
public static String getHBM() {
if (FileUtils.isFileWritable(HBM)) {
return HBM;
}
return null;
}
public static String getBACKLIGHT() {
if (FileUtils.isFileWritable(BACKLIGHT)) {
return BACKLIGHT;
}
return null;
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Boolean enabled = (Boolean) newValue;
boolean dcDimmingEnabled = PreferenceManager.getDefaultSharedPreferences(mContext).getBoolean(DcDimmingTileService.DC_DIMMING_ENABLE_KEY, false);
if (dcDimmingEnabled) {
return false;
}
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
if (enabled) {
// Save current brightness level
int currentBrightness = Settings.System.getInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 128);
sharedPrefs.edit().putInt("last_brightness", currentBrightness).apply();
FileUtils.writeLine(getHBM(), "1");
FileUtils.writeLine(getBACKLIGHT(), "2047");
Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 255);
} else {
FileUtils.writeLine(getHBM(), "0");
// Restore last brightness level
int lastBrightness = sharedPrefs.getInt("last_brightness", 128);
Settings.System.putInt(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, lastBrightness);
}
return true;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright (C) 2018 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 <http://www.gnu.org/licenses/>.
*
*/
package org.lineageos.settings.hbm;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.BroadcastReceiver;
import android.service.quicksettings.Tile;
import android.service.quicksettings.TileService;
import androidx.preference.PreferenceManager;
import android.provider.Settings;
import org.lineageos.settings.utils.FileUtils;
import org.lineageos.settings.display.*;
public class HBMModeTileService extends TileService {
private static final String HBM = "/sys/devices/platform/soc/soc:qcom,dsi-display-primary/hbm_enabled";
private static final String HBM_KEY = "hbm";
private static final String BACKLIGHT = "/sys/class/backlight/panel0-backlight/brightness";
private BroadcastReceiver screenStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
sharedPrefs.edit().putBoolean(HBM_KEY, false).commit();
updateUI(false);
}
}
};
private void updateUI(boolean enabled) {
final Tile tile = getQsTile();
tile.setState(enabled ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
tile.updateTile();
}
@Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(screenStateReceiver, filter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(screenStateReceiver);
}
@Override
public void onStartListening() {
super.onStartListening();
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
updateUI(sharedPrefs.getBoolean(HBM_KEY, false));
}
@Override
public void onStopListening() {
super.onStopListening();
}
@Override
public void onClick() {
super.onClick();
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
final boolean dcDimmingEnabled = sharedPrefs.getBoolean(DcDimmingTileService.DC_DIMMING_ENABLE_KEY, false);
if (dcDimmingEnabled) {
return;
}
final boolean enabled = !(sharedPrefs.getBoolean(HBM_KEY, false));
if (enabled) {
// Save current brightness level
int currentBrightness = Settings.System.getInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 128);
sharedPrefs.edit().putInt("last_brightness", currentBrightness).apply();
FileUtils.writeLine(HBM, "1");
FileUtils.writeLine(BACKLIGHT, "2047");
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 255);
} else {
FileUtils.writeLine(HBM, "0");
// Restore last brightness level
int lastBrightness = sharedPrefs.getInt("last_brightness", 128);
Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, lastBrightness);
}
sharedPrefs.edit().putBoolean(HBM_KEY, enabled).commit();
updateUI(enabled);
}
}

View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2020-2022 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.settings.refreshrate;
import android.os.Bundle;
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
public class RefreshActivity extends CollapsingToolbarBaseActivity {
private static final String TAG_REFRESH = "refresh";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(com.android.settingslib.collapsingtoolbar.R.id.content_frame,
new RefreshSettingsFragment(), TAG_REFRESH).commit();
}
}

View file

@ -0,0 +1,102 @@
/*
* Copyright (C) 2020 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.settings.refreshrate;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.ActivityTaskManager.RootTaskInfo;
import android.app.IActivityTaskManager;
import android.app.TaskStackListener;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.os.RemoteException;
public class RefreshService extends Service {
private static final String TAG = "RefreshService";
private static final boolean DEBUG = true;
private String mPreviousApp;
private RefreshUtils mRefreshUtils;
private IActivityTaskManager mActivityTaskManager;
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mPreviousApp = "";
}
};
@Override
public void onCreate() {
if (DEBUG) Log.d(TAG, "Creating service");
try {
mActivityTaskManager = ActivityTaskManager.getService();
mActivityTaskManager.registerTaskStackListener(mTaskListener);
} catch (RemoteException e) {
// Do nothing
}
mRefreshUtils = new RefreshUtils(this);
registerReceiver();
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (DEBUG) Log.d(TAG, "Starting service");
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void registerReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
this.registerReceiver(mIntentReceiver, filter);
}
private final TaskStackListener mTaskListener = new TaskStackListener() {
@Override
public void onTaskStackChanged() {
try {
final RootTaskInfo info = mActivityTaskManager.getFocusedRootTaskInfo();
if (info == null || info.topActivity == null) {
return;
}
String foregroundApp = info.topActivity.getPackageName();
if (!mRefreshUtils.isAppInList) {
mRefreshUtils.getOldRate();
}
if (!foregroundApp.equals(mPreviousApp)) {
mRefreshUtils.setRefreshRate(foregroundApp);
mPreviousApp = foregroundApp;
}
} catch (Exception e) {}
}
};
}

View file

@ -0,0 +1,419 @@
/**
* Copyright (C) 2020 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.settings.refreshrate;
import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SectionIndexer;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.preference.PreferenceFragment;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.android.settingslib.applications.ApplicationsState;
import org.lineageos.settings.R;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class RefreshSettingsFragment extends PreferenceFragment
implements ApplicationsState.Callbacks {
private AllPackagesAdapter mAllPackagesAdapter;
private ApplicationsState mApplicationsState;
private ApplicationsState.Session mSession;
private ActivityFilter mActivityFilter;
private Map<String, ApplicationsState.AppEntry> mEntryMap =
new HashMap<String, ApplicationsState.AppEntry>();
private RefreshUtils mRefreshUtils;
private RecyclerView mAppsRecyclerView;
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mApplicationsState = ApplicationsState.getInstance(getActivity().getApplication());
mSession = mApplicationsState.newSession(this);
mSession.onResume();
mActivityFilter = new ActivityFilter(getActivity().getPackageManager());
mAllPackagesAdapter = new AllPackagesAdapter(getActivity());
mRefreshUtils = new RefreshUtils(getActivity());
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.refresh_layout, container, false);
}
@Override
public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mAppsRecyclerView = view.findViewById(R.id.refresh_rv_view);
mAppsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mAppsRecyclerView.setAdapter(mAllPackagesAdapter);
}
@Override
public void onResume() {
super.onResume();
getActivity().setTitle(getResources().getString(R.string.refresh_title));
rebuild();
}
@Override
public void onDestroy() {
super.onDestroy();
mSession.onPause();
mSession.onDestroy();
}
@Override
public void onPackageListChanged() {
mActivityFilter.updateLauncherInfoList();
rebuild();
}
@Override
public void onRebuildComplete(ArrayList<ApplicationsState.AppEntry> entries) {
if (entries != null) {
handleAppEntries(entries);
mAllPackagesAdapter.notifyDataSetChanged();
}
}
@Override
public void onLoadEntriesCompleted() {
rebuild();
}
@Override
public void onAllSizesComputed() {
}
@Override
public void onLauncherInfoChanged() {
}
@Override
public void onPackageIconChanged() {
}
@Override
public void onPackageSizeChanged(String packageName) {
}
@Override
public void onRunningStateChanged(boolean running) {
}
private void handleAppEntries(List<ApplicationsState.AppEntry> entries) {
final ArrayList<String> sections = new ArrayList<String>();
final ArrayList<Integer> positions = new ArrayList<Integer>();
final PackageManager pm = getActivity().getPackageManager();
String lastSectionIndex = null;
int offset = 0;
for (int i = 0; i < entries.size(); i++) {
final ApplicationInfo info = entries.get(i).info;
final String label = (String) info.loadLabel(pm);
final String sectionIndex;
if (!info.enabled) {
sectionIndex = "--"; // XXX
} else if (TextUtils.isEmpty(label)) {
sectionIndex = "";
} else {
sectionIndex = label.substring(0, 1).toUpperCase();
}
if (lastSectionIndex == null ||
!TextUtils.equals(sectionIndex, lastSectionIndex)) {
sections.add(sectionIndex);
positions.add(offset);
lastSectionIndex = sectionIndex;
}
offset++;
}
mAllPackagesAdapter.setEntries(entries, sections, positions);
mEntryMap.clear();
for (ApplicationsState.AppEntry e : entries) {
mEntryMap.put(e.info.packageName, e);
}
}
private void rebuild() {
mSession.rebuild(mActivityFilter, ApplicationsState.ALPHA_COMPARATOR);
}
private int getStateDrawable(int state) {
switch (state) {
case RefreshUtils.STATE_STANDARD:
return R.drawable.ic_refresh_60;
case RefreshUtils.STATE_EXTREME:
return R.drawable.ic_refresh_120;
case RefreshUtils.STATE_DEFAULT:
default:
return R.drawable.ic_refresh_default;
}
}
private class ViewHolder extends RecyclerView.ViewHolder {
private TextView title;
private Spinner mode;
private ImageView icon;
private View rootView;
private ImageView stateIcon;
private ViewHolder(View view) {
super(view);
this.title = view.findViewById(R.id.app_name);
this.mode = view.findViewById(R.id.app_mode);
this.icon = view.findViewById(R.id.app_icon);
this.stateIcon = view.findViewById(R.id.state);
this.rootView = view;
view.setTag(this);
}
}
private class ModeAdapter extends BaseAdapter {
private final LayoutInflater inflater;
private final int[] items = {
R.string.refresh_default,
R.string.refresh_standard,
R.string.refresh_extreme
};
private ModeAdapter(Context context) {
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return items.length;
}
@Override
public Object getItem(int position) {
return items[position];
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView view;
if (convertView != null) {
view = (TextView) convertView;
} else {
view = (TextView) inflater.inflate(android.R.layout.simple_spinner_dropdown_item,
parent, false);
}
view.setText(items[position]);
view.setTextSize(14f);
return view;
}
}
private class AllPackagesAdapter extends RecyclerView.Adapter<ViewHolder>
implements AdapterView.OnItemSelectedListener, SectionIndexer {
private List<ApplicationsState.AppEntry> mEntries = new ArrayList<>();
private String[] mSections;
private int[] mPositions;
public AllPackagesAdapter(Context context) {
mActivityFilter = new ActivityFilter(context.getPackageManager());
}
@Override
public int getItemCount() {
return mEntries.size();
}
@Override
public long getItemId(int position) {
return mEntries.get(position).id;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.refresh_list_item, parent, false));
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Context context = holder.itemView.getContext();
ApplicationsState.AppEntry entry = mEntries.get(position);
if (entry == null) {
return;
}
holder.mode.setAdapter(new ModeAdapter(context));
holder.mode.setOnItemSelectedListener(this);
holder.title.setText(entry.label);
holder.title.setOnClickListener(v -> holder.mode.performClick());
mApplicationsState.ensureIcon(entry);
holder.icon.setImageDrawable(entry.icon);
int packageState = mRefreshUtils.getStateForPackage(entry.info.packageName);
holder.mode.setSelection(packageState, false);
holder.mode.setTag(entry);
holder.stateIcon.setImageResource(getStateDrawable(packageState));
}
private void setEntries(List<ApplicationsState.AppEntry> entries,
List<String> sections, List<Integer> positions) {
mEntries = entries;
mSections = sections.toArray(new String[sections.size()]);
mPositions = new int[positions.size()];
for (int i = 0; i < positions.size(); i++) {
mPositions[i] = positions.get(i);
}
notifyDataSetChanged();
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
final ApplicationsState.AppEntry entry = (ApplicationsState.AppEntry) parent.getTag();
int currentState = mRefreshUtils.getStateForPackage(entry.info.packageName);
if (currentState != position) {
mRefreshUtils.writePackage(entry.info.packageName, position);
notifyDataSetChanged();
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
@Override
public int getPositionForSection(int section) {
if (section < 0 || section >= mSections.length) {
return -1;
}
return mPositions[section];
}
@Override
public int getSectionForPosition(int position) {
if (position < 0 || position >= getItemCount()) {
return -1;
}
final int index = Arrays.binarySearch(mPositions, position);
/*
* Consider this example: section positions are 0, 3, 5; the supplied
* position is 4. The section corresponding to position 4 starts at
* position 3, so the expected return value is 1. Binary search will not
* find 4 in the array and thus will return -insertPosition-1, i.e. -3.
* To get from that number to the expected value of 1 we need to negate
* and subtract 2.
*/
return index >= 0 ? index : -index - 2;
}
@Override
public Object[] getSections() {
return mSections;
}
}
private class ActivityFilter implements ApplicationsState.AppFilter {
private final PackageManager mPackageManager;
private final List<String> mLauncherResolveInfoList = new ArrayList<String>();
private ActivityFilter(PackageManager packageManager) {
this.mPackageManager = packageManager;
updateLauncherInfoList();
}
public void updateLauncherInfoList() {
Intent i = new Intent(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveInfoList = mPackageManager.queryIntentActivities(i, 0);
synchronized (mLauncherResolveInfoList) {
mLauncherResolveInfoList.clear();
for (ResolveInfo ri : resolveInfoList) {
mLauncherResolveInfoList.add(ri.activityInfo.packageName);
}
}
}
@Override
public void init() {
}
@Override
public boolean filterApp(ApplicationsState.AppEntry entry) {
boolean show = !mAllPackagesAdapter.mEntries.contains(entry.info.packageName);
if (show) {
synchronized (mLauncherResolveInfoList) {
show = mLauncherResolveInfoList.contains(entry.info.packageName);
}
}
return show;
}
}
}

View file

@ -0,0 +1,141 @@
/*
* Copyright (C) 2020 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.settings.refreshrate;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.UserHandle;
import android.view.Display;
import android.provider.Settings;
import androidx.preference.PreferenceManager;
public final class RefreshUtils {
private static final String REFRESH_CONTROL = "refresh_control";
private static float defaultMaxRate;
private static float defaultMinRate;
private static final String KEY_PEAK_REFRESH_RATE = "peak_refresh_rate";
private static final String KEY_MIN_REFRESH_RATE = "min_refresh_rate";
private Context mContext;
protected static boolean isAppInList = false;
protected static final int STATE_DEFAULT = 0;
protected static final int STATE_STANDARD = 1;
protected static final int STATE_EXTREME = 2;
private static final float REFRESH_STATE_DEFAULT = 120f;
private static final float REFRESH_STATE_STANDARD = 60f;
private static final float REFRESH_STATE_EXTREME = 120f;
private static final String REFRESH_STANDARD = "refresh.standard=";
private static final String REFRESH_EXTREME = "refresh.extreme=";
private SharedPreferences mSharedPrefs;
protected RefreshUtils(Context context) {
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
mContext = context;
}
public static void startService(Context context) {
context.startServiceAsUser(new Intent(context, RefreshService.class),
UserHandle.CURRENT);
}
private void writeValue(String profiles) {
mSharedPrefs.edit().putString(REFRESH_CONTROL, profiles).apply();
}
protected void getOldRate(){
defaultMaxRate = Settings.System.getFloat(mContext.getContentResolver(), KEY_PEAK_REFRESH_RATE, REFRESH_STATE_DEFAULT);
defaultMinRate = Settings.System.getFloat(mContext.getContentResolver(), KEY_MIN_REFRESH_RATE, REFRESH_STATE_DEFAULT);
}
private String getValue() {
String value = mSharedPrefs.getString(REFRESH_CONTROL, null);
if (value == null || value.isEmpty()) {
value = REFRESH_STANDARD + ":" + REFRESH_EXTREME;
writeValue(value);
}
return value;
}
protected void writePackage(String packageName, int mode) {
String value = getValue();
value = value.replace(packageName + ",", "");
String[] modes = value.split(":");
String finalString;
switch (mode) {
case STATE_STANDARD:
modes[0] = modes[0] + packageName + ",";
break;
case STATE_EXTREME:
modes[1] = modes[1] + packageName + ",";
break;
}
finalString = modes[0] + ":" + modes[1];
writeValue(finalString);
}
protected int getStateForPackage(String packageName) {
String value = getValue();
String[] modes = value.split(":");
int state = STATE_DEFAULT;
if (modes[0].contains(packageName + ",")) {
state = STATE_STANDARD;
} else if (modes[1].contains(packageName + ",")) {
state = STATE_EXTREME;
}
return state;
}
protected void setRefreshRate(String packageName) {
String value = getValue();
String modes[];
float maxrate = defaultMaxRate;
float minrate = defaultMinRate;
isAppInList = false;
if (value != null) {
modes = value.split(":");
if (modes[0].contains(packageName + ",")) {
maxrate = REFRESH_STATE_STANDARD;
if ( minrate > maxrate){
minrate = maxrate;
}
isAppInList = true;
} else if (modes[1].contains(packageName + ",")) {
maxrate = REFRESH_STATE_EXTREME;
if ( minrate > maxrate){
minrate = maxrate;
}
isAppInList = true;
}
}
Settings.System.putFloat(mContext.getContentResolver(), KEY_MIN_REFRESH_RATE, minrate);
Settings.System.putFloat(mContext.getContentResolver(), KEY_PEAK_REFRESH_RATE, maxrate);
}
}

View file

@ -0,0 +1,34 @@
/*
* 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 org.lineageos.settings.speaker;
import android.os.Bundle;
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
public class ClearSpeakerActivity extends CollapsingToolbarBaseActivity {
private static final String TAG_CLEARSPEAKER = "clearspeaker";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(com.android.settingslib.collapsingtoolbar.R.id.content_frame,
new ClearSpeakerFragment(), TAG_CLEARSPEAKER).commit();
}
}

View file

@ -0,0 +1,121 @@
/*
* 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 org.lineageos.settings.speaker;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.AudioAttributes;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragment;
import androidx.preference.SwitchPreference;
import org.lineageos.settings.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 = (SwitchPreference) 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(() -> {
stopPlaying();
}, 30000);
return true;
}
}
}
return false;
}
@Override
public void onStop() {
super.onStop();
stopPlaying();
}
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 {
AssetFileDescriptor file = getResources().openRawResourceFd(R.raw.clear_speaker_sound);
try {
mMediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
} finally {
file.close();
}
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;
}
public void stopPlaying() {
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer=null;
}
}
mAudioManager.setParameters("status_earpiece_clean=off");
mClearSpeakerPref.setEnabled(true);
mClearSpeakerPref.setChecked(false);
}
}

Some files were not shown because too many files have changed in this diff Show more