• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.settings;
18 
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.app.Dialog;
22 import android.app.admin.DevicePolicyManager;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.net.ConnectivityManager;
26 import android.net.Proxy;
27 import android.net.ProxyInfo;
28 import android.os.Bundle;
29 import android.text.Selection;
30 import android.text.Spannable;
31 import android.text.TextUtils;
32 import android.util.Log;
33 import android.view.LayoutInflater;
34 import android.view.View;
35 import android.view.View.OnClickListener;
36 import android.view.View.OnFocusChangeListener;
37 import android.view.ViewGroup;
38 import android.widget.Button;
39 import android.widget.EditText;
40 import android.widget.TextView;
41 
42 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
43 import com.android.settings.SettingsPreferenceFragment.SettingsDialogFragment;
44 import com.android.settings.core.InstrumentedFragment;
45 
46 public class ProxySelector extends InstrumentedFragment implements DialogCreatable {
47     private static final String TAG = "ProxySelector";
48 
49     EditText    mHostnameField;
50     EditText    mPortField;
51     EditText    mExclusionListField;
52     Button      mOKButton;
53     Button      mClearButton;
54     Button      mDefaultButton;
55 
56     private static final int ERROR_DIALOG_ID = 0;
57 
58     private SettingsDialogFragment mDialogFragment;
59     private View mView;
60 
61     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)62     public View onCreateView(LayoutInflater inflater, ViewGroup container,
63             Bundle savedInstanceState) {
64         mView = inflater.inflate(R.layout.proxy, container, false);
65         initView(mView);
66         // TODO: Populate based on connection status
67         populateFields();
68         return mView;
69     }
70 
71     @Override
onActivityCreated(Bundle savedInstanceState)72     public void onActivityCreated(Bundle savedInstanceState) {
73         super.onActivityCreated(savedInstanceState);
74         final DevicePolicyManager dpm =
75                 (DevicePolicyManager)getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
76 
77         final boolean userSetGlobalProxy = (dpm.getGlobalProxyAdmin() == null);
78         // Disable UI if the Global Proxy is being controlled by a Device Admin
79         mHostnameField.setEnabled(userSetGlobalProxy);
80         mPortField.setEnabled(userSetGlobalProxy);
81         mExclusionListField.setEnabled(userSetGlobalProxy);
82         mOKButton.setEnabled(userSetGlobalProxy);
83         mClearButton.setEnabled(userSetGlobalProxy);
84         mDefaultButton.setEnabled(userSetGlobalProxy);
85     }
86 
87     // Dialog management
88 
89     @Override
onCreateDialog(int id)90     public Dialog onCreateDialog(int id) {
91         if (id == ERROR_DIALOG_ID) {
92             String hostname = mHostnameField.getText().toString().trim();
93             String portStr = mPortField.getText().toString().trim();
94             String exclList = mExclusionListField.getText().toString().trim();
95             String msg = getActivity().getString(validate(hostname, portStr, exclList));
96 
97             return new AlertDialog.Builder(getActivity())
98                     .setTitle(R.string.proxy_error)
99                     .setPositiveButton(R.string.proxy_error_dismiss, null)
100                     .setMessage(msg)
101                     .create();
102         }
103         return null;
104     }
105 
106     @Override
getDialogMetricsCategory(int dialogId)107     public int getDialogMetricsCategory(int dialogId) {
108         return MetricsEvent.DIALOG_PROXY_SELECTOR_ERROR;
109     }
110 
showDialog(int dialogId)111     private void showDialog(int dialogId) {
112         if (mDialogFragment != null) {
113             Log.e(TAG, "Old dialog fragment not null!");
114         }
115         mDialogFragment = new SettingsDialogFragment(this, dialogId);
116         mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
117     }
118 
initView(View view)119     private void initView(View view) {
120         mHostnameField = (EditText)view.findViewById(R.id.hostname);
121         mHostnameField.setOnFocusChangeListener(mOnFocusChangeHandler);
122 
123         mPortField = (EditText)view.findViewById(R.id.port);
124         mPortField.setOnClickListener(mOKHandler);
125         mPortField.setOnFocusChangeListener(mOnFocusChangeHandler);
126 
127         mExclusionListField = (EditText)view.findViewById(R.id.exclusionlist);
128         mExclusionListField.setOnFocusChangeListener(mOnFocusChangeHandler);
129 
130         mOKButton = (Button)view.findViewById(R.id.action);
131         mOKButton.setOnClickListener(mOKHandler);
132 
133         mClearButton = (Button)view.findViewById(R.id.clear);
134         mClearButton.setOnClickListener(mClearHandler);
135 
136         mDefaultButton = (Button)view.findViewById(R.id.defaultView);
137         mDefaultButton.setOnClickListener(mDefaultHandler);
138     }
139 
populateFields()140     void populateFields() {
141         final Activity activity = getActivity();
142         String hostname = "";
143         int port = -1;
144         String exclList = "";
145         // Use the last setting given by the user
146         ConnectivityManager cm =
147                 (ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
148 
149         ProxyInfo proxy = cm.getGlobalProxy();
150         if (proxy != null) {
151             hostname = proxy.getHost();
152             port = proxy.getPort();
153             exclList = proxy.getExclusionListAsString();
154         }
155 
156         if (hostname == null) {
157             hostname = "";
158         }
159 
160         mHostnameField.setText(hostname);
161 
162         String portStr = port == -1 ? "" : Integer.toString(port);
163         mPortField.setText(portStr);
164 
165         mExclusionListField.setText(exclList);
166 
167         final Intent intent = activity.getIntent();
168 
169         String buttonLabel = intent.getStringExtra("button-label");
170         if (!TextUtils.isEmpty(buttonLabel)) {
171             mOKButton.setText(buttonLabel);
172         }
173 
174         String title = intent.getStringExtra("title");
175         if (!TextUtils.isEmpty(title)) {
176             activity.setTitle(title);
177         } else {
178             activity.setTitle(R.string.proxy_settings_title);
179         }
180     }
181 
182     /**
183      * validate syntax of hostname and port entries
184      * @return 0 on success, string resource ID on failure
185      */
validate(String hostname, String port, String exclList)186     public static int validate(String hostname, String port, String exclList) {
187         switch (Proxy.validate(hostname, port, exclList)) {
188             case Proxy.PROXY_VALID:
189                 return 0;
190             case Proxy.PROXY_HOSTNAME_EMPTY:
191                 return R.string.proxy_error_empty_host_set_port;
192             case Proxy.PROXY_HOSTNAME_INVALID:
193                 return R.string.proxy_error_invalid_host;
194             case Proxy.PROXY_PORT_EMPTY:
195                 return R.string.proxy_error_empty_port;
196             case Proxy.PROXY_PORT_INVALID:
197                 return R.string.proxy_error_invalid_port;
198             case Proxy.PROXY_EXCLLIST_INVALID:
199                 return R.string.proxy_error_invalid_exclusion_list;
200             default:
201                 // should neven happen
202                 Log.e(TAG, "Unknown proxy settings error");
203                 return -1;
204         }
205     }
206 
207     /**
208      * returns true on success, false if the user must correct something
209      */
saveToDb()210     boolean saveToDb() {
211 
212         String hostname = mHostnameField.getText().toString().trim();
213         String portStr = mPortField.getText().toString().trim();
214         String exclList = mExclusionListField.getText().toString().trim();
215         int port = 0;
216 
217         int result = validate(hostname, portStr, exclList);
218         if (result != 0) {
219             showDialog(ERROR_DIALOG_ID);
220             return false;
221         }
222 
223         if (portStr.length() > 0) {
224             try {
225                 port = Integer.parseInt(portStr);
226             } catch (NumberFormatException ex) {
227                 // should never happen - caught by validate above
228                 return false;
229             }
230         }
231         ProxyInfo p = new ProxyInfo(hostname, port, exclList);
232         // FIXME: The best solution would be to make a better UI that would
233         // disable editing of the text boxes if the user chooses to use the
234         // default settings. i.e. checking a box to always use the default
235         // carrier. http:/b/issue?id=756480
236         // FIXME: If the user types in a proxy that matches the default, should
237         // we keep that setting? Can be fixed with a new UI.
238         ConnectivityManager cm =
239                 (ConnectivityManager)getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
240 
241         cm.setGlobalProxy(p);
242         return true;
243     }
244 
245     OnClickListener mOKHandler = new OnClickListener() {
246             public void onClick(View v) {
247                 if (saveToDb()) {
248                     getActivity().onBackPressed();
249                 }
250             }
251         };
252 
253     OnClickListener mClearHandler = new OnClickListener() {
254             public void onClick(View v) {
255                 mHostnameField.setText("");
256                 mPortField.setText("");
257                 mExclusionListField.setText("");
258             }
259         };
260 
261     OnClickListener mDefaultHandler = new OnClickListener() {
262             public void onClick(View v) {
263                 // TODO: populate based on connection status
264                 populateFields();
265             }
266         };
267 
268     OnFocusChangeListener mOnFocusChangeHandler = new OnFocusChangeListener() {
269             public void onFocusChange(View v, boolean hasFocus) {
270                 if (hasFocus) {
271                     TextView textView = (TextView) v;
272                     Selection.selectAll((Spannable) textView.getText());
273                 }
274             }
275         };
276 
277     @Override
getMetricsCategory()278     public int getMetricsCategory() {
279         return MetricsEvent.PROXY_SELECTOR;
280     }
281 }
282