[go: nahoru, domu]

1/*
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;
21import android.content.Intent;
22import android.os.Handler;
23import android.os.Looper;
24import android.os.Message;
25import android.os.UserHandle;
26import android.util.Log;
27import android.view.LayoutInflater;
28import android.view.View;
29import android.view.View.OnClickListener;
30import android.widget.ImageView;
31import android.widget.TextView;
32
33import com.android.systemui.FontSizeUtils;
34import 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;
38
39import static android.provider.Settings.ACTION_VPN_SETTINGS;
40
41public class QSFooter implements OnClickListener, DialogInterface.OnClickListener {
42    protected static final String TAG = "QSFooter";
43    protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
44
45    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;
55    private final Handler mMainHandler;
56
57    private boolean mIsVisible;
58    private boolean mIsIconVisible;
59    private int mFooterTextId;
60
61    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;
68        mMainHandler = new Handler();
69    }
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
85    public void onConfigurationChanged() {
86        FontSizeUtils.updateFontSize(mFooterText, R.dimen.qs_tile_text_size);
87    }
88
89    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        mIsIconVisible = mSecurityController.isVpnEnabled();
114        // If the device has device owner, show "Device may be monitored", but --
115        // TODO See b/25779452 -- device owner doesn't actually have monitoring power.
116        if (mSecurityController.isDeviceManaged()) {
117            mFooterTextId = R.string.device_owned_footer;
118            mIsVisible = true;
119        } else {
120            mFooterTextId = R.string.vpn_footer;
121            mIsVisible = mIsIconVisible;
122        }
123        mMainHandler.post(mUpdateDisplayState);
124    }
125
126    @Override
127    public void onClick(DialogInterface dialog, int which) {
128        if (which == DialogInterface.BUTTON_NEGATIVE) {
129            final Intent settingsIntent = new Intent(ACTION_VPN_SETTINGS);
130            mHost.startActivityDismissingKeyguard(settingsIntent);
131        }
132    }
133
134    private void createDialog() {
135        String deviceOwner = mSecurityController.getDeviceOwnerName();
136        String profileOwner = mSecurityController.getProfileOwnerName();
137        String primaryVpn = mSecurityController.getPrimaryVpnName();
138        String profileVpn = mSecurityController.getProfileVpnName();
139        boolean managed = mSecurityController.hasProfileOwner();
140
141        mDialog = new SystemUIDialog(mContext);
142        mDialog.setTitle(getTitle(deviceOwner));
143        mDialog.setMessage(getMessage(deviceOwner, profileOwner, primaryVpn, profileVpn, managed));
144        mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this);
145        if (mSecurityController.isVpnEnabled() && !mSecurityController.isVpnRestricted()) {
146            mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getSettingsButton(), this);
147        }
148        mDialog.show();
149    }
150
151    private String getSettingsButton() {
152        return mContext.getString(R.string.status_bar_settings_settings_button);
153    }
154
155    private String getPositiveButton() {
156        return mContext.getString(R.string.quick_settings_done);
157    }
158
159    private String getMessage(String deviceOwner, String profileOwner, String primaryVpn,
160            String profileVpn, boolean primaryUserIsManaged) {
161        // Show a special warning when the device has device owner, but --
162        // TODO See b/25779452 -- device owner doesn't actually have monitoring power.
163        if (deviceOwner != null) {
164            if (primaryVpn != null) {
165                return mContext.getString(R.string.monitoring_description_vpn_app_device_owned,
166                        deviceOwner, primaryVpn);
167            } else {
168                return mContext.getString(R.string.monitoring_description_device_owned,
169                        deviceOwner);
170            }
171        } else if (primaryVpn != null) {
172            if (profileVpn != null) {
173                return mContext.getString(R.string.monitoring_description_app_personal_work,
174                        profileOwner, profileVpn, primaryVpn);
175            } else {
176                return mContext.getString(R.string.monitoring_description_app_personal,
177                        primaryVpn);
178            }
179        } else if (profileVpn != null) {
180            return mContext.getString(R.string.monitoring_description_app_work,
181                    profileOwner, profileVpn);
182        } else if (profileOwner != null && primaryUserIsManaged) {
183            return mContext.getString(R.string.monitoring_description_device_owned,
184                    profileOwner);
185        } else {
186            // No device owner, no personal VPN, no work VPN, no user owner. Why are we here?
187            return null;
188        }
189    }
190
191    private int getTitle(String deviceOwner) {
192        if (deviceOwner != null) {
193            return R.string.monitoring_title_device_owned;
194        } else {
195            return R.string.monitoring_title;
196        }
197    }
198
199    private final Runnable mUpdateDisplayState = new Runnable() {
200        @Override
201        public void run() {
202            if (mFooterTextId != 0) {
203                mFooterText.setText(mFooterTextId);
204            }
205            mRootView.setVisibility(mIsVisible ? View.VISIBLE : View.GONE);
206            mFooterIcon.setVisibility(mIsIconVisible ? View.VISIBLE : View.INVISIBLE);
207        }
208    };
209
210    private class Callback implements SecurityController.SecurityControllerCallback {
211        @Override
212        public void onStateChanged() {
213            refreshState();
214        }
215    }
216
217    private class H extends Handler {
218        private static final int CLICK = 0;
219        private static final int REFRESH_STATE = 1;
220
221        private H(Looper looper) {
222            super(looper);
223        }
224
225        @Override
226        public void handleMessage(Message msg) {
227            String name = null;
228            try {
229                if (msg.what == REFRESH_STATE) {
230                    name = "handleRefreshState";
231                    handleRefreshState();
232                } else if (msg.what == CLICK) {
233                    name = "handleClick";
234                    handleClick();
235                }
236            } catch (Throwable t) {
237                final String error = "Error in " + name;
238                Log.w(TAG, error, t);
239                mHost.warn(error, t);
240            }
241        }
242    }
243
244}
245