sm8150-common: Introduce DolbyManager
- Converted Xiaomi dirac implementation based on observing Xiaomi sound effects app and daxservice. - Thanks to jhenrique09 for the hack from Xiaomi dirac parts "Pause/play music stream to get effects applied". Change-Id: I23f78ada3ea8fbb17cb9dd715b2b65f0f51feb36 Co-authored-by: Henrique Silva <jhenrique09.mcz@hotmail.com> Co-authored-by: Fabian Leutenegger <fabian.leutenegger@bluewin.ch>
This commit is contained in:
parent
a5a141dba7
commit
6536f4822a
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// Copyright (C) 2017-2021 The LineageOS Project
|
||||
// (C) 2023 Paranoid Android
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
android_app {
|
||||
name: "DolbyManager",
|
||||
srcs: ["src/**/*.java"],
|
||||
certificate: "platform",
|
||||
platform_apis: true,
|
||||
privileged: true,
|
||||
system_ext_specific: true,
|
||||
static_libs: [
|
||||
"SettingsLib",
|
||||
],
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2023 Paranoid Android
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="co.aospa.settings.dolby"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0"
|
||||
android:sharedUserId="android.uid.system">
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="31"
|
||||
android:targetSdkVersion="31"/>
|
||||
|
||||
<application
|
||||
android:label="@string/app_name"
|
||||
android:persistent="true"
|
||||
android:defaultToDeviceProtectedStorage="true"
|
||||
android:directBootAware="true">
|
||||
|
||||
<receiver
|
||||
android:name=".BootCompletedReceiver"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity
|
||||
android:name=".DolbyActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/dolby_title"
|
||||
android:theme="@style/Theme.SubSettingsBase">
|
||||
<intent-filter>
|
||||
<action android:name="com.android.settings.action.IA_SETTINGS" />
|
||||
<action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES"/>
|
||||
</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/dolby_summary" />
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name=".DolbyTileService"
|
||||
android:exported="true"
|
||||
android:icon="@drawable/ic_dolby_qs"
|
||||
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,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24" android:tint="?android:attr/colorControlNormal">
|
||||
<path android:fillColor="#000000" android:pathData="M1,4.0214C2.2767,4.0743 3.5798,3.9866 4.8252,4.2063C8.8352,4.9133 11.4129,8.3489 11.0507,12.3402C10.7124,16.0695 7.3661,18.9511 3.3484,18.9651C2.5657,18.9678 1.7827,18.9441 1,18.9324L1,4.0214Z" android:strokeColor="#00000000" android:strokeWidth="1" android:fillType="evenOdd"/>
|
||||
<group>
|
||||
<clip-path android:pathData="M12.9332,4l10.0668,0l0,15l-10.0668,0z"/>
|
||||
<path android:fillColor="#000000" android:pathData="M23,4.0924L23,18.8825C19.4973,19.298 16.399,18.6968 14.3366,15.6947C12.5148,13.043 12.4594,10.2265 14.2129,7.5241C16.244,4.394 19.3953,3.7204 23,4.0924" android:strokeColor="#00000000" android:strokeWidth="1" android:fillType="evenOdd"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||
<path android:fillColor="#191c1e" android:pathData="M1,4.0214C2.2767,4.0743 3.5798,3.9866 4.8252,4.2063C8.8352,4.9133 11.4129,8.3489 11.0507,12.3402C10.7124,16.0695 7.3661,18.9511 3.3484,18.9651C2.5657,18.9678 1.7827,18.9441 1,18.9324L1,4.0214Z" android:strokeColor="#00000000" android:strokeWidth="1" android:fillType="evenOdd"/>
|
||||
<group>
|
||||
<clip-path android:pathData="M12.9332,4l10.0668,0l0,15l-10.0668,0z"/>
|
||||
<path android:fillColor="#191c1e" android:pathData="M23,4.0924L23,18.8825C19.4973,19.298 16.399,18.6968 14.3366,15.6947C12.5148,13.043 12.4594,10.2265 14.2129,7.5241C16.244,4.394 19.3953,3.7204 23,4.0924" android:strokeColor="#00000000" android:strokeWidth="1" android:fillType="evenOdd"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -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="M16.9 21.02V2.98h-2v18.04h2zm4 0v-9.7h-2v9.7h2zm-8 0v-16h-2v16h2zm-6 0h2V9h-2v12.03z"/>
|
||||
<path
|
||||
android:fillColor="#000"
|
||||
android:pathData="M5.1 21.02h-2v-3.11h2v3.11z"/>
|
||||
</vector>
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2018 The LineageOS Project
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Dolby Atmos -->
|
||||
<string-array name="dolby_profile_entries">
|
||||
<item>@string/dolby_profile_dynamic</item>
|
||||
<item>@string/dolby_profile_movie</item>
|
||||
<item>@string/dolby_profile_music</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="dolby_profile_values">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="dolby_preset_entries" translatable="false">
|
||||
<item>@string/dolby_preset_default</item>
|
||||
<item>@string/dolby_preset_rock</item>
|
||||
<item>@string/dolby_preset_jazz</item>
|
||||
<item>@string/dolby_preset_pop</item>
|
||||
<item>@string/dolby_preset_classical</item>
|
||||
<item>@string/dolby_preset_hiphop</item>
|
||||
<item>@string/dolby_preset_blues</item>
|
||||
<item>@string/dolby_preset_electronic</item>
|
||||
<item>@string/dolby_preset_metal</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="dolby_preset_values">
|
||||
<item>0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0</item>
|
||||
<item>60,36,12,-12,-36,-24,-12,-8,-4,-20,-36,-20,-4,-20,-36,-16,4,32,60,60</item>
|
||||
<item>8,8,8,8,8,0,-8,-8,-8,-24,-40,-20,0,4,8,8,8,8,8,8</item>
|
||||
<item>-13,-1,11,-25,-61,-29,3,11,19,19,19,15,11,-9,-29,-9,11,15,19,19</item>
|
||||
<item>-32,-32,-32,-32,-32,-32,-32,-28,-24,-4,16,0,-16,24,64,32,0,32,64,64</item>
|
||||
<item>52,28,4,-20,-44,-24,-4,-4,-4,-24,-44,-24,-4,0,4,4,4,20,36,36</item>
|
||||
<item>28,28,28,-36,-100,-68,-36,4,44,28,12,4,-4,4,12,4,-4,12,28,28</item>
|
||||
<item>50,34,18,2,-14,-6,2,-2,-6,-26,-46,-26,-6,-2,2,2,2,2,2,2</item>
|
||||
<item>40,24,8,8,8,-4,-16,-12,-8,-32,-56,-24,8,8,8,8,8,8,8,8</item>
|
||||
</string-array>
|
||||
</resources>
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2018 The LineageOS Project
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<!-- App Name -->
|
||||
<string name="app_name">Dolby Manager</string>
|
||||
|
||||
<!-- Dolby Atmos -->
|
||||
<string name="dolby_title">Dolby Atmos</string>
|
||||
<string name="dolby_enable">Enable</string>
|
||||
<string name="dolby_summary">Surround sound</string>
|
||||
<string name="dolby_preset_title">Choose a preset</string>
|
||||
<string name="dolby_profile_title">Choose a profile</string>
|
||||
|
||||
<!-- Dolby Atmos: Sound Profiles -->
|
||||
<string name="dolby_profile_dynamic">Dynamic</string>
|
||||
<string name="dolby_profile_music">Music</string>
|
||||
<string name="dolby_profile_movie">Movie</string>
|
||||
|
||||
<!-- Dolby Atmos: Equalizer presets -->
|
||||
<string name="dolby_preset_default">Default</string>
|
||||
<string name="dolby_preset_rock">Rock</string>
|
||||
<string name="dolby_preset_jazz">Jazz</string>
|
||||
<string name="dolby_preset_pop">Pop</string>
|
||||
<string name="dolby_preset_classical">Classical</string>
|
||||
<string name="dolby_preset_hiphop">Hip Hop</string>
|
||||
<string name="dolby_preset_blues">Blues</string>
|
||||
<string name="dolby_preset_electronic">Electronic</string>
|
||||
<string name="dolby_preset_metal">Metal</string>
|
||||
</resources>
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2018 The LineageOS Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<PreferenceScreen
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:title="@string/dolby_title">
|
||||
|
||||
<com.android.settingslib.widget.MainSwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="dolby_enable"
|
||||
android:title="@string/dolby_enable" />
|
||||
|
||||
<ListPreference
|
||||
android:key="dolby_profile"
|
||||
android:entries="@array/dolby_profile_entries"
|
||||
android:entryValues="@array/dolby_profile_values"
|
||||
android:defaultValue="0"
|
||||
android:title="@string/dolby_profile_title"
|
||||
android:summary="%s"
|
||||
android:icon="@drawable/ic_dolby" />
|
||||
|
||||
<ListPreference
|
||||
android:key="dolby_preset"
|
||||
android:entries="@array/dolby_preset_entries"
|
||||
android:entryValues="@array/dolby_preset_values"
|
||||
android:defaultValue="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
|
||||
android:title="@string/dolby_preset_title"
|
||||
android:summary="%s"
|
||||
android:icon="@drawable/ic_preset"/>
|
||||
|
||||
</PreferenceScreen>
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Paranoid Android
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package co.aospa.settings.dolby;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
public class BootCompletedReceiver extends BroadcastReceiver {
|
||||
|
||||
private static final String TAG = "DolbyManager";
|
||||
private static final boolean DEBUG = true;
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, Intent intent) {
|
||||
if (!intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Received boot completed intent");
|
||||
DolbyUtils.getInstance(context).onBootCompleted();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package co.aospa.settings.dolby;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
|
||||
import com.android.settingslib.widget.R;
|
||||
|
||||
public class DolbyActivity extends CollapsingToolbarBaseActivity {
|
||||
|
||||
private static final String TAG_DOLBY = "dolby";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getFragmentManager().beginTransaction().replace(R.id.content_frame,
|
||||
new DolbySettingsFragment(), TAG_DOLBY).commit();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (C) 2018 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package co.aospa.settings.dolby;
|
||||
|
||||
import android.media.audiofx.AudioEffect;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class DolbyAtmos extends AudioEffect {
|
||||
|
||||
private static final String TAG = "DolbyAtmos";
|
||||
private static final UUID EFFECT_TYPE_DAP =
|
||||
UUID.fromString("9d4921da-8225-4f29-aefa-39537a04bcaa");
|
||||
private static final int DAP_PARAM = 5;
|
||||
private static final int DAP_PARAM_PROFILE = 0xA000000;
|
||||
private static final int DAP_PARAM_VALUE = 0x2000000;
|
||||
private static final int DAP_PARAM_GEQ = 110;
|
||||
private static final int DAP_PARAM_VOLUME_LEVELER = 103;
|
||||
private static final int DAP_PROFILES_COUNT = 9;
|
||||
|
||||
public DolbyAtmos(int priority, int audioSession) {
|
||||
super(EFFECT_TYPE_NULL, EFFECT_TYPE_DAP, priority, audioSession);
|
||||
}
|
||||
|
||||
private static int int32ToByteArray(int value, byte[] buf, int offset) {
|
||||
buf[offset] = (byte) (value & 255);
|
||||
buf[offset + 1] = (byte) ((value >>> 8) & 255);
|
||||
buf[offset + 2] = (byte) ((value >>> 16) & 255);
|
||||
buf[offset + 3] = (byte) ((value >>> 24) & 255);
|
||||
return 4;
|
||||
}
|
||||
|
||||
private static int byteArrayToInt32(byte[] buf) {
|
||||
return (buf[0] & 255) | ((buf[3] & 255) << 24)
|
||||
| ((buf[2] & 255) << 16) | ((buf[1] & 255) << 8);
|
||||
}
|
||||
|
||||
private static int int32ArrayToByteArray(int[] values, byte[] buf, int offset) {
|
||||
for (int value : values) {
|
||||
buf[offset] = (byte) ((value >>> 0) & 255);
|
||||
buf[offset + 1] = (byte) ((value >>> 8) & 255);
|
||||
buf[offset + 2] = (byte) ((value >>> 16) & 255);
|
||||
buf[offset + 3] = (byte) ((value >>> 24) & 255);
|
||||
offset += 4;
|
||||
}
|
||||
return values.length << 2;
|
||||
}
|
||||
|
||||
private void setIntParam(int param, int value) {
|
||||
byte[] buf = new byte[12];
|
||||
int i = int32ToByteArray(param, buf, 0);
|
||||
int32ToByteArray(value, buf, i + int32ToByteArray(1, buf, i));
|
||||
checkStatus(setParameter(DAP_PARAM, buf));
|
||||
}
|
||||
|
||||
private int getIntParam(int param) {
|
||||
byte[] buf = new byte[12];
|
||||
int32ToByteArray(param, buf, 0);
|
||||
checkStatus(getParameter(DAP_PARAM + param, buf));
|
||||
return byteArrayToInt32(buf);
|
||||
}
|
||||
|
||||
private void setDapParameter(int param, int values[]) {
|
||||
for (int profile = 0; profile < DAP_PROFILES_COUNT; profile++) {
|
||||
int length = values.length;
|
||||
byte[] buf = new byte[(length + 4) * 4];
|
||||
int i = int32ToByteArray(DAP_PARAM_VALUE, buf, 0);
|
||||
int i2 = i + int32ToByteArray(length + 1, buf, i);
|
||||
int i3 = i2 + int32ToByteArray(profile, buf, i2);
|
||||
int32ArrayToByteArray(values, buf, i3 + int32ToByteArray(param, buf, i3));
|
||||
checkStatus(setParameter(DAP_PARAM, buf));
|
||||
}
|
||||
}
|
||||
|
||||
public void setDsOn(boolean on) {
|
||||
setIntParam(0, on ? 1 : 0);
|
||||
super.setEnabled(on);
|
||||
}
|
||||
|
||||
public boolean getDsOn() {
|
||||
return getIntParam(0) == 1;
|
||||
}
|
||||
|
||||
public void setProfile(int index) {
|
||||
setIntParam(DAP_PARAM_PROFILE, index);
|
||||
}
|
||||
|
||||
public int getProfile() {
|
||||
return getIntParam(DAP_PARAM_PROFILE);
|
||||
}
|
||||
|
||||
public void setGeqBandGains(int[] gains) {
|
||||
setDapParameter(DAP_PARAM_GEQ, gains);
|
||||
}
|
||||
|
||||
public void setVolumeLevelerEnabled(boolean enable) {
|
||||
setDapParameter(DAP_PARAM_VOLUME_LEVELER, new int[]{enable ? 1 : 0});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (C) 2018,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 co.aospa.settings.dolby;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Switch;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.ListPreference;
|
||||
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;
|
||||
|
||||
public class DolbySettingsFragment extends PreferenceFragment implements
|
||||
OnPreferenceChangeListener, OnMainSwitchChangeListener {
|
||||
|
||||
public static final String PREF_ENABLE = "dolby_enable";
|
||||
public static final String PREF_PRESET = "dolby_preset";
|
||||
public static final String PREF_PROFILE = "dolby_profile";
|
||||
|
||||
private MainSwitchPreference mSwitchBar;
|
||||
private ListPreference mPresetPref;
|
||||
private ListPreference mProfilePref;
|
||||
|
||||
private DolbyUtils mDolbyUtils;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.dolby_settings);
|
||||
|
||||
mDolbyUtils = DolbyUtils.getInstance(getActivity());
|
||||
final boolean dsOn = mDolbyUtils.getDsOn();
|
||||
|
||||
mSwitchBar = (MainSwitchPreference) findPreference(PREF_ENABLE);
|
||||
mSwitchBar.addOnSwitchChangeListener(this);
|
||||
mSwitchBar.setChecked(dsOn);
|
||||
|
||||
mPresetPref = (ListPreference) findPreference(PREF_PRESET);
|
||||
mPresetPref.setOnPreferenceChangeListener(this);
|
||||
mPresetPref.setEnabled(dsOn);
|
||||
|
||||
mProfilePref = (ListPreference) findPreference(PREF_PROFILE);
|
||||
mProfilePref.setOnPreferenceChangeListener(this);
|
||||
mProfilePref.setEnabled(dsOn);
|
||||
mProfilePref.setValue(Integer.toString(mDolbyUtils.getProfile()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
switch (preference.getKey()) {
|
||||
case PREF_PRESET:
|
||||
mDolbyUtils.setPreset(newValue.toString());
|
||||
return true;
|
||||
case PREF_PROFILE:
|
||||
mDolbyUtils.setProfile(Integer.parseInt((newValue.toString())));
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwitchChanged(Switch switchView, boolean isChecked) {
|
||||
mSwitchBar.setChecked(isChecked);
|
||||
|
||||
mDolbyUtils.setDsOn(isChecked);
|
||||
mPresetPref.setEnabled(isChecked);
|
||||
mProfilePref.setEnabled(isChecked);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package co.aospa.settings.dolby;
|
||||
|
||||
import android.service.quicksettings.Tile;
|
||||
import android.service.quicksettings.TileService;
|
||||
|
||||
public class DolbyTileService extends TileService {
|
||||
|
||||
@Override
|
||||
public void onStartListening() {
|
||||
Tile tile = getQsTile();
|
||||
if (DolbyUtils.getInstance(getApplicationContext()).getDsOn()) {
|
||||
tile.setState(Tile.STATE_ACTIVE);
|
||||
} else {
|
||||
tile.setState(Tile.STATE_INACTIVE);
|
||||
}
|
||||
tile.updateTile();
|
||||
super.onStartListening();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
Tile tile = getQsTile();
|
||||
DolbyUtils dolbyUtils = DolbyUtils.getInstance(getApplicationContext());
|
||||
if (dolbyUtils.getDsOn()) {
|
||||
dolbyUtils.setDsOn(false);
|
||||
tile.setState(Tile.STATE_INACTIVE);
|
||||
} else {
|
||||
dolbyUtils.setDsOn(true);
|
||||
tile.setState(Tile.STATE_ACTIVE);
|
||||
}
|
||||
tile.updateTile();
|
||||
super.onClick();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (C) 2018,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 co.aospa.settings.dolby;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.media.AudioManager;
|
||||
import android.media.session.MediaController;
|
||||
import android.media.session.MediaSessionManager;
|
||||
import android.media.session.PlaybackState;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public final class DolbyUtils {
|
||||
|
||||
private static final String TAG = "DolbyUtils";
|
||||
private static final String DEFAULT_PRESET = "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0";
|
||||
private static final int EFFECT_PRIORITY = 100;
|
||||
|
||||
private static DolbyUtils mInstance;
|
||||
private DolbyAtmos mDolbyAtmos;
|
||||
private MediaSessionManager mMediaSessionManager;
|
||||
private Context mContext;
|
||||
private Handler mHandler = new Handler();
|
||||
|
||||
private DolbyUtils(Context context) {
|
||||
mContext = context;
|
||||
mDolbyAtmos = new DolbyAtmos(EFFECT_PRIORITY, 0);
|
||||
mMediaSessionManager = context.getSystemService(MediaSessionManager.class);
|
||||
}
|
||||
|
||||
public static synchronized DolbyUtils getInstance(Context context) {
|
||||
if (mInstance == null) {
|
||||
mInstance = new DolbyUtils(context);
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
public void onBootCompleted() {
|
||||
Log.i(TAG, "onBootCompleted");
|
||||
mDolbyAtmos.setEnabled(mDolbyAtmos.getDsOn());
|
||||
mDolbyAtmos.setVolumeLevelerEnabled(false);
|
||||
}
|
||||
|
||||
private void triggerPlayPause(MediaController controller) {
|
||||
long when = SystemClock.uptimeMillis();
|
||||
final KeyEvent evDownPause = new KeyEvent(when, when, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PAUSE, 0);
|
||||
final KeyEvent evUpPause = KeyEvent.changeAction(evDownPause, KeyEvent.ACTION_UP);
|
||||
final KeyEvent evDownPlay = new KeyEvent(when, when, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MEDIA_PLAY, 0);
|
||||
final KeyEvent evUpPlay = KeyEvent.changeAction(evDownPlay, KeyEvent.ACTION_UP);
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
controller.dispatchMediaButtonEvent(evDownPause);
|
||||
}
|
||||
});
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
controller.dispatchMediaButtonEvent(evUpPause);
|
||||
}
|
||||
}, 20);
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
controller.dispatchMediaButtonEvent(evDownPlay);
|
||||
}
|
||||
}, 1000);
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
controller.dispatchMediaButtonEvent(evUpPlay);
|
||||
}
|
||||
}, 1020);
|
||||
}
|
||||
|
||||
private int getMediaControllerPlaybackState(MediaController controller) {
|
||||
if (controller != null) {
|
||||
final PlaybackState playbackState = controller.getPlaybackState();
|
||||
if (playbackState != null) {
|
||||
return playbackState.getState();
|
||||
}
|
||||
}
|
||||
return PlaybackState.STATE_NONE;
|
||||
}
|
||||
|
||||
private void refreshPlaybackIfNecessary(){
|
||||
if (mMediaSessionManager == null) return;
|
||||
|
||||
final List<MediaController> sessions
|
||||
= mMediaSessionManager.getActiveSessionsForUser(
|
||||
null, UserHandle.ALL);
|
||||
for (MediaController controller : sessions) {
|
||||
if (PlaybackState.STATE_PLAYING ==
|
||||
getMediaControllerPlaybackState(controller)) {
|
||||
triggerPlayPause(controller);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkEffect() {
|
||||
if (!mDolbyAtmos.hasControl()) {
|
||||
Log.w(TAG, "lost control, recreating effect");
|
||||
mDolbyAtmos.release();
|
||||
mDolbyAtmos = new DolbyAtmos(EFFECT_PRIORITY, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDsOn(boolean on) {
|
||||
checkEffect();
|
||||
Log.i(TAG, "setDsOn: " + on);
|
||||
mDolbyAtmos.setDsOn(on);
|
||||
if (on) {
|
||||
refreshPlaybackIfNecessary();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getDsOn() {
|
||||
boolean on = mDolbyAtmos.getDsOn();
|
||||
Log.i(TAG, "getDsOn: " + on);
|
||||
return on;
|
||||
}
|
||||
|
||||
public void setProfile(int index) {
|
||||
checkEffect();
|
||||
Log.i(TAG, "setProfile: " + index);
|
||||
mDolbyAtmos.setProfile(index);
|
||||
}
|
||||
|
||||
public int getProfile() {
|
||||
int profile = mDolbyAtmos.getProfile();
|
||||
Log.i(TAG, "getProfile: " + profile);
|
||||
return profile;
|
||||
}
|
||||
|
||||
public void setPreset(String preset) {
|
||||
checkEffect();
|
||||
int[] gains = Arrays.stream(preset.split(",")).mapToInt(Integer::parseInt).toArray();
|
||||
Log.i(TAG, "setPreset: " + Arrays.toString(gains));
|
||||
mDolbyAtmos.setGeqBandGains(gains);
|
||||
}
|
||||
}
|
|
@ -116,6 +116,10 @@ PRODUCT_COPY_FILES += \
|
|||
PRODUCT_PACKAGES += \
|
||||
vendor.oneplus.hardware.display@1.0.vendor
|
||||
|
||||
# Dolby Manager
|
||||
PRODUCT_PACKAGES += \
|
||||
DolbyManager
|
||||
|
||||
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
|
||||
ro.surface_flinger.set_idle_timer_ms=2500 \
|
||||
ro.surface_flinger.set_touch_timer_ms=2500 \
|
||||
|
|
Loading…
Reference in New Issue