Implement SamsungDap
authorroynatech2544 <whiteshell2544@naver.com>
Mon, 15 Nov 2021 13:10:49 +0000 (22:10 +0900)
committerBruno Martins <bgcngm@gmail.com>
Sat, 12 Mar 2022 16:16:30 +0000 (16:16 +0000)
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

dap/Android.bp [new file with mode: 0644]
dap/AndroidManifest.xml [new file with mode: 0644]
dap/res/drawable/ic_dolby.xml [new file with mode: 0644]
dap/res/drawable/ic_settings.xml [new file with mode: 0644]
dap/res/values/strings.xml [new file with mode: 0644]
dap/res/xml/dolby_settings.xml [new file with mode: 0644]
dap/src/org/lineageos/dap/BootCompletedReceiver.kt [new file with mode: 0644]
dap/src/org/lineageos/dap/DolbyActivity.kt [new file with mode: 0644]
dap/src/org/lineageos/dap/DolbyCore.kt [new file with mode: 0644]
dap/src/org/lineageos/dap/DolbyFragment.kt [new file with mode: 0644]
dap/src/org/lineageos/dap/DolbyTile.kt [new file with mode: 0644]

diff --git a/dap/Android.bp b/dap/Android.bp
new file mode 100644 (file)
index 0000000..56e9e0b
--- /dev/null
@@ -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,
+}
diff --git a/dap/AndroidManifest.xml b/dap/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..f9cd0f2
--- /dev/null
@@ -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>
diff --git a/dap/res/drawable/ic_dolby.xml b/dap/res/drawable/ic_dolby.xml
new file mode 100644 (file)
index 0000000..be73ff9
--- /dev/null
@@ -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>
diff --git a/dap/res/drawable/ic_settings.xml b/dap/res/drawable/ic_settings.xml
new file mode 100644 (file)
index 0000000..a8a9179
--- /dev/null
@@ -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>
diff --git a/dap/res/values/strings.xml b/dap/res/values/strings.xml
new file mode 100644 (file)
index 0000000..295652f
--- /dev/null
@@ -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>
diff --git a/dap/res/xml/dolby_settings.xml b/dap/res/xml/dolby_settings.xml
new file mode 100644 (file)
index 0000000..a494eb6
--- /dev/null
@@ -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>
diff --git a/dap/src/org/lineageos/dap/BootCompletedReceiver.kt b/dap/src/org/lineageos/dap/BootCompletedReceiver.kt
new file mode 100644 (file)
index 0000000..594253d
--- /dev/null
@@ -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))
+    }
+}
diff --git a/dap/src/org/lineageos/dap/DolbyActivity.kt b/dap/src/org/lineageos/dap/DolbyActivity.kt
new file mode 100644 (file)
index 0000000..619c51e
--- /dev/null
@@ -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()
+    }
+}
diff --git a/dap/src/org/lineageos/dap/DolbyCore.kt b/dap/src/org/lineageos/dap/DolbyCore.kt
new file mode 100644 (file)
index 0000000..d34e55e
--- /dev/null
@@ -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
+}
diff --git a/dap/src/org/lineageos/dap/DolbyFragment.kt b/dap/src/org/lineageos/dap/DolbyFragment.kt
new file mode 100644 (file)
index 0000000..2331b65
--- /dev/null
@@ -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,
+        )
+    }
+}
diff --git a/dap/src/org/lineageos/dap/DolbyTile.kt b/dap/src/org/lineageos/dap/DolbyTile.kt
new file mode 100644 (file)
index 0000000..a2abc0f
--- /dev/null
@@ -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()
+    }
+}