Early version of new volume + power menus
Still needs a bunch of code cleanup, but this will get a version
into the tree for testing.
Test: visual
Bug: 37013646
Change-Id: I29800b57d80ea120c691663392f368c17325ab54
diff --git a/packages/SystemUI/res/drawable/rounded_bg.xml b/packages/SystemUI/res/drawable/rounded_bg.xml
new file mode 100644
index 0000000..56aa9fe
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="#ffffffff" />
+ <corners
+ android:bottomLeftRadius="@dimen/corner_size"
+ android:topLeftRadius="@dimen/corner_size"
+ android:bottomRightRadius="0dp"
+ android:topRightRadius="0dp"
+ />
+</shape>
diff --git a/packages/SystemUI/res/drawable/rounded_bg_bottom.xml b/packages/SystemUI/res/drawable/rounded_bg_bottom.xml
new file mode 100644
index 0000000..0201f28
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg_bottom.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="#ffeeeeee" />
+ <corners
+ android:bottomLeftRadius="@dimen/corner_size"
+ android:topLeftRadius="0dp"
+ android:bottomRightRadius="0dp"
+ android:topRightRadius="0dp"
+ />
+</shape>
diff --git a/packages/SystemUI/res/drawable/rounded_bg_full.xml b/packages/SystemUI/res/drawable/rounded_bg_full.xml
new file mode 100644
index 0000000..65d00de
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_bg_full.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="#ffffffff" />
+ <corners
+ android:bottomLeftRadius="@dimen/corner_size"
+ android:topLeftRadius="@dimen/corner_size"
+ android:bottomRightRadius="@dimen/corner_size"
+ android:topRightRadius="@dimen/corner_size"
+ />
+</shape>
diff --git a/packages/SystemUI/res/drawable/rounded_full_bg_bottom.xml b/packages/SystemUI/res/drawable/rounded_full_bg_bottom.xml
new file mode 100644
index 0000000..f6ee558
--- /dev/null
+++ b/packages/SystemUI/res/drawable/rounded_full_bg_bottom.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <solid android:color="#ffeeeeee" />
+ <corners
+ android:bottomLeftRadius="@dimen/corner_size"
+ android:topLeftRadius="0dp"
+ android:bottomRightRadius="@dimen/corner_size"
+ android:topRightRadius="0dp"
+ />
+</shape>
diff --git a/packages/SystemUI/res/layout/global_actions_item.xml b/packages/SystemUI/res/layout/global_actions_item.xml
new file mode 100644
index 0000000..358833c
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_actions_item.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<!-- RelativeLayouts have an issue enforcing minimum heights, so just
+ work around this for now with LinearLayouts. -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="@dimen/global_actions_panel_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:orientation="vertical"
+ android:paddingBottom="24dip"
+ android:paddingEnd="8dip"
+ android:paddingStart="8dip"
+ android:paddingTop="24dip">
+
+ <ImageView
+ android:id="@*android:id/icon"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_gravity="center"
+ android:scaleType="center"/>
+
+ <TextView
+ android:id="@*android:id/message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|center_horizontal"
+ android:gravity="center"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ />
+
+ <TextView
+ android:id="@*android:id/status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|center_horizontal"
+ android:gravity="center"
+ android:minHeight="26dp"
+ android:textColor="?android:attr/textColorTertiary"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ />
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/global_actions_wrapped.xml b/packages/SystemUI/res/layout/global_actions_wrapped.xml
new file mode 100644
index 0000000..f409c03
--- /dev/null
+++ b/packages/SystemUI/res/layout/global_actions_wrapped.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.systemui.HardwareUiLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginBottom="0dp"
+ android:paddingTop="@dimen/global_actions_top_padding"
+ android:clipToPadding="false"
+ android:clipChildren="false">
+
+ <LinearLayout
+ android:id="@android:id/list"
+ android:layout_width="@dimen/global_actions_panel_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top|end"
+ android:layout_marginBottom="@dimen/volume_dialog_margin_bottom"
+ android:orientation="vertical"
+ android:paddingTop="@dimen/volume_dialog_padding_top"
+ android:divider="@null"
+ android:dividerHeight="0dp"
+ android:translationZ="8dp">
+
+ </LinearLayout>
+
+</com.android.systemui.HardwareUiLayout>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 18ffd0f..9076199 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -16,12 +16,12 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/volume_dialog"
- android:layout_width="match_parent"
+ android:layout_width="@dimen/volume_dialog_panel_width"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/volume_dialog_margin_bottom"
- android:background="@drawable/volume_dialog_background"
+ android:layout_gravity="center_vertical|end"
android:paddingTop="@dimen/volume_dialog_padding_top"
- android:translationZ="4dp" >
+ android:translationZ="8dp" >
<LinearLayout
android:id="@+id/volume_dialog_content"
@@ -57,6 +57,7 @@
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
+ android:visibility="gone"
android:textAppearance="@style/TextAppearance.Volume.Header" />
<com.android.keyguard.AlphaOptimizedImageButton
xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/packages/SystemUI/res/layout/volume_dialog_wrapped.xml b/packages/SystemUI/res/layout/volume_dialog_wrapped.xml
new file mode 100644
index 0000000..57489fd
--- /dev/null
+++ b/packages/SystemUI/res/layout/volume_dialog_wrapped.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<com.android.systemui.HardwareUiLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginTop="@dimen/top_padding"
+ android:layout_marginBottom="@dimen/bottom_padding">
+
+ <include layout="@layout/volume_dialog"/>
+
+</com.android.systemui.HardwareUiLayout>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index a98afa9..2f5f727 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -208,8 +208,6 @@
<!-- 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_width">@dimen/standard_notification_panel_width</dimen>
-
<!-- Gravity for the notification panel -->
<integer name="notification_panel_layout_gravity">0x31</integer><!-- center_horizontal|top -->
@@ -780,4 +778,15 @@
<dimen name="signal_icon_size">17dp</dimen>
+ <dimen name="hwui_edge_margin">16dp</dimen>
+
+ <dimen name="volume_dialog_panel_width">315dp</dimen>
+ <dimen name="global_actions_panel_width">125dp</dimen>
+
+ <dimen name="global_actions_top_padding">100dp</dimen>
+
+ <dimen name="corner_size">16dp</dimen>
+ <dimen name="top_padding">0dp</dimen>
+ <dimen name="bottom_padding">48dp</dimen>
+ <dimen name="edge_margin">16dp</dimen>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
new file mode 100644
index 0000000..6417e29
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/HardwareBgDrawable.java
@@ -0,0 +1,114 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.util.Log;
+
+public class HardwareBgDrawable extends LayerDrawable {
+
+ private final Paint mPaint = new Paint();
+ private final Drawable[] mLayers;
+ private final boolean mRoundTop;
+ private int mPoint;
+ private boolean mRotatedBackground;
+
+ public HardwareBgDrawable(boolean roundTop, boolean roundEnd, Context context) {
+ this(roundTop, getLayers(context, roundTop, roundEnd));
+ }
+
+ public HardwareBgDrawable(boolean roundTop, Drawable[] layers) {
+ super(layers);
+ if (layers.length != 2) {
+ throw new IllegalArgumentException("Need 2 layers");
+ }
+ mRoundTop = roundTop;
+ mLayers = layers;
+ mLayers[1].setTint(0xffeeeeee);
+ }
+
+ private static Drawable[] getLayers(Context context, boolean roundTop, boolean roundEnd) {
+ int drawable = roundEnd ? R.drawable.rounded_bg_full : R.drawable.rounded_bg;
+ if (roundTop) {
+ return new Drawable[]{
+ context.getDrawable(drawable).mutate(),
+ context.getDrawable(drawable).mutate(),
+ };
+ }
+ return new Drawable[]{
+ context.getDrawable(drawable).mutate(),
+ context.getDrawable(roundEnd ? R.drawable.rounded_full_bg_bottom
+ : R.drawable.rounded_bg_bottom).mutate(),
+ };
+ }
+
+ public void setCutPoint(int point) {
+ mPoint = point;
+ invalidateSelf();
+ }
+
+ public int getCutPoint() {
+ return mPoint;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ if (mPoint >= 0 && !mRotatedBackground) {
+ Rect bounds = getBounds();
+ int top = bounds.top + mPoint;
+ if (top > bounds.bottom) top = bounds.bottom;
+ if (mRoundTop) {
+ mLayers[0].setBounds(bounds.left, bounds.top, bounds.right, top);
+ } else {
+ mLayers[1].setBounds(bounds.left, top, bounds.right, bounds.bottom);
+ }
+ if (mRoundTop) {
+ mLayers[1].draw(canvas);
+ mLayers[0].draw(canvas);
+ } else {
+ mLayers[0].draw(canvas);
+ mLayers[1].draw(canvas);
+ }
+ } else {
+ mLayers[0].draw(canvas);
+ }
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ mPaint.setAlpha(alpha);
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ mPaint.setColorFilter(colorFilter);
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.OPAQUE;
+ }
+
+ public void setRotatedBackground(boolean rotatedBackground) {
+ mRotatedBackground = rotatedBackground;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
new file mode 100644
index 0000000..bb0f2f9
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
@@ -0,0 +1,383 @@
+/*
+ * 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;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.provider.Settings;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
+import android.view.ViewTreeObserver;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+public class HardwareUiLayout extends FrameLayout implements Tunable {
+
+ private static final String EDGE_BLEED = "sysui_hwui_edge_bleed";
+ private static final String ROUNDED_DIVIDER = "sysui_hwui_rounded_divider";
+ private final int[] mTmp2 = new int[2];
+ private View mChild;
+ private int mOldHeight;
+ private boolean mAnimating;
+ private AnimatorSet mAnimation;
+ private View mDivision;
+ private boolean mHasOutsideTouch;
+ private HardwareBgDrawable mBackground;
+ private Animator mAnimator;
+ private boolean mCollapse;
+ private int mEndPoint;
+ private boolean mEdgeBleed;
+ private boolean mRoundedDivider;
+ private boolean mLandscape;
+ private boolean mRotatedBackground;
+
+ public HardwareUiLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ updateSettings();
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ updateSettings();
+ Dependency.get(TunerService.class).addTunable(this, EDGE_BLEED, ROUNDED_DIVIDER);
+ getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsListener);
+ Dependency.get(TunerService.class).removeTunable(this);
+ }
+
+ @Override
+ public void onTuningChanged(String key, String newValue) {
+ updateSettings();
+ }
+
+ private void updateSettings() {
+ mEdgeBleed = Settings.Secure.getInt(getContext().getContentResolver(),
+ EDGE_BLEED, 0) != 0;
+ mRoundedDivider = Settings.Secure.getInt(getContext().getContentResolver(),
+ ROUNDED_DIVIDER, 1) != 0;
+ updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
+ mBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed, getContext());
+ if (mChild != null) {
+ mChild.setBackground(mBackground);
+ requestLayout();
+ }
+ }
+
+ private void updateEdgeMargin(int edge) {
+ if (mChild != null) {
+ MarginLayoutParams params = (MarginLayoutParams) mChild.getLayoutParams();
+ if (mLandscape) {
+ params.topMargin = edge;
+ } else {
+ params.rightMargin = edge;
+ }
+ mChild.setLayoutParams(params);
+ }
+ }
+
+ private int getEdgePadding() {
+ return getContext().getResources().getDimensionPixelSize(R.dimen.edge_margin);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ if (mChild == null) {
+ if (getChildCount() != 0) {
+ mChild = getChildAt(0);
+ mChild.setBackground(mBackground);
+ updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
+ mOldHeight = mChild.getMeasuredHeight();
+ mChild.addOnLayoutChangeListener(
+ (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+ updatePosition());
+ } else {
+ return;
+ }
+ }
+ int newHeight = mChild.getMeasuredHeight();
+ if (newHeight != mOldHeight) {
+ animateChild(mOldHeight, newHeight);
+ }
+ post(() -> updatePosition());
+ boolean landscape = getMeasuredWidth() > getMeasuredHeight();
+ if (landscape != mLandscape) {
+ mLandscape = landscape;
+ if (mLandscape) {
+ toLandscape();
+ if (mChild instanceof LinearLayout) {
+ mRotatedBackground = true;
+ mBackground.setRotatedBackground(true);
+ ((LinearLayout) mChild).setOrientation(LinearLayout.HORIZONTAL);
+ swapDimens(mChild);
+ }
+ } else {
+ fromLandscape();
+ if (mChild instanceof LinearLayout) {
+ mRotatedBackground = false;
+ mBackground.setRotatedBackground(false);
+ ((LinearLayout) mChild).setOrientation(LinearLayout.VERTICAL);
+ swapDimens(mChild);
+ }
+ }
+ }
+ }
+
+ private void fromLandscape() {
+ rotateRight(this);
+ rotateRight(mChild);
+ swapDimens(this);
+
+ LayoutParams p = (LayoutParams) mChild.getLayoutParams();
+ p.gravity = rotateGravityRight(p.gravity);
+ mChild.setLayoutParams(p);
+ }
+
+ private void swapDimens(View v) {
+ ViewGroup.LayoutParams params = v.getLayoutParams();
+ int h = params.width;
+ params.width = params.height;
+ params.height = h;
+ v.setLayoutParams(params);
+ }
+
+ private int rotateGravityRight(int gravity) {
+ int retGravity = 0;
+ int layoutDirection = getLayoutDirection();
+ final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
+ final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+
+ switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+ case Gravity.CENTER_HORIZONTAL:
+ retGravity |= Gravity.CENTER_VERTICAL;
+ break;
+ case Gravity.RIGHT:
+ retGravity |= Gravity.BOTTOM;
+ break;
+ case Gravity.LEFT:
+ default:
+ retGravity |= Gravity.TOP;
+ break;
+ }
+
+ switch (verticalGravity) {
+ case Gravity.CENTER_VERTICAL:
+ retGravity |= Gravity.CENTER_HORIZONTAL;
+ break;
+ case Gravity.BOTTOM:
+ retGravity |= Gravity.LEFT;
+ break;
+ case Gravity.TOP:
+ default:
+ retGravity |= Gravity.RIGHT;
+ break;
+ }
+ return retGravity;
+ }
+
+ private void toLandscape() {
+ rotateLeft(this);
+ rotateLeft(mChild);
+ swapDimens(this);
+
+ LayoutParams p = (LayoutParams) mChild.getLayoutParams();
+ p.gravity = rotateGravityLeft(p.gravity);
+ mChild.setLayoutParams(p);
+ }
+
+ private int rotateGravityLeft(int gravity) {
+ if (gravity == -1) {
+ gravity = Gravity.TOP | Gravity.START;
+ }
+ int retGravity = 0;
+ int layoutDirection = getLayoutDirection();
+ final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
+ final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+
+ switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
+ case Gravity.CENTER_HORIZONTAL:
+ retGravity |= Gravity.CENTER_VERTICAL;
+ break;
+ case Gravity.RIGHT:
+ retGravity |= Gravity.TOP;
+ break;
+ case Gravity.LEFT:
+ default:
+ retGravity |= Gravity.BOTTOM;
+ break;
+ }
+
+ switch (verticalGravity) {
+ case Gravity.CENTER_VERTICAL:
+ retGravity |= Gravity.CENTER_HORIZONTAL;
+ break;
+ case Gravity.BOTTOM:
+ retGravity |= Gravity.RIGHT;
+ break;
+ case Gravity.TOP:
+ default:
+ retGravity |= Gravity.LEFT;
+ break;
+ }
+ return retGravity;
+ }
+
+ private void rotateLeft(View v) {
+ v.setPadding(v.getPaddingTop(), v.getPaddingRight(), v.getPaddingBottom(),
+ v.getPaddingLeft());
+ MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
+ params.setMargins(params.topMargin, params.rightMargin, params.bottomMargin,
+ params.leftMargin);
+ v.setLayoutParams(params);
+ }
+
+ private void rotateRight(View v) {
+ v.setPadding(v.getPaddingBottom(), v.getPaddingLeft(), v.getPaddingTop(),
+ v.getPaddingRight());
+ MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
+ params.setMargins(params.bottomMargin, params.leftMargin, params.topMargin,
+ params.rightMargin);
+ v.setLayoutParams(params);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ post(() -> updatePosition());
+ }
+
+ private void animateChild(int oldHeight, int newHeight) {
+ if (true) return;
+ if (mAnimating) {
+ mAnimation.cancel();
+ }
+ mAnimating = true;
+ mAnimation = new AnimatorSet();
+ mAnimation.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mAnimating = false;
+ }
+ });
+ int fromTop = mChild.getTop();
+ int fromBottom = mChild.getBottom();
+ int toTop = fromTop - ((newHeight - oldHeight) / 2);
+ int toBottom = fromBottom + ((newHeight - oldHeight) / 2);
+ ObjectAnimator top = ObjectAnimator.ofInt(mChild, "top", fromTop, toTop);
+ top.addUpdateListener(animation -> mBackground.invalidateSelf());
+ mAnimation.playTogether(top,
+ ObjectAnimator.ofInt(mChild, "bottom", fromBottom, toBottom));
+ }
+
+ public void setDivisionView(View v) {
+ mDivision = v;
+ if (mDivision != null) {
+ mDivision.addOnLayoutChangeListener(
+ (v1, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+ updatePosition());
+ }
+ updatePosition();
+ }
+
+ private void updatePosition() {
+ if (mChild == null) return;
+ if (mDivision != null && mDivision.getVisibility() == VISIBLE) {
+ int index = mRotatedBackground ? 0 : 1;
+ mDivision.getLocationOnScreen(mTmp2);
+ float trans = mRotatedBackground ? mDivision.getTranslationX()
+ : mDivision.getTranslationY();
+ int viewTop = (int) (mTmp2[index] + trans);
+ mChild.getLocationOnScreen(mTmp2);
+ viewTop -= mTmp2[index];
+ setCutPoint(viewTop);
+ } else {
+ setCutPoint(mChild.getMeasuredHeight());
+ }
+ }
+
+ private void setCutPoint(int point) {
+ int curPoint = mBackground.getCutPoint();
+ if (curPoint == point) return;
+ if (getAlpha() == 0 || curPoint == 0) {
+ mBackground.setCutPoint(point);
+ return;
+ }
+ if (mAnimator != null) {
+ if (mEndPoint == point) {
+ return;
+ }
+ mAnimator.cancel();
+ }
+ mEndPoint = point;
+ mAnimator = ObjectAnimator.ofInt(mBackground, "cutPoint", curPoint, point);
+ if (mCollapse) {
+ mAnimator.setStartDelay(300);
+ mCollapse = false;
+ }
+ mAnimator.start();
+ }
+
+ @Override
+ public ViewOutlineProvider getOutlineProvider() {
+ return super.getOutlineProvider();
+ }
+
+ public void setOutsideTouchListener(OnClickListener onClickListener) {
+ mHasOutsideTouch = true;
+ requestLayout();
+ setOnClickListener(onClickListener);
+ setClickable(true);
+ setFocusable(true);
+ }
+
+ public void setCollapse() {
+ mCollapse = true;
+ }
+
+ public static HardwareUiLayout get(View v) {
+ if (v instanceof HardwareUiLayout) return (HardwareUiLayout) v;
+ if (v.getParent() instanceof View) {
+ return get((View) v.getParent());
+ }
+ return null;
+ }
+
+ private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> {
+ if (mHasOutsideTouch || (mChild == null)) {
+ inoutInfo.setTouchableInsets(
+ ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
+ return;
+ }
+ inoutInfo.setTouchableInsets(
+ ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT);
+ inoutInfo.contentInsets.set(mChild.getLeft(), mChild.getTop(),
+ 0, getBottom() - mChild.getBottom());
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 206342e..4af21eb 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -15,15 +15,16 @@
package com.android.systemui.globalactions;
import com.android.internal.R;
-import com.android.internal.app.AlertController;
-import com.android.internal.app.AlertController.AlertParams;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.EmergencyAffordanceManager;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.HardwareUiLayout;
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
+import com.android.systemui.volume.VolumeDialogMotion.LogAccelerateInterpolator;
+import com.android.systemui.volume.VolumeDialogMotion.LogDecelerateInterpolator;
import android.app.ActivityManager;
import android.app.Dialog;
@@ -34,11 +35,13 @@
import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
+import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.os.Build;
-import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
@@ -56,8 +59,6 @@
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
-import android.util.TypedValue;
-import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -65,10 +66,11 @@
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
-import android.widget.ListView;
+import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
@@ -79,7 +81,7 @@
* may show depending on whether the keyguard is showing, and whether the device
* is provisioned.
*/
-class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener {
+class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener {
static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
@@ -162,6 +164,7 @@
/**
* Show the global actions dialog (creating if necessary)
+ *
* @param keyguardShowing True if keyguard is showing
*/
public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {
@@ -205,12 +208,14 @@
mDialog.getWindow().setAttributes(attrs);
mDialog.show();
mWindowManagerFuncs.onGlobalActionsShown();
- mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
+ mDialog.getWindow().getDecorView().setSystemUiVisibility(
+ View.STATUS_BAR_DISABLE_EXPAND);
}
}
/**
* Create the global actions dialog.
+ *
* @return A new dialog.
*/
private ActionsDialog createDialog() {
@@ -314,28 +319,19 @@
mAdapter = new MyAdapter();
- AlertParams params = new AlertParams(mContext);
- params.mAdapter = mAdapter;
- params.mOnClickListener = this;
- params.mForceInverseBackground = true;
-
- ActionsDialog dialog = new ActionsDialog(mContext, params);
+ OnItemLongClickListener onItemLongClickListener = new OnItemLongClickListener() {
+ @Override
+ public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
+ long id) {
+ final Action action = mAdapter.getItem(position);
+ if (action instanceof LongPressAction) {
+ return ((LongPressAction) action).onLongPress();
+ }
+ return false;
+ }
+ };
+ ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener);
dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
-
- dialog.getListView().setItemsCanFocus(true);
- dialog.getListView().setLongClickable(true);
- dialog.getListView().setOnItemLongClickListener(
- new AdapterView.OnItemLongClickListener() {
- @Override
- public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
- long id) {
- final Action action = mAdapter.getItem(position);
- if (action instanceof LongPressAction) {
- return ((LongPressAction) action).onLongPress();
- }
- return false;
- }
- });
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
dialog.setOnDismissListener(this);
@@ -346,7 +342,7 @@
private final class PowerAction extends SinglePressAction implements LongPressAction {
private PowerAction() {
super(R.drawable.ic_lock_power_off,
- R.string.global_action_power_off);
+ R.string.global_action_power_off);
}
@Override
@@ -614,7 +610,7 @@
SinglePressAction switchToUser = new SinglePressAction(
R.drawable.ic_menu_cc, icon,
(user.name != null ? user.name : "Primary")
- + (isCurrentUser ? " \u2714" : "")) {
+ + (isCurrentUser ? " \u2714" : "")) {
public void onPress() {
try {
ActivityManager.getService().switchUser(user.id);
@@ -652,7 +648,7 @@
if (!mHasVibrator) {
final boolean silentModeOn =
mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
- ((ToggleAction)mSilentModeAction).updateState(
+ ((ToggleAction) mSilentModeAction).updateState(
silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off);
}
}
@@ -681,7 +677,8 @@
/**
* The adapter used for the list within the global actions dialog, taking
* into account whether the keyguard is showing via
- * {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing} and whether the device is provisioned
+ * {@link com.android.systemui.globalactions.GlobalActionsDialog#mKeyguardShowing} and whether
+ * the device is provisioned
* via {@link com.android.systemui.globalactions.GlobalActionsDialog#mDeviceProvisioned}.
*/
private class MyAdapter extends BaseAdapter {
@@ -744,7 +741,11 @@
public View getView(int position, View convertView, ViewGroup parent) {
Action action = getItem(position);
- return action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
+ View view = action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
+ if (position == 2) {
+ HardwareUiLayout.get(parent).setDivisionView(view);
+ }
+ return view;
}
}
@@ -760,7 +761,7 @@
private interface Action {
/**
* @return Text that will be announced when dialog is created. null
- * for none.
+ * for none.
*/
CharSequence getLabelForAccessibility(Context context);
@@ -770,13 +771,13 @@
/**
* @return whether this action should appear in the dialog when the keygaurd
- * is showing.
+ * is showing.
*/
boolean showDuringKeyguard();
/**
* @return whether this action should appear in the dialog before the
- * device is provisioned.
+ * device is provisioned.
*/
boolean showBeforeProvisioning();
@@ -834,7 +835,8 @@
public View create(
Context context, View convertView, ViewGroup parent, LayoutInflater inflater) {
- View v = inflater.inflate(R.layout.global_actions_item, parent, false);
+ View v = inflater.inflate(com.android.systemui.R.layout.global_actions_item, parent,
+ false);
ImageView icon = (ImageView) v.findViewById(R.id.icon);
TextView messageView = (TextView) v.findViewById(R.id.message);
@@ -895,10 +897,10 @@
protected int mDisabledStatusMessageResId;
/**
- * @param enabledIconResId The icon for when this action is on.
- * @param disabledIconResid The icon for when this action is off.
- * @param message The general information message, e.g 'Silent Mode'
- * @param enabledStatusMessageResId The on status message, e.g 'sound disabled'
+ * @param enabledIconResId The icon for when this action is on.
+ * @param disabledIconResid The icon for when this action is off.
+ * @param message The general information message, e.g 'Silent Mode'
+ * @param enabledStatusMessageResId The on status message, e.g 'sound disabled'
* @param disabledStatusMessageResId The off status message, e.g. 'sound enabled'
*/
public ToggleAction(int enabledIconResId,
@@ -931,7 +933,7 @@
willCreate();
View v = inflater.inflate(R
- .layout.global_actions_item, parent, false);
+ .layout.global_actions_item, parent, false);
ImageView icon = (ImageView) v.findViewById(R.id.icon);
TextView messageView = (TextView) v.findViewById(R.id.message);
@@ -979,6 +981,7 @@
* Implementations may override this if their state can be in on of the intermediate
* states until some notification is received (e.g airplane mode is 'turning off' until
* we know the wireless connections are back online
+ *
* @param buttonOn Whether the button was turned on or off
*/
protected void changeStateFromPress(boolean buttonOn) {
@@ -1020,7 +1023,7 @@
private static class SilentModeTriStateAction implements Action, View.OnClickListener {
- private final int[] ITEM_IDS = { R.id.option1, R.id.option2, R.id.option3 };
+ private final int[] ITEM_IDS = {R.id.option1, R.id.option2, R.id.option3};
private final AudioManager mAudioManager;
private final Handler mHandler;
@@ -1145,19 +1148,19 @@
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
- case MESSAGE_DISMISS:
- if (mDialog != null) {
- mDialog.dismiss();
- mDialog = null;
- }
- break;
- case MESSAGE_REFRESH:
- refreshSilentMode();
- mAdapter.notifyDataSetChanged();
- break;
- case MESSAGE_SHOW:
- handleShow();
- break;
+ case MESSAGE_DISMISS:
+ if (mDialog != null) {
+ mDialog.dismiss();
+ mDialog = null;
+ }
+ break;
+ case MESSAGE_REFRESH:
+ refreshSilentMode();
+ mAdapter.notifyDataSetChanged();
+ break;
+ case MESSAGE_SHOW:
+ handleShow();
+ break;
}
}
};
@@ -1192,39 +1195,81 @@
}
private static final class ActionsDialog extends Dialog implements DialogInterface {
- private final Context mContext;
- private final AlertController mAlert;
- private final MyAdapter mAdapter;
- public ActionsDialog(Context context, AlertParams params) {
- super(context, getDialogTheme(context));
+ private final Context mContext;
+ private final MyAdapter mAdapter;
+ private final LinearLayout mListView;
+ private final HardwareUiLayout mHardwareLayout;
+ private final OnClickListener mClickListener;
+ private final OnItemLongClickListener mLongClickListener;
+
+ public ActionsDialog(Context context, OnClickListener clickListener, MyAdapter adapter,
+ OnItemLongClickListener longClickListener) {
+ super(context, android.R.style.Theme_DeviceDefault_Light_NoActionBar_Fullscreen);
mContext = getContext();
- mAlert = AlertController.create(mContext, this, getWindow());
- mAdapter = (MyAdapter) params.mAdapter;
- params.apply(mAlert);
+ mAdapter = adapter;
+ mClickListener = clickListener;
+ mLongClickListener = longClickListener;
+ setContentView(com.android.systemui.R.layout.global_actions_wrapped);
+ getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ mListView = findViewById(android.R.id.list);
+ mHardwareLayout = HardwareUiLayout.get(mListView);
+ mHardwareLayout.setOutsideTouchListener(view -> dismiss());
}
- private static int getDialogTheme(Context context) {
- TypedValue outValue = new TypedValue();
- context.getTheme().resolveAttribute(R.attr.alertDialogTheme,
- outValue, true);
- return outValue.resourceId;
+ private void updateList() {
+ mListView.removeAllViews();
+ for (int i = 0; i < mAdapter.getCount(); i++) {
+ View v = mAdapter.getView(i, null, mListView);
+ final int pos = i;
+ v.setOnClickListener(view -> mClickListener.onClick(this, pos));
+ v.setOnLongClickListener(view ->
+ mLongClickListener.onItemLongClick(null, v, pos, 0));
+ mListView.addView(v);
+ }
}
@Override
protected void onStart() {
super.setCanceledOnTouchOutside(true);
super.onStart();
- }
-
- public ListView getListView() {
- return mAlert.getListView();
+ updateList();
}
@Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mAlert.installContent();
+ protected void onStop() {
+ super.onStop();
+ }
+
+ @Override
+ public void show() {
+ super.show();
+ mHardwareLayout.setTranslationX(getAnimTranslation());
+ mHardwareLayout.setAlpha(0);
+ mHardwareLayout.animate()
+ .alpha(1)
+ .translationX(0)
+ .setDuration(300)
+ .setInterpolator(new LogDecelerateInterpolator())
+ .start();
+ }
+
+ @Override
+ public void dismiss() {
+ mHardwareLayout.setTranslationX(0);
+ mHardwareLayout.setAlpha(1);
+ mHardwareLayout.animate()
+ .alpha(0)
+ .translationX(getAnimTranslation())
+ .setDuration(300)
+ .withEndAction(() -> super.dismiss())
+ .setInterpolator(new LogAccelerateInterpolator())
+ .start();
+ }
+
+ private float getAnimTranslation() {
+ return getContext().getResources().getDimension(
+ com.android.systemui.R.dimen.global_actions_panel_width) / 2;
}
@Override
@@ -1240,21 +1285,5 @@
}
return super.dispatchPopulateAccessibilityEvent(event);
}
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (mAlert.onKeyDown(keyCode, event)) {
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
-
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (mAlert.onKeyUp(keyCode, event)) {
- return true;
- }
- return super.onKeyUp(keyCode, event);
- }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index b8b046b..1f674e0 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -18,6 +18,7 @@
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.animation.ObjectAnimator;
@@ -59,6 +60,7 @@
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.Window;
import android.view.WindowManager;
@@ -73,6 +75,7 @@
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.VolumeDialogController;
@@ -199,53 +202,37 @@
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
mDialog.setCanceledOnTouchOutside(true);
final Resources res = mContext.getResources();
- final WindowManager.LayoutParams lp = mWindow.getAttributes();
- lp.type = mWindowType;
- lp.format = PixelFormat.TRANSLUCENT;
- lp.setTitle(VolumeDialogImpl.class.getSimpleName());
- lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
- lp.y = res.getDimensionPixelSize(R.dimen.volume_offset_top);
- lp.gravity = Gravity.TOP;
- lp.windowAnimations = -1;
- mWindow.setAttributes(lp);
mWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
- mDialog.setContentView(R.layout.volume_dialog);
- mDialogView = (ViewGroup) mDialog.findViewById(R.id.volume_dialog);
- mDialogView.setOnHoverListener(new View.OnHoverListener() {
- @Override
- public boolean onHover(View v, MotionEvent event) {
- int action = event.getActionMasked();
- mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
- || (action == MotionEvent.ACTION_HOVER_MOVE);
- rescheduleTimeoutH();
- return true;
- }
+ mDialog.setContentView(R.layout.volume_dialog_wrapped);
+ mDialogView = mDialog.findViewById(R.id.volume_dialog);
+ mDialogView.setOnHoverListener((v, event) -> {
+ int action = event.getActionMasked();
+ mHovering = (action == MotionEvent.ACTION_HOVER_ENTER)
+ || (action == MotionEvent.ACTION_HOVER_MOVE);
+ rescheduleTimeoutH();
+ return true;
});
- mDialogContentView = (ViewGroup) mDialog.findViewById(R.id.volume_dialog_content);
- mDialogRowsView = (ViewGroup) mDialogContentView.findViewById(R.id.volume_dialog_rows);
+ mDialogContentView = mDialog.findViewById(R.id.volume_dialog_content);
+ mDialogRowsView = mDialogContentView.findViewById(R.id.volume_dialog_rows);
mExpanded = false;
- mExpandButton = (ImageButton) mDialogView.findViewById(R.id.volume_expand_button);
+ mExpandButton = mDialogView.findViewById(R.id.volume_expand_button);
mExpandButton.setOnClickListener(mClickExpand);
mExpandButton.setVisibility(
AudioSystem.isSingleVolume(mContext) ? View.GONE : View.VISIBLE);
- updateWindowWidthH();
updateExpandButtonH();
- 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;
- }
+ mMotion = new VolumeDialogMotion(mDialog, (View) mDialogView.getParent(),
+ mDialogContentView, mExpandButton, animating -> {
+ if (animating) return;
+ if (mPendingStateChanged) {
+ mHandler.sendEmptyMessage(H.STATE_CHANGED);
+ mPendingStateChanged = false;
+ }
+ if (mPendingRecheckAll) {
+ mHandler.sendEmptyMessage(H.RECHECK_ALL);
+ mPendingRecheckAll = false;
}
});
@@ -270,11 +257,20 @@
addExistingRows();
}
mExpandButtonAnimationDuration = res.getInteger(R.integer.volume_expand_animation_duration);
- mZenFooter = (ZenFooter) mDialog.findViewById(R.id.volume_zen_footer);
+ mZenFooter = mDialog.findViewById(R.id.volume_zen_footer);
mZenFooter.init(mZenModeController);
- mZenPanel = (TunerZenModePanel) mDialog.findViewById(R.id.tuner_zen_mode_panel);
+ mZenPanel = mDialog.findViewById(R.id.tuner_zen_mode_panel);
mZenPanel.init(mZenModeController);
mZenPanel.setCallback(mZenPanelCallback);
+
+ final WindowManager.LayoutParams lp = mWindow.getAttributes();
+ lp.width = MATCH_PARENT;
+ lp.height = MATCH_PARENT;
+ lp.type = mWindowType;
+ lp.format = PixelFormat.TRANSLUCENT;
+ lp.setTitle(VolumeDialogImpl.class.getSimpleName());
+ lp.windowAnimations = -1;
+ mWindow.setAttributes(lp);
}
@Override
@@ -288,20 +284,6 @@
return ColorStateList.valueOf(mContext.getColor(colorResId));
}
- private void updateWindowWidthH() {
- final ViewGroup.LayoutParams lp = mDialogView.getLayoutParams();
- final DisplayMetrics dm = mContext.getResources().getDisplayMetrics();
- if (D.BUG) Log.d(TAG, "updateWindowWidth dm.w=" + dm.widthPixels);
- int w = dm.widthPixels;
- final int max = mContext.getResources()
- .getDimensionPixelSize(R.dimen.volume_dialog_panel_width);
- if (w > max) {
- w = max;
- }
- lp.width = w;
- mDialogView.setLayoutParams(lp);
- }
-
public void setStreamImportant(int stream, boolean important) {
mHandler.obtainMessage(H.SET_STREAM_IMPORTANT, stream, important ? 1 : 0).sendToTarget();
}
@@ -542,10 +524,8 @@
}
private void updateDialogBottomMarginH() {
- final long diff = System.currentTimeMillis() - mCollapseTime;
- final boolean collapsing = mCollapseTime != 0 && diff < getConservativeCollapseDuration();
final ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) mDialogView.getLayoutParams();
- final int bottomMargin = collapsing ? mDialogContentView.getHeight() :
+ final int bottomMargin =
mContext.getResources().getDimensionPixelSize(R.dimen.volume_dialog_margin_bottom);
if (bottomMargin != mlp.bottomMargin) {
if (D.BUG) Log.d(TAG, "bottomMargin " + mlp.bottomMargin + " -> " + bottomMargin);
@@ -575,7 +555,7 @@
TransitionManager.endTransitions(mDialogView);
final VolumeRow activeRow = getActiveRow();
if (!dismissing) {
- mWindow.setLayout(mWindow.getAttributes().width, ViewGroup.LayoutParams.MATCH_PARENT);
+ mWindow.setLayout(mWindow.getAttributes().width, MATCH_PARENT);
TransitionManager.beginDelayedTransition(mDialogView, getTransistion());
}
updateRowsH(activeRow);
@@ -637,7 +617,7 @@
final boolean isActive = row == activeRow;
final boolean shouldBeVisible = shouldBeVisibleH(row, isActive);
Util.setVisOrGone(row.view, shouldBeVisible);
- Util.setVisOrGone(row.header, shouldBeVisible);
+ Util.setVisOrGone(row.header, shouldBeVisible && mExpanded);
if (row.view.isShown()) {
updateVolumeRowSliderTintH(row, isActive);
}
@@ -699,6 +679,16 @@
if (wasVisible != visible && !visible) {
prepareForCollapse();
}
+ if (visible != wasVisible) {
+ if (visible) {
+ HardwareUiLayout.get(mZenFooter).setDivisionView(mZenFooter);
+ } else {
+ mHandler.postDelayed(() ->
+ HardwareUiLayout.get(mZenFooter).setDivisionView(mZenFooter),
+ mExpandButtonAnimationDuration);
+ }
+
+ }
Util.setVisOrGone(mZenFooter, visible);
mZenFooter.update();
@@ -962,8 +952,7 @@
@Override
public void onTransitionEnd(Transition transition) {
- mWindow.setLayout(
- mWindow.getAttributes().width, ViewGroup.LayoutParams.WRAP_CONTENT);
+ mWindow.setLayout(MATCH_PARENT, MATCH_PARENT);
}
@Override
@@ -972,8 +961,7 @@
@Override
public void onTransitionPause(Transition transition) {
- mWindow.setLayout(
- mWindow.getAttributes().width, ViewGroup.LayoutParams.WRAP_CONTENT);
+ mWindow.setLayout(MATCH_PARENT, MATCH_PARENT);
}
@Override
@@ -1025,7 +1013,6 @@
initDialog();
mDensity = density;
}
- updateWindowWidthH();
mConfigurableTexts.update();
mZenFooter.onConfigurationChanged();
}
@@ -1081,6 +1068,9 @@
if (mExpandButtonAnimationRunning) return;
final boolean newExpand = !mExpanded;
Events.writeEvent(mContext, Events.EVENT_EXPAND, newExpand);
+ if (!newExpand) {
+ HardwareUiLayout.get(mDialogContentView).setCollapse();
+ }
updateExpandedH(newExpand, false /* dismissing */);
}
};
@@ -1156,8 +1146,8 @@
event.setPackageName(mContext.getPackageName());
ViewGroup.LayoutParams params = getWindow().getAttributes();
- boolean isFullScreen = (params.width == ViewGroup.LayoutParams.MATCH_PARENT) &&
- (params.height == ViewGroup.LayoutParams.MATCH_PARENT);
+ boolean isFullScreen = (params.width == MATCH_PARENT) &&
+ (params.height == MATCH_PARENT);
event.setFullScreen(isFullScreen);
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
index d6d0f75..8afd91d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogMotion.java
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.android.systemui.volume;
import android.animation.Animator;
@@ -67,8 +66,8 @@
@Override
public void onShow(DialogInterface dialog) {
if (D.BUG) Log.d(TAG, "mDialog.onShow");
- final int h = mDialogView.getHeight();
- mDialogView.setTranslationY(-h);
+ final int w = mDialogView.getWidth() / 4;
+ mDialogView.setTranslationX(w);
startShowAnimation();
}
});
@@ -117,7 +116,7 @@
}
private int chevronDistance() {
- return mChevron.getHeight() / 6;
+ return 0;
}
private int chevronPosY() {
@@ -128,7 +127,9 @@
private void startShowAnimation() {
if (D.BUG) Log.d(TAG, "startShowAnimation");
mDialogView.animate()
+ .translationX(0)
.translationY(0)
+ .alpha(1)
.setDuration(scaledDuration(300))
.setInterpolator(new LogDecelerateInterpolator())
.setListener(null)
@@ -139,7 +140,6 @@
// reposition chevron
final float v = (Float) mChevronPositionAnimator.getAnimatedValue();
final int posY = chevronPosY();
- mChevron.setTranslationY(posY + v + -mDialogView.getTranslationY());
}
})
.withEndAction(new Runnable() {
@@ -148,7 +148,6 @@
if (mChevronPositionAnimator == null) return;
// reposition chevron
final int posY = chevronPosY();
- mChevron.setTranslationY(posY + -mDialogView.getTranslationY());
}
})
.start();
@@ -164,19 +163,13 @@
if (D.BUG) Log.d(TAG, "show.onAnimationEnd");
setShowing(false);
}
+
@Override
public void onAnimationCancel(Animator animation) {
if (D.BUG) Log.d(TAG, "show.onAnimationCancel");
mCancelled = true;
}
});
- mContentsPositionAnimator.addUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- float v = (Float) animation.getAnimatedValue();
- mContents.setTranslationY(v + -mDialogView.getTranslationY());
- }
- });
mContentsPositionAnimator.setInterpolator(new LogDecelerateInterpolator());
mContentsPositionAnimator.start();
@@ -218,34 +211,26 @@
setShowing(false);
}
mDialogView.animate()
- .translationY(-mDialogView.getHeight())
+ .translationX(mDialogView.getWidth() / 4)
+ .alpha(0)
.setDuration(scaledDuration(250))
.setInterpolator(new LogAccelerateInterpolator())
- .setUpdateListener(new AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mContents.setTranslationY(-mDialogView.getTranslationY());
- final int posY = chevronPosY();
- mChevron.setTranslationY(posY + -mDialogView.getTranslationY());
- }
- })
.setListener(new AnimatorListenerAdapter() {
private boolean mCancelled;
+
@Override
public void onAnimationEnd(Animator animation) {
if (mCancelled) return;
if (D.BUG) Log.d(TAG, "dismiss.onAnimationEnd");
- mHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- if (D.BUG) Log.d(TAG, "mDialog.dismiss()");
- mDialog.dismiss();
- onComplete.run();
- setDismissing(false);
- }
+ mHandler.postDelayed(() -> {
+ if (D.BUG) Log.d(TAG, "mDialog.dismiss()");
+ mDialog.dismiss();
+ onComplete.run();
+ setDismissing(false);
}, PRE_DISMISS_DELAY);
}
+
@Override
public void onAnimationCancel(Animator animation) {
if (D.BUG) Log.d(TAG, "dismiss.onAnimationCancel");
@@ -258,13 +243,13 @@
return (int) (base * ANIMATION_SCALE);
}
- private static final class LogDecelerateInterpolator implements TimeInterpolator {
+ public static final class LogDecelerateInterpolator implements TimeInterpolator {
private final float mBase;
private final float mDrift;
private final float mTimeScale;
private final float mOutputScale;
- private LogDecelerateInterpolator() {
+ public LogDecelerateInterpolator() {
this(400f, 1.4f, 0);
}
@@ -286,12 +271,12 @@
}
}
- private static final class LogAccelerateInterpolator implements TimeInterpolator {
+ public static final class LogAccelerateInterpolator implements TimeInterpolator {
private final int mBase;
private final int mDrift;
private final float mLogScale;
- private LogAccelerateInterpolator() {
+ public LogAccelerateInterpolator() {
this(100, 0);
}