Skip to content

Commit

Permalink
Settings: Allow separating ringer & notification sound streams
Browse files Browse the repository at this point in the history
Using the newly added device config (QPR3).
AOSP have already implemented listeners for this to be runtime,
but it seems like they never tested settings side properly - especially when the toggle is at the same page.
After fixing some funny logic errors it now updates just fine.
base side needs no extra modifications, the observers there are programmed correctly.

Change-Id: Ic171b8411409e8936db7d22ed45e21723e6f66d6
  • Loading branch information
idoybh authored and basamaryan committed Jul 11, 2023
1 parent e547894 commit ef734a8
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 14 deletions.
3 changes: 3 additions & 0 deletions res/values/custom_strings.xml
Expand Up @@ -342,4 +342,7 @@
<string name="smart_5g_title">Smart 5G</string>
<string name="smart_5g_summary">Automatically switch between 5G and 4G to reduce battery consumption</string>

<!-- Separate ring & notification toggle -->
<string name="volume_separate_notification_title">Separated Ring and Notification</string>
<string name="volume_separate_notification_summary">Allow controlling each stream individually</string>
</resources>
7 changes: 7 additions & 0 deletions res/xml/sound_settings.xml
Expand Up @@ -97,6 +97,13 @@
android:order="-140"
settings:controller="com.android.settings.notification.AlarmVolumePreferenceController"/>

<!-- Separate ring & notification toggle -->
<SwitchPreference
android:key="volume_separate_notification"
android:title="@string/volume_separate_notification_title"
android:summary="@string/volume_separate_notification_summary"
android:order="-137"/>

<!-- Per-app volume -->
<com.android.settings.custom.preference.SystemSettingSwitchPreference
android:key="show_app_volume"
Expand Down
Expand Up @@ -61,10 +61,12 @@ public NotificationVolumePreferenceController(Context context, String key) {
mNormalIconId = R.drawable.ic_notifications;
mVibrateIconId = R.drawable.ic_volume_ringer_vibrate;
mSilentIconId = R.drawable.ic_notifications_off_24dp;
mSeparateNotification = isSeparateNotificationConfigEnabled();

if (updateRingerMode()) {
updateEnabledState();
}
updateVisibility();
}

