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:
Adithya R 2023-08-21 13:21:18 +05:30 committed by fazilsheik96
parent a5a141dba7
commit 6536f4822a
15 changed files with 714 additions and 0 deletions

18
DolbyManager/Android.bp Normal file
View File

@ -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",
],
}

View File

@ -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>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24" 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>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:fillColor="#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>

View File

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?android:attr/colorControlNormal">
<path
android:fillColor="#000"
android:pathData="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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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});
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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 \