Presentation.java revision a95a3b494fd88f83c9f5d32e001452575ba235ec
1a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown/*
2a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * Copyright (C) 2012 The Android Open Source Project
3a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown *
4a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * you may not use this file except in compliance with the License.
6a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * You may obtain a copy of the License at
7a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown *
8a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown *
10a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * Unless required by applicable law or agreed to in writing, software
11a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * See the License for the specific language governing permissions and
14a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * limitations under the License.
15a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown */
16a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
17a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownpackage android.app;
18a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
19a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.content.Context;
20a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.content.res.Resources;
21a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.hardware.display.DisplayManager;
22a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.hardware.display.DisplayManager.DisplayListener;
23a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.view.ContextThemeWrapper;
24a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.view.Display;
25a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.view.Gravity;
26a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.view.WindowManagerImpl;
27a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.os.Handler;
28a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.os.Message;
29a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.util.DisplayMetrics;
30a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.util.Log;
31a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownimport android.util.TypedValue;
32a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
33a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown/**
34a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * Base class for presentations.
35a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown * <p>
36a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * A presentation is a special kind of dialog whose purpose is to present
37a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * content on a secondary display.  A {@link Presentation} is associated with
38a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * the target {@link Display} at creation time and configures its context and
39a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * resource configuration according to the display's metrics.
40a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown * </p><p>
41a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * Notably, the {@link Context} of a presentation is different from the context
42a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * of its containing {@link Activity}.  It is important to inflate the layout
43a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * of a presentation and load other resources using the presentation's own context
44a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * to ensure that assets of the correct size and density for the target display
45a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * are loaded.
46a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown * </p><p>
47a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * A presentation is automatically canceled (see {@link Dialog#cancel()}) when
48a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * the display to which it is attached is removed.  An activity should take
49a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown * care of pausing and resuming whatever content is playing within the presentation
50a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown * whenever the activity itself is paused or resumed.
51a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown * </p>
52a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown *
53a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown * @see DisplayManager for information on how to enumerate displays and receive
54a95a3b494fd88f83c9f5d32e001452575ba235ecJeff Brown * notifications when displays are added or removed.
55a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown */
56a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brownpublic class Presentation extends Dialog {
57a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    private static final String TAG = "Presentation";
58a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
59a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    private static final int MSG_CANCEL = 1;
60a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
61a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    private final Display mDisplay;
62a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    private final DisplayManager mDisplayManager;
63a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
64a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    /**
65a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * Creates a new presentation that is attached to the specified display
66a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * using the default theme.
67a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     *
68a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * @param outerContext The context of the application that is showing the presentation.
69a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * The presentation will create its own context (see {@link #getContext()}) based
70a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * on this context and information about the associated display.
71a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * @param display The display to which the presentation should be attached.
72a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     */
73a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    public Presentation(Context outerContext, Display display) {
74a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        this(outerContext, display, 0);
75a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    }
76a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
77a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    /**
78a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * Creates a new presentation that is attached to the specified display
79a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * using the optionally specified theme.
80a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     *
81a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * @param outerContext The context of the application that is showing the presentation.
82a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * The presentation will create its own context (see {@link #getContext()}) based
83a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * on this context and information about the associated display.
84a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * @param display The display to which the presentation should be attached.
85a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * @param theme A style resource describing the theme to use for the window.
86a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * See <a href="{@docRoot}guide/topics/resources/available-resources.html#stylesandthemes">
87a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * Style and Theme Resources</a> for more information about defining and using
88a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * styles.  This theme is applied on top of the current theme in
89a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * <var>outerContext</var>.  If 0, the default presentation theme will be used.
90a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     */
91a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    public Presentation(Context outerContext, Display display, int theme) {
92a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        super(createPresentationContext(outerContext, display, theme), theme, false);
93a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
94a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        mDisplay = display;
95a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        mDisplayManager = (DisplayManager)getContext().getSystemService(Context.DISPLAY_SERVICE);
96a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
97a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        getWindow().setGravity(Gravity.FILL);
98a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        setCanceledOnTouchOutside(false);
99a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    }
100a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
101a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    /**
102a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * Gets the {@link Display} that this presentation appears on.
103a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     *
104a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * @return The display.
105a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     */
106a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    public Display getDisplay() {
107a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        return mDisplay;
108a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    }
109a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
110a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    /**
111a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * Gets the {@link Resources} that should be used to inflate the layout of this presentation.
112a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * This resources object has been configured according to the metrics of the
113a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * display that the presentation appears on.
114a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     *
115a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * @return The presentation resources object.
116a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     */
117a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    public Resources getResources() {
118a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        return getContext().getResources();
119a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    }
120a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
121a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    @Override
122a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    protected void onStart() {
123a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        super.onStart();
124a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        mDisplayManager.registerDisplayListener(mDisplayListener, null);
125a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
126a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // Since we were not watching for display changes until just now, there is a
127a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // chance that the display metrics have changed.  If so, we will need to
128a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // dismiss the presentation immediately.  This case is expected
129a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // to be rare but surprising, so we'll write a log message about it.
130a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        if (!isConfigurationStillValid()) {
131a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            Log.i(TAG, "Presentation is being immediately dismissed because the "
132a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                    + "display metrics have changed since it was created.");
133a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            mHandler.sendEmptyMessage(MSG_CANCEL);
134a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        }
135a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    }
136a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
137a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    @Override
138a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    protected void onStop() {
139a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        mDisplayManager.unregisterDisplayListener(mDisplayListener);
140a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        super.onStop();
141a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    }
142a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
143a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    /**
144a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * Called by the system when the {@link Display} to which the presentation
145a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * is attached has been removed.
146a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     *
147a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * The system automatically calls {@link #cancel} to dismiss the presentation
148a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * after sending this event.
149a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     *
150a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * @see #getDisplay
151a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     */
152a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    public void onDisplayRemoved() {
153a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    }
154a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
155a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    /**
156a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * Called by the system when the properties of the {@link Display} to which
157a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * the presentation is attached have changed.
158a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     *
159a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * If the display metrics have changed (for example, if the display has been
160a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * resized or rotated), then the system automatically calls
161a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * {@link #cancel} to dismiss the presentation.
162a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     *
163a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     * @see #getDisplay
164a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown     */
165a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    public void onDisplayChanged() {
166a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    }
167a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
168a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    private void handleDisplayRemoved() {
169a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        onDisplayRemoved();
170a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        cancel();
171a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    }
172a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
173a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    private void handleDisplayChanged() {
174a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        onDisplayChanged();
175a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
176a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // We currently do not support configuration changes for presentations
177a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // (although we could add that feature with a bit more work).
178a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // If the display metrics have changed in any way then the current configuration
179a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // is invalid and the application must recreate the presentation to get
180a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // a new context.
181a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        if (!isConfigurationStillValid()) {
182a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            cancel();
183a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        }
184a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    }
185a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
186a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    private boolean isConfigurationStillValid() {
187a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        DisplayMetrics dm = new DisplayMetrics();
188a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        mDisplay.getMetrics(dm);
189a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        return dm.equals(getResources().getDisplayMetrics());
190a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    }
191a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
192a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    private static Context createPresentationContext(
193a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            Context outerContext, Display display, int theme) {
194a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        if (outerContext == null) {
195a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            throw new IllegalArgumentException("outerContext must not be null");
196a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        }
197a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        if (display == null) {
198a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            throw new IllegalArgumentException("display must not be null");
199a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        }
200a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
201a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        Context displayContext = outerContext.createDisplayContext(display);
202a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        if (theme == 0) {
203a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            TypedValue outValue = new TypedValue();
204a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            displayContext.getTheme().resolveAttribute(
205a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                    com.android.internal.R.attr.presentationTheme, outValue, true);
206a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            theme = outValue.resourceId;
207a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        }
208a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
209a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // Derive the display's window manager from the outer window manager.
210a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // We do this because the outer window manager have some extra information
211a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // such as the parent window, which is important if the presentation uses
212a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        // an application window type.
213a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        final WindowManagerImpl outerWindowManager =
214a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                (WindowManagerImpl)outerContext.getSystemService(Context.WINDOW_SERVICE);
215a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        final WindowManagerImpl displayWindowManager =
216a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                outerWindowManager.createPresentationWindowManager(display);
217a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        return new ContextThemeWrapper(displayContext, theme) {
218a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            @Override
219a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            public Object getSystemService(String name) {
220a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                if (Context.WINDOW_SERVICE.equals(name)) {
221a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                    return displayWindowManager;
222a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                }
223a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                return super.getSystemService(name);
224a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            }
225a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        };
226a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    }
227a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
228a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    private final DisplayListener mDisplayListener = new DisplayListener() {
229a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        @Override
230a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        public void onDisplayAdded(int displayId) {
231a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        }
232a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
233a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        @Override
234a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        public void onDisplayRemoved(int displayId) {
235a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            if (displayId == mDisplay.getDisplayId()) {
236a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                handleDisplayRemoved();
237a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            }
238a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        }
239a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
240a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        @Override
241a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        public void onDisplayChanged(int displayId) {
242a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            if (displayId == mDisplay.getDisplayId()) {
243a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                handleDisplayChanged();
244a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            }
245a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        }
246a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    };
247a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown
248a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    private final Handler mHandler = new Handler() {
249a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        @Override
250a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        public void handleMessage(Message msg) {
251a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            switch (msg.what) {
252a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                case MSG_CANCEL:
253a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                    cancel();
254a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown                    break;
255a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown            }
256a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown        }
257a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown    };
258a492c3a7b2c18426fd0cb4d017eacbc368195dc5Jeff Brown}
259