blob: 06105f532eb62029bb2440fb6ac228733de4dd9a [file] [log] [blame]
Adrian Roos50052442014-07-17 23:35:18 +02001/*
2 * Copyright (C) 2014 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 com.android.systemui.statusbar.phone;
18
Adrian Roos50052442014-07-17 23:35:18 +020019import android.app.AlertDialog;
Jason Monk9ca18482017-08-01 10:38:02 -040020import android.app.Dialog;
21import android.content.BroadcastReceiver;
Adrian Roos50052442014-07-17 23:35:18 +020022import android.content.Context;
Jason Monk9ca18482017-08-01 10:38:02 -040023import android.content.Intent;
24import android.content.IntentFilter;
25import android.os.UserHandle;
Tiger Huang4a7835f2019-11-06 00:07:56 +080026import android.view.Window;
27import android.view.WindowInsets.Type;
Adrian Roos50052442014-07-17 23:35:18 +020028import android.view.WindowManager;
Jason Monk9ca18482017-08-01 10:38:02 -040029import android.view.WindowManager.LayoutParams;
Adrian Roos50052442014-07-17 23:35:18 +020030
Jason Monk9ca18482017-08-01 10:38:02 -040031import com.android.systemui.Dependency;
Winsonc0d70582016-01-29 10:24:39 -080032import com.android.systemui.R;
Fabian Kozynskiff5e91f2019-09-24 15:38:08 -040033import com.android.systemui.broadcast.BroadcastDispatcher;
Lucas Dupinc8f16e82019-09-17 18:24:50 -040034import com.android.systemui.statusbar.policy.KeyguardStateController;
Winsonc0d70582016-01-29 10:24:39 -080035
Amin Shaikh6be53682018-05-02 15:59:44 -040036
Adrian Roos50052442014-07-17 23:35:18 +020037/**
38 * Base class for dialogs that should appear over panels and keyguard.
Satoshi Sanno3756b092019-05-29 16:39:50 +090039 * The SystemUIDialog registers a listener for the screen off / close system dialogs broadcast,
40 * and dismisses itself when it receives the broadcast.
Adrian Roos50052442014-07-17 23:35:18 +020041 */
42public class SystemUIDialog extends AlertDialog {
43
John Spurlock1bb480a2014-08-02 17:12:43 -040044 private final Context mContext;
Satoshi Sanno3756b092019-05-29 16:39:50 +090045 private final DismissReceiver mDismissReceiver;
John Spurlock1bb480a2014-08-02 17:12:43 -040046
Adrian Roos50052442014-07-17 23:35:18 +020047 public SystemUIDialog(Context context) {
Jason Monk5db8a412015-10-21 15:16:23 -070048 this(context, R.style.Theme_SystemUI_Dialog);
49 }
50
51 public SystemUIDialog(Context context, int theme) {
52 super(context, theme);
John Spurlock1bb480a2014-08-02 17:12:43 -040053 mContext = context;
54
Jason Monk39c98e62016-03-16 09:18:35 -040055 applyFlags(this);
Adrian Roos50052442014-07-17 23:35:18 +020056 WindowManager.LayoutParams attrs = getWindow().getAttributes();
John Spurlock35134602014-07-24 18:10:48 -040057 attrs.setTitle(getClass().getSimpleName());
Adrian Roos50052442014-07-17 23:35:18 +020058 getWindow().setAttributes(attrs);
phweiss679dc242017-07-05 18:54:54 +020059
Satoshi Sanno3756b092019-05-29 16:39:50 +090060 mDismissReceiver = new DismissReceiver(this);
61 }
62
63 @Override
64 protected void onStart() {
65 super.onStart();
66 mDismissReceiver.register();
67 }
68
69 @Override
70 protected void onStop() {
71 super.onStop();
72 mDismissReceiver.unregister();
Adrian Roos50052442014-07-17 23:35:18 +020073 }
John Spurlock1bb480a2014-08-02 17:12:43 -040074
75 public void setShowForAllUsers(boolean show) {
Jason Monk39c98e62016-03-16 09:18:35 -040076 setShowForAllUsers(this, show);
John Spurlock1bb480a2014-08-02 17:12:43 -040077 }
78
79 public void setMessage(int resId) {
80 setMessage(mContext.getString(resId));
81 }
82
83 public void setPositiveButton(int resId, OnClickListener onClick) {
84 setButton(BUTTON_POSITIVE, mContext.getString(resId), onClick);
85 }
86
87 public void setNegativeButton(int resId, OnClickListener onClick) {
88 setButton(BUTTON_NEGATIVE, mContext.getString(resId), onClick);
89 }
Jason Monk39c98e62016-03-16 09:18:35 -040090
Makoto Onuki41d5ccf2018-04-03 11:46:02 -070091 public void setNeutralButton(int resId, OnClickListener onClick) {
92 setButton(BUTTON_NEUTRAL, mContext.getString(resId), onClick);
93 }
94
Jason Monk9ca18482017-08-01 10:38:02 -040095 public static void setShowForAllUsers(Dialog dialog, boolean show) {
Jason Monk39c98e62016-03-16 09:18:35 -040096 if (show) {
97 dialog.getWindow().getAttributes().privateFlags |=
Roshan Piusa3f89c62019-10-11 08:50:53 -070098 WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
Jason Monk39c98e62016-03-16 09:18:35 -040099 } else {
100 dialog.getWindow().getAttributes().privateFlags &=
Roshan Piusa3f89c62019-10-11 08:50:53 -0700101 ~WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
Jason Monk39c98e62016-03-16 09:18:35 -0400102 }
103 }
104
Jason Monk9ca18482017-08-01 10:38:02 -0400105 public static void setWindowOnTop(Dialog dialog) {
Lucas Dupinc8f16e82019-09-17 18:24:50 -0400106 if (Dependency.get(KeyguardStateController.class).isShowing()) {
Tiger Huang4a7835f2019-11-06 00:07:56 +0800107 final Window window = dialog.getWindow();
108 window.setType(LayoutParams.TYPE_STATUS_BAR_PANEL);
Tiger Huang52724442020-01-20 21:38:42 +0800109 window.getAttributes().setFitInsetsTypes(
110 window.getAttributes().getFitInsetsTypes() & ~Type.statusBars());
Jason Monk9ca18482017-08-01 10:38:02 -0400111 } else {
112 dialog.getWindow().setType(LayoutParams.TYPE_STATUS_BAR_SUB_PANEL);
113 }
114 }
115
Jason Monk54ff0ef2017-07-25 14:44:28 -0400116 public static AlertDialog applyFlags(AlertDialog dialog) {
Tiger Huang4a7835f2019-11-06 00:07:56 +0800117 final Window window = dialog.getWindow();
118 window.setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
119 window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
Jason Monk39c98e62016-03-16 09:18:35 -0400120 | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
Tiger Huang52724442020-01-20 21:38:42 +0800121 window.getAttributes().setFitInsetsTypes(
122 window.getAttributes().getFitInsetsTypes() & ~Type.statusBars());
Jason Monk54ff0ef2017-07-25 14:44:28 -0400123 return dialog;
Jason Monk39c98e62016-03-16 09:18:35 -0400124 }
Jason Monk9ca18482017-08-01 10:38:02 -0400125
Satoshi Sanno3756b092019-05-29 16:39:50 +0900126 /**
127 * Registers a listener that dismisses the given dialog when it receives
128 * the screen off / close system dialogs broadcast.
129 * <p>
130 * <strong>Note:</strong> Don't call dialog.setOnDismissListener() after
131 * calling this because it causes a leak of BroadcastReceiver.
132 *
133 * @param dialog The dialog to be associated with the listener.
134 */
Jason Monk9ca18482017-08-01 10:38:02 -0400135 public static void registerDismissListener(Dialog dialog) {
Amin Shaikh6be53682018-05-02 15:59:44 -0400136 DismissReceiver dismissReceiver = new DismissReceiver(dialog);
Satoshi Sanno3756b092019-05-29 16:39:50 +0900137 dialog.setOnDismissListener(d -> dismissReceiver.unregister());
Amin Shaikh6be53682018-05-02 15:59:44 -0400138 dismissReceiver.register();
Jason Monk9ca18482017-08-01 10:38:02 -0400139 }
Amin Shaikh6be53682018-05-02 15:59:44 -0400140
Satoshi Sanno3756b092019-05-29 16:39:50 +0900141 private static class DismissReceiver extends BroadcastReceiver {
Amin Shaikh6be53682018-05-02 15:59:44 -0400142 private static final IntentFilter INTENT_FILTER = new IntentFilter();
143 static {
144 INTENT_FILTER.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
145 INTENT_FILTER.addAction(Intent.ACTION_SCREEN_OFF);
146 }
147
148 private final Dialog mDialog;
149 private boolean mRegistered;
Fabian Kozynskiff5e91f2019-09-24 15:38:08 -0400150 private final BroadcastDispatcher mBroadcastDispatcher;
Amin Shaikh6be53682018-05-02 15:59:44 -0400151
152 DismissReceiver(Dialog dialog) {
153 mDialog = dialog;
Fabian Kozynskiff5e91f2019-09-24 15:38:08 -0400154 mBroadcastDispatcher = Dependency.get(BroadcastDispatcher.class);
Amin Shaikh6be53682018-05-02 15:59:44 -0400155 }
156
157 void register() {
Fabian Kozynskiff5e91f2019-09-24 15:38:08 -0400158 mBroadcastDispatcher.registerReceiver(this, INTENT_FILTER, null, UserHandle.CURRENT);
Amin Shaikh6be53682018-05-02 15:59:44 -0400159 mRegistered = true;
160 }
161
Satoshi Sanno3756b092019-05-29 16:39:50 +0900162 void unregister() {
Amin Shaikh6be53682018-05-02 15:59:44 -0400163 if (mRegistered) {
Fabian Kozynskiff5e91f2019-09-24 15:38:08 -0400164 mBroadcastDispatcher.unregisterReceiver(this);
Amin Shaikh6be53682018-05-02 15:59:44 -0400165 mRegistered = false;
166 }
167 }
Satoshi Sanno3756b092019-05-29 16:39:50 +0900168
169 @Override
170 public void onReceive(Context context, Intent intent) {
171 mDialog.dismiss();
172 }
173 }
174}