Volume UI updates
- Reorder streams - constrain ripples - Show an introductory ripple on the ringer toggle - Add sound/vibration feedback for the ringer toggle - resize some elements Test: manual Bug: 76438403 Fixes: 73892482 Change-Id: I92dd6f5681f1822ae493a5a2b218b15970293e80
This commit is contained in:
@@ -19,6 +19,7 @@ import android.content.ComponentName;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
import android.os.Handler;
|
||||
import android.os.VibrationEffect;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.systemui.plugins.VolumeDialogController.Callbacks;
|
||||
@@ -44,7 +45,8 @@ public interface VolumeDialogController {
|
||||
void setRingerMode(int ringerModeNormal, boolean external);
|
||||
|
||||
boolean hasVibrator();
|
||||
void vibrate();
|
||||
void vibrate(VibrationEffect effect);
|
||||
void scheduleTouchFeedback();
|
||||
|
||||
AudioManager getAudioManager();
|
||||
|
||||
|
||||
@@ -1,4 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2018 The Android Open Source 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.
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="?android:attr/colorPrimaryDark" />
|
||||
|
||||
30
packages/SystemUI/res/drawable/rounded_ripple.xml
Normal file
30
packages/SystemUI/res/drawable/rounded_ripple.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2018 The Android Open Source 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.
|
||||
-->
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?android:attr/colorControlHighlight">
|
||||
<item android:id="@android:id/mask">
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#FFFFFFFF"/>
|
||||
<corners android:radius="8dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:id="@android:id/background">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="#FFFFFFFF"/>
|
||||
<corners android:radius="8dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
@@ -38,7 +38,7 @@
|
||||
android:orientation="vertical"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:elevation="@dimen/volume_panel_elevation" >
|
||||
android:elevation="@dimen/volume_dialog_elevation" >
|
||||
<LinearLayout
|
||||
android:id="@+id/car_volume_dialog_rows"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="@dimen/volume_dialog_panel_transparent_padding"
|
||||
android:background="@android:color/transparent"
|
||||
android:theme="@style/qs_theme"
|
||||
android:clipChildren="false" >
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
<!-- right-aligned to be physically near volume button -->
|
||||
<LinearLayout
|
||||
android:id="@+id/volume_dialog"
|
||||
@@ -30,22 +32,25 @@
|
||||
android:background="@android:color/transparent"
|
||||
android:layout_margin="@dimen/volume_dialog_base_margin"
|
||||
android:orientation="vertical"
|
||||
android:clipChildren="false" >
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false" >
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/ringer"
|
||||
android:layout_width="@dimen/volume_dialog_ringer_size"
|
||||
android:layout_height="@dimen/volume_dialog_ringer_size"
|
||||
android:layout_marginBottom="@dimen/volume_dialog_spacer"
|
||||
android:elevation="@dimen/volume_panel_elevation"
|
||||
android:translationZ="@dimen/volume_dialog_elevation"
|
||||
android:layout_gravity="right"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:background="@drawable/rounded_bg_full">
|
||||
<com.android.keyguard.AlphaOptimizedImageButton
|
||||
android:id="@+id/ringer_icon"
|
||||
style="@style/VolumeButtons"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
android:layout_width="@dimen/volume_dialog_tap_target_size"
|
||||
android:layout_height="@dimen/volume_dialog_tap_target_size"
|
||||
android:background="@drawable/rounded_ripple"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:tint="@color/accent_tint_color_selector"
|
||||
android:layout_gravity="center"
|
||||
android:soundEffectsEnabled="false" />
|
||||
@@ -59,10 +64,10 @@
|
||||
android:minWidth="@dimen/volume_dialog_panel_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:translationZ="@dimen/volume_dialog_elevation"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:background="@drawable/rounded_bg_full"
|
||||
android:elevation="@dimen/volume_panel_elevation" >
|
||||
android:background="@drawable/rounded_bg_full" >
|
||||
<LinearLayout
|
||||
android:id="@+id/volume_dialog_rows"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -84,7 +89,7 @@
|
||||
android:layout_height="@dimen/volume_dialog_tap_target_size"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/accessibility_volume_settings"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/ripple_drawable_20dp"
|
||||
android:tint="?android:attr/colorControlNormal"
|
||||
android:soundEffectsEnabled="false" />
|
||||
</FrameLayout>
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
style="@style/VolumeButtons"
|
||||
android:layout_width="@dimen/volume_dialog_tap_target_size"
|
||||
android:layout_height="@dimen/volume_dialog_tap_target_size"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
android:background="@drawable/ripple_drawable_20dp"
|
||||
android:layout_marginBottom="@dimen/volume_dialog_row_margin_bottom"
|
||||
android:tint="@color/accent_tint_color_selector"
|
||||
android:soundEffectsEnabled="false" />
|
||||
|
||||
@@ -270,13 +270,15 @@
|
||||
<!-- The width of the panel that holds the quick settings. -->
|
||||
<dimen name="qs_panel_width">@dimen/notification_panel_width</dimen>
|
||||
|
||||
<dimen name="volume_dialog_panel_transparent_padding">8dp</dimen>
|
||||
|
||||
<!-- the amount the volume panel should be offset at the end from the view next to it (or
|
||||
the screen edge, in portrait-->
|
||||
<dimen name="volume_dialog_base_margin">8dp</dimen>
|
||||
|
||||
<dimen name="volume_dialog_panel_width">64dp</dimen>
|
||||
|
||||
<dimen name="volume_dialog_slider_height">108dp</dimen>
|
||||
<dimen name="volume_dialog_slider_height">116dp</dimen>
|
||||
|
||||
<dimen name="volume_dialog_row_height">252dp</dimen>
|
||||
|
||||
@@ -286,7 +288,7 @@
|
||||
|
||||
<dimen name="volume_dialog_spacer">4dp</dimen>
|
||||
|
||||
<dimen name="volume_dialog_slider_margin_top">22dp</dimen>
|
||||
<dimen name="volume_dialog_slider_margin_top">14dp</dimen>
|
||||
|
||||
<dimen name="volume_dialog_slider_margin_bottom">-2dp</dimen>
|
||||
|
||||
@@ -294,6 +296,8 @@
|
||||
|
||||
<dimen name="volume_dialog_settings_icon_size">16dp</dimen>
|
||||
|
||||
<dimen name="volume_dialog_elevation">9dp</dimen>
|
||||
|
||||
<!-- Gravity for the notification panel -->
|
||||
<integer name="notification_panel_layout_gravity">0x31</integer><!-- center_horizontal|top -->
|
||||
|
||||
@@ -734,8 +738,6 @@
|
||||
<dimen name="volume_expander_margin_end">2dp</dimen>
|
||||
<dimen name="volume_expander_margin_top">6dp</dimen>
|
||||
|
||||
<dimen name="volume_panel_elevation">8dp</dimen>
|
||||
|
||||
<!-- Padding between icon and text for managed profile toast -->
|
||||
<dimen name="managed_profile_toast_padding">4dp</dimen>
|
||||
|
||||
|
||||
@@ -1350,7 +1350,7 @@
|
||||
|
||||
<string name="volume_dialog_title">%s volume controls</string>
|
||||
|
||||
<string name="volume_dialog_ringer_guidance_ring">Calls and notifications will ring</string>
|
||||
<string name="volume_dialog_ringer_guidance_ring">Calls and notifications will ring (<xliff:g id="volume level" example="56">%1$s</xliff:g>)</string>
|
||||
|
||||
<string name="output_title">Media output</string>
|
||||
<string name="output_calls_title">Phone call output</string>
|
||||
|
||||
@@ -53,7 +53,8 @@ public final class Prefs {
|
||||
Key.NUM_APPS_LAUNCHED,
|
||||
Key.HAS_SEEN_RECENTS_ONBOARDING,
|
||||
Key.SEEN_RINGER_GUIDANCE_COUNT,
|
||||
Key.QS_HAS_TURNED_OFF_MOBILE_DATA
|
||||
Key.QS_HAS_TURNED_OFF_MOBILE_DATA,
|
||||
Key.TOUCHED_RINGER_TOGGLE
|
||||
})
|
||||
public @interface Key {
|
||||
@Deprecated
|
||||
@@ -91,6 +92,7 @@ public final class Prefs {
|
||||
String SEEN_RINGER_GUIDANCE_COUNT = "RingerGuidanceCount";
|
||||
String QS_TILE_SPECS_REVEALED = "QsTileSpecsRevealed";
|
||||
String QS_HAS_TURNED_OFF_MOBILE_DATA = "QsHasTurnedOffMobileData";
|
||||
String TOUCHED_RINGER_TOGGLE = "TouchedRingerToggle";
|
||||
}
|
||||
|
||||
public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.systemui.volume;
|
||||
|
||||
import static android.media.AudioManager.RINGER_MODE_NORMAL;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
@@ -29,6 +31,7 @@ import android.database.ContentObserver;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
import android.media.IAudioService;
|
||||
import android.media.IVolumeController;
|
||||
import android.media.VolumePolicy;
|
||||
import android.media.session.MediaController.PlaybackInfo;
|
||||
@@ -39,6 +42,7 @@ import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings;
|
||||
@@ -73,9 +77,11 @@ import java.util.Objects;
|
||||
public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpable {
|
||||
private static final String TAG = Util.logTag(VolumeDialogControllerImpl.class);
|
||||
|
||||
|
||||
private static final int TOUCH_FEEDBACK_TIMEOUT_MS = 1000;
|
||||
private static final int DYNAMIC_STREAM_START_INDEX = 100;
|
||||
private static final int VIBRATE_HINT_DURATION = 50;
|
||||
private static final AudioAttributes SONFICIATION_VIBRATION_ATTRIBUTES =
|
||||
private static final AudioAttributes SONIFICIATION_VIBRATION_ATTRIBUTES =
|
||||
new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
|
||||
@@ -100,6 +106,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
private final W mWorker;
|
||||
private final Context mContext;
|
||||
private AudioManager mAudio;
|
||||
private IAudioService mAudioService;
|
||||
protected StatusBar mStatusBar;
|
||||
private final NotificationManager mNoMan;
|
||||
private final SettingObserver mObserver;
|
||||
@@ -113,6 +120,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
private boolean mShowA11yStream;
|
||||
private boolean mShowVolumeDialog;
|
||||
private boolean mShowSafetyWarning;
|
||||
private long mLastToggledRingerOn;
|
||||
private final NotificationManager mNotificationManager;
|
||||
|
||||
private boolean mDestroyed;
|
||||
@@ -140,6 +148,8 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
mReceiver.init();
|
||||
mVibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
mHasVibrator = mVibrator != null && mVibrator.hasVibrator();
|
||||
mAudioService = IAudioService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.AUDIO_SERVICE));
|
||||
updateStatusBar();
|
||||
|
||||
boolean accessibilityVolumeStreamActive = context.getSystemService(
|
||||
@@ -300,10 +310,24 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
mShowSafetyWarning = safetyWarning;
|
||||
}
|
||||
|
||||
public void vibrate() {
|
||||
@Override
|
||||
public void scheduleTouchFeedback() {
|
||||
mLastToggledRingerOn = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private void playTouchFeedback() {
|
||||
if (System.currentTimeMillis() - mLastToggledRingerOn < TOUCH_FEEDBACK_TIMEOUT_MS) {
|
||||
try {
|
||||
mAudioService.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD);
|
||||
} catch (RemoteException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void vibrate(VibrationEffect effect) {
|
||||
if (mHasVibrator) {
|
||||
mVibrator.vibrate(VibrationEffect.createOneShot(VIBRATE_HINT_DURATION,
|
||||
VibrationEffect.DEFAULT_AMPLITUDE), SONFICIATION_VIBRATION_ATTRIBUTES);
|
||||
mVibrator.vibrate(effect, SONIFICIATION_VIBRATION_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,7 +449,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
for (int stream : STREAMS.keySet()) {
|
||||
updateStreamLevelW(stream, getAudioManagerStreamVolume(stream));
|
||||
streamStateW(stream).levelMin = getAudioManagerStreamMinVolume(stream);
|
||||
streamStateW(stream).levelMax = getAudioManagerStreamMaxVolume(stream);
|
||||
streamStateW(stream).levelMax = Math.max(1, getAudioManagerStreamMaxVolume(stream));
|
||||
updateStreamMuteW(stream, mAudio.isStreamMute(stream));
|
||||
final StreamState ss = streamStateW(stream);
|
||||
ss.muteSupported = mAudio.isStreamAffectedByMute(stream);
|
||||
@@ -556,6 +580,11 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
if (rm == mState.ringerModeInternal) return false;
|
||||
mState.ringerModeInternal = rm;
|
||||
Events.writeEvent(mContext, Events.EVENT_INTERNAL_RINGER_MODE_CHANGED, rm);
|
||||
|
||||
if (mState.ringerModeInternal == RINGER_MODE_NORMAL) {
|
||||
playTouchFeedback();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ import static android.media.AudioManager.RINGER_MODE_NORMAL;
|
||||
import static android.media.AudioManager.RINGER_MODE_SILENT;
|
||||
import static android.media.AudioManager.RINGER_MODE_VIBRATE;
|
||||
import static android.media.AudioManager.STREAM_ACCESSIBILITY;
|
||||
import static android.media.AudioManager.STREAM_ALARM;
|
||||
import static android.media.AudioManager.STREAM_MUSIC;
|
||||
import static android.media.AudioManager.STREAM_RING;
|
||||
import static android.media.AudioManager.STREAM_VOICE_CALL;
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
|
||||
@@ -41,13 +45,17 @@ import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.Debug;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Global;
|
||||
import android.text.InputFilter;
|
||||
@@ -126,6 +134,7 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
private final Accessibility mAccessibility = new Accessibility();
|
||||
private final ColorStateList mActiveSliderTint;
|
||||
private final ColorStateList mInactiveSliderTint;
|
||||
private final Vibrator mVibrator;
|
||||
|
||||
private boolean mShowing;
|
||||
private boolean mShowA11yStream;
|
||||
@@ -146,6 +155,7 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
mActiveSliderTint = ColorStateList.valueOf(Utils.getColorAccent(mContext));
|
||||
mInactiveSliderTint = loadColorStateList(R.color.volume_slider_inactive);
|
||||
mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
|
||||
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
}
|
||||
|
||||
public void init(int windowType, Callback callback) {
|
||||
@@ -203,6 +213,9 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
.setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator())
|
||||
.withEndAction(() -> {
|
||||
mWindow.getDecorView().requestAccessibilityFocus();
|
||||
if (!Prefs.getBoolean(mContext, Prefs.Key.TOUCHED_RINGER_TOGGLE, true)) {
|
||||
mRingerIcon.postOnAnimationDelayed(mSinglePress, 1500);
|
||||
}
|
||||
})
|
||||
.start();
|
||||
});
|
||||
@@ -223,12 +236,16 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
mSettingsIcon = mDialog.findViewById(R.id.settings);
|
||||
|
||||
if (mRows.isEmpty()) {
|
||||
if (!AudioSystem.isSingleVolume(mContext)) {
|
||||
addRow(STREAM_ACCESSIBILITY, R.drawable.ic_volume_accessibility,
|
||||
R.drawable.ic_volume_accessibility, true, false);
|
||||
}
|
||||
addRow(AudioManager.STREAM_MUSIC,
|
||||
R.drawable.ic_volume_media, R.drawable.ic_volume_media_mute, true, true);
|
||||
if (!AudioSystem.isSingleVolume(mContext)) {
|
||||
addRow(AudioManager.STREAM_RING,
|
||||
R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, true, false);
|
||||
addRow(AudioManager.STREAM_ALARM,
|
||||
addRow(STREAM_ALARM,
|
||||
R.drawable.ic_volume_alarm, R.drawable.ic_volume_alarm_mute, true, false);
|
||||
addRow(AudioManager.STREAM_VOICE_CALL,
|
||||
R.drawable.ic_volume_voice, R.drawable.ic_volume_voice, false, false);
|
||||
@@ -236,8 +253,6 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
R.drawable.ic_volume_bt_sco, R.drawable.ic_volume_bt_sco, false, false);
|
||||
addRow(AudioManager.STREAM_SYSTEM, R.drawable.ic_volume_system,
|
||||
R.drawable.ic_volume_system_mute, false, false);
|
||||
addRow(STREAM_ACCESSIBILITY, R.drawable.ic_volume_accessibility,
|
||||
R.drawable.ic_volume_accessibility, true, false);
|
||||
}
|
||||
} else {
|
||||
addExistingRows();
|
||||
@@ -287,11 +302,11 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
if (D.BUG) Slog.d(TAG, "Adding row for stream " + stream);
|
||||
VolumeRow row = new VolumeRow();
|
||||
initRow(row, stream, iconRes, iconMuteRes, important, defaultStream);
|
||||
int rowSize;
|
||||
if (mShowA11yStream && dynamic && (rowSize = mRows.size()) > 1) {
|
||||
// A11y Stream should be the first in the list, so it's shown to start of other rows
|
||||
mDialogRowsView.addView(row.view, 0);
|
||||
mRows.add(rowSize - 2, row);
|
||||
if (dynamic && mRows.size() > 2) {
|
||||
// Dynamic Streams should be the first in the list, so they're shown to start of
|
||||
// everything except a11y
|
||||
mDialogRowsView.addView(row.view, 1);
|
||||
mRows.add(1, row);
|
||||
} else {
|
||||
mDialogRowsView.addView(row.view);
|
||||
mRows.add(row);
|
||||
@@ -315,6 +330,11 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
return row;
|
||||
}
|
||||
}
|
||||
for (VolumeRow row : mRows) {
|
||||
if (row.stream == STREAM_MUSIC) {
|
||||
return row;
|
||||
}
|
||||
}
|
||||
return mRows.get(0);
|
||||
}
|
||||
|
||||
@@ -414,6 +434,7 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
mRingerIcon.setOnClickListener(v -> {
|
||||
Events.writeEvent(mContext, Events.EVENT_ICON_CLICK, AudioManager.STREAM_RING,
|
||||
mRingerIcon.getTag());
|
||||
Prefs.putBoolean(mContext, Prefs.Key.TOUCHED_RINGER_TOGGLE, true);
|
||||
final StreamState ss = mState.states.get(AudioManager.STREAM_RING);
|
||||
if (ss == null) {
|
||||
return;
|
||||
@@ -424,7 +445,6 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
final boolean hasVibrator = mController.hasVibrator();
|
||||
if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) {
|
||||
if (hasVibrator) {
|
||||
mController.vibrate();
|
||||
newRingerMode = AudioManager.RINGER_MODE_VIBRATE;
|
||||
} else {
|
||||
newRingerMode = AudioManager.RINGER_MODE_SILENT;
|
||||
@@ -438,30 +458,56 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
}
|
||||
updateRingerH();
|
||||
|
||||
provideTouchFeedbackH(newRingerMode);
|
||||
mController.setRingerMode(newRingerMode, false);
|
||||
maybeShowToastH(newRingerMode);
|
||||
});
|
||||
updateRingerH();
|
||||
}
|
||||
|
||||
|
||||
private void provideTouchFeedbackH(int newRingerMode) {
|
||||
VibrationEffect effect = null;
|
||||
switch (newRingerMode) {
|
||||
case RINGER_MODE_NORMAL:
|
||||
mController.scheduleTouchFeedback();
|
||||
break;
|
||||
case RINGER_MODE_SILENT:
|
||||
effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
|
||||
break;
|
||||
case RINGER_MODE_VIBRATE:
|
||||
default:
|
||||
effect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
|
||||
}
|
||||
if (effect != null) {
|
||||
mController.vibrate(effect);
|
||||
}
|
||||
}
|
||||
|
||||
private void maybeShowToastH(int newRingerMode) {
|
||||
int seenToastCount = Prefs.getInt(mContext, Prefs.Key.SEEN_RINGER_GUIDANCE_COUNT, 0);
|
||||
|
||||
if (seenToastCount > VolumePrefs.SHOW_RINGER_TOAST_COUNT) {
|
||||
return;
|
||||
}
|
||||
int toastText;
|
||||
CharSequence toastText = null;
|
||||
switch (newRingerMode) {
|
||||
case RINGER_MODE_NORMAL:
|
||||
toastText = R.string.volume_dialog_ringer_guidance_ring;
|
||||
final StreamState ss = mState.states.get(AudioManager.STREAM_RING);
|
||||
if (ss != null) {
|
||||
toastText = mContext.getString(
|
||||
R.string.volume_dialog_ringer_guidance_ring,
|
||||
Utils.formatPercentage(ss.level, ss.levelMax));
|
||||
}
|
||||
break;
|
||||
case RINGER_MODE_SILENT:
|
||||
toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_silent;
|
||||
toastText = mContext.getString(
|
||||
com.android.internal.R.string.volume_dialog_ringer_guidance_silent);
|
||||
break;
|
||||
case RINGER_MODE_VIBRATE:
|
||||
default:
|
||||
toastText = com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate;
|
||||
toastText = mContext.getString(
|
||||
com.android.internal.R.string.volume_dialog_ringer_guidance_vibrate);
|
||||
}
|
||||
|
||||
Toast.makeText(mContext, toastText, Toast.LENGTH_SHORT).show();
|
||||
@@ -538,7 +584,7 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
|
||||
private boolean shouldBeVisibleH(VolumeRow row, VolumeRow activeRow) {
|
||||
boolean isActive = row == activeRow;
|
||||
boolean isActive = row.stream == activeRow.stream;
|
||||
if (row.stream == AudioSystem.STREAM_ACCESSIBILITY) {
|
||||
return mShowA11yStream;
|
||||
}
|
||||
@@ -550,7 +596,17 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
return true;
|
||||
}
|
||||
|
||||
return row.defaultStream || isActive;
|
||||
if (isActive) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (row.defaultStream) {
|
||||
return activeRow.stream == STREAM_RING
|
||||
|| activeRow.stream == STREAM_ALARM
|
||||
|| activeRow.stream == STREAM_VOICE_CALL;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updateRowsH(final VolumeRow activeRow) {
|
||||
@@ -670,7 +726,8 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
if (mActiveStream != state.activeStream) {
|
||||
mPrevActiveStream = mActiveStream;
|
||||
mActiveStream = state.activeStream;
|
||||
updateRowsH(getActiveRow());
|
||||
VolumeRow activeRow = getActiveRow();
|
||||
updateRowsH(activeRow);
|
||||
rescheduleTimeoutH();
|
||||
}
|
||||
for (VolumeRow row : mRows) {
|
||||
@@ -696,7 +753,7 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
final boolean isA11yStream = row.stream == STREAM_ACCESSIBILITY;
|
||||
final boolean isRingStream = row.stream == AudioManager.STREAM_RING;
|
||||
final boolean isSystemStream = row.stream == AudioManager.STREAM_SYSTEM;
|
||||
final boolean isAlarmStream = row.stream == AudioManager.STREAM_ALARM;
|
||||
final boolean isAlarmStream = row.stream == STREAM_ALARM;
|
||||
final boolean isMusicStream = row.stream == AudioManager.STREAM_MUSIC;
|
||||
final boolean isRingVibrate = isRingStream
|
||||
&& mState.ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE;
|
||||
@@ -921,6 +978,21 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
}
|
||||
}
|
||||
|
||||
private Runnable mSinglePress = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mRingerIcon.setPressed(true);
|
||||
mRingerIcon.postOnAnimationDelayed(mSingleUnpress, 200);
|
||||
}
|
||||
};
|
||||
|
||||
private Runnable mSingleUnpress = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mRingerIcon.setPressed(false);
|
||||
}
|
||||
};
|
||||
|
||||
private final VolumeDialogController.Callbacks mControllerCallbackH
|
||||
= new VolumeDialogController.Callbacks() {
|
||||
@Override
|
||||
|
||||
@@ -43,7 +43,7 @@ public class VolumePrefs {
|
||||
public static final String PREF_ADJUST_ALARMS = "pref_adjust_alarms";
|
||||
public static final String PREF_ADJUST_NOTIFICATION = "pref_adjust_notification";
|
||||
|
||||
public static final int SHOW_RINGER_TOAST_COUNT = 9;
|
||||
public static final int SHOW_RINGER_TOAST_COUNT = 12;
|
||||
|
||||
public static final boolean DEFAULT_SHOW_HEADERS = true;
|
||||
public static final boolean DEFAULT_ENABLE_AUTOMUTE = true;
|
||||
|
||||
Reference in New Issue
Block a user