Implement SamsungDap

Co-authored-by: LuK1337 <priv.luk@gmail.com>
Co-authored-by: Bruno Martins <bgcngm@gmail.com>
Signed-off-by: SamarV-121 <samarvispute121@pm.me>
Signed-off-by: roynatech2544 <whiteshell2544@naver.com>
Change-Id: I7f52714bdf7d94c9fb1c2d645839d54fd09d6bbe
tirimbino
roynatech2544 3 years ago committed by Bruno Martins
parent 3a3a22e0cf
commit 61f341dca6
  1. 25
      dap/Android.bp
  2. 65
      dap/AndroidManifest.xml
  3. 13
      dap/res/drawable/ic_dolby.xml
  4. 11
      dap/res/drawable/ic_settings.xml
  5. 22
      dap/res/values/strings.xml
  6. 52
      dap/res/xml/dolby_settings.xml
  7. 40
      dap/src/org/lineageos/dap/BootCompletedReceiver.kt
  8. 32
      dap/src/org/lineageos/dap/DolbyActivity.kt
  9. 51
      dap/src/org/lineageos/dap/DolbyCore.kt
  10. 78
      dap/src/org/lineageos/dap/DolbyFragment.kt
  11. 47
      dap/src/org/lineageos/dap/DolbyTile.kt

