--- /dev/null
+<?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>
<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>
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;
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 {
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) {
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;
}
mChild.addOnLayoutChangeListener(
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
updatePosition());
+ updateRotation();
} else {
return;
}
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);
return retGravity;
}
- private void toLandscape() {
+ private void rotateLeft() {
rotateLeft(this);
rotateLeft(mChild);
swapDimens(this);
/** {@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();
}
/**
.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;
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;
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(
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
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)));
}
}
};
--- /dev/null
+/*
+ * 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;
+ }
+}
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;
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 {
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);
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));
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);