Skip to content

Commit

Permalink
优化: 移除高音量安全限制支持仅在耳机状态开启(需要重新设置此功能)
Browse files Browse the repository at this point in the history
  • Loading branch information
HChenX committed Jun 11, 2024
1 parent 63713d1 commit 444690e
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 53 deletions.
Original file line number Diff line number Diff line change
@@ -1,44 +1,125 @@
/*
* This file is part of HyperCeiler.
* This file is part of HyperCeiler.
* HyperCeiler is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License.
* HyperCeiler is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* Copyright (C) 2023-2024 HyperCeiler Contributions
*/
* Copyright (C) 2023-2024 HyperCeiler Contributions
*/
package com.sevtinge.hyperceiler.module.hook.systemframework;

import static com.sevtinge.hyperceiler.utils.devicesdk.SystemSDKKt.isMoreAndroidVersion;

import com.sevtinge.hyperceiler.module.base.BaseHook;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;

public class VolumeDisableSafe extends BaseHook {
import com.hchen.hooktool.callback.IAction;
import com.hchen.hooktool.tool.ParamTool;
import com.sevtinge.hyperceiler.module.base.BaseTool;

Class<?> mAudioService;
public class VolumeDisableSafe extends BaseTool {
private static boolean isHeadsetOn = false;

private static final int mode = mPrefsMap.getStringAsInt("system_framework_volume_disable_safe_new", 0);

@Override
public void init() {
public void doHook() {
if (isMoreAndroidVersion(34)) {
// by starVoyager
mAudioService = findClassIfExists("com.android.server.audio.SoundDoseHelperStubImpl");
returnIntConstant(mAudioService, "updateSafeMediaVolumeIndex");
hcHook.findClass("sound", "com.android.server.audio.SoundDoseHelperStubImpl")
.getMethod("updateSafeMediaVolumeIndex", int.class)
.hook(new IAction() {
@Override
public void before(ParamTool param) {
if (mode == 1) {
param.setResult(2147483646);
return;
}
if (isHeadsetOn) param.setResult(2147483646);
}
})
.findClass("SoundDoseHelper", "com.android.server.audio.SoundDoseHelper")
.getMethod("safeMediaVolumeIndex", int.class)
.hook(new IAction() {
@Override
public void before(ParamTool param) {
if (mode == 1) {
param.setResult(2147483646);
return;
}
if (isHeadsetOn) param.setResult(2147483646);
}
})
.getAnyConstructor()
.hook(new IAction() {
@Override
public void after(ParamTool param) {
if (mode == 1) {
return;
}
Context context = param.second();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
intentFilter.addAction(AudioManager.ACTION_HEADSET_PLUG);
context.registerReceiver(new Listener(), intentFilter);
}
})
;
} else {
mAudioService = findClassIfExists("com.android.server.audio.AudioService");
returnIntConstant(mAudioService, "safeMediaVolumeIndex");
hcHook.findClass("audio", "com.android.server.audio.AudioService")
.getAnyMethod("safeMediaVolumeIndex")
.hook(new IAction() {
@Override
public void before(ParamTool param) {
if (mode == 1) {
param.setResult(2147483646);
return;
}
if (isHeadsetOn) param.setResult(2147483646);
}
});
}
}

private void returnIntConstant(Class<?> cls, String methodName) {
hookAllMethods(cls, methodName, MethodHook.returnConstant(2147483646));
private static class Listener extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action != null) {
switch (action) {
case BluetoothDevice.ACTION_ACL_CONNECTED -> {
isHeadsetOn = true;
}
case BluetoothDevice.ACTION_ACL_DISCONNECTED -> {
isHeadsetOn = false;
}
case AudioManager.ACTION_HEADSET_PLUG -> {
if (intent.hasExtra("state")) {
int state = intent.getIntExtra("state", 0);
if (state == 1) {
isHeadsetOn = true;
} else if (state == 0) {
isHeadsetOn = false;
}
}
}
}
}
}
}
}
12 changes: 12 additions & 0 deletions app/src/main/res/values/arrays.xml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@
<item>5</item>
</string-array>

