From fd27966b59a8d1d8c049083949086fd952186eb1 Mon Sep 17 00:00:00 2001 From: Jason Monk Date: Thu, 29 Jun 2017 19:37:48 -0400 Subject: [PATCH] Update power menu + dialog - Update power menu to handle seascape properly - Update shutting down dialog, the gradient is covered by the global actions dialog not going away completely, everything else is still in ShutdownThread. Test: visual Change-Id: I06a2fdd2652bf006dc5c0b45e3bc922e43093301 Fixes: 62391660 --- core/res/res/layout/shutdown_dialog.xml | 52 +++++++++++ core/res/res/values/symbols.xml | 1 + .../android/systemui/HardwareUiLayout.java | 93 ++++++++++++++----- .../globalactions/GlobalActionsDialog.java | 19 +++- .../recents/ScreenPinningRequest.java | 27 ++---- .../systemui/util/leak/RotationUtils.java | 39 ++++++++ .../android/server/power/ShutdownThread.java | 75 ++++++++++----- 7 files changed, 239 insertions(+), 67 deletions(-) create mode 100644 core/res/res/layout/shutdown_dialog.xml create mode 100644 packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java diff --git a/core/res/res/layout/shutdown_dialog.xml b/core/res/res/layout/shutdown_dialog.xml new file mode 100644 index 0000000000000..398bfb1824c77 --- /dev/null +++ b/core/res/res/layout/shutdown_dialog.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 99807f93834f2..50550a493fd78 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3058,4 +3058,5 @@ + diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java index bb0f2f9f3ac00..22bb2a3c8f5bf 100644 --- a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java +++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java @@ -19,6 +19,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; +import android.content.res.Configuration; import android.provider.Settings; import android.util.AttributeSet; import android.view.Gravity; @@ -28,9 +29,15 @@ 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; +import com.android.systemui.util.leak.RotationUtils; + +import java.util.ArrayList; + +import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE; public class HardwareUiLayout extends FrameLayout implements Tunable { @@ -49,7 +56,7 @@ public class HardwareUiLayout extends FrameLayout implements Tunable { private int mEndPoint; private boolean mEdgeBleed; private boolean mRoundedDivider; - private boolean mLandscape; + private int mRotation = ROTATION_NONE; private boolean mRotatedBackground; public HardwareUiLayout(Context context, AttributeSet attrs) { @@ -93,8 +100,10 @@ public class HardwareUiLayout extends FrameLayout implements Tunable { private void updateEdgeMargin(int edge) { if (mChild != null) { MarginLayoutParams params = (MarginLayoutParams) mChild.getLayoutParams(); - if (mLandscape) { + if (mRotation == ROTATION_LANDSCAPE) { params.topMargin = edge; + } else if (mRotation == ROTATION_SEASCAPE) { + params.bottomMargin = edge; } else { params.rightMargin = edge; } @@ -118,6 +127,7 @@ public class HardwareUiLayout extends FrameLayout implements Tunable { mChild.addOnLayoutChangeListener( (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> updatePosition()); + updateRotation(); } else { return; } @@ -127,30 +137,69 @@ public class HardwareUiLayout extends FrameLayout implements Tunable { 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); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + updateRotation(); + } + + private void updateRotation() { + int rotation = RotationUtils.getRotation(getContext()); + if (rotation != mRotation) { + rotate(mRotation, rotation); + mRotation = rotation; + } + } + + private void rotate(int from, int to) { + if (from != ROTATION_NONE && to != ROTATION_NONE) { + // Rather than handling this confusing case, just do 2 rotations. + rotate(from, ROTATION_NONE); + rotate(ROTATION_NONE, to); + return; + } + if (from == ROTATION_LANDSCAPE || to == ROTATION_SEASCAPE) { + rotateRight(); + } else { + rotateLeft(); + } + if (to != ROTATION_NONE) { + if (mChild instanceof LinearLayout) { + mRotatedBackground = true; + mBackground.setRotatedBackground(true); + LinearLayout linearLayout = (LinearLayout) mChild; + if (to == ROTATION_SEASCAPE) { + swapOrder(linearLayout); } - } else { - fromLandscape(); - if (mChild instanceof LinearLayout) { - mRotatedBackground = false; - mBackground.setRotatedBackground(false); - ((LinearLayout) mChild).setOrientation(LinearLayout.VERTICAL); - swapDimens(mChild); + linearLayout.setOrientation(LinearLayout.HORIZONTAL); + swapDimens(this.mChild); + } + } else { + if (mChild instanceof LinearLayout) { + mRotatedBackground = false; + mBackground.setRotatedBackground(false); + LinearLayout linearLayout = (LinearLayout) mChild; + if (from == ROTATION_SEASCAPE) { + swapOrder(linearLayout); } + linearLayout.setOrientation(LinearLayout.VERTICAL); + swapDimens(mChild); } } } - private void fromLandscape() { + private void swapOrder(LinearLayout linearLayout) { + ArrayList children = new ArrayList<>(); + for (int i = 0; i < linearLayout.getChildCount(); i++) { + children.add(0, linearLayout.getChildAt(i)); + linearLayout.removeViewAt(i); + } + children.forEach(v -> linearLayout.addView(v)); + } + + private void rotateRight() { rotateRight(this); rotateRight(mChild); swapDimens(this); @@ -202,7 +251,7 @@ public class HardwareUiLayout extends FrameLayout implements Tunable { return retGravity; } - private void toLandscape() { + private void rotateLeft() { rotateLeft(this); rotateLeft(mChild); swapDimens(this); diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 1a8a474a4187f..31d41acc3925e 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -682,10 +682,14 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogIn /** {@inheritDoc} */ public void onClick(DialogInterface dialog, int which) { - if (!(mAdapter.getItem(which) instanceof SilentModeTriStateAction)) { + Action item = mAdapter.getItem(which); + if ((item instanceof PowerAction) + || (item instanceof RestartAction)) { + if (mDialog != null) mDialog.fadeOut(); + } else if (!(item instanceof SilentModeTriStateAction)) { dialog.dismiss(); } - mAdapter.getItem(which).onPress(); + item.onPress(); } /** @@ -1321,6 +1325,17 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogIn .start(); } + public void fadeOut() { + mHardwareLayout.setTranslationX(0); + mHardwareLayout.setAlpha(1); + mListView.animate() + .alpha(0) + .translationX(getAnimTranslation()) + .setDuration(300) + .setInterpolator(new LogAccelerateInterpolator()) + .start(); + } + private float getAnimTranslation() { return getContext().getResources().getDimension( com.android.systemui.R.dimen.global_actions_panel_width) / 2; diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java index 521157dc59917..d74970face233 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java +++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java @@ -43,14 +43,14 @@ import android.widget.LinearLayout; import android.widget.TextView; import com.android.systemui.R; +import com.android.systemui.util.leak.RotationUtils; import java.util.ArrayList; -public class ScreenPinningRequest implements View.OnClickListener { +import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE; - private static final int ROTATION_NONE = 0; - private static final int ROTATION_LANDSCAPE = 1; - private static final int ROTATION_SEASCAPE = 2; +public class ScreenPinningRequest implements View.OnClickListener { private final Context mContext; @@ -160,7 +160,7 @@ public class ScreenPinningRequest implements View.OnClickListener { DisplayMetrics metrics = new DisplayMetrics(); mWindowManager.getDefaultDisplay().getMetrics(metrics); float density = metrics.density; - int rotation = getRotation(mContext); + int rotation = RotationUtils.getRotation(mContext); inflateView(rotation); int bgColor = mContext.getColor( @@ -202,19 +202,6 @@ public class ScreenPinningRequest implements View.OnClickListener { mContext.registerReceiver(mReceiver, filter); } - private int getRotation(Context context) { - Configuration config = mContext.getResources().getConfiguration(); - int rot = context.getDisplay().getRotation(); - if (config.smallestScreenWidthDp < 600) { - if (rot == Surface.ROTATION_90) { - return ROTATION_LANDSCAPE; - } else if (rot == Surface.ROTATION_270) { - return ROTATION_SEASCAPE; - } - } - return ROTATION_NONE; - } - private void inflateView(int rotation) { // We only want this landscape orientation on <600dp, so rather than handle // resource overlay for -land and -sw600dp-land, just inflate this @@ -287,14 +274,14 @@ public class ScreenPinningRequest implements View.OnClickListener { protected void onConfigurationChanged() { removeAllViews(); - inflateView(getRotation(mContext)); + inflateView(RotationUtils.getRotation(mContext)); } private final Runnable mUpdateLayoutRunnable = new Runnable() { @Override public void run() { if (mLayout != null && mLayout.getParent() != null) { - mLayout.setLayoutParams(getRequestLayoutParams(getRotation(mContext))); + mLayout.setLayoutParams(getRequestLayoutParams(RotationUtils.getRotation(mContext))); } } }; diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java b/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java new file mode 100644 index 0000000000000..ad20900097143 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java @@ -0,0 +1,39 @@ +/* + * 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.util.leak; + +import android.content.Context; +import android.content.res.Configuration; +import android.view.Surface; + +public class RotationUtils { + + public static final int ROTATION_NONE = 0; + public static final int ROTATION_LANDSCAPE = 1; + public static final int ROTATION_SEASCAPE = 2; + + public static int getRotation(Context context) { + Configuration config = context.getResources().getConfiguration(); + int rot = context.getDisplay().getRotation(); + if (config.smallestScreenWidthDp < 600) { + if (rot == Surface.ROTATION_90) { + return ROTATION_LANDSCAPE; + } else if (rot == Surface.ROTATION_270) { + return ROTATION_SEASCAPE; + } + } + return ROTATION_NONE; + } +} diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java index 02f2afcb0be8f..56612ad213986 100644 --- a/services/core/java/com/android/server/power/ShutdownThread.java +++ b/services/core/java/com/android/server/power/ShutdownThread.java @@ -23,14 +23,17 @@ import android.app.IActivityManager; import android.app.ProgressDialog; import android.bluetooth.BluetoothAdapter; import android.bluetooth.IBluetoothManager; -import android.media.AudioAttributes; -import android.nfc.NfcAdapter; -import android.nfc.INfcAdapter; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; +import android.content.om.IOverlayManager; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.media.AudioAttributes; +import android.nfc.INfcAdapter; +import android.nfc.NfcAdapter; import android.os.FileUtils; import android.os.Handler; import android.os.PowerManager; @@ -39,24 +42,21 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.SystemVibrator; import android.os.UserHandle; import android.os.UserManager; import android.os.Vibrator; -import android.os.SystemVibrator; -import android.os.storage.IStorageShutdownObserver; import android.os.storage.IStorageManager; -import android.system.ErrnoException; -import android.system.Os; - +import android.os.storage.IStorageShutdownObserver; +import android.util.Log; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.ProgressBar; +import android.widget.TextView; import com.android.internal.telephony.ITelephony; import com.android.server.pm.PackageManagerService; -import android.util.Log; -import android.view.WindowManager; - -import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; import java.io.IOException; public final class ShutdownThread extends Thread { @@ -243,15 +243,7 @@ public final class ShutdownThread extends Thread { shutdownInner(context, confirm); } - private static void beginShutdownSequence(Context context) { - synchronized (sIsStartedGuard) { - if (sIsStarted) { - Log.d(TAG, "Shutdown sequence already running, returning."); - return; - } - sIsStarted = true; - } - + private static ProgressDialog showShutdownDialog(Context context) { // Throw up a system dialog to indicate the device is rebooting / shutting down. ProgressDialog pd = new ProgressDialog(context); @@ -303,6 +295,32 @@ public final class ShutdownThread extends Thread { pd.setMessage(context.getText( com.android.internal.R.string.reboot_to_reset_message)); pd.setIndeterminate(true); + } else if (mReason != null && mReason.equals(PowerManager.SHUTDOWN_USER_REQUESTED)) { + Dialog d = new Dialog(context); + d.setContentView(com.android.internal.R.layout.shutdown_dialog); + d.setCancelable(false); + + int color = Color.WHITE; + try { + IOverlayManager service = IOverlayManager.Stub.asInterface( + ServiceManager.getService(Context.OVERLAY_SERVICE)); + if (service.getOverlayInfo("com.android.systemui.theme.lightwallpaper", 0).isEnabled()) { + color = Color.BLACK; + } + } catch (Exception e) { + // Shutdown UI really shouldn't crash or have strict dependencies on other services. + Log.w(TAG, "Problem getting overlay state", e); + } + ProgressBar bar = d.findViewById(com.android.internal.R.id.progress); + bar.getIndeterminateDrawable().setTint(color); + ((TextView) d.findViewById(com.android.internal.R.id.text1)).setTextColor(color); + d.getWindow().getAttributes().width = ViewGroup.LayoutParams.MATCH_PARENT; + d.getWindow().getAttributes().height = ViewGroup.LayoutParams.MATCH_PARENT; + d.getWindow().setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY); + d.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); + d.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + d.show(); + return null; } else { pd.setTitle(context.getText(com.android.internal.R.string.power_off)); pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress)); @@ -312,8 +330,19 @@ public final class ShutdownThread extends Thread { pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); pd.show(); + return pd; + } - sInstance.mProgressDialog = pd; + private static void beginShutdownSequence(Context context) { + synchronized (sIsStartedGuard) { + if (sIsStarted) { + Log.d(TAG, "Shutdown sequence already running, returning."); + return; + } + sIsStarted = true; + } + + sInstance.mProgressDialog = showShutdownDialog(context); sInstance.mContext = context; sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);