The default Material theme for presentations on external displays has a white background. This changes keyguard to use a custom theme since we want white lettering on black. Fixes bug 22305037 Change-Id: Idc6aca2398be34c4603446983e5d276abcace001
174 lines
6.4 KiB
Java
174 lines
6.4 KiB
Java
/*
|
|
* 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 = KeyguardConstants.DEBUG;
|
|
Presentation mPresentation;
|
|
private MediaRouter mMediaRouter;
|
|
private Context mContext;
|
|
private boolean mShowing;
|
|
|
|
public KeyguardDisplayManager(Context context) {
|
|
mContext = context;
|
|
mMediaRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
|
|
}
|
|
|
|
public 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;
|
|
}
|
|
|
|
public 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,
|
|
R.style.keyguard_presentation_theme);
|
|
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, int theme) {
|
|
super(context, display, theme);
|
|
getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
|
|
}
|
|
|
|
@Override
|
|
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);
|
|
}
|
|
}
|
|
}
|