blob: a72525c264078e0e418834f4cf6a9a5c04d03c7b [file] [log] [blame]
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -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 com.android.settings;
18
19import android.app.Activity;
20import android.app.AlertDialog;
Jiehua.Dai20108e22010-05-12 08:37:52 +020021import android.app.Dialog;
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -070022import android.app.admin.DevicePolicyManager;
Oscar Montemayor05411892010-08-03 16:56:09 -070023import android.content.Context;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080024import android.content.Intent;
Robert Greenwalt52322a92010-10-13 14:07:03 -070025import android.net.ConnectivityManager;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080026import android.net.Proxy;
Jason Monke86790c2014-05-05 12:36:10 -040027import android.net.ProxyInfo;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080028import android.os.Bundle;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080029import android.text.Selection;
30import android.text.Spannable;
31import android.text.TextUtils;
32import android.util.Log;
Oscar Montemayor05411892010-08-03 16:56:09 -070033import android.view.LayoutInflater;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080034import android.view.View;
35import android.view.View.OnClickListener;
36import android.view.View.OnFocusChangeListener;
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -070037import android.view.ViewGroup;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080038import android.widget.Button;
39import android.widget.EditText;
40import android.widget.TextView;
41
Tamas Berghammer265d3c22016-06-22 15:34:45 +010042import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Jason Monk39b46742015-09-10 15:52:51 -040043import com.android.settings.SettingsPreferenceFragment.SettingsDialogFragment;
Fan Zhang2d0b3442016-12-05 17:02:33 -080044import com.android.settings.core.InstrumentedPreferenceFragment;
Jason Monk39b46742015-09-10 15:52:51 -040045
Fan Zhang2d0b3442016-12-05 17:02:33 -080046public class ProxySelector extends InstrumentedPreferenceFragment implements DialogCreatable {
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -070047 private static final String TAG = "ProxySelector";
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080048
49 EditText mHostnameField;
50 EditText mPortField;
Oscar Montemayor05411892010-08-03 16:56:09 -070051 EditText mExclusionListField;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080052 Button mOKButton;
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -070053 Button mClearButton;
54 Button mDefaultButton;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080055
Jiehua.Dai20108e22010-05-12 08:37:52 +020056 private static final int ERROR_DIALOG_ID = 0;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080057
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -070058 private SettingsDialogFragment mDialogFragment;
59 private View mView;
60
61 @Override
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080062 public void onCreate(Bundle icicle) {
63 super.onCreate(icicle);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -080064 }
65
Jiehua.Dai20108e22010-05-12 08:37:52 +020066 @Override
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -070067 public View onCreateView(LayoutInflater inflater, ViewGroup container,
68 Bundle savedInstanceState) {
69 mView = inflater.inflate(R.layout.proxy, container, false);
70 initView(mView);
71 // TODO: Populate based on connection status
Robert Greenwalt52322a92010-10-13 14:07:03 -070072 populateFields();
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -070073 return mView;
74 }
75
76 @Override
77 public void onActivityCreated(Bundle savedInstanceState) {
78 super.onActivityCreated(savedInstanceState);
79 final DevicePolicyManager dpm =
80 (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
81
82 final boolean userSetGlobalProxy = (dpm.getGlobalProxyAdmin() == null);
83 // Disable UI if the Global Proxy is being controlled by a Device Admin
84 mHostnameField.setEnabled(userSetGlobalProxy);
85 mPortField.setEnabled(userSetGlobalProxy);
86 mExclusionListField.setEnabled(userSetGlobalProxy);
87 mOKButton.setEnabled(userSetGlobalProxy);
88 mClearButton.setEnabled(userSetGlobalProxy);
89 mDefaultButton.setEnabled(userSetGlobalProxy);
90 }
91
92 // Dialog management
93
94 @Override
95 public Dialog onCreateDialog(int id) {
Jiehua.Dai20108e22010-05-12 08:37:52 +020096 if (id == ERROR_DIALOG_ID) {
97 String hostname = mHostnameField.getText().toString().trim();
98 String portStr = mPortField.getText().toString().trim();
Oscar Montemayor05411892010-08-03 16:56:09 -070099 String exclList = mExclusionListField.getText().toString().trim();
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700100 String msg = getActivity().getString(validate(hostname, portStr, exclList));
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800101
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700102 return new AlertDialog.Builder(getActivity())
Jiehua.Dai20108e22010-05-12 08:37:52 +0200103 .setTitle(R.string.proxy_error)
104 .setPositiveButton(R.string.proxy_error_dismiss, null)
105 .setMessage(msg)
106 .create();
107 }
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700108 return null;
Jiehua.Dai20108e22010-05-12 08:37:52 +0200109 }
110
Fan Zhangd65184f2016-09-19 17:45:24 -0700111 @Override
112 public int getDialogMetricsCategory(int dialogId) {
113 return MetricsEvent.DIALOG_PROXY_SELECTOR_ERROR;
114 }
115
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700116 private void showDialog(int dialogId) {
117 if (mDialogFragment != null) {
118 Log.e(TAG, "Old dialog fragment not null!");
Jiehua.Dai20108e22010-05-12 08:37:52 +0200119 }
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700120 mDialogFragment = new SettingsDialogFragment(this, dialogId);
121 mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800122 }
123
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700124 private void initView(View view) {
125 mHostnameField = (EditText)view.findViewById(R.id.hostname);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800126 mHostnameField.setOnFocusChangeListener(mOnFocusChangeHandler);
127
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700128 mPortField = (EditText)view.findViewById(R.id.port);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800129 mPortField.setOnClickListener(mOKHandler);
130 mPortField.setOnFocusChangeListener(mOnFocusChangeHandler);
131
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700132 mExclusionListField = (EditText)view.findViewById(R.id.exclusionlist);
Oscar Montemayor05411892010-08-03 16:56:09 -0700133 mExclusionListField.setOnFocusChangeListener(mOnFocusChangeHandler);
134
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700135 mOKButton = (Button)view.findViewById(R.id.action);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800136 mOKButton.setOnClickListener(mOKHandler);
137
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700138 mClearButton = (Button)view.findViewById(R.id.clear);
139 mClearButton.setOnClickListener(mClearHandler);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800140
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700141 mDefaultButton = (Button)view.findViewById(R.id.defaultView);
142 mDefaultButton.setOnClickListener(mDefaultHandler);
143 }
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800144
Robert Greenwalt52322a92010-10-13 14:07:03 -0700145 void populateFields() {
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700146 final Activity activity = getActivity();
Robert Greenwalt52322a92010-10-13 14:07:03 -0700147 String hostname = "";
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800148 int port = -1;
Robert Greenwalt52322a92010-10-13 14:07:03 -0700149 String exclList = "";
150 // Use the last setting given by the user
151 ConnectivityManager cm =
152 (ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
153
Jason Monke86790c2014-05-05 12:36:10 -0400154 ProxyInfo proxy = cm.getGlobalProxy();
Robert Greenwalt52322a92010-10-13 14:07:03 -0700155 if (proxy != null) {
156 hostname = proxy.getHost();
157 port = proxy.getPort();
Jason Monkd65928c2014-05-07 16:28:29 -0400158 exclList = proxy.getExclusionListAsString();
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800159 }
160
161 if (hostname == null) {
162 hostname = "";
163 }
164
165 mHostnameField.setText(hostname);
166
167 String portStr = port == -1 ? "" : Integer.toString(port);
168 mPortField.setText(portStr);
169
Oscar Montemayor05411892010-08-03 16:56:09 -0700170 mExclusionListField.setText(exclList);
171
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700172 final Intent intent = activity.getIntent();
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800173
174 String buttonLabel = intent.getStringExtra("button-label");
175 if (!TextUtils.isEmpty(buttonLabel)) {
176 mOKButton.setText(buttonLabel);
177 }
178
179 String title = intent.getStringExtra("title");
180 if (!TextUtils.isEmpty(title)) {
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700181 activity.setTitle(title);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800182 }
183 }
184
185 /**
186 * validate syntax of hostname and port entries
187 * @return 0 on success, string resource ID on failure
188 */
Irfan Sheriffc5361922010-09-22 16:09:35 -0700189 public static int validate(String hostname, String port, String exclList) {
Yuhao Zheng1f7a1902014-02-28 17:09:43 -0800190 switch (Proxy.validate(hostname, port, exclList)) {
191 case Proxy.PROXY_VALID:
192 return 0;
193 case Proxy.PROXY_HOSTNAME_EMPTY:
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800194 return R.string.proxy_error_empty_host_set_port;
Yuhao Zheng1f7a1902014-02-28 17:09:43 -0800195 case Proxy.PROXY_HOSTNAME_INVALID:
196 return R.string.proxy_error_invalid_host;
197 case Proxy.PROXY_PORT_EMPTY:
198 return R.string.proxy_error_empty_port;
199 case Proxy.PROXY_PORT_INVALID:
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800200 return R.string.proxy_error_invalid_port;
Yuhao Zheng1f7a1902014-02-28 17:09:43 -0800201 case Proxy.PROXY_EXCLLIST_INVALID:
202 return R.string.proxy_error_invalid_exclusion_list;
203 default:
204 // should neven happen
205 Log.e(TAG, "Unknown proxy settings error");
206 return -1;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800207 }
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800208 }
209
210 /**
211 * returns true on success, false if the user must correct something
212 */
213 boolean saveToDb() {
214
215 String hostname = mHostnameField.getText().toString().trim();
216 String portStr = mPortField.getText().toString().trim();
Oscar Montemayor05411892010-08-03 16:56:09 -0700217 String exclList = mExclusionListField.getText().toString().trim();
Robert Greenwalt52322a92010-10-13 14:07:03 -0700218 int port = 0;
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800219
Oscar Montemayor05411892010-08-03 16:56:09 -0700220 int result = validate(hostname, portStr, exclList);
Yuhao Zheng1f7a1902014-02-28 17:09:43 -0800221 if (result != 0) {
Jiehua.Dai20108e22010-05-12 08:37:52 +0200222 showDialog(ERROR_DIALOG_ID);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800223 return false;
224 }
225
226 if (portStr.length() > 0) {
227 try {
228 port = Integer.parseInt(portStr);
229 } catch (NumberFormatException ex) {
Robert Greenwalt52322a92010-10-13 14:07:03 -0700230 // should never happen - caught by validate above
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800231 return false;
232 }
233 }
Jason Monke86790c2014-05-05 12:36:10 -0400234 ProxyInfo p = new ProxyInfo(hostname, port, exclList);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800235 // FIXME: The best solution would be to make a better UI that would
236 // disable editing of the text boxes if the user chooses to use the
237 // default settings. i.e. checking a box to always use the default
238 // carrier. http:/b/issue?id=756480
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800239 // FIXME: If the user types in a proxy that matches the default, should
240 // we keep that setting? Can be fixed with a new UI.
Robert Greenwalt52322a92010-10-13 14:07:03 -0700241 ConnectivityManager cm =
242 (ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800243
Robert Greenwalt52322a92010-10-13 14:07:03 -0700244 cm.setGlobalProxy(p);
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800245 return true;
246 }
247
248 OnClickListener mOKHandler = new OnClickListener() {
249 public void onClick(View v) {
250 if (saveToDb()) {
Daisuke Miyakawa21c1abc2010-09-12 15:42:56 -0700251 getActivity().onBackPressed();
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800252 }
253 }
254 };
255
256 OnClickListener mClearHandler = new OnClickListener() {
257 public void onClick(View v) {
258 mHostnameField.setText("");
259 mPortField.setText("");
Oscar Montemayor05411892010-08-03 16:56:09 -0700260 mExclusionListField.setText("");
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800261 }
262 };
263
264 OnClickListener mDefaultHandler = new OnClickListener() {
265 public void onClick(View v) {
Oscar Montemayor05411892010-08-03 16:56:09 -0700266 // TODO: populate based on connection status
Robert Greenwalt52322a92010-10-13 14:07:03 -0700267 populateFields();
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800268 }
269 };
270
271 OnFocusChangeListener mOnFocusChangeHandler = new OnFocusChangeListener() {
272 public void onFocusChange(View v, boolean hasFocus) {
273 if (hasFocus) {
274 TextView textView = (TextView) v;
275 Selection.selectAll((Spannable) textView.getText());
276 }
277 }
278 };
Chris Wren8a963ba2015-03-20 10:29:14 -0400279
280 @Override
Fan Zhang65076132016-08-08 10:25:13 -0700281 public int getMetricsCategory() {
Chris Wren9d1bfd12016-01-26 18:04:01 -0500282 return MetricsEvent.PROXY_SELECTOR;
Chris Wren8a963ba2015-03-20 10:29:14 -0400283 }
The Android Open Source Projectafc4ab22009-03-03 19:32:34 -0800284}