sm8350-common: parts: Import from xiaomi_sdm845-common
e261035d91/parts
Change-Id: I442f48780ca020f3e420ee4ccaf8ac07b05457cb
Signed-off-by: Anush02198 <anush.4376@gmail.com>
This commit is contained in:
parent
7b5ee0675f
commit
a873a54015
@ -128,6 +128,10 @@ PRODUCT_COPY_FILES += \
|
||||
# DebugFS
|
||||
PRODUCT_SET_DEBUGFS_RESTRICTIONS := true
|
||||
|
||||
# Device-specific settings
|
||||
PRODUCT_PACKAGES += \
|
||||
XiaomiParts
|
||||
|
||||
# Display
|
||||
PRODUCT_PACKAGES += \
|
||||
android.hardware.graphics.mapper@3.0-impl-qti-display \
|
||||
|
@ -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
|
||||
|
25
parts/Android.bp
Normal file
25
parts/Android.bp
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// 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",
|
||||
],
|
||||
|
||||
optimize: {
|
||||
proguard_flags_files: ["proguard.flags"],
|
||||
},
|
||||
|
||||
}
|
115
parts/AndroidManifest.xml
Normal file
115
parts/AndroidManifest.xml
Normal file
@ -0,0 +1,115 @@
|
||||
<?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"
|
||||
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" />
|
||||
|
||||
<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" />
|
||||
<meta-data
|
||||
android:name="com.android.settings.order"
|
||||
android:value="1" />
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name=".thermal.ThermalService"
|
||||
android:permission="ThermalService">
|
||||
</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>
|
||||
|
||||
</application>
|
||||
</manifest>
|
3
parts/proguard.flags
Normal file
3
parts/proguard.flags
Normal file
@ -0,0 +1,3 @@
|
||||
-keep class org.lineageos.settings.doze.* {
|
||||
*;
|
||||
}
|
13
parts/res/drawable/ic_clear_speaker.xml
Normal file
13
parts/res/drawable/ic_clear_speaker.xml
Normal 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>
|
9
parts/res/drawable/ic_doze_aod.xml
Normal file
9
parts/res/drawable/ic_doze_aod.xml
Normal 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>
|
9
parts/res/drawable/ic_doze_brightness_auto.xml
Normal file
9
parts/res/drawable/ic_doze_brightness_auto.xml
Normal 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>
|
9
parts/res/drawable/ic_doze_brightness_high.xml
Normal file
9
parts/res/drawable/ic_doze_brightness_high.xml
Normal 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>
|
9
parts/res/drawable/ic_doze_brightness_low.xml
Normal file
9
parts/res/drawable/ic_doze_brightness_low.xml
Normal 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>
|
22
parts/res/drawable/ic_refresh_120.xml
Normal file
22
parts/res/drawable/ic_refresh_120.xml
Normal 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>
|
17
parts/res/drawable/ic_refresh_60.xml
Normal file
17
parts/res/drawable/ic_refresh_60.xml
Normal 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>
|
11
parts/res/drawable/ic_refresh_default.xml
Normal file
11
parts/res/drawable/ic_refresh_default.xml
Normal 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>
|
9
parts/res/drawable/ic_scenes.xml
Normal file
9
parts/res/drawable/ic_scenes.xml
Normal 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>
|
19
parts/res/drawable/ic_thermal_benchmark.xml
Normal file
19
parts/res/drawable/ic_thermal_benchmark.xml
Normal 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>
|
11
parts/res/drawable/ic_thermal_browser.xml
Normal file
11
parts/res/drawable/ic_thermal_browser.xml
Normal 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>
|
19
parts/res/drawable/ic_thermal_camera.xml
Normal file
19
parts/res/drawable/ic_thermal_camera.xml
Normal 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>
|
19
parts/res/drawable/ic_thermal_default.xml
Normal file
19
parts/res/drawable/ic_thermal_default.xml
Normal 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>
|
18
parts/res/drawable/ic_thermal_dialer.xml
Normal file
18
parts/res/drawable/ic_thermal_dialer.xml
Normal 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>
|
19
parts/res/drawable/ic_thermal_gaming.xml
Normal file
19
parts/res/drawable/ic_thermal_gaming.xml
Normal 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>
|
19
parts/res/drawable/ic_thermal_streaming.xml
Normal file
19
parts/res/drawable/ic_thermal_streaming.xml
Normal 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>
|
18
parts/res/layout/refresh_layout.xml
Normal file
18
parts/res/layout/refresh_layout.xml
Normal 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" />
|
64
parts/res/layout/refresh_list_item.xml
Normal file
64
parts/res/layout/refresh_list_item.xml
Normal 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>
|
18
parts/res/layout/thermal_layout.xml
Normal file
18
parts/res/layout/thermal_layout.xml
Normal 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" />
|
64
parts/res/layout/thermal_list_item.xml
Normal file
64
parts/res/layout/thermal_list_item.xml
Normal 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>
|
BIN
parts/res/raw/clear_speaker_sound.mp3
Normal file
BIN
parts/res/raw/clear_speaker_sound.mp3
Normal file
Binary file not shown.
28
parts/res/values/arrays.xml
Normal file
28
parts/res/values/arrays.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?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>
|
||||
</resources>
|
49
parts/res/values/strings.xml
Normal file
49
parts/res/values/strings.xml
Normal file
@ -0,0 +1,49 @@
|
||||
<?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_streaming">Streaming</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>
|
||||
|
||||
</resources>
|
17
parts/res/xml/clear_speaker_settings.xml
Normal file
17
parts/res/xml/clear_speaker_settings.xml
Normal 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>
|
42
parts/res/xml/doze_settings.xml
Normal file
42
parts/res/xml/doze_settings.xml
Normal 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>
|
41
parts/src/org/lineageos/settings/BootCompletedReceiver.java
Normal file
41
parts/src/org/lineageos/settings/BootCompletedReceiver.java
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 org.lineageos.settings.doze.DozeUtils;
|
||||
import org.lineageos.settings.thermal.ThermalUtils;
|
||||
import org.lineageos.settings.refreshrate.RefreshUtils;
|
||||
|
||||
public class BootCompletedReceiver extends BroadcastReceiver {
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String TAG = "XiaomiParts";
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, Intent intent) {
|
||||
if (DEBUG)
|
||||
Log.d(TAG, "Received boot completed intent");
|
||||
DozeUtils.onBootCompleted(context);
|
||||
ThermalUtils.startService(context);
|
||||
RefreshUtils.startService(context);
|
||||
}
|
||||
}
|
80
parts/src/org/lineageos/settings/doze/AodSensor.java
Normal file
80
parts/src/org/lineageos/settings/doze/AodSensor.java
Normal 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); });
|
||||
}
|
||||
}
|
92
parts/src/org/lineageos/settings/doze/DozeService.java
Normal file
92
parts/src/org/lineageos/settings/doze/DozeService.java
Normal 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();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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;
|
||||
import com.android.settingslib.widget.R;
|
||||
|
||||
public class DozeSettingsActivity extends CollapsingToolbarBaseActivity {
|
||||
private static final String TAG_DOZE = "doze";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getFragmentManager().beginTransaction().replace(R.id.content_frame,
|
||||
new DozeSettingsFragment(), TAG_DOZE).commit();
|
||||
}
|
||||
}
|
156
parts/src/org/lineageos/settings/doze/DozeSettingsFragment.java
Normal file
156
parts/src/org/lineageos/settings/doze/DozeSettingsFragment.java
Normal 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.Switch;
|
||||
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 com.android.settingslib.widget.OnMainSwitchChangeListener;
|
||||
|
||||
import org.lineageos.settings.R;
|
||||
import org.lineageos.settings.utils.FileUtils;
|
||||
|
||||
public class DozeSettingsFragment extends PreferenceFragment
|
||||
implements OnPreferenceChangeListener, OnMainSwitchChangeListener {
|
||||
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 onSwitchChanged(Switch switchView, 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");
|
||||
}
|
||||
}
|
155
parts/src/org/lineageos/settings/doze/DozeUtils.java
Normal file
155
parts/src/org/lineageos/settings/doze/DozeUtils.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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;
|
||||
import com.android.settingslib.widget.R;
|
||||
|
||||
public class RefreshActivity extends CollapsingToolbarBaseActivity {
|
||||
private static final String TAG_REFRESH = "refresh";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getFragmentManager().beginTransaction().replace(R.id.content_frame,
|
||||
new RefreshSettingsFragment(), TAG_REFRESH).commit();
|
||||
}
|
||||
}
|
102
parts/src/org/lineageos/settings/refreshrate/RefreshService.java
Normal file
102
parts/src/org/lineageos/settings/refreshrate/RefreshService.java
Normal 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) {}
|
||||
}
|
||||
};
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
141
parts/src/org/lineageos/settings/refreshrate/RefreshUtils.java
Normal file
141
parts/src/org/lineageos/settings/refreshrate/RefreshUtils.java
Normal 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);
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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;
|
||||
import com.android.settingslib.widget.R;
|
||||
|
||||
public class ClearSpeakerActivity extends CollapsingToolbarBaseActivity {
|
||||
|
||||
private static final String TAG_CLEARSPEAKER = "clearspeaker";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getFragmentManager().beginTransaction().replace(R.id.content_frame,
|
||||
new ClearSpeakerFragment(), TAG_CLEARSPEAKER).commit();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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.thermal;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
|
||||
|
||||
public class ThermalActivity extends CollapsingToolbarBaseActivity {
|
||||
private static final String TAG_THERMAL = "thermal";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getFragmentManager().beginTransaction().replace(com.android.settingslib.collapsingtoolbar.R.id.content_frame,
|
||||
new ThermalSettingsFragment(), TAG_THERMAL).commit();
|
||||
}
|
||||
}
|
96
parts/src/org/lineageos/settings/thermal/ThermalService.java
Normal file
96
parts/src/org/lineageos/settings/thermal/ThermalService.java
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.thermal;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityTaskManager;
|
||||
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.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
public class ThermalService extends Service {
|
||||
|
||||
private static final String TAG = "ThermalService";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private String mPreviousApp;
|
||||
private ThermalUtils mThermalUtils;
|
||||
|
||||
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
mPreviousApp = "";
|
||||
mThermalUtils.setDefaultThermalProfile();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
if (DEBUG) Log.d(TAG, "Creating service");
|
||||
try {
|
||||
ActivityTaskManager.getService().registerTaskStackListener(mTaskListener);
|
||||
} catch (RemoteException e) {
|
||||
// Do nothing
|
||||
}
|
||||
mThermalUtils = new ThermalUtils(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 ActivityTaskManager.RootTaskInfo focusedTask =
|
||||
ActivityTaskManager.getService().getFocusedRootTaskInfo();
|
||||
if (focusedTask != null && focusedTask.topActivity != null) {
|
||||
ComponentName taskComponentName = focusedTask.topActivity;
|
||||
String foregroundApp = taskComponentName.getPackageName();
|
||||
if (!foregroundApp.equals(mPreviousApp)) {
|
||||
mThermalUtils.setThermalProfile(foregroundApp);
|
||||
mPreviousApp = foregroundApp;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
};
|
||||
}
|
@ -0,0 +1,428 @@
|
||||
/**
|
||||
* 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.thermal;
|
||||
|
||||
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 ThermalSettingsFragment 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 ThermalUtils mThermalUtils;
|
||||
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());
|
||||
|
||||
mThermalUtils = new ThermalUtils(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.thermal_layout, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
mAppsRecyclerView = view.findViewById(R.id.thermal_rv_view);
|
||||
mAppsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
|
||||
mAppsRecyclerView.setAdapter(mAllPackagesAdapter);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
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 ThermalUtils.STATE_BENCHMARK:
|
||||
return R.drawable.ic_thermal_benchmark;
|
||||
case ThermalUtils.STATE_BROWSER:
|
||||
return R.drawable.ic_thermal_browser;
|
||||
case ThermalUtils.STATE_CAMERA:
|
||||
return R.drawable.ic_thermal_camera;
|
||||
case ThermalUtils.STATE_DIALER:
|
||||
return R.drawable.ic_thermal_dialer;
|
||||
case ThermalUtils.STATE_GAMING:
|
||||
return R.drawable.ic_thermal_gaming;
|
||||
case ThermalUtils.STATE_STREAMING:
|
||||
return R.drawable.ic_thermal_streaming;
|
||||
case ThermalUtils.STATE_DEFAULT:
|
||||
default:
|
||||
return R.drawable.ic_thermal_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.thermal_default,
|
||||
R.string.thermal_benchmark,
|
||||
R.string.thermal_browser,
|
||||
R.string.thermal_camera,
|
||||
R.string.thermal_dialer,
|
||||
R.string.thermal_gaming,
|
||||
R.string.thermal_streaming
|
||||
};
|
||||
|
||||
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.thermal_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 = mThermalUtils.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 = mThermalUtils.getStateForPackage(entry.info.packageName);
|
||||
if (currentState != position) {
|
||||
mThermalUtils.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;
|
||||
}
|
||||
}
|
||||
}
|
165
parts/src/org/lineageos/settings/thermal/ThermalUtils.java
Normal file
165
parts/src/org/lineageos/settings/thermal/ThermalUtils.java
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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.thermal;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import org.lineageos.settings.utils.FileUtils;
|
||||
|
||||
public final class ThermalUtils {
|
||||
|
||||
private static final String THERMAL_CONTROL = "thermal_control";
|
||||
|
||||
protected static final int STATE_DEFAULT = 0;
|
||||
protected static final int STATE_BENCHMARK = 1;
|
||||
protected static final int STATE_BROWSER = 2;
|
||||
protected static final int STATE_CAMERA = 3;
|
||||
protected static final int STATE_DIALER = 4;
|
||||
protected static final int STATE_GAMING = 5;
|
||||
protected static final int STATE_STREAMING = 6;
|
||||
|
||||
private static final String THERMAL_STATE_DEFAULT = "0";
|
||||
private static final String THERMAL_STATE_BENCHMARK = "10";
|
||||
private static final String THERMAL_STATE_BROWSER = "11";
|
||||
private static final String THERMAL_STATE_CAMERA = "12";
|
||||
private static final String THERMAL_STATE_DIALER = "8";
|
||||
private static final String THERMAL_STATE_GAMING = "9";
|
||||
private static final String THERMAL_STATE_STREAMING = "14";
|
||||
|
||||
private static final String THERMAL_BENCHMARK = "thermal.benchmark=";
|
||||
private static final String THERMAL_BROWSER = "thermal.browser=";
|
||||
private static final String THERMAL_CAMERA = "thermal.camera=";
|
||||
private static final String THERMAL_DIALER = "thermal.dialer=";
|
||||
private static final String THERMAL_GAMING = "thermal.gaming=";
|
||||
private static final String THERMAL_STREAMING = "thermal.streaming=";
|
||||
|
||||
private static final String THERMAL_SCONFIG = "/sys/class/thermal/thermal_message/sconfig";
|
||||
|
||||
private SharedPreferences mSharedPrefs;
|
||||
|
||||
protected ThermalUtils(Context context) {
|
||||
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
}
|
||||
|
||||
public static void startService(Context context) {
|
||||
context.startServiceAsUser(new Intent(context, ThermalService.class),
|
||||
UserHandle.CURRENT);
|
||||
}
|
||||
|
||||
private void writeValue(String profiles) {
|
||||
mSharedPrefs.edit().putString(THERMAL_CONTROL, profiles).apply();
|
||||
}
|
||||
|
||||
private String getValue() {
|
||||
String value = mSharedPrefs.getString(THERMAL_CONTROL, null);
|
||||
|
||||
if (value == null || value.isEmpty()) {
|
||||
value = THERMAL_BENCHMARK + ":" + THERMAL_BROWSER + ":" + THERMAL_CAMERA + ":" +
|
||||
THERMAL_DIALER + ":" + THERMAL_GAMING + ":" + THERMAL_STREAMING;
|
||||
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_BENCHMARK:
|
||||
modes[0] = modes[0] + packageName + ",";
|
||||
break;
|
||||
case STATE_BROWSER:
|
||||
modes[1] = modes[1] + packageName + ",";
|
||||
break;
|
||||
case STATE_CAMERA:
|
||||
modes[2] = modes[2] + packageName + ",";
|
||||
break;
|
||||
case STATE_DIALER:
|
||||
modes[3] = modes[3] + packageName + ",";
|
||||
break;
|
||||
case STATE_GAMING:
|
||||
modes[4] = modes[4] + packageName + ",";
|
||||
break;
|
||||
case STATE_STREAMING:
|
||||
modes[5] = modes[5] + packageName + ",";
|
||||
break;
|
||||
}
|
||||
|
||||
finalString = modes[0] + ":" + modes[1] + ":" + modes[2] + ":" + modes[3] + ":" +
|
||||
modes[4] + ":" + modes[5];
|
||||
|
||||
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_BENCHMARK;
|
||||
} else if (modes[1].contains(packageName + ",")) {
|
||||
state = STATE_BROWSER;
|
||||
} else if (modes[2].contains(packageName + ",")) {
|
||||
state = STATE_CAMERA;
|
||||
} else if (modes[3].contains(packageName + ",")) {
|
||||
state = STATE_DIALER;
|
||||
} else if (modes[4].contains(packageName + ",")) {
|
||||
state = STATE_GAMING;
|
||||
} else if (modes[5].contains(packageName + ",")) {
|
||||
state = STATE_STREAMING;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
protected void setDefaultThermalProfile() {
|
||||
FileUtils.writeLine(THERMAL_SCONFIG, THERMAL_STATE_DEFAULT);
|
||||
}
|
||||
|
||||
protected void setThermalProfile(String packageName) {
|
||||
String value = getValue();
|
||||
String modes[];
|
||||
String state = THERMAL_STATE_DEFAULT;
|
||||
|
||||
if (value != null) {
|
||||
modes = value.split(":");
|
||||
|
||||
if (modes[0].contains(packageName + ",")) {
|
||||
state = THERMAL_STATE_BENCHMARK;
|
||||
} else if (modes[1].contains(packageName + ",")) {
|
||||
state = THERMAL_STATE_BROWSER;
|
||||
} else if (modes[2].contains(packageName + ",")) {
|
||||
state = THERMAL_STATE_CAMERA;
|
||||
} else if (modes[3].contains(packageName + ",")) {
|
||||
state = THERMAL_STATE_DIALER;
|
||||
} else if (modes[4].contains(packageName + ",")) {
|
||||
state = THERMAL_STATE_GAMING;
|
||||
} else if (modes[5].contains(packageName + ",")) {
|
||||
state = THERMAL_STATE_STREAMING;
|
||||
}
|
||||
}
|
||||
FileUtils.writeLine(THERMAL_SCONFIG, state);
|
||||
}
|
||||
}
|
160
parts/src/org/lineageos/settings/utils/FileUtils.java
Normal file
160
parts/src/org/lineageos/settings/utils/FileUtils.java
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.lineageos.settings.utils;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
public final class FileUtils {
|
||||
private static final String TAG = "FileUtils";
|
||||
|
||||
private FileUtils() {
|
||||
// This class is not supposed to be instantiated
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the first line of text from the given file.
|
||||
* Reference {@link BufferedReader#readLine()} for clarification on what a line is
|
||||
*
|
||||
* @return the read line contents, or null on failure
|
||||
*/
|
||||
public static String readOneLine(String fileName) {
|
||||
String line = null;
|
||||
BufferedReader reader = null;
|
||||
|
||||
try {
|
||||
reader = new BufferedReader(new FileReader(fileName), 512);
|
||||
line = reader.readLine();
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(TAG, "No such file " + fileName + " for reading", e);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not read from file " + fileName, e);
|
||||
} finally {
|
||||
try {
|
||||
if (reader != null) {
|
||||
reader.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignored, not much we can do anyway
|
||||
}
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given value into the given file
|
||||
*
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
public static boolean writeLine(String fileName, String value) {
|
||||
BufferedWriter writer = null;
|
||||
|
||||
try {
|
||||
writer = new BufferedWriter(new FileWriter(fileName));
|
||||
writer.write(value);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(TAG, "No such file " + fileName + " for writing", e);
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not write to file " + fileName, e);
|
||||
return false;
|
||||
} finally {
|
||||
try {
|
||||
if (writer != null) {
|
||||
writer.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignored, not much we can do anyway
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given file exists
|
||||
*
|
||||
* @return true if exists, false if not
|
||||
*/
|
||||
public static boolean fileExists(String fileName) {
|
||||
final File file = new File(fileName);
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given file is readable
|
||||
*
|
||||
* @return true if readable, false if not
|
||||
*/
|
||||
public static boolean isFileReadable(String fileName) {
|
||||
final File file = new File(fileName);
|
||||
return file.exists() && file.canRead();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given file is writable
|
||||
*
|
||||
* @return true if writable, false if not
|
||||
*/
|
||||
public static boolean isFileWritable(String fileName) {
|
||||
final File file = new File(fileName);
|
||||
return file.exists() && file.canWrite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing file
|
||||
*
|
||||
* @return true if the delete was successful, false if not
|
||||
*/
|
||||
public static boolean delete(String fileName) {
|
||||
final File file = new File(fileName);
|
||||
boolean ok = false;
|
||||
try {
|
||||
ok = file.delete();
|
||||
} catch (SecurityException e) {
|
||||
Log.w(TAG, "SecurityException trying to delete " + fileName, e);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames an existing file
|
||||
*
|
||||
* @return true if the rename was successful, false if not
|
||||
*/
|
||||
public static boolean rename(String srcPath, String dstPath) {
|
||||
final File srcFile = new File(srcPath);
|
||||
final File dstFile = new File(dstPath);
|
||||
boolean ok = false;
|
||||
try {
|
||||
ok = srcFile.renameTo(dstFile);
|
||||
} catch (SecurityException e) {
|
||||
Log.w(TAG, "SecurityException trying to rename " + srcPath + " to " + dstPath, e);
|
||||
} catch (NullPointerException e) {
|
||||
Log.e(TAG, "NullPointerException trying to rename " + srcPath + " to " + dstPath, e);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user