OSDN Git Service

Update power menu + dialog
authorJason Monk <jmonk@google.com>
Thu, 29 Jun 2017 23:37:48 +0000 (19:37 -0400)
committerJason Monk <jmonk@google.com>
Wed, 5 Jul 2017 13:56:33 +0000 (09:56 -0400)
 - 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 [new file with mode: 0644]
core/res/res/values/symbols.xml
packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
packages/SystemUI/src/com/android/systemui/util/leak/RotationUtils.java [new file with mode: 0644]
services/core/java/com/android/server/power/ShutdownThread.java

diff --git a/core/res/res/layout/shutdown_dialog.xml b/core/res/res/layout/shutdown_dialog.xml
new file mode 100644 (file)
index 0000000..398bfb1
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:gravity="center_horizontal" >
+
+    <Space
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="6" />
+
+    <TextView
+        android:id="@id/text1"
+        android:layout_width="wrap_content"
+        android:layout_height="32dp"
+        android:text="@string/shutdown_progress"
+        android:textDirection="locale"
+        android:textSize="24sp"
+        android:textAppearance="?attr/textAppearanceLarge"
+        android:gravity="center"
+        android:layout_marginBottom="24dp"
+        android:fontFamily="@string/config_headlineFontFamily"/>
+
+    <ProgressBar
+        android:id="@id/progress"
+        android:layout_width="30dp"
+        android:layout_height="30dp"
+        style="?attr/progressBarStyleLarge" />
+
+    <Space
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="10" />
+
+</LinearLayout>
index 99807f9..50550a4 100644 (file)
   <java-symbol type="array" name="config_batteryPackageTypeSystem" />
   <java-symbol type="array" name="config_batteryPackageTypeService" />
   <java-symbol type="bool" name="config_showAreaUpdateInfoSettings" />
+  <java-symbol type="layout" name="shutdown_dialog" />
 </resources>
index bb0f2f9..22bb2a3 100644 (file)
@@ -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<View> 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);
index 1a8a474..31d41ac 100644 (file)
@@ -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;
index 521157d..d74970f 100644 (file)
@@ -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 (file)
index 0000000..ad20900
--- /dev/null
@@ -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;
+    }
+}
index 02f2afc..56612ad 100644 (file)
@@ -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 com.android.internal.telephony.ITelephony;
-import com.android.server.pm.PackageManagerService;
-
+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 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;
+    }
+
+    private static void beginShutdownSequence(Context context) {
+        synchronized (sIsStartedGuard) {
+            if (sIsStarted) {
+                Log.d(TAG, "Shutdown sequence already running, returning.");
+                return;
+            }
+            sIsStarted = true;
+        }
 
-        sInstance.mProgressDialog = pd;
+        sInstance.mProgressDialog = showShutdownDialog(context);
         sInstance.mContext = context;
         sInstance.mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);