@ -0,0 +1,25 @@
//
// Copyright (C) 2022 The LineageOS Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
android_app {
name: "SamsungDAP",
defaults: ["SettingsLibDefaults"],
srcs: ["src/**/*.kt"],
certificate: "platform",
platform_apis: true,
static_libs: ["androidx.preference_preference"],
system_ext_specific: true,
}

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2022 The LineageOS Project
Licensed under the Apache License, Version 2.0 (the "License"
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.lineageos.dap"
android:sharedUserId="android.uid.system"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true"
android:label="SamsungDAP"
android:persistent="true"
android:supportsRtl="true"
android:theme="@style/Theme.SubSettingsBase">
<activity
android:name=".DolbyActivity"
android:exported="true"
android:label="@string/dolby_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" />
</activity>
<receiver
android:name=".BootCompletedReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service
android:name=".DolbyTile"
android:exported="true"
android:icon="@drawable/ic_dolby"
android:label="@string/dolby_title"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
</application>
</manifest>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24">
<path android:pathData="M0 0h24v24H0z" />
<path
android:fillColor="#FFFFFFFF"
android:pathData="M20 4H4c-1.1 0-2 0.9-2 2v12c0 1.1 0.9 2 2 2h16c1.1 0 2-0.9 2-2V6c0-1.1-0.9-2-2-2zM7.76 16.24l-1.41 1.41C4.78 16.1 4 14.05 4 12c0-2.05 0.78 -4.1 2.34-5.66l1.41 1.41C6.59 8.93 6 10.46 6 12s0.59 3.07 1.76 4.24zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm5.66 1.66l-1.41-1.41C17.41 15.07 18 13.54 18 12s-0.59-3.07-1.76-4.24l1.41-1.41C19.22 7.9 20 9.95 20 12c0 2.05-0.78 4.1-2.34 5.66zM12 10c-1.1 0-2 0.9-2 2s0.9 2 2 2 2-0.9 2-2-0.9-2-2-2z" />
</vector>

@ -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:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#000"
android:pathData="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z" />
</vector>

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Title -->
<string name="dolby_title" translatable="false">Dolby Atmos</string>
<!-- Switch bar -->
<string name="dolby_enable_title">Enable Dolby Atmos</string>
<!-- Intro -->
<string name="dolby_top_intro_summary">Experience breakthrough audio for media playback that flows above and around you</string>
<!-- Profiles -->
<string name="dolby_profile_auto">Auto Profile</string>
<string name="dolby_profile_game">Game Profile</string>
<string name="dolby_profile_game_1">Game 1 Profile</string>
<string name="dolby_profile_game_2">Game 2 Profile</string>
<string name="dolby_profile_movie">Movie Profile</string>
<string name="dolby_profile_music">Music Profile</string>
<string name="dolby_profile_off">No Profile</string>
<string name="dolby_profile_spacial_audio">Spacial Audio Profile</string>
<string name="dolby_profile_voice">Voice Profile</string>
</resources>

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/dolby_title">
<com.android.settingslib.widget.MainSwitchPreference
android:defaultValue="false"
android:key="dolby_enable"
android:title="@string/dolby_enable_title" />
<com.android.settingslib.widget.TopIntroPreference
android:key="dolby_top_intro"
android:title="@string/dolby_top_intro_summary" />
<com.android.settingslib.widget.RadioButtonPreference
android:defaultValue="true"
android:key="dolby_profile_auto"
android:title="@string/dolby_profile_auto" />
<com.android.settingslib.widget.RadioButtonPreference
android:key="dolby_profile_game"
android:title="@string/dolby_profile_game" />
<com.android.settingslib.widget.RadioButtonPreference
android:key="dolby_profile_game_1"
android:title="@string/dolby_profile_game_1" />
<com.android.settingslib.widget.RadioButtonPreference
android:key="dolby_profile_game_2"
android:title="@string/dolby_profile_game_2" />
<com.android.settingslib.widget.RadioButtonPreference
android:key="dolby_profile_movie"
android:title="@string/dolby_profile_movie" />
<com.android.settingslib.widget.RadioButtonPreference
android:key="dolby_profile_music"
android:title="@string/dolby_profile_music" />
<com.android.settingslib.widget.RadioButtonPreference
android:key="dolby_profile_off"
android:title="@string/dolby_profile_off" />
<com.android.settingslib.widget.RadioButtonPreference
android:key="dolby_profile_spacial_audio"
android:title="@string/dolby_profile_spacial_audio" />
<com.android.settingslib.widget.RadioButtonPreference
android:key="dolby_profile_voice"
android:title="@string/dolby_profile_voice" />
</PreferenceScreen>

@ -0,0 +1,40 @@
/*
* Copyright (C) 2022 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.lineageos.dap
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.preference.PreferenceManager
import org.lineageos.dap.DolbyFragment.Companion.PREF_DOLBY_ENABLE
import org.lineageos.dap.DolbyFragment.Companion.PREF_DOLBY_MODES
class BootCompletedReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context)
for ((key, value) in PREF_DOLBY_MODES) {
if (sharedPrefs.getBoolean(key, false)) {
DolbyCore.setProfile(value)
break
}
}
DolbyCore.setEnabled(sharedPrefs.getBoolean(PREF_DOLBY_ENABLE, false))
}
}

@ -0,0 +1,32 @@
/*
* Copyright (C) 2022 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.lineageos.dap
import android.os.Bundle
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity
import com.android.settingslib.collapsingtoolbar.R
class DolbyActivity : CollapsingToolbarBaseActivity() {
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
fragmentManager.beginTransaction().replace(
R.id.content_frame,
DolbyFragment()
).commit()
}
}

@ -0,0 +1,51 @@
/*
* Copyright (C) 2022 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.lineageos.dap
import android.media.audiofx.AudioEffect
import java.util.UUID
object DolbyCore {
private const val EFFECT_PARAM_PROFILE = 0
private const val EFFECT_PARAM_EFF_ENAB = 19
const val PROFILE_AUTO = 0
const val PROFILE_MOVIE = 1
const val PROFILE_MUSIC = 2
const val PROFILE_VOICE = 3
const val PROFILE_GAME = 4
const val PROFILE_OFF = 5
const val PROFILE_GAME_1 = 6
const val PROFILE_GAME_2 = 7
const val PROFILE_SPACIAL_AUDIO = 8
private val audioEffect = AudioEffect(
UUID.fromString("46d279d9-9be7-453d-9d7c-ef937f675587"), AudioEffect.EFFECT_TYPE_NULL, 0, 0
)
fun setProfile(profile: Int) {
audioEffect.setParameter(EFFECT_PARAM_EFF_ENAB, 1)
audioEffect.setParameter(EFFECT_PARAM_PROFILE, profile)
}
fun setEnabled(enabled: Boolean) {
audioEffect.enabled = enabled
}
fun isEnabled() = audioEffect.enabled
}

@ -0,0 +1,78 @@
/*
* Copyright (C) 2022 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.lineageos.dap
import android.os.Bundle
import android.widget.Switch
import androidx.preference.PreferenceFragment
import com.android.settingslib.widget.MainSwitchPreference
import com.android.settingslib.widget.OnMainSwitchChangeListener
import com.android.settingslib.widget.RadioButtonPreference
import org.lineageos.dap.R
class DolbyFragment : PreferenceFragment(), OnMainSwitchChangeListener {
private lateinit var switchBar: MainSwitchPreference
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
addPreferencesFromResource(R.xml.dolby_settings)
switchBar = findPreference<MainSwitchPreference>(PREF_DOLBY_ENABLE)!!
switchBar.addOnSwitchChangeListener(this)
switchBar.isChecked = DolbyCore.isEnabled()
for ((key, value) in PREF_DOLBY_MODES) {
val preference = findPreference<RadioButtonPreference>(key)!!
preference.setOnPreferenceClickListener {
setProfile(value)
true
}
}
}
override fun onSwitchChanged(switchView: Switch, isChecked: Boolean) {
DolbyCore.setEnabled(isChecked)
}
private fun setProfile(profile: Int) {
DolbyCore.setProfile(profile)
for ((key, value) in PREF_DOLBY_MODES) {
val preference = findPreference<RadioButtonPreference>(key)!!
preference.isChecked = value == profile
}
}
companion object {
const val PREF_DOLBY_ENABLE = "dolby_enable"
val PREF_DOLBY_MODES = mapOf(
"dolby_profile_auto" to DolbyCore.PROFILE_AUTO,
"dolby_profile_movie" to DolbyCore.PROFILE_MOVIE,
"dolby_profile_music" to DolbyCore.PROFILE_MUSIC,
"dolby_profile_voice" to DolbyCore.PROFILE_VOICE,
"dolby_profile_game" to DolbyCore.PROFILE_GAME,
"dolby_profile_off" to DolbyCore.PROFILE_OFF,
"dolby_profile_game_1" to DolbyCore.PROFILE_GAME_1,
"dolby_profile_game_2" to DolbyCore.PROFILE_GAME_2,
"dolby_profile_spacial_audio" to DolbyCore.PROFILE_SPACIAL_AUDIO,
)
}
}

@ -0,0 +1,47 @@
/*
* Copyright (C) 2022 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.lineageos.dap
import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import androidx.preference.PreferenceManager
import org.lineageos.dap.DolbyFragment.Companion.PREF_DOLBY_ENABLE
class DolbyTile : TileService() {
private var isEnabled = false
set(value) {
field = value
qsTile.state = if (value) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
qsTile.updateTile()
}
override fun onStartListening() {
super.onStartListening()
isEnabled = DolbyCore.isEnabled()
}
override fun onClick() {
isEnabled = !isEnabled
DolbyCore.setEnabled(isEnabled)
PreferenceManager.getDefaultSharedPreferences(this)
.edit()
.putBoolean(PREF_DOLBY_ENABLE, isEnabled)
.commit()
}
}
Loading…
Cancel
Save