/**
Expand All @@ -82,6 +84,7 @@ public void displayPreference(PreferenceScreen screen) {
updateEffectsSuppressor();
selectPreferenceIconState();
updateEnabledState();
updateVisibility();
}

/**
Expand All @@ -95,18 +98,21 @@ private void onDeviceConfigChange(DeviceConfig.Properties properties) {
if (newVal != mSeparateNotification) {
mSeparateNotification = newVal;
// Update UI if config change happens when Sound Settings page is on the foreground
if (mPreference != null) {
int status = getAvailabilityStatus();
mPreference.setVisible(status == AVAILABLE
|| status == DISABLED_DEPENDENT_SETTING);
if (status == DISABLED_DEPENDENT_SETTING) {
mPreference.setEnabled(false);
}
}
updateVisibility();
}
}
}

private void updateVisibility() {
if (mPreference == null) return;
int status = getAvailabilityStatus();
mPreference.setVisible(status == AVAILABLE
|| status == DISABLED_DEPENDENT_SETTING);
if (status == DISABLED_DEPENDENT_SETTING) {
mPreference.setEnabled(false);
}
}

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
@Override
public void onResume() {
Expand All @@ -133,7 +139,7 @@ public int getAvailabilityStatus() {
&& !mHelper.isSingleVolume() && separateNotification
? (mRingerMode == AudioManager.RINGER_MODE_NORMAL
? AVAILABLE : DISABLED_DEPENDENT_SETTING)
: UNSUPPORTED_ON_DEVICE;
: CONDITIONALLY_UNAVAILABLE;
}

@Override
Expand Down
Expand Up @@ -63,6 +63,9 @@ public RingVolumePreferenceController(Context context, String key) {

mSeparateNotification = isSeparateNotificationConfigEnabled();
updateRingerMode();
if (mPreference != null) {
mPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
}
}

/**
Expand All @@ -75,6 +78,9 @@ private void onDeviceConfigChange(DeviceConfig.Properties properties) {
if (valueUpdated) {
updateEffectsSuppressor();
selectPreferenceIconState();
if (mPreference != null) {
mPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
}
}
}
}
Expand Down Expand Up @@ -114,7 +120,7 @@ public String getPreferenceKey() {
public int getAvailabilityStatus() {
boolean separateNotification = isSeparateNotificationConfigEnabled();
return !separateNotification && !mHelper.isSingleVolume()
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}

@Override
Expand Down
Expand Up @@ -62,6 +62,9 @@ public SeparateRingVolumePreferenceController(Context context, String key) {

mSeparateNotification = isSeparateNotificationConfigEnabled();
updateRingerMode();
if (mPreference != null) {
mPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
}
}

/**
Expand All @@ -74,6 +77,9 @@ private void onDeviceConfigChange(DeviceConfig.Properties properties) {
if (valueUpdated) {
updateEffectsSuppressor();
selectPreferenceIconState();
if (mPreference != null) {
mPreference.setVisible(getAvailabilityStatus() == AVAILABLE);
}
}
}
}
Expand Down Expand Up @@ -111,7 +117,7 @@ public String getPreferenceKey() {
public int getAvailabilityStatus() {
boolean separateNotification = isSeparateNotificationConfigEnabled();
return separateNotification && !mHelper.isSingleVolume()
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}

@Override
Expand Down
6 changes: 6 additions & 0 deletions src/com/android/settings/notification/SoundSettings.java
Expand Up @@ -42,6 +42,7 @@
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.sound.HandsFreeProfileOutputPreferenceController;
import com.android.settings.sound.SeparateNotificationPreferenceController;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.Instrumentable;
Expand Down Expand Up @@ -276,6 +277,11 @@ private static List<AbstractPreferenceController> buildPreferenceControllers(Con
controllers.add(new AlarmRingtonePreferenceController(context));
controllers.add(new NotificationRingtonePreferenceController(context));

final SeparateNotificationPreferenceController separateNotificationPreferenceController =
new SeparateNotificationPreferenceController(context);

controllers.add(separateNotificationPreferenceController);

return controllers;
}

Expand Down
Expand Up @@ -54,9 +54,7 @@ public void setCallback(Callback callback) {
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
if (isAvailable()) {
setupVolPreference(screen);
}
setupVolPreference(screen);
}

protected void setupVolPreference(PreferenceScreen screen) {
Expand Down
@@ -0,0 +1,77 @@
/*
* Copyright (C) 2023 Yet Another AOSP 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 com.android.settings.sound;

import android.content.Context;
import android.provider.DeviceConfig;

import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;

import com.android.settings.R;
import com.android.settingslib.core.AbstractPreferenceController;

/**
* A simple preference controller to allow splitting notification and ringtone streams
*/
public class SeparateNotificationPreferenceController extends AbstractPreferenceController
implements Preference.OnPreferenceChangeListener {

private static final String KEY = "volume_separate_notification";

private SwitchPreference mPreference;

public SeparateNotificationPreferenceController(Context context) {
super(context);
}

@Override
public boolean isAvailable() {
return true;
}

@Override
public String getPreferenceKey() {
return KEY;
}

@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = (SwitchPreference) screen.findPreference(KEY);
mPreference.setChecked(getDeviceConfig(KEY));
mPreference.setOnPreferenceChangeListener(this);
}

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference == mPreference) {
final boolean value = (Boolean) newValue;
updateDeviceConfig(KEY, value);
return true;
}
return false;
}

private boolean getDeviceConfig(String key) {
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, key, false);
}

private void updateDeviceConfig(String key, boolean enabled) {
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
key, String.valueOf(enabled), false /* makeDefault */);
}
}

0 comments on commit ef734a8

Please sign in to comment.