blob: d8e3984a2bbb4e29c0626f52053445bc5c9b7453 [file] [log] [blame]
Jason Monk3d5f5512014-07-25 11:17:28 -04001/*
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 */
16package com.android.systemui.qs;
17
18import android.app.AlertDialog;
19import android.content.Context;
20import android.content.DialogInterface;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010021import android.content.Intent;
Jason Monk3d5f5512014-07-25 11:17:28 -040022import android.os.Handler;
23import android.os.Looper;
24import android.os.Message;
Robin Lee9cb1d5f2015-04-16 17:01:49 +010025import android.os.UserHandle;
Jason Monk3d5f5512014-07-25 11:17:28 -040026import android.util.Log;
Jason Monk3d5f5512014-07-25 11:17:28 -040027import android.view.LayoutInflater;
28import android.view.View;
29import android.view.View.OnClickListener;
Jason Monk3d5f5512014-07-25 11:17:28 -040030import android.widget.ImageView;
31import android.widget.TextView;
32
Jorim Jaggie17c4b42014-08-26 17:27:31 +020033import com.android.systemui.FontSizeUtils;
Jason Monk3d5f5512014-07-25 11:17:28 -040034import com.android.systemui.R;
35import com.android.systemui.statusbar.phone.QSTileHost;
36import com.android.systemui.statusbar.phone.SystemUIDialog;
37import com.android.systemui.statusbar.policy.SecurityController;
Jason Monk3d5f5512014-07-25 11:17:28 -040038
39public class QSFooter implements OnClickListener, DialogInterface.OnClickListener {
40 protected static final String TAG = "QSFooter";
41 protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
42
Robin Lee9cb1d5f2015-04-16 17:01:49 +010043 private static final String ACTION_VPN_SETTINGS = "android.net.vpn.SETTINGS";
44
Jason Monk3d5f5512014-07-25 11:17:28 -040045 private final View mRootView;
46 private final TextView mFooterText;
47 private final ImageView mFooterIcon;
48 private final Context mContext;
49 private final Callback mCallback = new Callback();
50
51 private SecurityController mSecurityController;
52 private AlertDialog mDialog;
53 private QSTileHost mHost;
54 private Handler mHandler;
Selim Cinek24ac55e2014-08-27 12:51:45 +020055 private final Handler mMainHandler;
Jason Monk3d5f5512014-07-25 11:17:28 -040056
Jason Monkb1c2f3b2014-08-20 10:17:00 -040057 private boolean mIsVisible;
58 private boolean mIsIconVisible;
59 private int mFooterTextId;
60
Jason Monk3d5f5512014-07-25 11:17:28 -040061 public QSFooter(QSPanel qsPanel, Context context) {
62 mRootView = LayoutInflater.from(context)
63 .inflate(R.layout.quick_settings_footer, qsPanel, false);
64 mRootView.setOnClickListener(this);
65 mFooterText = (TextView) mRootView.findViewById(R.id.footer_text);
66 mFooterIcon = (ImageView) mRootView.findViewById(R.id.footer_icon);
67 mContext = context;
Selim Cinek24ac55e2014-08-27 12:51:45 +020068 mMainHandler = new Handler();
Jason Monk3d5f5512014-07-25 11:17:28 -040069 }
70
71 public void setHost(QSTileHost host) {
72 mHost = host;
73 mSecurityController = host.getSecurityController();
74 mHandler = new H(host.getLooper());
75 }
76
77 public void setListening(boolean listening) {
78 if (listening) {
79 mSecurityController.addCallback(mCallback);
80 } else {
81 mSecurityController.removeCallback(mCallback);
82 }
83 }
84
Jorim Jaggie17c4b42014-08-26 17:27:31 +020085 public void onConfigurationChanged() {
86 FontSizeUtils.updateFontSize(mFooterText, R.dimen.qs_tile_text_size);
87 }
88
Jason Monk3d5f5512014-07-25 11:17:28 -040089 public View getView() {
90 return mRootView;
91 }
92
93 public boolean hasFooter() {
94 return mRootView.getVisibility() != View.GONE;
95 }
96
97 @Override
98 public void onClick(View v) {
99 mHandler.sendEmptyMessage(H.CLICK);
100 }
101
102 private void handleClick() {
103 mHost.collapsePanels();
104 // TODO: Delay dialog creation until after panels are collapsed.
105 createDialog();
106 }
107
108 public void refreshState() {
109 mHandler.sendEmptyMessage(H.REFRESH_STATE);
110 }
111
112 private void handleRefreshState() {
113 if (mSecurityController.hasDeviceOwner()) {
Jason Monkb1c2f3b2014-08-20 10:17:00 -0400114 mFooterTextId = R.string.device_owned_footer;
115 mIsVisible = true;
116 mIsIconVisible = false;
Selim Cinek24ac55e2014-08-27 12:51:45 +0200117 } else if (mSecurityController.hasProfileOwner()) {
118 mFooterTextId = R.string.profile_owned_footer;
119 mIsVisible = true;
120 mIsIconVisible = false;
Jason Monk3d5f5512014-07-25 11:17:28 -0400121 } else if (mSecurityController.isVpnEnabled()) {
Jason Monkb1c2f3b2014-08-20 10:17:00 -0400122 mFooterTextId = R.string.vpn_footer;
123 mIsVisible = true;
124 mIsIconVisible = true;
Jason Monk3d5f5512014-07-25 11:17:28 -0400125 } else {
Jason Monkb1c2f3b2014-08-20 10:17:00 -0400126 mIsVisible = false;
Selim Cinek24ac55e2014-08-27 12:51:45 +0200127 mIsIconVisible = false;
Jason Monk3d5f5512014-07-25 11:17:28 -0400128 }
Selim Cinek24ac55e2014-08-27 12:51:45 +0200129 mMainHandler.post(mUpdateDisplayState);
Jason Monk3d5f5512014-07-25 11:17:28 -0400130 }
131
132 @Override
133 public void onClick(DialogInterface dialog, int which) {
134 if (which == DialogInterface.BUTTON_NEGATIVE) {
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100135 final Intent settingsIntent = new Intent(ACTION_VPN_SETTINGS);
136 mContext.startActivityAsUser(settingsIntent, UserHandle.CURRENT);
Jason Monk3d5f5512014-07-25 11:17:28 -0400137 }
138 }
139
140 private void createDialog() {
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100141 boolean hasDeviceOwner = mSecurityController.hasDeviceOwner();
142 boolean hasProfile = mSecurityController.hasProfileOwner();
143 boolean hasVpn = mSecurityController.isVpnEnabled();
144
Jason Monk3d5f5512014-07-25 11:17:28 -0400145 mDialog = new SystemUIDialog(mContext);
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100146 mDialog.setTitle(getTitle(hasDeviceOwner, hasProfile));
147 mDialog.setMessage(getMessage(hasDeviceOwner, hasProfile, hasVpn));
Jason Monk3d5f5512014-07-25 11:17:28 -0400148 mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this);
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100149 if (hasVpn) {
Jason Monk3d5f5512014-07-25 11:17:28 -0400150 mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getNegativeButton(), this);
151 }
152 mDialog.show();
153 }
154
155 private String getNegativeButton() {
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100156 return mContext.getString(R.string.status_bar_settings_settings_button);
Jason Monk3d5f5512014-07-25 11:17:28 -0400157 }
158
159 private String getPositiveButton() {
160 return mContext.getString(R.string.quick_settings_done);
161 }
162
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100163 private String getMessage(boolean hasDeviceOwner, boolean hasProfile, boolean hasVpn) {
164 if (hasDeviceOwner) {
165 if (hasProfile) {
166 if (hasVpn) {
167 return mContext.getString(
168 R.string.monitoring_description_vpn_device_and_profile_owned,
169 mSecurityController.getDeviceOwnerName(),
170 mSecurityController.getProfileOwnerName());
Selim Cinek24ac55e2014-08-27 12:51:45 +0200171 } else {
172 return mContext.getString(
173 R.string.monitoring_description_device_and_profile_owned,
174 mSecurityController.getDeviceOwnerName(),
175 mSecurityController.getProfileOwnerName());
176 }
177 } else {
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100178 if (hasVpn) {
179 return mContext.getString(R.string.monitoring_description_vpn_device_owned,
180 mSecurityController.getDeviceOwnerName());
Selim Cinek24ac55e2014-08-27 12:51:45 +0200181 } else {
182 return mContext.getString(R.string.monitoring_description_device_owned,
183 mSecurityController.getDeviceOwnerName());
184 }
185 }
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100186 } else if (hasProfile) {
187 if (hasVpn) {
188 return mContext.getString(
189 R.string.monitoring_description_vpn_profile_owned,
190 mSecurityController.getProfileOwnerName());
Jason Monk3d5f5512014-07-25 11:17:28 -0400191 } else {
Selim Cinek24ac55e2014-08-27 12:51:45 +0200192 return mContext.getString(
193 R.string.monitoring_description_profile_owned,
194 mSecurityController.getProfileOwnerName());
Jason Monk3d5f5512014-07-25 11:17:28 -0400195 }
196 } else {
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100197 return mContext.getString(R.string.monitoring_description_vpn);
Jason Monk3d5f5512014-07-25 11:17:28 -0400198 }
199 }
200
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100201 private int getTitle(boolean hasDeviceOwner, boolean hasProfile) {
202 if (hasDeviceOwner) {
Jason Monk3d5f5512014-07-25 11:17:28 -0400203 return R.string.monitoring_title_device_owned;
Robin Lee9cb1d5f2015-04-16 17:01:49 +0100204 } else if (hasProfile) {
Selim Cinek24ac55e2014-08-27 12:51:45 +0200205 return R.string.monitoring_title_profile_owned;
206 }
Jason Monk3d5f5512014-07-25 11:17:28 -0400207 return R.string.monitoring_title;
208 }
209
Jason Monkb1c2f3b2014-08-20 10:17:00 -0400210 private final Runnable mUpdateDisplayState = new Runnable() {
211 @Override
212 public void run() {
213 if (mFooterTextId != 0) {
214 mFooterText.setText(mFooterTextId);
215 }
216 mRootView.setVisibility(mIsVisible ? View.VISIBLE : View.GONE);
217 mFooterIcon.setVisibility(mIsIconVisible ? View.VISIBLE : View.INVISIBLE);
218 }
219 };
220
Selim Cinek24ac55e2014-08-27 12:51:45 +0200221 private class Callback implements SecurityController.SecurityControllerCallback {
Jason Monk3d5f5512014-07-25 11:17:28 -0400222 @Override
Selim Cinek24ac55e2014-08-27 12:51:45 +0200223 public void onStateChanged() {
Jason Monk3d5f5512014-07-25 11:17:28 -0400224 refreshState();
225 }
226 }
227
228 private class H extends Handler {
229 private static final int CLICK = 0;
230 private static final int REFRESH_STATE = 1;
231
232 private H(Looper looper) {
233 super(looper);
234 }
235
236 @Override
237 public void handleMessage(Message msg) {
238 String name = null;
239 try {
240 if (msg.what == REFRESH_STATE) {
241 name = "handleRefreshState";
242 handleRefreshState();
243 } else if (msg.what == CLICK) {
244 name = "handleClick";
245 handleClick();
246 }
247 } catch (Throwable t) {
248 final String error = "Error in " + name;
249 Log.w(TAG, error, t);
250 mHost.warn(error, t);
251 }
252 }
253 }
254
255}