summaryrefslogtreecommitdiffstats
path: root/packages/Keyguard
diff options
context:
space:
mode:
authorJim Miller <jaggies@google.com>2013-11-08 11:35:18 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2013-11-08 11:35:18 -0800
commitc9fd186b4692e2da63698f15be59abcd360e321c (patch)
tree50146842bbd749c9582d65cdb02a8eda5f64b1d2 /packages/Keyguard
parenteb544c338c39f3e9435ad1098d559b618d287cf2 (diff)
parent44ee0fb144947206713e6527a5227fd44e2d4e1e (diff)
downloadframeworks_base-c9fd186b4692e2da63698f15be59abcd360e321c.zip
frameworks_base-c9fd186b4692e2da63698f15be59abcd360e321c.tar.gz
frameworks_base-c9fd186b4692e2da63698f15be59abcd360e321c.tar.bz2
am 44ee0fb1: am c55edb26: Merge changes I74bfc0d5,I577f9d36 into klp-dev
* commit '44ee0fb144947206713e6527a5227fd44e2d4e1e': Delay tearing down external displays until keyguard finishes Show keyguard scrim on external displays while keyguard showing
Diffstat (limited to 'packages/Keyguard')
-rw-r--r--packages/Keyguard/res/layout/keyguard_presentation.xml63
-rw-r--r--packages/Keyguard/res/layout/keyguard_status_view.xml2
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardDisplayManager.java171
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java7
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java19
5 files changed, 259 insertions, 3 deletions
diff --git a/packages/Keyguard/res/layout/keyguard_presentation.xml b/packages/Keyguard/res/layout/keyguard_presentation.xml
new file mode 100644
index 0000000..7df0b70
--- /dev/null
+++ b/packages/Keyguard/res/layout/keyguard_presentation.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2013, 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.
+*/
+-->
+
+<!-- This is a view that shows general status information in Keyguard. -->
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/res/com.android.keyguard"
+ android:id="@+id/presentation"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.android.keyguard.KeyguardStatusView
+ android:id="@+id/clock"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="@string/keyguard_accessibility_status">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|top"
+ android:orientation="vertical"
+ android:focusable="true">
+ <TextClock
+ android:id="@+id/clock_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|top"
+ android:textColor="@color/clock_white"
+ android:singleLine="true"
+ style="@style/widget_big_thin"
+ android:format12Hour="@string/keyguard_widget_12_hours_format"
+ android:format24Hour="@string/keyguard_widget_24_hours_format"
+ android:baselineAligned="true"
+ android:layout_marginBottom="@dimen/bottom_text_spacing_digital" />
+
+ <include layout="@layout/keyguard_status_area" />
+ <ImageView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="10dip"
+ android:layout_gravity="center_horizontal"
+ android:src="@drawable/kg_security_lock_normal" />
+ </LinearLayout>
+ </com.android.keyguard.KeyguardStatusView>
+
+</FrameLayout>
diff --git a/packages/Keyguard/res/layout/keyguard_status_view.xml b/packages/Keyguard/res/layout/keyguard_status_view.xml
index 5857fc2..a4d298a 100644
--- a/packages/Keyguard/res/layout/keyguard_status_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_status_view.xml
@@ -26,7 +26,7 @@
android:layout_height="match_parent"
androidprv:layout_maxWidth="@dimen/keyguard_security_width"
androidprv:layout_maxHeight="@dimen/keyguard_security_height"
- android:gravity="center_horizontal">
+ android:gravity="center">
<com.android.keyguard.KeyguardStatusView
android:id="@+id/keyguard_status_view_face_palm"
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardDisplayManager.java
new file mode 100644
index 0000000..6bcbd6c
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2013 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.keyguard;
+
+import android.app.Presentation;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnDismissListener;
+import android.graphics.Point;
+import android.media.MediaRouter;
+import android.media.MediaRouter.RouteInfo;
+import android.os.Bundle;
+import android.util.Slog;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowManager;
+
+public class KeyguardDisplayManager {
+ protected static final String TAG = "KeyguardDisplayManager";
+ private static boolean DEBUG = KeyguardViewMediator.DEBUG;
+ Presentation mPresentation;
+ private MediaRouter mMediaRouter;
+ private Context mContext;
+ private boolean mShowing;
+
+ KeyguardDisplayManager(Context context) {
+ mContext = context;
+ mMediaRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ }
+
+ void show() {
+ if (!mShowing) {
+ if (DEBUG) Slog.v(TAG, "show");
+ mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY,
+ mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_PASSIVE_DISCOVERY);
+ updateDisplays(true);
+ }
+ mShowing = true;
+ }
+
+ void hide() {
+ if (mShowing) {
+ if (DEBUG) Slog.v(TAG, "hide");
+ mMediaRouter.removeCallback(mMediaRouterCallback);
+ updateDisplays(false);
+ }
+ mShowing = false;
+ }
+
+ private final MediaRouter.SimpleCallback mMediaRouterCallback =
+ new MediaRouter.SimpleCallback() {
+ @Override
+ public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
+ if (DEBUG) Slog.d(TAG, "onRouteSelected: type=" + type + ", info=" + info);
+ updateDisplays(mShowing);
+ }
+
+ @Override
+ public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
+ if (DEBUG) Slog.d(TAG, "onRouteUnselected: type=" + type + ", info=" + info);
+ updateDisplays(mShowing);
+ }
+
+ @Override
+ public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo info) {
+ if (DEBUG) Slog.d(TAG, "onRoutePresentationDisplayChanged: info=" + info);
+ updateDisplays(mShowing);
+ }
+ };
+
+ private OnDismissListener mOnDismissListener = new OnDismissListener() {
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ mPresentation = null;
+ }
+ };
+
+ protected void updateDisplays(boolean showing) {
+ if (showing) {
+ MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(
+ MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY);
+ boolean useDisplay = route != null
+ && route.getPlaybackType() == MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE;
+ Display presentationDisplay = useDisplay ? route.getPresentationDisplay() : null;
+
+ if (mPresentation != null && mPresentation.getDisplay() != presentationDisplay) {
+ if (DEBUG) Slog.v(TAG, "Display gone: " + mPresentation.getDisplay());
+ mPresentation.dismiss();
+ mPresentation = null;
+ }
+
+ if (mPresentation == null && presentationDisplay != null) {
+ if (DEBUG) Slog.i(TAG, "Keyguard enabled on display: " + presentationDisplay);
+ mPresentation = new KeyguardPresentation(mContext, presentationDisplay);
+ mPresentation.setOnDismissListener(mOnDismissListener);
+ try {
+ mPresentation.show();
+ } catch (WindowManager.InvalidDisplayException ex) {
+ Slog.w(TAG, "Invalid display:", ex);
+ mPresentation = null;
+ }
+ }
+ } else {
+ if (mPresentation != null) {
+ mPresentation.dismiss();
+ mPresentation = null;
+ }
+ }
+ }
+
+ private final static class KeyguardPresentation extends Presentation {
+ private static final int VIDEO_SAFE_REGION = 80; // Percentage of display width & height
+ private static final int MOVE_CLOCK_TIMEOUT = 10000; // 10s
+ private View mClock;
+ private int mUsableWidth;
+ private int mUsableHeight;
+ private int mMarginTop;
+ private int mMarginLeft;
+ Runnable mMoveTextRunnable = new Runnable() {
+ @Override
+ public void run() {
+ int x = mMarginLeft + (int) (Math.random() * (mUsableWidth - mClock.getWidth()));
+ int y = mMarginTop + (int) (Math.random() * (mUsableHeight - mClock.getHeight()));
+ mClock.setTranslationX(x);
+ mClock.setTranslationY(y);
+ mClock.postDelayed(mMoveTextRunnable, MOVE_CLOCK_TIMEOUT);
+ }
+ };
+
+ public KeyguardPresentation(Context context, Display display) {
+ super(context, display);
+ getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+ }
+
+ public void onDetachedFromWindow() {
+ mClock.removeCallbacks(mMoveTextRunnable);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Point p = new Point();
+ getDisplay().getSize(p);
+ mUsableWidth = VIDEO_SAFE_REGION * p.x/100;
+ mUsableHeight = VIDEO_SAFE_REGION * p.y/100;
+ mMarginLeft = (100 - VIDEO_SAFE_REGION) * p.x / 200;
+ mMarginTop = (100 - VIDEO_SAFE_REGION) * p.y / 200;
+
+ setContentView(R.layout.keyguard_presentation);
+ mClock = findViewById(R.id.clock);
+
+ // Avoid screen burn in
+ mClock.post(mMoveTextRunnable);
+ }
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index fd7cae6..6aa0a4b 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -61,9 +61,11 @@ import android.widget.FrameLayout;
public class KeyguardViewManager {
private final static boolean DEBUG = KeyguardViewMediator.DEBUG;
private static String TAG = "KeyguardViewManager";
- public static boolean USE_UPPER_CASE = true;
public final static String IS_SWITCHING_USER = "is_switching_user";
+ // Delay dismissing keyguard to allow animations to complete.
+ private static final int HIDE_KEYGUARD_DELAY = 500;
+
// Timeout used for keypresses
static final int DIGIT_PRESS_WAKE_MILLIS = 5000;
@@ -509,9 +511,10 @@ public class KeyguardViewManager {
mKeyguardHost.setCustomBackground(null);
updateShowWallpaper(true);
mKeyguardHost.removeView(lastView);
+ mViewMediatorCallback.keyguardGone();
}
}
- }, 500);
+ }, HIDE_KEYGUARD_DELAY);
}
}
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
index b92ae90..49982ea 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
@@ -253,6 +253,11 @@ public class KeyguardViewMediator {
private final float mLockSoundVolume;
/**
+ * For managing external displays
+ */
+ private KeyguardDisplayManager mKeyguardDisplayManager;
+
+ /**
* Cache of avatar drawables, for use by KeyguardMultiUserAvatar.
*/
private static MultiUserAvatarCache sMultiUserAvatarCache = new MultiUserAvatarCache();
@@ -304,6 +309,11 @@ public class KeyguardViewMediator {
* Report that the keyguard is dismissable, pending the next keyguardDone call.
*/
void keyguardDonePending();
+
+ /**
+ * Report when keyguard is actually gone
+ */
+ void keyguardGone();
}
KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
@@ -457,6 +467,11 @@ public class KeyguardViewMediator {
public void keyguardDonePending() {
mKeyguardDonePending = true;
}
+
+ @Override
+ public void keyguardGone() {
+ mKeyguardDisplayManager.hide();
+ }
};
private void userActivity() {
@@ -483,6 +498,8 @@ public class KeyguardViewMediator {
mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(DELAYED_KEYGUARD_ACTION));
+ mKeyguardDisplayManager = new KeyguardDisplayManager(context);
+
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
mUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
@@ -597,6 +614,7 @@ public class KeyguardViewMediator {
}
}
KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurndOff(why);
+ mKeyguardDisplayManager.show();
}
private void doKeyguardLaterLocked() {
@@ -1218,6 +1236,7 @@ public class KeyguardViewMediator {
mShowKeyguardWakeLock.release();
}
+ mKeyguardDisplayManager.show();
}
/**