diff options
Diffstat (limited to 'packages/Keyguard')
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(); } /** |