diff options
-rw-r--r-- | core/java/android/preference/SeekBarVolumizer.java | 19 | ||||
-rw-r--r-- | core/java/android/provider/Settings.java | 6 | ||||
-rw-r--r-- | packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java | 2 | ||||
-rwxr-xr-x | packages/SystemUI/res/drawable-hdpi/ic_ringer_audible.png | bin | 0 -> 783 bytes | |||
-rwxr-xr-x | packages/SystemUI/res/drawable-mdpi/ic_ringer_audible.png | bin | 0 -> 523 bytes | |||
-rwxr-xr-x | packages/SystemUI/res/drawable-xhdpi/ic_ringer_audible.png | bin | 0 -> 1021 bytes | |||
-rwxr-xr-x | packages/SystemUI/res/drawable-xxhdpi/ic_ringer_audible.png | bin | 0 -> 1495 bytes | |||
-rw-r--r-- | packages/SystemUI/res/drawable/ic_notification_audible.xml (renamed from packages/SystemUI/res/drawable/ic_volume_ringer.xml) | 0 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java | 84 | ||||
-rw-r--r-- | packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java | 20 | ||||
-rw-r--r-- | services/core/java/com/android/server/audio/AudioService.java | 29 |
11 files changed, 126 insertions, 34 deletions
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java index 2445bc2..1754e6e 100644 --- a/core/java/android/preference/SeekBarVolumizer.java +++ b/core/java/android/preference/SeekBarVolumizer.java @@ -59,6 +59,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba private final NotificationManager mNotificationManager; private final int mStreamType; private final int mMaxStreamVolume; + private final boolean mVoiceCapable; private boolean mAffectedByRingerMode; private boolean mNotificationOrRing; private final Receiver mReceiver = new Receiver(); @@ -110,12 +111,19 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba } } mDefaultUri = defaultUri; + mVoiceCapable = context.getResources().getBoolean( + com.android.internal.R.bool.config_voice_capable); } private static boolean isNotificationOrRing(int stream) { return stream == AudioManager.STREAM_RING || stream == AudioManager.STREAM_NOTIFICATION; } + private boolean isNotificationStreamLinked() { + return mVoiceCapable && Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.VOLUME_LINK_NOTIFICATION, 1) == 1; + } + public void setSeekBar(SeekBar seekBar) { if (mSeekBar != null) { mSeekBar.setOnSeekBarChangeListener(null); @@ -139,13 +147,19 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba mSeekBar.setProgress(mLastAudibleStreamVolume); } else if (mNotificationOrRing && mRingerMode == AudioManager.RINGER_MODE_VIBRATE) { mSeekBar.setProgress(0); + mSeekBar.setEnabled(enableSeekBar()); } else if (mMuted) { mSeekBar.setProgress(0); } else { + mSeekBar.setEnabled(enableSeekBar()); mSeekBar.setProgress(mLastProgress > -1 ? mLastProgress : mOriginalStreamVolume); } } + private boolean enableSeekBar() { + return !(mStreamType == AudioManager.STREAM_NOTIFICATION && isNotificationStreamLinked()); + } + @Override public boolean handleMessage(Message msg) { switch (msg.what) { @@ -250,7 +264,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { - if (fromTouch) { + if (fromTouch && enableSeekBar()) { postSetVolume(progress); } if (mCallback != null) { @@ -415,7 +429,8 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba } private void updateVolumeSlider(int streamType, int streamValue) { - final boolean streamMatch = mNotificationOrRing ? isNotificationOrRing(streamType) + final boolean streamMatch = mNotificationOrRing && isNotificationStreamLinked() + ? isNotificationOrRing(streamType) : (streamType == mStreamType); if (mSeekBar != null && streamMatch && streamValue != -1) { final boolean muted = mAudioManager.isStreamMute(mStreamType) diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index e107fd1..6e11c42 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1500,6 +1500,7 @@ public final class Settings { MOVED_TO_SECURE.add(System.KEYBOARD_BRIGHTNESS); MOVED_TO_SECURE.add(System.BUTTON_BRIGHTNESS); MOVED_TO_SECURE.add(System.BUTTON_BACKLIGHT_TIMEOUT); + MOVED_TO_SECURE.add(Secure.VOLUME_LINK_NOTIFICATION); } private static final HashSet<String> MOVED_TO_GLOBAL; @@ -6032,6 +6033,11 @@ public final class Settings { public static final String CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED = "camera_double_tap_power_gesture_disabled"; + /** + * Boolean value whether to link ringtone and notification volume + * @hide + */ + public static final String VOLUME_LINK_NOTIFICATION = "volume_link_notification"; /** * This are the settings to be backed up. diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java index b3ec295..02e4e88 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java @@ -1932,7 +1932,7 @@ class DatabaseHelper extends SQLiteOpenHelper { if (upgradeVersion < 116) { moveSettingsToNewTable(db, TABLE_SYSTEM, TABLE_SECURE, - new String[]{CMSettings.Secure.VOLUME_LINK_NOTIFICATION}, true); + new String[]{Settings.Secure.VOLUME_LINK_NOTIFICATION}, true); if (mUserHandle == UserHandle.USER_OWNER) { db.beginTransaction(); SQLiteStatement stmt = null; diff --git a/packages/SystemUI/res/drawable-hdpi/ic_ringer_audible.png b/packages/SystemUI/res/drawable-hdpi/ic_ringer_audible.png Binary files differnew file mode 100755 index 0000000..03a8f69 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_ringer_audible.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_ringer_audible.png b/packages/SystemUI/res/drawable-mdpi/ic_ringer_audible.png Binary files differnew file mode 100755 index 0000000..36ba5ba --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_ringer_audible.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_ringer_audible.png b/packages/SystemUI/res/drawable-xhdpi/ic_ringer_audible.png Binary files differnew file mode 100755 index 0000000..a9fb16e --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/ic_ringer_audible.png diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_ringer_audible.png b/packages/SystemUI/res/drawable-xxhdpi/ic_ringer_audible.png Binary files differnew file mode 100755 index 0000000..c7a870e --- /dev/null +++ b/packages/SystemUI/res/drawable-xxhdpi/ic_ringer_audible.png diff --git a/packages/SystemUI/res/drawable/ic_volume_ringer.xml b/packages/SystemUI/res/drawable/ic_notification_audible.xml index c566d5a..c566d5a 100644 --- a/packages/SystemUI/res/drawable/ic_volume_ringer.xml +++ b/packages/SystemUI/res/drawable/ic_notification_audible.xml diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java index e9f1095..003662b 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java @@ -42,6 +42,7 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemClock; +import android.provider.Settings; import android.provider.Settings.Global; import android.util.DisplayMetrics; import android.util.Log; @@ -130,7 +131,7 @@ public class VolumeDialog { private long mCollapseTime; public VolumeDialog(Context context, int windowType, VolumeDialogController controller, - ZenModeController zenModeController, Callback callback) { + ZenModeController zenModeController, Callback callback) { mContext = context; mController = controller; mCallback = callback; @@ -177,22 +178,22 @@ public class VolumeDialog { mDialogContentView.setLayoutTransition(mLayoutTransition); mMotion = new VolumeDialogMotion(mDialog, mDialogView, mDialogContentView, mExpandButton, new VolumeDialogMotion.Callback() { - @Override - public void onAnimatingChanged(boolean animating) { - if (animating) return; - if (mPendingStateChanged) { - mHandler.sendEmptyMessage(H.STATE_CHANGED); - mPendingStateChanged = false; - } - if (mPendingRecheckAll) { - mHandler.sendEmptyMessage(H.RECHECK_ALL); - mPendingRecheckAll = false; - } - } - }); + @Override + public void onAnimatingChanged(boolean animating) { + if (animating) return; + if (mPendingStateChanged) { + mHandler.sendEmptyMessage(H.STATE_CHANGED); + mPendingStateChanged = false; + } + if (mPendingRecheckAll) { + mHandler.sendEmptyMessage(H.RECHECK_ALL); + mPendingRecheckAll = false; + } + } + }); addRow(AudioManager.STREAM_RING, - R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, true); + R.drawable.ic_ringer_audible, R.drawable.ic_volume_ringer_mute, true); addRow(AudioManager.STREAM_MUSIC, R.drawable.ic_volume_media, R.drawable.ic_volume_media_mute, true); addRow(AudioManager.STREAM_ALARM, @@ -272,7 +273,7 @@ public class VolumeDialog { row.settingsButton.addOnLayoutChangeListener(new OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, - int oldLeft, int oldTop, int oldRight, int oldBottom) { + int oldLeft, int oldTop, int oldRight, int oldBottom) { final boolean moved = oldLeft != left || oldTop != top; if (D.BUG) Log.d(TAG, "onLayoutChange moved=" + moved + " old=" + new Rect(oldLeft, oldTop, oldRight, oldBottom).toShortString() @@ -597,13 +598,17 @@ public class VolumeDialog { final VolumeRow row = mRows.get(i); if (row.ss == null || !row.ss.dynamic) continue; if (!mDynamic.get(row.stream)) { - mRows.remove(i); - mDialogContentView.removeView(row.view); - mDialogContentView.removeView(row.space); + removeRow(row); } } } + private void removeRow(VolumeRow volumeRow) { + mRows.remove(volumeRow); + mDialogContentView.removeView(volumeRow.view); + mDialogContentView.removeView(volumeRow.space); + } + private void onStateChangedH(State state) { final boolean animating = mMotion.isAnimating(); if (D.BUG) Log.d(TAG, "onStateChangedH animating=" + animating); @@ -624,6 +629,8 @@ public class VolumeDialog { } } + updateNotificationRowH(); + if (mActiveStream != state.activeStream) { mActiveStream = state.activeStream; updateRowsH(); @@ -635,6 +642,19 @@ public class VolumeDialog { updateFooterH(); } + private void updateNotificationRowH() { + VolumeRow notificationRow = findRow(AudioManager.STREAM_NOTIFICATION); + if (notificationRow != null) { + if (mState.linkedNotification) { + removeRow(notificationRow); + } + } else if (!mState.linkedNotification) { + // TODO get icon for mute state + addRow(AudioManager.STREAM_NOTIFICATION, + R.drawable.ic_notification_audible, R.drawable.ic_notification_audible, true); + } + } + private void updateFooterH() { if (D.BUG) Log.d(TAG, "updateFooterH"); final boolean wasVisible = mZenFooter.getVisibility() == View.VISIBLE; @@ -663,8 +683,9 @@ public class VolumeDialog { final boolean isSystemStream = row.stream == AudioManager.STREAM_SYSTEM; final boolean isAlarmStream = row.stream == AudioManager.STREAM_ALARM; final boolean isMusicStream = row.stream == AudioManager.STREAM_MUSIC; - final boolean isRingVibrate = isRingStream - && mState.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE; + final boolean isNotificationStream = row.stream == AudioManager.STREAM_NOTIFICATION; + final boolean isVibrate = mState.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE; + final boolean isRingVibrate = isRingStream && isVibrate; final boolean isRingSilent = isRingStream && mState.ringerModeInternal == AudioManager.RINGER_MODE_SILENT; final boolean isZenAlarms = mState.zenMode == Global.ZEN_MODE_ALARMS; @@ -672,8 +693,9 @@ public class VolumeDialog { final boolean isZenPriority = mState.zenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; final boolean isRingZenNone = (isRingStream || isSystemStream) && isZenNone; final boolean isRingLimited = isRingStream && isZenPriority; - final boolean zenMuted = isZenAlarms ? (isRingStream || isSystemStream) - : isZenNone ? (isRingStream || isSystemStream || isAlarmStream || isMusicStream) + final boolean zenMuted = isZenAlarms ? (isRingStream || isSystemStream || isNotificationStream) + : isZenNone ? (isRingStream || isSystemStream || isAlarmStream || isMusicStream || isNotificationStream) + : isVibrate ? (isNotificationStream) : false; // update slider max @@ -708,12 +730,12 @@ public class VolumeDialog { row.icon.setAlpha(iconEnabled ? 1 : 0.5f); final int iconRes = isRingVibrate ? R.drawable.ic_volume_ringer_vibrate - : isRingSilent || zenMuted ? row.cachedIconRes - : ss.routedToBluetooth ? + : isRingSilent || zenMuted ? row.cachedIconRes + : ss.routedToBluetooth ? (ss.muted ? R.drawable.ic_volume_media_bt_mute : R.drawable.ic_volume_media_bt) - : mAutomute && ss.level == 0 ? row.iconMuteRes - : (ss.muted ? row.iconMuteRes : row.iconRes); + : mAutomute && ss.level == 0 ? row.iconMuteRes + : (ss.muted ? row.iconMuteRes : row.iconRes); if (iconRes != row.cachedIconRes) { if (row.cachedIconRes != 0 && isRingVibrate) { mController.vibrate(); @@ -723,11 +745,11 @@ public class VolumeDialog { } row.iconState = iconRes == R.drawable.ic_volume_ringer_vibrate ? Events.ICON_STATE_VIBRATE - : (iconRes == R.drawable.ic_volume_media_bt_mute || iconRes == row.iconMuteRes) + : (iconRes == R.drawable.ic_volume_media_bt_mute || iconRes == row.iconMuteRes) ? Events.ICON_STATE_MUTE - : (iconRes == R.drawable.ic_volume_media_bt || iconRes == row.iconRes) + : (iconRes == R.drawable.ic_volume_media_bt || iconRes == row.iconRes) ? Events.ICON_STATE_UNMUTE - : Events.ICON_STATE_UNKNOWN; + : Events.ICON_STATE_UNKNOWN; row.icon.setContentDescription(ss.name); // update slider @@ -1081,7 +1103,7 @@ public class VolumeDialog { @Override public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, - AccessibilityEvent event) { + AccessibilityEvent event) { rescheduleTimeoutH(); return super.onRequestSendAccessibilityEvent(host, child, event); } diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java index 32d6805..024fb8c 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java @@ -400,6 +400,16 @@ public class VolumeDialogController { return stream == AudioManager.STREAM_RING || stream == AudioManager.STREAM_NOTIFICATION; } + private boolean updateLinkNotificationConfigW() { + boolean linkNotificationWithVolume = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.VOLUME_LINK_NOTIFICATION, 1) == 1; + if (mState.linkedNotification == linkNotificationWithVolume) { + return false; + } + mState.linkedNotification = linkNotificationWithVolume; + return true; + } + private boolean updateZenModeConfigW() { final ZenModeConfig zenModeConfig = getZenModeConfig(); if (Objects.equals(mState.zenModeConfig, zenModeConfig)) return false; @@ -714,6 +724,8 @@ public class VolumeDialogController { Settings.Global.getUriFor(Settings.Global.ZEN_MODE); private final Uri ZEN_MODE_CONFIG_URI = Settings.Global.getUriFor(Settings.Global.ZEN_MODE_CONFIG_ETAG); + private final Uri VOLUME_LINK_NOTIFICATION_URI = + Settings.Secure.getUriFor(Settings.Secure.VOLUME_LINK_NOTIFICATION); public SettingObserver(Handler handler) { super(handler); @@ -723,6 +735,8 @@ public class VolumeDialogController { mContext.getContentResolver().registerContentObserver(SERVICE_URI, false, this); mContext.getContentResolver().registerContentObserver(ZEN_MODE_URI, false, this); mContext.getContentResolver().registerContentObserver(ZEN_MODE_CONFIG_URI, false, this); + mContext.getContentResolver().registerContentObserver(VOLUME_LINK_NOTIFICATION_URI, + false, this); onChange(true, SERVICE_URI); } @@ -750,6 +764,9 @@ public class VolumeDialogController { if (ZEN_MODE_CONFIG_URI.equals(uri)) { changed = updateZenModeConfigW(); } + if (VOLUME_LINK_NOTIFICATION_URI.equals(uri)) { + changed = updateLinkNotificationConfigW(); + } if (changed) { mCallbacks.onStateChanged(mState); } @@ -947,6 +964,7 @@ public class VolumeDialogController { public String effectsSuppressorName; public ZenModeConfig zenModeConfig; public int activeStream = NO_ACTIVE_STREAM; + public boolean linkedNotification; public State copy() { final State rt = new State(); @@ -960,6 +978,7 @@ public class VolumeDialogController { rt.effectsSuppressorName = effectsSuppressorName; if (zenModeConfig != null) rt.zenModeConfig = zenModeConfig.copy(); rt.activeStream = activeStream; + rt.linkedNotification = linkedNotification; return rt; } @@ -989,6 +1008,7 @@ public class VolumeDialogController { sep(sb, indent); sb.append("effectsSuppressorName:").append(effectsSuppressorName); sep(sb, indent); sb.append("zenModeConfig:").append(zenModeConfig); sep(sb, indent); sb.append("activeStream:").append(activeStream); + sep(sb, indent); sb.append("linkedNotification:").append(linkedNotification); if (indent > 0) sep(sb, indent); return sb.append('}').toString(); } diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index c7e08bb..b922218 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -583,6 +583,8 @@ public class AudioService extends IAudioService.Stub { // If absolute volume is supported in AVRCP device private boolean mAvrcpAbsVolSupported = false; + private boolean mLinkNotificationWithVolume; + private final boolean mVoiceCapable; private static Long mLastDeviceConnectMsgTime = new Long(0); private AudioManagerInternal.RingerModeDelegate mRingerModeDelegate; @@ -640,6 +642,9 @@ public class AudioService extends IAudioService.Stub { mForcedUseForComm = AudioSystem.FORCE_NONE; + mVoiceCapable = context.getResources().getBoolean( + com.android.internal.R.bool.config_voice_capable); + createAudioSystemThread(); AudioSystem.setErrorCallback(mAudioSystemCallback); @@ -671,6 +676,10 @@ public class AudioService extends IAudioService.Stub { mForceAnalogCarDock = mContext.getResources().getBoolean( com.android.internal.R.bool.config_forceAnalogCarDock); + // read this in before readPersistedSettings() because updateStreamVolumeAlias needs it + mLinkNotificationWithVolume = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.VOLUME_LINK_NOTIFICATION, 1) == 1; + // must be called before readPersistedSettings() which needs a valid mStreamVolumeAlias[] // array initialized by updateStreamVolumeAlias() updateStreamVolumeAlias(false /*updateVolumes*/, TAG); @@ -1080,6 +1089,13 @@ public class AudioService extends IAudioService.Stub { } mStreamVolumeAlias[AudioSystem.STREAM_DTMF] = dtmfStreamAlias; + + if (mLinkNotificationWithVolume && mVoiceCapable) { + mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING; + } else { + mStreamVolumeAlias[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_NOTIFICATION; + } + if (updateVolumes) { mStreamStates[AudioSystem.STREAM_DTMF].setAllIndexes(mStreamStates[dtmfStreamAlias], caller); @@ -1152,6 +1168,9 @@ public class AudioService extends IAudioService.Stub { readDockAudioSettings(cr); } + mLinkNotificationWithVolume = Settings.Secure.getInt(cr, + Settings.Secure.VOLUME_LINK_NOTIFICATION, 1) == 1; + mMuteAffectedStreams = System.getIntForUser(cr, System.MUTE_STREAMS_AFFECTED, AudioSystem.DEFAULT_MUTE_STREAMS_AFFECTED, UserHandle.USER_CURRENT); @@ -4705,6 +4724,8 @@ public class AudioService extends IAudioService.Stub { Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this); mContentResolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.DOCK_AUDIO_MEDIA_ENABLED), false, this); + mContentResolver.registerContentObserver(Settings.Secure.getUriFor( + Settings.Secure.VOLUME_LINK_NOTIFICATION), false, this); } @Override @@ -4723,6 +4744,14 @@ public class AudioService extends IAudioService.Stub { setRingerModeInt(getRingerModeInternal(), false); } readDockAudioSettings(mContentResolver); + + boolean linkNotificationWithVolume = Settings.Secure.getInt(mContentResolver, + Settings.Secure.VOLUME_LINK_NOTIFICATION, 1) == 1; + if (linkNotificationWithVolume != mLinkNotificationWithVolume) { + mLinkNotificationWithVolume = linkNotificationWithVolume; + createStreamStates(); + updateStreamVolumeAlias(true, TAG); + } } } } |