<string-array name="default_volume_safe">
<item>@string/array_default</item>
<item>@string/default_volume_safe_all</item>
<item>@string/default_volume_safe_headset</item>
</string-array>

<string-array name="default_volume_safe_value">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>

<string-array name="open_with_test">
<item>@string/open_with_test_picture</item>
<item>@string/open_with_test_audio</item>
Expand Down
60 changes: 31 additions & 29 deletions app/src/main/res/xml/framework_volume.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,64 @@
app:myLocation="@string/system_framework_volume_title">

<DropDownPreference
android:title="@string/system_framework_default_volume_stream"
android:defaultValue="0"
android:key="prefs_key_system_framework_default_volume_stream"
android:title="@string/system_framework_default_volume_stream"
app:entries="@array/default_volume_stream"
app:entryValues="@array/default_volume_streame_value"
android:defaultValue="0" />
app:entryValues="@array/default_volume_streame_value" />

<DropDownPreference
android:defaultValue="0"
android:key="prefs_key_system_framework_volume_disable_safe_new"
android:title="@string/system_framework_volume_disable_safe"
app:entries="@array/default_volume_safe"
app:entryValues="@array/default_volume_safe_value" />

<SwitchPreference
android:title="@string/system_framework_volume_first_press"
android:defaultValue="false"
android:key="prefs_key_system_framework_volume_first_press"
android:defaultValue="false" />
android:title="@string/system_framework_volume_first_press" />

<SwitchPreference
android:title="@string/system_framework_volume_separate_control"
android:defaultValue="false"
android:key="prefs_key_system_framework_volume_separate_control"
android:defaultValue="false" />
android:title="@string/system_framework_volume_separate_control" />

<SwitchPreference
android:title="@string/system_framework_volume_separate_slider"
android:key="prefs_key_system_framework_volume_separate_slider"
android:defaultValue="false"
android:dependency="prefs_key_system_framework_volume_separate_control" />

<SwitchPreference
android:title="@string/system_framework_volume_disable_safe"
android:key="prefs_key_system_framework_volume_disable_safe"
android:defaultValue="false" />
android:dependency="prefs_key_system_framework_volume_separate_control"
android:key="prefs_key_system_framework_volume_separate_slider"
android:title="@string/system_framework_volume_separate_slider" />

<SwitchPreference
android:defaultValue="false"
android:key="prefs_key_system_framework_volume_media_steps_enable"
android:title="@string/system_framework_volume_media_steps"
android:summary="@string/system_framework_volume_media_steps_desc" />
android:summary="@string/system_framework_volume_media_steps_desc"
android:title="@string/system_framework_volume_media_steps" />

<SeekBarPreferenceEx
android:layout="@layout/preference_seekbar_no_padding"
android:key="prefs_key_system_framework_volume_media_steps"
android:dependency="prefs_key_system_framework_volume_media_steps_enable"
android:defaultValue="15"
android:dependency="prefs_key_system_framework_volume_media_steps_enable"
android:key="prefs_key_system_framework_volume_media_steps"
android:layout="@layout/preference_seekbar_no_padding"
app:defaultValueText="@string/array_default"
app:format="%s"
app:maxValue="29"
app:minValue="15"
app:stepValue="1"
app:format="%s"
app:showSeekBarValue="true" />
app:showSeekBarValue="true"
app:stepValue="1" />

<SeekBarPreferenceEx
android:defaultValue="0"
android:key="prefs_key_system_framework_volume_steps"
android:title="@string/system_framework_volume_steps"
android:defaultValue="0"
app:defaultValueText="@string/array_default"
app:minValue="0"
app:maxValue="500"
app:stepValue="25"
app:format="X %s"
app:displayDividerValue="100"
app:format="X %s"
app:isPreferenceVisible="false"
app:maxValue="500"
app:minValue="0"
app:showSeekBarValue="true"
app:isPreferenceVisible="false" />
app:stepValue="25" />

</PreferenceScreen>

0 comments on commit 444690e

Please sign in to comment.