/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.settings; import android.app.Activity; import android.app.AlertDialog; import android.content.ContentResolver; import android.content.Intent; import android.net.Proxy; import android.os.Bundle; import android.provider.Settings; import android.text.Selection; import android.text.Spannable; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnFocusChangeListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * To start the Proxy Selector activity, create the following intent. * * * Intent intent = new Intent(); * intent.setClassName("com.android.browser.ProxySelector"); * startActivity(intent); * * * you can add extra options to the intent by using * * * intent.putExtra(key, value); * * * the extra options are: * * button-label: a string label to display for the okay button * title: the title of the window * error-text: If not null, will be used as the label of the error message. */ public class ProxySelector extends Activity { private final static String LOGTAG = "Settings"; EditText mHostnameField; EditText mPortField; Button mOKButton; // Matches blank input, ips, and domain names private static final String HOSTNAME_REGEXP = "^$|^[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*(\\.[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*)*$"; private static final Pattern HOSTNAME_PATTERN; static { HOSTNAME_PATTERN = Pattern.compile(HOSTNAME_REGEXP); } public void onCreate(Bundle icicle) { super.onCreate(icicle); if (android.util.Config.LOGV) Log.v(LOGTAG, "[ProxySelector] onStart"); setContentView(R.layout.proxy); initView(); populateFields(false); } protected void showError(int error) { new AlertDialog.Builder(this) .setTitle(R.string.proxy_error) .setMessage(error) .setPositiveButton(R.string.proxy_error_dismiss, null) .show(); } void initView() { mHostnameField = (EditText)findViewById(R.id.hostname); mHostnameField.setOnFocusChangeListener(mOnFocusChangeHandler); mPortField = (EditText)findViewById(R.id.port); mPortField.setOnClickListener(mOKHandler); mPortField.setOnFocusChangeListener(mOnFocusChangeHandler); mOKButton = (Button)findViewById(R.id.action); mOKButton.setOnClickListener(mOKHandler); Button b = (Button)findViewById(R.id.clear); b.setOnClickListener(mClearHandler); b = (Button)findViewById(R.id.defaultView); b.setOnClickListener(mDefaultHandler); } void populateFields(boolean useDefault) { String hostname = null; int port = -1; if (useDefault) { // Use the default proxy settings provided by the carrier hostname = Proxy.getDefaultHost(); port = Proxy.getDefaultPort(); } else { // Use the last setting given by the user hostname = Proxy.getHost(this); port = Proxy.getPort(this); } if (hostname == null) { hostname = ""; } mHostnameField.setText(hostname); String portStr = port == -1 ? "" : Integer.toString(port); mPortField.setText(portStr); Intent intent = getIntent(); String buttonLabel = intent.getStringExtra("button-label"); if (!TextUtils.isEmpty(buttonLabel)) { mOKButton.setText(buttonLabel); } String title = intent.getStringExtra("title"); if (!TextUtils.isEmpty(title)) { setTitle(title); } } /** * validate syntax of hostname and port entries * @return 0 on success, string resource ID on failure */ int validate(String hostname, String port) { Matcher match = HOSTNAME_PATTERN.matcher(hostname); if (!match.matches()) return R.string.proxy_error_invalid_host; if (hostname.length() > 0 && port.length() == 0) { return R.string.proxy_error_empty_port; } if (port.length() > 0) { if (hostname.length() == 0) { return R.string.proxy_error_empty_host_set_port; } int portVal = -1; try { portVal = Integer.parseInt(port); } catch (NumberFormatException ex) { return R.string.proxy_error_invalid_port; } if (portVal <= 0 || portVal > 0xFFFF) { return R.string.proxy_error_invalid_port; } } return 0; } /** * returns true on success, false if the user must correct something */ boolean saveToDb() { String hostname = mHostnameField.getText().toString().trim(); String portStr = mPortField.getText().toString().trim(); int port = -1; int result = validate(hostname, portStr); if (result > 0) { showError(result); return false; } if (portStr.length() > 0) { try { port = Integer.parseInt(portStr); } catch (NumberFormatException ex) { return false; } } // FIXME: The best solution would be to make a better UI that would // disable editing of the text boxes if the user chooses to use the // default settings. i.e. checking a box to always use the default // carrier. http:/b/issue?id=756480 // FIXME: This currently will not work if the default host is blank and // the user has cleared the input boxes in order to not use a proxy. // This is a UI problem and can be solved with some better form // controls. // FIXME: If the user types in a proxy that matches the default, should // we keep that setting? Can be fixed with a new UI. ContentResolver res = getContentResolver(); if (hostname.equals(Proxy.getDefaultHost()) && port == Proxy.getDefaultPort()) { // If the user hit the default button and didn't change any of // the input boxes, treat it as if the user has not specified a // proxy. hostname = null; } if (!TextUtils.isEmpty(hostname)) { hostname += ':' + portStr; } Settings.Secure.putString(res, Settings.Secure.HTTP_PROXY, hostname); sendBroadcast(new Intent(Proxy.PROXY_CHANGE_ACTION)); return true; } OnClickListener mOKHandler = new OnClickListener() { public void onClick(View v) { if (saveToDb()) { finish(); } } }; OnClickListener mClearHandler = new OnClickListener() { public void onClick(View v) { mHostnameField.setText(""); mPortField.setText(""); } }; OnClickListener mDefaultHandler = new OnClickListener() { public void onClick(View v) { populateFields(true); } }; OnFocusChangeListener mOnFocusChangeHandler = new OnFocusChangeListener() { public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { TextView textView = (TextView) v; Selection.selectAll((Spannable) textView.getText()); } } }; }