Loading packages/SystemUI/res/layout/volume_dialog.xml +57 −8 Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. --> <com.android.systemui.HardwareUiLayout <com.android.systemui.volume.VolumeUiLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" Loading @@ -21,18 +21,19 @@ android:clipChildren="false" > <RelativeLayout android:id="@+id/volume_dialog" android:layout_width="@dimen/volume_dialog_panel_width" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical|end" android:paddingTop="@dimen/volume_row_padding_bottom" android:layout_margin="12dp" android:background="?android:attr/actionBarItemBackground" android:translationZ="8dp" > android:background="@drawable/rounded_full_bg_bottom" android:translationZ="8dp" android:clipChildren="false" > <LinearLayout android:id="@+id/volume_dialog_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:clipChildren="false" android:clipToPadding="false" android:orientation="vertical" > <LinearLayout Loading @@ -42,7 +43,55 @@ android:orientation="vertical" > <!-- volume rows added and removed here! :-) --> </LinearLayout> </LinearLayout> <!-- special row for ringer mode --> <RelativeLayout android:id="@+id/ringer_mode" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/rounded_bg_full" android:clipChildren="false" android:clipToPadding="false" android:layout_margin="10dp"> <com.android.keyguard.AlphaOptimizedImageButton android:id="@+id/ringer_icon" style="@style/VolumeButtons" android:background="?android:selectableItemBackgroundBorderless" android:layout_width="@dimen/volume_button_size" android:layout_height="@dimen/volume_button_size" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:soundEffectsEnabled="false" /> <TextView android:id="@+id/ringer_title" android:text="@string/stream_ring" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:maxLines="1" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_toEndOf="@+id/ringer_icon" android:layout_marginStart="64dp" android:textColor="?android:attr/colorControlNormal" android:textAppearance="?android:attr/textAppearanceSmall" android:paddingStart="@dimen/volume_row_header_padding_start" /> <TextView android:id="@+id/ringer_status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginEnd="14dp" android:maxLines="1" android:textColor="?android:attr/colorControlNormal" android:textAppearance="?android:attr/textAppearanceSmall" /> </RelativeLayout> </LinearLayout> </RelativeLayout> </com.android.systemui.HardwareUiLayout> </com.android.systemui.volume.VolumeUiLayout> No newline at end of file packages/SystemUI/res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -1248,6 +1248,10 @@ <string name="stream_tts" translatable="false">Transmitted Through Speaker</string> <!-- STREAM_TTS --> <string name="stream_accessibility">Accessibility</string> <!-- STREAM_ACCESSIBILITY --> <string name="volume_ringer_status_normal">Ring</string> <string name="volume_ringer_status_vibrate">Vibrate</string> <string name="volume_ringer_status_silent">Mute</string> <string name="volume_stream_muted" translatable="false">%s silent</string> <string name="volume_stream_vibrate" translatable="false">%s vibrate</string> <string name="volume_stream_suppressed" translatable="false">%1$s silent — %2$s</string> Loading packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +118 −37 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.app.KeyguardManager; import android.content.Context; import android.content.DialogInterface; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Color; import android.graphics.Rect; Loading Loading @@ -67,8 +66,6 @@ import android.widget.TextView; import com.android.settingslib.Utils; import com.android.systemui.Dependency; import com.android.systemui.HardwareUiLayout; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.plugins.VolumeDialog; import com.android.systemui.plugins.VolumeDialogController; Loading Loading @@ -97,11 +94,12 @@ public class VolumeDialogImpl implements VolumeDialog { private final VolumeDialogController mController; private Window mWindow; private HardwareUiLayout mHardwareLayout; private CustomDialog mDialog; private ViewGroup mDialogView; private ViewGroup mDialogRowsView; private ViewGroup mDialogContentView; private ImageButton mRingerIcon; private TextView mRingerStatus; private final List<VolumeRow> mRows = new ArrayList<>(); private ConfigurableTexts mConfigurableTexts; private final SparseBooleanArray mDynamic = new SparseBooleanArray(); Loading @@ -111,6 +109,7 @@ public class VolumeDialogImpl implements VolumeDialog { private final Accessibility mAccessibility = new Accessibility(); private final ColorStateList mActiveSliderTint; private final ColorStateList mInactiveSliderTint; private VolumeUiLayout mHardwareLayout; private boolean mShowing; private boolean mShowA11yStream; Loading Loading @@ -160,17 +159,34 @@ public class VolumeDialogImpl implements VolumeDialog { mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); mWindow.addFlags( WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); mWindow.setTitle(VolumeDialogImpl.class.getSimpleName()); mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY); mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast); mDialog.setContentView(R.layout.volume_dialog); mDialogView = (ViewGroup) mDialog.findViewById(R.id.volume_dialog); mDialog.setOnShowListener(new DialogInterface.OnShowListener() { @Override public void onShow(DialogInterface dialog) { mDialogView.setTranslationY(-mDialogView.getHeight()); mDialogView.setAlpha(0); mDialogView.animate() .alpha(1) .translationY(0) .setDuration(300) .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator()) .withEndAction(() -> { mWindow.getDecorView().requestAccessibilityFocus(); }) .start(); } }); mDialogView = mDialog.findViewById(R.id.volume_dialog); mDialogView.setOnHoverListener(new View.OnHoverListener() { @Override public boolean onHover(View v, MotionEvent event) { Loading @@ -181,18 +197,20 @@ public class VolumeDialogImpl implements VolumeDialog { return true; } }); mHardwareLayout = HardwareUiLayout.get(mDialogView); mHardwareLayout = VolumeUiLayout.get(mDialogView); mHardwareLayout.setOutsideTouchListener(view -> dismiss(DISMISS_REASON_TOUCH_OUTSIDE)); mDialogContentView = mDialog.findViewById(R.id.volume_dialog_content); mDialogRowsView = mDialogContentView.findViewById(R.id.volume_dialog_rows); mRingerIcon = mDialogContentView.findViewById(R.id.ringer_icon); mRingerStatus = mDialogContentView.findViewById(R.id.ringer_status); if (mRows.isEmpty()) { addRow(AudioManager.STREAM_MUSIC, R.drawable.ic_volume_media, R.drawable.ic_volume_media_mute, true); if (!AudioSystem.isSingleVolume(mContext)) { addRow(AudioManager.STREAM_RING, R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, true); R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, false); addRow(AudioManager.STREAM_ALARM, R.drawable.ic_volume_alarm, R.drawable.ic_volume_alarm_mute, false); addRow(AudioManager.STREAM_VOICE_CALL, Loading @@ -208,6 +226,7 @@ public class VolumeDialogImpl implements VolumeDialog { addExistingRows(); } updateRowsH(getActiveRow()); initRingerH(); } private ColorStateList loadColorStateList(int colorResId) { Loading Loading @@ -374,6 +393,30 @@ public class VolumeDialogImpl implements VolumeDialog { } } public void initRingerH() { mRingerIcon.setOnClickListener(v -> { Events.writeEvent(mContext, Events.EVENT_ICON_CLICK, AudioManager.STREAM_RING, mRingerIcon.getTag()); final StreamState ss = mState.states.get(AudioManager.STREAM_RING); final boolean hasVibrator = mController.hasVibrator(); if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) { if (hasVibrator) { mController.setRingerMode(AudioManager.RINGER_MODE_VIBRATE, false); } else { final boolean wasZero = ss.level == 0; mController.setStreamVolume(AudioManager.STREAM_RING, wasZero ? 1 : 0); } } else { mController.setRingerMode(AudioManager.RINGER_MODE_NORMAL, false); if (ss.level == 0) { mController.setStreamVolume(AudioManager.STREAM_RING, 1); } } updateRingerH(); }); updateRingerH(); } public void show(int reason) { mHandler.obtainMessage(H.SHOW, reason, 0).sendToTarget(); } Loading @@ -389,27 +432,12 @@ public class VolumeDialogImpl implements VolumeDialog { rescheduleTimeoutH(); if (mShowing) return; mShowing = true; mHardwareLayout.setTranslationX(getAnimTranslation()); mHardwareLayout.setAlpha(0); mHardwareLayout.animate() .alpha(1) .translationX(0) .setDuration(300) .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) .withEndAction(() -> { mDialog.show(); mWindow.getDecorView().requestAccessibilityFocus(); }) .start(); Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked()); mController.notifyVisible(true); } private float getAnimTranslation() { return mContext.getResources().getDimension( R.dimen.volume_dialog_panel_width) / 2; } protected void rescheduleTimeoutH() { mHandler.removeMessages(H.DISMISS); final int timeout = computeTimeoutH(); Loading @@ -423,7 +451,6 @@ public class VolumeDialogImpl implements VolumeDialog { if (mAccessibility.mFeedbackEnabled) return 20000; if (mHovering) return 16000; if (mSafetyWarning != null) return 5000; if (mActiveStream == AudioManager.STREAM_MUSIC) return 1500; return 3000; } Loading @@ -431,16 +458,22 @@ public class VolumeDialogImpl implements VolumeDialog { mHandler.removeMessages(H.DISMISS); mHandler.removeMessages(H.SHOW); if (!mShowing) return; mDialogView.animate().cancel(); mShowing = false; mHardwareLayout.setTranslationX(0); mHardwareLayout.setAlpha(1); mHardwareLayout.animate() mDialogView.setTranslationY(0); mDialogView.setAlpha(1); mDialogView.animate() .alpha(0) .translationX(getAnimTranslation()) .setDuration(300) .withEndAction(() -> mDialog.dismiss()) .translationY(-mDialogView.getHeight()) .setDuration(250) .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator()) .withEndAction(() -> mHandler.postDelayed(() -> { if (D.BUG) Log.d(TAG, "mDialog.dismiss()"); mDialog.dismiss(); }, 50)) .start(); if (mAccessibilityMgr.isEnabled()) { AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); Loading Loading @@ -493,6 +526,53 @@ public class VolumeDialogImpl implements VolumeDialog { } } protected void updateRingerH() { if (mState != null) { final StreamState ss = mState.states.get(AudioManager.STREAM_RING); switch (mState.ringerModeInternal) { case AudioManager.RINGER_MODE_VIBRATE: mRingerStatus.setText(R.string.volume_ringer_status_vibrate); mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_vibrate); mRingerIcon.setTag(Events.ICON_STATE_VIBRATE); break; case AudioManager.RINGER_MODE_SILENT: mRingerStatus.setText(R.string.volume_ringer_status_silent); mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute); mRingerIcon.setContentDescription(mContext.getString( R.string.volume_stream_content_description_unmute, getStreamLabelH(ss))); mRingerIcon.setTag(Events.ICON_STATE_MUTE); break; case AudioManager.RINGER_MODE_NORMAL: default: boolean muted = (mAutomute && ss.level == 0) || ss.muted ? true : false; if (muted) { mRingerStatus.setText(R.string.volume_ringer_status_silent); mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute); mRingerIcon.setContentDescription(mContext.getString( R.string.volume_stream_content_description_unmute, getStreamLabelH(ss))); mRingerIcon.setTag(Events.ICON_STATE_MUTE); } else { mRingerStatus.setText(R.string.volume_ringer_status_normal); mRingerIcon.setImageResource(R.drawable.ic_volume_ringer); if (mController.hasVibrator()) { mRingerIcon.setContentDescription(mContext.getString( mShowA11yStream ? R.string.volume_stream_content_description_vibrate_a11y : R.string.volume_stream_content_description_vibrate, getStreamLabelH(ss))); } else { mRingerIcon.setContentDescription(getStreamLabelH(ss)); } mRingerIcon.setTag(Events.ICON_STATE_UNMUTE); } break; } } } private void trimObsoleteH() { if (D.BUG) Log.d(TAG, "trimObsoleteH"); for (int i = mRows.size() - 1; i >= 0; i--) { Loading Loading @@ -529,6 +609,7 @@ public class VolumeDialogImpl implements VolumeDialog { for (VolumeRow row : mRows) { updateVolumeRowH(row); } updateRingerH(); } private void updateVolumeRowH(VolumeRow row) { Loading packages/SystemUI/src/com/android/systemui/volume/VolumeUiLayout.java 0 → 100644 +66 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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. */ package com.android.systemui.volume; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.widget.FrameLayout; public class VolumeUiLayout extends FrameLayout { public VolumeUiLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsListener); } @Override public ViewOutlineProvider getOutlineProvider() { return super.getOutlineProvider(); } public void setOutsideTouchListener(OnClickListener onClickListener) { requestLayout(); setOnClickListener(onClickListener); setClickable(true); setFocusable(true); } public static VolumeUiLayout get(View v) { if (v instanceof VolumeUiLayout) return (VolumeUiLayout) v; if (v.getParent() instanceof View) { return get((View) v.getParent()); } return null; } private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> { inoutInfo.setTouchableInsets( ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME); }; } Loading
packages/SystemUI/res/layout/volume_dialog.xml +57 −8 Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. --> <com.android.systemui.HardwareUiLayout <com.android.systemui.volume.VolumeUiLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" Loading @@ -21,18 +21,19 @@ android:clipChildren="false" > <RelativeLayout android:id="@+id/volume_dialog" android:layout_width="@dimen/volume_dialog_panel_width" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical|end" android:paddingTop="@dimen/volume_row_padding_bottom" android:layout_margin="12dp" android:background="?android:attr/actionBarItemBackground" android:translationZ="8dp" > android:background="@drawable/rounded_full_bg_bottom" android:translationZ="8dp" android:clipChildren="false" > <LinearLayout android:id="@+id/volume_dialog_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:clipChildren="false" android:clipToPadding="false" android:orientation="vertical" > <LinearLayout Loading @@ -42,7 +43,55 @@ android:orientation="vertical" > <!-- volume rows added and removed here! :-) --> </LinearLayout> </LinearLayout> <!-- special row for ringer mode --> <RelativeLayout android:id="@+id/ringer_mode" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/rounded_bg_full" android:clipChildren="false" android:clipToPadding="false" android:layout_margin="10dp"> <com.android.keyguard.AlphaOptimizedImageButton android:id="@+id/ringer_icon" style="@style/VolumeButtons" android:background="?android:selectableItemBackgroundBorderless" android:layout_width="@dimen/volume_button_size" android:layout_height="@dimen/volume_button_size" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:soundEffectsEnabled="false" /> <TextView android:id="@+id/ringer_title" android:text="@string/stream_ring" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:maxLines="1" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_toEndOf="@+id/ringer_icon" android:layout_marginStart="64dp" android:textColor="?android:attr/colorControlNormal" android:textAppearance="?android:attr/textAppearanceSmall" android:paddingStart="@dimen/volume_row_header_padding_start" /> <TextView android:id="@+id/ringer_status" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginEnd="14dp" android:maxLines="1" android:textColor="?android:attr/colorControlNormal" android:textAppearance="?android:attr/textAppearanceSmall" /> </RelativeLayout> </LinearLayout> </RelativeLayout> </com.android.systemui.HardwareUiLayout> </com.android.systemui.volume.VolumeUiLayout> No newline at end of file
packages/SystemUI/res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -1248,6 +1248,10 @@ <string name="stream_tts" translatable="false">Transmitted Through Speaker</string> <!-- STREAM_TTS --> <string name="stream_accessibility">Accessibility</string> <!-- STREAM_ACCESSIBILITY --> <string name="volume_ringer_status_normal">Ring</string> <string name="volume_ringer_status_vibrate">Vibrate</string> <string name="volume_ringer_status_silent">Mute</string> <string name="volume_stream_muted" translatable="false">%s silent</string> <string name="volume_stream_vibrate" translatable="false">%s vibrate</string> <string name="volume_stream_suppressed" translatable="false">%1$s silent — %2$s</string> Loading
packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +118 −37 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.app.KeyguardManager; import android.content.Context; import android.content.DialogInterface; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Color; import android.graphics.Rect; Loading Loading @@ -67,8 +66,6 @@ import android.widget.TextView; import com.android.settingslib.Utils; import com.android.systemui.Dependency; import com.android.systemui.HardwareUiLayout; import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.plugins.VolumeDialog; import com.android.systemui.plugins.VolumeDialogController; Loading Loading @@ -97,11 +94,12 @@ public class VolumeDialogImpl implements VolumeDialog { private final VolumeDialogController mController; private Window mWindow; private HardwareUiLayout mHardwareLayout; private CustomDialog mDialog; private ViewGroup mDialogView; private ViewGroup mDialogRowsView; private ViewGroup mDialogContentView; private ImageButton mRingerIcon; private TextView mRingerStatus; private final List<VolumeRow> mRows = new ArrayList<>(); private ConfigurableTexts mConfigurableTexts; private final SparseBooleanArray mDynamic = new SparseBooleanArray(); Loading @@ -111,6 +109,7 @@ public class VolumeDialogImpl implements VolumeDialog { private final Accessibility mAccessibility = new Accessibility(); private final ColorStateList mActiveSliderTint; private final ColorStateList mInactiveSliderTint; private VolumeUiLayout mHardwareLayout; private boolean mShowing; private boolean mShowA11yStream; Loading Loading @@ -160,17 +159,34 @@ public class VolumeDialogImpl implements VolumeDialog { mWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); mWindow.addFlags( WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); mWindow.setTitle(VolumeDialogImpl.class.getSimpleName()); mWindow.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY); mWindow.setWindowAnimations(com.android.internal.R.style.Animation_Toast); mDialog.setContentView(R.layout.volume_dialog); mDialogView = (ViewGroup) mDialog.findViewById(R.id.volume_dialog); mDialog.setOnShowListener(new DialogInterface.OnShowListener() { @Override public void onShow(DialogInterface dialog) { mDialogView.setTranslationY(-mDialogView.getHeight()); mDialogView.setAlpha(0); mDialogView.animate() .alpha(1) .translationY(0) .setDuration(300) .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator()) .withEndAction(() -> { mWindow.getDecorView().requestAccessibilityFocus(); }) .start(); } }); mDialogView = mDialog.findViewById(R.id.volume_dialog); mDialogView.setOnHoverListener(new View.OnHoverListener() { @Override public boolean onHover(View v, MotionEvent event) { Loading @@ -181,18 +197,20 @@ public class VolumeDialogImpl implements VolumeDialog { return true; } }); mHardwareLayout = HardwareUiLayout.get(mDialogView); mHardwareLayout = VolumeUiLayout.get(mDialogView); mHardwareLayout.setOutsideTouchListener(view -> dismiss(DISMISS_REASON_TOUCH_OUTSIDE)); mDialogContentView = mDialog.findViewById(R.id.volume_dialog_content); mDialogRowsView = mDialogContentView.findViewById(R.id.volume_dialog_rows); mRingerIcon = mDialogContentView.findViewById(R.id.ringer_icon); mRingerStatus = mDialogContentView.findViewById(R.id.ringer_status); if (mRows.isEmpty()) { addRow(AudioManager.STREAM_MUSIC, R.drawable.ic_volume_media, R.drawable.ic_volume_media_mute, true); if (!AudioSystem.isSingleVolume(mContext)) { addRow(AudioManager.STREAM_RING, R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, true); R.drawable.ic_volume_ringer, R.drawable.ic_volume_ringer_mute, false); addRow(AudioManager.STREAM_ALARM, R.drawable.ic_volume_alarm, R.drawable.ic_volume_alarm_mute, false); addRow(AudioManager.STREAM_VOICE_CALL, Loading @@ -208,6 +226,7 @@ public class VolumeDialogImpl implements VolumeDialog { addExistingRows(); } updateRowsH(getActiveRow()); initRingerH(); } private ColorStateList loadColorStateList(int colorResId) { Loading Loading @@ -374,6 +393,30 @@ public class VolumeDialogImpl implements VolumeDialog { } } public void initRingerH() { mRingerIcon.setOnClickListener(v -> { Events.writeEvent(mContext, Events.EVENT_ICON_CLICK, AudioManager.STREAM_RING, mRingerIcon.getTag()); final StreamState ss = mState.states.get(AudioManager.STREAM_RING); final boolean hasVibrator = mController.hasVibrator(); if (mState.ringerModeInternal == AudioManager.RINGER_MODE_NORMAL) { if (hasVibrator) { mController.setRingerMode(AudioManager.RINGER_MODE_VIBRATE, false); } else { final boolean wasZero = ss.level == 0; mController.setStreamVolume(AudioManager.STREAM_RING, wasZero ? 1 : 0); } } else { mController.setRingerMode(AudioManager.RINGER_MODE_NORMAL, false); if (ss.level == 0) { mController.setStreamVolume(AudioManager.STREAM_RING, 1); } } updateRingerH(); }); updateRingerH(); } public void show(int reason) { mHandler.obtainMessage(H.SHOW, reason, 0).sendToTarget(); } Loading @@ -389,27 +432,12 @@ public class VolumeDialogImpl implements VolumeDialog { rescheduleTimeoutH(); if (mShowing) return; mShowing = true; mHardwareLayout.setTranslationX(getAnimTranslation()); mHardwareLayout.setAlpha(0); mHardwareLayout.animate() .alpha(1) .translationX(0) .setDuration(300) .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) .withEndAction(() -> { mDialog.show(); mWindow.getDecorView().requestAccessibilityFocus(); }) .start(); Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked()); mController.notifyVisible(true); } private float getAnimTranslation() { return mContext.getResources().getDimension( R.dimen.volume_dialog_panel_width) / 2; } protected void rescheduleTimeoutH() { mHandler.removeMessages(H.DISMISS); final int timeout = computeTimeoutH(); Loading @@ -423,7 +451,6 @@ public class VolumeDialogImpl implements VolumeDialog { if (mAccessibility.mFeedbackEnabled) return 20000; if (mHovering) return 16000; if (mSafetyWarning != null) return 5000; if (mActiveStream == AudioManager.STREAM_MUSIC) return 1500; return 3000; } Loading @@ -431,16 +458,22 @@ public class VolumeDialogImpl implements VolumeDialog { mHandler.removeMessages(H.DISMISS); mHandler.removeMessages(H.SHOW); if (!mShowing) return; mDialogView.animate().cancel(); mShowing = false; mHardwareLayout.setTranslationX(0); mHardwareLayout.setAlpha(1); mHardwareLayout.animate() mDialogView.setTranslationY(0); mDialogView.setAlpha(1); mDialogView.animate() .alpha(0) .translationX(getAnimTranslation()) .setDuration(300) .withEndAction(() -> mDialog.dismiss()) .translationY(-mDialogView.getHeight()) .setDuration(250) .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator()) .withEndAction(() -> mHandler.postDelayed(() -> { if (D.BUG) Log.d(TAG, "mDialog.dismiss()"); mDialog.dismiss(); }, 50)) .start(); if (mAccessibilityMgr.isEnabled()) { AccessibilityEvent event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); Loading Loading @@ -493,6 +526,53 @@ public class VolumeDialogImpl implements VolumeDialog { } } protected void updateRingerH() { if (mState != null) { final StreamState ss = mState.states.get(AudioManager.STREAM_RING); switch (mState.ringerModeInternal) { case AudioManager.RINGER_MODE_VIBRATE: mRingerStatus.setText(R.string.volume_ringer_status_vibrate); mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_vibrate); mRingerIcon.setTag(Events.ICON_STATE_VIBRATE); break; case AudioManager.RINGER_MODE_SILENT: mRingerStatus.setText(R.string.volume_ringer_status_silent); mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute); mRingerIcon.setContentDescription(mContext.getString( R.string.volume_stream_content_description_unmute, getStreamLabelH(ss))); mRingerIcon.setTag(Events.ICON_STATE_MUTE); break; case AudioManager.RINGER_MODE_NORMAL: default: boolean muted = (mAutomute && ss.level == 0) || ss.muted ? true : false; if (muted) { mRingerStatus.setText(R.string.volume_ringer_status_silent); mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute); mRingerIcon.setContentDescription(mContext.getString( R.string.volume_stream_content_description_unmute, getStreamLabelH(ss))); mRingerIcon.setTag(Events.ICON_STATE_MUTE); } else { mRingerStatus.setText(R.string.volume_ringer_status_normal); mRingerIcon.setImageResource(R.drawable.ic_volume_ringer); if (mController.hasVibrator()) { mRingerIcon.setContentDescription(mContext.getString( mShowA11yStream ? R.string.volume_stream_content_description_vibrate_a11y : R.string.volume_stream_content_description_vibrate, getStreamLabelH(ss))); } else { mRingerIcon.setContentDescription(getStreamLabelH(ss)); } mRingerIcon.setTag(Events.ICON_STATE_UNMUTE); } break; } } } private void trimObsoleteH() { if (D.BUG) Log.d(TAG, "trimObsoleteH"); for (int i = mRows.size() - 1; i >= 0; i--) { Loading Loading @@ -529,6 +609,7 @@ public class VolumeDialogImpl implements VolumeDialog { for (VolumeRow row : mRows) { updateVolumeRowH(row); } updateRingerH(); } private void updateVolumeRowH(VolumeRow row) { Loading
packages/SystemUI/src/com/android/systemui/volume/VolumeUiLayout.java 0 → 100644 +66 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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. */ package com.android.systemui.volume; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.widget.FrameLayout; public class VolumeUiLayout extends FrameLayout { public VolumeUiLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsListener); } @Override public ViewOutlineProvider getOutlineProvider() { return super.getOutlineProvider(); } public void setOutsideTouchListener(OnClickListener onClickListener) { requestLayout(); setOnClickListener(onClickListener); setClickable(true); setFocusable(true); } public static VolumeUiLayout get(View v) { if (v instanceof VolumeUiLayout) return (VolumeUiLayout) v; if (v.getParent() instanceof View) { return get((View) v.getParent()); } return null; } private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> { inoutInfo.setTouchableInsets( ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME); }; }