blob: 1d35ba29e443f9cf4982bead8ea94c40abc472e9 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
Tor Norbyec615c6f2015-03-02 10:11:44 -080019import android.annotation.CallSuper;
Tor Norbye7b9c9122013-05-30 16:48:33 -070020import android.annotation.DrawableRes;
21import android.annotation.IdRes;
22import android.annotation.LayoutRes;
Alan Viverette682a4332015-04-10 11:05:50 -070023import android.annotation.NonNull;
Scott Kennedyc0519552015-02-11 15:33:10 -080024import android.annotation.Nullable;
Clara Bayarri75e09792015-07-29 16:20:40 +010025import android.annotation.StringRes;
Alan Viverette682a4332015-04-10 11:05:50 -070026import android.annotation.StyleRes;
Karl Rosaen53d24af2009-07-14 14:58:10 -070027import android.content.ComponentName;
Adam Powell6e346362010-07-23 10:18:23 -070028import android.content.Context;
Karl Rosaen7bafed82009-09-04 11:15:21 -070029import android.content.ContextWrapper;
Adam Powell6e346362010-07-23 10:18:23 -070030import android.content.DialogInterface;
Jorim Jaggib10e33f2015-02-04 21:57:40 +010031import android.content.pm.ApplicationInfo;
Chris Craik6faa9e52018-01-11 10:46:10 -080032import android.content.res.Configuration;
Adam Lesinski9553fb32017-05-23 18:53:44 -070033import android.content.res.ResourceId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.graphics.drawable.Drawable;
35import android.net.Uri;
svetoslavganov75986cf2009-05-14 22:28:01 -070036import android.os.Bundle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.os.Handler;
Svetoslav Ganov44bfdd82012-01-26 10:00:18 -080038import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.os.Message;
Adam Powell89fc3ac2011-11-01 18:00:44 -070040import android.util.Log;
Adam Powell2fbf4de62010-09-30 15:46:46 -070041import android.util.TypedValue;
Adam Powelldec9dfd2010-08-09 15:27:54 -070042import android.view.ActionMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.view.ContextMenu;
Adam Powell6e346362010-07-23 10:18:23 -070044import android.view.ContextMenu.ContextMenuInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.view.ContextThemeWrapper;
46import android.view.Gravity;
47import android.view.KeyEvent;
svetoslavganov75986cf2009-05-14 22:28:01 -070048import android.view.LayoutInflater;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.view.Menu;
50import android.view.MenuItem;
51import android.view.MotionEvent;
Tim Kilbourn6a975b32015-04-09 17:14:34 -070052import android.view.SearchEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.view.View;
Adam Powell6e346362010-07-23 10:18:23 -070054import android.view.View.OnCreateContextMenuListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.view.ViewGroup;
Adam Powell6e346362010-07-23 10:18:23 -070056import android.view.ViewGroup.LayoutParams;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.view.Window;
58import android.view.WindowManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070059import android.view.accessibility.AccessibilityEvent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060
Chris Craik6faa9e52018-01-11 10:46:10 -080061import com.android.internal.R;
62import com.android.internal.app.WindowDecorActionBar;
63import com.android.internal.policy.PhoneWindow;
64
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import java.lang.ref.WeakReference;
66
67/**
68 * Base class for Dialogs.
69 *
70 * <p>Note: Activities provide a facility to manage the creation, saving and
71 * restoring of dialogs. See {@link Activity#onCreateDialog(int)},
72 * {@link Activity#onPrepareDialog(int, Dialog)},
73 * {@link Activity#showDialog(int)}, and {@link Activity#dismissDialog(int)}. If
74 * these methods are used, {@link #getOwnerActivity()} will return the Activity
75 * that managed this dialog.
76 *
77 * <p>Often you will want to have a Dialog display on top of the current
78 * input method, because there is no reason for it to accept text. You can
79 * do this by setting the {@link WindowManager.LayoutParams#FLAG_ALT_FOCUSABLE_IM
80 * WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM} window flag (assuming
81 * your Dialog takes input focus, as it the default) with the following code:
82 *
83 * <pre>
Joe Fernandez558459f2011-10-13 16:47:36 -070084 * getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
85 * WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);</pre>
86 *
87 * <div class="special reference">
88 * <h3>Developer Guides</h3>
89 * <p>For more information about creating dialogs, read the
90 * <a href="{@docRoot}guide/topics/ui/dialogs.html">Dialogs</a> developer guide.</p>
91 * </div>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 */
93public class Dialog implements DialogInterface, Window.Callback,
Adam Powell117b6952014-05-05 18:14:56 -070094 KeyEvent.Callback, OnCreateContextMenuListener, Window.OnWindowDismissedCallback {
Adam Powell89fc3ac2011-11-01 18:00:44 -070095 private static final String TAG = "Dialog";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 private Activity mOwnerActivity;
Alan Viverette48728c22016-04-01 15:00:10 -040097
98 private final WindowManager mWindowManager;
99
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 final Context mContext;
Alan Viverette48728c22016-04-01 15:00:10 -0400101 final Window mWindow;
102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 View mDecor;
Alan Viverette48728c22016-04-01 15:00:10 -0400104
Adam Powelle43340c2014-03-17 19:10:43 -0700105 private ActionBar mActionBar;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 /**
107 * This field should be made private, so it is hidden from the SDK.
108 * {@hide}
109 */
110 protected boolean mCancelable = true;
svetoslavganov75986cf2009-05-14 22:28:01 -0700111
Dianne Hackbornf812fee2011-01-25 14:54:29 -0800112 private String mCancelAndDismissTaken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113 private Message mCancelMessage;
114 private Message mDismissMessage;
Romain Guy045163a2009-07-14 13:59:33 -0700115 private Message mShowMessage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 private OnKeyListener mOnKeyListener;
118
119 private boolean mCreated = false;
120 private boolean mShowing = false;
Dianne Hackborn8b4cac12011-01-03 13:58:14 -0800121 private boolean mCanceled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 private final Handler mHandler = new Handler();
124
Romain Guy7883c972010-03-01 16:39:17 -0800125 private static final int DISMISS = 0x43;
126 private static final int CANCEL = 0x44;
127 private static final int SHOW = 0x45;
128
Alan Viverette48728c22016-04-01 15:00:10 -0400129 private final Handler mListenersHandler;
Romain Guy7883c972010-03-01 16:39:17 -0800130
Tim Kilbourn6a975b32015-04-09 17:14:34 -0700131 private SearchEvent mSearchEvent;
132
Adam Powellcfe9aee2011-11-01 14:56:27 -0700133 private ActionMode mActionMode;
134
Clara Bayarri4423d912015-03-02 19:42:48 +0000135 private int mActionModeTypeStarting = ActionMode.TYPE_PRIMARY;
136
Alan Viverette48728c22016-04-01 15:00:10 -0400137 private final Runnable mDismissAction = this::dismissDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138
139 /**
Alan Viverette5696f042015-04-08 11:03:32 -0700140 * Creates a dialog window that uses the default dialog theme.
141 * <p>
142 * The supplied {@code context} is used to obtain the window manager and
143 * base theme used to present the dialog.
144 *
145 * @param context the context in which the dialog should run
146 * @see android.R.styleable#Theme_dialogTheme
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 */
Alan Viverette682a4332015-04-10 11:05:50 -0700148 public Dialog(@NonNull Context context) {
Dianne Hackborne79b5542011-01-27 15:18:46 -0800149 this(context, 0, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 }
151
152 /**
Alan Viverette5696f042015-04-08 11:03:32 -0700153 * Creates a dialog window that uses a custom dialog style.
154 * <p>
155 * The supplied {@code context} is used to obtain the window manager and
156 * base theme used to present the dialog.
157 * <p>
158 * The supplied {@code theme} is applied on top of the context's theme. See
159 * <a href="{@docRoot}guide/topics/resources/available-resources.html#stylesandthemes">
160 * Style and Theme Resources</a> for more information about defining and
161 * using styles.
Jorim Jaggib10e33f2015-02-04 21:57:40 +0100162 *
Alan Viverette5696f042015-04-08 11:03:32 -0700163 * @param context the context in which the dialog should run
Alan Viverette682a4332015-04-10 11:05:50 -0700164 * @param themeResId a style resource describing the theme to use for the
Alan Viverette5696f042015-04-08 11:03:32 -0700165 * window, or {@code 0} to use the default dialog theme
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 */
Alan Viverette682a4332015-04-10 11:05:50 -0700167 public Dialog(@NonNull Context context, @StyleRes int themeResId) {
168 this(context, themeResId, true);
Dianne Hackborne79b5542011-01-27 15:18:46 -0800169 }
170
Alan Viverette682a4332015-04-10 11:05:50 -0700171 Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) {
Jeff Browna492c3a2012-08-23 19:48:44 -0700172 if (createContextThemeWrapper) {
Adam Lesinski9553fb32017-05-23 18:53:44 -0700173 if (themeResId == ResourceId.ID_NULL) {
Alan Viverette5696f042015-04-08 11:03:32 -0700174 final TypedValue outValue = new TypedValue();
175 context.getTheme().resolveAttribute(R.attr.dialogTheme, outValue, true);
Alan Viverette682a4332015-04-10 11:05:50 -0700176 themeResId = outValue.resourceId;
Jeff Browna492c3a2012-08-23 19:48:44 -0700177 }
Alan Viverette682a4332015-04-10 11:05:50 -0700178 mContext = new ContextThemeWrapper(context, themeResId);
Jeff Browna492c3a2012-08-23 19:48:44 -0700179 } else {
180 mContext = context;
Adam Powell2fbf4de62010-09-30 15:46:46 -0700181 }
182
Alan Viverette682a4332015-04-10 11:05:50 -0700183 mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Alan Viverette5696f042015-04-08 11:03:32 -0700184
185 final Window w = new PhoneWindow(mContext);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 mWindow = w;
187 w.setCallback(this);
Adam Powell117b6952014-05-05 18:14:56 -0700188 w.setOnWindowDismissedCallback(this);
Michael Kwan67639a52016-12-16 12:38:10 -0800189 w.setOnWindowSwipeDismissedCallback(() -> {
190 if (mCancelable) {
191 cancel();
192 }
193 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800194 w.setWindowManager(mWindowManager, null, null);
195 w.setGravity(Gravity.CENTER);
Alan Viverette5696f042015-04-08 11:03:32 -0700196
Romain Guy045163a2009-07-14 13:59:33 -0700197 mListenersHandler = new ListenersHandler(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 }
Jeff Browna492c3a2012-08-23 19:48:44 -0700199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 /**
201 * @deprecated
202 * @hide
203 */
204 @Deprecated
Alan Viverette48728c22016-04-01 15:00:10 -0400205 protected Dialog(@NonNull Context context, boolean cancelable,
206 @Nullable Message cancelCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 this(context);
208 mCancelable = cancelable;
Michael Kwanf7964be2016-11-30 16:44:33 -0800209 updateWindowForCancelable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 mCancelMessage = cancelCallback;
211 }
212
Alan Viverette682a4332015-04-10 11:05:50 -0700213 protected Dialog(@NonNull Context context, boolean cancelable,
Alan Viverette48728c22016-04-01 15:00:10 -0400214 @Nullable OnCancelListener cancelListener) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 this(context);
216 mCancelable = cancelable;
Michael Kwanf7964be2016-11-30 16:44:33 -0800217 updateWindowForCancelable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 setOnCancelListener(cancelListener);
219 }
220
221 /**
222 * Retrieve the Context this Dialog is running in.
223 *
Adam Powellc49c1732010-09-28 16:03:15 -0700224 * @return Context The Context used by the Dialog.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 */
Alan Viverette48728c22016-04-01 15:00:10 -0400226 public final @NonNull Context getContext() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 return mContext;
228 }
229
230 /**
Adam Powelldec9dfd2010-08-09 15:27:54 -0700231 * Retrieve the {@link ActionBar} attached to this dialog, if present.
232 *
233 * @return The ActionBar attached to the dialog or null if no ActionBar is present.
234 */
Alan Viverette48728c22016-04-01 15:00:10 -0400235 public @Nullable ActionBar getActionBar() {
Adam Powelldec9dfd2010-08-09 15:27:54 -0700236 return mActionBar;
237 }
238
239 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240 * Sets the Activity that owns this dialog. An example use: This Dialog will
241 * use the suggested volume control stream of the Activity.
242 *
243 * @param activity The Activity that owns this dialog.
244 */
Alan Viverette48728c22016-04-01 15:00:10 -0400245 public final void setOwnerActivity(@NonNull Activity activity) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 mOwnerActivity = activity;
247
248 getWindow().setVolumeControlStream(mOwnerActivity.getVolumeControlStream());
249 }
250
251 /**
252 * Returns the Activity that owns this Dialog. For example, if
253 * {@link Activity#showDialog(int)} is used to show this Dialog, that
254 * Activity will be the owner (by default). Depending on how this dialog was
255 * created, this may return null.
256 *
257 * @return The Activity that owns this Dialog.
258 */
Alan Viverette48728c22016-04-01 15:00:10 -0400259 public final @Nullable Activity getOwnerActivity() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 return mOwnerActivity;
261 }
262
263 /**
264 * @return Whether the dialog is currently showing.
265 */
266 public boolean isShowing() {
tiansiming [田思明]ca1c4d22018-03-09 17:19:12 +0800267 return mDecor == null ? false : mDecor.getVisibility() == View.VISIBLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 }
269
270 /**
Alan Viverettef34ef742013-12-11 15:59:53 -0800271 * Forces immediate creation of the dialog.
272 * <p>
273 * Note that you should not override this method to perform dialog creation.
274 * Rather, override {@link #onCreate(Bundle)}.
275 */
276 public void create() {
277 if (!mCreated) {
278 dispatchOnCreate(null);
279 }
280 }
281
282 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 * Start the dialog and display it on screen. The window is placed in the
284 * application layer and opaque. Note that you should not override this
285 * method to do initialization when the dialog is shown, instead implement
286 * that in {@link #onStart}.
287 */
288 public void show() {
289 if (mShowing) {
svetoslavganov75986cf2009-05-14 22:28:01 -0700290 if (mDecor != null) {
Adam Powelle67a9dc2010-08-17 17:28:56 -0700291 if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
292 mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
293 }
tiansiming [田思明]690b3692018-02-10 15:53:53 +0800294 if (mDecor.getVisibility() != View.VISIBLE) {
295 mDecor.setVisibility(View.VISIBLE);
296 sendShowMessage();
297 }
svetoslavganov75986cf2009-05-14 22:28:01 -0700298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 return;
300 }
301
Dianne Hackborn8b4cac12011-01-03 13:58:14 -0800302 mCanceled = false;
Robert Carrd7dbec72016-10-05 13:13:21 -0700303
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 if (!mCreated) {
305 dispatchOnCreate(null);
Robert Carrd7dbec72016-10-05 13:13:21 -0700306 } else {
307 // Fill the DecorView in on any configuration changes that
308 // may have occured while it was removed from the WindowManager.
309 final Configuration config = mContext.getResources().getConfiguration();
310 mWindow.getDecorView().dispatchConfigurationChanged(config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 }
312
313 onStart();
314 mDecor = mWindow.getDecorView();
Adam Powelldec9dfd2010-08-09 15:27:54 -0700315
316 if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
Adam Powell04fe6eb2013-05-31 14:39:48 -0700317 final ApplicationInfo info = mContext.getApplicationInfo();
318 mWindow.setDefaultIcon(info.icon);
319 mWindow.setDefaultLogo(info.logo);
Adam Powelle43340c2014-03-17 19:10:43 -0700320 mActionBar = new WindowDecorActionBar(this);
Adam Powelldec9dfd2010-08-09 15:27:54 -0700321 }
322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 WindowManager.LayoutParams l = mWindow.getAttributes();
Felipe Leme15d403d2018-03-29 10:02:32 -0700324 boolean restoreSoftInputMode = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 if ((l.softInputMode
326 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
Felipe Leme15d403d2018-03-29 10:02:32 -0700327 l.softInputMode |=
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
Felipe Leme15d403d2018-03-29 10:02:32 -0700329 restoreSoftInputMode = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 }
Romain Guy045163a2009-07-14 13:59:33 -0700331
Alan Viverette48728c22016-04-01 15:00:10 -0400332 mWindowManager.addView(mDecor, l);
Felipe Leme15d403d2018-03-29 10:02:32 -0700333 if (restoreSoftInputMode) {
334 l.softInputMode &=
335 ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
336 }
337
Alan Viverette48728c22016-04-01 15:00:10 -0400338 mShowing = true;
339
340 sendShowMessage();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 }
342
343 /**
344 * Hide the dialog, but do not dismiss it.
345 */
346 public void hide() {
svetoslavganov75986cf2009-05-14 22:28:01 -0700347 if (mDecor != null) {
348 mDecor.setVisibility(View.GONE);
349 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 }
351
352 /**
353 * Dismiss this dialog, removing it from the screen. This method can be
354 * invoked safely from any thread. Note that you should not override this
355 * method to do cleanup when the dialog is dismissed, instead implement
356 * that in {@link #onStop}.
357 */
Craig Mautner92098c72013-06-10 11:27:26 -0700358 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 public void dismiss() {
Svetoslav Ganov44bfdd82012-01-26 10:00:18 -0800360 if (Looper.myLooper() == mHandler.getLooper()) {
361 dismissDialog();
362 } else {
363 mHandler.post(mDismissAction);
364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 }
366
Adam Powell89fc3ac2011-11-01 18:00:44 -0700367 void dismissDialog() {
Romain Guy08a4ac32010-03-16 11:40:40 -0700368 if (mDecor == null || !mShowing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 return;
370 }
371
Adam Powell89fc3ac2011-11-01 18:00:44 -0700372 if (mWindow.isDestroyed()) {
373 Log.e(TAG, "Tried to dismissDialog() but the Dialog's window was already destroyed!");
374 return;
375 }
376
Romain Guyd2671e12010-03-11 18:06:42 -0800377 try {
Craig Mautner92098c72013-06-10 11:27:26 -0700378 mWindowManager.removeViewImmediate(mDecor);
Romain Guyd2671e12010-03-11 18:06:42 -0800379 } finally {
Adam Powellcfe9aee2011-11-01 14:56:27 -0700380 if (mActionMode != null) {
381 mActionMode.finish();
382 }
Romain Guyd2671e12010-03-11 18:06:42 -0800383 mDecor = null;
384 mWindow.closeAllPanels();
385 onStop();
386 mShowing = false;
Craig Mautner92098c72013-06-10 11:27:26 -0700387
Romain Guyd2671e12010-03-11 18:06:42 -0800388 sendDismissMessage();
389 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 }
391
392 private void sendDismissMessage() {
393 if (mDismissMessage != null) {
394 // Obtain a new message so this dialog can be re-used
395 Message.obtain(mDismissMessage).sendToTarget();
396 }
397 }
svetoslavganov75986cf2009-05-14 22:28:01 -0700398
Romain Guy045163a2009-07-14 13:59:33 -0700399 private void sendShowMessage() {
400 if (mShowMessage != null) {
401 // Obtain a new message so this dialog can be re-used
402 Message.obtain(mShowMessage).sendToTarget();
403 }
404 }
405
Alan Viverette48728c22016-04-01 15:00:10 -0400406 // internal method to make sure mCreated is set properly without requiring
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 // users to call through to super in onCreate
408 void dispatchOnCreate(Bundle savedInstanceState) {
Alan Viverettef34ef742013-12-11 15:59:53 -0800409 if (!mCreated) {
Romain Guy6de4aed2009-07-08 10:54:45 -0700410 onCreate(savedInstanceState);
411 mCreated = true;
412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 }
414
415 /**
Chet Haase49afa5b2010-08-23 11:39:53 -0700416 * Similar to {@link Activity#onCreate}, you should initialize your dialog
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 * in this method, including calling {@link #setContentView}.
Alan Viverette48728c22016-04-01 15:00:10 -0400418 * @param savedInstanceState If this dialog is being reinitialized after a
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 * the hosting activity was previously shut down, holds the result from
420 * the most recent call to {@link #onSaveInstanceState}, or null if this
421 * is the first time.
422 */
423 protected void onCreate(Bundle savedInstanceState) {
424 }
425
426 /**
427 * Called when the dialog is starting.
428 */
429 protected void onStart() {
Adam Powell50efbed2011-02-08 16:20:15 -0800430 if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 }
432
433 /**
434 * Called to tell you that you're stopping.
435 */
436 protected void onStop() {
Adam Powell50efbed2011-02-08 16:20:15 -0800437 if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 }
439
440 private static final String DIALOG_SHOWING_TAG = "android:dialogShowing";
441 private static final String DIALOG_HIERARCHY_TAG = "android:dialogHierarchy";
442
443 /**
444 * Saves the state of the dialog into a bundle.
445 *
446 * The default implementation saves the state of its view hierarchy, so you'll
447 * likely want to call through to super if you override this to save additional
448 * state.
449 * @return A bundle with the state of the dialog.
450 */
Alan Viverette48728c22016-04-01 15:00:10 -0400451 public @NonNull Bundle onSaveInstanceState() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452 Bundle bundle = new Bundle();
453 bundle.putBoolean(DIALOG_SHOWING_TAG, mShowing);
454 if (mCreated) {
455 bundle.putBundle(DIALOG_HIERARCHY_TAG, mWindow.saveHierarchyState());
456 }
457 return bundle;
458 }
459
460 /**
461 * Restore the state of the dialog from a previously saved bundle.
462 *
463 * The default implementation restores the state of the dialog's view
464 * hierarchy that was saved in the default implementation of {@link #onSaveInstanceState()},
465 * so be sure to call through to super when overriding unless you want to
466 * do all restoring of state yourself.
467 * @param savedInstanceState The state of the dialog previously saved by
468 * {@link #onSaveInstanceState()}.
469 */
Alan Viverette48728c22016-04-01 15:00:10 -0400470 public void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 final Bundle dialogHierarchyState = savedInstanceState.getBundle(DIALOG_HIERARCHY_TAG);
472 if (dialogHierarchyState == null) {
473 // dialog has never been shown, or onCreated, nothing to restore.
474 return;
475 }
476 dispatchOnCreate(savedInstanceState);
477 mWindow.restoreHierarchyState(dialogHierarchyState);
478 if (savedInstanceState.getBoolean(DIALOG_SHOWING_TAG)) {
479 show();
480 }
481 }
482
483 /**
484 * Retrieve the current Window for the activity. This can be used to
485 * directly access parts of the Window API that are not available
486 * through Activity/Screen.
487 *
488 * @return Window The current window, or null if the activity is not
489 * visual.
490 */
Alan Viverette48728c22016-04-01 15:00:10 -0400491 public @Nullable Window getWindow() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 return mWindow;
493 }
494
495 /**
496 * Call {@link android.view.Window#getCurrentFocus} on the
497 * Window if this Activity to return the currently focused view.
498 *
499 * @return View The current View with focus or null.
500 *
501 * @see #getWindow
502 * @see android.view.Window#getCurrentFocus
503 */
Alan Viverette48728c22016-04-01 15:00:10 -0400504 public @Nullable View getCurrentFocus() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 return mWindow != null ? mWindow.getCurrentFocus() : null;
506 }
507
508 /**
Alan Viverettedb7423c2017-03-31 13:13:58 -0400509 * Finds the first descendant view with the given ID or {@code null} if the
510 * ID is invalid (< 0), there is no matching view in the hierarchy, or the
511 * dialog has not yet been fully created (for example, via {@link #show()}
512 * or {@link #create()}).
513 * <p>
514 * <strong>Note:</strong> In most cases -- depending on compiler support --
515 * the resulting view is automatically cast to the target class type. If
516 * the target class type is unconstrained, an explicit cast may be
517 * necessary.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 *
Alan Viverettedb7423c2017-03-31 13:13:58 -0400519 * @param id the ID to search for
520 * @return a view with given ID if found, or {@code null} otherwise
521 * @see View#findViewById(int)
Chris Craik6faa9e52018-01-11 10:46:10 -0800522 * @see Dialog#requireViewById(int)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 */
Alan Viverettedb7423c2017-03-31 13:13:58 -0400524 @Nullable
525 public <T extends View> T findViewById(@IdRes int id) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 return mWindow.findViewById(id);
527 }
528
529 /**
Chris Craik6faa9e52018-01-11 10:46:10 -0800530 * Finds the first descendant view with the given ID or throws an IllegalArgumentException if
531 * the ID is invalid (< 0), there is no matching view in the hierarchy, or the dialog has not
532 * yet been fully created (for example, via {@link #show()} or {@link #create()}).
533 * <p>
534 * <strong>Note:</strong> In most cases -- depending on compiler support --
535 * the resulting view is automatically cast to the target class type. If
536 * the target class type is unconstrained, an explicit cast may be
537 * necessary.
538 *
539 * @param id the ID to search for
540 * @return a view with given ID
541 * @see View#requireViewById(int)
542 * @see Dialog#findViewById(int)
543 */
544 @NonNull
545 public final <T extends View> T requireViewById(@IdRes int id) {
546 T view = findViewById(id);
547 if (view == null) {
548 throw new IllegalArgumentException("ID does not reference a View inside this Dialog");
549 }
550 return view;
551 }
552
553 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 * Set the screen content from a layout resource. The resource will be
555 * inflated, adding all top-level views to the screen.
556 *
557 * @param layoutResID Resource ID to be inflated.
558 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700559 public void setContentView(@LayoutRes int layoutResID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 mWindow.setContentView(layoutResID);
561 }
562
563 /**
564 * Set the screen content to an explicit view. This view is placed
565 * directly into the screen's view hierarchy. It can itself be a complex
Alan Viveretteec186702013-12-05 11:10:31 -0800566 * view hierarchy.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 *
568 * @param view The desired content to display.
569 */
Alan Viverette48728c22016-04-01 15:00:10 -0400570 public void setContentView(@NonNull View view) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 mWindow.setContentView(view);
572 }
573
574 /**
575 * Set the screen content to an explicit view. This view is placed
576 * directly into the screen's view hierarchy. It can itself be a complex
Alan Viverette48728c22016-04-01 15:00:10 -0400577 * view hierarchy.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 *
579 * @param view The desired content to display.
580 * @param params Layout parameters for the view.
581 */
Alan Viverette48728c22016-04-01 15:00:10 -0400582 public void setContentView(@NonNull View view, @Nullable ViewGroup.LayoutParams params) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 mWindow.setContentView(view, params);
584 }
585
586 /**
587 * Add an additional content view to the screen. Added after any existing
588 * ones in the screen -- existing views are NOT removed.
589 *
590 * @param view The desired content to display.
591 * @param params Layout parameters for the view.
592 */
Alan Viverette48728c22016-04-01 15:00:10 -0400593 public void addContentView(@NonNull View view, @Nullable ViewGroup.LayoutParams params) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 mWindow.addContentView(view, params);
595 }
596
597 /**
598 * Set the title text for this dialog's window.
599 *
600 * @param title The new text to display in the title.
601 */
Alan Viverette48728c22016-04-01 15:00:10 -0400602 public void setTitle(@Nullable CharSequence title) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 mWindow.setTitle(title);
604 mWindow.getAttributes().setTitle(title);
605 }
606
607 /**
608 * Set the title text for this dialog's window. The text is retrieved
609 * from the resources with the supplied identifier.
610 *
611 * @param titleId the title's text resource identifier
612 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700613 public void setTitle(@StringRes int titleId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 setTitle(mContext.getText(titleId));
615 }
616
617 /**
618 * A key was pressed down.
Emilie Robertsc1c572e2018-01-31 17:33:32 +0000619 * <p>
620 * If the focused view didn't want this event, this method is called.
621 * <p>
622 * Default implementation consumes {@link KeyEvent#KEYCODE_BACK KEYCODE_BACK}
623 * and, as of {@link android.os.Build.VERSION_CODES#P P}, {@link KeyEvent#KEYCODE_ESCAPE
624 * KEYCODE_ESCAPE} to later handle them in {@link #onKeyUp}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 * @see #onKeyUp
627 * @see android.view.KeyEvent
628 */
Alan Viverette48728c22016-04-01 15:00:10 -0400629 @Override
630 public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
Emilie Robertsc1c572e2018-01-31 17:33:32 +0000631 if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700632 event.startTracking();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 return true;
634 }
635
636 return false;
637 }
638
639 /**
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700640 * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
641 * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
642 * the event).
643 */
Alan Viverette48728c22016-04-01 15:00:10 -0400644 @Override
645 public boolean onKeyLongPress(int keyCode, @NonNull KeyEvent event) {
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700646 return false;
647 }
648
649 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 * A key was released.
Emilie Robertsc1c572e2018-01-31 17:33:32 +0000651 * <p>
652 * Default implementation consumes {@link KeyEvent#KEYCODE_BACK KEYCODE_BACK}
653 * and, as of {@link android.os.Build.VERSION_CODES#P P}, {@link KeyEvent#KEYCODE_ESCAPE
654 * KEYCODE_ESCAPE} to close the dialog.
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700655 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656 * @see #onKeyDown
Emilie Robertsc1c572e2018-01-31 17:33:32 +0000657 * @see android.view.KeyEvent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 */
Alan Viverette48728c22016-04-01 15:00:10 -0400659 @Override
660 public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
Emilie Robertsc1c572e2018-01-31 17:33:32 +0000661 if ((keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE)
662 && event.isTracking()
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700663 && !event.isCanceled()) {
664 onBackPressed();
665 return true;
666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800667 return false;
668 }
669
670 /**
671 * Default implementation of {@link KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent)
672 * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle
673 * the event).
674 */
Alan Viverette48728c22016-04-01 15:00:10 -0400675 @Override
676 public boolean onKeyMultiple(int keyCode, int repeatCount, @NonNull KeyEvent event) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800677 return false;
678 }
679
680 /**
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700681 * Called when the dialog has detected the user's press of the back
682 * key. The default implementation simply cancels the dialog (only if
683 * it is cancelable), but you can override this to do whatever you want.
684 */
685 public void onBackPressed() {
686 if (mCancelable) {
687 cancel();
688 }
689 }
Jeff Brown64da12a2011-01-04 19:57:47 -0800690
691 /**
Ken Wakasaf76a50c2012-03-09 19:56:35 +0900692 * Called when a key shortcut event is not handled by any of the views in the Dialog.
Jeff Brown64da12a2011-01-04 19:57:47 -0800693 * Override this method to implement global key shortcuts for the Dialog.
694 * Key shortcuts can also be implemented by setting the
695 * {@link MenuItem#setShortcut(char, char) shortcut} property of menu items.
696 *
697 * @param keyCode The value in event.getKeyCode().
698 * @param event Description of the key event.
699 * @return True if the key shortcut was handled.
700 */
Alan Viverette48728c22016-04-01 15:00:10 -0400701 public boolean onKeyShortcut(int keyCode, @NonNull KeyEvent event) {
Jeff Brown64da12a2011-01-04 19:57:47 -0800702 return false;
703 }
704
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700705 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800706 * Called when a touch screen event was not handled by any of the views
707 * under it. This is most useful to process touch events that happen outside
708 * of your window bounds, where there is no view to receive it.
709 *
710 * @param event The touch screen event being processed.
711 * @return Return true if you have consumed the event, false if you haven't.
712 * The default implementation will cancel the dialog when a touch
713 * happens outside of the window bounds.
714 */
Alan Viverette48728c22016-04-01 15:00:10 -0400715 public boolean onTouchEvent(@NonNull MotionEvent event) {
Dianne Hackborncfaf8872011-01-18 13:57:54 -0800716 if (mCancelable && mShowing && mWindow.shouldCloseOnTouch(mContext, event)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800717 cancel();
718 return true;
719 }
720
721 return false;
722 }
723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800724 /**
725 * Called when the trackball was moved and not handled by any of the
726 * views inside of the activity. So, for example, if the trackball moves
727 * while focus is on a button, you will receive a call here because
728 * buttons do not normally do anything with trackball events. The call
729 * here happens <em>before</em> trackball movements are converted to
730 * DPAD key events, which then get sent back to the view hierarchy, and
731 * will be processed at the point for things like focus navigation.
732 *
733 * @param event The trackball event being processed.
734 *
735 * @return Return true if you have consumed the event, false if you haven't.
736 * The default implementation always returns false.
737 */
Alan Viverette48728c22016-04-01 15:00:10 -0400738 public boolean onTrackballEvent(@NonNull MotionEvent event) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800739 return false;
740 }
Jeff Browncb1404e2011-01-15 18:14:15 -0800741
742 /**
743 * Called when a generic motion event was not handled by any of the
744 * views inside of the dialog.
745 * <p>
Jeff Brown33bbfd22011-02-24 20:55:35 -0800746 * Generic motion events describe joystick movements, mouse hovers, track pad
747 * touches, scroll wheel movements and other input events. The
Jeff Browncb1404e2011-01-15 18:14:15 -0800748 * {@link MotionEvent#getSource() source} of the motion event specifies
749 * the class of input that was received. Implementations of this method
750 * must examine the bits in the source before processing the event.
751 * The following code example shows how this is done.
Jeff Brown33bbfd22011-02-24 20:55:35 -0800752 * </p><p>
753 * Generic motion events with source class
754 * {@link android.view.InputDevice#SOURCE_CLASS_POINTER}
755 * are delivered to the view under the pointer. All other generic motion events are
756 * delivered to the focused view.
757 * </p><p>
758 * See {@link View#onGenericMotionEvent(MotionEvent)} for an example of how to
759 * handle this event.
Jeff Browncb1404e2011-01-15 18:14:15 -0800760 * </p>
Jeff Browncb1404e2011-01-15 18:14:15 -0800761 *
762 * @param event The generic motion event being processed.
763 *
764 * @return Return true if you have consumed the event, false if you haven't.
765 * The default implementation always returns false.
766 */
Alan Viverette48728c22016-04-01 15:00:10 -0400767 public boolean onGenericMotionEvent(@NonNull MotionEvent event) {
Jeff Browncb1404e2011-01-15 18:14:15 -0800768 return false;
769 }
770
Alan Viverette48728c22016-04-01 15:00:10 -0400771 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
773 if (mDecor != null) {
774 mWindowManager.updateViewLayout(mDecor, params);
775 }
776 }
777
Alan Viverette48728c22016-04-01 15:00:10 -0400778 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 public void onContentChanged() {
780 }
Wale Ogunwaleba7881c2015-08-01 19:28:29 -0700781
Alan Viverette48728c22016-04-01 15:00:10 -0400782 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783 public void onWindowFocusChanged(boolean hasFocus) {
784 }
785
Alan Viverette48728c22016-04-01 15:00:10 -0400786 @Override
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700787 public void onAttachedToWindow() {
788 }
Wale Ogunwaleba7881c2015-08-01 19:28:29 -0700789
Alan Viverette48728c22016-04-01 15:00:10 -0400790 @Override
Dianne Hackborn3be63c02009-08-20 19:31:38 -0700791 public void onDetachedFromWindow() {
792 }
Will Haldean Brownca6234e2014-02-12 10:23:41 -0800793
Adam Powell117b6952014-05-05 18:14:56 -0700794 /** @hide */
795 @Override
Ned Burns7d6cb912016-12-02 17:25:33 -0500796 public void onWindowDismissed(boolean finishTask, boolean suppressWindowTransition) {
Will Haldean Brownca6234e2014-02-12 10:23:41 -0800797 dismiss();
798 }
Wale Ogunwaleba7881c2015-08-01 19:28:29 -0700799
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800800 /**
Wale Ogunwaleba7881c2015-08-01 19:28:29 -0700801 * Called to process key events. You can override this to intercept all
802 * key events before they are dispatched to the window. Be sure to call
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800803 * this implementation for key events that should be handled normally.
Wale Ogunwaleba7881c2015-08-01 19:28:29 -0700804 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 * @param event The key event.
Wale Ogunwaleba7881c2015-08-01 19:28:29 -0700806 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 * @return boolean Return true if this event was consumed.
808 */
Alan Viverette48728c22016-04-01 15:00:10 -0400809 @Override
810 public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 if ((mOnKeyListener != null) && (mOnKeyListener.onKey(this, event.getKeyCode(), event))) {
812 return true;
813 }
814 if (mWindow.superDispatchKeyEvent(event)) {
815 return true;
816 }
Dianne Hackborn83fe3f52009-09-12 23:38:30 -0700817 return event.dispatch(this, mDecor != null
818 ? mDecor.getKeyDispatcherState() : null, this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 }
820
821 /**
Jeff Brown64da12a2011-01-04 19:57:47 -0800822 * Called to process a key shortcut event.
823 * You can override this to intercept all key shortcut events before they are
824 * dispatched to the window. Be sure to call this implementation for key shortcut
825 * events that should be handled normally.
826 *
827 * @param event The key shortcut event.
828 * @return True if this event was consumed.
829 */
Alan Viverette48728c22016-04-01 15:00:10 -0400830 @Override
831 public boolean dispatchKeyShortcutEvent(@NonNull KeyEvent event) {
Jeff Brown64da12a2011-01-04 19:57:47 -0800832 if (mWindow.superDispatchKeyShortcutEvent(event)) {
833 return true;
834 }
835 return onKeyShortcut(event.getKeyCode(), event);
836 }
837
838 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 * Called to process touch screen events. You can override this to
840 * intercept all touch screen events before they are dispatched to the
841 * window. Be sure to call this implementation for touch screen events
842 * that should be handled normally.
843 *
844 * @param ev The touch screen event.
845 *
846 * @return boolean Return true if this event was consumed.
847 */
Alan Viverette48728c22016-04-01 15:00:10 -0400848 @Override
849 public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 if (mWindow.superDispatchTouchEvent(ev)) {
851 return true;
852 }
853 return onTouchEvent(ev);
854 }
855
856 /**
857 * Called to process trackball events. You can override this to
858 * intercept all trackball events before they are dispatched to the
859 * window. Be sure to call this implementation for trackball events
860 * that should be handled normally.
861 *
862 * @param ev The trackball event.
863 *
864 * @return boolean Return true if this event was consumed.
865 */
Alan Viverette48728c22016-04-01 15:00:10 -0400866 @Override
867 public boolean dispatchTrackballEvent(@NonNull MotionEvent ev) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 if (mWindow.superDispatchTrackballEvent(ev)) {
869 return true;
870 }
871 return onTrackballEvent(ev);
872 }
873
Jeff Browncb1404e2011-01-15 18:14:15 -0800874 /**
875 * Called to process generic motion events. You can override this to
876 * intercept all generic motion events before they are dispatched to the
877 * window. Be sure to call this implementation for generic motion events
878 * that should be handled normally.
879 *
880 * @param ev The generic motion event.
881 *
882 * @return boolean Return true if this event was consumed.
883 */
Alan Viverette48728c22016-04-01 15:00:10 -0400884 @Override
885 public boolean dispatchGenericMotionEvent(@NonNull MotionEvent ev) {
Jeff Browncb1404e2011-01-15 18:14:15 -0800886 if (mWindow.superDispatchGenericMotionEvent(ev)) {
887 return true;
888 }
889 return onGenericMotionEvent(ev);
890 }
891
Alan Viverette48728c22016-04-01 15:00:10 -0400892 @Override
893 public boolean dispatchPopulateAccessibilityEvent(@NonNull AccessibilityEvent event) {
svetoslavganov75986cf2009-05-14 22:28:01 -0700894 event.setClassName(getClass().getName());
895 event.setPackageName(mContext.getPackageName());
896
897 LayoutParams params = getWindow().getAttributes();
Romain Guy980a9382010-01-08 15:06:28 -0800898 boolean isFullScreen = (params.width == LayoutParams.MATCH_PARENT) &&
899 (params.height == LayoutParams.MATCH_PARENT);
svetoslavganov75986cf2009-05-14 22:28:01 -0700900 event.setFullScreen(isFullScreen);
901
902 return false;
903 }
904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800905 /**
906 * @see Activity#onCreatePanelView(int)
907 */
Alan Viverette48728c22016-04-01 15:00:10 -0400908 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 public View onCreatePanelView(int featureId) {
910 return null;
911 }
912
913 /**
914 * @see Activity#onCreatePanelMenu(int, Menu)
915 */
Alan Viverette48728c22016-04-01 15:00:10 -0400916 @Override
917 public boolean onCreatePanelMenu(int featureId, @NonNull Menu menu) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918 if (featureId == Window.FEATURE_OPTIONS_PANEL) {
919 return onCreateOptionsMenu(menu);
920 }
921
922 return false;
923 }
924
925 /**
926 * @see Activity#onPreparePanel(int, View, Menu)
927 */
Alan Viverette48728c22016-04-01 15:00:10 -0400928 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 public boolean onPreparePanel(int featureId, View view, Menu menu) {
930 if (featureId == Window.FEATURE_OPTIONS_PANEL && menu != null) {
Alan Viverette48728c22016-04-01 15:00:10 -0400931 return onPrepareOptionsMenu(menu) && menu.hasVisibleItems();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 }
933 return true;
934 }
935
936 /**
937 * @see Activity#onMenuOpened(int, Menu)
938 */
Alan Viverette48728c22016-04-01 15:00:10 -0400939 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 public boolean onMenuOpened(int featureId, Menu menu) {
Adam Powell8515ee82010-11-30 14:09:55 -0800941 if (featureId == Window.FEATURE_ACTION_BAR) {
942 mActionBar.dispatchMenuVisibilityChanged(true);
943 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 return true;
945 }
946
947 /**
948 * @see Activity#onMenuItemSelected(int, MenuItem)
949 */
Alan Viverette48728c22016-04-01 15:00:10 -0400950 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 public boolean onMenuItemSelected(int featureId, MenuItem item) {
952 return false;
953 }
954
955 /**
956 * @see Activity#onPanelClosed(int, Menu)
957 */
Alan Viverette48728c22016-04-01 15:00:10 -0400958 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 public void onPanelClosed(int featureId, Menu menu) {
Adam Powell8515ee82010-11-30 14:09:55 -0800960 if (featureId == Window.FEATURE_ACTION_BAR) {
961 mActionBar.dispatchMenuVisibilityChanged(false);
962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 }
964
965 /**
966 * It is usually safe to proxy this call to the owner activity's
967 * {@link Activity#onCreateOptionsMenu(Menu)} if the client desires the same
968 * menu for this Dialog.
969 *
970 * @see Activity#onCreateOptionsMenu(Menu)
971 * @see #getOwnerActivity()
972 */
Alan Viverette48728c22016-04-01 15:00:10 -0400973 public boolean onCreateOptionsMenu(@NonNull Menu menu) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 return true;
975 }
976
977 /**
978 * It is usually safe to proxy this call to the owner activity's
979 * {@link Activity#onPrepareOptionsMenu(Menu)} if the client desires the
980 * same menu for this Dialog.
981 *
982 * @see Activity#onPrepareOptionsMenu(Menu)
983 * @see #getOwnerActivity()
984 */
Alan Viverette48728c22016-04-01 15:00:10 -0400985 public boolean onPrepareOptionsMenu(@NonNull Menu menu) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800986 return true;
987 }
988
989 /**
990 * @see Activity#onOptionsItemSelected(MenuItem)
991 */
Alan Viverette48728c22016-04-01 15:00:10 -0400992 public boolean onOptionsItemSelected(@NonNull MenuItem item) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 return false;
994 }
995
996 /**
997 * @see Activity#onOptionsMenuClosed(Menu)
998 */
Alan Viverette48728c22016-04-01 15:00:10 -0400999 public void onOptionsMenuClosed(@NonNull Menu menu) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 }
1001
1002 /**
1003 * @see Activity#openOptionsMenu()
1004 */
1005 public void openOptionsMenu() {
Jose Lima7a22fc62015-01-23 17:24:22 -08001006 if (mWindow.hasFeature(Window.FEATURE_OPTIONS_PANEL)) {
1007 mWindow.openPanel(Window.FEATURE_OPTIONS_PANEL, null);
1008 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001009 }
Jose Lima7a22fc62015-01-23 17:24:22 -08001010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 /**
1012 * @see Activity#closeOptionsMenu()
1013 */
1014 public void closeOptionsMenu() {
Jose Lima7a22fc62015-01-23 17:24:22 -08001015 if (mWindow.hasFeature(Window.FEATURE_OPTIONS_PANEL)) {
1016 mWindow.closePanel(Window.FEATURE_OPTIONS_PANEL);
1017 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 }
1019
1020 /**
Adam Powelle67a9dc2010-08-17 17:28:56 -07001021 * @see Activity#invalidateOptionsMenu()
1022 */
1023 public void invalidateOptionsMenu() {
Jose Lima7a22fc62015-01-23 17:24:22 -08001024 if (mWindow.hasFeature(Window.FEATURE_OPTIONS_PANEL)) {
1025 mWindow.invalidatePanelMenu(Window.FEATURE_OPTIONS_PANEL);
1026 }
Adam Powelle67a9dc2010-08-17 17:28:56 -07001027 }
1028
1029 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 * @see Activity#onCreateContextMenu(ContextMenu, View, ContextMenuInfo)
1031 */
Alan Viverette48728c22016-04-01 15:00:10 -04001032 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001033 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
1034 }
1035
1036 /**
1037 * @see Activity#registerForContextMenu(View)
1038 */
Alan Viverette48728c22016-04-01 15:00:10 -04001039 public void registerForContextMenu(@NonNull View view) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001040 view.setOnCreateContextMenuListener(this);
1041 }
1042
1043 /**
1044 * @see Activity#unregisterForContextMenu(View)
1045 */
Alan Viverette48728c22016-04-01 15:00:10 -04001046 public void unregisterForContextMenu(@NonNull View view) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001047 view.setOnCreateContextMenuListener(null);
1048 }
1049
1050 /**
1051 * @see Activity#openContextMenu(View)
1052 */
Alan Viverette48728c22016-04-01 15:00:10 -04001053 public void openContextMenu(@NonNull View view) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 view.showContextMenu();
1055 }
1056
1057 /**
1058 * @see Activity#onContextItemSelected(MenuItem)
1059 */
Alan Viverette48728c22016-04-01 15:00:10 -04001060 public boolean onContextItemSelected(@NonNull MenuItem item) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 return false;
1062 }
Clara Bayarri4423d912015-03-02 19:42:48 +00001063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001064 /**
1065 * @see Activity#onContextMenuClosed(Menu)
1066 */
Alan Viverette48728c22016-04-01 15:00:10 -04001067 public void onContextMenuClosed(@NonNull Menu menu) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001068 }
Clara Bayarri4423d912015-03-02 19:42:48 +00001069
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001070 /**
1071 * This hook is called when the user signals the desire to start a search.
1072 */
Alan Viverette48728c22016-04-01 15:00:10 -04001073 @Override
1074 public boolean onSearchRequested(@NonNull SearchEvent searchEvent) {
Tim Kilbourn6a975b32015-04-09 17:14:34 -07001075 mSearchEvent = searchEvent;
1076 return onSearchRequested();
1077 }
1078
1079 /**
1080 * This hook is called when the user signals the desire to start a search.
1081 */
Alan Viverette48728c22016-04-01 15:00:10 -04001082 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001083 public boolean onSearchRequested() {
Karl Rosaen53d24af2009-07-14 14:58:10 -07001084 final SearchManager searchManager = (SearchManager) mContext
1085 .getSystemService(Context.SEARCH_SERVICE);
1086
Bjorn Bringertb8144a92010-02-22 20:48:57 +00001087 // associate search with owner activity
Karl Rosaen7bafed82009-09-04 11:15:21 -07001088 final ComponentName appName = getAssociatedActivity();
lge-aosp06ca9972011-03-15 10:25:57 +09001089 if (appName != null && searchManager.getSearchableInfo(appName) != null) {
Bjorn Bringertb8144a92010-02-22 20:48:57 +00001090 searchManager.startSearch(null, false, appName, null, false);
1091 dismiss();
1092 return true;
1093 } else {
1094 return false;
1095 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 }
1097
Clara Bayarri4423d912015-03-02 19:42:48 +00001098 /**
Tim Kilbourn6a975b32015-04-09 17:14:34 -07001099 * During the onSearchRequested() callbacks, this function will return the
1100 * {@link SearchEvent} that triggered the callback, if it exists.
1101 *
1102 * @return SearchEvent The SearchEvent that triggered the {@link
1103 * #onSearchRequested} callback.
1104 */
Alan Viverette48728c22016-04-01 15:00:10 -04001105 public final @Nullable SearchEvent getSearchEvent() {
Tim Kilbourn6a975b32015-04-09 17:14:34 -07001106 return mSearchEvent;
1107 }
1108
Clara Bayarri4423d912015-03-02 19:42:48 +00001109 @Override
Adam Powelldebf3be2010-11-15 18:58:48 -08001110 public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
Clara Bayarri4423d912015-03-02 19:42:48 +00001111 if (mActionBar != null && mActionModeTypeStarting == ActionMode.TYPE_PRIMARY) {
Adam Powelldec9dfd2010-08-09 15:27:54 -07001112 return mActionBar.startActionMode(callback);
1113 }
Adam Powell6e346362010-07-23 10:18:23 -07001114 return null;
1115 }
1116
Clara Bayarri4423d912015-03-02 19:42:48 +00001117 @Override
1118 public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) {
1119 try {
1120 mActionModeTypeStarting = type;
1121 return onWindowStartingActionMode(callback);
1122 } finally {
1123 mActionModeTypeStarting = ActionMode.TYPE_PRIMARY;
1124 }
1125 }
1126
1127 /**
1128 * {@inheritDoc}
Adam Powellcfe9aee2011-11-01 14:56:27 -07001129 *
1130 * Note that if you override this method you should always call through
1131 * to the superclass implementation by calling super.onActionModeStarted(mode).
1132 */
Alan Viverette48728c22016-04-01 15:00:10 -04001133 @Override
Tor Norbyec615c6f2015-03-02 10:11:44 -08001134 @CallSuper
Adam Powelldebf3be2010-11-15 18:58:48 -08001135 public void onActionModeStarted(ActionMode mode) {
Adam Powellcfe9aee2011-11-01 14:56:27 -07001136 mActionMode = mode;
Adam Powelldebf3be2010-11-15 18:58:48 -08001137 }
1138
Adam Powellcfe9aee2011-11-01 14:56:27 -07001139 /**
1140 * {@inheritDoc}
1141 *
1142 * Note that if you override this method you should always call through
1143 * to the superclass implementation by calling super.onActionModeFinished(mode).
1144 */
Alan Viverette48728c22016-04-01 15:00:10 -04001145 @Override
Tor Norbyec615c6f2015-03-02 10:11:44 -08001146 @CallSuper
Adam Powelldebf3be2010-11-15 18:58:48 -08001147 public void onActionModeFinished(ActionMode mode) {
Adam Powellcfe9aee2011-11-01 14:56:27 -07001148 if (mode == mActionMode) {
1149 mActionMode = null;
1150 }
Adam Powelldebf3be2010-11-15 18:58:48 -08001151 }
1152
Karl Rosaen7bafed82009-09-04 11:15:21 -07001153 /**
Adam Powelldec9dfd2010-08-09 15:27:54 -07001154 * @return The activity associated with this dialog, or null if there is no associated activity.
Karl Rosaen7bafed82009-09-04 11:15:21 -07001155 */
1156 private ComponentName getAssociatedActivity() {
1157 Activity activity = mOwnerActivity;
1158 Context context = getContext();
1159 while (activity == null && context != null) {
1160 if (context instanceof Activity) {
1161 activity = (Activity) context; // found it!
1162 } else {
1163 context = (context instanceof ContextWrapper) ?
1164 ((ContextWrapper) context).getBaseContext() : // unwrap one level
1165 null; // done
1166 }
1167 }
1168 return activity == null ? null : activity.getComponentName();
1169 }
1170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171
1172 /**
1173 * Request that key events come to this dialog. Use this if your
1174 * dialog has no views with focus, but the dialog still wants
1175 * a chance to process key events.
1176 *
1177 * @param get true if the dialog should receive key events, false otherwise
1178 * @see android.view.Window#takeKeyEvents
1179 */
1180 public void takeKeyEvents(boolean get) {
1181 mWindow.takeKeyEvents(get);
1182 }
1183
1184 /**
1185 * Enable extended window features. This is a convenience for calling
1186 * {@link android.view.Window#requestFeature getWindow().requestFeature()}.
1187 *
1188 * @param featureId The desired feature as defined in
1189 * {@link android.view.Window}.
1190 * @return Returns true if the requested feature is supported and now
1191 * enabled.
1192 *
1193 * @see android.view.Window#requestFeature
1194 */
1195 public final boolean requestWindowFeature(int featureId) {
1196 return getWindow().requestFeature(featureId);
1197 }
1198
1199 /**
1200 * Convenience for calling
1201 * {@link android.view.Window#setFeatureDrawableResource}.
1202 */
Tor Norbye7b9c9122013-05-30 16:48:33 -07001203 public final void setFeatureDrawableResource(int featureId, @DrawableRes int resId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001204 getWindow().setFeatureDrawableResource(featureId, resId);
1205 }
1206
1207 /**
1208 * Convenience for calling
1209 * {@link android.view.Window#setFeatureDrawableUri}.
1210 */
Alan Viverette48728c22016-04-01 15:00:10 -04001211 public final void setFeatureDrawableUri(int featureId, @Nullable Uri uri) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001212 getWindow().setFeatureDrawableUri(featureId, uri);
1213 }
1214
1215 /**
1216 * Convenience for calling
1217 * {@link android.view.Window#setFeatureDrawable(int, Drawable)}.
1218 */
Alan Viverette48728c22016-04-01 15:00:10 -04001219 public final void setFeatureDrawable(int featureId, @Nullable Drawable drawable) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001220 getWindow().setFeatureDrawable(featureId, drawable);
1221 }
1222
1223 /**
1224 * Convenience for calling
1225 * {@link android.view.Window#setFeatureDrawableAlpha}.
1226 */
1227 public final void setFeatureDrawableAlpha(int featureId, int alpha) {
1228 getWindow().setFeatureDrawableAlpha(featureId, alpha);
1229 }
1230
Alan Viverette48728c22016-04-01 15:00:10 -04001231 public @NonNull LayoutInflater getLayoutInflater() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 return getWindow().getLayoutInflater();
1233 }
1234
1235 /**
1236 * Sets whether this dialog is cancelable with the
1237 * {@link KeyEvent#KEYCODE_BACK BACK} key.
1238 */
1239 public void setCancelable(boolean flag) {
1240 mCancelable = flag;
Michael Kwanf7964be2016-11-30 16:44:33 -08001241 updateWindowForCancelable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001242 }
1243
1244 /**
1245 * Sets whether this dialog is canceled when touched outside the window's
1246 * bounds. If setting to true, the dialog is set to be cancelable if not
1247 * already set.
1248 *
1249 * @param cancel Whether the dialog should be canceled when touched outside
1250 * the window.
1251 */
1252 public void setCanceledOnTouchOutside(boolean cancel) {
1253 if (cancel && !mCancelable) {
1254 mCancelable = true;
Michael Kwanf7964be2016-11-30 16:44:33 -08001255 updateWindowForCancelable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256 }
1257
Dianne Hackborncfaf8872011-01-18 13:57:54 -08001258 mWindow.setCloseOnTouchOutside(cancel);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001259 }
1260
1261 /**
1262 * Cancel the dialog. This is essentially the same as calling {@link #dismiss()}, but it will
1263 * also call your {@link DialogInterface.OnCancelListener} (if registered).
1264 */
Alan Viverette48728c22016-04-01 15:00:10 -04001265 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 public void cancel() {
Dianne Hackborn8b4cac12011-01-03 13:58:14 -08001267 if (!mCanceled && mCancelMessage != null) {
1268 mCanceled = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 // Obtain a new message so this dialog can be re-used
1270 Message.obtain(mCancelMessage).sendToTarget();
1271 }
1272 dismiss();
1273 }
1274
1275 /**
1276 * Set a listener to be invoked when the dialog is canceled.
Adam Powell7f02dc52012-08-27 13:35:16 -07001277 *
1278 * <p>This will only be invoked when the dialog is canceled.
1279 * Cancel events alone will not capture all ways that
1280 * the dialog might be dismissed. If the creator needs
1281 * to know when a dialog is dismissed in general, use
1282 * {@link #setOnDismissListener}.</p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 *
1284 * @param listener The {@link DialogInterface.OnCancelListener} to use.
1285 */
Alan Viverette48728c22016-04-01 15:00:10 -04001286 public void setOnCancelListener(@Nullable OnCancelListener listener) {
Dianne Hackbornf812fee2011-01-25 14:54:29 -08001287 if (mCancelAndDismissTaken != null) {
1288 throw new IllegalStateException(
1289 "OnCancelListener is already taken by "
1290 + mCancelAndDismissTaken + " and can not be replaced.");
1291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 if (listener != null) {
Romain Guy045163a2009-07-14 13:59:33 -07001293 mCancelMessage = mListenersHandler.obtainMessage(CANCEL, listener);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294 } else {
1295 mCancelMessage = null;
1296 }
1297 }
1298
1299 /**
1300 * Set a message to be sent when the dialog is canceled.
1301 * @param msg The msg to send when the dialog is canceled.
1302 * @see #setOnCancelListener(android.content.DialogInterface.OnCancelListener)
1303 */
Alan Viverette48728c22016-04-01 15:00:10 -04001304 public void setCancelMessage(@Nullable Message msg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 mCancelMessage = msg;
1306 }
1307
1308 /**
1309 * Set a listener to be invoked when the dialog is dismissed.
1310 * @param listener The {@link DialogInterface.OnDismissListener} to use.
1311 */
Alan Viverette48728c22016-04-01 15:00:10 -04001312 public void setOnDismissListener(@Nullable OnDismissListener listener) {
Dianne Hackbornf812fee2011-01-25 14:54:29 -08001313 if (mCancelAndDismissTaken != null) {
1314 throw new IllegalStateException(
1315 "OnDismissListener is already taken by "
1316 + mCancelAndDismissTaken + " and can not be replaced.");
1317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 if (listener != null) {
Romain Guy045163a2009-07-14 13:59:33 -07001319 mDismissMessage = mListenersHandler.obtainMessage(DISMISS, listener);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 } else {
1321 mDismissMessage = null;
1322 }
1323 }
1324
1325 /**
Romain Guy045163a2009-07-14 13:59:33 -07001326 * Sets a listener to be invoked when the dialog is shown.
Ficus Kirkpatrick130a8b72010-01-14 15:39:43 -08001327 * @param listener The {@link DialogInterface.OnShowListener} to use.
Romain Guy045163a2009-07-14 13:59:33 -07001328 */
Alan Viverette48728c22016-04-01 15:00:10 -04001329 public void setOnShowListener(@Nullable OnShowListener listener) {
Romain Guy045163a2009-07-14 13:59:33 -07001330 if (listener != null) {
1331 mShowMessage = mListenersHandler.obtainMessage(SHOW, listener);
1332 } else {
1333 mShowMessage = null;
1334 }
1335 }
1336
1337 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001338 * Set a message to be sent when the dialog is dismissed.
1339 * @param msg The msg to send when the dialog is dismissed.
1340 */
Alan Viverette48728c22016-04-01 15:00:10 -04001341 public void setDismissMessage(@Nullable Message msg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001342 mDismissMessage = msg;
1343 }
1344
Dianne Hackbornf812fee2011-01-25 14:54:29 -08001345 /** @hide */
Alan Viverette48728c22016-04-01 15:00:10 -04001346 public boolean takeCancelAndDismissListeners(@Nullable String msg,
1347 @Nullable OnCancelListener cancel, @Nullable OnDismissListener dismiss) {
Dianne Hackbornf812fee2011-01-25 14:54:29 -08001348 if (mCancelAndDismissTaken != null) {
1349 mCancelAndDismissTaken = null;
1350 } else if (mCancelMessage != null || mDismissMessage != null) {
1351 return false;
1352 }
1353
1354 setOnCancelListener(cancel);
1355 setOnDismissListener(dismiss);
1356 mCancelAndDismissTaken = msg;
1357
1358 return true;
1359 }
1360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361 /**
1362 * By default, this will use the owner Activity's suggested stream type.
1363 *
1364 * @see Activity#setVolumeControlStream(int)
1365 * @see #setOwnerActivity(Activity)
1366 */
1367 public final void setVolumeControlStream(int streamType) {
1368 getWindow().setVolumeControlStream(streamType);
1369 }
1370
1371 /**
1372 * @see Activity#getVolumeControlStream()
1373 */
1374 public final int getVolumeControlStream() {
1375 return getWindow().getVolumeControlStream();
1376 }
1377
1378 /**
1379 * Sets the callback that will be called if a key is dispatched to the dialog.
1380 */
Alan Viverette48728c22016-04-01 15:00:10 -04001381 public void setOnKeyListener(@Nullable OnKeyListener onKeyListener) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 mOnKeyListener = onKeyListener;
1383 }
1384
Romain Guy045163a2009-07-14 13:59:33 -07001385 private static final class ListenersHandler extends Handler {
Alan Viverette48728c22016-04-01 15:00:10 -04001386 private final WeakReference<DialogInterface> mDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387
Romain Guy045163a2009-07-14 13:59:33 -07001388 public ListenersHandler(Dialog dialog) {
Alan Viverette48728c22016-04-01 15:00:10 -04001389 mDialog = new WeakReference<>(dialog);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 }
1391
1392 @Override
1393 public void handleMessage(Message msg) {
1394 switch (msg.what) {
1395 case DISMISS:
1396 ((OnDismissListener) msg.obj).onDismiss(mDialog.get());
1397 break;
1398 case CANCEL:
1399 ((OnCancelListener) msg.obj).onCancel(mDialog.get());
1400 break;
Romain Guy045163a2009-07-14 13:59:33 -07001401 case SHOW:
1402 ((OnShowListener) msg.obj).onShow(mDialog.get());
1403 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404 }
1405 }
1406 }
Michael Kwanf7964be2016-11-30 16:44:33 -08001407
1408 private void updateWindowForCancelable() {
1409 mWindow.setCloseOnSwipeEnabled(mCancelable);
1410 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001411}