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