summaryrefslogtreecommitdiffstats
path: root/core/java/android/net
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
commitd83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /core/java/android/net
parent076357b8567458d4b6dfdcf839ef751634cd2bfb (diff)
downloadframeworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.gz
frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.bz2
frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.zip
auto import from //depot/cupcake/@135843
Diffstat (limited to 'core/java/android/net')
-rw-r--r--core/java/android/net/ConnectivityManager.java294
-rw-r--r--core/java/android/net/Credentials.java48
-rw-r--r--core/java/android/net/DhcpInfo.aidl19
-rw-r--r--core/java/android/net/DhcpInfo.java96
-rw-r--r--core/java/android/net/IConnectivityManager.aidl51
-rw-r--r--core/java/android/net/LocalServerSocket.java117
-rw-r--r--core/java/android/net/LocalSocket.java288
-rw-r--r--core/java/android/net/LocalSocketAddress.java100
-rw-r--r--core/java/android/net/LocalSocketImpl.java490
-rw-r--r--core/java/android/net/MailTo.java172
-rw-r--r--core/java/android/net/MobileDataStateTracker.java493
-rw-r--r--core/java/android/net/NetworkConnectivityListener.java220
-rw-r--r--core/java/android/net/NetworkInfo.aidl19
-rw-r--r--core/java/android/net/NetworkInfo.java380
-rw-r--r--core/java/android/net/NetworkStateTracker.java348
-rw-r--r--core/java/android/net/NetworkUtils.java128
-rw-r--r--core/java/android/net/ParseException.java30
-rw-r--r--core/java/android/net/Proxy.java120
-rw-r--r--core/java/android/net/SSLCertificateSocketFactory.java254
-rw-r--r--core/java/android/net/SntpClient.java201
-rwxr-xr-xcore/java/android/net/Uri.aidl19
-rw-r--r--core/java/android/net/Uri.java2252
-rw-r--r--core/java/android/net/UrlQuerySanitizer.java913
-rw-r--r--core/java/android/net/WebAddress.java134
-rw-r--r--core/java/android/net/http/AndroidHttpClient.java463
-rw-r--r--core/java/android/net/http/AndroidHttpClientConnection.java464
-rw-r--r--core/java/android/net/http/CertificateChainValidator.java444
-rw-r--r--core/java/android/net/http/CertificateValidatorCache.java254
-rw-r--r--core/java/android/net/http/CharArrayBuffers.java89
-rw-r--r--core/java/android/net/http/Connection.java528
-rw-r--r--core/java/android/net/http/ConnectionThread.java137
-rw-r--r--core/java/android/net/http/DomainNameChecker.java277
-rw-r--r--core/java/android/net/http/EventHandler.java147
-rw-r--r--core/java/android/net/http/Headers.java447
-rw-r--r--core/java/android/net/http/HttpAuthHeader.java422
-rw-r--r--core/java/android/net/http/HttpConnection.java96
-rw-r--r--core/java/android/net/http/HttpLog.java44
-rw-r--r--core/java/android/net/http/HttpsConnection.java427
-rw-r--r--core/java/android/net/http/IdleCache.java175
-rw-r--r--core/java/android/net/http/LoggingEventHandler.java90
-rw-r--r--core/java/android/net/http/Request.java462
-rw-r--r--core/java/android/net/http/RequestFeeder.java42
-rw-r--r--core/java/android/net/http/RequestHandle.java424
-rw-r--r--core/java/android/net/http/RequestQueue.java647
-rw-r--r--core/java/android/net/http/SslCertificate.java251
-rw-r--r--core/java/android/net/http/SslError.java144
-rw-r--r--core/java/android/net/http/Timer.java41
-rwxr-xr-xcore/java/android/net/http/package.html2
-rwxr-xr-xcore/java/android/net/package.html5
49 files changed, 0 insertions, 13708 deletions
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
deleted file mode 100644
index 1429bc1aff4..00000000000
--- a/core/java/android/net/ConnectivityManager.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.os.RemoteException;
-
-/**
- * Class that answers queries about the state of network connectivity. It also
- * notifies applications when network connectivity changes. Get an instance
- * of this class by calling
- * {@link android.content.Context#getSystemService(String) Context.getSystemService(Context.CONNECTIVITY_SERVICE)}.
- * <p>
- * The primary responsibilities of this class are to:
- * <ol>
- * <li>Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)</li>
- * <li>Send broadcast intents when network connectivity changes</li>
- * <li>Attempt to "fail over" to another network when connectivity to a network
- * is lost</li>
- * <li>Provide an API that allows applications to query the coarse-grained or fine-grained
- * state of the available networks</li>
- * </ol>
- */
-public class ConnectivityManager
-{
- /**
- * A change in network connectivity has occurred. A connection has either
- * been established or lost. The NetworkInfo for the affected network is
- * sent as an extra; it should be consulted to see what kind of
- * connectivity event occurred.
- * <p/>
- * If this is a connection that was the result of failing over from a
- * disconnected network, then the FAILOVER_CONNECTION boolean extra is
- * set to true.
- * <p/>
- * For a loss of connectivity, if the connectivity manager is attempting
- * to connect (or has already connected) to another network, the
- * NetworkInfo for the new network is also passed as an extra. This lets
- * any receivers of the broadcast know that they should not necessarily
- * tell the user that no data traffic will be possible. Instead, the
- * reciever should expect another broadcast soon, indicating either that
- * the failover attempt succeeded (and so there is still overall data
- * connectivity), or that the failover attempt failed, meaning that all
- * connectivity has been lost.
- * <p/>
- * For a disconnect event, the boolean extra EXTRA_NO_CONNECTIVITY
- * is set to {@code true} if there are no connected networks at all.
- */
- public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
- /**
- * The lookup key for a {@link NetworkInfo} object. Retrieve with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_NETWORK_INFO = "networkInfo";
- /**
- * The lookup key for a boolean that indicates whether a connect event
- * is for a network to which the connectivity manager was failing over
- * following a disconnect on another network.
- * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
- */
- public static final String EXTRA_IS_FAILOVER = "isFailover";
- /**
- * The lookup key for a {@link NetworkInfo} object. This is supplied when
- * there is another network that it may be possible to connect to. Retrieve with
- * {@link android.content.Intent#getParcelableExtra(String)}.
- */
- public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
- /**
- * The lookup key for a boolean that indicates whether there is a
- * complete lack of connectivity, i.e., no network is available.
- * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
- */
- public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
- /**
- * The lookup key for a string that indicates why an attempt to connect
- * to a network failed. The string has no particular structure. It is
- * intended to be used in notifications presented to users. Retrieve
- * it with {@link android.content.Intent#getStringExtra(String)}.
- */
- public static final String EXTRA_REASON = "reason";
- /**
- * The lookup key for a string that provides optionally supplied
- * extra information about the network state. The information
- * may be passed up from the lower networking layers, and its
- * meaning may be specific to a particular network type. Retrieve
- * it with {@link android.content.Intent#getStringExtra(String)}.
- */
- public static final String EXTRA_EXTRA_INFO = "extraInfo";
-
- /**
- * Broadcast Action: The setting for background data usage has changed
- * values. Use {@link #getBackgroundDataSetting()} to get the current value.
- * <p>
- * If an application uses the network in the background, it should listen
- * for this broadcast and stop using the background data if the value is
- * false.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED =
- "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
-
- public static final int TYPE_MOBILE = 0;
- public static final int TYPE_WIFI = 1;
-
- public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
-
- private IConnectivityManager mService;
-
- static public boolean isNetworkTypeValid(int networkType) {
- return networkType == TYPE_WIFI || networkType == TYPE_MOBILE;
- }
-
- public void setNetworkPreference(int preference) {
- try {
- mService.setNetworkPreference(preference);
- } catch (RemoteException e) {
- }
- }
-
- public int getNetworkPreference() {
- try {
- return mService.getNetworkPreference();
- } catch (RemoteException e) {
- return -1;
- }
- }
-
- public NetworkInfo getActiveNetworkInfo() {
- try {
- return mService.getActiveNetworkInfo();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- public NetworkInfo getNetworkInfo(int networkType) {
- try {
- return mService.getNetworkInfo(networkType);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- public NetworkInfo[] getAllNetworkInfo() {
- try {
- return mService.getAllNetworkInfo();
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /** {@hide} */
- public boolean setRadios(boolean turnOn) {
- try {
- return mService.setRadios(turnOn);
- } catch (RemoteException e) {
- return false;
- }
- }
-
- /** {@hide} */
- public boolean setRadio(int networkType, boolean turnOn) {
- try {
- return mService.setRadio(networkType, turnOn);
- } catch (RemoteException e) {
- return false;
- }
- }
-
- /**
- * Tells the underlying networking system that the caller wants to
- * begin using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * @param networkType specifies which network the request pertains to
- * @param feature the name of the feature to be used
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- */
- public int startUsingNetworkFeature(int networkType, String feature) {
- try {
- return mService.startUsingNetworkFeature(networkType, feature);
- } catch (RemoteException e) {
- return -1;
- }
- }
-
- /**
- * Tells the underlying networking system that the caller is finished
- * using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * @param networkType specifies which network the request pertains to
- * @param feature the name of the feature that is no longer needed
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- */
- public int stopUsingNetworkFeature(int networkType, String feature) {
- try {
- return mService.stopUsingNetworkFeature(networkType, feature);
- } catch (RemoteException e) {
- return -1;
- }
- }
-
- /**
- * Ensure that a network route exists to deliver traffic to the specified
- * host via the specified network interface. An attempt to add a route that
- * already exists is ignored, but treated as successful.
- * @param networkType the type of the network over which traffic to the specified
- * host is to be routed
- * @param hostAddress the IP address of the host to which the route is desired
- * @return {@code true} on success, {@code false} on failure
- */
- public boolean requestRouteToHost(int networkType, int hostAddress) {
- try {
- return mService.requestRouteToHost(networkType, hostAddress);
- } catch (RemoteException e) {
- return false;
- }
- }
-
- /**
- * Returns the value of the setting for background data usage. If false,
- * applications should not use the network if the application is not in the
- * foreground. Developers should respect this setting, and check the value
- * of this before performing any background data operations.
- * <p>
- * All applications that have background services that use the network
- * should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}.
- *
- * @return Whether background data usage is allowed.
- */
- public boolean getBackgroundDataSetting() {
- try {
- return mService.getBackgroundDataSetting();
- } catch (RemoteException e) {
- // Err on the side of safety
- return false;
- }
- }
-
- /**
- * Sets the value of the setting for background data usage.
- *
- * @param allowBackgroundData Whether an application should use data while
- * it is in the background.
- *
- * @attr ref android.Manifest.permission#CHANGE_BACKGROUND_DATA_SETTING
- * @see #getBackgroundDataSetting()
- * @hide
- */
- public void setBackgroundDataSetting(boolean allowBackgroundData) {
- try {
- mService.setBackgroundDataSetting(allowBackgroundData);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Don't allow use of default constructor.
- */
- @SuppressWarnings({"UnusedDeclaration"})
- private ConnectivityManager() {
- }
-
- /**
- * {@hide}
- */
- public ConnectivityManager(IConnectivityManager service) {
- if (service == null) {
- throw new IllegalArgumentException(
- "ConnectivityManager() cannot be constructed with null service");
- }
- mService = service;
- }
-}
diff --git a/core/java/android/net/Credentials.java b/core/java/android/net/Credentials.java
deleted file mode 100644
index 7f6cf9d3392..00000000000
--- a/core/java/android/net/Credentials.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net;
-
-/**
- * A class for representing UNIX credentials passed via ancillary data
- * on UNIX domain sockets. See "man 7 unix" on a desktop linux distro.
- */
-public class Credentials {
- /** pid of process. root peers may lie. */
- private final int pid;
- /** uid of process. root peers may lie. */
- private final int uid;
- /** gid of process. root peers may lie. */
- private final int gid;
-
- public Credentials (int pid, int uid, int gid) {
- this.pid = pid;
- this.uid = uid;
- this.gid = gid;
- }
-
- public int getPid() {
- return pid;
- }
-
- public int getUid() {
- return uid;
- }
-
- public int getGid() {
- return gid;
- }
-}
diff --git a/core/java/android/net/DhcpInfo.aidl b/core/java/android/net/DhcpInfo.aidl
deleted file mode 100644
index 29cd21fe765..00000000000
--- a/core/java/android/net/DhcpInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2008, 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 android.net;
-
-parcelable DhcpInfo;
diff --git a/core/java/android/net/DhcpInfo.java b/core/java/android/net/DhcpInfo.java
deleted file mode 100644
index 1178bec39b5..00000000000
--- a/core/java/android/net/DhcpInfo.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-/**
- * A simple object for retrieving the results of a DHCP request.
- */
-public class DhcpInfo implements Parcelable {
- public int ipAddress;
- public int gateway;
- public int netmask;
-
- public int dns1;
- public int dns2;
-
- public int serverAddress;
- public int leaseDuration;
-
- public DhcpInfo() {
- super();
- }
-
- public String toString() {
- StringBuffer str = new StringBuffer();
-
- str.append("ipaddr "); putAddress(str, ipAddress);
- str.append(" gateway "); putAddress(str, gateway);
- str.append(" netmask "); putAddress(str, netmask);
- str.append(" dns1 "); putAddress(str, dns1);
- str.append(" dns2 "); putAddress(str, dns2);
- str.append(" DHCP server "); putAddress(str, serverAddress);
- str.append(" lease ").append(leaseDuration).append(" seconds");
-
- return str.toString();
- }
-
- private static void putAddress(StringBuffer buf, int addr) {
- buf.append(addr & 0xff).append('.').
- append((addr >>>= 8) & 0xff).append('.').
- append((addr >>>= 8) & 0xff).append('.').
- append((addr >>>= 8) & 0xff);
- }
-
- /** Implement the Parcelable interface {@hide} */
- public int describeContents() {
- return 0;
- }
-
- /** Implement the Parcelable interface {@hide} */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(ipAddress);
- dest.writeInt(gateway);
- dest.writeInt(netmask);
- dest.writeInt(dns1);
- dest.writeInt(dns2);
- dest.writeInt(serverAddress);
- dest.writeInt(leaseDuration);
- }
-
- /** Implement the Parcelable interface {@hide} */
- public static final Creator<DhcpInfo> CREATOR =
- new Creator<DhcpInfo>() {
- public DhcpInfo createFromParcel(Parcel in) {
- DhcpInfo info = new DhcpInfo();
- info.ipAddress = in.readInt();
- info.gateway = in.readInt();
- info.netmask = in.readInt();
- info.dns1 = in.readInt();
- info.dns2 = in.readInt();
- info.serverAddress = in.readInt();
- info.leaseDuration = in.readInt();
- return info;
- }
-
- public DhcpInfo[] newArray(int size) {
- return new DhcpInfo[size];
- }
- };
-}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
deleted file mode 100644
index de6859809d8..00000000000
--- a/core/java/android/net/IConnectivityManager.aidl
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Copyright (c) 2008, 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 android.net;
-
-import android.net.NetworkInfo;
-
-/**
- * Interface that answers queries about, and allows changing, the
- * state of network connectivity.
- */
-/** {@hide} */
-interface IConnectivityManager
-{
- void setNetworkPreference(int pref);
-
- int getNetworkPreference();
-
- NetworkInfo getActiveNetworkInfo();
-
- NetworkInfo getNetworkInfo(int networkType);
-
- NetworkInfo[] getAllNetworkInfo();
-
- boolean setRadios(boolean onOff);
-
- boolean setRadio(int networkType, boolean turnOn);
-
- int startUsingNetworkFeature(int networkType, in String feature);
-
- int stopUsingNetworkFeature(int networkType, in String feature);
-
- boolean requestRouteToHost(int networkType, int hostAddress);
-
- boolean getBackgroundDataSetting();
-
- void setBackgroundDataSetting(boolean allowBackgroundData);
-}
diff --git a/core/java/android/net/LocalServerSocket.java b/core/java/android/net/LocalServerSocket.java
deleted file mode 100644
index 2b93fc2235f..00000000000
--- a/core/java/android/net/LocalServerSocket.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net;
-
-import java.io.IOException;
-import java.io.FileDescriptor;
-
-/**
- * non-standard class for creating inbound UNIX-domain socket
- * on the Android platform, this is created in the Linux non-filesystem
- * namespace.
- *
- * On simulator platforms, this may be created in a temporary directory on
- * the filesystem
- */
-public class LocalServerSocket {
- private final LocalSocketImpl impl;
- private final LocalSocketAddress localAddress;
-
- /** 50 seems a bit much, but it's what was here */
- private static final int LISTEN_BACKLOG = 50;
-
- /**
- * Crewates a new server socket listening at specified name.
- * On the Android platform, the name is created in the Linux
- * abstract namespace (instead of on the filesystem).
- *
- * @param name address for socket
- * @throws IOException
- */
- public LocalServerSocket(String name) throws IOException
- {
- impl = new LocalSocketImpl();
-
- impl.create(true);
-
- localAddress = new LocalSocketAddress(name);
- impl.bind(localAddress);
-
- impl.listen(LISTEN_BACKLOG);
- }
-
- /**
- * Create a LocalServerSocket from a file descriptor that's already
- * been created and bound. listen() will be called immediately on it.
- * Used for cases where file descriptors are passed in via environment
- * variables
- *
- * @param fd bound file descriptor
- * @throws IOException
- */
- public LocalServerSocket(FileDescriptor fd) throws IOException
- {
- impl = new LocalSocketImpl(fd);
- impl.listen(LISTEN_BACKLOG);
- localAddress = impl.getSockAddress();
- }
-
- /**
- * Obtains the socket's local address
- *
- * @return local address
- */
- public LocalSocketAddress getLocalSocketAddress()
- {
- return localAddress;
- }
-
- /**
- * Accepts a new connection to the socket. Blocks until a new
- * connection arrives.
- *
- * @return a socket representing the new connection.
- * @throws IOException
- */
- public LocalSocket accept() throws IOException
- {
- LocalSocketImpl acceptedImpl = new LocalSocketImpl();
-
- impl.accept (acceptedImpl);
-
- return new LocalSocket(acceptedImpl);
- }
-
- /**
- * Returns file descriptor or null if not yet open/already closed
- *
- * @return fd or null
- */
- public FileDescriptor getFileDescriptor() {
- return impl.getFileDescriptor();
- }
-
- /**
- * Closes server socket.
- *
- * @throws IOException
- */
- public void close() throws IOException
- {
- impl.close();
- }
-}
diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java
deleted file mode 100644
index 4039a690de5..00000000000
--- a/core/java/android/net/LocalSocket.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.SocketOptions;
-
-/**
- * Creates a (non-server) socket in the UNIX-domain namespace. The interface
- * here is not entirely unlike that of java.net.Socket
- */
-public class LocalSocket {
-
- private LocalSocketImpl impl;
- private volatile boolean implCreated;
- private LocalSocketAddress localAddress;
- private boolean isBound;
- private boolean isConnected;
-
- /**
- * Creates a AF_LOCAL/UNIX domain stream socket.
- */
- public LocalSocket() {
- this(new LocalSocketImpl());
- isBound = false;
- isConnected = false;
- }
-
- /**
- * for use with AndroidServerSocket
- * @param impl a SocketImpl
- */
- /*package*/ LocalSocket(LocalSocketImpl impl) {
- this.impl = impl;
- this.isConnected = false;
- this.isBound = false;
- }
-
- /** {@inheritDoc} */
- @Override
- public String toString() {
- return super.toString() + " impl:" + impl;
- }
-
- /**
- * It's difficult to discern from the spec when impl.create() should be
- * called, but it seems like a reasonable rule is "as soon as possible,
- * but not in a context where IOException cannot be thrown"
- *
- * @throws IOException from SocketImpl.create()
- */
- private void implCreateIfNeeded() throws IOException {
- if (!implCreated) {
- synchronized (this) {
- if (!implCreated) {
- implCreated = true;
- impl.create(true);
- }
- }
- }
- }
-
- /**
- * Connects this socket to an endpoint. May only be called on an instance
- * that has not yet been connected.
- *
- * @param endpoint endpoint address
- * @throws IOException if socket is in invalid state or the address does
- * not exist.
- */
- public void connect(LocalSocketAddress endpoint) throws IOException {
- synchronized (this) {
- if (isConnected) {
- throw new IOException("already connected");
- }
-
- implCreateIfNeeded();
- impl.connect(endpoint, 0);
- isConnected = true;
- isBound = true;
- }
- }
-
- /**
- * Binds this socket to an endpoint name. May only be called on an instance
- * that has not yet been bound.
- *
- * @param bindpoint endpoint address
- * @throws IOException
- */
- public void bind(LocalSocketAddress bindpoint) throws IOException {
- implCreateIfNeeded();
-
- synchronized (this) {
- if (isBound) {
- throw new IOException("already bound");
- }
-
- localAddress = bindpoint;
- impl.bind(localAddress);
- isBound = true;
- }
- }
-
- /**
- * Retrieves the name that this socket is bound to, if any.
- *
- * @return Local address or null if anonymous
- */
- public LocalSocketAddress getLocalSocketAddress() {
- return localAddress;
- }
-
- /**
- * Retrieves the input stream for this instance.
- *
- * @return input stream
- * @throws IOException if socket has been closed or cannot be created.
- */
- public InputStream getInputStream() throws IOException {
- implCreateIfNeeded();
- return impl.getInputStream();
- }
-
- /**
- * Retrieves the output stream for this instance.
- *
- * @return output stream
- * @throws IOException if socket has been closed or cannot be created.
- */
- public OutputStream getOutputStream() throws IOException {
- implCreateIfNeeded();
- return impl.getOutputStream();
- }
-
- /**
- * Closes the socket.
- *
- * @throws IOException
- */
- public void close() throws IOException {
- implCreateIfNeeded();
- impl.close();
- }
-
- /**
- * Shuts down the input side of the socket.
- *
- * @throws IOException
- */
- public void shutdownInput() throws IOException {
- implCreateIfNeeded();
- impl.shutdownInput();
- }
-
- /**
- * Shuts down the output side of the socket.
- *
- * @throws IOException
- */
- public void shutdownOutput() throws IOException {
- implCreateIfNeeded();
- impl.shutdownOutput();
- }
-
- public void setReceiveBufferSize(int size) throws IOException {
- impl.setOption(SocketOptions.SO_RCVBUF, Integer.valueOf(size));
- }
-
- public int getReceiveBufferSize() throws IOException {
- return ((Integer) impl.getOption(SocketOptions.SO_RCVBUF)).intValue();
- }
-
- public void setSoTimeout(int n) throws IOException {
- impl.setOption(SocketOptions.SO_TIMEOUT, Integer.valueOf(n));
- }
-
- public int getSoTimeout() throws IOException {
- return ((Integer) impl.getOption(SocketOptions.SO_TIMEOUT)).intValue();
- }
-
- public void setSendBufferSize(int n) throws IOException {
- impl.setOption(SocketOptions.SO_SNDBUF, Integer.valueOf(n));
- }
-
- public int getSendBufferSize() throws IOException {
- return ((Integer) impl.getOption(SocketOptions.SO_SNDBUF)).intValue();
- }
-
- //???SEC
- public LocalSocketAddress getRemoteSocketAddress() {
- throw new UnsupportedOperationException();
- }
-
- //???SEC
- public synchronized boolean isConnected() {
- return isConnected;
- }
-
- //???SEC
- public boolean isClosed() {
- throw new UnsupportedOperationException();
- }
-
- //???SEC
- public synchronized boolean isBound() {
- return isBound;
- }
-
- //???SEC
- public boolean isOutputShutdown() {
- throw new UnsupportedOperationException();
- }
-
- //???SEC
- public boolean isInputShutdown() {
- throw new UnsupportedOperationException();
- }
-
- //???SEC
- public void connect(LocalSocketAddress endpoint, int timeout)
- throws IOException {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Enqueues a set of file descriptors to send to the peer. The queue
- * is one deep. The file descriptors will be sent with the next write
- * of normal data, and will be delivered in a single ancillary message.
- * See "man 7 unix" SCM_RIGHTS on a desktop Linux machine.
- *
- * @param fds non-null; file descriptors to send.
- */
- public void setFileDescriptorsForSend(FileDescriptor[] fds) {
- impl.setFileDescriptorsForSend(fds);
- }
-
- /**
- * Retrieves a set of file descriptors that a peer has sent through
- * an ancillary message. This method retrieves the most recent set sent,
- * and then returns null until a new set arrives.
- * File descriptors may only be passed along with regular data, so this
- * method can only return a non-null after a read operation.
- *
- * @return null or file descriptor array
- * @throws IOException
- */
- public FileDescriptor[] getAncillaryFileDescriptors() throws IOException {
- return impl.getAncillaryFileDescriptors();
- }
-
- /**
- * Retrieves the credentials of this socket's peer. Only valid on
- * connected sockets.
- *
- * @return non-null; peer credentials
- * @throws IOException
- */
- public Credentials getPeerCredentials() throws IOException {
- return impl.getPeerCredentials();
- }
-
- /**
- * Returns file descriptor or null if not yet open/already closed
- *
- * @return fd or null
- */
- public FileDescriptor getFileDescriptor() {
- return impl.getFileDescriptor();
- }
-}
diff --git a/core/java/android/net/LocalSocketAddress.java b/core/java/android/net/LocalSocketAddress.java
deleted file mode 100644
index 8265b85bfcf..00000000000
--- a/core/java/android/net/LocalSocketAddress.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net;
-
-/**
- * A UNIX-domain (AF_LOCAL) socket address. For use with
- * android.net.LocalSocket and android.net.LocalServerSocket.
- *
- * On the Android system, these names refer to names in the Linux
- * abstract (non-filesystem) UNIX domain namespace.
- */
-public class LocalSocketAddress
-{
- /**
- * The namespace that this address exists in. See also
- * include/cutils/sockets.h ANDROID_SOCKET_NAMESPACE_*
- */
- public enum Namespace {
- /** A socket in the Linux abstract namespace */
- ABSTRACT(0),
- /**
- * A socket in the Android reserved namespace in /dev/socket.
- * Only the init process may create a socket here.
- */
- RESERVED(1),
- /**
- * A socket named with a normal filesystem path.
- */
- FILESYSTEM(2);
-
- /** The id matches with a #define in include/cutils/sockets.h */
- private int id;
- Namespace (int id) {
- this.id = id;
- }
-
- /**
- * @return int constant shared with native code
- */
- /*package*/ int getId() {
- return id;
- }
- }
-
- private final String name;
- private final Namespace namespace;
-
- /**
- * Creates an instance with a given name.
- *
- * @param name non-null name
- * @param namespace namespace the name should be created in.
- */
- public LocalSocketAddress(String name, Namespace namespace) {
- this.name = name;
- this.namespace = namespace;
- }
-
- /**
- * Creates an instance with a given name in the {@link Namespace#ABSTRACT}
- * namespace
- *
- * @param name non-null name
- */
- public LocalSocketAddress(String name) {
- this(name,Namespace.ABSTRACT);
- }
-
- /**
- * Retrieves the string name of this address
- * @return string name
- */
- public String getName()
- {
- return name;
- }
-
- /**
- * Returns the namespace used by this address.
- *
- * @return non-null a namespace
- */
- public Namespace getNamespace() {
- return namespace;
- }
-}
diff --git a/core/java/android/net/LocalSocketImpl.java b/core/java/android/net/LocalSocketImpl.java
deleted file mode 100644
index 6c36a7d62ff..00000000000
--- a/core/java/android/net/LocalSocketImpl.java
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.InputStream;
-import java.io.FileDescriptor;
-import java.net.SocketOptions;
-
-/**
- * Socket implementation used for android.net.LocalSocket and
- * android.net.LocalServerSocket. Supports only AF_LOCAL sockets.
- */
-class LocalSocketImpl
-{
- private SocketInputStream fis;
- private SocketOutputStream fos;
- private Object readMonitor = new Object();
- private Object writeMonitor = new Object();
-
- /** null if closed or not yet created */
- private FileDescriptor fd;
-
- // These fields are accessed by native code;
- /** file descriptor array received during a previous read */
- FileDescriptor[] inboundFileDescriptors;
- /** file descriptor array that should be written during next write */
- FileDescriptor[] outboundFileDescriptors;
-
- /**
- * An input stream for local sockets. Needed because we may
- * need to read ancillary data.
- */
- class SocketInputStream extends InputStream {
- /** {@inheritDoc} */
- @Override
- public int available() throws IOException {
- return available_native(fd);
- }
-
- /** {@inheritDoc} */
- @Override
- public void close() throws IOException {
- LocalSocketImpl.this.close();
- }
-
- /** {@inheritDoc} */
- @Override
- public int read() throws IOException {
- int ret;
- synchronized (readMonitor) {
- FileDescriptor myFd = fd;
- if (myFd == null) throw new IOException("socket closed");
-
- ret = read_native(myFd);
- return ret;
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public int read(byte[] b) throws IOException {
- return read(b, 0, b.length);
- }
-
- /** {@inheritDoc} */
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- synchronized (readMonitor) {
- FileDescriptor myFd = fd;
- if (myFd == null) throw new IOException("socket closed");
-
- if (off < 0 || len < 0 || (off + len) > b.length ) {
- throw new ArrayIndexOutOfBoundsException();
- }
-
- int ret = readba_native(b, off, len, myFd);
-
- return ret;
- }
- }
- }
-
- /**
- * An output stream for local sockets. Needed because we may
- * need to read ancillary data.
- */
- class SocketOutputStream extends OutputStream {
- /** {@inheritDoc} */
- @Override
- public void close() throws IOException {
- LocalSocketImpl.this.close();
- }
-
- /** {@inheritDoc} */
- @Override
- public void write (byte[] b) throws IOException {
- write(b, 0, b.length);
- }
-
- /** {@inheritDoc} */
- @Override
- public void write (byte[] b, int off, int len) throws IOException {
- synchronized (writeMonitor) {
- FileDescriptor myFd = fd;
- if (myFd == null) throw new IOException("socket closed");
-
- if (off < 0 || len < 0 || (off + len) > b.length ) {
- throw new ArrayIndexOutOfBoundsException();
- }
- writeba_native(b, off, len, myFd);
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public void write (int b) throws IOException {
- synchronized (writeMonitor) {
- FileDescriptor myFd = fd;
- if (myFd == null) throw new IOException("socket closed");
- write_native(b, myFd);
- }
- }
- }
-
- private native int available_native(FileDescriptor fd) throws IOException;
- private native void close_native(FileDescriptor fd) throws IOException;
- private native int read_native(FileDescriptor fd) throws IOException;
- private native int readba_native(byte[] b, int off, int len,
- FileDescriptor fd) throws IOException;
- private native void writeba_native(byte[] b, int off, int len,
- FileDescriptor fd) throws IOException;
- private native void write_native(int b, FileDescriptor fd)
- throws IOException;
- private native void connectLocal(FileDescriptor fd, String name,
- int namespace) throws IOException;
- private native void bindLocal(FileDescriptor fd, String name, int namespace)
- throws IOException;
- private native FileDescriptor create_native(boolean stream)
- throws IOException;
- private native void listen_native(FileDescriptor fd, int backlog)
- throws IOException;
- private native void shutdown(FileDescriptor fd, boolean shutdownInput);
- private native Credentials getPeerCredentials_native(
- FileDescriptor fd) throws IOException;
- private native int getOption_native(FileDescriptor fd, int optID)
- throws IOException;
- private native void setOption_native(FileDescriptor fd, int optID,
- int b, int value) throws IOException;
-
-// private native LocalSocketAddress getSockName_native
-// (FileDescriptor fd) throws IOException;
-
- /**
- * Accepts a connection on a server socket.
- *
- * @param fd file descriptor of server socket
- * @param s socket implementation that will become the new socket
- * @return file descriptor of new socket
- */
- private native FileDescriptor accept
- (FileDescriptor fd, LocalSocketImpl s) throws IOException;
-
- /**
- * Create a new instance.
- */
- /*package*/ LocalSocketImpl()
- {
- }
-
- /**
- * Create a new instance from a file descriptor representing
- * a bound socket. The state of the file descriptor is not checked here
- * but the caller can verify socket state by calling listen().
- *
- * @param fd non-null; bound file descriptor
- */
- /*package*/ LocalSocketImpl(FileDescriptor fd) throws IOException
- {
- this.fd = fd;
- }
-
- public String toString() {
- return super.toString() + " fd:" + fd;
- }
-
- /**
- * Creates a socket in the underlying OS.
- *
- * @param stream true if this should be a stream socket, false for
- * datagram.
- * @throws IOException
- */
- public void create (boolean stream) throws IOException {
- // no error if socket already created
- // need this for LocalServerSocket.accept()
- if (fd == null) {
- fd = create_native(stream);
- }
- }
-
- /**
- * Closes the socket.
- *
- * @throws IOException
- */
- public void close() throws IOException {
- synchronized (LocalSocketImpl.this) {
- if (fd == null) return;
- close_native(fd);
- fd = null;
- }
- }
-
- /** note timeout presently ignored */
- protected void connect(LocalSocketAddress address, int timeout)
- throws IOException
- {
- if (fd == null) {
- throw new IOException("socket not created");
- }
-
- connectLocal(fd, address.getName(), address.getNamespace().getId());
- }
-
- /**
- * Binds this socket to an endpoint name. May only be called on an instance
- * that has not yet been bound.
- *
- * @param endpoint endpoint address
- * @throws IOException
- */
- public void bind(LocalSocketAddress endpoint) throws IOException
- {
- if (fd == null) {
- throw new IOException("socket not created");
- }
-
- bindLocal(fd, endpoint.getName(), endpoint.getNamespace().getId());
- }
-
- protected void listen(int backlog) throws IOException
- {
- if (fd == null) {
- throw new IOException("socket not created");
- }
-
- listen_native(fd, backlog);
- }
-
- /**
- * Accepts a new connection to the socket. Blocks until a new
- * connection arrives.
- *
- * @param s a socket that will be used to represent the new connection.
- * @throws IOException
- */
- protected void accept(LocalSocketImpl s) throws IOException
- {
- if (fd == null) {
- throw new IOException("socket not created");
- }
-
- s.fd = accept(fd, s);
- }
-
- /**
- * Retrieves the input stream for this instance.
- *
- * @return input stream
- * @throws IOException if socket has been closed or cannot be created.
- */
- protected InputStream getInputStream() throws IOException
- {
- if (fd == null) {
- throw new IOException("socket not created");
- }
-
- synchronized (this) {
- if (fis == null) {
- fis = new SocketInputStream();
- }
-
- return fis;
- }
- }
-
- /**
- * Retrieves the output stream for this instance.
- *
- * @return output stream
- * @throws IOException if socket has been closed or cannot be created.
- */
- protected OutputStream getOutputStream() throws IOException
- {
- if (fd == null) {
- throw new IOException("socket not created");
- }
-
- synchronized (this) {
- if (fos == null) {
- fos = new SocketOutputStream();
- }
-
- return fos;
- }
- }
-
- /**
- * Returns the number of bytes available for reading without blocking.
- *
- * @return >= 0 count bytes available
- * @throws IOException
- */
- protected int available() throws IOException
- {
- return getInputStream().available();
- }
-
- /**
- * Shuts down the input side of the socket.
- *
- * @throws IOException
- */
- protected void shutdownInput() throws IOException
- {
- if (fd == null) {
- throw new IOException("socket not created");
- }
-
- shutdown(fd, true);
- }
-
- /**
- * Shuts down the output side of the socket.
- *
- * @throws IOException
- */
- protected void shutdownOutput() throws IOException
- {
- if (fd == null) {
- throw new IOException("socket not created");
- }
-
- shutdown(fd, false);
- }
-
- protected FileDescriptor getFileDescriptor()
- {
- return fd;
- }
-
- protected boolean supportsUrgentData()
- {
- return false;
- }
-
- protected void sendUrgentData(int data) throws IOException
- {
- throw new RuntimeException ("not impled");
- }
-
- public Object getOption(int optID) throws IOException
- {
- if (fd == null) {
- throw new IOException("socket not created");
- }
-
- if (optID == SocketOptions.SO_TIMEOUT) {
- return 0;
- }
-
- int value = getOption_native(fd, optID);
- switch (optID)
- {
- case SocketOptions.SO_RCVBUF:
- case SocketOptions.SO_SNDBUF:
- return value;
- case SocketOptions.SO_REUSEADDR:
- default:
- return value;
- }
- }
-
- public void setOption(int optID, Object value)
- throws IOException {
- /*
- * Boolean.FALSE is used to disable some options, so it
- * is important to distinguish between FALSE and unset.
- * We define it here that -1 is unset, 0 is FALSE, and 1
- * is TRUE.
- */
- int boolValue = -1;
- int intValue = 0;
-
- if (fd == null) {
- throw new IOException("socket not created");
- }
-
- if (value instanceof Integer) {
- intValue = (Integer)value;
- } else if (value instanceof Boolean) {
- boolValue = ((Boolean) value)? 1 : 0;
- } else {
- throw new IOException("bad value: " + value);
- }
-
- setOption_native(fd, optID, boolValue, intValue);
- }
-
- /**
- * Enqueues a set of file descriptors to send to the peer. The queue
- * is one deep. The file descriptors will be sent with the next write
- * of normal data, and will be delivered in a single ancillary message.
- * See "man 7 unix" SCM_RIGHTS on a desktop Linux machine.
- *
- * @param fds non-null; file descriptors to send.
- * @throws IOException
- */
- public void setFileDescriptorsForSend(FileDescriptor[] fds) {
- synchronized(writeMonitor) {
- outboundFileDescriptors = fds;
- }
- }
-
- /**
- * Retrieves a set of file descriptors that a peer has sent through
- * an ancillary message. This method retrieves the most recent set sent,
- * and then returns null until a new set arrives.
- * File descriptors may only be passed along with regular data, so this
- * method can only return a non-null after a read operation.
- *
- * @return null or file descriptor array
- * @throws IOException
- */
- public FileDescriptor[] getAncillaryFileDescriptors() throws IOException {
- synchronized(readMonitor) {
- FileDescriptor[] result = inboundFileDescriptors;
-
- inboundFileDescriptors = null;
- return result;
- }
- }
-
- /**
- * Retrieves the credentials of this socket's peer. Only valid on
- * connected sockets.
- *
- * @return non-null; peer credentials
- * @throws IOException
- */
- public Credentials getPeerCredentials() throws IOException
- {
- return getPeerCredentials_native(fd);
- }
-
- /**
- * Retrieves the socket name from the OS.
- *
- * @return non-null; socket name
- * @throws IOException on failure
- */
- public LocalSocketAddress getSockAddress() throws IOException
- {
- return null;
- //TODO implement this
- //return getSockName_native(fd);
- }
-
- @Override
- protected void finalize() throws IOException {
- close();
- }
-}
-
diff --git a/core/java/android/net/MailTo.java b/core/java/android/net/MailTo.java
deleted file mode 100644
index ca28f86a7f0..00000000000
--- a/core/java/android/net/MailTo.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- *
- * MailTo URL parser
- *
- * This class parses a mailto scheme URL and then can be queried for
- * the parsed parameters. This implements RFC 2368.
- *
- */
-public class MailTo {
-
- static public final String MAILTO_SCHEME = "mailto:";
-
- // All the parsed content is added to the headers.
- private HashMap<String, String> mHeaders;
-
- // Well known headers
- static private final String TO = "to";
- static private final String BODY = "body";
- static private final String CC = "cc";
- static private final String SUBJECT = "subject";
-
-
- /**
- * Test to see if the given string is a mailto URL
- * @param url string to be tested
- * @return true if the string is a mailto URL
- */
- public static boolean isMailTo(String url) {
- if (url != null && url.startsWith(MAILTO_SCHEME)) {
- return true;
- }
- return false;
- }
-
- /**
- * Parse and decode a mailto scheme string. This parser implements
- * RFC 2368. The returned object can be queried for the parsed parameters.
- * @param url String containing a mailto URL
- * @return MailTo object
- * @exception ParseException if the scheme is not a mailto URL
- */
- public static MailTo parse(String url) throws ParseException {
- if (url == null) {
- throw new NullPointerException();
- }
- if (!isMailTo(url)) {
- throw new ParseException("Not a mailto scheme");
- }
- // Strip the scheme as the Uri parser can't cope with it.
- String noScheme = url.substring(MAILTO_SCHEME.length());
- Uri email = Uri.parse(noScheme);
- MailTo m = new MailTo();
-
- // Parse out the query parameters
- String query = email.getQuery();
- if (query != null ) {
- String[] queries = query.split("&");
- for (String q : queries) {
- String[] nameval = q.split("=");
- if (nameval.length == 0) {
- continue;
- }
- // insert the headers with the name in lowercase so that
- // we can easily find common headers
- m.mHeaders.put(Uri.decode(nameval[0]).toLowerCase(),
- nameval.length > 1 ? Uri.decode(nameval[1]) : null);
- }
- }
-
- // Address can be specified in both the headers and just after the
- // mailto line. Join the two together.
- String address = email.getPath();
- if (address != null) {
- String addr = m.getTo();
- if (addr != null) {
- address += ", " + addr;
- }
- m.mHeaders.put(TO, address);
- }
-
- return m;
- }
-
- /**
- * Retrieve the To address line from the parsed mailto URL. This could be
- * several email address that are comma-space delimited.
- * If no To line was specified, then null is return
- * @return comma delimited email addresses or null
- */
- public String getTo() {
- return mHeaders.get(TO);
- }
-
- /**
- * Retrieve the CC address line from the parsed mailto URL. This could be
- * several email address that are comma-space delimited.
- * If no CC line was specified, then null is return
- * @return comma delimited email addresses or null
- */
- public String getCc() {
- return mHeaders.get(CC);
- }
-
- /**
- * Retrieve the subject line from the parsed mailto URL.
- * If no subject line was specified, then null is return
- * @return subject or null
- */
- public String getSubject() {
- return mHeaders.get(SUBJECT);
- }
-
- /**
- * Retrieve the body line from the parsed mailto URL.
- * If no body line was specified, then null is return
- * @return body or null
- */
- public String getBody() {
- return mHeaders.get(BODY);
- }
-
- /**
- * Retrieve all the parsed email headers from the mailto URL
- * @return map containing all parsed values
- */
- public Map<String, String> getHeaders() {
- return mHeaders;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder(MAILTO_SCHEME);
- sb.append('?');
- for (Map.Entry<String,String> header : mHeaders.entrySet()) {
- sb.append(Uri.encode(header.getKey()));
- sb.append('=');
- sb.append(Uri.encode(header.getValue()));
- sb.append('&');
- }
- return sb.toString();
- }
-
- /**
- * Private constructor. The only way to build a Mailto object is through
- * the parse() method.
- */
- private MailTo() {
- mHeaders = new HashMap<String, String>();
- }
-}
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
deleted file mode 100644
index 1d939e10068..00000000000
--- a/core/java/android/net/MobileDataStateTracker.java
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.RemoteException;
-import android.os.Handler;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.TelephonyIntents;
-import android.net.NetworkInfo.DetailedState;
-import android.telephony.TelephonyManager;
-import android.util.Log;
-import android.text.TextUtils;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * Track the state of mobile data connectivity. This is done by
- * receiving broadcast intents from the Phone process whenever
- * the state of data connectivity changes.
- *
- * {@hide}
- */
-public class MobileDataStateTracker extends NetworkStateTracker {
-
- private static final String TAG = "MobileDataStateTracker";
- private static final boolean DBG = false;
-
- private Phone.DataState mMobileDataState;
- private ITelephony mPhoneService;
- private static final String[] sDnsPropNames = {
- "net.rmnet0.dns1",
- "net.rmnet0.dns2",
- "net.eth0.dns1",
- "net.eth0.dns2",
- "net.eth0.dns3",
- "net.eth0.dns4",
- "net.gprs.dns1",
- "net.gprs.dns2"
- };
- private List<String> mDnsServers;
- private String mInterfaceName;
- private int mDefaultGatewayAddr;
- private int mLastCallingPid = -1;
-
- /**
- * Create a new MobileDataStateTracker
- * @param context the application context of the caller
- * @param target a message handler for getting callbacks about state changes
- */
- public MobileDataStateTracker(Context context, Handler target) {
- super(context, target, ConnectivityManager.TYPE_MOBILE,
- TelephonyManager.getDefault().getNetworkType(), "MOBILE",
- TelephonyManager.getDefault().getNetworkTypeName());
- mPhoneService = null;
- mDnsServers = new ArrayList<String>();
- }
-
- /**
- * Begin monitoring mobile data connectivity.
- */
- public void startMonitoring() {
- IntentFilter filter =
- new IntentFilter(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
- filter.addAction(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED);
- filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
-
- Intent intent = mContext.registerReceiver(new MobileDataStateReceiver(), filter);
- if (intent != null)
- mMobileDataState = getMobileDataState(intent);
- else
- mMobileDataState = Phone.DataState.DISCONNECTED;
- }
-
- private static Phone.DataState getMobileDataState(Intent intent) {
- String str = intent.getStringExtra(Phone.STATE_KEY);
- if (str != null)
- return Enum.valueOf(Phone.DataState.class, str);
- else
- return Phone.DataState.DISCONNECTED;
- }
-
- private class MobileDataStateReceiver extends BroadcastReceiver {
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
- Phone.DataState state = getMobileDataState(intent);
- String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY);
- String apnName = intent.getStringExtra(Phone.DATA_APN_KEY);
- boolean unavailable = intent.getBooleanExtra(Phone.NETWORK_UNAVAILABLE_KEY, false);
- if (DBG) Log.d(TAG, "Received " + intent.getAction() +
- " broadcast - state = " + state
- + ", unavailable = " + unavailable
- + ", reason = " + (reason == null ? "(unspecified)" : reason));
- mNetworkInfo.setIsAvailable(!unavailable);
- if (mMobileDataState != state) {
- mMobileDataState = state;
-
- switch (state) {
- case DISCONNECTED:
- setDetailedState(DetailedState.DISCONNECTED, reason, apnName);
- if (mInterfaceName != null) {
- NetworkUtils.resetConnections(mInterfaceName);
- }
- mInterfaceName = null;
- mDefaultGatewayAddr = 0;
- break;
- case CONNECTING:
- setDetailedState(DetailedState.CONNECTING, reason, apnName);
- break;
- case SUSPENDED:
- setDetailedState(DetailedState.SUSPENDED, reason, apnName);
- break;
- case CONNECTED:
- mInterfaceName = intent.getStringExtra(Phone.DATA_IFACE_NAME_KEY);
- if (mInterfaceName == null) {
- Log.d(TAG, "CONNECTED event did not supply interface name.");
- }
- setupDnsProperties();
- setDetailedState(DetailedState.CONNECTED, reason, apnName);
- break;
- }
- }
- } else if (intent.getAction().equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
- String reason = intent.getStringExtra(Phone.FAILURE_REASON_KEY);
- String apnName = intent.getStringExtra(Phone.DATA_APN_KEY);
- if (DBG) Log.d(TAG, "Received " + intent.getAction() + " broadcast" +
- reason == null ? "" : "(" + reason + ")");
- setDetailedState(DetailedState.FAILED, reason, apnName);
- }
- TelephonyManager tm = TelephonyManager.getDefault();
- setRoamingStatus(tm.isNetworkRoaming());
- setSubtype(tm.getNetworkType(), tm.getNetworkTypeName());
- }
- }
-
- /**
- * Make sure that route(s) exist to the carrier DNS server(s).
- */
- public void addPrivateRoutes() {
- if (mInterfaceName != null) {
- for (String addrString : mDnsServers) {
- int addr = NetworkUtils.lookupHost(addrString);
- if (addr != -1) {
- NetworkUtils.addHostRoute(mInterfaceName, addr);
- }
- }
- }
- }
-
- public void removePrivateRoutes() {
- if(mInterfaceName != null) {
- NetworkUtils.removeHostRoutes(mInterfaceName);
- }
- }
-
- public void removeDefaultRoute() {
- if(mInterfaceName != null) {
- mDefaultGatewayAddr = NetworkUtils.getDefaultRoute(mInterfaceName);
- NetworkUtils.removeDefaultRoute(mInterfaceName);
- }
- }
-
- public void restoreDefaultRoute() {
- // 0 is not a valid address for a gateway
- if (mInterfaceName != null && mDefaultGatewayAddr != 0) {
- NetworkUtils.setDefaultRoute(mInterfaceName, mDefaultGatewayAddr);
- }
- }
-
- private void getPhoneService(boolean forceRefresh) {
- if ((mPhoneService == null) || forceRefresh) {
- mPhoneService = ITelephony.Stub.asInterface(ServiceManager.getService("phone"));
- }
- }
-
- /**
- * Report whether data connectivity is possible.
- */
- public boolean isAvailable() {
- getPhoneService(false);
-
- /*
- * If the phone process has crashed in the past, we'll get a
- * RemoteException and need to re-reference the service.
- */
- for (int retry = 0; retry < 2; retry++) {
- if (mPhoneService == null) break;
-
- try {
- return mPhoneService.isDataConnectivityPossible();
- } catch (RemoteException e) {
- // First-time failed, get the phone service again
- if (retry == 0) getPhoneService(true);
- }
- }
-
- return false;
- }
-
- /**
- * Return the IP addresses of the DNS servers available for the mobile data
- * network interface.
- * @return a list of DNS addresses, with no holes.
- */
- public String[] getNameServers() {
- return getNameServerList(sDnsPropNames);
- }
-
- /**
- * {@inheritDoc}
- * The mobile data network subtype indicates what generation network technology is in effect,
- * e.g., GPRS, EDGE, UMTS, etc.
- */
- public int getNetworkSubtype() {
- return TelephonyManager.getDefault().getNetworkType();
- }
-
- /**
- * Return the system properties name associated with the tcp buffer sizes
- * for this network.
- */
- public String getTcpBufferSizesPropName() {
- String networkTypeStr = "unknown";
- TelephonyManager tm = new TelephonyManager(mContext);
- switch(tm.getNetworkType()) {
- case TelephonyManager.NETWORK_TYPE_GPRS:
- networkTypeStr = "gprs";
- break;
- case TelephonyManager.NETWORK_TYPE_EDGE:
- networkTypeStr = "edge";
- break;
- case TelephonyManager.NETWORK_TYPE_UMTS:
- networkTypeStr = "umts";
- break;
- }
- return "net.tcp.buffersize." + networkTypeStr;
- }
-
- /**
- * Tear down mobile data connectivity, i.e., disable the ability to create
- * mobile data connections.
- */
- @Override
- public boolean teardown() {
- getPhoneService(false);
- /*
- * If the phone process has crashed in the past, we'll get a
- * RemoteException and need to re-reference the service.
- */
- for (int retry = 0; retry < 2; retry++) {
- if (mPhoneService == null) {
- Log.w(TAG,
- "Ignoring mobile data teardown request because could not acquire PhoneService");
- break;
- }
-
- try {
- return mPhoneService.disableDataConnectivity();
- } catch (RemoteException e) {
- if (retry == 0) getPhoneService(true);
- }
- }
-
- Log.w(TAG, "Failed to tear down mobile data connectivity");
- return false;
- }
-
- /**
- * Re-enable mobile data connectivity after a {@link #teardown()}.
- */
- public boolean reconnect() {
- getPhoneService(false);
- /*
- * If the phone process has crashed in the past, we'll get a
- * RemoteException and need to re-reference the service.
- */
- for (int retry = 0; retry < 2; retry++) {
- if (mPhoneService == null) {
- Log.w(TAG,
- "Ignoring mobile data connect request because could not acquire PhoneService");
- break;
- }
-
- try {
- return mPhoneService.enableDataConnectivity();
- } catch (RemoteException e) {
- if (retry == 0) getPhoneService(true);
- }
- }
-
- Log.w(TAG, "Failed to set up mobile data connectivity");
- return false;
- }
-
- /**
- * Turn on or off the mobile radio. No connectivity will be possible while the
- * radio is off. The operation is a no-op if the radio is already in the desired state.
- * @param turnOn {@code true} if the radio should be turned on, {@code false} if
- */
- public boolean setRadio(boolean turnOn) {
- getPhoneService(false);
- /*
- * If the phone process has crashed in the past, we'll get a
- * RemoteException and need to re-reference the service.
- */
- for (int retry = 0; retry < 2; retry++) {
- if (mPhoneService == null) {
- Log.w(TAG,
- "Ignoring mobile radio request because could not acquire PhoneService");
- break;
- }
-
- try {
- return mPhoneService.setRadio(turnOn);
- } catch (RemoteException e) {
- if (retry == 0) getPhoneService(true);
- }
- }
-
- Log.w(TAG, "Could not set radio power to " + (turnOn ? "on" : "off"));
- return false;
- }
-
- /**
- * Tells the phone sub-system that the caller wants to
- * begin using the named feature. The only supported feature at
- * this time is {@code Phone.FEATURE_ENABLE_MMS}, which allows an application
- * to specify that it wants to send and/or receive MMS data.
- * @param feature the name of the feature to be used
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is feature-specific.
- * specific, except that the value {@code -1}
- * always indicates failure. For {@code Phone.FEATURE_ENABLE_MMS},
- * the other possible return values are
- * <ul>
- * <li>{@code Phone.APN_ALREADY_ACTIVE}</li>
- * <li>{@code Phone.APN_REQUEST_STARTED}</li>
- * <li>{@code Phone.APN_TYPE_NOT_AVAILABLE}</li>
- * <li>{@code Phone.APN_REQUEST_FAILED}</li>
- * </ul>
- */
- public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
- mLastCallingPid = callingPid;
- return setEnableApn(Phone.APN_TYPE_MMS, true);
- } else {
- return -1;
- }
- }
-
- /**
- * Tells the phone sub-system that the caller is finished
- * using the named feature. The only supported feature at
- * this time is {@code Phone.FEATURE_ENABLE_MMS}, which allows an application
- * to specify that it wants to send and/or receive MMS data.
- * @param feature the name of the feature that is no longer needed
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is feature-specific, except that
- * the value {@code -1} always indicates failure.
- */
- public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
- if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
- return setEnableApn(Phone.APN_TYPE_MMS, false);
- } else {
- return -1;
- }
- }
-
- /**
- * Ensure that a network route exists to deliver traffic to the specified
- * host via the mobile data network.
- * @param hostAddress the IP address of the host to which the route is desired,
- * in network byte order.
- * @return {@code true} on success, {@code false} on failure
- */
- @Override
- public boolean requestRouteToHost(int hostAddress) {
- if (mInterfaceName != null && hostAddress != -1) {
- if (DBG) {
- Log.d(TAG, "Requested host route to " + Integer.toHexString(hostAddress));
- }
- return NetworkUtils.addHostRoute(mInterfaceName, hostAddress) == 0;
- } else {
- return false;
- }
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer("Mobile data state: ");
-
- sb.append(mMobileDataState);
- return sb.toString();
- }
-
- private void setupDnsProperties() {
- mDnsServers.clear();
- // Set up per-process DNS server list on behalf of the MMS process
- int i = 1;
- if (mInterfaceName != null) {
- for (String propName : sDnsPropNames) {
- if (propName.indexOf(mInterfaceName) != -1) {
- String propVal = SystemProperties.get(propName);
- if (propVal != null && propVal.length() != 0 && !propVal.equals("0.0.0.0")) {
- mDnsServers.add(propVal);
- if (mLastCallingPid != -1) {
- SystemProperties.set("net.dns" + i + "." + mLastCallingPid, propVal);
- }
- ++i;
- }
- }
- }
- }
- if (i == 1) {
- Log.d(TAG, "DNS server addresses are not known.");
- } else if (mLastCallingPid != -1) {
- /*
- * Bump the property that tells the name resolver library
- * to reread the DNS server list from the properties.
- */
- String propVal = SystemProperties.get("net.dnschange");
- if (propVal.length() != 0) {
- try {
- int n = Integer.parseInt(propVal);
- SystemProperties.set("net.dnschange", "" + (n+1));
- } catch (NumberFormatException e) {
- }
- }
- }
- mLastCallingPid = -1;
- }
-
- /**
- * Internal method supporting the ENABLE_MMS feature.
- * @param apnType the type of APN to be enabled or disabled (e.g., mms)
- * @param enable {@code true} to enable the specified APN type,
- * {@code false} to disable it.
- * @return an integer value representing the outcome of the request.
- */
- private int setEnableApn(String apnType, boolean enable) {
- getPhoneService(false);
- /*
- * If the phone process has crashed in the past, we'll get a
- * RemoteException and need to re-reference the service.
- */
- for (int retry = 0; retry < 2; retry++) {
- if (mPhoneService == null) {
- Log.w(TAG,
- "Ignoring feature request because could not acquire PhoneService");
- break;
- }
-
- try {
- if (enable) {
- return mPhoneService.enableApnType(apnType);
- } else {
- return mPhoneService.disableApnType(apnType);
- }
- } catch (RemoteException e) {
- if (retry == 0) getPhoneService(true);
- }
- }
-
- Log.w(TAG, "Could not " + (enable ? "enable" : "disable")
- + " APN type \"" + apnType + "\"");
- return Phone.APN_REQUEST_FAILED;
- }
-}
diff --git a/core/java/android/net/NetworkConnectivityListener.java b/core/java/android/net/NetworkConnectivityListener.java
deleted file mode 100644
index 858fc779563..00000000000
--- a/core/java/android/net/NetworkConnectivityListener.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * 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 android.net;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Iterator;
-
-/**
- * A wrapper for a broadcast receiver that provides network connectivity
- * state information, independent of network type (mobile, Wi-Fi, etc.).
- * {@hide}
- */
-public class NetworkConnectivityListener {
- private static final String TAG = "NetworkConnectivityListener";
- private static final boolean DBG = false;
-
- private Context mContext;
- private HashMap<Handler, Integer> mHandlers = new HashMap<Handler, Integer>();
- private State mState;
- private boolean mListening;
- private String mReason;
- private boolean mIsFailover;
-
- /** Network connectivity information */
- private NetworkInfo mNetworkInfo;
-
- /**
- * In case of a Disconnect, the connectivity manager may have
- * already established, or may be attempting to establish, connectivity
- * with another network. If so, {@code mOtherNetworkInfo} will be non-null.
- */
- private NetworkInfo mOtherNetworkInfo;
-
- private ConnectivityBroadcastReceiver mReceiver;
-
- private class ConnectivityBroadcastReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
-
- if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
- mListening == false) {
- Log.w(TAG, "onReceived() called with " + mState.toString() + " and " + intent);
- return;
- }
-
- boolean noConnectivity =
- intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
-
- if (noConnectivity) {
- mState = State.NOT_CONNECTED;
- } else {
- mState = State.CONNECTED;
- }
-
- mNetworkInfo = (NetworkInfo)
- intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
- mOtherNetworkInfo = (NetworkInfo)
- intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
-
- mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
- mIsFailover =
- intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
-
- if (DBG) {
- Log.d(TAG, "onReceive(): mNetworkInfo=" + mNetworkInfo + " mOtherNetworkInfo = "
- + (mOtherNetworkInfo == null ? "[none]" : mOtherNetworkInfo +
- " noConn=" + noConnectivity) + " mState=" + mState.toString());
- }
-
- // Notifiy any handlers.
- Iterator<Handler> it = mHandlers.keySet().iterator();
- while (it.hasNext()) {
- Handler target = it.next();
- Message message = Message.obtain(target, mHandlers.get(target));
- target.sendMessage(message);
- }
- }
- };
-
- public enum State {
- UNKNOWN,
-
- /** This state is returned if there is connectivity to any network **/
- CONNECTED,
- /**
- * This state is returned if there is no connectivity to any network. This is set
- * to true under two circumstances:
- * <ul>
- * <li>When connectivity is lost to one network, and there is no other available
- * network to attempt to switch to.</li>
- * <li>When connectivity is lost to one network, and the attempt to switch to
- * another network fails.</li>
- */
- NOT_CONNECTED
- }
-
- /**
- * Create a new NetworkConnectivityListener.
- */
- public NetworkConnectivityListener() {
- mState = State.UNKNOWN;
- mReceiver = new ConnectivityBroadcastReceiver();
- }
-
- /**
- * This method starts listening for network connectivity state changes.
- * @param context
- */
- public synchronized void startListening(Context context) {
- if (!mListening) {
- mContext = context;
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- context.registerReceiver(mReceiver, filter);
- mListening = true;
- }
- }
-
- /**
- * This method stops this class from listening for network changes.
- */
- public synchronized void stopListening() {
- if (mListening) {
- mContext.unregisterReceiver(mReceiver);
- mContext = null;
- mNetworkInfo = null;
- mOtherNetworkInfo = null;
- mIsFailover = false;
- mReason = null;
- mListening = false;
- }
- }
-
- /**
- * This methods registers a Handler to be called back onto with the specified what code when
- * the network connectivity state changes.
- *
- * @param target The target handler.
- * @param what The what code to be used when posting a message to the handler.
- */
- public void registerHandler(Handler target, int what) {
- mHandlers.put(target, what);
- }
-
- /**
- * This methods unregisters the specified Handler.
- * @param target
- */
- public void unregisterHandler(Handler target) {
- mHandlers.remove(target);
- }
-
- public State getState() {
- return mState;
- }
-
- /**
- * Return the NetworkInfo associated with the most recent connectivity event.
- * @return {@code NetworkInfo} for the network that had the most recent connectivity event.
- */
- public NetworkInfo getNetworkInfo() {
- return mNetworkInfo;
- }
-
- /**
- * If the most recent connectivity event was a DISCONNECT, return
- * any information supplied in the broadcast about an alternate
- * network that might be available. If this returns a non-null
- * value, then another broadcast should follow shortly indicating
- * whether connection to the other network succeeded.
- *
- * @return NetworkInfo
- */
- public NetworkInfo getOtherNetworkInfo() {
- return mOtherNetworkInfo;
- }
-
- /**
- * Returns true if the most recent event was for an attempt to switch over to
- * a new network following loss of connectivity on another network.
- * @return {@code true} if this was a failover attempt, {@code false} otherwise.
- */
- public boolean isFailover() {
- return mIsFailover;
- }
-
- /**
- * An optional reason for the connectivity state change may have been supplied.
- * This returns it.
- * @return the reason for the state change, if available, or {@code null}
- * otherwise.
- */
- public String getReason() {
- return mReason;
- }
-}
diff --git a/core/java/android/net/NetworkInfo.aidl b/core/java/android/net/NetworkInfo.aidl
deleted file mode 100644
index f5018730296..00000000000
--- a/core/java/android/net/NetworkInfo.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2007, 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 android.net;
-
-parcelable NetworkInfo;
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
deleted file mode 100644
index 8c82212f0d8..00000000000
--- a/core/java/android/net/NetworkInfo.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import java.util.EnumMap;
-
-/**
- * Describes the status of a network interface of a given type
- * (currently either Mobile or Wifi).
- */
-public class NetworkInfo implements Parcelable {
-
- /**
- * Coarse-grained network state. This is probably what most applications should
- * use, rather than {@link android.net.NetworkInfo.DetailedState DetailedState}.
- * The mapping between the two is as follows:
- * <br/><br/>
- * <table>
- * <tr><td><b>Detailed state</b></td><td><b>Coarse-grained state</b></td></tr>
- * <tr><td><code>IDLE</code></td><td><code>DISCONNECTED</code></td></tr>
- * <tr><td><code>SCANNING</code></td><td><code>CONNECTING</code></td></tr>
- * <tr><td><code>CONNECTING</code></td><td><code>CONNECTING</code></td></tr>
- * <tr><td><code>AUTHENTICATING</code></td><td><code>CONNECTING</code></td></tr>
- * <tr><td><code>CONNECTED</code></td><td<code>CONNECTED</code></td></tr>
- * <tr><td><code>DISCONNECTING</code></td><td><code>DISCONNECTING</code></td></tr>
- * <tr><td><code>DISCONNECTED</code></td><td><code>DISCONNECTED</code></td></tr>
- * <tr><td><code>UNAVAILABLE</code></td><td><code>DISCONNECTED</code></td></tr>
- * <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr>
- * </table>
- */
- public enum State {
- CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN
- }
-
- /**
- * The fine-grained state of a network connection. This level of detail
- * is probably of interest to few applications. Most should use
- * {@link android.net.NetworkInfo.State State} instead.
- */
- public enum DetailedState {
- /** Ready to start data connection setup. */
- IDLE,
- /** Searching for an available access point. */
- SCANNING,
- /** Currently setting up data connection. */
- CONNECTING,
- /** Network link established, performing authentication. */
- AUTHENTICATING,
- /** Awaiting response from DHCP server in order to assign IP address information. */
- OBTAINING_IPADDR,
- /** IP traffic should be available. */
- CONNECTED,
- /** IP traffic is suspended */
- SUSPENDED,
- /** Currently tearing down data connection. */
- DISCONNECTING,
- /** IP traffic not available. */
- DISCONNECTED,
- /** Attempt to connect failed. */
- FAILED
- }
-
- /**
- * This is the map described in the Javadoc comment above. The positions
- * of the elements of the array must correspond to the ordinal values
- * of <code>DetailedState</code>.
- */
- private static final EnumMap<DetailedState, State> stateMap =
- new EnumMap<DetailedState, State>(DetailedState.class);
-
- static {
- stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
- stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
- stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
- stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
- stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
- stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
- stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
- stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
- stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
- stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
- }
-
- private int mNetworkType;
- private int mSubtype;
- private String mTypeName;
- private String mSubtypeName;
- private State mState;
- private DetailedState mDetailedState;
- private String mReason;
- private String mExtraInfo;
- private boolean mIsFailover;
- private boolean mIsRoaming;
- /**
- * Indicates whether network connectivity is possible:
- */
- private boolean mIsAvailable;
-
- /**
- * TODO This is going away as soon as API council review happens.
- * @param type network type
- */
- public NetworkInfo(int type) {}
-
- NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
- if (!ConnectivityManager.isNetworkTypeValid(type)) {
- throw new IllegalArgumentException("Invalid network type: " + type);
- }
- mNetworkType = type;
- mSubtype = subtype;
- mTypeName = typeName;
- mSubtypeName = subtypeName;
- setDetailedState(DetailedState.IDLE, null, null);
- mState = State.UNKNOWN;
- mIsAvailable = true;
- mIsRoaming = false;
- }
-
- /**
- * Reports the type of network (currently mobile or Wi-Fi) to which the
- * info in this object pertains.
- * @return the network type
- */
- public int getType() {
- return mNetworkType;
- }
-
- /**
- * Return a network-type-specific integer describing the subtype
- * of the network.
- * @return the network subtype
- *
- * @hide pending API council review
- */
- public int getSubtype() {
- return mSubtype;
- }
-
- void setSubtype(int subtype, String subtypeName) {
- mSubtype = subtype;
- mSubtypeName = subtypeName;
- }
-
- /**
- * Return a human-readable name describe the type of the network,
- * for example "WIFI" or "MOBILE".
- * @return the name of the network type
- */
- public String getTypeName() {
- return mTypeName;
- }
-
- /**
- * Return a human-readable name describing the subtype of the network.
- * @return the name of the network subtype
- *
- * @hide pending API council review
- */
- public String getSubtypeName() {
- return mSubtypeName;
- }
-
- /**
- * Indicates whether network connectivity exists or is in the process
- * of being established. This is good for applications that need to
- * do anything related to the network other than read or write data.
- * For the latter, call {@link #isConnected()} instead, which guarantees
- * that the network is fully usable.
- * @return {@code true} if network connectivity exists or is in the process
- * of being established, {@code false} otherwise.
- */
- public boolean isConnectedOrConnecting() {
- return mState == State.CONNECTED || mState == State.CONNECTING;
- }
-
- /**
- * Indicates whether network connectivity exists and it is possible to establish
- * connections and pass data.
- * @return {@code true} if network connectivity exists, {@code false} otherwise.
- */
- public boolean isConnected() {
- return mState == State.CONNECTED;
- }
-
- /**
- * Indicates whether network connectivity is possible. A network is unavailable
- * when a persistent or semi-persistent condition prevents the possibility
- * of connecting to that network. Examples include
- * <ul>
- * <li>The device is out of the coverage area for any network of this type.</li>
- * <li>The device is on a network other than the home network (i.e., roaming), and
- * data roaming has been disabled.</li>
- * <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li>
- * </ul>
- * @return {@code true} if the network is available, {@code false} otherwise
- */
- public boolean isAvailable() {
- return mIsAvailable;
- }
-
- /**
- * Sets if the network is available, ie, if the connectivity is possible.
- * @param isAvailable the new availability value.
- *
- * @hide
- */
- public void setIsAvailable(boolean isAvailable) {
- mIsAvailable = isAvailable;
- }
-
- /**
- * Indicates whether the current attempt to connect to the network
- * resulted from the ConnectivityManager trying to fail over to this
- * network following a disconnect from another network.
- * @return {@code true} if this is a failover attempt, {@code false}
- * otherwise.
- */
- public boolean isFailover() {
- return mIsFailover;
- }
-
- /**
- * Set the failover boolean.
- * @param isFailover {@code true} to mark the current connection attempt
- * as a failover.
- * @hide
- */
- public void setFailover(boolean isFailover) {
- mIsFailover = isFailover;
- }
-
- /**
- * Indicates whether the device is currently roaming on this network.
- * When {@code true}, it suggests that use of data on this network
- * may incur extra costs.
- * @return {@code true} if roaming is in effect, {@code false} otherwise.
- *
- * @hide pending API council
- */
- public boolean isRoaming() {
- return mIsRoaming;
- }
-
- void setRoaming(boolean isRoaming) {
- mIsRoaming = isRoaming;
- }
-
- /**
- * Reports the current coarse-grained state of the network.
- * @return the coarse-grained state
- */
- public State getState() {
- return mState;
- }
-
- /**
- * Reports the current fine-grained state of the network.
- * @return the fine-grained state
- */
- public DetailedState getDetailedState() {
- return mDetailedState;
- }
-
- /**
- * Sets the fine-grained state of the network.
- * @param detailedState the {@link DetailedState}.
- * @param reason a {@code String} indicating the reason for the state change,
- * if one was supplied. May be {@code null}.
- * @param extraInfo an optional {@code String} providing addditional network state
- * information passed up from the lower networking layers.
- */
- void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
- this.mDetailedState = detailedState;
- this.mState = stateMap.get(detailedState);
- this.mReason = reason;
- this.mExtraInfo = extraInfo;
- }
-
- /**
- * Report the reason an attempt to establish connectivity failed,
- * if one is available.
- * @return the reason for failure, or null if not available
- */
- public String getReason() {
- return mReason;
- }
-
- /**
- * Report the extra information about the network state, if any was
- * provided by the lower networking layers.,
- * if one is available.
- * @return the extra information, or null if not available
- */
- public String getExtraInfo() {
- return mExtraInfo;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder("NetworkInfo: ");
- builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()).
- append("], state: ").append(mState).append("/").append(mDetailedState).
- append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
- append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
- append(", roaming: ").append(mIsRoaming).
- append(", failover: ").append(mIsFailover).
- append(", isAvailable: ").append(mIsAvailable);
- return builder.toString();
- }
-
- /**
- * Implement the Parcelable interface
- * @hide
- */
- public int describeContents() {
- return 0;
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mNetworkType);
- dest.writeInt(mSubtype);
- dest.writeString(mTypeName);
- dest.writeString(mSubtypeName);
- dest.writeString(mState.name());
- dest.writeString(mDetailedState.name());
- dest.writeInt(mIsFailover ? 1 : 0);
- dest.writeInt(mIsAvailable ? 1 : 0);
- dest.writeInt(mIsRoaming ? 1 : 0);
- dest.writeString(mReason);
- dest.writeString(mExtraInfo);
- }
-
- /**
- * Implement the Parcelable interface.
- * @hide
- */
- public static final Creator<NetworkInfo> CREATOR =
- new Creator<NetworkInfo>() {
- public NetworkInfo createFromParcel(Parcel in) {
- int netType = in.readInt();
- int subtype = in.readInt();
- String typeName = in.readString();
- String subtypeName = in.readString();
- NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName);
- netInfo.mState = State.valueOf(in.readString());
- netInfo.mDetailedState = DetailedState.valueOf(in.readString());
- netInfo.mIsFailover = in.readInt() != 0;
- netInfo.mIsAvailable = in.readInt() != 0;
- netInfo.mIsRoaming = in.readInt() != 0;
- netInfo.mReason = in.readString();
- netInfo.mExtraInfo = in.readString();
- return netInfo;
- }
-
- public NetworkInfo[] newArray(int size) {
- return new NetworkInfo[size];
- }
- };
-}
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
deleted file mode 100644
index 37087aca23a..00000000000
--- a/core/java/android/net/NetworkStateTracker.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net;
-
-import java.io.FileWriter;
-import java.io.IOException;
-
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.content.Context;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
-
-/**
- * Each subclass of this class keeps track of the state of connectivity
- * of a network interface. All state information for a network should
- * be kept in a Tracker class. This superclass manages the
- * network-type-independent aspects of network state.
- *
- * {@hide}
- */
-public abstract class NetworkStateTracker extends Handler {
-
- protected NetworkInfo mNetworkInfo;
- protected Context mContext;
- protected Handler mTarget;
- private boolean mTeardownRequested;
-
- private static boolean DBG = Config.LOGV;
- private static final String TAG = "NetworkStateTracker";
-
- public static final int EVENT_STATE_CHANGED = 1;
- public static final int EVENT_SCAN_RESULTS_AVAILABLE = 2;
- /**
- * arg1: 1 to show, 0 to hide
- * arg2: ID of the notification
- * obj: Notification (if showing)
- */
- public static final int EVENT_NOTIFICATION_CHANGED = 3;
- public static final int EVENT_CONFIGURATION_CHANGED = 4;
- public static final int EVENT_ROAMING_CHANGED = 5;
- public static final int EVENT_NETWORK_SUBTYPE_CHANGED = 6;
-
- public NetworkStateTracker(Context context,
- Handler target,
- int networkType,
- int subType,
- String typeName,
- String subtypeName) {
- super();
- mContext = context;
- mTarget = target;
- mTeardownRequested = false;
- this.mNetworkInfo = new NetworkInfo(networkType, subType, typeName, subtypeName);
- }
-
- public NetworkInfo getNetworkInfo() {
- return mNetworkInfo;
- }
-
- /**
- * Return the list of DNS servers associated with this network.
- * @return a list of the IP addresses of the DNS servers available
- * for the network.
- */
- public abstract String[] getNameServers();
-
- /**
- * Return the system properties name associated with the tcp buffer sizes
- * for this network.
- */
- public abstract String getTcpBufferSizesPropName();
-
- /**
- * Return the IP addresses of the DNS servers available for this
- * network interface.
- * @param propertyNames the names of the system properties whose values
- * give the IP addresses. Properties with no values are skipped.
- * @return an array of {@code String}s containing the IP addresses
- * of the DNS servers, in dot-notation. This may have fewer
- * non-null entries than the list of names passed in, since
- * some of the passed-in names may have empty values.
- */
- static protected String[] getNameServerList(String[] propertyNames) {
- String[] dnsAddresses = new String[propertyNames.length];
- int i, j;
-
- for (i = 0, j = 0; i < propertyNames.length; i++) {
- String value = SystemProperties.get(propertyNames[i]);
- // The GSM layer sometimes sets a bogus DNS server address of
- // 0.0.0.0
- if (!TextUtils.isEmpty(value) && !TextUtils.equals(value, "0.0.0.0")) {
- dnsAddresses[j++] = value;
- }
- }
- return dnsAddresses;
- }
-
- /**
- * Reads the network specific TCP buffer sizes from SystemProperties
- * net.tcp.buffersize.[default|wifi|umts|edge|gprs] and set them for system
- * wide use
- */
- public void updateNetworkSettings() {
- String key = getTcpBufferSizesPropName();
- String bufferSizes = SystemProperties.get(key);
-
- if (bufferSizes.length() == 0) {
- Log.e(TAG, key + " not found in system properties. Using defaults");
-
- // Setting to default values so we won't be stuck to previous values
- key = "net.tcp.buffersize.default";
- bufferSizes = SystemProperties.get(key);
- }
-
- // Set values in kernel
- if (bufferSizes.length() != 0) {
- if (DBG) {
- Log.v(TAG, "Setting TCP values: [" + bufferSizes
- + "] which comes from [" + key + "]");
- }
- setBufferSize(bufferSizes);
- }
- }
-
- /**
- * Release the wakelock, if any, that may be held while handling a
- * disconnect operation.
- */
- public void releaseWakeLock() {
- }
-
- /**
- * Writes TCP buffer sizes to /sys/kernel/ipv4/tcp_[r/w]mem_[min/def/max]
- * which maps to /proc/sys/net/ipv4/tcp_rmem and tcpwmem
- *
- * @param bufferSizes in the format of "readMin, readInitial, readMax,
- * writeMin, writeInitial, writeMax"
- */
- private void setBufferSize(String bufferSizes) {
- try {
- String[] values = bufferSizes.split(",");
-
- if (values.length == 6) {
- final String prefix = "/sys/kernel/ipv4/tcp_";
- stringToFile(prefix + "rmem_min", values[0]);
- stringToFile(prefix + "rmem_def", values[1]);
- stringToFile(prefix + "rmem_max", values[2]);
- stringToFile(prefix + "wmem_min", values[3]);
- stringToFile(prefix + "wmem_def", values[4]);
- stringToFile(prefix + "wmem_max", values[5]);
- } else {
- Log.e(TAG, "Invalid buffersize string: " + bufferSizes);
- }
- } catch (IOException e) {
- Log.e(TAG, "Can't set tcp buffer sizes:" + e);
- }
- }
-
- /**
- * Writes string to file. Basically same as "echo -n $string > $filename"
- *
- * @param filename
- * @param string
- * @throws IOException
- */
- private void stringToFile(String filename, String string) throws IOException {
- FileWriter out = new FileWriter(filename);
- try {
- out.write(string);
- } finally {
- out.close();
- }
- }
-
- /**
- * Record the detailed state of a network, and if it is a
- * change from the previous state, send a notification to
- * any listeners.
- * @param state the new @{code DetailedState}
- */
- public void setDetailedState(NetworkInfo.DetailedState state) {
- setDetailedState(state, null, null);
- }
-
- /**
- * Record the detailed state of a network, and if it is a
- * change from the previous state, send a notification to
- * any listeners.
- * @param state the new @{code DetailedState}
- * @param reason a {@code String} indicating a reason for the state change,
- * if one was supplied. May be {@code null}.
- * @param extraInfo optional {@code String} providing extra information about the state change
- */
- public void setDetailedState(NetworkInfo.DetailedState state, String reason, String extraInfo) {
- if (state != mNetworkInfo.getDetailedState()) {
- boolean wasConnecting = (mNetworkInfo.getState() == NetworkInfo.State.CONNECTING);
- String lastReason = mNetworkInfo.getReason();
- /*
- * If a reason was supplied when the CONNECTING state was entered, and no
- * reason was supplied for entering the CONNECTED state, then retain the
- * reason that was supplied when going to CONNECTING.
- */
- if (wasConnecting && state == NetworkInfo.DetailedState.CONNECTED && reason == null
- && lastReason != null)
- reason = lastReason;
- mNetworkInfo.setDetailedState(state, reason, extraInfo);
- Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
- msg.sendToTarget();
- }
- }
-
- protected void setDetailedStateInternal(NetworkInfo.DetailedState state) {
- mNetworkInfo.setDetailedState(state, null, null);
- }
-
- public void setTeardownRequested(boolean isRequested) {
- mTeardownRequested = isRequested;
- }
-
- public boolean isTeardownRequested() {
- return mTeardownRequested;
- }
-
- /**
- * Send a notification that the results of a scan for network access
- * points has completed, and results are available.
- */
- protected void sendScanResultsAvailable() {
- Message msg = mTarget.obtainMessage(EVENT_SCAN_RESULTS_AVAILABLE, mNetworkInfo);
- msg.sendToTarget();
- }
-
- /**
- * Record the roaming status of the device, and if it is a change from the previous
- * status, send a notification to any listeners.
- * @param isRoaming {@code true} if the device is now roaming, {@code false}
- * if it is no longer roaming.
- */
- protected void setRoamingStatus(boolean isRoaming) {
- if (isRoaming != mNetworkInfo.isRoaming()) {
- mNetworkInfo.setRoaming(isRoaming);
- Message msg = mTarget.obtainMessage(EVENT_ROAMING_CHANGED, mNetworkInfo);
- msg.sendToTarget();
- }
- }
-
- protected void setSubtype(int subtype, String subtypeName) {
- if (mNetworkInfo.isConnected()) {
- int oldSubtype = mNetworkInfo.getSubtype();
- if (subtype != oldSubtype) {
- mNetworkInfo.setSubtype(subtype, subtypeName);
- Message msg = mTarget.obtainMessage(
- EVENT_NETWORK_SUBTYPE_CHANGED, oldSubtype, 0, mNetworkInfo);
- msg.sendToTarget();
- }
- }
- }
-
- public abstract void startMonitoring();
-
- /**
- * Disable connectivity to a network
- * @return {@code true} if a teardown occurred, {@code false} if the
- * teardown did not occur.
- */
- public abstract boolean teardown();
-
- /**
- * Reenable connectivity to a network after a {@link #teardown()}.
- */
- public abstract boolean reconnect();
-
- /**
- * Turn the wireless radio off for a network.
- * @param turnOn {@code true} to turn the radio on, {@code false}
- */
- public abstract boolean setRadio(boolean turnOn);
-
- /**
- * Returns an indication of whether this network is available for
- * connections. A value of {@code false} means that some quasi-permanent
- * condition prevents connectivity to this network.
- */
- public abstract boolean isAvailable();
-
- /**
- * Tells the underlying networking system that the caller wants to
- * begin using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * @param feature the name of the feature to be used
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- */
- public abstract int startUsingNetworkFeature(String feature, int callingPid, int callingUid);
-
- /**
- * Tells the underlying networking system that the caller is finished
- * using the named feature. The interpretation of {@code feature}
- * is completely up to each networking implementation.
- * @param feature the name of the feature that is no longer needed.
- * @param callingPid the process ID of the process that is issuing this request
- * @param callingUid the user ID of the process that is issuing this request
- * @return an integer value representing the outcome of the request.
- * The interpretation of this value is specific to each networking
- * implementation+feature combination, except that the value {@code -1}
- * always indicates failure.
- */
- public abstract int stopUsingNetworkFeature(String feature, int callingPid, int callingUid);
-
- /**
- * Ensure that a network route exists to deliver traffic to the specified
- * host via this network interface.
- * @param hostAddress the IP address of the host to which the route is desired
- * @return {@code true} on success, {@code false} on failure
- */
- public boolean requestRouteToHost(int hostAddress) {
- return false;
- }
-
- /**
- * Interprets scan results. This will be called at a safe time for
- * processing, and from a safe thread.
- */
- public void interpretScanResultsAvailable() {
- }
-
-}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
deleted file mode 100644
index 11536487295..00000000000
--- a/core/java/android/net/NetworkUtils.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-/**
- * Native methods for managing network interfaces.
- *
- * {@hide}
- */
-public class NetworkUtils {
- /** Bring the named network interface down. */
- public native static int disableInterface(String interfaceName);
-
- /** Add a route to the specified host via the named interface. */
- public native static int addHostRoute(String interfaceName, int hostaddr);
-
- /** Add a default route for the named interface. */
- public native static int setDefaultRoute(String interfaceName, int gwayAddr);
-
- /** Return the gateway address for the default route for the named interface. */
- public native static int getDefaultRoute(String interfaceName);
-
- /** Remove host routes that uses the named interface. */
- public native static int removeHostRoutes(String interfaceName);
-
- /** Remove the default route for the named interface. */
- public native static int removeDefaultRoute(String interfaceName);
-
- /** Reset any sockets that are connected via the named interface. */
- public native static int resetConnections(String interfaceName);
-
- /**
- * Start the DHCP client daemon, in order to have it request addresses
- * for the named interface, and then configure the interface with those
- * addresses. This call blocks until it obtains a result (either success
- * or failure) from the daemon.
- * @param interfaceName the name of the interface to configure
- * @param ipInfo if the request succeeds, this object is filled in with
- * the IP address information.
- * @return {@code true} for success, {@code false} for failure
- */
- public native static boolean runDhcp(String interfaceName, DhcpInfo ipInfo);
-
- /**
- * Shut down the DHCP client daemon.
- * @param interfaceName the name of the interface for which the daemon
- * should be stopped
- * @return {@code true} for success, {@code false} for failure
- */
- public native static boolean stopDhcp(String interfaceName);
-
- /**
- * Release the current DHCP lease.
- * @param interfaceName the name of the interface for which the lease should
- * be released
- * @return {@code true} for success, {@code false} for failure
- */
- public native static boolean releaseDhcpLease(String interfaceName);
-
- /**
- * Return the last DHCP-related error message that was recorded.
- * <p/>NOTE: This string is not localized, but currently it is only
- * used in logging.
- * @return the most recent error message, if any
- */
- public native static String getDhcpError();
-
- /**
- * When static IP configuration has been specified, configure the network
- * interface according to the values supplied.
- * @param interfaceName the name of the interface to configure
- * @param ipInfo the IP address, default gateway, and DNS server addresses
- * with which to configure the interface.
- * @return {@code true} for success, {@code false} for failure
- */
- public static boolean configureInterface(String interfaceName, DhcpInfo ipInfo) {
- return configureNative(interfaceName,
- ipInfo.ipAddress,
- ipInfo.netmask,
- ipInfo.gateway,
- ipInfo.dns1,
- ipInfo.dns2);
- }
-
- private native static boolean configureNative(
- String interfaceName, int ipAddress, int netmask, int gateway, int dns1, int dns2);
-
- /**
- * Look up a host name and return the result as an int. Works if the argument
- * is an IP address in dot notation. Obviously, this can only be used for IPv4
- * addresses.
- * @param hostname the name of the host (or the IP address)
- * @return the IP address as an {@code int} in network byte order
- */
- public static int lookupHost(String hostname) {
- InetAddress inetAddress;
- try {
- inetAddress = InetAddress.getByName(hostname);
- } catch (UnknownHostException e) {
- return -1;
- }
- byte[] addrBytes;
- int addr;
- addrBytes = inetAddress.getAddress();
- addr = ((addrBytes[3] & 0xff) << 24)
- | ((addrBytes[2] & 0xff) << 16)
- | ((addrBytes[1] & 0xff) << 8)
- | (addrBytes[0] & 0xff);
- return addr;
- }
-}
diff --git a/core/java/android/net/ParseException.java b/core/java/android/net/ParseException.java
deleted file mode 100644
index 000fa685ed6..00000000000
--- a/core/java/android/net/ParseException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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 android.net;
-
-/**
- *
- *
- * When WebAddress Parser Fails, this exception is thrown
- */
-public class ParseException extends RuntimeException {
- public String response;
-
- ParseException(String response) {
- this.response = response;
- }
-}
diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java
deleted file mode 100644
index 9f07c0a2c5b..00000000000
--- a/core/java/android/net/Proxy.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.SystemProperties;
-import android.provider.Settings;
-import android.util.Log;
-
-import junit.framework.Assert;
-
-/**
- * A convenience class for accessing the user and default proxy
- * settings.
- */
-final public class Proxy {
-
- static final public String PROXY_CHANGE_ACTION =
- "android.intent.action.PROXY_CHANGE";
-
- /**
- * Return the proxy host set by the user.
- * @param ctx A Context used to get the settings for the proxy host.
- * @return String containing the host name. If the user did not set a host
- * name it returns the default host. A null value means that no
- * host is to be used.
- */
- static final public String getHost(Context ctx) {
- ContentResolver contentResolver = ctx.getContentResolver();
- Assert.assertNotNull(contentResolver);
- String host = Settings.Secure.getString(
- contentResolver,
- Settings.Secure.HTTP_PROXY);
- if (host != null) {
- int i = host.indexOf(':');
- if (i == -1) {
- if (android.util.Config.DEBUG) {
- Assert.assertTrue(host.length() == 0);
- }
- return null;
- }
- return host.substring(0, i);
- }
- return getDefaultHost();
- }
-
- /**
- * Return the proxy port set by the user.
- * @param ctx A Context used to get the settings for the proxy port.
- * @return The port number to use or -1 if no proxy is to be used.
- */
- static final public int getPort(Context ctx) {
- ContentResolver contentResolver = ctx.getContentResolver();
- Assert.assertNotNull(contentResolver);
- String host = Settings.Secure.getString(
- contentResolver,
- Settings.Secure.HTTP_PROXY);
- if (host != null) {
- int i = host.indexOf(':');
- if (i == -1) {
- if (android.util.Config.DEBUG) {
- Assert.assertTrue(host.length() == 0);
- }
- return -1;
- }
- if (android.util.Config.DEBUG) {
- Assert.assertTrue(i < host.length());
- }
- return Integer.parseInt(host.substring(i+1));
- }
- return getDefaultPort();
- }
-
- /**
- * Return the default proxy host specified by the carrier.
- * @return String containing the host name or null if there is no proxy for
- * this carrier.
- */
- static final public String getDefaultHost() {
- String host = SystemProperties.get("net.gprs.http-proxy");
- if (host != null) {
- Uri u = Uri.parse(host);
- host = u.getHost();
- return host;
- } else {
- return null;
- }
- }
-
- /**
- * Return the default proxy port specified by the carrier.
- * @return The port number to be used with the proxy host or -1 if there is
- * no proxy for this carrier.
- */
- static final public int getDefaultPort() {
- String host = SystemProperties.get("net.gprs.http-proxy");
- if (host != null) {
- Uri u = Uri.parse(host);
- return u.getPort();
- } else {
- return -1;
- }
- }
-
-};
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
deleted file mode 100644
index f816caa6da2..00000000000
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net;
-
-import android.util.Log;
-import android.util.Config;
-import android.net.http.DomainNameChecker;
-import android.os.SystemProperties;
-
-import javax.net.SocketFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.security.NoSuchAlgorithmException;
-import java.security.KeyManagementException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.GeneralSecurityException;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-
-public class SSLCertificateSocketFactory extends SSLSocketFactory {
-
- private static final boolean DBG = true;
- private static final String LOG_TAG = "SSLCertificateSocketFactory";
-
- private static X509TrustManager sDefaultTrustManager;
-
- private final int socketReadTimeoutForSslHandshake;
-
- static {
- try {
- TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
- tmf.init((KeyStore)null);
- TrustManager[] tms = tmf.getTrustManagers();
- if (tms != null) {
- for (TrustManager tm : tms) {
- if (tm instanceof X509TrustManager) {
- sDefaultTrustManager = (X509TrustManager)tm;
- break;
- }
- }
- }
- } catch (NoSuchAlgorithmException e) {
- Log.e(LOG_TAG, "Unable to get X509 Trust Manager ", e);
- } catch (KeyStoreException e) {
- Log.e(LOG_TAG, "Key Store exception while initializing TrustManagerFactory ", e);
- }
- }
-
- private static final TrustManager[] TRUST_MANAGER = new TrustManager[] {
- new X509TrustManager() {
- public X509Certificate[] getAcceptedIssuers() {
- return null;
- }
-
- public void checkClientTrusted(X509Certificate[] certs,
- String authType) { }
-
- public void checkServerTrusted(X509Certificate[] certs,
- String authType) { }
- }
- };
-
- private SSLSocketFactory factory;
-
- public SSLCertificateSocketFactory(int socketReadTimeoutForSslHandshake)
- throws NoSuchAlgorithmException, KeyManagementException {
- SSLContext context = SSLContext.getInstance("TLS");
- context.init(null, TRUST_MANAGER, new java.security.SecureRandom());
- factory = (SSLSocketFactory) context.getSocketFactory();
- this.socketReadTimeoutForSslHandshake = socketReadTimeoutForSslHandshake;
- }
-
- /**
- * Returns a default instantiation of a new socket factory which
- * only allows SSL connections with valid certificates.
- *
- * @param socketReadTimeoutForSslHandshake the socket read timeout used for performing
- * ssl handshake. The socket read timeout is set back to 0 after the handshake.
- * @return a new SocketFactory, or null on error
- */
- public static SocketFactory getDefault(int socketReadTimeoutForSslHandshake) {
- try {
- return new SSLCertificateSocketFactory(socketReadTimeoutForSslHandshake);
- } catch (NoSuchAlgorithmException e) {
- Log.e(LOG_TAG,
- "SSLCertifcateSocketFactory.getDefault" +
- " NoSuchAlgorithmException " , e);
- return null;
- } catch (KeyManagementException e) {
- Log.e(LOG_TAG,
- "SSLCertifcateSocketFactory.getDefault" +
- " KeyManagementException " , e);
- return null;
- }
- }
-
- private boolean hasValidCertificateChain(Certificate[] certs)
- throws IOException {
- if (sDefaultTrustManager == null) {
- if (Config.LOGD) {
- Log.d(LOG_TAG,"hasValidCertificateChain():" +
- " null default trust manager!");
- }
- throw new IOException("null default trust manager");
- }
-
- boolean trusted = (certs != null && (certs.length > 0));
-
- if (trusted) {
- try {
- // the authtype we pass in doesn't actually matter
- sDefaultTrustManager.checkServerTrusted((X509Certificate[]) certs, "RSA");
- } catch (GeneralSecurityException e) {
- String exceptionMessage = e != null ? e.getMessage() : "none";
- if (Config.LOGD) {
- Log.d(LOG_TAG,"hasValidCertificateChain(): sec. exception: "
- + exceptionMessage);
- }
- trusted = false;
- }
- }
-
- return trusted;
- }
-
- private void validateSocket(SSLSocket sslSock, String destHost)
- throws IOException
- {
- if (Config.LOGV) {
- Log.v(LOG_TAG,"validateSocket() to host "+destHost);
- }
-
- String relaxSslCheck = SystemProperties.get("socket.relaxsslcheck");
- String secure = SystemProperties.get("ro.secure");
-
- // only allow relaxing the ssl check on non-secure builds where the relaxation is
- // specifically requested.
- if ("0".equals(secure) && "yes".equals(relaxSslCheck)) {
- if (Config.LOGD) {
- Log.d(LOG_TAG,"sys prop socket.relaxsslcheck is set," +
- " ignoring invalid certs");
- }
- return;
- }
-
- Certificate[] certs = null;
- sslSock.setUseClientMode(true);
- sslSock.startHandshake();
- certs = sslSock.getSession().getPeerCertificates();
-
- // check that the root certificate in the chain belongs to
- // a CA we trust
- if (certs == null) {
- Log.e(LOG_TAG,
- "[SSLCertificateSocketFactory] no trusted root CA");
- throw new IOException("no trusted root CA");
- }
-
- if (Config.LOGV) {
- Log.v(LOG_TAG,"validateSocket # certs = " +certs.length);
- }
-
- if (!hasValidCertificateChain(certs)) {
- if (Config.LOGD) {
- Log.d(LOG_TAG,"validateSocket(): certificate untrusted!");
- }
- throw new IOException("Certificate untrusted");
- }
-
- X509Certificate lastChainCert = (X509Certificate) certs[0];
-
- if (!DomainNameChecker.match(lastChainCert, destHost)) {
- if (Config.LOGD) {
- Log.d(LOG_TAG,"validateSocket(): domain name check failed");
- }
- throw new IOException("Domain Name check failed");
- }
- }
-
- public Socket createSocket(Socket socket, String s, int i, boolean flag)
- throws IOException
- {
- throw new IOException("Cannot validate certification without a hostname");
- }
-
- public Socket createSocket(InetAddress inaddr, int i, InetAddress inaddr2, int j)
- throws IOException
- {
- throw new IOException("Cannot validate certification without a hostname");
- }
-
- public Socket createSocket(InetAddress inaddr, int i) throws IOException {
- throw new IOException("Cannot validate certification without a hostname");
- }
-
- public Socket createSocket(String s, int i, InetAddress inaddr, int j) throws IOException {
- SSLSocket sslSock = (SSLSocket) factory.createSocket(s, i, inaddr, j);
-
- if (socketReadTimeoutForSslHandshake >= 0) {
- sslSock.setSoTimeout(socketReadTimeoutForSslHandshake);
- }
-
- validateSocket(sslSock,s);
- sslSock.setSoTimeout(0);
-
- return sslSock;
- }
-
- public Socket createSocket(String s, int i) throws IOException {
- SSLSocket sslSock = (SSLSocket) factory.createSocket(s, i);
-
- if (socketReadTimeoutForSslHandshake >= 0) {
- sslSock.setSoTimeout(socketReadTimeoutForSslHandshake);
- }
-
- validateSocket(sslSock,s);
- sslSock.setSoTimeout(0);
-
- return sslSock;
- }
-
- public String[] getDefaultCipherSuites() {
- return factory.getSupportedCipherSuites();
- }
-
- public String[] getSupportedCipherSuites() {
- return factory.getSupportedCipherSuites();
- }
-}
-
-
diff --git a/core/java/android/net/SntpClient.java b/core/java/android/net/SntpClient.java
deleted file mode 100644
index 28134b29156..00000000000
--- a/core/java/android/net/SntpClient.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net;
-
-import android.os.SystemClock;
-import android.util.Config;
-import android.util.Log;
-
-import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-
-/**
- * {@hide}
- *
- * Simple SNTP client class for retrieving network time.
- *
- * Sample usage:
- * <pre>SntpClient client = new SntpClient();
- * if (client.requestTime("time.foo.com")) {
- * long now = client.getNtpTime() + SystemClock.elapsedRealtime() - client.getNtpTimeReference();
- * }
- * </pre>
- */
-public class SntpClient
-{
- private static final String TAG = "SntpClient";
-
- private static final int REFERENCE_TIME_OFFSET = 16;
- private static final int ORIGINATE_TIME_OFFSET = 24;
- private static final int RECEIVE_TIME_OFFSET = 32;
- private static final int TRANSMIT_TIME_OFFSET = 40;
- private static final int NTP_PACKET_SIZE = 48;
-
- private static final int NTP_PORT = 123;
- private static final int NTP_MODE_CLIENT = 3;
- private static final int NTP_VERSION = 3;
-
- // Number of seconds between Jan 1, 1900 and Jan 1, 1970
- // 70 years plus 17 leap days
- private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;
-
- // system time computed from NTP server response
- private long mNtpTime;
-
- // value of SystemClock.elapsedRealtime() corresponding to mNtpTime
- private long mNtpTimeReference;
-
- // round trip time in milliseconds
- private long mRoundTripTime;
-
- /**
- * Sends an SNTP request to the given host and processes the response.
- *
- * @param host host name of the server.
- * @param timeout network timeout in milliseconds.
- * @return true if the transaction was successful.
- */
- public boolean requestTime(String host, int timeout) {
- try {
- DatagramSocket socket = new DatagramSocket();
- socket.setSoTimeout(timeout);
- InetAddress address = InetAddress.getByName(host);
- byte[] buffer = new byte[NTP_PACKET_SIZE];
- DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);
-
- // set mode = 3 (client) and version = 3
- // mode is in low 3 bits of first byte
- // version is in bits 3-5 of first byte
- buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);
-
- // get current time and write it to the request packet
- long requestTime = System.currentTimeMillis();
- long requestTicks = SystemClock.elapsedRealtime();
- writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET, requestTime);
-
- socket.send(request);
-
- // read the response
- DatagramPacket response = new DatagramPacket(buffer, buffer.length);
- socket.receive(response);
- long responseTicks = SystemClock.elapsedRealtime();
- long responseTime = requestTime + (responseTicks - requestTicks);
- socket.close();
-
- // extract the results
- long originateTime = readTimeStamp(buffer, ORIGINATE_TIME_OFFSET);
- long receiveTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);
- long transmitTime = readTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
- long roundTripTime = responseTicks - requestTicks - (transmitTime - receiveTime);
- long clockOffset = (receiveTime - originateTime) + (transmitTime - responseTime);
- if (Config.LOGD) Log.d(TAG, "round trip: " + roundTripTime + " ms");
- if (Config.LOGD) Log.d(TAG, "clock offset: " + clockOffset + " ms");
-
- // save our results
- mNtpTime = requestTime + clockOffset;
- mNtpTimeReference = requestTicks;
- mRoundTripTime = roundTripTime;
- } catch (Exception e) {
- if (Config.LOGD) Log.d(TAG, "request time failed: " + e);
- return false;
- }
-
- return true;
- }
-
- /**
- * Returns the time computed from the NTP transaction.
- *
- * @return time value computed from NTP server response.
- */
- public long getNtpTime() {
- return mNtpTime;
- }
-
- /**
- * Returns the reference clock value (value of SystemClock.elapsedRealtime())
- * corresponding to the NTP time.
- *
- * @return reference clock corresponding to the NTP time.
- */
- public long getNtpTimeReference() {
- return mNtpTimeReference;
- }
-
- /**
- * Returns the round trip time of the NTP transaction
- *
- * @return round trip time in milliseconds.
- */
- public long getRoundTripTime() {
- return mRoundTripTime;
- }
-
- /**
- * Reads an unsigned 32 bit big endian number from the given offset in the buffer.
- */
- private long read32(byte[] buffer, int offset) {
- byte b0 = buffer[offset];
- byte b1 = buffer[offset+1];
- byte b2 = buffer[offset+2];
- byte b3 = buffer[offset+3];
-
- // convert signed bytes to unsigned values
- int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0);
- int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1);
- int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2);
- int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3);
-
- return ((long)i0 << 24) + ((long)i1 << 16) + ((long)i2 << 8) + (long)i3;
- }
-
- /**
- * Reads the NTP time stamp at the given offset in the buffer and returns
- * it as a system time (milliseconds since January 1, 1970).
- */
- private long readTimeStamp(byte[] buffer, int offset) {
- long seconds = read32(buffer, offset);
- long fraction = read32(buffer, offset + 4);
- return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L) / 0x100000000L);
- }
-
- /**
- * Writes system time (milliseconds since January 1, 1970) as an NTP time stamp
- * at the given offset in the buffer.
- */
- private void writeTimeStamp(byte[] buffer, int offset, long time) {
- long seconds = time / 1000L;
- long milliseconds = time - seconds * 1000L;
- seconds += OFFSET_1900_TO_1970;
-
- // write seconds in big endian format
- buffer[offset++] = (byte)(seconds >> 24);
- buffer[offset++] = (byte)(seconds >> 16);
- buffer[offset++] = (byte)(seconds >> 8);
- buffer[offset++] = (byte)(seconds >> 0);
-
- long fraction = milliseconds * 0x100000000L / 1000L;
- // write fraction in big endian format
- buffer[offset++] = (byte)(fraction >> 24);
- buffer[offset++] = (byte)(fraction >> 16);
- buffer[offset++] = (byte)(fraction >> 8);
- // low order bits should be random data
- buffer[offset++] = (byte)(Math.random() * 255.0);
- }
-}
diff --git a/core/java/android/net/Uri.aidl b/core/java/android/net/Uri.aidl
deleted file mode 100755
index 6bd3be5e041..00000000000
--- a/core/java/android/net/Uri.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2007, 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 android.net;
-
-parcelable Uri;
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
deleted file mode 100644
index c23df217a85..00000000000
--- a/core/java/android/net/Uri.java
+++ /dev/null
@@ -1,2252 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.io.ByteArrayOutputStream;
-import java.net.URLEncoder;
-import java.util.AbstractList;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.RandomAccess;
-
-/**
- * Immutable URI reference. A URI reference includes a URI and a fragment, the
- * component of the URI following a '#'. Builds and parses URI references
- * which conform to
- * <a href="http://www.faqs.org/rfcs/rfc2396.html">RFC 2396</a>.
- *
- * <p>In the interest of performance, this class performs little to no
- * validation. Behavior is undefined for invalid input. This class is very
- * forgiving--in the face of invalid input, it will return garbage
- * rather than throw an exception unless otherwise specified.
- */
-public abstract class Uri implements Parcelable, Comparable<Uri> {
-
- /*
-
- This class aims to do as little up front work as possible. To accomplish
- that, we vary the implementation dependending on what the user passes in.
- For example, we have one implementation if the user passes in a
- URI string (StringUri) and another if the user passes in the
- individual components (OpaqueUri).
-
- *Concurrency notes*: Like any truly immutable object, this class is safe
- for concurrent use. This class uses a caching pattern in some places where
- it doesn't use volatile or synchronized. This is safe to do with ints
- because getting or setting an int is atomic. It's safe to do with a String
- because the internal fields are final and the memory model guarantees other
- threads won't see a partially initialized instance. We are not guaranteed
- that some threads will immediately see changes from other threads on
- certain platforms, but we don't mind if those threads reconstruct the
- cached result. As a result, we get thread safe caching with no concurrency
- overhead, which means the most common case, access from a single thread,
- is as fast as possible.
-
- From the Java Language spec.:
-
- "17.5 Final Field Semantics
-
- ... when the object is seen by another thread, that thread will always
- see the correctly constructed version of that object's final fields.
- It will also see versions of any object or array referenced by
- those final fields that are at least as up-to-date as the final fields
- are."
-
- In that same vein, all non-transient fields within Uri
- implementations should be final and immutable so as to ensure true
- immutability for clients even when they don't use proper concurrency
- control.
-
- For reference, from RFC 2396:
-
- "4.3. Parsing a URI Reference
-
- A URI reference is typically parsed according to the four main
- components and fragment identifier in order to determine what
- components are present and whether the reference is relative or
- absolute. The individual components are then parsed for their
- subparts and, if not opaque, to verify their validity.
-
- Although the BNF defines what is allowed in each component, it is
- ambiguous in terms of differentiating between an authority component
- and a path component that begins with two slash characters. The
- greedy algorithm is used for disambiguation: the left-most matching
- rule soaks up as much of the URI reference string as it is capable of
- matching. In other words, the authority component wins."
-
- The "four main components" of a hierarchical URI consist of
- <scheme>://<authority><path>?<query>
-
- */
-
- /** Log tag. */
- private static final String LOG = Uri.class.getSimpleName();
-
- /**
- * The empty URI, equivalent to "".
- */
- public static final Uri EMPTY = new HierarchicalUri(null, Part.NULL,
- PathPart.EMPTY, Part.NULL, Part.NULL);
-
- /**
- * Prevents external subclassing.
- */
- private Uri() {}
-
- /**
- * Returns true if this URI is hierarchical like "http://google.com".
- * Absolute URIs are hierarchical if the scheme-specific part starts with
- * a '/'. Relative URIs are always hierarchical.
- */
- public abstract boolean isHierarchical();
-
- /**
- * Returns true if this URI is opaque like "mailto:nobody@google.com". The
- * scheme-specific part of an opaque URI cannot start with a '/'.
- */
- public boolean isOpaque() {
- return !isHierarchical();
- }
-
- /**
- * Returns true if this URI is relative, i.e. if it doesn't contain an
- * explicit scheme.
- *
- * @return true if this URI is relative, false if it's absolute
- */
- public abstract boolean isRelative();
-
- /**
- * Returns true if this URI is absolute, i.e. if it contains an
- * explicit scheme.
- *
- * @return true if this URI is absolute, false if it's relative
- */
- public boolean isAbsolute() {
- return !isRelative();
- }
-
- /**
- * Gets the scheme of this URI. Example: "http"
- *
- * @return the scheme or null if this is a relative URI
- */
- public abstract String getScheme();
-
- /**
- * Gets the scheme-specific part of this URI, i.e. everything between the
- * scheme separator ':' and the fragment separator '#'. If this is a
- * relative URI, this method returns the entire URI. Decodes escaped octets.
- *
- * <p>Example: "//www.google.com/search?q=android"
- *
- * @return the decoded scheme-specific-part
- */
- public abstract String getSchemeSpecificPart();
-
- /**
- * Gets the scheme-specific part of this URI, i.e. everything between the
- * scheme separator ':' and the fragment separator '#'. If this is a
- * relative URI, this method returns the entire URI. Leaves escaped octets
- * intact.
- *
- * <p>Example: "//www.google.com/search?q=android"
- *
- * @return the decoded scheme-specific-part
- */
- public abstract String getEncodedSchemeSpecificPart();
-
- /**
- * Gets the decoded authority part of this URI. For
- * server addresses, the authority is structured as follows:
- * {@code [ userinfo '@' ] host [ ':' port ]}
- *
- * <p>Examples: "google.com", "bob@google.com:80"
- *
- * @return the authority for this URI or null if not present
- */
- public abstract String getAuthority();
-
- /**
- * Gets the encoded authority part of this URI. For
- * server addresses, the authority is structured as follows:
- * {@code [ userinfo '@' ] host [ ':' port ]}
- *
- * <p>Examples: "google.com", "bob@google.com:80"
- *
- * @return the authority for this URI or null if not present
- */
- public abstract String getEncodedAuthority();
-
- /**
- * Gets the decoded user information from the authority.
- * For example, if the authority is "nobody@google.com", this method will
- * return "nobody".
- *
- * @return the user info for this URI or null if not present
- */
- public abstract String getUserInfo();
-
- /**
- * Gets the encoded user information from the authority.
- * For example, if the authority is "nobody@google.com", this method will
- * return "nobody".
- *
- * @return the user info for this URI or null if not present
- */
- public abstract String getEncodedUserInfo();
-
- /**
- * Gets the encoded host from the authority for this URI. For example,
- * if the authority is "bob@google.com", this method will return
- * "google.com".
- *
- * @return the host for this URI or null if not present
- */
- public abstract String getHost();
-
- /**
- * Gets the port from the authority for this URI. For example,
- * if the authority is "google.com:80", this method will return 80.
- *
- * @return the port for this URI or -1 if invalid or not present
- */
- public abstract int getPort();
-
- /**
- * Gets the decoded path.
- *
- * @return the decoded path, or null if this is not a hierarchical URI
- * (like "mailto:nobody@google.com") or the URI is invalid
- */
- public abstract String getPath();
-
- /**
- * Gets the encoded path.
- *
- * @return the encoded path, or null if this is not a hierarchical URI
- * (like "mailto:nobody@google.com") or the URI is invalid
- */
- public abstract String getEncodedPath();
-
- /**
- * Gets the decoded query component from this URI. The query comes after
- * the query separator ('?') and before the fragment separator ('#'). This
- * method would return "q=android" for
- * "http://www.google.com/search?q=android".
- *
- * @return the decoded query or null if there isn't one
- */
- public abstract String getQuery();
-
- /**
- * Gets the encoded query component from this URI. The query comes after
- * the query separator ('?') and before the fragment separator ('#'). This
- * method would return "q=android" for
- * "http://www.google.com/search?q=android".
- *
- * @return the encoded query or null if there isn't one
- */
- public abstract String getEncodedQuery();
-
- /**
- * Gets the decoded fragment part of this URI, everything after the '#'.
- *
- * @return the decoded fragment or null if there isn't one
- */
- public abstract String getFragment();
-
- /**
- * Gets the encoded fragment part of this URI, everything after the '#'.
- *
- * @return the encoded fragment or null if there isn't one
- */
- public abstract String getEncodedFragment();
-
- /**
- * Gets the decoded path segments.
- *
- * @return decoded path segments, each without a leading or trailing '/'
- */
- public abstract List<String> getPathSegments();
-
- /**
- * Gets the decoded last segment in the path.
- *
- * @return the decoded last segment or null if the path is empty
- */
- public abstract String getLastPathSegment();
-
- /**
- * Compares this Uri to another object for equality. Returns true if the
- * encoded string representations of this Uri and the given Uri are
- * equal. Case counts. Paths are not normalized. If one Uri specifies a
- * default port explicitly and the other leaves it implicit, they will not
- * be considered equal.
- */
- public boolean equals(Object o) {
- if (!(o instanceof Uri)) {
- return false;
- }
-
- Uri other = (Uri) o;
-
- return toString().equals(other.toString());
- }
-
- /**
- * Hashes the encoded string represention of this Uri consistently with
- * {@link #equals(Object)}.
- */
- public int hashCode() {
- return toString().hashCode();
- }
-
- /**
- * Compares the string representation of this Uri with that of
- * another.
- */
- public int compareTo(Uri other) {
- return toString().compareTo(other.toString());
- }
-
- /**
- * Returns the encoded string representation of this URI.
- * Example: "http://google.com/"
- */
- public abstract String toString();
-
- /**
- * Constructs a new builder, copying the attributes from this Uri.
- */
- public abstract Builder buildUpon();
-
- /** Index of a component which was not found. */
- private final static int NOT_FOUND = -1;
-
- /** Placeholder value for an index which hasn't been calculated yet. */
- private final static int NOT_CALCULATED = -2;
-
- /**
- * Placeholder for strings which haven't been cached. This enables us
- * to cache null. We intentionally create a new String instance so we can
- * compare its identity and there is no chance we will confuse it with
- * user data.
- */
- @SuppressWarnings("RedundantStringConstructorCall")
- private static final String NOT_CACHED = new String("NOT CACHED");
-
- /**
- * Error message presented when a user tries to treat an opaque URI as
- * hierarchical.
- */
- private static final String NOT_HIERARCHICAL
- = "This isn't a hierarchical URI.";
-
- /** Default encoding. */
- private static final String DEFAULT_ENCODING = "UTF-8";
-
- /**
- * Creates a Uri which parses the given encoded URI string.
- *
- * @param uriString an RFC 3296-compliant, encoded URI
- * @throws NullPointerException if uriString is null
- * @return Uri for this given uri string
- */
- public static Uri parse(String uriString) {
- return new StringUri(uriString);
- }
-
- /**
- * Creates a Uri from a file. The URI has the form
- * "file://<absolute path>". Encodes path characters with the exception of
- * '/'.
- *
- * <p>Example: "file:///tmp/android.txt"
- *
- * @throws NullPointerException if file is null
- * @return a Uri for the given file
- */
- public static Uri fromFile(File file) {
- if (file == null) {
- throw new NullPointerException("file");
- }
-
- PathPart path = PathPart.fromDecoded(file.getAbsolutePath());
- return new HierarchicalUri(
- "file", Part.EMPTY, path, Part.NULL, Part.NULL);
- }
-
- /**
- * An implementation which wraps a String URI. This URI can be opaque or
- * hierarchical, but we extend AbstractHierarchicalUri in case we need
- * the hierarchical functionality.
- */
- private static class StringUri extends AbstractHierarchicalUri {
-
- /** Used in parcelling. */
- static final int TYPE_ID = 1;
-
- /** URI string representation. */
- private final String uriString;
-
- private StringUri(String uriString) {
- if (uriString == null) {
- throw new NullPointerException("uriString");
- }
-
- this.uriString = uriString;
- }
-
- static Uri readFrom(Parcel parcel) {
- return new StringUri(parcel.readString());
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeInt(TYPE_ID);
- parcel.writeString(uriString);
- }
-
- /** Cached scheme separator index. */
- private volatile int cachedSsi = NOT_CALCULATED;
-
- /** Finds the first ':'. Returns -1 if none found. */
- private int findSchemeSeparator() {
- return cachedSsi == NOT_CALCULATED
- ? cachedSsi = uriString.indexOf(':')
- : cachedSsi;
- }
-
- /** Cached fragment separator index. */
- private volatile int cachedFsi = NOT_CALCULATED;
-
- /** Finds the first '#'. Returns -1 if none found. */
- private int findFragmentSeparator() {
- return cachedFsi == NOT_CALCULATED
- ? cachedFsi = uriString.indexOf('#', findSchemeSeparator())
- : cachedFsi;
- }
-
- public boolean isHierarchical() {
- int ssi = findSchemeSeparator();
-
- if (ssi == NOT_FOUND) {
- // All relative URIs are hierarchical.
- return true;
- }
-
- if (uriString.length() == ssi + 1) {
- // No ssp.
- return false;
- }
-
- // If the ssp starts with a '/', this is hierarchical.
- return uriString.charAt(ssi + 1) == '/';
- }
-
- public boolean isRelative() {
- // Note: We return true if the index is 0
- return findSchemeSeparator() == NOT_FOUND;
- }
-
- private volatile String scheme = NOT_CACHED;
-
- public String getScheme() {
- @SuppressWarnings("StringEquality")
- boolean cached = (scheme != NOT_CACHED);
- return cached ? scheme : (scheme = parseScheme());
- }
-
- private String parseScheme() {
- int ssi = findSchemeSeparator();
- return ssi == NOT_FOUND ? null : uriString.substring(0, ssi);
- }
-
- private Part ssp;
-
- private Part getSsp() {
- return ssp == null ? ssp = Part.fromEncoded(parseSsp()) : ssp;
- }
-
- public String getEncodedSchemeSpecificPart() {
- return getSsp().getEncoded();
- }
-
- public String getSchemeSpecificPart() {
- return getSsp().getDecoded();
- }
-
- private String parseSsp() {
- int ssi = findSchemeSeparator();
- int fsi = findFragmentSeparator();
-
- // Return everything between ssi and fsi.
- return fsi == NOT_FOUND
- ? uriString.substring(ssi + 1)
- : uriString.substring(ssi + 1, fsi);
- }
-
- private Part authority;
-
- private Part getAuthorityPart() {
- if (authority == null) {
- String encodedAuthority
- = parseAuthority(this.uriString, findSchemeSeparator());
- return authority = Part.fromEncoded(encodedAuthority);
- }
-
- return authority;
- }
-
- public String getEncodedAuthority() {
- return getAuthorityPart().getEncoded();
- }
-
- public String getAuthority() {
- return getAuthorityPart().getDecoded();
- }
-
- private PathPart path;
-
- private PathPart getPathPart() {
- return path == null
- ? path = PathPart.fromEncoded(parsePath())
- : path;
- }
-
- public String getPath() {
- return getPathPart().getDecoded();
- }
-
- public String getEncodedPath() {
- return getPathPart().getEncoded();
- }
-
- public List<String> getPathSegments() {
- return getPathPart().getPathSegments();
- }
-
- private String parsePath() {
- String uriString = this.uriString;
- int ssi = findSchemeSeparator();
-
- // If the URI is absolute.
- if (ssi > -1) {
- // Is there anything after the ':'?
- boolean schemeOnly = ssi + 1 == uriString.length();
- if (schemeOnly) {
- // Opaque URI.
- return null;
- }
-
- // A '/' after the ':' means this is hierarchical.
- if (uriString.charAt(ssi + 1) != '/') {
- // Opaque URI.
- return null;
- }
- } else {
- // All relative URIs are hierarchical.
- }
-
- return parsePath(uriString, ssi);
- }
-
- private Part query;
-
- private Part getQueryPart() {
- return query == null
- ? query = Part.fromEncoded(parseQuery()) : query;
- }
-
- public String getEncodedQuery() {
- return getQueryPart().getEncoded();
- }
-
- private String parseQuery() {
- // It doesn't make sense to cache this index. We only ever
- // calculate it once.
- int qsi = uriString.indexOf('?', findSchemeSeparator());
- if (qsi == NOT_FOUND) {
- return null;
- }
-
- int fsi = findFragmentSeparator();
-
- if (fsi == NOT_FOUND) {
- return uriString.substring(qsi + 1);
- }
-
- if (fsi < qsi) {
- // Invalid.
- return null;
- }
-
- return uriString.substring(qsi + 1, fsi);
- }
-
- public String getQuery() {
- return getQueryPart().getDecoded();
- }
-
- private Part fragment;
-
- private Part getFragmentPart() {
- return fragment == null
- ? fragment = Part.fromEncoded(parseFragment()) : fragment;
- }
-
- public String getEncodedFragment() {
- return getFragmentPart().getEncoded();
- }
-
- private String parseFragment() {
- int fsi = findFragmentSeparator();
- return fsi == NOT_FOUND ? null : uriString.substring(fsi + 1);
- }
-
- public String getFragment() {
- return getFragmentPart().getDecoded();
- }
-
- public String toString() {
- return uriString;
- }
-
- /**
- * Parses an authority out of the given URI string.
- *
- * @param uriString URI string
- * @param ssi scheme separator index, -1 for a relative URI
- *
- * @return the authority or null if none is found
- */
- static String parseAuthority(String uriString, int ssi) {
- int length = uriString.length();
-
- // If "//" follows the scheme separator, we have an authority.
- if (length > ssi + 2
- && uriString.charAt(ssi + 1) == '/'
- && uriString.charAt(ssi + 2) == '/') {
- // We have an authority.
-
- // Look for the start of the path, query, or fragment, or the
- // end of the string.
- int end = ssi + 3;
- LOOP: while (end < length) {
- switch (uriString.charAt(end)) {
- case '/': // Start of path
- case '?': // Start of query
- case '#': // Start of fragment
- break LOOP;
- }
- end++;
- }
-
- return uriString.substring(ssi + 3, end);
- } else {
- return null;
- }
-
- }
-
- /**
- * Parses a path out of this given URI string.
- *
- * @param uriString URI string
- * @param ssi scheme separator index, -1 for a relative URI
- *
- * @return the path
- */
- static String parsePath(String uriString, int ssi) {
- int length = uriString.length();
-
- // Find start of path.
- int pathStart;
- if (length > ssi + 2
- && uriString.charAt(ssi + 1) == '/'
- && uriString.charAt(ssi + 2) == '/') {
- // Skip over authority to path.
- pathStart = ssi + 3;
- LOOP: while (pathStart < length) {
- switch (uriString.charAt(pathStart)) {
- case '?': // Start of query
- case '#': // Start of fragment
- return ""; // Empty path.
- case '/': // Start of path!
- break LOOP;
- }
- pathStart++;
- }
- } else {
- // Path starts immediately after scheme separator.
- pathStart = ssi + 1;
- }
-
- // Find end of path.
- int pathEnd = pathStart;
- LOOP: while (pathEnd < length) {
- switch (uriString.charAt(pathEnd)) {
- case '?': // Start of query
- case '#': // Start of fragment
- break LOOP;
- }
- pathEnd++;
- }
-
- return uriString.substring(pathStart, pathEnd);
- }
-
- public Builder buildUpon() {
- if (isHierarchical()) {
- return new Builder()
- .scheme(getScheme())
- .authority(getAuthorityPart())
- .path(getPathPart())
- .query(getQueryPart())
- .fragment(getFragmentPart());
- } else {
- return new Builder()
- .scheme(getScheme())
- .opaquePart(getSsp())
- .fragment(getFragmentPart());
- }
- }
- }
-
- /**
- * Creates an opaque Uri from the given components. Encodes the ssp
- * which means this method cannot be used to create hierarchical URIs.
- *
- * @param scheme of the URI
- * @param ssp scheme-specific-part, everything between the
- * scheme separator (':') and the fragment separator ('#'), which will
- * get encoded
- * @param fragment fragment, everything after the '#', null if undefined,
- * will get encoded
- *
- * @throws NullPointerException if scheme or ssp is null
- * @return Uri composed of the given scheme, ssp, and fragment
- *
- * @see Builder if you don't want the ssp and fragment to be encoded
- */
- public static Uri fromParts(String scheme, String ssp,
- String fragment) {
- if (scheme == null) {
- throw new NullPointerException("scheme");
- }
- if (ssp == null) {
- throw new NullPointerException("ssp");
- }
-
- return new OpaqueUri(scheme, Part.fromDecoded(ssp),
- Part.fromDecoded(fragment));
- }
-
- /**
- * Opaque URI.
- */
- private static class OpaqueUri extends Uri {
-
- /** Used in parcelling. */
- static final int TYPE_ID = 2;
-
- private final String scheme;
- private final Part ssp;
- private final Part fragment;
-
- private OpaqueUri(String scheme, Part ssp, Part fragment) {
- this.scheme = scheme;
- this.ssp = ssp;
- this.fragment = fragment == null ? Part.NULL : fragment;
- }
-
- static Uri readFrom(Parcel parcel) {
- return new OpaqueUri(
- parcel.readString(),
- Part.readFrom(parcel),
- Part.readFrom(parcel)
- );
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeInt(TYPE_ID);
- parcel.writeString(scheme);
- ssp.writeTo(parcel);
- fragment.writeTo(parcel);
- }
-
- public boolean isHierarchical() {
- return false;
- }
-
- public boolean isRelative() {
- return scheme == null;
- }
-
- public String getScheme() {
- return this.scheme;
- }
-
- public String getEncodedSchemeSpecificPart() {
- return ssp.getEncoded();
- }
-
- public String getSchemeSpecificPart() {
- return ssp.getDecoded();
- }
-
- public String getAuthority() {
- return null;
- }
-
- public String getEncodedAuthority() {
- return null;
- }
-
- public String getPath() {
- return null;
- }
-
- public String getEncodedPath() {
- return null;
- }
-
- public String getQuery() {
- return null;
- }
-
- public String getEncodedQuery() {
- return null;
- }
-
- public String getFragment() {
- return fragment.getDecoded();
- }
-
- public String getEncodedFragment() {
- return fragment.getEncoded();
- }
-
- public List<String> getPathSegments() {
- return Collections.emptyList();
- }
-
- public String getLastPathSegment() {
- return null;
- }
-
- public String getUserInfo() {
- return null;
- }
-
- public String getEncodedUserInfo() {
- return null;
- }
-
- public String getHost() {
- return null;
- }
-
- public int getPort() {
- return -1;
- }
-
- private volatile String cachedString = NOT_CACHED;
-
- public String toString() {
- @SuppressWarnings("StringEquality")
- boolean cached = cachedString != NOT_CACHED;
- if (cached) {
- return cachedString;
- }
-
- StringBuilder sb = new StringBuilder();
-
- sb.append(scheme).append(':');
- sb.append(getEncodedSchemeSpecificPart());
-
- if (!fragment.isEmpty()) {
- sb.append('#').append(fragment.getEncoded());
- }
-
- return cachedString = sb.toString();
- }
-
- public Builder buildUpon() {
- return new Builder()
- .scheme(this.scheme)
- .opaquePart(this.ssp)
- .fragment(this.fragment);
- }
- }
-
- /**
- * Wrapper for path segment array.
- */
- static class PathSegments extends AbstractList<String>
- implements RandomAccess {
-
- static final PathSegments EMPTY = new PathSegments(null, 0);
-
- final String[] segments;
- final int size;
-
- PathSegments(String[] segments, int size) {
- this.segments = segments;
- this.size = size;
- }
-
- public String get(int index) {
- if (index >= size) {
- throw new IndexOutOfBoundsException();
- }
-
- return segments[index];
- }
-
- public int size() {
- return this.size;
- }
- }
-
- /**
- * Builds PathSegments.
- */
- static class PathSegmentsBuilder {
-
- String[] segments;
- int size = 0;
-
- void add(String segment) {
- if (segments == null) {
- segments = new String[4];
- } else if (size + 1 == segments.length) {
- String[] expanded = new String[segments.length * 2];
- System.arraycopy(segments, 0, expanded, 0, segments.length);
- segments = expanded;
- }
-
- segments[size++] = segment;
- }
-
- PathSegments build() {
- if (segments == null) {
- return PathSegments.EMPTY;
- }
-
- try {
- return new PathSegments(segments, size);
- } finally {
- // Makes sure this doesn't get reused.
- segments = null;
- }
- }
- }
-
- /**
- * Support for hierarchical URIs.
- */
- private abstract static class AbstractHierarchicalUri extends Uri {
-
- public String getLastPathSegment() {
- // TODO: If we haven't parsed all of the segments already, just
- // grab the last one directly so we only allocate one string.
-
- List<String> segments = getPathSegments();
- int size = segments.size();
- if (size == 0) {
- return null;
- }
- return segments.get(size - 1);
- }
-
- private Part userInfo;
-
- private Part getUserInfoPart() {
- return userInfo == null
- ? userInfo = Part.fromEncoded(parseUserInfo()) : userInfo;
- }
-
- public final String getEncodedUserInfo() {
- return getUserInfoPart().getEncoded();
- }
-
- private String parseUserInfo() {
- String authority = getEncodedAuthority();
- if (authority == null) {
- return null;
- }
-
- int end = authority.indexOf('@');
- return end == NOT_FOUND ? null : authority.substring(0, end);
- }
-
- public String getUserInfo() {
- return getUserInfoPart().getDecoded();
- }
-
- private volatile String host = NOT_CACHED;
-
- public String getHost() {
- @SuppressWarnings("StringEquality")
- boolean cached = (host != NOT_CACHED);
- return cached ? host
- : (host = parseHost());
- }
-
- private String parseHost() {
- String authority = getAuthority();
- if (authority == null) {
- return null;
- }
-
- // Parse out user info and then port.
- int userInfoSeparator = authority.indexOf('@');
- int portSeparator = authority.indexOf(':', userInfoSeparator);
-
- return portSeparator == NOT_FOUND
- ? authority.substring(userInfoSeparator + 1)
- : authority.substring(userInfoSeparator + 1, portSeparator);
- }
-
- private volatile int port = NOT_CALCULATED;
-
- public int getPort() {
- return port == NOT_CALCULATED
- ? port = parsePort()
- : port;
- }
-
- private int parsePort() {
- String authority = getAuthority();
- if (authority == null) {
- return -1;
- }
-
- // Make sure we look for the port separtor *after* the user info
- // separator. We have URLs with a ':' in the user info.
- int userInfoSeparator = authority.indexOf('@');
- int portSeparator = authority.indexOf(':', userInfoSeparator);
-
- if (portSeparator == NOT_FOUND) {
- return -1;
- }
-
- String portString = authority.substring(portSeparator + 1);
- try {
- return Integer.parseInt(portString);
- } catch (NumberFormatException e) {
- Log.w(LOG, "Error parsing port string.", e);
- return -1;
- }
- }
- }
-
- /**
- * Hierarchical Uri.
- */
- private static class HierarchicalUri extends AbstractHierarchicalUri {
-
- /** Used in parcelling. */
- static final int TYPE_ID = 3;
-
- private final String scheme;
- private final Part authority;
- private final PathPart path;
- private final Part query;
- private final Part fragment;
-
- private HierarchicalUri(String scheme, Part authority, PathPart path,
- Part query, Part fragment) {
- this.scheme = scheme;
- this.authority = authority;
- this.path = path;
- this.query = query;
- this.fragment = fragment;
- }
-
- static Uri readFrom(Parcel parcel) {
- return new HierarchicalUri(
- parcel.readString(),
- Part.readFrom(parcel),
- PathPart.readFrom(parcel),
- Part.readFrom(parcel),
- Part.readFrom(parcel)
- );
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeInt(TYPE_ID);
- parcel.writeString(scheme);
- authority.writeTo(parcel);
- path.writeTo(parcel);
- query.writeTo(parcel);
- fragment.writeTo(parcel);
- }
-
- public boolean isHierarchical() {
- return true;
- }
-
- public boolean isRelative() {
- return scheme == null;
- }
-
- public String getScheme() {
- return scheme;
- }
-
- private Part ssp;
-
- private Part getSsp() {
- return ssp == null
- ? ssp = Part.fromEncoded(makeSchemeSpecificPart()) : ssp;
- }
-
- public String getEncodedSchemeSpecificPart() {
- return getSsp().getEncoded();
- }
-
- public String getSchemeSpecificPart() {
- return getSsp().getDecoded();
- }
-
- /**
- * Creates the encoded scheme-specific part from its sub parts.
- */
- private String makeSchemeSpecificPart() {
- StringBuilder builder = new StringBuilder();
- appendSspTo(builder);
- return builder.toString();
- }
-
- private void appendSspTo(StringBuilder builder) {
- if (authority != null) {
- String encodedAuthority = authority.getEncoded();
- if (encodedAuthority != null) {
- // Even if the authority is "", we still want to append "//".
- builder.append("//").append(encodedAuthority);
- }
- }
-
- // path is never null.
- String encodedPath = path.getEncoded();
- if (encodedPath != null) {
- builder.append(encodedPath);
- }
-
- if (query != null && !query.isEmpty()) {
- builder.append('?').append(query.getEncoded());
- }
- }
-
- public String getAuthority() {
- return this.authority.getDecoded();
- }
-
- public String getEncodedAuthority() {
- return this.authority.getEncoded();
- }
-
- public String getEncodedPath() {
- return this.path.getEncoded();
- }
-
- public String getPath() {
- return this.path.getDecoded();
- }
-
- public String getQuery() {
- return this.query.getDecoded();
- }
-
- public String getEncodedQuery() {
- return this.query.getEncoded();
- }
-
- public String getFragment() {
- return this.fragment.getDecoded();
- }
-
- public String getEncodedFragment() {
- return this.fragment.getEncoded();
- }
-
- public List<String> getPathSegments() {
- return this.path.getPathSegments();
- }
-
- private volatile String uriString = NOT_CACHED;
-
- @Override
- public String toString() {
- @SuppressWarnings("StringEquality")
- boolean cached = (uriString != NOT_CACHED);
- return cached ? uriString
- : (uriString = makeUriString());
- }
-
- private String makeUriString() {
- StringBuilder builder = new StringBuilder();
-
- if (scheme != null) {
- builder.append(scheme).append(':');
- }
-
- appendSspTo(builder);
-
- if (fragment != null && !fragment.isEmpty()) {
- builder.append('#').append(fragment.getEncoded());
- }
-
- return builder.toString();
- }
-
- public Builder buildUpon() {
- return new Builder()
- .scheme(scheme)
- .authority(authority)
- .path(path)
- .query(query)
- .fragment(fragment);
- }
- }
-
- /**
- * Helper class for building or manipulating URI references. Not safe for
- * concurrent use.
- *
- * <p>An absolute hierarchical URI reference follows the pattern:
- * {@code &lt;scheme&gt;://&lt;authority&gt;&lt;absolute path&gt;?&lt;query&gt;#&lt;fragment&gt;}
- *
- * <p>Relative URI references (which are always hierarchical) follow one
- * of two patterns: {@code &lt;relative or absolute path&gt;?&lt;query&gt;#&lt;fragment&gt;}
- * or {@code //&lt;authority&gt;&lt;absolute path&gt;?&lt;query&gt;#&lt;fragment&gt;}
- *
- * <p>An opaque URI follows this pattern:
- * {@code &lt;scheme&gt;:&lt;opaque part&gt;#&lt;fragment&gt;}
- */
- public static final class Builder {
-
- private String scheme;
- private Part opaquePart;
- private Part authority;
- private PathPart path;
- private Part query;
- private Part fragment;
-
- /**
- * Constructs a new Builder.
- */
- public Builder() {}
-
- /**
- * Sets the scheme.
- *
- * @param scheme name or {@code null} if this is a relative Uri
- */
- public Builder scheme(String scheme) {
- this.scheme = scheme;
- return this;
- }
-
- Builder opaquePart(Part opaquePart) {
- this.opaquePart = opaquePart;
- return this;
- }
-
- /**
- * Encodes and sets the given opaque scheme-specific-part.
- *
- * @param opaquePart decoded opaque part
- */
- public Builder opaquePart(String opaquePart) {
- return opaquePart(Part.fromDecoded(opaquePart));
- }
-
- /**
- * Sets the previously encoded opaque scheme-specific-part.
- *
- * @param opaquePart encoded opaque part
- */
- public Builder encodedOpaquePart(String opaquePart) {
- return opaquePart(Part.fromEncoded(opaquePart));
- }
-
- Builder authority(Part authority) {
- // This URI will be hierarchical.
- this.opaquePart = null;
-
- this.authority = authority;
- return this;
- }
-
- /**
- * Encodes and sets the authority.
- */
- public Builder authority(String authority) {
- return authority(Part.fromDecoded(authority));
- }
-
- /**
- * Sets the previously encoded authority.
- */
- public Builder encodedAuthority(String authority) {
- return authority(Part.fromEncoded(authority));
- }
-
- Builder path(PathPart path) {
- // This URI will be hierarchical.
- this.opaquePart = null;
-
- this.path = path;
- return this;
- }
-
- /**
- * Sets the path. Leaves '/' characters intact but encodes others as
- * necessary.
- *
- * <p>If the path is not null and doesn't start with a '/', and if
- * you specify a scheme and/or authority, the builder will prepend the
- * given path with a '/'.
- */
- public Builder path(String path) {
- return path(PathPart.fromDecoded(path));
- }
-
- /**
- * Sets the previously encoded path.
- *
- * <p>If the path is not null and doesn't start with a '/', and if
- * you specify a scheme and/or authority, the builder will prepend the
- * given path with a '/'.
- */
- public Builder encodedPath(String path) {
- return path(PathPart.fromEncoded(path));
- }
-
- /**
- * Encodes the given segment and appends it to the path.
- */
- public Builder appendPath(String newSegment) {
- return path(PathPart.appendDecodedSegment(path, newSegment));
- }
-
- /**
- * Appends the given segment to the path.
- */
- public Builder appendEncodedPath(String newSegment) {
- return path(PathPart.appendEncodedSegment(path, newSegment));
- }
-
- Builder query(Part query) {
- // This URI will be hierarchical.
- this.opaquePart = null;
-
- this.query = query;
- return this;
- }
-
- /**
- * Encodes and sets the query.
- */
- public Builder query(String query) {
- return query(Part.fromDecoded(query));
- }
-
- /**
- * Sets the previously encoded query.
- */
- public Builder encodedQuery(String query) {
- return query(Part.fromEncoded(query));
- }
-
- Builder fragment(Part fragment) {
- this.fragment = fragment;
- return this;
- }
-
- /**
- * Encodes and sets the fragment.
- */
- public Builder fragment(String fragment) {
- return fragment(Part.fromDecoded(fragment));
- }
-
- /**
- * Sets the previously encoded fragment.
- */
- public Builder encodedFragment(String fragment) {
- return fragment(Part.fromEncoded(fragment));
- }
-
- /**
- * Encodes the key and value and then appends the parameter to the
- * query string.
- *
- * @param key which will be encoded
- * @param value which will be encoded
- */
- public Builder appendQueryParameter(String key, String value) {
- // This URI will be hierarchical.
- this.opaquePart = null;
-
- String encodedParameter = encode(key, null) + "="
- + encode(value, null);
-
- if (query == null) {
- query = Part.fromEncoded(encodedParameter);
- return this;
- }
-
- String oldQuery = query.getEncoded();
- if (oldQuery == null || oldQuery.length() == 0) {
- query = Part.fromEncoded(encodedParameter);
- } else {
- query = Part.fromEncoded(oldQuery + "&" + encodedParameter);
- }
-
- return this;
- }
-
- /**
- * Constructs a Uri with the current attributes.
- *
- * @throws UnsupportedOperationException if the URI is opaque and the
- * scheme is null
- */
- public Uri build() {
- if (opaquePart != null) {
- if (this.scheme == null) {
- throw new UnsupportedOperationException(
- "An opaque URI must have a scheme.");
- }
-
- return new OpaqueUri(scheme, opaquePart, fragment);
- } else {
- // Hierarchical URIs should not return null for getPath().
- PathPart path = this.path;
- if (path == null || path == PathPart.NULL) {
- path = PathPart.EMPTY;
- } else {
- // If we have a scheme and/or authority, the path must
- // be absolute. Prepend it with a '/' if necessary.
- if (hasSchemeOrAuthority()) {
- path = PathPart.makeAbsolute(path);
- }
- }
-
- return new HierarchicalUri(
- scheme, authority, path, query, fragment);
- }
- }
-
- private boolean hasSchemeOrAuthority() {
- return scheme != null
- || (authority != null && authority != Part.NULL);
-
- }
-
- @Override
- public String toString() {
- return build().toString();
- }
- }
-
- /**
- * Searches the query string for parameter values with the given key.
- *
- * @param key which will be encoded
- *
- * @throws UnsupportedOperationException if this isn't a hierarchical URI
- * @throws NullPointerException if key is null
- *
- * @return a list of decoded values
- */
- public List<String> getQueryParameters(String key) {
- if (isOpaque()) {
- throw new UnsupportedOperationException(NOT_HIERARCHICAL);
- }
-
- String query = getQuery();
- if (query == null) {
- return Collections.emptyList();
- }
-
- String encodedKey;
- try {
- encodedKey = URLEncoder.encode(key, DEFAULT_ENCODING);
- } catch (UnsupportedEncodingException e) {
- throw new AssertionError(e);
- }
-
- // Prepend query with "&" making the first parameter the same as the
- // rest.
- query = "&" + query;
-
- // Parameter prefix.
- String prefix = "&" + encodedKey + "=";
-
- ArrayList<String> values = new ArrayList<String>();
-
- int start = 0;
- int length = query.length();
- while (start < length) {
- start = query.indexOf(prefix, start);
-
- if (start == -1) {
- // No more values.
- break;
- }
-
- // Move start to start of value.
- start += prefix.length();
-
- // Find end of value.
- int end = query.indexOf('&', start);
- if (end == -1) {
- end = query.length();
- }
-
- String value = query.substring(start, end);
- values.add(decode(value));
-
- start = end;
- }
-
- return Collections.unmodifiableList(values);
- }
-
- /**
- * Searches the query string for the first value with the given key.
- *
- * @param key which will be encoded
- * @throws UnsupportedOperationException if this isn't a hierarchical URI
- * @throws NullPointerException if key is null
- *
- * @return the decoded value or null if no parameter is found
- */
- public String getQueryParameter(String key) {
- if (isOpaque()) {
- throw new UnsupportedOperationException(NOT_HIERARCHICAL);
- }
-
- String query = getQuery();
-
- if (query == null) {
- return null;
- }
-
- String encodedKey;
- try {
- encodedKey = URLEncoder.encode(key, DEFAULT_ENCODING);
- } catch (UnsupportedEncodingException e) {
- throw new AssertionError(e);
- }
-
- String prefix = encodedKey + "=";
-
- if (query.length() < prefix.length()) {
- return null;
- }
-
- int start;
- if (query.startsWith(prefix)) {
- // It's the first parameter.
- start = prefix.length();
- } else {
- // It must be later in the query string.
- prefix = "&" + prefix;
- start = query.indexOf(prefix);
-
- if (start == -1) {
- // Not found.
- return null;
- }
-
- start += prefix.length();
- }
-
- // Find end of value.
- int end = query.indexOf('&', start);
- if (end == -1) {
- end = query.length();
- }
-
- String value = query.substring(start, end);
- return decode(value);
- }
-
- /** Identifies a null parcelled Uri. */
- private static final int NULL_TYPE_ID = 0;
-
- /**
- * Reads Uris from Parcels.
- */
- public static final Parcelable.Creator<Uri> CREATOR
- = new Parcelable.Creator<Uri>() {
- public Uri createFromParcel(Parcel in) {
- int type = in.readInt();
- switch (type) {
- case NULL_TYPE_ID: return null;
- case StringUri.TYPE_ID: return StringUri.readFrom(in);
- case OpaqueUri.TYPE_ID: return OpaqueUri.readFrom(in);
- case HierarchicalUri.TYPE_ID:
- return HierarchicalUri.readFrom(in);
- }
-
- throw new AssertionError("Unknown URI type: " + type);
- }
-
- public Uri[] newArray(int size) {
- return new Uri[size];
- }
- };
-
- /**
- * Writes a Uri to a Parcel.
- *
- * @param out parcel to write to
- * @param uri to write, can be null
- */
- public static void writeToParcel(Parcel out, Uri uri) {
- if (uri == null) {
- out.writeInt(NULL_TYPE_ID);
- } else {
- uri.writeToParcel(out, 0);
- }
- }
-
- private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
-
- /**
- * Encodes characters in the given string as '%'-escaped octets
- * using the UTF-8 scheme. Leaves letters ("A-Z", "a-z"), numbers
- * ("0-9"), and unreserved characters ("_-!.~'()*") intact. Encodes
- * all other characters.
- *
- * @param s string to encode
- * @return an encoded version of s suitable for use as a URI component,
- * or null if s is null
- */
- public static String encode(String s) {
- return encode(s, null);
- }
-
- /**
- * Encodes characters in the given string as '%'-escaped octets
- * using the UTF-8 scheme. Leaves letters ("A-Z", "a-z"), numbers
- * ("0-9"), and unreserved characters ("_-!.~'()*") intact. Encodes
- * all other characters with the exception of those specified in the
- * allow argument.
- *
- * @param s string to encode
- * @param allow set of additional characters to allow in the encoded form,
- * null if no characters should be skipped
- * @return an encoded version of s suitable for use as a URI component,
- * or null if s is null
- */
- public static String encode(String s, String allow) {
- if (s == null) {
- return null;
- }
-
- // Lazily-initialized buffers.
- StringBuilder encoded = null;
-
- int oldLength = s.length();
-
- // This loop alternates between copying over allowed characters and
- // encoding in chunks. This results in fewer method calls and
- // allocations than encoding one character at a time.
- int current = 0;
- while (current < oldLength) {
- // Start in "copying" mode where we copy over allowed chars.
-
- // Find the next character which needs to be encoded.
- int nextToEncode = current;
- while (nextToEncode < oldLength
- && isAllowed(s.charAt(nextToEncode), allow)) {
- nextToEncode++;
- }
-
- // If there's nothing more to encode...
- if (nextToEncode == oldLength) {
- if (current == 0) {
- // We didn't need to encode anything!
- return s;
- } else {
- // Presumably, we've already done some encoding.
- encoded.append(s, current, oldLength);
- return encoded.toString();
- }
- }
-
- if (encoded == null) {
- encoded = new StringBuilder();
- }
-
- if (nextToEncode > current) {
- // Append allowed characters leading up to this point.
- encoded.append(s, current, nextToEncode);
- } else {
- // assert nextToEncode == current
- }
-
- // Switch to "encoding" mode.
-
- // Find the next allowed character.
- current = nextToEncode;
- int nextAllowed = current + 1;
- while (nextAllowed < oldLength
- && !isAllowed(s.charAt(nextAllowed), allow)) {
- nextAllowed++;
- }
-
- // Convert the substring to bytes and encode the bytes as
- // '%'-escaped octets.
- String toEncode = s.substring(current, nextAllowed);
- try {
- byte[] bytes = toEncode.getBytes(DEFAULT_ENCODING);
- int bytesLength = bytes.length;
- for (int i = 0; i < bytesLength; i++) {
- encoded.append('%');
- encoded.append(HEX_DIGITS[(bytes[i] & 0xf0) >> 4]);
- encoded.append(HEX_DIGITS[bytes[i] & 0xf]);
- }
- } catch (UnsupportedEncodingException e) {
- throw new AssertionError(e);
- }
-
- current = nextAllowed;
- }
-
- // Encoded could still be null at this point if s is empty.
- return encoded == null ? s : encoded.toString();
- }
-
- /**
- * Returns true if the given character is allowed.
- *
- * @param c character to check
- * @param allow characters to allow
- * @return true if the character is allowed or false if it should be
- * encoded
- */
- private static boolean isAllowed(char c, String allow) {
- return (c >= 'A' && c <= 'Z')
- || (c >= 'a' && c <= 'z')
- || (c >= '0' && c <= '9')
- || "_-!.~'()*".indexOf(c) != NOT_FOUND
- || (allow != null && allow.indexOf(c) != NOT_FOUND);
- }
-
- /** Unicode replacement character: \\uFFFD. */
- private static final byte[] REPLACEMENT = { (byte) 0xFF, (byte) 0xFD };
-
- /**
- * Decodes '%'-escaped octets in the given string using the UTF-8 scheme.
- * Replaces invalid octets with the unicode replacement character
- * ("\\uFFFD").
- *
- * @param s encoded string to decode
- * @return the given string with escaped octets decoded, or null if
- * s is null
- */
- public static String decode(String s) {
- /*
- Compared to java.net.URLEncoderDecoder.decode(), this method decodes a
- chunk at a time instead of one character at a time, and it doesn't
- throw exceptions. It also only allocates memory when necessary--if
- there's nothing to decode, this method won't do much.
- */
-
- if (s == null) {
- return null;
- }
-
- // Lazily-initialized buffers.
- StringBuilder decoded = null;
- ByteArrayOutputStream out = null;
-
- int oldLength = s.length();
-
- // This loop alternates between copying over normal characters and
- // escaping in chunks. This results in fewer method calls and
- // allocations than decoding one character at a time.
- int current = 0;
- while (current < oldLength) {
- // Start in "copying" mode where we copy over normal characters.
-
- // Find the next escape sequence.
- int nextEscape = s.indexOf('%', current);
-
- if (nextEscape == NOT_FOUND) {
- if (decoded == null) {
- // We didn't actually decode anything.
- return s;
- } else {
- // Append the remainder and return the decoded string.
- decoded.append(s, current, oldLength);
- return decoded.toString();
- }
- }
-
- // Prepare buffers.
- if (decoded == null) {
- // Looks like we're going to need the buffers...
- // We know the new string will be shorter. Using the old length
- // may overshoot a bit, but it will save us from resizing the
- // buffer.
- decoded = new StringBuilder(oldLength);
- out = new ByteArrayOutputStream(4);
- } else {
- // Clear decoding buffer.
- out.reset();
- }
-
- // Append characters leading up to the escape.
- if (nextEscape > current) {
- decoded.append(s, current, nextEscape);
-
- current = nextEscape;
- } else {
- // assert current == nextEscape
- }
-
- // Switch to "decoding" mode where we decode a string of escape
- // sequences.
-
- // Decode and append escape sequences. Escape sequences look like
- // "%ab" where % is literal and a and b are hex digits.
- try {
- do {
- if (current + 2 >= oldLength) {
- // Truncated escape sequence.
- out.write(REPLACEMENT);
- } else {
- int a = Character.digit(s.charAt(current + 1), 16);
- int b = Character.digit(s.charAt(current + 2), 16);
-
- if (a == -1 || b == -1) {
- // Non hex digits.
- out.write(REPLACEMENT);
- } else {
- // Combine the hex digits into one byte and write.
- out.write((a << 4) + b);
- }
- }
-
- // Move passed the escape sequence.
- current += 3;
- } while (current < oldLength && s.charAt(current) == '%');
-
- // Decode UTF-8 bytes into a string and append it.
- decoded.append(out.toString(DEFAULT_ENCODING));
- } catch (UnsupportedEncodingException e) {
- throw new AssertionError(e);
- } catch (IOException e) {
- throw new AssertionError(e);
- }
- }
-
- // If we don't have a buffer, we didn't have to decode anything.
- return decoded == null ? s : decoded.toString();
- }
-
- /**
- * Support for part implementations.
- */
- static abstract class AbstractPart {
-
- /**
- * Enum which indicates which representation of a given part we have.
- */
- static class Representation {
- static final int BOTH = 0;
- static final int ENCODED = 1;
- static final int DECODED = 2;
- }
-
- volatile String encoded;
- volatile String decoded;
-
- AbstractPart(String encoded, String decoded) {
- this.encoded = encoded;
- this.decoded = decoded;
- }
-
- abstract String getEncoded();
-
- final String getDecoded() {
- @SuppressWarnings("StringEquality")
- boolean hasDecoded = decoded != NOT_CACHED;
- return hasDecoded ? decoded : (decoded = decode(encoded));
- }
-
- final void writeTo(Parcel parcel) {
- @SuppressWarnings("StringEquality")
- boolean hasEncoded = encoded != NOT_CACHED;
-
- @SuppressWarnings("StringEquality")
- boolean hasDecoded = decoded != NOT_CACHED;
-
- if (hasEncoded && hasDecoded) {
- parcel.writeInt(Representation.BOTH);
- parcel.writeString(encoded);
- parcel.writeString(decoded);
- } else if (hasEncoded) {
- parcel.writeInt(Representation.ENCODED);
- parcel.writeString(encoded);
- } else if (hasDecoded) {
- parcel.writeInt(Representation.DECODED);
- parcel.writeString(decoded);
- } else {
- throw new AssertionError();
- }
- }
- }
-
- /**
- * Immutable wrapper of encoded and decoded versions of a URI part. Lazily
- * creates the encoded or decoded version from the other.
- */
- static class Part extends AbstractPart {
-
- /** A part with null values. */
- static final Part NULL = new EmptyPart(null);
-
- /** A part with empty strings for values. */
- static final Part EMPTY = new EmptyPart("");
-
- private Part(String encoded, String decoded) {
- super(encoded, decoded);
- }
-
- boolean isEmpty() {
- return false;
- }
-
- String getEncoded() {
- @SuppressWarnings("StringEquality")
- boolean hasEncoded = encoded != NOT_CACHED;
- return hasEncoded ? encoded : (encoded = encode(decoded));
- }
-
- static Part readFrom(Parcel parcel) {
- int representation = parcel.readInt();
- switch (representation) {
- case Representation.BOTH:
- return from(parcel.readString(), parcel.readString());
- case Representation.ENCODED:
- return fromEncoded(parcel.readString());
- case Representation.DECODED:
- return fromDecoded(parcel.readString());
- default:
- throw new AssertionError();
- }
- }
-
- /**
- * Returns given part or {@link #NULL} if the given part is null.
- */
- static Part nonNull(Part part) {
- return part == null ? NULL : part;
- }
-
- /**
- * Creates a part from the encoded string.
- *
- * @param encoded part string
- */
- static Part fromEncoded(String encoded) {
- return from(encoded, NOT_CACHED);
- }
-
- /**
- * Creates a part from the decoded string.
- *
- * @param decoded part string
- */
- static Part fromDecoded(String decoded) {
- return from(NOT_CACHED, decoded);
- }
-
- /**
- * Creates a part from the encoded and decoded strings.
- *
- * @param encoded part string
- * @param decoded part string
- */
- static Part from(String encoded, String decoded) {
- // We have to check both encoded and decoded in case one is
- // NOT_CACHED.
-
- if (encoded == null) {
- return NULL;
- }
- if (encoded.length() == 0) {
- return EMPTY;
- }
-
- if (decoded == null) {
- return NULL;
- }
- if (decoded .length() == 0) {
- return EMPTY;
- }
-
- return new Part(encoded, decoded);
- }
-
- private static class EmptyPart extends Part {
- public EmptyPart(String value) {
- super(value, value);
- }
-
- @Override
- boolean isEmpty() {
- return true;
- }
- }
- }
-
- /**
- * Immutable wrapper of encoded and decoded versions of a path part. Lazily
- * creates the encoded or decoded version from the other.
- */
- static class PathPart extends AbstractPart {
-
- /** A part with null values. */
- static final PathPart NULL = new PathPart(null, null);
-
- /** A part with empty strings for values. */
- static final PathPart EMPTY = new PathPart("", "");
-
- private PathPart(String encoded, String decoded) {
- super(encoded, decoded);
- }
-
- String getEncoded() {
- @SuppressWarnings("StringEquality")
- boolean hasEncoded = encoded != NOT_CACHED;
-
- // Don't encode '/'.
- return hasEncoded ? encoded : (encoded = encode(decoded, "/"));
- }
-
- /**
- * Cached path segments. This doesn't need to be volatile--we don't
- * care if other threads see the result.
- */
- private PathSegments pathSegments;
-
- /**
- * Gets the individual path segments. Parses them if necessary.
- *
- * @return parsed path segments or null if this isn't a hierarchical
- * URI
- */
- PathSegments getPathSegments() {
- if (pathSegments != null) {
- return pathSegments;
- }
-
- String path = getEncoded();
- if (path == null) {
- return pathSegments = PathSegments.EMPTY;
- }
-
- PathSegmentsBuilder segmentBuilder = new PathSegmentsBuilder();
-
- int previous = 0;
- int current;
- while ((current = path.indexOf('/', previous)) > -1) {
- // This check keeps us from adding a segment if the path starts
- // '/' and an empty segment for "//".
- if (previous < current) {
- String decodedSegment
- = decode(path.substring(previous, current));
- segmentBuilder.add(decodedSegment);
- }
- previous = current + 1;
- }
-
- // Add in the final path segment.
- if (previous < path.length()) {
- segmentBuilder.add(decode(path.substring(previous)));
- }
-
- return pathSegments = segmentBuilder.build();
- }
-
- static PathPart appendEncodedSegment(PathPart oldPart,
- String newSegment) {
- // If there is no old path, should we make the new path relative
- // or absolute? I pick absolute.
-
- if (oldPart == null) {
- // No old path.
- return fromEncoded("/" + newSegment);
- }
-
- String oldPath = oldPart.getEncoded();
-
- if (oldPath == null) {
- oldPath = "";
- }
-
- int oldPathLength = oldPath.length();
- String newPath;
- if (oldPathLength == 0) {
- // No old path.
- newPath = "/" + newSegment;
- } else if (oldPath.charAt(oldPathLength - 1) == '/') {
- newPath = oldPath + newSegment;
- } else {
- newPath = oldPath + "/" + newSegment;
- }
-
- return fromEncoded(newPath);
- }
-
- static PathPart appendDecodedSegment(PathPart oldPart, String decoded) {
- String encoded = encode(decoded);
-
- // TODO: Should we reuse old PathSegments? Probably not.
- return appendEncodedSegment(oldPart, encoded);
- }
-
- static PathPart readFrom(Parcel parcel) {
- int representation = parcel.readInt();
- switch (representation) {
- case Representation.BOTH:
- return from(parcel.readString(), parcel.readString());
- case Representation.ENCODED:
- return fromEncoded(parcel.readString());
- case Representation.DECODED:
- return fromDecoded(parcel.readString());
- default:
- throw new AssertionError();
- }
- }
-
- /**
- * Creates a path from the encoded string.
- *
- * @param encoded part string
- */
- static PathPart fromEncoded(String encoded) {
- return from(encoded, NOT_CACHED);
- }
-
- /**
- * Creates a path from the decoded string.
- *
- * @param decoded part string
- */
- static PathPart fromDecoded(String decoded) {
- return from(NOT_CACHED, decoded);
- }
-
- /**
- * Creates a path from the encoded and decoded strings.
- *
- * @param encoded part string
- * @param decoded part string
- */
- static PathPart from(String encoded, String decoded) {
- if (encoded == null) {
- return NULL;
- }
-
- if (encoded.length() == 0) {
- return EMPTY;
- }
-
- return new PathPart(encoded, decoded);
- }
-
- /**
- * Prepends path values with "/" if they're present, not empty, and
- * they don't already start with "/".
- */
- static PathPart makeAbsolute(PathPart oldPart) {
- @SuppressWarnings("StringEquality")
- boolean encodedCached = oldPart.encoded != NOT_CACHED;
-
- // We don't care which version we use, and we don't want to force
- // unneccessary encoding/decoding.
- String oldPath = encodedCached ? oldPart.encoded : oldPart.decoded;
-
- if (oldPath == null || oldPath.length() == 0
- || oldPath.startsWith("/")) {
- return oldPart;
- }
-
- // Prepend encoded string if present.
- String newEncoded = encodedCached
- ? "/" + oldPart.encoded : NOT_CACHED;
-
- // Prepend decoded string if present.
- @SuppressWarnings("StringEquality")
- boolean decodedCached = oldPart.decoded != NOT_CACHED;
- String newDecoded = decodedCached
- ? "/" + oldPart.decoded
- : NOT_CACHED;
-
- return new PathPart(newEncoded, newDecoded);
- }
- }
-
- /**
- * Creates a new Uri by appending an already-encoded path segment to a
- * base Uri.
- *
- * @param baseUri Uri to append path segment to
- * @param pathSegment encoded path segment to append
- * @return a new Uri based on baseUri with the given segment appended to
- * the path
- * @throws NullPointerException if baseUri is null
- */
- public static Uri withAppendedPath(Uri baseUri, String pathSegment) {
- Builder builder = baseUri.buildUpon();
- builder = builder.appendEncodedPath(pathSegment);
- return builder.build();
- }
-}
diff --git a/core/java/android/net/UrlQuerySanitizer.java b/core/java/android/net/UrlQuerySanitizer.java
deleted file mode 100644
index a6efcdd3da5..00000000000
--- a/core/java/android/net/UrlQuerySanitizer.java
+++ /dev/null
@@ -1,913 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-/**
- *
- * Sanitizes the Query portion of a URL. Simple example:
- * <code>
- * UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
- * sanitizer.setAllowUnregisteredParamaters(true);
- * sanitizer.parseUrl("http://example.com/?name=Joe+User");
- * String name = sanitizer.getValue("name"));
- * // name now contains "Joe_User"
- * </code>
- *
- * Register ValueSanitizers to customize the way individual
- * parameters are sanitized:
- * <code>
- * UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
- * sanitizer.registerParamater("name", UrlQuerySanitizer.createSpaceLegal());
- * sanitizer.parseUrl("http://example.com/?name=Joe+User");
- * String name = sanitizer.getValue("name"));
- * // name now contains "Joe User". (The string is first decoded, which
- * // converts the '+' to a ' '. Then the string is sanitized, which
- * // converts the ' ' to an '_'. (The ' ' is converted because the default
- * unregistered parameter sanitizer does not allow any special characters,
- * and ' ' is a special character.)
- * </code>
- *
- * There are several ways to create ValueSanitizers. In order of increasing
- * sophistication:
- * <ol>
- * <li>Call one of the UrlQuerySanitizer.createXXX() methods.
- * <li>Construct your own instance of
- * UrlQuerySanitizer.IllegalCharacterValueSanitizer.
- * <li>Subclass UrlQuerySanitizer.ValueSanitizer to define your own value
- * sanitizer.
- * </ol>
- *
- */
-public class UrlQuerySanitizer {
-
- /**
- * A simple tuple that holds parameter-value pairs.
- *
- */
- public class ParameterValuePair {
- /**
- * Construct a parameter-value tuple.
- * @param parameter an unencoded parameter
- * @param value an unencoded value
- */
- public ParameterValuePair(String parameter,
- String value) {
- mParameter = parameter;
- mValue = value;
- }
- /**
- * The unencoded parameter
- */
- public String mParameter;
- /**
- * The unencoded value
- */
- public String mValue;
- }
-
- final private HashMap<String, ValueSanitizer> mSanitizers =
- new HashMap<String, ValueSanitizer>();
- final private HashMap<String, String> mEntries =
- new HashMap<String, String>();
- final private ArrayList<ParameterValuePair> mEntriesList =
- new ArrayList<ParameterValuePair>();
- private boolean mAllowUnregisteredParamaters;
- private boolean mPreferFirstRepeatedParameter;
- private ValueSanitizer mUnregisteredParameterValueSanitizer =
- getAllIllegal();
-
- /**
- * A functor used to sanitize a single query value.
- *
- */
- public static interface ValueSanitizer {
- /**
- * Sanitize an unencoded value.
- * @param value
- * @return the sanitized unencoded value
- */
- public String sanitize(String value);
- }
-
- /**
- * Sanitize values based on which characters they contain. Illegal
- * characters are replaced with either space or '_', depending upon
- * whether space is a legal character or not.
- */
- public static class IllegalCharacterValueSanitizer implements
- ValueSanitizer {
- private int mFlags;
-
- /**
- * Allow space (' ') characters.
- */
- public final static int SPACE_OK = 1 << 0;
- /**
- * Allow whitespace characters other than space. The
- * other whitespace characters are
- * '\t' '\f' '\n' '\r' and '\0x000b' (vertical tab)
- */
- public final static int OTHER_WHITESPACE_OK = 1 << 1;
- /**
- * Allow characters with character codes 128 to 255.
- */
- public final static int NON_7_BIT_ASCII_OK = 1 << 2;
- /**
- * Allow double quote characters. ('"')
- */
- public final static int DQUOTE_OK = 1 << 3;
- /**
- * Allow single quote characters. ('\'')
- */
- public final static int SQUOTE_OK = 1 << 4;
- /**
- * Allow less-than characters. ('<')
- */
- public final static int LT_OK = 1 << 5;
- /**
- * Allow greater-than characters. ('>')
- */
- public final static int GT_OK = 1 << 6;
- /**
- * Allow ampersand characters ('&')
- */
- public final static int AMP_OK = 1 << 7;
- /**
- * Allow percent-sign characters ('%')
- */
- public final static int PCT_OK = 1 << 8;
- /**
- * Allow nul characters ('\0')
- */
- public final static int NUL_OK = 1 << 9;
- /**
- * Allow text to start with a script URL
- * such as "javascript:" or "vbscript:"
- */
- public final static int SCRIPT_URL_OK = 1 << 10;
-
- /**
- * Mask with all fields set to OK
- */
- public final static int ALL_OK = 0x7ff;
-
- /**
- * Mask with both regular space and other whitespace OK
- */
- public final static int ALL_WHITESPACE_OK =
- SPACE_OK | OTHER_WHITESPACE_OK;
-
-
- // Common flag combinations:
-
- /**
- * <ul>
- * <li>Deny all special characters.
- * <li>Deny script URLs.
- * </ul>
- */
- public final static int ALL_ILLEGAL =
- 0;
- /**
- * <ul>
- * <li>Allow all special characters except Nul. ('\0').
- * <li>Allow script URLs.
- * </ul>
- */
- public final static int ALL_BUT_NUL_LEGAL =
- ALL_OK & ~NUL_OK;
- /**
- * <ul>
- * <li>Allow all special characters except for:
- * <ul>
- * <li>whitespace characters
- * <li>Nul ('\0')
- * </ul>
- * <li>Allow script URLs.
- * </ul>
- */
- public final static int ALL_BUT_WHITESPACE_LEGAL =
- ALL_OK & ~(ALL_WHITESPACE_OK | NUL_OK);
- /**
- * <ul>
- * <li>Allow characters used by encoded URLs.
- * <li>Deny script URLs.
- * </ul>
- */
- public final static int URL_LEGAL =
- NON_7_BIT_ASCII_OK | SQUOTE_OK | AMP_OK | PCT_OK;
- /**
- * <ul>
- * <li>Allow characters used by encoded URLs.
- * <li>Allow spaces.
- * <li>Deny script URLs.
- * </ul>
- */
- public final static int URL_AND_SPACE_LEGAL =
- URL_LEGAL | SPACE_OK;
- /**
- * <ul>
- * <li>Allow ampersand.
- * <li>Deny script URLs.
- * </ul>
- */
- public final static int AMP_LEGAL =
- AMP_OK;
- /**
- * <ul>
- * <li>Allow ampersand.
- * <li>Allow space.
- * <li>Deny script URLs.
- * </ul>
- */
- public final static int AMP_AND_SPACE_LEGAL =
- AMP_OK | SPACE_OK;
- /**
- * <ul>
- * <li>Allow space.
- * <li>Deny script URLs.
- * </ul>
- */
- public final static int SPACE_LEGAL =
- SPACE_OK;
- /**
- * <ul>
- * <li>Allow all but.
- * <ul>
- * <li>Nul ('\0')
- * <li>Angle brackets ('<', '>')
- * </ul>
- * <li>Deny script URLs.
- * </ul>
- */
- public final static int ALL_BUT_NUL_AND_ANGLE_BRACKETS_LEGAL =
- ALL_OK & ~(NUL_OK | LT_OK | GT_OK);
-
- /**
- * Script URL definitions
- */
-
- private final static String JAVASCRIPT_PREFIX = "javascript:";
-
- private final static String VBSCRIPT_PREFIX = "vbscript:";
-
- private final static int MIN_SCRIPT_PREFIX_LENGTH = Math.min(
- JAVASCRIPT_PREFIX.length(), VBSCRIPT_PREFIX.length());
-
- /**
- * Construct a sanitizer. The parameters set the behavior of the
- * sanitizer.
- * @param flags some combination of the XXX_OK flags.
- */
- public IllegalCharacterValueSanitizer(
- int flags) {
- mFlags = flags;
- }
- /**
- * Sanitize a value.
- * <ol>
- * <li>If script URLs are not OK, the will be removed.
- * <li>If neither spaces nor other white space is OK, then
- * white space will be trimmed from the beginning and end of
- * the URL. (Just the actual white space characters are trimmed, not
- * other control codes.)
- * <li> Illegal characters will be replaced with
- * either ' ' or '_', depending on whether a space is itself a
- * legal character.
- * </ol>
- * @param value
- * @return the sanitized value
- */
- public String sanitize(String value) {
- if (value == null) {
- return null;
- }
- int length = value.length();
- if ((mFlags & SCRIPT_URL_OK) != 0) {
- if (length >= MIN_SCRIPT_PREFIX_LENGTH) {
- String asLower = value.toLowerCase();
- if (asLower.startsWith(JAVASCRIPT_PREFIX) ||
- asLower.startsWith(VBSCRIPT_PREFIX)) {
- return "";
- }
- }
- }
-
- // If whitespace isn't OK, get rid of whitespace at beginning
- // and end of value.
- if ( (mFlags & ALL_WHITESPACE_OK) == 0) {
- value = trimWhitespace(value);
- // The length could have changed, so we need to correct
- // the length variable.
- length = value.length();
- }
-
- StringBuilder stringBuilder = new StringBuilder(length);
- for(int i = 0; i < length; i++) {
- char c = value.charAt(i);
- if (!characterIsLegal(c)) {
- if ((mFlags & SPACE_OK) != 0) {
- c = ' ';
- }
- else {
- c = '_';
- }
- }
- stringBuilder.append(c);
- }
- return stringBuilder.toString();
- }
-
- /**
- * Trim whitespace from the beginning and end of a string.
- * <p>
- * Note: can't use {@link String#trim} because {@link String#trim} has a
- * different definition of whitespace than we want.
- * @param value the string to trim
- * @return the trimmed string
- */
- private String trimWhitespace(String value) {
- int start = 0;
- int last = value.length() - 1;
- int end = last;
- while (start <= end && isWhitespace(value.charAt(start))) {
- start++;
- }
- while (end >= start && isWhitespace(value.charAt(end))) {
- end--;
- }
- if (start == 0 && end == last) {
- return value;
- }
- return value.substring(start, end + 1);
- }
-
- /**
- * Check if c is whitespace.
- * @param c character to test
- * @return true if c is a whitespace character
- */
- private boolean isWhitespace(char c) {
- switch(c) {
- case ' ':
- case '\t':
- case '\f':
- case '\n':
- case '\r':
- case 11: /* VT */
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Check whether an individual character is legal. Uses the
- * flag bit-set passed into the constructor.
- * @param c
- * @return true if c is a legal character
- */
- private boolean characterIsLegal(char c) {
- switch(c) {
- case ' ' : return (mFlags & SPACE_OK) != 0;
- case '\t': case '\f': case '\n': case '\r': case 11: /* VT */
- return (mFlags & OTHER_WHITESPACE_OK) != 0;
- case '\"': return (mFlags & DQUOTE_OK) != 0;
- case '\'': return (mFlags & SQUOTE_OK) != 0;
- case '<' : return (mFlags & LT_OK) != 0;
- case '>' : return (mFlags & GT_OK) != 0;
- case '&' : return (mFlags & AMP_OK) != 0;
- case '%' : return (mFlags & PCT_OK) != 0;
- case '\0': return (mFlags & NUL_OK) != 0;
- default : return (c >= 32 && c < 127) ||
- ((c >= 128) && ((mFlags & NON_7_BIT_ASCII_OK) != 0));
- }
- }
- }
-
- /**
- * Get the current value sanitizer used when processing
- * unregistered parameter values.
- * <p>
- * <b>Note:</b> The default unregistered parameter value sanitizer is
- * one that doesn't allow any special characters, similar to what
- * is returned by calling createAllIllegal.
- *
- * @return the current ValueSanitizer used to sanitize unregistered
- * parameter values.
- */
- public ValueSanitizer getUnregisteredParameterValueSanitizer() {
- return mUnregisteredParameterValueSanitizer;
- }
-
- /**
- * Set the value sanitizer used when processing unregistered
- * parameter values.
- * @param sanitizer set the ValueSanitizer used to sanitize unregistered
- * parameter values.
- */
- public void setUnregisteredParameterValueSanitizer(
- ValueSanitizer sanitizer) {
- mUnregisteredParameterValueSanitizer = sanitizer;
- }
-
-
- // Private fields for singleton sanitizers:
-
- private static final ValueSanitizer sAllIllegal =
- new IllegalCharacterValueSanitizer(
- IllegalCharacterValueSanitizer.ALL_ILLEGAL);
-
- private static final ValueSanitizer sAllButNulLegal =
- new IllegalCharacterValueSanitizer(
- IllegalCharacterValueSanitizer.ALL_BUT_NUL_LEGAL);
-
- private static final ValueSanitizer sAllButWhitespaceLegal =
- new IllegalCharacterValueSanitizer(
- IllegalCharacterValueSanitizer.ALL_BUT_WHITESPACE_LEGAL);
-
- private static final ValueSanitizer sURLLegal =
- new IllegalCharacterValueSanitizer(
- IllegalCharacterValueSanitizer.URL_LEGAL);
-
- private static final ValueSanitizer sUrlAndSpaceLegal =
- new IllegalCharacterValueSanitizer(
- IllegalCharacterValueSanitizer.URL_AND_SPACE_LEGAL);
-
- private static final ValueSanitizer sAmpLegal =
- new IllegalCharacterValueSanitizer(
- IllegalCharacterValueSanitizer.AMP_LEGAL);
-
- private static final ValueSanitizer sAmpAndSpaceLegal =
- new IllegalCharacterValueSanitizer(
- IllegalCharacterValueSanitizer.AMP_AND_SPACE_LEGAL);
-
- private static final ValueSanitizer sSpaceLegal =
- new IllegalCharacterValueSanitizer(
- IllegalCharacterValueSanitizer.SPACE_LEGAL);
-
- private static final ValueSanitizer sAllButNulAndAngleBracketsLegal =
- new IllegalCharacterValueSanitizer(
- IllegalCharacterValueSanitizer.ALL_BUT_NUL_AND_ANGLE_BRACKETS_LEGAL);
-
- /**
- * Return a value sanitizer that does not allow any special characters,
- * and also does not allow script URLs.
- * @return a value sanitizer
- */
- public static final ValueSanitizer getAllIllegal() {
- return sAllIllegal;
- }
-
- /**
- * Return a value sanitizer that allows everything except Nul ('\0')
- * characters. Script URLs are allowed.
- * @return a value sanitizer
- */
- public static final ValueSanitizer getAllButNulLegal() {
- return sAllButNulLegal;
- }
- /**
- * Return a value sanitizer that allows everything except Nul ('\0')
- * characters, space (' '), and other whitespace characters.
- * Script URLs are allowed.
- * @return a value sanitizer
- */
- public static final ValueSanitizer getAllButWhitespaceLegal() {
- return sAllButWhitespaceLegal;
- }
- /**
- * Return a value sanitizer that allows all the characters used by
- * encoded URLs. Does not allow script URLs.
- * @return a value sanitizer
- */
- public static final ValueSanitizer getUrlLegal() {
- return sURLLegal;
- }
- /**
- * Return a value sanitizer that allows all the characters used by
- * encoded URLs and allows spaces, which are not technically legal
- * in encoded URLs, but commonly appear anyway.
- * Does not allow script URLs.
- * @return a value sanitizer
- */
- public static final ValueSanitizer getUrlAndSpaceLegal() {
- return sUrlAndSpaceLegal;
- }
- /**
- * Return a value sanitizer that does not allow any special characters
- * except ampersand ('&'). Does not allow script URLs.
- * @return a value sanitizer
- */
- public static final ValueSanitizer getAmpLegal() {
- return sAmpLegal;
- }
- /**
- * Return a value sanitizer that does not allow any special characters
- * except ampersand ('&') and space (' '). Does not allow script URLs.
- * @return a value sanitizer
- */
- public static final ValueSanitizer getAmpAndSpaceLegal() {
- return sAmpAndSpaceLegal;
- }
- /**
- * Return a value sanitizer that does not allow any special characters
- * except space (' '). Does not allow script URLs.
- * @return a value sanitizer
- */
- public static final ValueSanitizer getSpaceLegal() {
- return sSpaceLegal;
- }
- /**
- * Return a value sanitizer that allows any special characters
- * except angle brackets ('<' and '>') and Nul ('\0').
- * Allows script URLs.
- * @return a value sanitizer
- */
- public static final ValueSanitizer getAllButNulAndAngleBracketsLegal() {
- return sAllButNulAndAngleBracketsLegal;
- }
-
- /**
- * Constructs a UrlQuerySanitizer.
- * <p>
- * Defaults:
- * <ul>
- * <li>unregistered parameters are not allowed.
- * <li>the last instance of a repeated parameter is preferred.
- * <li>The default value sanitizer is an AllIllegal value sanitizer.
- * <ul>
- */
- public UrlQuerySanitizer() {
- }
-
- /**
- * Constructs a UrlQuerySanitizer and parse a URL.
- * This constructor is provided for convenience when the
- * default parsing behavior is acceptable.
- * <p>
- * Because the URL is parsed before the constructor returns, there isn't
- * a chance to configure the sanitizer to change the parsing behavior.
- * <p>
- * <code>
- * UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(myUrl);
- * String name = sanitizer.getValue("name");
- * </code>
- * <p>
- * Defaults:
- * <ul>
- * <li>unregistered parameters <em>are</em> allowed.
- * <li>the last instance of a repeated parameter is preferred.
- * <li>The default value sanitizer is an AllIllegal value sanitizer.
- * <ul>
- */
- public UrlQuerySanitizer(String url) {
- setAllowUnregisteredParamaters(true);
- parseUrl(url);
- }
-
- /**
- * Parse the query parameters out of an encoded URL.
- * Works by extracting the query portion from the URL and then
- * calling parseQuery(). If there is no query portion it is
- * treated as if the query portion is an empty string.
- * @param url the encoded URL to parse.
- */
- public void parseUrl(String url) {
- int queryIndex = url.indexOf('?');
- String query;
- if (queryIndex >= 0) {
- query = url.substring(queryIndex + 1);
- }
- else {
- query = "";
- }
- parseQuery(query);
- }
-
- /**
- * Parse a query. A query string is any number of parameter-value clauses
- * separated by any non-zero number of ampersands. A parameter-value clause
- * is a parameter followed by an equal sign, followed by a value. If the
- * equal sign is missing, the value is assumed to be the empty string.
- * @param query the query to parse.
- */
- public void parseQuery(String query) {
- clear();
- // Split by '&'
- StringTokenizer tokenizer = new StringTokenizer(query, "&");
- while(tokenizer.hasMoreElements()) {
- String attributeValuePair = tokenizer.nextToken();
- if (attributeValuePair.length() > 0) {
- int assignmentIndex = attributeValuePair.indexOf('=');
- if (assignmentIndex < 0) {
- // No assignment found, treat as if empty value
- parseEntry(attributeValuePair, "");
- }
- else {
- parseEntry(attributeValuePair.substring(0, assignmentIndex),
- attributeValuePair.substring(assignmentIndex + 1));
- }
- }
- }
- }
-
- /**
- * Get a set of all of the parameters found in the sanitized query.
- * <p>
- * Note: Do not modify this set. Treat it as a read-only set.
- * @return all the parameters found in the current query.
- */
- public Set<String> getParameterSet() {
- return mEntries.keySet();
- }
-
- /**
- * An array list of all of the parameter value pairs in the sanitized
- * query, in the order they appeared in the query. May contain duplicate
- * parameters.
- * <p class="note"><b>Note:</b> Do not modify this list. Treat it as a read-only list.</p>
- */
- public List<ParameterValuePair> getParameterList() {
- return mEntriesList;
- }
-
- /**
- * Check if a parameter exists in the current sanitized query.
- * @param parameter the unencoded name of a parameter.
- * @return true if the paramater exists in the current sanitized queary.
- */
- public boolean hasParameter(String parameter) {
- return mEntries.containsKey(parameter);
- }
-
- /**
- * Get the value for a parameter in the current sanitized query.
- * Returns null if the parameter does not
- * exit.
- * @param parameter the unencoded name of a parameter.
- * @return the sanitized unencoded value of the parameter,
- * or null if the parameter does not exist.
- */
- public String getValue(String parameter) {
- return mEntries.get(parameter);
- }
-
- /**
- * Register a value sanitizer for a particular parameter. Can also be used
- * to replace or remove an already-set value sanitizer.
- * <p>
- * Registering a non-null value sanitizer for a particular parameter
- * makes that parameter a registered parameter.
- * @param parameter an unencoded parameter name
- * @param valueSanitizer the value sanitizer to use for a particular
- * parameter. May be null in order to unregister that parameter.
- * @see #getAllowUnregisteredParamaters()
- */
- public void registerParameter(String parameter,
- ValueSanitizer valueSanitizer) {
- if (valueSanitizer == null) {
- mSanitizers.remove(parameter);
- }
- mSanitizers.put(parameter, valueSanitizer);
- }
-
- /**
- * Register a value sanitizer for an array of parameters.
- * @param parameters An array of unencoded parameter names.
- * @param valueSanitizer
- * @see #registerParameter
- */
- public void registerParameters(String[] parameters,
- ValueSanitizer valueSanitizer) {
- int length = parameters.length;
- for(int i = 0; i < length; i++) {
- mSanitizers.put(parameters[i], valueSanitizer);
- }
- }
-
- /**
- * Set whether or not unregistered parameters are allowed. If they
- * are not allowed, then they will be dropped when a query is sanitized.
- * <p>
- * Defaults to false.
- * @param allowUnregisteredParamaters true to allow unregistered parameters.
- * @see #getAllowUnregisteredParamaters()
- */
- public void setAllowUnregisteredParamaters(
- boolean allowUnregisteredParamaters) {
- mAllowUnregisteredParamaters = allowUnregisteredParamaters;
- }
-
- /**
- * Get whether or not unregistered parameters are allowed. If not
- * allowed, they will be dropped when a query is parsed.
- * @return true if unregistered parameters are allowed.
- * @see #setAllowUnregisteredParamaters(boolean)
- */
- public boolean getAllowUnregisteredParamaters() {
- return mAllowUnregisteredParamaters;
- }
-
- /**
- * Set whether or not the first occurrence of a repeated parameter is
- * preferred. True means the first repeated parameter is preferred.
- * False means that the last repeated parameter is preferred.
- * <p>
- * The preferred parameter is the one that is returned when getParameter
- * is called.
- * <p>
- * defaults to false.
- * @param preferFirstRepeatedParameter True if the first repeated
- * parameter is preferred.
- * @see #getPreferFirstRepeatedParameter()
- */
- public void setPreferFirstRepeatedParameter(
- boolean preferFirstRepeatedParameter) {
- mPreferFirstRepeatedParameter = preferFirstRepeatedParameter;
- }
-
- /**
- * Get whether or not the first occurrence of a repeated parameter is
- * preferred.
- * @return true if the first occurrence of a repeated parameter is
- * preferred.
- * @see #setPreferFirstRepeatedParameter(boolean)
- */
- public boolean getPreferFirstRepeatedParameter() {
- return mPreferFirstRepeatedParameter;
- }
-
- /**
- * Parse an escaped parameter-value pair. The default implementation
- * unescapes both the parameter and the value, then looks up the
- * effective value sanitizer for the parameter and uses it to sanitize
- * the value. If all goes well then addSanitizedValue is called with
- * the unescaped parameter and the sanitized unescaped value.
- * @param parameter an escaped parameter
- * @param value an unsanitzied escaped value
- */
- protected void parseEntry(String parameter, String value) {
- String unescapedParameter = unescape(parameter);
- ValueSanitizer valueSanitizer =
- getEffectiveValueSanitizer(unescapedParameter);
-
- if (valueSanitizer == null) {
- return;
- }
- String unescapedValue = unescape(value);
- String sanitizedValue = valueSanitizer.sanitize(unescapedValue);
- addSanitizedEntry(unescapedParameter, sanitizedValue);
- }
-
- /**
- * Record a sanitized parameter-value pair. Override if you want to
- * do additional filtering or validation.
- * @param parameter an unescaped parameter
- * @param value a sanitized unescaped value
- */
- protected void addSanitizedEntry(String parameter, String value) {
- mEntriesList.add(
- new ParameterValuePair(parameter, value));
- if (mPreferFirstRepeatedParameter) {
- if (mEntries.containsKey(parameter)) {
- return;
- }
- }
- mEntries.put(parameter, value);
- }
-
- /**
- * Get the value sanitizer for a parameter. Returns null if there
- * is no value sanitizer registered for the parameter.
- * @param parameter the unescaped parameter
- * @return the currently registered value sanitizer for this parameter.
- * @see #registerParameter(String, android.net.UrlQuerySanitizer.ValueSanitizer)
- */
- public ValueSanitizer getValueSanitizer(String parameter) {
- return mSanitizers.get(parameter);
- }
-
- /**
- * Get the effective value sanitizer for a parameter. Like getValueSanitizer,
- * except if there is no value sanitizer registered for a parameter, and
- * unregistered paramaters are allowed, then the default value sanitizer is
- * returned.
- * @param parameter an unescaped parameter
- * @return the effective value sanitizer for a parameter.
- */
- public ValueSanitizer getEffectiveValueSanitizer(String parameter) {
- ValueSanitizer sanitizer = getValueSanitizer(parameter);
- if (sanitizer == null && mAllowUnregisteredParamaters) {
- sanitizer = getUnregisteredParameterValueSanitizer();
- }
- return sanitizer;
- }
-
- /**
- * Unescape an escaped string.
- * <ul>
- * <li>'+' characters are replaced by
- * ' ' characters.
- * <li>Valid "%xx" escape sequences are replaced by the
- * corresponding unescaped character.
- * <li>Invalid escape sequences such as %1z", are passed through unchanged.
- * <ol>
- * @param string the escaped string
- * @return the unescaped string.
- */
- public String unescape(String string) {
- // Early exit if no escaped characters.
- int firstEscape = string.indexOf('%');
- if ( firstEscape < 0) {
- firstEscape = string.indexOf('+');
- if (firstEscape < 0) {
- return string;
- }
- }
-
- int length = string.length();
-
- StringBuilder stringBuilder = new StringBuilder(length);
- stringBuilder.append(string.substring(0, firstEscape));
- for (int i = firstEscape; i < length; i++) {
- char c = string.charAt(i);
- if (c == '+') {
- c = ' ';
- }
- else if ( c == '%' && i + 2 < length) {
- char c1 = string.charAt(i + 1);
- char c2 = string.charAt(i + 2);
- if (isHexDigit(c1) && isHexDigit(c2)) {
- c = (char) (decodeHexDigit(c1) * 16 + decodeHexDigit(c2));
- i += 2;
- }
- }
- stringBuilder.append(c);
- }
- return stringBuilder.toString();
- }
-
- /**
- * Test if a character is a hexidecimal digit. Both upper case and lower
- * case hex digits are allowed.
- * @param c the character to test
- * @return true if c is a hex digit.
- */
- protected boolean isHexDigit(char c) {
- return decodeHexDigit(c) >= 0;
- }
-
- /**
- * Convert a character that represents a hexidecimal digit into an integer.
- * If the character is not a hexidecimal digit, then -1 is returned.
- * Both upper case and lower case hex digits are allowed.
- * @param c the hexidecimal digit.
- * @return the integer value of the hexidecimal digit.
- */
-
- protected int decodeHexDigit(char c) {
- if (c >= '0' && c <= '9') {
- return c - '0';
- }
- else if (c >= 'A' && c <= 'F') {
- return c - 'A' + 10;
- }
- else if (c >= 'a' && c <= 'f') {
- return c - 'a' + 10;
- }
- else {
- return -1;
- }
- }
-
- /**
- * Clear the existing entries. Called to get ready to parse a new
- * query string.
- */
- protected void clear() {
- mEntries.clear();
- mEntriesList.clear();
- }
-}
-
diff --git a/core/java/android/net/WebAddress.java b/core/java/android/net/WebAddress.java
deleted file mode 100644
index f4a2a6a9430..00000000000
--- a/core/java/android/net/WebAddress.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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 android.net;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * {@hide}
- *
- * Web Address Parser
- *
- * This is called WebAddress, rather than URL or URI, because it
- * attempts to parse the stuff that a user will actually type into a
- * browser address widget.
- *
- * Unlike java.net.uri, this parser will not choke on URIs missing
- * schemes. It will only throw a ParseException if the input is
- * really hosed.
- *
- * If given an https scheme but no port, fills in port
- *
- */
-public class WebAddress {
-
- private final static String LOGTAG = "http";
-
- public String mScheme;
- public String mHost;
- public int mPort;
- public String mPath;
- public String mAuthInfo;
-
- static final int MATCH_GROUP_SCHEME = 1;
- static final int MATCH_GROUP_AUTHORITY = 2;
- static final int MATCH_GROUP_HOST = 3;
- static final int MATCH_GROUP_PORT = 4;
- static final int MATCH_GROUP_PATH = 5;
-
- static Pattern sAddressPattern = Pattern.compile(
- /* scheme */ "(?:(http|HTTP|https|HTTPS|file|FILE)\\:\\/\\/)?" +
- /* authority */ "(?:([-A-Za-z0-9$_.+!*'(),;?&=]+(?:\\:[-A-Za-z0-9$_.+!*'(),;?&=]+)?)@)?" +
- /* host */ "([-A-Za-z0-9%]+(?:\\.[-A-Za-z0-9%]+)*)?" +
- /* port */ "(?:\\:([0-9]+))?" +
- /* path */ "(\\/?.*)?");
-
- /** parses given uriString. */
- public WebAddress(String address) throws ParseException {
- if (address == null) {
- throw new NullPointerException();
- }
-
- // android.util.Log.d(LOGTAG, "WebAddress: " + address);
-
- mScheme = "";
- mHost = "";
- mPort = -1;
- mPath = "/";
- mAuthInfo = "";
-
- Matcher m = sAddressPattern.matcher(address);
- String t;
- if (m.matches()) {
- t = m.group(MATCH_GROUP_SCHEME);
- if (t != null) mScheme = t;
- t = m.group(MATCH_GROUP_AUTHORITY);
- if (t != null) mAuthInfo = t;
- t = m.group(MATCH_GROUP_HOST);
- if (t != null) mHost = t;
- t = m.group(MATCH_GROUP_PORT);
- if (t != null) {
- try {
- mPort = Integer.parseInt(t);
- } catch (NumberFormatException ex) {
- throw new ParseException("Bad port");
- }
- }
- t = m.group(MATCH_GROUP_PATH);
- if (t != null && t.length() > 0) {
- /* handle busted myspace frontpage redirect with
- missing initial "/" */
- if (t.charAt(0) == '/') {
- mPath = t;
- } else {
- mPath = "/" + t;
- }
- }
-
- } else {
- // nothing found... outa here
- throw new ParseException("Bad address");
- }
-
- /* Get port from scheme or scheme from port, if necessary and
- possible */
- if (mPort == 443 && mScheme.equals("")) {
- mScheme = "https";
- } else if (mPort == -1) {
- if (mScheme.equals("https"))
- mPort = 443;
- else
- mPort = 80; // default
- }
- if (mScheme.equals("")) mScheme = "http";
- }
-
- public String toString() {
- String port = "";
- if ((mPort != 443 && mScheme.equals("https")) ||
- (mPort != 80 && mScheme.equals("http"))) {
- port = ":" + Integer.toString(mPort);
- }
- String authInfo = "";
- if (mAuthInfo.length() > 0) {
- authInfo = mAuthInfo + "@";
- }
-
- return mScheme + "://" + authInfo + mHost + port + mPath;
- }
-}
diff --git a/core/java/android/net/http/AndroidHttpClient.java b/core/java/android/net/http/AndroidHttpClient.java
deleted file mode 100644
index 4fb14991d9f..00000000000
--- a/core/java/android/net/http/AndroidHttpClient.java
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net.http;
-
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpException;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpRequestInterceptor;
-import org.apache.http.HttpResponse;
-import org.apache.http.entity.AbstractHttpEntity;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.protocol.ClientContext;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.params.HttpClientParams;
-import org.apache.http.conn.ClientConnectionManager;
-import org.apache.http.conn.scheme.PlainSocketFactory;
-import org.apache.http.conn.scheme.Scheme;
-import org.apache.http.conn.scheme.SchemeRegistry;
-import org.apache.http.conn.ssl.SSLSocketFactory;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.client.RequestWrapper;
-import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpProtocolParams;
-import org.apache.http.protocol.BasicHttpProcessor;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.BasicHttpContext;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStream;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.GZIPOutputStream;
-import java.net.URI;
-
-import android.util.Log;
-import android.content.ContentResolver;
-import android.provider.Settings;
-import android.text.TextUtils;
-
-/**
- * Subclass of the Apache {@link DefaultHttpClient} that is configured with
- * reasonable default settings and registered schemes for Android, and
- * also lets the user add {@link HttpRequestInterceptor} classes.
- * Don't create this directly, use the {@link #newInstance} factory method.
- *
- * <p>This client processes cookies but does not retain them by default.
- * To retain cookies, simply add a cookie store to the HttpContext:</p>
- *
- * <pre>context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);</pre>
- *
- * {@hide}
- */
-public final class AndroidHttpClient implements HttpClient {
-
- // Gzip of data shorter than this probably won't be worthwhile
- public static long DEFAULT_SYNC_MIN_GZIP_BYTES = 256;
-
- private static final String TAG = "AndroidHttpClient";
-
-
- /** Set if HTTP requests are blocked from being executed on this thread */
- private static final ThreadLocal<Boolean> sThreadBlocked =
- new ThreadLocal<Boolean>();
-
- /** Interceptor throws an exception if the executing thread is blocked */
- private static final HttpRequestInterceptor sThreadCheckInterceptor =
- new HttpRequestInterceptor() {
- public void process(HttpRequest request, HttpContext context) {
- if (sThreadBlocked.get() != null && sThreadBlocked.get()) {
- throw new RuntimeException("This thread forbids HTTP requests");
- }
- }
- };
-
- /**
- * Create a new HttpClient with reasonable defaults (which you can update).
- * @param userAgent to report in your HTTP requests.
- * @return AndroidHttpClient for you to use for all your requests.
- */
- public static AndroidHttpClient newInstance(String userAgent) {
- HttpParams params = new BasicHttpParams();
-
- // Turn off stale checking. Our connections break all the time anyway,
- // and it's not worth it to pay the penalty of checking every time.
- HttpConnectionParams.setStaleCheckingEnabled(params, false);
-
- // Default connection and socket timeout of 20 seconds. Tweak to taste.
- HttpConnectionParams.setConnectionTimeout(params, 20 * 1000);
- HttpConnectionParams.setSoTimeout(params, 20 * 1000);
- HttpConnectionParams.setSocketBufferSize(params, 8192);
-
- // Don't handle redirects -- return them to the caller. Our code
- // often wants to re-POST after a redirect, which we must do ourselves.
- HttpClientParams.setRedirecting(params, false);
-
- // Set the specified user agent and register standard protocols.
- HttpProtocolParams.setUserAgent(params, userAgent);
- SchemeRegistry schemeRegistry = new SchemeRegistry();
- schemeRegistry.register(new Scheme("http",
- PlainSocketFactory.getSocketFactory(), 80));
- schemeRegistry.register(new Scheme("https",
- SSLSocketFactory.getSocketFactory(), 443));
- ClientConnectionManager manager =
- new ThreadSafeClientConnManager(params, schemeRegistry);
-
- // We use a factory method to modify superclass initialization
- // parameters without the funny call-a-static-method dance.
- return new AndroidHttpClient(manager, params);
- }
-
- private final HttpClient delegate;
-
- private RuntimeException mLeakedException = new IllegalStateException(
- "AndroidHttpClient created and never closed");
-
- private AndroidHttpClient(ClientConnectionManager ccm, HttpParams params) {
- this.delegate = new DefaultHttpClient(ccm, params) {
- @Override
- protected BasicHttpProcessor createHttpProcessor() {
- // Add interceptor to prevent making requests from main thread.
- BasicHttpProcessor processor = super.createHttpProcessor();
- processor.addRequestInterceptor(sThreadCheckInterceptor);
- processor.addRequestInterceptor(new CurlLogger());
-
- return processor;
- }
-
- @Override
- protected HttpContext createHttpContext() {
- // Same as DefaultHttpClient.createHttpContext() minus the
- // cookie store.
- HttpContext context = new BasicHttpContext();
- context.setAttribute(
- ClientContext.AUTHSCHEME_REGISTRY,
- getAuthSchemes());
- context.setAttribute(
- ClientContext.COOKIESPEC_REGISTRY,
- getCookieSpecs());
- context.setAttribute(
- ClientContext.CREDS_PROVIDER,
- getCredentialsProvider());
- return context;
- }
- };
- }
-
- @Override
- protected void finalize() throws Throwable {
- super.finalize();
- if (mLeakedException != null) {
- Log.e(TAG, "Leak found", mLeakedException);
- mLeakedException = null;
- }
- }
-
- /**
- * Block this thread from executing HTTP requests.
- * Used to guard against HTTP requests blocking the main application thread.
- * @param blocked if HTTP requests run on this thread should be denied
- */
- public static void setThreadBlocked(boolean blocked) {
- sThreadBlocked.set(blocked);
- }
-
- /**
- * Modifies a request to indicate to the server that we would like a
- * gzipped response. (Uses the "Accept-Encoding" HTTP header.)
- * @param request the request to modify
- * @see #getUngzippedContent
- */
- public static void modifyRequestToAcceptGzipResponse(HttpRequest request) {
- request.addHeader("Accept-Encoding", "gzip");
- }
-
- /**
- * Gets the input stream from a response entity. If the entity is gzipped
- * then this will get a stream over the uncompressed data.
- *
- * @param entity the entity whose content should be read
- * @return the input stream to read from
- * @throws IOException
- */
- public static InputStream getUngzippedContent(HttpEntity entity)
- throws IOException {
- InputStream responseStream = entity.getContent();
- if (responseStream == null) return responseStream;
- Header header = entity.getContentEncoding();
- if (header == null) return responseStream;
- String contentEncoding = header.getValue();
- if (contentEncoding == null) return responseStream;
- if (contentEncoding.contains("gzip")) responseStream
- = new GZIPInputStream(responseStream);
- return responseStream;
- }
-
- /**
- * Release resources associated with this client. You must call this,
- * or significant resources (sockets and memory) may be leaked.
- */
- public void close() {
- if (mLeakedException != null) {
- getConnectionManager().shutdown();
- mLeakedException = null;
- }
- }
-
- public HttpParams getParams() {
- return delegate.getParams();
- }
-
- public ClientConnectionManager getConnectionManager() {
- return delegate.getConnectionManager();
- }
-
- public HttpResponse execute(HttpUriRequest request) throws IOException {
- return delegate.execute(request);
- }
-
- public HttpResponse execute(HttpUriRequest request, HttpContext context)
- throws IOException {
- return delegate.execute(request, context);
- }
-
- public HttpResponse execute(HttpHost target, HttpRequest request)
- throws IOException {
- return delegate.execute(target, request);
- }
-
- public HttpResponse execute(HttpHost target, HttpRequest request,
- HttpContext context) throws IOException {
- return delegate.execute(target, request, context);
- }
-
- public <T> T execute(HttpUriRequest request,
- ResponseHandler<? extends T> responseHandler)
- throws IOException, ClientProtocolException {
- return delegate.execute(request, responseHandler);
- }
-
- public <T> T execute(HttpUriRequest request,
- ResponseHandler<? extends T> responseHandler, HttpContext context)
- throws IOException, ClientProtocolException {
- return delegate.execute(request, responseHandler, context);
- }
-
- public <T> T execute(HttpHost target, HttpRequest request,
- ResponseHandler<? extends T> responseHandler) throws IOException,
- ClientProtocolException {
- return delegate.execute(target, request, responseHandler);
- }
-
- public <T> T execute(HttpHost target, HttpRequest request,
- ResponseHandler<? extends T> responseHandler, HttpContext context)
- throws IOException, ClientProtocolException {
- return delegate.execute(target, request, responseHandler, context);
- }
-
- /**
- * Compress data to send to server.
- * Creates a Http Entity holding the gzipped data.
- * The data will not be compressed if it is too short.
- * @param data The bytes to compress
- * @return Entity holding the data
- */
- public static AbstractHttpEntity getCompressedEntity(byte data[], ContentResolver resolver)
- throws IOException {
- AbstractHttpEntity entity;
- if (data.length < getMinGzipSize(resolver)) {
- entity = new ByteArrayEntity(data);
- } else {
- ByteArrayOutputStream arr = new ByteArrayOutputStream();
- OutputStream zipper = new GZIPOutputStream(arr);
- zipper.write(data);
- zipper.close();
- entity = new ByteArrayEntity(arr.toByteArray());
- entity.setContentEncoding("gzip");
- }
- return entity;
- }
-
- /**
- * Retrieves the minimum size for compressing data.
- * Shorter data will not be compressed.
- */
- public static long getMinGzipSize(ContentResolver resolver) {
- String sMinGzipBytes = Settings.Gservices.getString(resolver,
- Settings.Gservices.SYNC_MIN_GZIP_BYTES);
-
- if (!TextUtils.isEmpty(sMinGzipBytes)) {
- try {
- return Long.parseLong(sMinGzipBytes);
- } catch (NumberFormatException nfe) {
- Log.w(TAG, "Unable to parse " +
- Settings.Gservices.SYNC_MIN_GZIP_BYTES + " " +
- sMinGzipBytes, nfe);
- }
- }
- return DEFAULT_SYNC_MIN_GZIP_BYTES;
- }
-
- /* cURL logging support. */
-
- /**
- * Logging tag and level.
- */
- private static class LoggingConfiguration {
-
- private final String tag;
- private final int level;
-
- private LoggingConfiguration(String tag, int level) {
- this.tag = tag;
- this.level = level;
- }
-
- /**
- * Returns true if logging is turned on for this configuration.
- */
- private boolean isLoggable() {
- return Log.isLoggable(tag, level);
- }
-
- /**
- * Returns true if auth logging is turned on for this configuration.
- */
- private boolean isAuthLoggable() {
- return Log.isLoggable(tag + "-auth", level);
- }
-
- /**
- * Prints a message using this configuration.
- */
- private void println(String message) {
- Log.println(level, tag, message);
- }
- }
-
- /** cURL logging configuration. */
- private volatile LoggingConfiguration curlConfiguration;
-
- /**
- * Enables cURL request logging for this client.
- *
- * @param name to log messages with
- * @param level at which to log messages (see {@link android.util.Log})
- */
- public void enableCurlLogging(String name, int level) {
- if (name == null) {
- throw new NullPointerException("name");
- }
- if (level < Log.VERBOSE || level > Log.ASSERT) {
- throw new IllegalArgumentException("Level is out of range ["
- + Log.VERBOSE + ".." + Log.ASSERT + "]");
- }
-
- curlConfiguration = new LoggingConfiguration(name, level);
- }
-
- /**
- * Disables cURL logging for this client.
- */
- public void disableCurlLogging() {
- curlConfiguration = null;
- }
-
- /**
- * Logs cURL commands equivalent to requests.
- */
- private class CurlLogger implements HttpRequestInterceptor {
- public void process(HttpRequest request, HttpContext context)
- throws HttpException, IOException {
- LoggingConfiguration configuration = curlConfiguration;
- if (configuration != null
- && configuration.isLoggable()
- && request instanceof HttpUriRequest) {
- configuration.println(toCurl((HttpUriRequest) request,
- configuration.isAuthLoggable()));
- }
- }
- }
-
- /**
- * Generates a cURL command equivalent to the given request.
- */
- private static String toCurl(HttpUriRequest request, boolean logAuthToken) throws IOException {
- StringBuilder builder = new StringBuilder();
-
- builder.append("curl ");
-
- for (Header header: request.getAllHeaders()) {
- if (!logAuthToken
- && (header.getName().equals("Authorization") ||
- header.getName().equals("Cookie"))) {
- continue;
- }
- builder.append("--header \"");
- builder.append(header.toString().trim());
- builder.append("\" ");
- }
-
- URI uri = request.getURI();
-
- // If this is a wrapped request, use the URI from the original
- // request instead. getURI() on the wrapper seems to return a
- // relative URI. We want an absolute URI.
- if (request instanceof RequestWrapper) {
- HttpRequest original = ((RequestWrapper) request).getOriginal();
- if (original instanceof HttpUriRequest) {
- uri = ((HttpUriRequest) original).getURI();
- }
- }
-
- builder.append("\"");
- builder.append(uri);
- builder.append("\"");
-
- if (request instanceof HttpEntityEnclosingRequest) {
- HttpEntityEnclosingRequest entityRequest =
- (HttpEntityEnclosingRequest) request;
- HttpEntity entity = entityRequest.getEntity();
- if (entity != null && entity.isRepeatable()) {
- if (entity.getContentLength() < 1024) {
- ByteArrayOutputStream stream = new ByteArrayOutputStream();
- entity.writeTo(stream);
- String entityString = stream.toString();
-
- // TODO: Check the content type, too.
- builder.append(" --data-ascii \"")
- .append(entityString)
- .append("\"");
- } else {
- builder.append(" [TOO MUCH DATA TO INCLUDE]");
- }
- }
- }
-
- return builder.toString();
- }
-}
diff --git a/core/java/android/net/http/AndroidHttpClientConnection.java b/core/java/android/net/http/AndroidHttpClientConnection.java
deleted file mode 100644
index eb96679a3d3..00000000000
--- a/core/java/android/net/http/AndroidHttpClientConnection.java
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net.http;
-
-import org.apache.http.Header;
-
-import org.apache.http.HttpConnection;
-import org.apache.http.HttpClientConnection;
-import org.apache.http.HttpConnectionMetrics;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpException;
-import org.apache.http.HttpInetConnection;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseFactory;
-import org.apache.http.NoHttpResponseException;
-import org.apache.http.StatusLine;
-import org.apache.http.entity.BasicHttpEntity;
-import org.apache.http.entity.ContentLengthStrategy;
-import org.apache.http.impl.DefaultHttpResponseFactory;
-import org.apache.http.impl.HttpConnectionMetricsImpl;
-import org.apache.http.impl.entity.EntitySerializer;
-import org.apache.http.impl.entity.StrictContentLengthStrategy;
-import org.apache.http.impl.io.ChunkedInputStream;
-import org.apache.http.impl.io.ContentLengthInputStream;
-import org.apache.http.impl.io.HttpRequestWriter;
-import org.apache.http.impl.io.IdentityInputStream;
-import org.apache.http.impl.io.SocketInputBuffer;
-import org.apache.http.impl.io.SocketOutputBuffer;
-import org.apache.http.io.HttpMessageWriter;
-import org.apache.http.io.SessionInputBuffer;
-import org.apache.http.io.SessionOutputBuffer;
-import org.apache.http.message.BasicLineParser;
-import org.apache.http.message.ParserCursor;
-import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpConnectionParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.ParseException;
-import org.apache.http.util.CharArrayBuffer;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.net.SocketException;
-
-/**
- * A alternate class for (@link DefaultHttpClientConnection).
- * It has better performance than DefaultHttpClientConnection
- *
- * {@hide}
- */
-public class AndroidHttpClientConnection
- implements HttpInetConnection, HttpConnection {
-
- private SessionInputBuffer inbuffer = null;
- private SessionOutputBuffer outbuffer = null;
- private int maxHeaderCount;
- // store CoreConnectionPNames.MAX_LINE_LENGTH for performance
- private int maxLineLength;
-
- private final EntitySerializer entityserializer;
-
- private HttpMessageWriter requestWriter = null;
- private HttpConnectionMetricsImpl metrics = null;
- private volatile boolean open;
- private Socket socket = null;
-
- public AndroidHttpClientConnection() {
- this.entityserializer = new EntitySerializer(
- new StrictContentLengthStrategy());
- }
-
- /**
- * Bind socket and set HttpParams to AndroidHttpClientConnection
- * @param socket outgoing socket
- * @param params HttpParams
- * @throws IOException
- */
- public void bind(
- final Socket socket,
- final HttpParams params) throws IOException {
- if (socket == null) {
- throw new IllegalArgumentException("Socket may not be null");
- }
- if (params == null) {
- throw new IllegalArgumentException("HTTP parameters may not be null");
- }
- assertNotOpen();
- socket.setTcpNoDelay(HttpConnectionParams.getTcpNoDelay(params));
- socket.setSoTimeout(HttpConnectionParams.getSoTimeout(params));
-
- int linger = HttpConnectionParams.getLinger(params);
- if (linger >= 0) {
- socket.setSoLinger(linger > 0, linger);
- }
- this.socket = socket;
-
- int buffersize = HttpConnectionParams.getSocketBufferSize(params);
- this.inbuffer = new SocketInputBuffer(socket, buffersize, params);
- this.outbuffer = new SocketOutputBuffer(socket, buffersize, params);
-
- maxHeaderCount = params.getIntParameter(
- CoreConnectionPNames.MAX_HEADER_COUNT, -1);
- maxLineLength = params.getIntParameter(
- CoreConnectionPNames.MAX_LINE_LENGTH, -1);
-
- this.requestWriter = new HttpRequestWriter(outbuffer, null, params);
-
- this.metrics = new HttpConnectionMetricsImpl(
- inbuffer.getMetrics(),
- outbuffer.getMetrics());
-
- this.open = true;
- }
-
- @Override
- public String toString() {
- StringBuilder buffer = new StringBuilder();
- buffer.append(getClass().getSimpleName()).append("[");
- if (isOpen()) {
- buffer.append(getRemotePort());
- } else {
- buffer.append("closed");
- }
- buffer.append("]");
- return buffer.toString();
- }
-
-
- private void assertNotOpen() {
- if (this.open) {
- throw new IllegalStateException("Connection is already open");
- }
- }
-
- private void assertOpen() {
- if (!this.open) {
- throw new IllegalStateException("Connection is not open");
- }
- }
-
- public boolean isOpen() {
- // to make this method useful, we want to check if the socket is connected
- return (this.open && this.socket != null && this.socket.isConnected());
- }
-
- public InetAddress getLocalAddress() {
- if (this.socket != null) {
- return this.socket.getLocalAddress();
- } else {
- return null;
- }
- }
-
- public int getLocalPort() {
- if (this.socket != null) {
- return this.socket.getLocalPort();
- } else {
- return -1;
- }
- }
-
- public InetAddress getRemoteAddress() {
- if (this.socket != null) {
- return this.socket.getInetAddress();
- } else {
- return null;
- }
- }
-
- public int getRemotePort() {
- if (this.socket != null) {
- return this.socket.getPort();
- } else {
- return -1;
- }
- }
-
- public void setSocketTimeout(int timeout) {
- assertOpen();
- if (this.socket != null) {
- try {
- this.socket.setSoTimeout(timeout);
- } catch (SocketException ignore) {
- // It is not quite clear from the original documentation if there are any
- // other legitimate cases for a socket exception to be thrown when setting
- // SO_TIMEOUT besides the socket being already closed
- }
- }
- }
-
- public int getSocketTimeout() {
- if (this.socket != null) {
- try {
- return this.socket.getSoTimeout();
- } catch (SocketException ignore) {
- return -1;
- }
- } else {
- return -1;
- }
- }
-
- public void shutdown() throws IOException {
- this.open = false;
- Socket tmpsocket = this.socket;
- if (tmpsocket != null) {
- tmpsocket.close();
- }
- }
-
- public void close() throws IOException {
- if (!this.open) {
- return;
- }
- this.open = false;
- doFlush();
- try {
- try {
- this.socket.shutdownOutput();
- } catch (IOException ignore) {
- }
- try {
- this.socket.shutdownInput();
- } catch (IOException ignore) {
- }
- } catch (UnsupportedOperationException ignore) {
- // if one isn't supported, the other one isn't either
- }
- this.socket.close();
- }
-
- /**
- * Sends the request line and all headers over the connection.
- * @param request the request whose headers to send.
- * @throws HttpException
- * @throws IOException
- */
- public void sendRequestHeader(final HttpRequest request)
- throws HttpException, IOException {
- if (request == null) {
- throw new IllegalArgumentException("HTTP request may not be null");
- }
- assertOpen();
- this.requestWriter.write(request);
- this.metrics.incrementRequestCount();
- }
-
- /**
- * Sends the request entity over the connection.
- * @param request the request whose entity to send.
- * @throws HttpException
- * @throws IOException
- */
- public void sendRequestEntity(final HttpEntityEnclosingRequest request)
- throws HttpException, IOException {
- if (request == null) {
- throw new IllegalArgumentException("HTTP request may not be null");
- }
- assertOpen();
- if (request.getEntity() == null) {
- return;
- }
- this.entityserializer.serialize(
- this.outbuffer,
- request,
- request.getEntity());
- }
-
- protected void doFlush() throws IOException {
- this.outbuffer.flush();
- }
-
- public void flush() throws IOException {
- assertOpen();
- doFlush();
- }
-
- /**
- * Parses the response headers and adds them to the
- * given {@code headers} object, and returns the response StatusLine
- * @param headers store parsed header to headers.
- * @throws IOException
- * @return StatusLine
- * @see HttpClientConnection#receiveResponseHeader()
- */
- public StatusLine parseResponseHeader(Headers headers)
- throws IOException, ParseException {
- assertOpen();
-
- CharArrayBuffer current = new CharArrayBuffer(64);
-
- if (inbuffer.readLine(current) == -1) {
- throw new NoHttpResponseException("The target server failed to respond");
- }
-
- // Create the status line from the status string
- StatusLine statusline = BasicLineParser.DEFAULT.parseStatusLine(
- current, new ParserCursor(0, current.length()));
-
- if (HttpLog.LOGV) HttpLog.v("read: " + statusline);
- int statusCode = statusline.getStatusCode();
-
- // Parse header body
- CharArrayBuffer previous = null;
- int headerNumber = 0;
- while(true) {
- if (current == null) {
- current = new CharArrayBuffer(64);
- } else {
- // This must be he buffer used to parse the status
- current.clear();
- }
- int l = inbuffer.readLine(current);
- if (l == -1 || current.length() < 1) {
- break;
- }
- // Parse the header name and value
- // Check for folded headers first
- // Detect LWS-char see HTTP/1.0 or HTTP/1.1 Section 2.2
- // discussion on folded headers
- char first = current.charAt(0);
- if ((first == ' ' || first == '\t') && previous != null) {
- // we have continuation folded header
- // so append value
- int start = 0;
- int length = current.length();
- while (start < length) {
- char ch = current.charAt(start);
- if (ch != ' ' && ch != '\t') {
- break;
- }
- start++;
- }
- if (maxLineLength > 0 &&
- previous.length() + 1 + current.length() - start >
- maxLineLength) {
- throw new IOException("Maximum line length limit exceeded");
- }
- previous.append(' ');
- previous.append(current, start, current.length() - start);
- } else {
- if (previous != null) {
- headers.parseHeader(previous);
- }
- headerNumber++;
- previous = current;
- current = null;
- }
- if (maxHeaderCount > 0 && headerNumber >= maxHeaderCount) {
- throw new IOException("Maximum header count exceeded");
- }
- }
-
- if (previous != null) {
- headers.parseHeader(previous);
- }
-
- if (statusCode >= 200) {
- this.metrics.incrementResponseCount();
- }
- return statusline;
- }
-
- /**
- * Return the next response entity.
- * @param headers contains values for parsing entity
- * @see HttpClientConnection#receiveResponseEntity(HttpResponse response)
- */
- public HttpEntity receiveResponseEntity(final Headers headers) {
- assertOpen();
- BasicHttpEntity entity = new BasicHttpEntity();
-
- long len = determineLength(headers);
- if (len == ContentLengthStrategy.CHUNKED) {
- entity.setChunked(true);
- entity.setContentLength(-1);
- entity.setContent(new ChunkedInputStream(inbuffer));
- } else if (len == ContentLengthStrategy.IDENTITY) {
- entity.setChunked(false);
- entity.setContentLength(-1);
- entity.setContent(new IdentityInputStream(inbuffer));
- } else {
- entity.setChunked(false);
- entity.setContentLength(len);
- entity.setContent(new ContentLengthInputStream(inbuffer, len));
- }
-
- String contentTypeHeader = headers.getContentType();
- if (contentTypeHeader != null) {
- entity.setContentType(contentTypeHeader);
- }
- String contentEncodingHeader = headers.getContentEncoding();
- if (contentEncodingHeader != null) {
- entity.setContentEncoding(contentEncodingHeader);
- }
-
- return entity;
- }
-
- private long determineLength(final Headers headers) {
- long transferEncoding = headers.getTransferEncoding();
- // We use Transfer-Encoding if present and ignore Content-Length.
- // RFC2616, 4.4 item number 3
- if (transferEncoding < Headers.NO_TRANSFER_ENCODING) {
- return transferEncoding;
- } else {
- long contentlen = headers.getContentLength();
- if (contentlen > Headers.NO_CONTENT_LENGTH) {
- return contentlen;
- } else {
- return ContentLengthStrategy.IDENTITY;
- }
- }
- }
-
- /**
- * Checks whether this connection has gone down.
- * Network connections may get closed during some time of inactivity
- * for several reasons. The next time a read is attempted on such a
- * connection it will throw an IOException.
- * This method tries to alleviate this inconvenience by trying to
- * find out if a connection is still usable. Implementations may do
- * that by attempting a read with a very small timeout. Thus this
- * method may block for a small amount of time before returning a result.
- * It is therefore an <i>expensive</i> operation.
- *
- * @return <code>true</code> if attempts to use this connection are
- * likely to succeed, or <code>false</code> if they are likely
- * to fail and this connection should be closed
- */
- public boolean isStale() {
- assertOpen();
- try {
- this.inbuffer.isDataAvailable(1);
- return false;
- } catch (IOException ex) {
- return true;
- }
- }
-
- /**
- * Returns a collection of connection metrcis
- * @return HttpConnectionMetrics
- */
- public HttpConnectionMetrics getMetrics() {
- return this.metrics;
- }
-}
diff --git a/core/java/android/net/http/CertificateChainValidator.java b/core/java/android/net/http/CertificateChainValidator.java
deleted file mode 100644
index b7f7368ae24..00000000000
--- a/core/java/android/net/http/CertificateChainValidator.java
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net.http;
-
-import android.os.SystemClock;
-
-import java.io.IOException;
-
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateExpiredException;
-import java.security.cert.CertificateNotYetValidException;
-import java.security.cert.X509Certificate;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-
-import java.util.Arrays;
-import java.util.Date;
-import java.util.Enumeration;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
-import org.apache.http.HttpHost;
-
-import org.bouncycastle.asn1.x509.X509Name;
-
-/**
- * Class responsible for all server certificate validation functionality
- *
- * {@hide}
- */
-class CertificateChainValidator {
-
- private static long sTotal = 0;
- private static long sTotalReused = 0;
-
- /**
- * The singleton instance of the certificate chain validator
- */
- private static CertificateChainValidator sInstance;
-
- /**
- * Default trust manager (used to perform CA certificate validation)
- */
- private X509TrustManager mDefaultTrustManager;
-
- /**
- * @return The singleton instance of the certificator chain validator
- */
- public static CertificateChainValidator getInstance() {
- if (sInstance == null) {
- sInstance = new CertificateChainValidator();
- }
-
- return sInstance;
- }
-
- /**
- * Creates a new certificate chain validator. This is a pivate constructor.
- * If you need a Certificate chain validator, call getInstance().
- */
- private CertificateChainValidator() {
- try {
- TrustManagerFactory trustManagerFactory
- = TrustManagerFactory.getInstance("X509");
- trustManagerFactory.init((KeyStore)null);
- TrustManager[] trustManagers =
- trustManagerFactory.getTrustManagers();
- if (trustManagers != null && trustManagers.length > 0) {
- for (TrustManager trustManager : trustManagers) {
- if (trustManager instanceof X509TrustManager) {
- mDefaultTrustManager = (X509TrustManager)(trustManager);
- break;
- }
- }
- }
- } catch (Exception exc) {
- if (HttpLog.LOGV) {
- HttpLog.v("CertificateChainValidator():" +
- " failed to initialize the trust manager");
- }
- }
- }
-
- /**
- * Performs the handshake and server certificates validation
- * @param sslSocket The secure connection socket
- * @param domain The website domain
- * @return An SSL error object if there is an error and null otherwise
- */
- public SslError doHandshakeAndValidateServerCertificates(
- HttpsConnection connection, SSLSocket sslSocket, String domain)
- throws SSLHandshakeException, IOException {
-
- ++sTotal;
-
- SSLContext sslContext = HttpsConnection.getContext();
- if (sslContext == null) {
- closeSocketThrowException(sslSocket, "SSL context is null");
- }
-
- X509Certificate[] serverCertificates = null;
-
- long sessionBeforeHandshakeLastAccessedTime = 0;
- byte[] sessionBeforeHandshakeId = null;
-
- SSLSession sessionAfterHandshake = null;
-
- synchronized(sslContext) {
- // get SSL session before the handshake
- SSLSession sessionBeforeHandshake =
- getSSLSession(sslContext, connection.getHost());
- if (sessionBeforeHandshake != null) {
- sessionBeforeHandshakeLastAccessedTime =
- sessionBeforeHandshake.getLastAccessedTime();
-
- sessionBeforeHandshakeId =
- sessionBeforeHandshake.getId();
- }
-
- // start handshake, close the socket if we fail
- try {
- sslSocket.setUseClientMode(true);
- sslSocket.startHandshake();
- } catch (IOException e) {
- closeSocketThrowException(
- sslSocket, e.getMessage(),
- "failed to perform SSL handshake");
- }
-
- // retrieve the chain of the server peer certificates
- Certificate[] peerCertificates =
- sslSocket.getSession().getPeerCertificates();
-
- if (peerCertificates == null || peerCertificates.length <= 0) {
- closeSocketThrowException(
- sslSocket, "failed to retrieve peer certificates");
- } else {
- serverCertificates =
- new X509Certificate[peerCertificates.length];
- for (int i = 0; i < peerCertificates.length; ++i) {
- serverCertificates[i] =
- (X509Certificate)(peerCertificates[i]);
- }
-
- // update the SSL certificate associated with the connection
- if (connection != null) {
- if (serverCertificates[0] != null) {
- connection.setCertificate(
- new SslCertificate(serverCertificates[0]));
- }
- }
- }
-
- // get SSL session after the handshake
- sessionAfterHandshake =
- getSSLSession(sslContext, connection.getHost());
- }
-
- if (sessionBeforeHandshakeLastAccessedTime != 0 &&
- sessionAfterHandshake != null &&
- Arrays.equals(
- sessionBeforeHandshakeId, sessionAfterHandshake.getId()) &&
- sessionBeforeHandshakeLastAccessedTime <
- sessionAfterHandshake.getLastAccessedTime()) {
-
- if (HttpLog.LOGV) {
- HttpLog.v("SSL session was reused: total reused: "
- + sTotalReused
- + " out of total of: " + sTotal);
-
- ++sTotalReused;
- }
-
- // no errors!!!
- return null;
- }
-
- // check if the first certificate in the chain is for this site
- X509Certificate currCertificate = serverCertificates[0];
- if (currCertificate == null) {
- closeSocketThrowException(
- sslSocket, "certificate for this site is null");
- } else {
- if (!DomainNameChecker.match(currCertificate, domain)) {
- String errorMessage = "certificate not for this host: " + domain;
-
- if (HttpLog.LOGV) {
- HttpLog.v(errorMessage);
- }
-
- sslSocket.getSession().invalidate();
- return new SslError(
- SslError.SSL_IDMISMATCH, currCertificate);
- }
- }
-
- //
- // first, we validate the chain using the standard validation
- // solution; if we do not find any errors, we are done; if we
- // fail the standard validation, we re-validate again below,
- // this time trying to retrieve any individual errors we can
- // report back to the user.
- //
- try {
- synchronized (mDefaultTrustManager) {
- mDefaultTrustManager.checkServerTrusted(
- serverCertificates, "RSA");
-
- // no errors!!!
- return null;
- }
- } catch (CertificateException e) {
- if (HttpLog.LOGV) {
- HttpLog.v(
- "failed to pre-validate the certificate chain, error: " +
- e.getMessage());
- }
- }
-
- sslSocket.getSession().invalidate();
-
- SslError error = null;
-
- // we check the root certificate separately from the rest of the
- // chain; this is because we need to know what certificate in
- // the chain resulted in an error if any
- currCertificate =
- serverCertificates[serverCertificates.length - 1];
- if (currCertificate == null) {
- closeSocketThrowException(
- sslSocket, "root certificate is null");
- }
-
- // check if the last certificate in the chain (root) is trusted
- X509Certificate[] rootCertificateChain = { currCertificate };
- try {
- synchronized (mDefaultTrustManager) {
- mDefaultTrustManager.checkServerTrusted(
- rootCertificateChain, "RSA");
- }
- } catch (CertificateExpiredException e) {
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage = "root certificate has expired";
- }
-
- if (HttpLog.LOGV) {
- HttpLog.v(errorMessage);
- }
-
- error = new SslError(
- SslError.SSL_EXPIRED, currCertificate);
- } catch (CertificateNotYetValidException e) {
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage = "root certificate not valid yet";
- }
-
- if (HttpLog.LOGV) {
- HttpLog.v(errorMessage);
- }
-
- error = new SslError(
- SslError.SSL_NOTYETVALID, currCertificate);
- } catch (CertificateException e) {
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage = "root certificate not trusted";
- }
-
- if (HttpLog.LOGV) {
- HttpLog.v(errorMessage);
- }
-
- return new SslError(
- SslError.SSL_UNTRUSTED, currCertificate);
- }
-
- // Then go through the certificate chain checking that each
- // certificate trusts the next and that each certificate is
- // within its valid date range. Walk the chain in the order
- // from the CA to the end-user
- X509Certificate prevCertificate =
- serverCertificates[serverCertificates.length - 1];
-
- for (int i = serverCertificates.length - 2; i >= 0; --i) {
- currCertificate = serverCertificates[i];
-
- // if a certificate is null, we cannot verify the chain
- if (currCertificate == null) {
- closeSocketThrowException(
- sslSocket, "null certificate in the chain");
- }
-
- // verify if trusted by chain
- if (!prevCertificate.getSubjectDN().equals(
- currCertificate.getIssuerDN())) {
- String errorMessage = "not trusted by chain";
-
- if (HttpLog.LOGV) {
- HttpLog.v(errorMessage);
- }
-
- return new SslError(
- SslError.SSL_UNTRUSTED, currCertificate);
- }
-
- try {
- currCertificate.verify(prevCertificate.getPublicKey());
- } catch (GeneralSecurityException e) {
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage = "not trusted by chain";
- }
-
- if (HttpLog.LOGV) {
- HttpLog.v(errorMessage);
- }
-
- return new SslError(
- SslError.SSL_UNTRUSTED, currCertificate);
- }
-
- // verify if the dates are valid
- try {
- currCertificate.checkValidity();
- } catch (CertificateExpiredException e) {
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage = "certificate expired";
- }
-
- if (HttpLog.LOGV) {
- HttpLog.v(errorMessage);
- }
-
- if (error == null ||
- error.getPrimaryError() < SslError.SSL_EXPIRED) {
- error = new SslError(
- SslError.SSL_EXPIRED, currCertificate);
- }
- } catch (CertificateNotYetValidException e) {
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage = "certificate not valid yet";
- }
-
- if (HttpLog.LOGV) {
- HttpLog.v(errorMessage);
- }
-
- if (error == null ||
- error.getPrimaryError() < SslError.SSL_NOTYETVALID) {
- error = new SslError(
- SslError.SSL_NOTYETVALID, currCertificate);
- }
- }
-
- prevCertificate = currCertificate;
- }
-
- // if we do not have an error to report back to the user, throw
- // an exception (a generic error will be reported instead)
- if (error == null) {
- closeSocketThrowException(
- sslSocket,
- "failed to pre-validate the certificate chain due to a non-standard error");
- }
-
- return error;
- }
-
- private void closeSocketThrowException(
- SSLSocket socket, String errorMessage, String defaultErrorMessage)
- throws SSLHandshakeException, IOException {
- closeSocketThrowException(
- socket, errorMessage != null ? errorMessage : defaultErrorMessage);
- }
-
- private void closeSocketThrowException(SSLSocket socket, String errorMessage)
- throws SSLHandshakeException, IOException {
- if (HttpLog.LOGV) {
- HttpLog.v("validation error: " + errorMessage);
- }
-
- if (socket != null) {
- SSLSession session = socket.getSession();
- if (session != null) {
- session.invalidate();
- }
-
- socket.close();
- }
-
- throw new SSLHandshakeException(errorMessage);
- }
-
- /**
- * @param sslContext The SSL context shared accross all the SSL sessions
- * @param host The host associated with the session
- * @return A suitable SSL session from the SSL context
- */
- private SSLSession getSSLSession(SSLContext sslContext, HttpHost host) {
- if (sslContext != null && host != null) {
- Enumeration en = sslContext.getClientSessionContext().getIds();
- while (en.hasMoreElements()) {
- byte[] id = (byte[]) en.nextElement();
- if (id != null) {
- SSLSession session =
- sslContext.getClientSessionContext().getSession(id);
- if (session.isValid() &&
- host.getHostName().equals(session.getPeerHost()) &&
- host.getPort() == session.getPeerPort()) {
- return session;
- }
- }
- }
- }
-
- return null;
- }
-}
diff --git a/core/java/android/net/http/CertificateValidatorCache.java b/core/java/android/net/http/CertificateValidatorCache.java
deleted file mode 100644
index 54a1dbe51aa..00000000000
--- a/core/java/android/net/http/CertificateValidatorCache.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net.http;
-
-import android.os.SystemClock;
-
-import android.security.Sha1MessageDigest;
-
-import java.security.cert.Certificate;
-import java.security.cert.CertificateFactory;
-import java.security.cert.CertPath;
-import java.security.GeneralSecurityException;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Random;
-
-
-/**
- * Validator cache used to speed-up certificate chain validation. The idea is
- * to keep each secure domain name associated with a cryptographically secure
- * hash of the certificate chain successfully used to validate the domain. If
- * we establish connection with the domain more than once and each time receive
- * the same list of certificates, we do not have to re-validate.
- *
- * {@hide}
- */
-class CertificateValidatorCache {
-
- // TODO: debug only!
- public static long mSave = 0;
- public static long mCost = 0;
- // TODO: debug only!
-
- /**
- * The cache-entry lifetime in milliseconds (here, 10 minutes)
- */
- private static final long CACHE_ENTRY_LIFETIME = 10 * 60 * 1000;
-
- /**
- * The certificate factory
- */
- private static CertificateFactory sCertificateFactory;
-
- /**
- * The certificate validator cache map (domain to a cache entry)
- */
- private HashMap<Integer, CacheEntry> mCacheMap;
-
- /**
- * Random salt
- */
- private int mBigScrew;
-
- /**
- * @param certificate The array of server certificates to compute a
- * secure hash from
- * @return The secure hash computed from server certificates
- */
- public static byte[] secureHash(Certificate[] certificates) {
- byte[] secureHash = null;
-
- // TODO: debug only!
- long beg = SystemClock.uptimeMillis();
- // TODO: debug only!
-
- if (certificates != null && certificates.length != 0) {
- byte[] encodedCertPath = null;
- try {
- synchronized (CertificateValidatorCache.class) {
- if (sCertificateFactory == null) {
- try {
- sCertificateFactory =
- CertificateFactory.getInstance("X.509");
- } catch(GeneralSecurityException e) {
- if (HttpLog.LOGV) {
- HttpLog.v("CertificateValidatorCache:" +
- " failed to create the certificate factory");
- }
- }
- }
- }
-
- CertPath certPath =
- sCertificateFactory.generateCertPath(Arrays.asList(certificates));
- if (certPath != null) {
- encodedCertPath = certPath.getEncoded();
- if (encodedCertPath != null) {
- Sha1MessageDigest messageDigest =
- new Sha1MessageDigest();
- secureHash = messageDigest.digest(encodedCertPath);
- }
- }
- } catch (GeneralSecurityException e) {}
- }
-
- // TODO: debug only!
- long end = SystemClock.uptimeMillis();
- mCost += (end - beg);
- // TODO: debug only!
-
- return secureHash;
- }
-
- /**
- * Creates a new certificate-validator cache
- */
- public CertificateValidatorCache() {
- Random random = new Random();
- mBigScrew = random.nextInt();
-
- mCacheMap = new HashMap<Integer, CacheEntry>();
- }
-
- /**
- * @param domain The domain to check against
- * @param secureHash The secure hash to check against
- * @return True iff there is a valid (not expired) cache entry
- * associated with the domain and the secure hash
- */
- public boolean has(String domain, byte[] secureHash) {
- boolean rval = false;
-
- if (domain != null && domain.length() != 0) {
- if (secureHash != null && secureHash.length != 0) {
- CacheEntry cacheEntry = (CacheEntry)mCacheMap.get(
- new Integer(mBigScrew ^ domain.hashCode()));
- if (cacheEntry != null) {
- if (!cacheEntry.expired()) {
- rval = cacheEntry.has(domain, secureHash);
- // TODO: debug only!
- if (rval) {
- mSave += cacheEntry.mSave;
- }
- // TODO: debug only!
- } else {
- mCacheMap.remove(cacheEntry);
- }
- }
- }
- }
-
- return rval;
- }
-
- /**
- * Adds the (domain, secureHash) tuple to the cache
- * @param domain The domain to be added to the cache
- * @param secureHash The secure hash to be added to the cache
- * @return True iff succeeds
- */
- public boolean put(String domain, byte[] secureHash, long save) {
- if (domain != null && domain.length() != 0) {
- if (secureHash != null && secureHash.length != 0) {
- mCacheMap.put(
- new Integer(mBigScrew ^ domain.hashCode()),
- new CacheEntry(domain, secureHash, save));
-
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Certificate-validator cache entry. We have one per domain
- */
- private class CacheEntry {
-
- /**
- * The hash associated with this cache entry
- */
- private byte[] mHash;
-
- /**
- * The time associated with this cache entry
- */
- private long mTime;
-
- // TODO: debug only!
- public long mSave;
- // TODO: debug only!
-
- /**
- * The host associated with this cache entry
- */
- private String mDomain;
-
- /**
- * Creates a new certificate-validator cache entry
- * @param domain The domain to be associated with this cache entry
- * @param secureHash The secure hash to be associated with this cache
- * entry
- */
- public CacheEntry(String domain, byte[] secureHash, long save) {
- mDomain = domain;
- mHash = secureHash;
- // TODO: debug only!
- mSave = save;
- // TODO: debug only!
- mTime = SystemClock.uptimeMillis();
- }
-
- /**
- * @return True iff the cache item has expired
- */
- public boolean expired() {
- return CACHE_ENTRY_LIFETIME < SystemClock.uptimeMillis() - mTime;
- }
-
- /**
- * @param domain The domain to check
- * @param secureHash The secure hash to check
- * @return True iff the given domain and hash match those associated
- * with this entry
- */
- public boolean has(String domain, byte[] secureHash) {
- if (domain != null && 0 < domain.length()) {
- if (!mDomain.equals(domain)) {
- return false;
- }
- }
-
- int hashLength = secureHash.length;
- if (secureHash != null && 0 < hashLength) {
- if (hashLength == mHash.length) {
- for (int i = 0; i < hashLength; ++i) {
- if (secureHash[i] != mHash[i]) {
- return false;
- }
- }
- return true;
- }
- }
-
- return false;
- }
- }
-};
diff --git a/core/java/android/net/http/CharArrayBuffers.java b/core/java/android/net/http/CharArrayBuffers.java
deleted file mode 100644
index 77d45f6d342..00000000000
--- a/core/java/android/net/http/CharArrayBuffers.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net.http;
-
-import org.apache.http.util.CharArrayBuffer;
-import org.apache.http.protocol.HTTP;
-
-/**
- * Utility methods for working on CharArrayBuffers.
- *
- * {@hide}
- */
-class CharArrayBuffers {
-
- static final char uppercaseAddon = 'a' - 'A';
-
- /**
- * Returns true if the buffer contains the given string. Ignores leading
- * whitespace and case.
- *
- * @param buffer to search
- * @param beginIndex index at which we should start
- * @param str to search for
- */
- static boolean containsIgnoreCaseTrimmed(CharArrayBuffer buffer,
- int beginIndex, final String str) {
- int len = buffer.length();
- char[] chars = buffer.buffer();
- while (beginIndex < len && HTTP.isWhitespace(chars[beginIndex])) {
- beginIndex++;
- }
- int size = str.length();
- boolean ok = len >= beginIndex + size;
- for (int j=0; ok && (j<size); j++) {
- char a = chars[beginIndex+j];
- char b = str.charAt(j);
- if (a != b) {
- a = toLower(a);
- b = toLower(b);
- ok = a == b;
- }
- }
- return ok;
- }
-
- /**
- * Returns index of first occurence ch. Lower cases characters leading up
- * to first occurrence of ch.
- */
- static int setLowercaseIndexOf(CharArrayBuffer buffer, final int ch) {
-
- int beginIndex = 0;
- int endIndex = buffer.length();
- char[] chars = buffer.buffer();
-
- for (int i = beginIndex; i < endIndex; i++) {
- char current = chars[i];
- if (current == ch) {
- return i;
- } else if (current >= 'A' && current <= 'Z'){
- // make lower case
- current += uppercaseAddon;
- chars[i] = current;
- }
- }
- return -1;
- }
-
- private static char toLower(char c) {
- if (c >= 'A' && c <= 'Z'){
- c += uppercaseAddon;
- }
- return c;
- }
-}
diff --git a/core/java/android/net/http/Connection.java b/core/java/android/net/http/Connection.java
deleted file mode 100644
index 563634fd469..00000000000
--- a/core/java/android/net/http/Connection.java
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net.http;
-
-import android.content.Context;
-import android.os.SystemClock;
-
-import java.io.IOException;
-import java.net.UnknownHostException;
-import java.util.ListIterator;
-import java.util.LinkedList;
-
-import javax.net.ssl.SSLHandshakeException;
-
-import org.apache.http.ConnectionReuseStrategy;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpException;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpVersion;
-import org.apache.http.ParseException;
-import org.apache.http.ProtocolVersion;
-import org.apache.http.protocol.ExecutionContext;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.BasicHttpContext;
-
-/**
- * {@hide}
- */
-abstract class Connection {
-
- /**
- * Allow a TCP connection 60 idle seconds before erroring out
- */
- static final int SOCKET_TIMEOUT = 60000;
-
- private static final int SEND = 0;
- private static final int READ = 1;
- private static final int DRAIN = 2;
- private static final int DONE = 3;
- private static final String[] states = {"SEND", "READ", "DRAIN", "DONE"};
-
- Context mContext;
-
- /** The low level connection */
- protected AndroidHttpClientConnection mHttpClientConnection = null;
-
- /**
- * The server SSL certificate associated with this connection
- * (null if the connection is not secure)
- * It would be nice to store the whole certificate chain, but
- * we want to keep things as light-weight as possible
- */
- protected SslCertificate mCertificate = null;
-
- /**
- * The host this connection is connected to. If using proxy,
- * this is set to the proxy address
- */
- HttpHost mHost;
-
- /** true if the connection can be reused for sending more requests */
- private boolean mCanPersist;
-
- /** context required by ConnectionReuseStrategy. */
- private HttpContext mHttpContext;
-
- /** set when cancelled */
- private static int STATE_NORMAL = 0;
- private static int STATE_CANCEL_REQUESTED = 1;
- private int mActive = STATE_NORMAL;
-
- /** The number of times to try to re-connect (if connect fails). */
- private final static int RETRY_REQUEST_LIMIT = 2;
-
- private static final int MIN_PIPE = 2;
- private static final int MAX_PIPE = 3;
-
- /**
- * Doesn't seem to exist anymore in the new HTTP client, so copied here.
- */
- private static final String HTTP_CONNECTION = "http.connection";
-
- RequestQueue.ConnectionManager mConnectionManager;
- RequestFeeder mRequestFeeder;
-
- /**
- * Buffer for feeding response blocks to webkit. One block per
- * connection reduces memory churn.
- */
- private byte[] mBuf;
-
- protected Connection(Context context, HttpHost host,
- RequestQueue.ConnectionManager connectionManager,
- RequestFeeder requestFeeder) {
- mContext = context;
- mHost = host;
- mConnectionManager = connectionManager;
- mRequestFeeder = requestFeeder;
-
- mCanPersist = false;
- mHttpContext = new BasicHttpContext(null);
- }
-
- HttpHost getHost() {
- return mHost;
- }
-
- /**
- * connection factory: returns an HTTP or HTTPS connection as
- * necessary
- */
- static Connection getConnection(
- Context context, HttpHost host,
- RequestQueue.ConnectionManager connectionManager,
- RequestFeeder requestFeeder) {
-
- if (host.getSchemeName().equals("http")) {
- return new HttpConnection(context, host, connectionManager,
- requestFeeder);
- }
-
- // Otherwise, default to https
- return new HttpsConnection(context, host, connectionManager,
- requestFeeder);
- }
-
- /**
- * @return The server SSL certificate associated with this
- * connection (null if the connection is not secure)
- */
- /* package */ SslCertificate getCertificate() {
- return mCertificate;
- }
-
- /**
- * Close current network connection
- * Note: this runs in non-network thread
- */
- void cancel() {
- mActive = STATE_CANCEL_REQUESTED;
- closeConnection();
- if (HttpLog.LOGV) HttpLog.v(
- "Connection.cancel(): connection closed " + mHost);
- }
-
- /**
- * Process requests in queue
- * pipelines requests
- */
- void processRequests(Request firstRequest) {
- Request req = null;
- boolean empty;
- int error = EventHandler.OK;
- Exception exception = null;
-
- LinkedList<Request> pipe = new LinkedList<Request>();
-
- int minPipe = MIN_PIPE, maxPipe = MAX_PIPE;
- int state = SEND;
-
- while (state != DONE) {
- if (HttpLog.LOGV) HttpLog.v(
- states[state] + " pipe " + pipe.size());
-
- /* If a request was cancelled, give other cancel requests
- some time to go through so we don't uselessly restart
- connections */
- if (mActive == STATE_CANCEL_REQUESTED) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException x) { /* ignore */ }
- mActive = STATE_NORMAL;
- }
-
- switch (state) {
- case SEND: {
- if (pipe.size() == maxPipe) {
- state = READ;
- break;
- }
- /* get a request */
- if (firstRequest == null) {
- req = mRequestFeeder.getRequest(mHost);
- } else {
- req = firstRequest;
- firstRequest = null;
- }
- if (req == null) {
- state = DRAIN;
- break;
- }
- req.setConnection(this);
-
- /* Don't work on cancelled requests. */
- if (req.mCancelled) {
- if (HttpLog.LOGV) HttpLog.v(
- "processRequests(): skipping cancelled request "
- + req);
- req.complete();
- break;
- }
-
- if (mHttpClientConnection == null ||
- !mHttpClientConnection.isOpen()) {
- /* If this call fails, the address is bad or
- the net is down. Punt for now.
-
- FIXME: blow out entire queue here on
- connection failure if net up? */
-
- if (!openHttpConnection(req)) {
- state = DONE;
- break;
- }
- }
-
- try {
- /* FIXME: don't increment failure count if old
- connection? There should not be a penalty for
- attempting to reuse an old connection */
- req.sendRequest(mHttpClientConnection);
- } catch (HttpException e) {
- exception = e;
- error = EventHandler.ERROR;
- } catch (IOException e) {
- exception = e;
- error = EventHandler.ERROR_IO;
- } catch (IllegalStateException e) {
- exception = e;
- error = EventHandler.ERROR_IO;
- }
- if (exception != null) {
- if (httpFailure(req, error, exception) &&
- !req.mCancelled) {
- /* retry request if not permanent failure
- or cancelled */
- pipe.addLast(req);
- }
- exception = null;
- state = (clearPipe(pipe) ||
- !mConnectionManager.isNetworkConnected()) ?
- DONE : SEND;
- minPipe = maxPipe = 1;
- break;
- }
-
- pipe.addLast(req);
- if (!mCanPersist) state = READ;
- break;
-
- }
- case DRAIN:
- case READ: {
- empty = !mRequestFeeder.haveRequest(mHost);
- int pipeSize = pipe.size();
- if (state != DRAIN && pipeSize < minPipe &&
- !empty && mCanPersist) {
- state = SEND;
- break;
- } else if (pipeSize == 0) {
- /* Done if no other work to do */
- state = empty ? DONE : SEND;
- break;
- }
-
- req = (Request)pipe.removeFirst();
- if (HttpLog.LOGV) HttpLog.v(
- "processRequests() reading " + req);
-
- try {
- req.readResponse(mHttpClientConnection);
- } catch (ParseException e) {
- exception = e;
- error = EventHandler.ERROR_IO;
- } catch (IOException e) {
- exception = e;
- error = EventHandler.ERROR_IO;
- } catch (IllegalStateException e) {
- exception = e;
- error = EventHandler.ERROR_IO;
- }
- if (exception != null) {
- if (httpFailure(req, error, exception) &&
- !req.mCancelled) {
- /* retry request if not permanent failure
- or cancelled */
- req.reset();
- pipe.addFirst(req);
- }
- exception = null;
- mCanPersist = false;
- }
- if (!mCanPersist) {
- if (HttpLog.LOGV) HttpLog.v(
- "processRequests(): no persist, closing " +
- mHost);
-
- closeConnection();
-
- mHttpContext.removeAttribute(HTTP_CONNECTION);
- clearPipe(pipe);
- minPipe = maxPipe = 1;
- /* If network active continue to service this queue */
- state = mConnectionManager.isNetworkConnected() ?
- SEND : DONE;
- }
- break;
- }
- }
- }
- }
-
- /**
- * After a send/receive failure, any pipelined requests must be
- * cleared back to the mRequest queue
- * @return true if mRequests is empty after pipe cleared
- */
- private boolean clearPipe(LinkedList<Request> pipe) {
- boolean empty = true;
- if (HttpLog.LOGV) HttpLog.v(
- "Connection.clearPipe(): clearing pipe " + pipe.size());
- synchronized (mRequestFeeder) {
- Request tReq;
- while (!pipe.isEmpty()) {
- tReq = (Request)pipe.removeLast();
- if (HttpLog.LOGV) HttpLog.v(
- "clearPipe() adding back " + mHost + " " + tReq);
- mRequestFeeder.requeueRequest(tReq);
- empty = false;
- }
- if (empty) empty = mRequestFeeder.haveRequest(mHost);
- }
- return empty;
- }
-
- /**
- * @return true on success
- */
- private boolean openHttpConnection(Request req) {
-
- long now = SystemClock.uptimeMillis();
- int error = EventHandler.OK;
- Exception exception = null;
-
- try {
- // reset the certificate to null before opening a connection
- mCertificate = null;
- mHttpClientConnection = openConnection(req);
- if (mHttpClientConnection != null) {
- mHttpClientConnection.setSocketTimeout(SOCKET_TIMEOUT);
- mHttpContext.setAttribute(HTTP_CONNECTION,
- mHttpClientConnection);
- } else {
- // we tried to do SSL tunneling, failed,
- // and need to drop the request;
- // we have already informed the handler
- req.mFailCount = RETRY_REQUEST_LIMIT;
- return false;
- }
- } catch (UnknownHostException e) {
- if (HttpLog.LOGV) HttpLog.v("Failed to open connection");
- error = EventHandler.ERROR_LOOKUP;
- exception = e;
- } catch (IllegalArgumentException e) {
- if (HttpLog.LOGV) HttpLog.v("Illegal argument exception");
- error = EventHandler.ERROR_CONNECT;
- req.mFailCount = RETRY_REQUEST_LIMIT;
- exception = e;
- } catch (SSLConnectionClosedByUserException e) {
- // hack: if we have an SSL connection failure,
- // we don't want to reconnect
- req.mFailCount = RETRY_REQUEST_LIMIT;
- // no error message
- return false;
- } catch (SSLHandshakeException e) {
- // hack: if we have an SSL connection failure,
- // we don't want to reconnect
- req.mFailCount = RETRY_REQUEST_LIMIT;
- if (HttpLog.LOGV) HttpLog.v(
- "SSL exception performing handshake");
- error = EventHandler.ERROR_FAILED_SSL_HANDSHAKE;
- exception = e;
- } catch (IOException e) {
- error = EventHandler.ERROR_CONNECT;
- exception = e;
- }
-
- if (HttpLog.LOGV) {
- long now2 = SystemClock.uptimeMillis();
- HttpLog.v("Connection.openHttpConnection() " +
- (now2 - now) + " " + mHost);
- }
-
- if (error == EventHandler.OK) {
- return true;
- } else {
- if (mConnectionManager.isNetworkConnected() == false ||
- req.mFailCount < RETRY_REQUEST_LIMIT) {
- // requeue
- mRequestFeeder.requeueRequest(req);
- req.mFailCount++;
- } else {
- httpFailure(req, error, exception);
- }
- return error == EventHandler.OK;
- }
- }
-
- /**
- * Helper. Calls the mEventHandler's error() method only if
- * request failed permanently. Increments mFailcount on failure.
- *
- * Increments failcount only if the network is believed to be
- * connected
- *
- * @return true if request can be retried (less than
- * RETRY_REQUEST_LIMIT failures have occurred).
- */
- private boolean httpFailure(Request req, int errorId, Exception e) {
- boolean ret = true;
- boolean networkConnected = mConnectionManager.isNetworkConnected();
-
- // e.printStackTrace();
- if (HttpLog.LOGV) HttpLog.v(
- "httpFailure() ******* " + e + " count " + req.mFailCount +
- " networkConnected " + networkConnected + " " + mHost + " " + req.getUri());
-
- if (networkConnected && ++req.mFailCount >= RETRY_REQUEST_LIMIT) {
- ret = false;
- String error;
- if (errorId < 0) {
- error = mContext.getText(
- EventHandler.errorStringResources[-errorId]).toString();
- } else {
- Throwable cause = e.getCause();
- error = cause != null ? cause.toString() : e.getMessage();
- }
- req.mEventHandler.error(errorId, error);
- req.complete();
- }
-
- closeConnection();
- mHttpContext.removeAttribute(HTTP_CONNECTION);
-
- return ret;
- }
-
- HttpContext getHttpContext() {
- return mHttpContext;
- }
-
- /**
- * Use same logic as ConnectionReuseStrategy
- * @see ConnectionReuseStrategy
- */
- private boolean keepAlive(HttpEntity entity,
- ProtocolVersion ver, int connType, final HttpContext context) {
- org.apache.http.HttpConnection conn = (org.apache.http.HttpConnection)
- context.getAttribute(ExecutionContext.HTTP_CONNECTION);
-
- if (conn != null && !conn.isOpen())
- return false;
- // do NOT check for stale connection, that is an expensive operation
-
- if (entity != null) {
- if (entity.getContentLength() < 0) {
- if (!entity.isChunked() || ver.lessEquals(HttpVersion.HTTP_1_0)) {
- // if the content length is not known and is not chunk
- // encoded, the connection cannot be reused
- return false;
- }
- }
- }
- // Check for 'Connection' directive
- if (connType == Headers.CONN_CLOSE) {
- return false;
- } else if (connType == Headers.CONN_KEEP_ALIVE) {
- return true;
- }
- // Resorting to protocol version default close connection policy
- return !ver.lessEquals(HttpVersion.HTTP_1_0);
- }
-
- void setCanPersist(HttpEntity entity, ProtocolVersion ver, int connType) {
- mCanPersist = keepAlive(entity, ver, connType, mHttpContext);
- }
-
- void setCanPersist(boolean canPersist) {
- mCanPersist = canPersist;
- }
-
- boolean getCanPersist() {
- return mCanPersist;
- }
-
- /** typically http or https... set by subclass */
- abstract String getScheme();
- abstract void closeConnection();
- abstract AndroidHttpClientConnection openConnection(Request req) throws IOException;
-
- /**
- * Prints request queue to log, for debugging.
- * returns request count
- */
- public synchronized String toString() {
- return mHost.toString();
- }
-
- byte[] getBuf() {
- if (mBuf == null) mBuf = new byte[8192];
- return mBuf;
- }
-
-}
diff --git a/core/java/android/net/http/ConnectionThread.java b/core/java/android/net/http/ConnectionThread.java
deleted file mode 100644
index 8e759e24728..00000000000
--- a/core/java/android/net/http/ConnectionThread.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net.http;
-
-import android.content.Context;
-import android.os.SystemClock;
-
-import org.apache.http.HttpHost;
-
-import java.lang.Thread;
-
-/**
- * {@hide}
- */
-class ConnectionThread extends Thread {
-
- static final int WAIT_TIMEOUT = 5000;
- static final int WAIT_TICK = 1000;
-
- // Performance probe
- long mStartThreadTime;
- long mCurrentThreadTime;
-
- private boolean mWaiting;
- private volatile boolean mRunning = true;
- private Context mContext;
- private RequestQueue.ConnectionManager mConnectionManager;
- private RequestFeeder mRequestFeeder;
-
- private int mId;
- Connection mConnection;
-
- ConnectionThread(Context context,
- int id,
- RequestQueue.ConnectionManager connectionManager,
- RequestFeeder requestFeeder) {
- super();
- mContext = context;
- setName("http" + id);
- mId = id;
- mConnectionManager = connectionManager;
- mRequestFeeder = requestFeeder;
- }
-
- void requestStop() {
- synchronized (mRequestFeeder) {
- mRunning = false;
- mRequestFeeder.notify();
- }
- }
-
- /**
- * Loop until app shutdown. Runs connections in priority
- * order.
- */
- public void run() {
- android.os.Process.setThreadPriority(
- android.os.Process.THREAD_PRIORITY_LESS_FAVORABLE);
-
- mStartThreadTime = -1;
- mCurrentThreadTime = SystemClock.currentThreadTimeMillis();
-
- while (mRunning) {
- Request request;
-
- /* Get a request to process */
- request = mRequestFeeder.getRequest();
-
- /* wait for work */
- if (request == null) {
- synchronized(mRequestFeeder) {
- if (HttpLog.LOGV) HttpLog.v("ConnectionThread: Waiting for work");
- mWaiting = true;
- try {
- if (mStartThreadTime != -1) {
- mCurrentThreadTime = SystemClock
- .currentThreadTimeMillis();
- }
- mRequestFeeder.wait();
- } catch (InterruptedException e) {
- }
- mWaiting = false;
- }
- } else {
- if (HttpLog.LOGV) HttpLog.v("ConnectionThread: new request " +
- request.mHost + " " + request );
-
- HttpHost proxy = mConnectionManager.getProxyHost();
-
- HttpHost host;
- if (false) {
- // Allow https proxy
- host = proxy == null ? request.mHost : proxy;
- } else {
- // Disallow https proxy -- tmob proxy server
- // serves a request loop for https reqs
- host = (proxy == null ||
- request.mHost.getSchemeName().equals("https")) ?
- request.mHost : proxy;
- }
- mConnection = mConnectionManager.getConnection(mContext, host);
- mConnection.processRequests(request);
- if (mConnection.getCanPersist()) {
- if (!mConnectionManager.recycleConnection(host,
- mConnection)) {
- mConnection.closeConnection();
- }
- } else {
- mConnection.closeConnection();
- }
- mConnection = null;
- }
-
- }
- }
-
- public synchronized String toString() {
- String con = mConnection == null ? "" : mConnection.toString();
- String active = mWaiting ? "w" : "a";
- return "cid " + mId + " " + active + " " + con;
- }
-
-}
diff --git a/core/java/android/net/http/DomainNameChecker.java b/core/java/android/net/http/DomainNameChecker.java
deleted file mode 100644
index e4c8009774b..00000000000
--- a/core/java/android/net/http/DomainNameChecker.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2008 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 android.net.http;
-
-import org.bouncycastle.asn1.x509.X509Name;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.security.cert.X509Certificate;
-import java.security.cert.CertificateParsingException;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-import java.util.Vector;
-
-/**
- * Implements basic domain-name validation as specified by RFC2818.
- *
- * {@hide}
- */
-public class DomainNameChecker {
- private static Pattern QUICK_IP_PATTERN;
- static {
- try {
- QUICK_IP_PATTERN = Pattern.compile("^[a-f0-9\\.:]+$");
- } catch (PatternSyntaxException e) {}
- }
-
- private static final int ALT_DNS_NAME = 2;
- private static final int ALT_IPA_NAME = 7;
-
- /**
- * Checks the site certificate against the domain name of the site being visited
- * @param certificate The certificate to check
- * @param thisDomain The domain name of the site being visited
- * @return True iff if there is a domain match as specified by RFC2818
- */
- public static boolean match(X509Certificate certificate, String thisDomain) {
- if (certificate == null || thisDomain == null || thisDomain.length() == 0) {
- return false;
- }
-
- thisDomain = thisDomain.toLowerCase();
- if (!isIpAddress(thisDomain)) {
- return matchDns(certificate, thisDomain);
- } else {
- return matchIpAddress(certificate, thisDomain);
- }
- }
-
- /**
- * @return True iff the domain name is specified as an IP address
- */
- private static boolean isIpAddress(String domain) {
- boolean rval = (domain != null && domain.length() != 0);
- if (rval) {
- try {
- // do a quick-dirty IP match first to avoid DNS lookup
- rval = QUICK_IP_PATTERN.matcher(domain).matches();
- if (rval) {
- rval = domain.equals(
- InetAddress.getByName(domain).getHostAddress());
- }
- } catch (UnknownHostException e) {
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage = "unknown host exception";
- }
-
- if (HttpLog.LOGV) {
- HttpLog.v("DomainNameChecker.isIpAddress(): " + errorMessage);
- }
-
- rval = false;
- }
- }
-
- return rval;
- }
-
- /**
- * Checks the site certificate against the IP domain name of the site being visited
- * @param certificate The certificate to check
- * @param thisDomain The DNS domain name of the site being visited
- * @return True iff if there is a domain match as specified by RFC2818
- */
- private static boolean matchIpAddress(X509Certificate certificate, String thisDomain) {
- if (HttpLog.LOGV) {
- HttpLog.v("DomainNameChecker.matchIpAddress(): this domain: " + thisDomain);
- }
-
- try {
- Collection subjectAltNames = certificate.getSubjectAlternativeNames();
- if (subjectAltNames != null) {
- Iterator i = subjectAltNames.iterator();
- while (i.hasNext()) {
- List altNameEntry = (List)(i.next());
- if (altNameEntry != null && 2 <= altNameEntry.size()) {
- Integer altNameType = (Integer)(altNameEntry.get(0));
- if (altNameType != null) {
- if (altNameType.intValue() == ALT_IPA_NAME) {
- String altName = (String)(altNameEntry.get(1));
- if (altName != null) {
- if (HttpLog.LOGV) {
- HttpLog.v("alternative IP: " + altName);
- }
- if (thisDomain.equalsIgnoreCase(altName)) {
- return true;
- }
- }
- }
- }
- }
- }
- }
- } catch (CertificateParsingException e) {}
-
- return false;
- }
-
- /**
- * Checks the site certificate against the DNS domain name of the site being visited
- * @param certificate The certificate to check
- * @param thisDomain The DNS domain name of the site being visited
- * @return True iff if there is a domain match as specified by RFC2818
- */
- private static boolean matchDns(X509Certificate certificate, String thisDomain) {
- boolean hasDns = false;
- try {
- Collection subjectAltNames = certificate.getSubjectAlternativeNames();
- if (subjectAltNames != null) {
- Iterator i = subjectAltNames.iterator();
- while (i.hasNext()) {
- List altNameEntry = (List)(i.next());
- if (altNameEntry != null && 2 <= altNameEntry.size()) {
- Integer altNameType = (Integer)(altNameEntry.get(0));
- if (altNameType != null) {
- if (altNameType.intValue() == ALT_DNS_NAME) {
- hasDns = true;
- String altName = (String)(altNameEntry.get(1));
- if (altName != null) {
- if (matchDns(thisDomain, altName)) {
- return true;
- }
- }
- }
- }
- }
- }
- }
- } catch (CertificateParsingException e) {
- // one way we can get here is if an alternative name starts with
- // '*' character, which is contrary to one interpretation of the
- // spec (a valid DNS name must start with a letter); there is no
- // good way around this, and in order to be compatible we proceed
- // to check the common name (ie, ignore alternative names)
- if (HttpLog.LOGV) {
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage = "failed to parse certificate";
- }
-
- if (HttpLog.LOGV) {
- HttpLog.v("DomainNameChecker.matchDns(): " + errorMessage);
- }
- }
- }
-
- if (!hasDns) {
- X509Name xName = new X509Name(certificate.getSubjectDN().getName());
- Vector val = xName.getValues();
- Vector oid = xName.getOIDs();
- for (int i = 0; i < oid.size(); i++) {
- if (oid.elementAt(i).equals(X509Name.CN)) {
- return matchDns(thisDomain, (String)(val.elementAt(i)));
- }
- }
- }
-
- return false;
- }
-
- /**
- * @param thisDomain The domain name of the site being visited
- * @param thatDomain The domain name from the certificate
- * @return True iff thisDomain matches thatDomain as specified by RFC2818
- */
- private static boolean matchDns(String thisDomain, String thatDomain) {
- if (HttpLog.LOGV) {
- HttpLog.v("DomainNameChecker.matchDns():" +
- " this domain: " + thisDomain +
- " that domain: " + thatDomain);
- }
-
- if (thisDomain == null || thisDomain.length() == 0 ||
- thatDomain == null || thatDomain.length() == 0) {
- return false;
- }
-
- thatDomain = thatDomain.toLowerCase();
-
- // (a) domain name strings are equal, ignoring case: X matches X
- boolean rval = thisDomain.equals(thatDomain);
- if (!rval) {
- String[] thisDomainTokens = thisDomain.split("\\.");
- String[] thatDomainTokens = thatDomain.split("\\.");
-
- int thisDomainTokensNum = thisDomainTokens.length;
- int thatDomainTokensNum = thatDomainTokens.length;
-
- // (b) OR thatHost is a '.'-suffix of thisHost: Z.Y.X matches X
- if (thisDomainTokensNum >= thatDomainTokensNum) {
- for (int i = thatDomainTokensNum - 1; i >= 0; --i) {
- rval = thisDomainTokens[i].equals(thatDomainTokens[i]);
- if (!rval) {
- // (c) OR we have a special *-match:
- // Z.Y.X matches *.Y.X but does not match *.X
- rval = (i == 0 && thisDomainTokensNum == thatDomainTokensNum);
- if (rval) {
- rval = thatDomainTokens[0].equals("*");
- if (!rval) {
- // (d) OR we have a *-component match:
- // f*.com matches foo.com but not bar.com
- rval = domainTokenMatch(
- thisDomainTokens[0], thatDomainTokens[0]);
- }
- }
-
- break;
- }
- }
- }
- }
-
- return rval;
- }
-
- /**
- * @param thisDomainToken The domain token from the current domain name
- * @param thatDomainToken The domain token from the certificate
- * @return True iff thisDomainToken matches thatDomainToken, using the
- * wildcard match as specified by RFC2818-3.1. For example, f*.com must
- * match foo.com but not bar.com
- */
- private static boolean domainTokenMatch(String thisDomainToken, String thatDomainToken) {
- if (thisDomainToken != null && thatDomainToken != null) {
- int starIndex = thatDomainToken.indexOf('*');
- if (starIndex >= 0) {
- if (thatDomainToken.length() - 1 <= thisDomainToken.length()) {
- String prefix = thatDomainToken.substring(0, starIndex);
- String suffix = thatDomainToken.substring(starIndex + 1);
-
- return thisDomainToken.startsWith(prefix) && thisDomainToken.endsWith(suffix);
- }
- }
- }
-
- return false;
- }
-}
diff --git a/core/java/android/net/http/EventHandler.java b/core/java/android/net/http/EventHandler.java
deleted file mode 100644
index 830d1f14cbf..00000000000
--- a/core/java/android/net/http/EventHandler.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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 android.net.http;
-
-
-/**
- * Callbacks in this interface are made as an HTTP request is
- * processed. The normal order of callbacks is status(), headers(),
- * then multiple data() then endData(). handleSslErrorRequest(), if
- * there is an SSL certificate error. error() can occur anywhere
- * in the transaction.
- *
- * {@hide}
- */
-
-public interface EventHandler {
-
- /**
- * Error codes used in the error() callback. Positive error codes
- * are reserved for codes sent by http servers. Negative error
- * codes are connection/parsing failures, etc.
- */
-
- /** Success */
- public static final int OK = 0;
- /** Generic error */
- public static final int ERROR = -1;
- /** Server or proxy hostname lookup failed */
- public static final int ERROR_LOOKUP = -2;
- /** Unsupported authentication scheme (ie, not basic or digest) */
- public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3;
- /** User authentication failed on server */
- public static final int ERROR_AUTH = -4;
- /** User authentication failed on proxy */
- public static final int ERROR_PROXYAUTH = -5;
- /** Could not connect to server */
- public static final int ERROR_CONNECT = -6;
- /** Failed to write to or read from server */
- public static final int ERROR_IO = -7;
- /** Connection timed out */
- public static final int ERROR_TIMEOUT = -8;
- /** Too many redirects */
- public static final int ERROR_REDIRECT_LOOP = -9;
- /** Unsupported URI scheme (ie, not http, https, etc) */
- public static final int ERROR_UNSUPPORTED_SCHEME = -10;
- /** Failed to perform SSL handshake */
- public static final int ERROR_FAILED_SSL_HANDSHAKE = -11;
- /** Bad URL */
- public static final int ERROR_BAD_URL = -12;
- /** Generic file error for file:/// loads */
- public static final int FILE_ERROR = -13;
- /** File not found error for file:/// loads */
- public static final int FILE_NOT_FOUND_ERROR = -14;
- /** Too many requests queued */
- public static final int TOO_MANY_REQUESTS_ERROR = -15;
-
- final static int[] errorStringResources = {
- com.android.internal.R.string.httpErrorOk,
- com.android.internal.R.string.httpError,
- com.android.internal.R.string.httpErrorLookup,
- com.android.internal.R.string.httpErrorUnsupportedAuthScheme,
- com.android.internal.R.string.httpErrorAuth,
- com.android.internal.R.string.httpErrorProxyAuth,
- com.android.internal.R.string.httpErrorConnect,
- com.android.internal.R.string.httpErrorIO,
- com.android.internal.R.string.httpErrorTimeout,
- com.android.internal.R.string.httpErrorRedirectLoop,
- com.android.internal.R.string.httpErrorUnsupportedScheme,
- com.android.internal.R.string.httpErrorFailedSslHandshake,
- com.android.internal.R.string.httpErrorBadUrl,
- com.android.internal.R.string.httpErrorFile,
- com.android.internal.R.string.httpErrorFileNotFound,
- com.android.internal.R.string.httpErrorTooManyRequests
- };
-
- /**
- * Called after status line has been sucessfully processed.
- * @param major_version HTTP version advertised by server. major
- * is the part before the "."
- * @param minor_version HTTP version advertised by server. minor
- * is the part after the "."
- * @param code HTTP Status code. See RFC 2616.
- * @param reason_phrase Textual explanation sent by server
- */
- public void status(int major_version,
- int minor_version,
- int code,
- String reason_phrase);
-
- /**
- * Called after all headers are successfully processed.
- */
- public void headers(Headers headers);
-
- /**
- * An array containing all or part of the http body as read from
- * the server.
- * @param data A byte array containing the content
- * @param len The length of valid content in data
- *
- * Note: chunked and compressed encodings are handled within
- * android.net.http. Decoded data is passed through this
- * interface.
- */
- public void data(byte[] data, int len);
-
- /**
- * Called when the document is completely read. No more data()
- * callbacks will be made after this call
- */
- public void endData();
-
- /**
- * SSL certificate callback called every time a resource is
- * loaded via a secure connection
- */
- public void certificate(SslCertificate certificate);
-
- /**
- * There was trouble.
- * @param id One of the error codes defined below
- * @param description of error
- */
- public void error(int id, String description);
-
- /**
- * SSL certificate error callback. Handles SSL error(s) on the way
- * up to the user. The callback has to make sure that restartConnection() is called,
- * otherwise the connection will be suspended indefinitely.
- */
- public void handleSslErrorRequest(SslError error);
-
-}
diff --git a/core/java/android/net/http/Headers.java b/core/java/android/net/http/Headers.java
deleted file mode 100644
index b0923d1ce27..00000000000
--- a/core/java/android/net/http/Headers.java
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * 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 android.net.http;
-
-import android.util.Config;
-import android.util.Log;
-
-import java.util.ArrayList;
-
-import org.apache.http.HeaderElement;
-import org.apache.http.entity.ContentLengthStrategy;
-import org.apache.http.message.BasicHeaderValueParser;
-import org.apache.http.message.ParserCursor;
-import org.apache.http.protocol.HTTP;
-import org.apache.http.util.CharArrayBuffer;
-
-/**
- * Manages received headers
- *
- * {@hide}
- */
-public final class Headers {
- private static final String LOGTAG = "Http";
-
- // header parsing constant
- /**
- * indicate HTTP 1.0 connection close after the response
- */
- public final static int CONN_CLOSE = 1;
- /**
- * indicate HTTP 1.1 connection keep alive
- */
- public final static int CONN_KEEP_ALIVE = 2;
-
- // initial values.
- public final static int NO_CONN_TYPE = 0;
- public final static long NO_TRANSFER_ENCODING = 0;
- public final static long NO_CONTENT_LENGTH = -1;
-
- // header strings
- public final static String TRANSFER_ENCODING = "transfer-encoding";
- public final static String CONTENT_LEN = "content-length";
- public final static String CONTENT_TYPE = "content-type";
- public final static String CONTENT_ENCODING = "content-encoding";
- public final static String CONN_DIRECTIVE = "connection";
-
- public final static String LOCATION = "location";
- public final static String PROXY_CONNECTION = "proxy-connection";
-
- public final static String WWW_AUTHENTICATE = "www-authenticate";
- public final static String PROXY_AUTHENTICATE = "proxy-authenticate";
- public final static String CONTENT_DISPOSITION = "content-disposition";
- public final static String ACCEPT_RANGES = "accept-ranges";
- public final static String EXPIRES = "expires";
- public final static String CACHE_CONTROL = "cache-control";
- public final static String LAST_MODIFIED = "last-modified";
- public final static String ETAG = "etag";
- public final static String SET_COOKIE = "set-cookie";
- public final static String PRAGMA = "pragma";
- public final static String REFRESH = "refresh";
-
- // following hash are generated by String.hashCode()
- private final static int HASH_TRANSFER_ENCODING = 1274458357;
- private final static int HASH_CONTENT_LEN = -1132779846;
- private final static int HASH_CONTENT_TYPE = 785670158;
- private final static int HASH_CONTENT_ENCODING = 2095084583;
- private final static int HASH_CONN_DIRECTIVE = -775651618;
- private final static int HASH_LOCATION = 1901043637;
- private final static int HASH_PROXY_CONNECTION = 285929373;
- private final static int HASH_WWW_AUTHENTICATE = -243037365;
- private final static int HASH_PROXY_AUTHENTICATE = -301767724;
- private final static int HASH_CONTENT_DISPOSITION = -1267267485;
- private final static int HASH_ACCEPT_RANGES = 1397189435;
- private final static int HASH_EXPIRES = -1309235404;
- private final static int HASH_CACHE_CONTROL = -208775662;
- private final static int HASH_LAST_MODIFIED = 150043680;
- private final static int HASH_ETAG = 3123477;
- private final static int HASH_SET_COOKIE = 1237214767;
- private final static int HASH_PRAGMA = -980228804;
- private final static int HASH_REFRESH = 1085444827;
-
- // keep any headers that require direct access in a presized
- // string array
- private final static int IDX_TRANSFER_ENCODING = 0;
- private final static int IDX_CONTENT_LEN = 1;
- private final static int IDX_CONTENT_TYPE = 2;
- private final static int IDX_CONTENT_ENCODING = 3;
- private final static int IDX_CONN_DIRECTIVE = 4;
- private final static int IDX_LOCATION = 5;
- private final static int IDX_PROXY_CONNECTION = 6;
- private final static int IDX_WWW_AUTHENTICATE = 7;
- private final static int IDX_PROXY_AUTHENTICATE = 8;
- private final static int IDX_CONTENT_DISPOSITION = 9;
- private final static int IDX_ACCEPT_RANGES = 10;
- private final static int IDX_EXPIRES = 11;
- private final static int IDX_CACHE_CONTROL = 12;
- private final static int IDX_LAST_MODIFIED = 13;
- private final static int IDX_ETAG = 14;
- private final static int IDX_SET_COOKIE = 15;
- private final static int IDX_PRAGMA = 16;
- private final static int IDX_REFRESH = 17;
-
- private final static int HEADER_COUNT = 18;
-
- /* parsed values */
- private long transferEncoding;
- private long contentLength; // Content length of the incoming data
- private int connectionType;
- private ArrayList<String> cookies = new ArrayList<String>(2);
-
- private String[] mHeaders = new String[HEADER_COUNT];
- private final static String[] sHeaderNames = {
- TRANSFER_ENCODING,
- CONTENT_LEN,
- CONTENT_TYPE,
- CONTENT_ENCODING,
- CONN_DIRECTIVE,
- LOCATION,
- PROXY_CONNECTION,
- WWW_AUTHENTICATE,
- PROXY_AUTHENTICATE,
- CONTENT_DISPOSITION,
- ACCEPT_RANGES,
- EXPIRES,
- CACHE_CONTROL,
- LAST_MODIFIED,
- ETAG,
- SET_COOKIE,
- PRAGMA,
- REFRESH
- };
-
- // Catch-all for headers not explicitly handled
- private ArrayList<String> mExtraHeaderNames = new ArrayList<String>(4);
- private ArrayList<String> mExtraHeaderValues = new ArrayList<String>(4);
-
- public Headers() {
- transferEncoding = NO_TRANSFER_ENCODING;
- contentLength = NO_CONTENT_LENGTH;
- connectionType = NO_CONN_TYPE;
- }
-
- public void parseHeader(CharArrayBuffer buffer) {
- int pos = CharArrayBuffers.setLowercaseIndexOf(buffer, ':');
- if (pos == -1) {
- return;
- }
- String name = buffer.substringTrimmed(0, pos);
- if (name.length() == 0) {
- return;
- }
- pos++;
-
- String val = buffer.substringTrimmed(pos, buffer.length());
- if (HttpLog.LOGV) {
- HttpLog.v("hdr " + buffer.length() + " " + buffer);
- }
-
- switch (name.hashCode()) {
- case HASH_TRANSFER_ENCODING:
- if (name.equals(TRANSFER_ENCODING)) {
- mHeaders[IDX_TRANSFER_ENCODING] = val;
- HeaderElement[] encodings = BasicHeaderValueParser.DEFAULT
- .parseElements(buffer, new ParserCursor(pos,
- buffer.length()));
- // The chunked encoding must be the last one applied RFC2616,
- // 14.41
- int len = encodings.length;
- if (HTTP.IDENTITY_CODING.equalsIgnoreCase(val)) {
- transferEncoding = ContentLengthStrategy.IDENTITY;
- } else if ((len > 0)
- && (HTTP.CHUNK_CODING
- .equalsIgnoreCase(encodings[len - 1].getName()))) {
- transferEncoding = ContentLengthStrategy.CHUNKED;
- } else {
- transferEncoding = ContentLengthStrategy.IDENTITY;
- }
- }
- break;
- case HASH_CONTENT_LEN:
- if (name.equals(CONTENT_LEN)) {
- mHeaders[IDX_CONTENT_LEN] = val;
- try {
- contentLength = Long.parseLong(val);
- } catch (NumberFormatException e) {
- if (Config.LOGV) {
- Log.v(LOGTAG, "Headers.headers(): error parsing"
- + " content length: " + buffer.toString());
- }
- }
- }
- break;
- case HASH_CONTENT_TYPE:
- if (name.equals(CONTENT_TYPE)) {
- mHeaders[IDX_CONTENT_TYPE] = val;
- }
- break;
- case HASH_CONTENT_ENCODING:
- if (name.equals(CONTENT_ENCODING)) {
- mHeaders[IDX_CONTENT_ENCODING] = val;
- }
- break;
- case HASH_CONN_DIRECTIVE:
- if (name.equals(CONN_DIRECTIVE)) {
- mHeaders[IDX_CONN_DIRECTIVE] = val;
- setConnectionType(buffer, pos);
- }
- break;
- case HASH_LOCATION:
- if (name.equals(LOCATION)) {
- mHeaders[IDX_LOCATION] = val;
- }
- break;
- case HASH_PROXY_CONNECTION:
- if (name.equals(PROXY_CONNECTION)) {
- mHeaders[IDX_PROXY_CONNECTION] = val;
- setConnectionType(buffer, pos);
- }
- break;
- case HASH_WWW_AUTHENTICATE:
- if (name.equals(WWW_AUTHENTICATE)) {
- mHeaders[IDX_WWW_AUTHENTICATE] = val;
- }
- break;
- case HASH_PROXY_AUTHENTICATE:
- if (name.equals(PROXY_AUTHENTICATE)) {
- mHeaders[IDX_PROXY_AUTHENTICATE] = val;
- }
- break;
- case HASH_CONTENT_DISPOSITION:
- if (name.equals(CONTENT_DISPOSITION)) {
- mHeaders[IDX_CONTENT_DISPOSITION] = val;
- }
- break;
- case HASH_ACCEPT_RANGES:
- if (name.equals(ACCEPT_RANGES)) {
- mHeaders[IDX_ACCEPT_RANGES] = val;
- }
- break;
- case HASH_EXPIRES:
- if (name.equals(EXPIRES)) {
- mHeaders[IDX_EXPIRES] = val;
- }
- break;
- case HASH_CACHE_CONTROL:
- if (name.equals(CACHE_CONTROL)) {
- mHeaders[IDX_CACHE_CONTROL] = val;
- }
- break;
- case HASH_LAST_MODIFIED:
- if (name.equals(LAST_MODIFIED)) {
- mHeaders[IDX_LAST_MODIFIED] = val;
- }
- break;
- case HASH_ETAG:
- if (name.equals(ETAG)) {
- mHeaders[IDX_ETAG] = val;
- }
- break;
- case HASH_SET_COOKIE:
- if (name.equals(SET_COOKIE)) {
- mHeaders[IDX_SET_COOKIE] = val;
- cookies.add(val);
- }
- break;
- case HASH_PRAGMA:
- if (name.equals(PRAGMA)) {
- mHeaders[IDX_PRAGMA] = val;
- }
- break;
- case HASH_REFRESH:
- if (name.equals(REFRESH)) {
- mHeaders[IDX_REFRESH] = val;
- }
- break;
- default:
- mExtraHeaderNames.add(name);
- mExtraHeaderValues.add(val);
- }
- }
-
- public long getTransferEncoding() {
- return transferEncoding;
- }
-
- public long getContentLength() {
- return contentLength;
- }
-
- public int getConnectionType() {
- return connectionType;
- }
-
- public String getContentType() {
- return mHeaders[IDX_CONTENT_TYPE];
- }
-
- public String getContentEncoding() {
- return mHeaders[IDX_CONTENT_ENCODING];
- }
-
- public String getLocation() {
- return mHeaders[IDX_LOCATION];
- }
-
- public String getWwwAuthenticate() {
- return mHeaders[IDX_WWW_AUTHENTICATE];
- }
-
- public String getProxyAuthenticate() {
- return mHeaders[IDX_PROXY_AUTHENTICATE];
- }
-
- public String getContentDisposition() {
- return mHeaders[IDX_CONTENT_DISPOSITION];
- }
-
- public String getAcceptRanges() {
- return mHeaders[IDX_ACCEPT_RANGES];
- }
-
- public String getExpires() {
- return mHeaders[IDX_EXPIRES];
- }
-
- public String getCacheControl() {
- return mHeaders[IDX_CACHE_CONTROL];
- }
-
- public String getLastModified() {
- return mHeaders[IDX_LAST_MODIFIED];
- }
-
- public String getEtag() {
- return mHeaders[IDX_ETAG];
- }
-
- public ArrayList<String> getSetCookie() {
- return this.cookies;
- }
-
- public String getPragma() {
- return mHeaders[IDX_PRAGMA];
- }
-
- public String getRefresh() {
- return mHeaders[IDX_REFRESH];
- }
-
- public void setContentLength(long value) {
- this.contentLength = value;
- }
-
- public void setContentType(String value) {
- mHeaders[IDX_CONTENT_TYPE] = value;
- }
-
- public void setContentEncoding(String value) {
- mHeaders[IDX_CONTENT_ENCODING] = value;
- }
-
- public void setLocation(String value) {
- mHeaders[IDX_LOCATION] = value;
- }
-
- public void setWwwAuthenticate(String value) {
- mHeaders[IDX_WWW_AUTHENTICATE] = value;
- }
-
- public void setProxyAuthenticate(String value) {
- mHeaders[IDX_PROXY_AUTHENTICATE] = value;
- }
-
- public void setContentDisposition(String value) {
- mHeaders[IDX_CONTENT_DISPOSITION] = value;
- }
-
- public void setAcceptRanges(String value) {
- mHeaders[IDX_ACCEPT_RANGES] = value;
- }
-
- public void setExpires(String value) {
- mHeaders[IDX_EXPIRES] = value;
- }
-
- public void setCacheControl(String value) {
- mHeaders[IDX_CACHE_CONTROL] = value;
- }
-
- public void setLastModified(String value) {
- mHeaders[IDX_LAST_MODIFIED] = value;
- }
-
- public void setEtag(String value) {
- mHeaders[IDX_ETAG] = value;
- }
-
- public interface HeaderCallback {
- public void header(String name, String value);
- }
-
- /**
- * Reports all non-null headers to the callback
- */
- public void getHeaders(HeaderCallback hcb) {
- for (int i = 0; i < HEADER_COUNT; i++) {
- String h = mHeaders[i];
- if (h != null) {
- hcb.header(sHeaderNames[i], h);
- }
- }
- int extraLen = mExtraHeaderNames.size();
- for (int i = 0; i < extraLen; i++) {
- if (Config.LOGV) {
- HttpLog.v("Headers.getHeaders() extra: " + i + " " +
- mExtraHeaderNames.get(i) + " " + mExtraHeaderValues.get(i));
- }
- hcb.header(mExtraHeaderNames.get(i),
- mExtraHeaderValues.get(i));
- }
-
- }
-
- private void setConnectionType(CharArrayBuffer buffer, int pos) {
- if (CharArrayBuffers.containsIgnoreCaseTrimmed(
- buffer, pos, HTTP.CONN_CLOSE)) {
- connectionType = CONN_CLOSE;
- } else if (CharArrayBuffers.containsIgnoreCaseTrimmed(
- buffer, pos, HTTP.CONN_KEEP_ALIVE)) {
- connectionType = CONN_KEEP_ALIVE;
- }
- }
-}
diff --git a/core/java/android/net/http/HttpAuthHeader.java b/core/java/android/net/http/HttpAuthHeader.java
deleted file mode 100644
index d41284ca63d..00000000000
--- a/core/java/android/net/http/HttpAuthHeader.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net.http;
-
-/**
- * HttpAuthHeader: a class to store HTTP authentication-header parameters.
- * For more information, see: RFC 2617: HTTP Authentication.
- *
- * {@hide}
- */
-public class HttpAuthHeader {
- /**
- * Possible HTTP-authentication header tokens to search for:
- */
- public final static String BASIC_TOKEN = "Basic";
- public final static String DIGEST_TOKEN = "Digest";
-
- private final static String REALM_TOKEN = "realm";
- private final static String NONCE_TOKEN = "nonce";
- private final static String STALE_TOKEN = "stale";
- private final static String OPAQUE_TOKEN = "opaque";
- private final static String QOP_TOKEN = "qop";
- private final static String ALGORITHM_TOKEN = "algorithm";
-
- /**
- * An authentication scheme. We currently support two different schemes:
- * HttpAuthHeader.BASIC - basic, and
- * HttpAuthHeader.DIGEST - digest (algorithm=MD5, QOP="auth").
- */
- private int mScheme;
-
- public static final int UNKNOWN = 0;
- public static final int BASIC = 1;
- public static final int DIGEST = 2;
-
- /**
- * A flag, indicating that the previous request from the client was
- * rejected because the nonce value was stale. If stale is TRUE
- * (case-insensitive), the client may wish to simply retry the request
- * with a new encrypted response, without reprompting the user for a
- * new username and password.
- */
- private boolean mStale;
-
- /**
- * A string to be displayed to users so they know which username and
- * password to use.
- */
- private String mRealm;
-
- /**
- * A server-specified data string which should be uniquely generated
- * each time a 401 response is made.
- */
- private String mNonce;
-
- /**
- * A string of data, specified by the server, which should be returned
- * by the client unchanged in the Authorization header of subsequent
- * requests with URIs in the same protection space.
- */
- private String mOpaque;
-
- /**
- * This directive is optional, but is made so only for backward
- * compatibility with RFC 2069 [6]; it SHOULD be used by all
- * implementations compliant with this version of the Digest scheme.
- * If present, it is a quoted string of one or more tokens indicating
- * the "quality of protection" values supported by the server. The
- * value "auth" indicates authentication; the value "auth-int"
- * indicates authentication with integrity protection.
- */
- private String mQop;
-
- /**
- * A string indicating a pair of algorithms used to produce the digest
- * and a checksum. If this is not present it is assumed to be "MD5".
- */
- private String mAlgorithm;
-
- /**
- * Is this authentication request a proxy authentication request?
- */
- private boolean mIsProxy;
-
- /**
- * Username string we get from the user.
- */
- private String mUsername;
-
- /**
- * Password string we get from the user.
- */
- private String mPassword;
-
- /**
- * Creates a new HTTP-authentication header object from the
- * input header string.
- * The header string is assumed to contain parameters of at
- * most one authentication-scheme (ensured by the caller).
- */
- public HttpAuthHeader(String header) {
- if (header != null) {
- parseHeader(header);
- }
- }
-
- /**
- * @return True iff this is a proxy authentication header.
- */
- public boolean isProxy() {
- return mIsProxy;
- }
-
- /**
- * Marks this header as a proxy authentication header.
- */
- public void setProxy() {
- mIsProxy = true;
- }
-
- /**
- * @return The username string.
- */
- public String getUsername() {
- return mUsername;
- }
-
- /**
- * Sets the username string.
- */
- public void setUsername(String username) {
- mUsername = username;
- }
-
- /**
- * @return The password string.
- */
- public String getPassword() {
- return mPassword;
- }
-
- /**
- * Sets the password string.
- */
- public void setPassword(String password) {
- mPassword = password;
- }
-
- /**
- * @return True iff this is the BASIC-authentication request.
- */
- public boolean isBasic () {
- return mScheme == BASIC;
- }
-
- /**
- * @return True iff this is the DIGEST-authentication request.
- */
- public boolean isDigest() {
- return mScheme == DIGEST;
- }
-
- /**
- * @return The authentication scheme requested. We currently
- * support two schemes:
- * HttpAuthHeader.BASIC - basic, and
- * HttpAuthHeader.DIGEST - digest (algorithm=MD5, QOP="auth").
- */
- public int getScheme() {
- return mScheme;
- }
-
- /**
- * @return True if indicating that the previous request from
- * the client was rejected because the nonce value was stale.
- */
- public boolean getStale() {
- return mStale;
- }
-
- /**
- * @return The realm value or null if there is none.
- */
- public String getRealm() {
- return mRealm;
- }
-
- /**
- * @return The nonce value or null if there is none.
- */
- public String getNonce() {
- return mNonce;
- }
-
- /**
- * @return The opaque value or null if there is none.
- */
- public String getOpaque() {
- return mOpaque;
- }
-
- /**
- * @return The QOP ("quality-of_protection") value or null if
- * there is none. The QOP value is always lower-case.
- */
- public String getQop() {
- return mQop;
- }
-
- /**
- * @return The name of the algorithm used or null if there is
- * none. By default, MD5 is used.
- */
- public String getAlgorithm() {
- return mAlgorithm;
- }
-
- /**
- * @return True iff the authentication scheme requested by the
- * server is supported; currently supported schemes:
- * BASIC,
- * DIGEST (only algorithm="md5", no qop or qop="auth).
- */
- public boolean isSupportedScheme() {
- // it is a good idea to enforce non-null realms!
- if (mRealm != null) {
- if (mScheme == BASIC) {
- return true;
- } else {
- if (mScheme == DIGEST) {
- return
- mAlgorithm.equals("md5") &&
- (mQop == null || mQop.equals("auth"));
- }
- }
- }
-
- return false;
- }
-
- /**
- * Parses the header scheme name and then scheme parameters if
- * the scheme is supported.
- */
- private void parseHeader(String header) {
- if (HttpLog.LOGV) {
- HttpLog.v("HttpAuthHeader.parseHeader(): header: " + header);
- }
-
- if (header != null) {
- String parameters = parseScheme(header);
- if (parameters != null) {
- // if we have a supported scheme
- if (mScheme != UNKNOWN) {
- parseParameters(parameters);
- }
- }
- }
- }
-
- /**
- * Parses the authentication scheme name. If we have a Digest
- * scheme, sets the algorithm value to the default of MD5.
- * @return The authentication scheme parameters string to be
- * parsed later (if the scheme is supported) or null if failed
- * to parse the scheme (the header value is null?).
- */
- private String parseScheme(String header) {
- if (header != null) {
- int i = header.indexOf(' ');
- if (i >= 0) {
- String scheme = header.substring(0, i).trim();
- if (scheme.equalsIgnoreCase(DIGEST_TOKEN)) {
- mScheme = DIGEST;
-
- // md5 is the default algorithm!!!
- mAlgorithm = "md5";
- } else {
- if (scheme.equalsIgnoreCase(BASIC_TOKEN)) {
- mScheme = BASIC;
- }
- }
-
- return header.substring(i + 1);
- }
- }
-
- return null;
- }
-
- /**
- * Parses a comma-separated list of authentification scheme
- * parameters.
- */
- private void parseParameters(String parameters) {
- if (HttpLog.LOGV) {
- HttpLog.v("HttpAuthHeader.parseParameters():" +
- " parameters: " + parameters);
- }
-
- if (parameters != null) {
- int i;
- do {
- i = parameters.indexOf(',');
- if (i < 0) {
- // have only one parameter
- parseParameter(parameters);
- } else {
- parseParameter(parameters.substring(0, i));
- parameters = parameters.substring(i + 1);
- }
- } while (i >= 0);
- }
- }
-
- /**
- * Parses a single authentication scheme parameter. The parameter
- * string is expected to follow the format: PARAMETER=VALUE.
- */
- private void parseParameter(String parameter) {
- if (parameter != null) {
- // here, we are looking for the 1st occurence of '=' only!!!
- int i = parameter.indexOf('=');
- if (i >= 0) {
- String token = parameter.substring(0, i).trim();
- String value =
- trimDoubleQuotesIfAny(parameter.substring(i + 1).trim());
-
- if (HttpLog.LOGV) {
- HttpLog.v("HttpAuthHeader.parseParameter():" +
- " token: " + token +
- " value: " + value);
- }
-
- if (token.equalsIgnoreCase(REALM_TOKEN)) {
- mRealm = value;
- } else {
- if (mScheme == DIGEST) {
- parseParameter(token, value);
- }
- }
- }
- }
- }
-
- /**
- * If the token is a known parameter name, parses and initializes
- * the token value.
- */
- private void parseParameter(String token, String value) {
- if (token != null && value != null) {
- if (token.equalsIgnoreCase(NONCE_TOKEN)) {
- mNonce = value;
- return;
- }
-
- if (token.equalsIgnoreCase(STALE_TOKEN)) {
- parseStale(value);
- return;
- }
-
- if (token.equalsIgnoreCase(OPAQUE_TOKEN)) {
- mOpaque = value;
- return;
- }
-
- if (token.equalsIgnoreCase(QOP_TOKEN)) {
- mQop = value.toLowerCase();
- return;
- }
-
- if (token.equalsIgnoreCase(ALGORITHM_TOKEN)) {
- mAlgorithm = value.toLowerCase();
- return;
- }
- }
- }
-
- /**
- * Parses and initializes the 'stale' paramer value. Any value
- * different from case-insensitive "true" is considered "false".
- */
- private void parseStale(String value) {
- if (value != null) {
- if (value.equalsIgnoreCase("true")) {
- mStale = true;
- }
- }
- }
-
- /**
- * Trims double-quotes around a parameter value if there are any.
- * @return The string value without the outermost pair of double-
- * quotes or null if the original value is null.
- */
- static private String trimDoubleQuotesIfAny(String value) {
- if (value != null) {
- int len = value.length();
- if (len > 2 &&
- value.charAt(0) == '\"' && value.charAt(len - 1) == '\"') {
- return value.substring(1, len - 1);
- }
- }
-
- return value;
- }
-}
diff --git a/core/java/android/net/http/HttpConnection.java b/core/java/android/net/http/HttpConnection.java
deleted file mode 100644
index 8b12d0b3ae2..00000000000
--- a/core/java/android/net/http/HttpConnection.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net.http;
-
-import android.content.Context;
-
-import java.net.Socket;
-import java.io.IOException;
-
-import org.apache.http.HttpClientConnection;
-import org.apache.http.HttpHost;
-import org.apache.http.impl.DefaultHttpClientConnection;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpConnectionParams;
-
-/**
- * A requestConnection connecting to a normal (non secure) http server
- *
- * {@hide}
- */
-class HttpConnection extends Connection {
-
- HttpConnection(Context context, HttpHost host,
- RequestQueue.ConnectionManager connectionManager,
- RequestFeeder requestFeeder) {
- super(context, host, connectionManager, requestFeeder);
- }
-
- /**
- * Opens the connection to a http server
- *
- * @return the opened low level connection
- * @throws IOException if the connection fails for any reason.
- */
- @Override
- AndroidHttpClientConnection openConnection(Request req) throws IOException {
-
- // Update the certificate info (connection not secure - set to null)
- EventHandler eventHandler = req.getEventHandler();
- mCertificate = null;
- eventHandler.certificate(mCertificate);
-
- AndroidHttpClientConnection conn = new AndroidHttpClientConnection();
- BasicHttpParams params = new BasicHttpParams();
- Socket sock = new Socket(mHost.getHostName(), mHost.getPort());
- params.setIntParameter(HttpConnectionParams.SOCKET_BUFFER_SIZE, 8192);
- conn.bind(sock, params);
- return conn;
- }
-
- /**
- * Closes the low level connection.
- *
- * If an exception is thrown then it is assumed that the
- * connection will have been closed (to the extent possible)
- * anyway and the caller does not need to take any further action.
- *
- */
- void closeConnection() {
- try {
- if (mHttpClientConnection != null && mHttpClientConnection.isOpen()) {
- mHttpClientConnection.close();
- }
- } catch (IOException e) {
- if (HttpLog.LOGV) HttpLog.v(
- "closeConnection(): failed closing connection " +
- mHost);
- e.printStackTrace();
- }
- }
-
- /**
- * Restart a secure connection suspended waiting for user interaction.
- */
- void restartConnection(boolean abort) {
- // not required for plain http connections
- }
-
- String getScheme() {
- return "http";
- }
-}
diff --git a/core/java/android/net/http/HttpLog.java b/core/java/android/net/http/HttpLog.java
deleted file mode 100644
index 30bf647549f..00000000000
--- a/core/java/android/net/http/HttpLog.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2007 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-level logging flag
- */
-
-package android.net.http;
-
-import android.os.SystemClock;
-
-import android.util.Log;
-import android.util.Config;
-
-/**
- * {@hide}
- */
-class HttpLog {
- private final static String LOGTAG = "http";
-
- private static final boolean DEBUG = false;
- static final boolean LOGV = DEBUG ? Config.LOGD : Config.LOGV;
-
- static void v(String logMe) {
- Log.v(LOGTAG, SystemClock.uptimeMillis() + " " + Thread.currentThread().getName() + " " + logMe);
- }
-
- static void e(String logMe) {
- Log.e(LOGTAG, logMe);
- }
-}
diff --git a/core/java/android/net/http/HttpsConnection.java b/core/java/android/net/http/HttpsConnection.java
deleted file mode 100644
index fe02d3ea643..00000000000
--- a/core/java/android/net/http/HttpsConnection.java
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.net.http;
-
-import android.content.Context;
-
-import junit.framework.Assert;
-
-import java.io.IOException;
-
-import java.security.cert.X509Certificate;
-
-import java.net.Socket;
-import java.net.InetSocketAddress;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-import org.apache.http.Header;
-import org.apache.http.HttpClientConnection;
-import org.apache.http.HttpException;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.ParseException;
-import org.apache.http.ProtocolVersion;
-import org.apache.http.StatusLine;
-import org.apache.http.impl.DefaultHttpClientConnection;
-import org.apache.http.message.BasicHttpRequest;
-import org.apache.http.params.BasicHttpParams;
-import org.apache.http.params.HttpParams;
-import org.apache.http.params.HttpConnectionParams;
-
-/**
- * Simple exception we throw if the SSL connection is closed by the user.
- *
- * {@hide}
- */
-class SSLConnectionClosedByUserException extends SSLException {
-
- public SSLConnectionClosedByUserException(String reason) {
- super(reason);
- }
-}
-
-/**
- * A Connection connecting to a secure http server or tunneling through
- * a http proxy server to a https server.
- */
-class HttpsConnection extends Connection {
-
- /**
- * SSL context
- */
- private static SSLContext mSslContext = null;
-
- /**
- * SSL socket factory
- */
- private static SSLSocketFactory mSslSocketFactory = null;
-
- static {
- // initialize the socket factory
- try {
- mSslContext = SSLContext.getInstance("TLS");
- if (mSslContext != null) {
- // here, trust managers is a single trust-all manager
- TrustManager[] trustManagers = new TrustManager[] {
- new X509TrustManager() {
- public X509Certificate[] getAcceptedIssuers() {
- return null;
- }
-
- public void checkClientTrusted(
- X509Certificate[] certs, String authType) {
- }
-
- public void checkServerTrusted(
- X509Certificate[] certs, String authType) {
- }
- }
- };
-
- mSslContext.init(null, trustManagers, null);
- mSslSocketFactory = mSslContext.getSocketFactory();
- }
- } catch (Exception t) {
- if (HttpLog.LOGV) {
- HttpLog.v("HttpsConnection: failed to initialize the socket factory");
- }
- }
- }
-
- /**
- * @return The shared SSL context.
- */
- /*package*/ static SSLContext getContext() {
- return mSslContext;
- }
-
- /**
- * Object to wait on when suspending the SSL connection
- */
- private Object mSuspendLock = new Object();
-
- /**
- * True if the connection is suspended pending the result of asking the
- * user about an error.
- */
- private boolean mSuspended = false;
-
- /**
- * True if the connection attempt should be aborted due to an ssl
- * error.
- */
- private boolean mAborted = false;
-
- /**
- * Contructor for a https connection.
- */
- HttpsConnection(Context context, HttpHost host,
- RequestQueue.ConnectionManager connectionManager,
- RequestFeeder requestFeeder) {
- super(context, host, connectionManager, requestFeeder);
- }
-
- /**
- * Sets the server SSL certificate associated with this
- * connection.
- * @param certificate The SSL certificate
- */
- /* package */ void setCertificate(SslCertificate certificate) {
- mCertificate = certificate;
- }
-
- /**
- * Opens the connection to a http server or proxy.
- *
- * @return the opened low level connection
- * @throws IOException if the connection fails for any reason.
- */
- @Override
- AndroidHttpClientConnection openConnection(Request req) throws IOException {
- SSLSocket sslSock = null;
-
- HttpHost proxyHost = mConnectionManager.getProxyHost();
- if (proxyHost != null) {
- // If we have a proxy set, we first send a CONNECT request
- // to the proxy; if the proxy returns 200 OK, we negotiate
- // a secure connection to the target server via the proxy.
- // If the request fails, we drop it, but provide the event
- // handler with the response status and headers. The event
- // handler is then responsible for cancelling the load or
- // issueing a new request.
- AndroidHttpClientConnection proxyConnection = null;
- Socket proxySock = null;
- try {
- proxySock = new Socket
- (proxyHost.getHostName(), proxyHost.getPort());
-
- proxySock.setSoTimeout(60 * 1000);
-
- proxyConnection = new AndroidHttpClientConnection();
- HttpParams params = new BasicHttpParams();
- HttpConnectionParams.setSocketBufferSize(params, 8192);
-
- proxyConnection.bind(proxySock, params);
- } catch(IOException e) {
- if (proxyConnection != null) {
- proxyConnection.close();
- }
-
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage =
- "failed to establish a connection to the proxy";
- }
-
- throw new IOException(errorMessage);
- }
-
- StatusLine statusLine = null;
- int statusCode = 0;
- Headers headers = new Headers();
- try {
- BasicHttpRequest proxyReq = new BasicHttpRequest
- ("CONNECT", mHost.toHostString());
-
- // add all 'proxy' headers from the original request
- for (Header h : req.mHttpRequest.getAllHeaders()) {
- String headerName = h.getName().toLowerCase();
- if (headerName.startsWith("proxy") || headerName.equals("keep-alive")) {
- proxyReq.addHeader(h);
- }
- }
-
- proxyConnection.sendRequestHeader(proxyReq);
- proxyConnection.flush();
-
- // it is possible to receive informational status
- // codes prior to receiving actual headers;
- // all those status codes are smaller than OK 200
- // a loop is a standard way of dealing with them
- do {
- statusLine = proxyConnection.parseResponseHeader(headers);
- statusCode = statusLine.getStatusCode();
- } while (statusCode < HttpStatus.SC_OK);
- } catch (ParseException e) {
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage =
- "failed to send a CONNECT request";
- }
-
- throw new IOException(errorMessage);
- } catch (HttpException e) {
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage =
- "failed to send a CONNECT request";
- }
-
- throw new IOException(errorMessage);
- } catch (IOException e) {
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage =
- "failed to send a CONNECT request";
- }
-
- throw new IOException(errorMessage);
- }
-
- if (statusCode == HttpStatus.SC_OK) {
- try {
- synchronized (mSslSocketFactory) {
- sslSock = (SSLSocket) mSslSocketFactory.createSocket(
- proxySock, mHost.getHostName(), mHost.getPort(), true);
- }
- } catch(IOException e) {
- if (sslSock != null) {
- sslSock.close();
- }
-
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage =
- "failed to create an SSL socket";
- }
- throw new IOException(errorMessage);
- }
- } else {
- // if the code is not OK, inform the event handler
- ProtocolVersion version = statusLine.getProtocolVersion();
-
- req.mEventHandler.status(version.getMajor(),
- version.getMinor(),
- statusCode,
- statusLine.getReasonPhrase());
- req.mEventHandler.headers(headers);
- req.mEventHandler.endData();
-
- proxyConnection.close();
-
- // here, we return null to indicate that the original
- // request needs to be dropped
- return null;
- }
- } else {
- // if we do not have a proxy, we simply connect to the host
- try {
- synchronized (mSslSocketFactory) {
- sslSock = (SSLSocket) mSslSocketFactory.createSocket();
-
- sslSock.setSoTimeout(SOCKET_TIMEOUT);
- sslSock.connect(new InetSocketAddress(mHost.getHostName(),
- mHost.getPort()));
-
- }
- } catch(IOException e) {
- if (sslSock != null) {
- sslSock.close();
- }
-
- String errorMessage = e.getMessage();
- if (errorMessage == null) {
- errorMessage = "failed to create an SSL socket";
- }
-
- throw new IOException(errorMessage);
- }
- }
-
- // do handshake and validate server certificates
- SslError error = CertificateChainValidator.getInstance().
- doHandshakeAndValidateServerCertificates(this, sslSock, mHost.getHostName());
-
- EventHandler eventHandler = req.getEventHandler();
-
- // Update the certificate info (to be consistent, it is better to do it
- // here, before we start handling SSL errors, if any)
- eventHandler.certificate(mCertificate);
-
- // Inform the user if there is a problem
- if (error != null) {
- // handleSslErrorRequest may immediately unsuspend if it wants to
- // allow the certificate anyway.
- // So we mark the connection as suspended, call handleSslErrorRequest
- // then check if we're still suspended and only wait if we actually
- // need to.
- synchronized (mSuspendLock) {
- mSuspended = true;
- }
- // don't hold the lock while calling out to the event handler
- eventHandler.handleSslErrorRequest(error);
- synchronized (mSuspendLock) {
- if (mSuspended) {
- try {
- // Put a limit on how long we are waiting; if the timeout
- // expires (which should never happen unless you choose
- // to ignore the SSL error dialog for a very long time),
- // we wake up the thread and abort the request. This is
- // to prevent us from stalling the network if things go
- // very bad.
- mSuspendLock.wait(10 * 60 * 1000);
- if (mSuspended) {
- // mSuspended is true if we have not had a chance to
- // restart the connection yet (ie, the wait timeout
- // has expired)
- mSuspended = false;
- mAborted = true;
- if (HttpLog.LOGV) {
- HttpLog.v("HttpsConnection.openConnection():" +
- " SSL timeout expired and request was cancelled!!!");
- }
- }
- } catch (InterruptedException e) {
- // ignore
- }
- }
- if (mAborted) {
- // The user decided not to use this unverified connection
- // so close it immediately.
- sslSock.close();
- throw new SSLConnectionClosedByUserException("connection closed by the user");
- }
- }
- }
-
- // All went well, we have an open, verified connection.
- AndroidHttpClientConnection conn = new AndroidHttpClientConnection();
- BasicHttpParams params = new BasicHttpParams();
- params.setIntParameter(HttpConnectionParams.SOCKET_BUFFER_SIZE, 8192);
- conn.bind(sslSock, params);
- return conn;
- }
-
- /**
- * Closes the low level connection.
- *
- * If an exception is thrown then it is assumed that the connection will
- * have been closed (to the extent possible) anyway and the caller does not
- * need to take any further action.
- *
- */
- @Override
- void closeConnection() {
- // if the connection has been suspended due to an SSL error
- if (mSuspended) {
- // wake up the network thread
- restartConnection(false);
- }
-
- try {
- if (mHttpClientConnection != null && mHttpClientConnection.isOpen()) {
- mHttpClientConnection.close();
- }
- } catch (IOException e) {
- if (HttpLog.LOGV)
- HttpLog.v("HttpsConnection.closeConnection():" +
- " failed closing connection " + mHost);
- e.printStackTrace();
- }
- }
-
- /**
- * Restart a secure connection suspended waiting for user interaction.
- */
- void restartConnection(boolean proceed) {
- if (HttpLog.LOGV) {
- HttpLog.v("HttpsConnection.restartConnection():" +
- " proceed: " + proceed);
- }
-
- synchronized (mSuspendLock) {
- if (mSuspended) {
- mSuspended = false;
- mAborted = !proceed;
- mSuspendLock.notify();
- }
- }
- }
-
- @Override
- String getScheme() {
- return "https";
- }
-}
diff --git a/core/java/android/net/http/IdleCache.java b/core/java/android/net/http/IdleCache.java
deleted file mode 100644
index fda60091a57..00000000000
--- a/core/java/android/net/http/IdleCache.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-/**
- * Hangs onto idle live connections for a little while
- */
-
-package android.net.http;
-
-import org.apache.http.HttpHost;
-
-import android.os.SystemClock;
-
-/**
- * {@hide}
- */
-class IdleCache {
-
- class Entry {
- HttpHost mHost;
- Connection mConnection;
- long mTimeout;
- };
-
- private final static int IDLE_CACHE_MAX = 8;
-
- /* Allow five consecutive empty queue checks before shutdown */
- private final static int EMPTY_CHECK_MAX = 5;
-
- /* six second timeout for connections */
- private final static int TIMEOUT = 6 * 1000;
- private final static int CHECK_INTERVAL = 2 * 1000;
- private Entry[] mEntries = new Entry[IDLE_CACHE_MAX];
-
- private int mCount = 0;
-
- private IdleReaper mThread = null;
-
- /* stats */
- private int mCached = 0;
- private int mReused = 0;
-
- IdleCache() {
- for (int i = 0; i < IDLE_CACHE_MAX; i++) {
- mEntries[i] = new Entry();
- }
- }
-
- /**
- * Caches connection, if there is room.
- * @return true if connection cached
- */
- synchronized boolean cacheConnection(
- HttpHost host, Connection connection) {
-
- boolean ret = false;
-
- if (HttpLog.LOGV) {
- HttpLog.v("IdleCache size " + mCount + " host " + host);
- }
-
- if (mCount < IDLE_CACHE_MAX) {
- long time = SystemClock.uptimeMillis();
- for (int i = 0; i < IDLE_CACHE_MAX; i++) {
- Entry entry = mEntries[i];
- if (entry.mHost == null) {
- entry.mHost = host;
- entry.mConnection = connection;
- entry.mTimeout = time + TIMEOUT;
- mCount++;
- if (HttpLog.LOGV) mCached++;
- ret = true;
- if (mThread == null) {
- mThread = new IdleReaper();
- mThread.start();
- }
- break;
- }
- }
- }
- return ret;
- }
-
- synchronized Connection getConnection(HttpHost host) {
- Connection ret = null;
-
- if (mCount > 0) {
- for (int i = 0; i < IDLE_CACHE_MAX; i++) {
- Entry entry = mEntries[i];
- HttpHost eHost = entry.mHost;
- if (eHost != null && eHost.equals(host)) {
- ret = entry.mConnection;
- entry.mHost = null;
- entry.mConnection = null;
- mCount--;
- if (HttpLog.LOGV) mReused++;
- break;
- }
- }
- }
- return ret;
- }
-
- synchronized void clear() {
- for (int i = 0; mCount > 0 && i < IDLE_CACHE_MAX; i++) {
- Entry entry = mEntries[i];
- if (entry.mHost != null) {
- entry.mHost = null;
- entry.mConnection.closeConnection();
- entry.mConnection = null;
- mCount--;
- }
- }
- }
-
- private synchronized void clearIdle() {
- if (mCount > 0) {
- long time = SystemClock.uptimeMillis();
- for (int i = 0; i < IDLE_CACHE_MAX; i++) {
- Entry entry = mEntries[i];
- if (entry.mHost != null && time > entry.mTimeout) {
- entry.mHost = null;
- entry.mConnection.closeConnection();
- entry.mConnection = null;
- mCount--;
- }
- }
- }
- }
-
- private class IdleReaper extends Thread {
-
- public void run() {
- int check = 0;
-
- setName("IdleReaper");
- android.os.Process.setThreadPriority(
- android.os.Process.THREAD_PRIORITY_BACKGROUND);
- synchronized (IdleCache.this) {
- while (check < EMPTY_CHECK_MAX) {
- try {
- IdleCache.this.wait(CHECK_INTERVAL);
- } catch (InterruptedException ex) {
- }
- if (mCount == 0) {
- check++;
- } else {
- check = 0;
- clearIdle();
- }
- }
- mThread = null;
- }
- if (HttpLog.LOGV) {
- HttpLog.v("IdleCache IdleReaper shutdown: cached " + mCached +
- " reused " + mReused);
- mCached = 0;
- mReused = 0;
- }
- }
- }
-}
diff --git a/core/java/android/net/http/LoggingEventHandler.java b/core/java/android/net/http/LoggingEventHandler.java
deleted file mode 100644
index 1b18651bea8..00000000000
--- a/core/java/android/net/http/LoggingEventHandler.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * A test EventHandler: Logs everything received
- */
-
-package android.net.http;
-
-import android.net.http.Headers;
-
-/**
- * {@hide}
- */
-public class LoggingEventHandler implements EventHandler {
-
- public void requestSent() {
- HttpLog.v("LoggingEventHandler:requestSent()");
- }
-
- public void status(int major_version,
- int minor_version,
- int code, /* Status-Code value */
- String reason_phrase) {
- if (HttpLog.LOGV) {
- HttpLog.v("LoggingEventHandler:status() major: " + major_version +
- " minor: " + minor_version +
- " code: " + code +
- " reason: " + reason_phrase);
- }
- }
-
- public void headers(Headers headers) {
- if (HttpLog.LOGV) {
- HttpLog.v("LoggingEventHandler:headers()");
- HttpLog.v(headers.toString());
- }
- }
-
- public void locationChanged(String newLocation, boolean permanent) {
- if (HttpLog.LOGV) {
- HttpLog.v("LoggingEventHandler: locationChanged() " + newLocation +
- " permanent " + permanent);
- }
- }
-
- public void data(byte[] data, int len) {
- if (HttpLog.LOGV) {
- HttpLog.v("LoggingEventHandler: data() " + len + " bytes");
- }
- // HttpLog.v(new String(data, 0, len));
- }
- public void endData() {
- if (HttpLog.LOGV) {
- HttpLog.v("LoggingEventHandler: endData() called");
- }
- }
-
- public void certificate(SslCertificate certificate) {
- if (HttpLog.LOGV) {
- HttpLog.v("LoggingEventHandler: certificate(): " + certificate);
- }
- }
-
- public void error(int id, String description) {
- if (HttpLog.LOGV) {
- HttpLog.v("LoggingEventHandler: error() called Id:" + id +
- " description " + description);
- }
- }
-
- public void handleSslErrorRequest(SslError error) {
- if (HttpLog.LOGV) {
- HttpLog.v("LoggingEventHandler: handleSslErrorRequest():" + error);
- }
- }
-}
diff --git a/core/java/android/net/http/Request.java b/core/java/android/net/http/Request.java
deleted file mode 100644
index df4fff015dc..00000000000
--- a/core/java/android/net/http/Request.java
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * 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 android.net.http;
-
-import java.io.EOFException;
-import java.io.InputStream;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.zip.GZIPInputStream;
-
-import org.apache.http.entity.InputStreamEntity;
-import org.apache.http.Header;
-import org.apache.http.HttpClientConnection;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpException;
-import org.apache.http.HttpHost;
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.ParseException;
-import org.apache.http.ProtocolVersion;
-
-import org.apache.http.StatusLine;
-import org.apache.http.message.BasicHttpRequest;
-import org.apache.http.message.BasicHttpEntityEnclosingRequest;
-import org.apache.http.protocol.RequestContent;
-
-/**
- * Represents an HTTP request for a given host.
- *
- * {@hide}
- */
-
-class Request {
-
- /** The eventhandler to call as the request progresses */
- EventHandler mEventHandler;
-
- private Connection mConnection;
-
- /** The Apache http request */
- BasicHttpRequest mHttpRequest;
-
- /** The path component of this request */
- String mPath;
-
- /** Host serving this request */
- HttpHost mHost;
-
- /** Set if I'm using a proxy server */
- HttpHost mProxyHost;
-
- /** True if request is .html, .js, .css */
- boolean mHighPriority;
-
- /** True if request has been cancelled */
- volatile boolean mCancelled = false;
-
- int mFailCount = 0;
-
- private InputStream mBodyProvider;
- private int mBodyLength;
-
- private final static String HOST_HEADER = "Host";
- private final static String ACCEPT_ENCODING_HEADER = "Accept-Encoding";
- private final static String CONTENT_LENGTH_HEADER = "content-length";
-
- /* Used to synchronize waitUntilComplete() requests */
- private final Object mClientResource = new Object();
-
- /**
- * Processor used to set content-length and transfer-encoding
- * headers.
- */
- private static RequestContent requestContentProcessor =
- new RequestContent();
-
- /**
- * Instantiates a new Request.
- * @param method GET/POST/PUT
- * @param host The server that will handle this request
- * @param path path part of URI
- * @param bodyProvider InputStream providing HTTP body, null if none
- * @param bodyLength length of body, must be 0 if bodyProvider is null
- * @param eventHandler request will make progress callbacks on
- * this interface
- * @param headers reqeust headers
- * @param highPriority true for .html, css, .cs
- */
- Request(String method, HttpHost host, HttpHost proxyHost, String path,
- InputStream bodyProvider, int bodyLength,
- EventHandler eventHandler,
- Map<String, String> headers, boolean highPriority) {
- mEventHandler = eventHandler;
- mHost = host;
- mProxyHost = proxyHost;
- mPath = path;
- mHighPriority = highPriority;
- mBodyProvider = bodyProvider;
- mBodyLength = bodyLength;
-
- if (bodyProvider == null) {
- mHttpRequest = new BasicHttpRequest(method, getUri());
- } else {
- mHttpRequest = new BasicHttpEntityEnclosingRequest(
- method, getUri());
- setBodyProvider(bodyProvider, bodyLength);
- }
- addHeader(HOST_HEADER, getHostPort());
-
- /* FIXME: if webcore will make the root document a
- high-priority request, we can ask for gzip encoding only on
- high priority reqs (saving the trouble for images, etc) */
- addHeader(ACCEPT_ENCODING_HEADER, "gzip");
- addHeaders(headers);
- }
-
- /**
- * @param connection Request served by this connection
- */
- void setConnection(Connection connection) {
- mConnection = connection;
- }
-
- /* package */ EventHandler getEventHandler() {
- return mEventHandler;
- }
-
- /**
- * Add header represented by given pair to request. Header will
- * be formatted in request as "name: value\r\n".
- * @param name of header
- * @param value of header
- */
- void addHeader(String name, String value) {
- if (name == null) {
- String damage = "Null http header name";
- HttpLog.e(damage);
- throw new NullPointerException(damage);
- }
- if (value == null || value.length() == 0) {
- String damage = "Null or empty value for header \"" + name + "\"";
- HttpLog.e(damage);
- throw new RuntimeException(damage);
- }
- mHttpRequest.addHeader(name, value);
- }
-
- /**
- * Add all headers in given map to this request. This is a helper
- * method: it calls addHeader for each pair in the map.
- */
- void addHeaders(Map<String, String> headers) {
- if (headers == null) {
- return;
- }
-
- Entry<String, String> entry;
- Iterator<Entry<String, String>> i = headers.entrySet().iterator();
- while (i.hasNext()) {
- entry = i.next();
- addHeader(entry.getKey(), entry.getValue());
- }
- }
-
- /**
- * Send the request line and headers
- */
- void sendRequest(AndroidHttpClientConnection httpClientConnection)
- throws HttpException, IOException {
-
- if (mCancelled) return; // don't send cancelled requests
-
- if (HttpLog.LOGV) {
- HttpLog.v("Request.sendRequest() " + mHost.getSchemeName() + "://" + getHostPort());
- // HttpLog.v(mHttpRequest.getRequestLine().toString());
- if (false) {
- Iterator i = mHttpRequest.headerIterator();
- while (i.hasNext()) {
- Header header = (Header)i.next();
- HttpLog.v(header.getName() + ": " + header.getValue());
- }
- }
- }
-
- requestContentProcessor.process(mHttpRequest,
- mConnection.getHttpContext());
- httpClientConnection.sendRequestHeader(mHttpRequest);
- if (mHttpRequest instanceof HttpEntityEnclosingRequest) {
- httpClientConnection.sendRequestEntity(
- (HttpEntityEnclosingRequest) mHttpRequest);
- }
-
- if (HttpLog.LOGV) {
- HttpLog.v("Request.requestSent() " + mHost.getSchemeName() + "://" + getHostPort() + mPath);
- }
- }
-
-
- /**
- * Receive a single http response.
- *
- * @param httpClientConnection the request to receive the response for.
- */
- void readResponse(AndroidHttpClientConnection httpClientConnection)
- throws IOException, ParseException {
-
- if (mCancelled) return; // don't send cancelled requests
-
- StatusLine statusLine = null;
- boolean hasBody = false;
- boolean reuse = false;
- httpClientConnection.flush();
- int statusCode = 0;
-
- Headers header = new Headers();
- do {
- statusLine = httpClientConnection.parseResponseHeader(header);
- statusCode = statusLine.getStatusCode();
- } while (statusCode < HttpStatus.SC_OK);
- if (HttpLog.LOGV) HttpLog.v(
- "Request.readResponseStatus() " +
- statusLine.toString().length() + " " + statusLine);
-
- ProtocolVersion v = statusLine.getProtocolVersion();
- mEventHandler.status(v.getMajor(), v.getMinor(),
- statusCode, statusLine.getReasonPhrase());
- mEventHandler.headers(header);
- HttpEntity entity = null;
- hasBody = canResponseHaveBody(mHttpRequest, statusCode);
-
- if (hasBody)
- entity = httpClientConnection.receiveResponseEntity(header);
-
- if (entity != null) {
- InputStream is = entity.getContent();
-
- // process gzip content encoding
- Header contentEncoding = entity.getContentEncoding();
- InputStream nis = null;
- try {
- if (contentEncoding != null &&
- contentEncoding.getValue().equals("gzip")) {
- nis = new GZIPInputStream(is);
- } else {
- nis = is;
- }
-
- /* accumulate enough data to make it worth pushing it
- * up the stack */
- byte[] buf = mConnection.getBuf();
- int len = 0;
- int count = 0;
- int lowWater = buf.length / 2;
- while (len != -1) {
- len = nis.read(buf, count, buf.length - count);
- if (len != -1) {
- count += len;
- }
- if (len == -1 || count >= lowWater) {
- if (HttpLog.LOGV) HttpLog.v("Request.readResponse() " + count);
- mEventHandler.data(buf, count);
- count = 0;
- }
- }
- } catch (EOFException e) {
- /* InflaterInputStream throws an EOFException when the
- server truncates gzipped content. Handle this case
- as we do truncated non-gzipped content: no error */
- if (HttpLog.LOGV) HttpLog.v( "readResponse() handling " + e);
- } catch(IOException e) {
- // don't throw if we have a non-OK status code
- if (statusCode == HttpStatus.SC_OK) {
- throw e;
- }
- } finally {
- if (nis != null) {
- nis.close();
- }
- }
- }
- mConnection.setCanPersist(entity, statusLine.getProtocolVersion(),
- header.getConnectionType());
- mEventHandler.endData();
- complete();
-
- if (HttpLog.LOGV) HttpLog.v("Request.readResponse(): done " +
- mHost.getSchemeName() + "://" + getHostPort() + mPath);
- }
-
- /**
- * Data will not be sent to or received from server after cancel()
- * call. Does not close connection--use close() below for that.
- *
- * Called by RequestHandle from non-network thread
- */
- void cancel() {
- if (HttpLog.LOGV) {
- HttpLog.v("Request.cancel(): " + getUri());
- }
- mCancelled = true;
- if (mConnection != null) {
- mConnection.cancel();
- }
- }
-
- String getHostPort() {
- String myScheme = mHost.getSchemeName();
- int myPort = mHost.getPort();
-
- // Only send port when we must... many servers can't deal with it
- if (myPort != 80 && myScheme.equals("http") ||
- myPort != 443 && myScheme.equals("https")) {
- return mHost.toHostString();
- } else {
- return mHost.getHostName();
- }
- }
-
- String getUri() {
- if (mProxyHost == null ||
- mHost.getSchemeName().equals("https")) {
- return mPath;
- }
- return mHost.getSchemeName() + "://" + getHostPort() + mPath;
- }
-
- /**
- * for debugging
- */
- public String toString() {
- return (mHighPriority ? "P*" : "") + mPath;
- }
-
-
- /**
- * If this request has been sent once and failed, it must be reset
- * before it can be sent again.
- */
- void reset() {
- /* clear content-length header */
- mHttpRequest.removeHeaders(CONTENT_LENGTH_HEADER);
-
- if (mBodyProvider != null) {
- try {
- mBodyProvider.reset();
- } catch (IOException ex) {
- if (HttpLog.LOGV) HttpLog.v(
- "failed to reset body provider " +
- getUri());
- }
- setBodyProvider(mBodyProvider, mBodyLength);
- }
- }
-
- /**
- * Pause thread request completes. Used for synchronous requests,
- * and testing
- */
- void waitUntilComplete() {
- synchronized (mClientResource) {
- try {
- if (HttpLog.LOGV) HttpLog.v("Request.waitUntilComplete()");
- mClientResource.wait();
- if (HttpLog.LOGV) HttpLog.v("Request.waitUntilComplete() done waiting");
- } catch (InterruptedException e) {
- }
- }
- }
-
- void complete() {
- synchronized (mClientResource) {
- mClientResource.notifyAll();
- }
- }
-
- /**
- * Decide whether a response comes with an entity.
- * The implementation in this class is based on RFC 2616.
- * Unknown methods and response codes are supposed to
- * indicate responses with an entity.
- * <br/>
- * Derived executors can override this method to handle
- * methods and response codes not specified in RFC 2616.
- *
- * @param request the request, to obtain the executed method
- * @param response the response, to obtain the status code
- */
-
- private static boolean canResponseHaveBody(final HttpRequest request,
- final int status) {
-
- if ("HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) {
- return false;
- }
- return status >= HttpStatus.SC_OK
- && status != HttpStatus.SC_NO_CONTENT
- && status != HttpStatus.SC_NOT_MODIFIED
- && status != HttpStatus.SC_RESET_CONTENT;
- }
-
- /**
- * Supply an InputStream that provides the body of a request. It's
- * not great that the caller must also provide the length of the data
- * returned by that InputStream, but the client needs to know up
- * front, and I'm not sure how to get this out of the InputStream
- * itself without a costly readthrough. I'm not sure skip() would
- * do what we want. If you know a better way, please let me know.
- */
- private void setBodyProvider(InputStream bodyProvider, int bodyLength) {
- if (!bodyProvider.markSupported()) {
- throw new IllegalArgumentException(
- "bodyProvider must support mark()");
- }
- // Mark beginning of stream
- bodyProvider.mark(Integer.MAX_VALUE);
-
- ((BasicHttpEntityEnclosingRequest)mHttpRequest).setEntity(
- new InputStreamEntity(bodyProvider, bodyLength));
- }
-
-
- /**
- * Handles SSL error(s) on the way down from the user (the user
- * has already provided their feedback).
- */
- public void handleSslErrorResponse(boolean proceed) {
- HttpsConnection connection = (HttpsConnection)(mConnection);
- if (connection != null) {
- connection.restartConnection(proceed);
- }
- }
-
- /**
- * Helper: calls error() on eventhandler with appropriate message
- * This should not be called before the mConnection is set.
- */
- void error(int errorId, int resourceId) {
- mEventHandler.error(
- errorId,
- mConnection.mContext.getText(
- resourceId).toString());
- }
-
-}
diff --git a/core/java/android/net/http/RequestFeeder.java b/core/java/android/net/http/RequestFeeder.java
deleted file mode 100644
index 34ca267271b..00000000000
--- a/core/java/android/net/http/RequestFeeder.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-/**
- * Supplies Requests to a Connection
- */
-
-package android.net.http;
-
-import org.apache.http.HttpHost;
-
-/**
- * {@hide}
- */
-interface RequestFeeder {
-
- Request getRequest();
- Request getRequest(HttpHost host);
-
- /**
- * @return true if a request for this host is available
- */
- boolean haveRequest(HttpHost host);
-
- /**
- * Put request back on head of queue
- */
- void requeueRequest(Request request);
-}
diff --git a/core/java/android/net/http/RequestHandle.java b/core/java/android/net/http/RequestHandle.java
deleted file mode 100644
index c4ee5b0da0e..00000000000
--- a/core/java/android/net/http/RequestHandle.java
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * 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 android.net.http;
-
-import android.net.ParseException;
-import android.net.WebAddress;
-import android.security.Md5MessageDigest;
-import junit.framework.Assert;
-import android.webkit.CookieManager;
-
-import org.apache.commons.codec.binary.Base64;
-
-import java.io.InputStream;
-import java.lang.Math;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Random;
-
-/**
- * RequestHandle: handles a request session that may include multiple
- * redirects, HTTP authentication requests, etc.
- *
- * {@hide}
- */
-public class RequestHandle {
-
- private String mUrl;
- private WebAddress mUri;
- private String mMethod;
- private Map<String, String> mHeaders;
-
- private RequestQueue mRequestQueue;
-
- private Request mRequest;
-
- private InputStream mBodyProvider;
- private int mBodyLength;
-
- private int mRedirectCount = 0;
-
- private final static String AUTHORIZATION_HEADER = "Authorization";
- private final static String PROXY_AUTHORIZATION_HEADER = "Proxy-Authorization";
-
- public final static int MAX_REDIRECT_COUNT = 16;
-
- /**
- * Creates a new request session.
- */
- public RequestHandle(RequestQueue requestQueue, String url, WebAddress uri,
- String method, Map<String, String> headers,
- InputStream bodyProvider, int bodyLength, Request request) {
-
- if (headers == null) {
- headers = new HashMap<String, String>();
- }
- mHeaders = headers;
- mBodyProvider = bodyProvider;
- mBodyLength = bodyLength;
- mMethod = method == null? "GET" : method;
-
- mUrl = url;
- mUri = uri;
-
- mRequestQueue = requestQueue;
-
- mRequest = request;
- }
-
- /**
- * Cancels this request
- */
- public void cancel() {
- if (mRequest != null) {
- mRequest.cancel();
- }
- }
-
- /**
- * Handles SSL error(s) on the way down from the user (the user
- * has already provided their feedback).
- */
- public void handleSslErrorResponse(boolean proceed) {
- if (mRequest != null) {
- mRequest.handleSslErrorResponse(proceed);
- }
- }
-
- /**
- * @return true if we've hit the max redirect count
- */
- public boolean isRedirectMax() {
- return mRedirectCount >= MAX_REDIRECT_COUNT;
- }
-
- public int getRedirectCount() {
- return mRedirectCount;
- }
-
- public void setRedirectCount(int count) {
- mRedirectCount = count;
- }
-
- /**
- * Create and queue a redirect request.
- *
- * @param redirectTo URL to redirect to
- * @param statusCode HTTP status code returned from original request
- * @param cacheHeaders Cache header for redirect URL
- * @return true if setup succeeds, false otherwise (redirect loop
- * count exceeded, body provider unable to rewind on 307 redirect)
- */
- public boolean setupRedirect(String redirectTo, int statusCode,
- Map<String, String> cacheHeaders) {
- if (HttpLog.LOGV) {
- HttpLog.v("RequestHandle.setupRedirect(): redirectCount " +
- mRedirectCount);
- }
-
- // be careful and remove authentication headers, if any
- mHeaders.remove(AUTHORIZATION_HEADER);
- mHeaders.remove(PROXY_AUTHORIZATION_HEADER);
-
- if (++mRedirectCount == MAX_REDIRECT_COUNT) {
- // Way too many redirects -- fail out
- if (HttpLog.LOGV) HttpLog.v(
- "RequestHandle.setupRedirect(): too many redirects " +
- mRequest);
- mRequest.error(EventHandler.ERROR_REDIRECT_LOOP,
- com.android.internal.R.string.httpErrorRedirectLoop);
- return false;
- }
-
- if (mUrl.startsWith("https:") && redirectTo.startsWith("http:")) {
- // implement http://www.w3.org/Protocols/rfc2616/rfc2616-sec15.html#sec15.1.3
- if (HttpLog.LOGV) {
- HttpLog.v("blowing away the referer on an https -> http redirect");
- }
- mHeaders.remove("Referer");
- }
-
- mUrl = redirectTo;
- try {
- mUri = new WebAddress(mUrl);
- } catch (ParseException e) {
- e.printStackTrace();
- }
-
- // update the "cookie" header based on the redirected url
- mHeaders.remove("cookie");
- String cookie = CookieManager.getInstance().getCookie(mUri);
- if (cookie != null && cookie.length() > 0) {
- mHeaders.put("cookie", cookie);
- }
-
- if ((statusCode == 302 || statusCode == 303) && mMethod.equals("POST")) {
- if (HttpLog.LOGV) {
- HttpLog.v("replacing POST with GET on redirect to " + redirectTo);
- }
- mMethod = "GET";
- }
- /* Only repost content on a 307. If 307, reset the body
- provider so we can replay the body */
- if (statusCode == 307) {
- try {
- if (mBodyProvider != null) mBodyProvider.reset();
- } catch (java.io.IOException ex) {
- if (HttpLog.LOGV) {
- HttpLog.v("setupAuthResponse() failed to reset body provider");
- }
- return false;
- }
-
- } else {
- mHeaders.remove("Content-Type");
- mBodyProvider = null;
- }
-
- // Update the cache headers for this URL
- mHeaders.putAll(cacheHeaders);
-
- createAndQueueNewRequest();
- return true;
- }
-
- /**
- * Create and queue an HTTP authentication-response (basic) request.
- */
- public void setupBasicAuthResponse(boolean isProxy, String username, String password) {
- String response = computeBasicAuthResponse(username, password);
- if (HttpLog.LOGV) {
- HttpLog.v("setupBasicAuthResponse(): response: " + response);
- }
- mHeaders.put(authorizationHeader(isProxy), "Basic " + response);
- setupAuthResponse();
- }
-
- /**
- * Create and queue an HTTP authentication-response (digest) request.
- */
- public void setupDigestAuthResponse(boolean isProxy,
- String username,
- String password,
- String realm,
- String nonce,
- String QOP,
- String algorithm,
- String opaque) {
-
- String response = computeDigestAuthResponse(
- username, password, realm, nonce, QOP, algorithm, opaque);
- if (HttpLog.LOGV) {
- HttpLog.v("setupDigestAuthResponse(): response: " + response);
- }
- mHeaders.put(authorizationHeader(isProxy), "Digest " + response);
- setupAuthResponse();
- }
-
- private void setupAuthResponse() {
- try {
- if (mBodyProvider != null) mBodyProvider.reset();
- } catch (java.io.IOException ex) {
- if (HttpLog.LOGV) {
- HttpLog.v("setupAuthResponse() failed to reset body provider");
- }
- }
- createAndQueueNewRequest();
- }
-
- /**
- * @return HTTP request method (GET, PUT, etc).
- */
- public String getMethod() {
- return mMethod;
- }
-
- /**
- * @return Basic-scheme authentication response: BASE64(username:password).
- */
- public static String computeBasicAuthResponse(String username, String password) {
- Assert.assertNotNull(username);
- Assert.assertNotNull(password);
-
- // encode username:password to base64
- return new String(Base64.encodeBase64((username + ':' + password).getBytes()));
- }
-
- public void waitUntilComplete() {
- mRequest.waitUntilComplete();
- }
-
- /**
- * @return Digest-scheme authentication response.
- */
- private String computeDigestAuthResponse(String username,
- String password,
- String realm,
- String nonce,
- String QOP,
- String algorithm,
- String opaque) {
-
- Assert.assertNotNull(username);
- Assert.assertNotNull(password);
- Assert.assertNotNull(realm);
-
- String A1 = username + ":" + realm + ":" + password;
- String A2 = mMethod + ":" + mUrl;
-
- // because we do not preemptively send authorization headers, nc is always 1
- String nc = "000001";
- String cnonce = computeCnonce();
- String digest = computeDigest(A1, A2, nonce, QOP, nc, cnonce);
-
- String response = "";
- response += "username=" + doubleQuote(username) + ", ";
- response += "realm=" + doubleQuote(realm) + ", ";
- response += "nonce=" + doubleQuote(nonce) + ", ";
- response += "uri=" + doubleQuote(mUrl) + ", ";
- response += "response=" + doubleQuote(digest) ;
-
- if (opaque != null) {
- response += ", opaque=" + doubleQuote(opaque);
- }
-
- if (algorithm != null) {
- response += ", algorithm=" + algorithm;
- }
-
- if (QOP != null) {
- response += ", qop=" + QOP + ", nc=" + nc + ", cnonce=" + doubleQuote(cnonce);
- }
-
- return response;
- }
-
- /**
- * @return The right authorization header (dependeing on whether it is a proxy or not).
- */
- public static String authorizationHeader(boolean isProxy) {
- if (!isProxy) {
- return AUTHORIZATION_HEADER;
- } else {
- return PROXY_AUTHORIZATION_HEADER;
- }
- }
-
- /**
- * @return Double-quoted MD5 digest.
- */
- private String computeDigest(
- String A1, String A2, String nonce, String QOP, String nc, String cnonce) {
- if (HttpLog.LOGV) {
- HttpLog.v("computeDigest(): QOP: " + QOP);
- }
-
- if (QOP == null) {
- return KD(H(A1), nonce + ":" + H(A2));
- } else {
- if (QOP.equalsIgnoreCase("auth")) {
- return KD(H(A1), nonce + ":" + nc + ":" + cnonce + ":" + QOP + ":" + H(A2));
- }
- }
-
- return null;
- }
-
- /**
- * @return MD5 hash of concat(secret, ":", data).
- */
- private String KD(String secret, String data) {
- return H(secret + ":" + data);
- }
-
- /**
- * @return MD5 hash of param.
- */
- private String H(String param) {
- if (param != null) {
- Md5MessageDigest md5 = new Md5MessageDigest();
-
- byte[] d = md5.digest(param.getBytes());
- if (d != null) {
- return bufferToHex(d);
- }
- }
-
- return null;
- }
-
- /**
- * @return HEX buffer representation.
- */
- private String bufferToHex(byte[] buffer) {
- final char hexChars[] =
- { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
-
- if (buffer != null) {
- int length = buffer.length;
- if (length > 0) {
- StringBuilder hex = new StringBuilder(2 * length);
-
- for (int i = 0; i < length; ++i) {
- byte l = (byte) (buffer[i] & 0x0F);
- byte h = (byte)((buffer[i] & 0xF0) >> 4);
-
- hex.append(hexChars[h]);
- hex.append(hexChars[l]);
- }
-
- return hex.toString();
- } else {
- return "";
- }
- }
-
- return null;
- }
-
- /**
- * Computes a random cnonce value based on the current time.
- */
- private String computeCnonce() {
- Random rand = new Random();
- int nextInt = rand.nextInt();
- nextInt = (nextInt == Integer.MIN_VALUE) ?
- Integer.MAX_VALUE : Math.abs(nextInt);
- return Integer.toString(nextInt, 16);
- }
-
- /**
- * "Double-quotes" the argument.
- */
- private String doubleQuote(String param) {
- if (param != null) {
- return "\"" + param + "\"";
- }
-
- return null;
- }
-
- /**
- * Creates and queues new request.
- */
- private void createAndQueueNewRequest() {
- mRequest = mRequestQueue.queueRequest(
- mUrl, mUri, mMethod, mHeaders, mRequest.mEventHandler,
- mBodyProvider,
- mBodyLength, mRequest.mHighPriority).mRequest;
- }
-}
diff --git a/core/java/android/net/http/RequestQueue.java b/core/java/android/net/http/RequestQueue.java
deleted file mode 100644
index 66d572288f1..00000000000
--- a/core/java/android/net/http/RequestQueue.java
+++ /dev/null
@@ -1,647 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * High level HTTP Interface
- * Queues requests as necessary
- */
-
-package android.net.http;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.ConnectivityManager;
-import android.net.NetworkConnectivityListener;
-import android.net.NetworkInfo;
-import android.net.Proxy;
-import android.net.WebAddress;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.InputStream;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Map;
-
-import org.apache.http.HttpHost;
-
-/**
- * {@hide}
- */
-public class RequestQueue implements RequestFeeder {
-
- private Context mContext;
-
- /**
- * Requests, indexed by HttpHost (scheme, host, port)
- */
- private LinkedHashMap<HttpHost, LinkedList<Request>> mPending;
-
- /* Support for notifying a client when queue is empty */
- private boolean mClientWaiting = false;
-
- /** true if connected */
- boolean mNetworkConnected = true;
-
- private HttpHost mProxyHost = null;
- private BroadcastReceiver mProxyChangeReceiver;
-
- private ActivePool mActivePool;
-
- /* default simultaneous connection count */
- private static final int CONNECTION_COUNT = 4;
-
- /**
- * This intent broadcast when http is paused or unpaused due to
- * net availability toggling
- */
- public final static String HTTP_NETWORK_STATE_CHANGED_INTENT =
- "android.net.http.NETWORK_STATE";
- public final static String HTTP_NETWORK_STATE_UP = "up";
-
- /**
- * Listen to platform network state. On a change,
- * (1) kick stack on or off as appropriate
- * (2) send an intent to my host app telling
- * it what I've done
- */
- private NetworkStateTracker mNetworkStateTracker;
- class NetworkStateTracker {
-
- final static int EVENT_DATA_STATE_CHANGED = 100;
-
- Context mContext;
- NetworkConnectivityListener mConnectivityListener;
- NetworkInfo.State mLastNetworkState = NetworkInfo.State.CONNECTED;
- int mCurrentNetworkType;
-
- NetworkStateTracker(Context context) {
- mContext = context;
- }
-
- /**
- * register for updates
- */
- protected void enable() {
- if (mConnectivityListener == null) {
- /*
- * Initializing the network type is really unnecessary,
- * since as soon as we register with the NCL, we'll
- * get a CONNECTED event for the active network, and
- * we'll configure the HTTP proxy accordingly. However,
- * as a fallback in case that doesn't happen for some
- * reason, initializing to type WIFI would mean that
- * we'd start out without a proxy. This seems better
- * than thinking we have a proxy (which is probably
- * private to the carrier network and therefore
- * unreachable outside of that network) when we really
- * shouldn't.
- */
- mCurrentNetworkType = ConnectivityManager.TYPE_WIFI;
- mConnectivityListener = new NetworkConnectivityListener();
- mConnectivityListener.registerHandler(mHandler, EVENT_DATA_STATE_CHANGED);
- mConnectivityListener.startListening(mContext);
- }
- }
-
- protected void disable() {
- if (mConnectivityListener != null) {
- mConnectivityListener.unregisterHandler(mHandler);
- mConnectivityListener.stopListening();
- mConnectivityListener = null;
- }
- }
-
- private Handler mHandler = new Handler() {
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case EVENT_DATA_STATE_CHANGED:
- networkStateChanged();
- break;
- }
- }
- };
-
- int getCurrentNetworkType() {
- return mCurrentNetworkType;
- }
-
- void networkStateChanged() {
- if (mConnectivityListener == null)
- return;
-
-
- NetworkConnectivityListener.State connectivityState = mConnectivityListener.getState();
- NetworkInfo info = mConnectivityListener.getNetworkInfo();
- if (info == null) {
- /**
- * We've been seeing occasional NPEs here. I believe recent changes
- * have made this impossible, but in the interest of being totally
- * paranoid, check and log this here.
- */
- HttpLog.v("NetworkStateTracker: connectivity broadcast"
- + " has null network info - ignoring");
- return;
- }
- NetworkInfo.State state = info.getState();
-
- if (HttpLog.LOGV) {
- HttpLog.v("NetworkStateTracker " + info.getTypeName() +
- " state= " + state + " last= " + mLastNetworkState +
- " connectivityState= " + connectivityState.toString());
- }
-
- boolean newConnection =
- state != mLastNetworkState && state == NetworkInfo.State.CONNECTED;
-
- if (state == NetworkInfo.State.CONNECTED) {
- mCurrentNetworkType = info.getType();
- setProxyConfig();
- }
-
- mLastNetworkState = state;
- if (connectivityState == NetworkConnectivityListener.State.NOT_CONNECTED) {
- setNetworkState(false);
- broadcastState(false);
- } else if (newConnection) {
- setNetworkState(true);
- broadcastState(true);
- }
-
- }
-
- void broadcastState(boolean connected) {
- Intent intent = new Intent(HTTP_NETWORK_STATE_CHANGED_INTENT);
- intent.putExtra(HTTP_NETWORK_STATE_UP, connected);
- mContext.sendBroadcast(intent);
- }
- }
-
- /**
- * This class maintains active connection threads
- */
- class ActivePool implements ConnectionManager {
- /** Threads used to process requests */
- ConnectionThread[] mThreads;
-
- IdleCache mIdleCache;
-
- private int mTotalRequest;
- private int mTotalConnection;
- private int mConnectionCount;
-
- ActivePool(int connectionCount) {
- mIdleCache = new IdleCache();
- mConnectionCount = connectionCount;
- mThreads = new ConnectionThread[mConnectionCount];
-
- for (int i = 0; i < mConnectionCount; i++) {
- mThreads[i] = new ConnectionThread(
- mContext, i, this, RequestQueue.this);
- }
- }
-
- void startup() {
- for (int i = 0; i < mConnectionCount; i++) {
- mThreads[i].start();
- }
- }
-
- void shutdown() {
- for (int i = 0; i < mConnectionCount; i++) {
- mThreads[i].requestStop();
- }
- }
-
- public boolean isNetworkConnected() {
- return mNetworkConnected;
- }
-
- void startConnectionThread() {
- synchronized (RequestQueue.this) {
- RequestQueue.this.notify();
- }
- }
-
- public void startTiming() {
- for (int i = 0; i < mConnectionCount; i++) {
- mThreads[i].mStartThreadTime = mThreads[i].mCurrentThreadTime;
- }
- mTotalRequest = 0;
- mTotalConnection = 0;
- }
-
- public void stopTiming() {
- int totalTime = 0;
- for (int i = 0; i < mConnectionCount; i++) {
- ConnectionThread rt = mThreads[i];
- totalTime += (rt.mCurrentThreadTime - rt.mStartThreadTime);
- rt.mStartThreadTime = -1;
- }
- Log.d("Http", "Http thread used " + totalTime + " ms " + " for "
- + mTotalRequest + " requests and " + mTotalConnection
- + " connections");
- }
-
- void logState() {
- StringBuilder dump = new StringBuilder();
- for (int i = 0; i < mConnectionCount; i++) {
- dump.append(mThreads[i] + "\n");
- }
- HttpLog.v(dump.toString());
- }
-
-
- public HttpHost getProxyHost() {
- return mProxyHost;
- }
-
- /**
- * Turns off persistence on all live connections
- */
- void disablePersistence() {
- for (int i = 0; i < mConnectionCount; i++) {
- Connection connection = mThreads[i].mConnection;
- if (connection != null) connection.setCanPersist(false);
- }
- mIdleCache.clear();
- }
-
- /* Linear lookup -- okay for small thread counts. Might use
- private HashMap<HttpHost, LinkedList<ConnectionThread>> mActiveMap;
- if this turns out to be a hotspot */
- ConnectionThread getThread(HttpHost host) {
- synchronized(RequestQueue.this) {
- for (int i = 0; i < mThreads.length; i++) {
- ConnectionThread ct = mThreads[i];
- Connection connection = ct.mConnection;
- if (connection != null && connection.mHost.equals(host)) {
- return ct;
- }
- }
- }
- return null;
- }
-
- public Connection getConnection(Context context, HttpHost host) {
- Connection con = mIdleCache.getConnection(host);
- if (con == null) {
- mTotalConnection++;
- con = Connection.getConnection(
- mContext, host, this, RequestQueue.this);
- }
- return con;
- }
- public boolean recycleConnection(HttpHost host, Connection connection) {
- return mIdleCache.cacheConnection(host, connection);
- }
-
- }
-
- /**
- * A RequestQueue class instance maintains a set of queued
- * requests. It orders them, makes the requests against HTTP
- * servers, and makes callbacks to supplied eventHandlers as data
- * is read. It supports request prioritization, connection reuse
- * and pipelining.
- *
- * @param context application context
- */
- public RequestQueue(Context context) {
- this(context, CONNECTION_COUNT);
- }
-
- /**
- * A RequestQueue class instance maintains a set of queued
- * requests. It orders them, makes the requests against HTTP
- * servers, and makes callbacks to supplied eventHandlers as data
- * is read. It supports request prioritization, connection reuse
- * and pipelining.
- *
- * @param context application context
- * @param connectionCount The number of simultaneous connections
- */
- public RequestQueue(Context context, int connectionCount) {
- mContext = context;
-
- mPending = new LinkedHashMap<HttpHost, LinkedList<Request>>(32);
-
- mActivePool = new ActivePool(connectionCount);
- mActivePool.startup();
- }
-
- /**
- * Enables data state and proxy tracking
- */
- public synchronized void enablePlatformNotifications() {
- if (HttpLog.LOGV) HttpLog.v("RequestQueue.enablePlatformNotifications() network");
-
- if (mProxyChangeReceiver == null) {
- mProxyChangeReceiver =
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context ctx, Intent intent) {
- setProxyConfig();
- }
- };
- mContext.registerReceiver(mProxyChangeReceiver,
- new IntentFilter(Proxy.PROXY_CHANGE_ACTION));
- }
-
- /* Network state notification is broken on the simulator
- don't register for notifications on SIM */
- String device = SystemProperties.get("ro.product.device");
- boolean simulation = TextUtils.isEmpty(device);
-
- if (!simulation) {
- if (mNetworkStateTracker == null) {
- mNetworkStateTracker = new NetworkStateTracker(mContext);
- }
- mNetworkStateTracker.enable();
- }
- }
-
- /**
- * If platform notifications have been enabled, call this method
- * to disable before destroying RequestQueue
- */
- public synchronized void disablePlatformNotifications() {
- if (HttpLog.LOGV) HttpLog.v("RequestQueue.disablePlatformNotifications() network");
-
- if (mNetworkStateTracker != null) {
- mNetworkStateTracker.disable();
- }
-
- if (mProxyChangeReceiver != null) {
- mContext.unregisterReceiver(mProxyChangeReceiver);
- mProxyChangeReceiver = null;
- }
- }
-
- /**
- * Because our IntentReceiver can run within a different thread,
- * synchronize setting the proxy
- */
- private synchronized void setProxyConfig() {
- if (mNetworkStateTracker.getCurrentNetworkType() == ConnectivityManager.TYPE_WIFI) {
- mProxyHost = null;
- } else {
- String host = Proxy.getHost(mContext);
- if (HttpLog.LOGV) HttpLog.v("RequestQueue.setProxyConfig " + host);
- if (host == null) {
- mProxyHost = null;
- } else {
- mActivePool.disablePersistence();
- mProxyHost = new HttpHost(host, Proxy.getPort(mContext), "http");
- }
- }
- }
-
- /**
- * used by webkit
- * @return proxy host if set, null otherwise
- */
- public HttpHost getProxyHost() {
- return mProxyHost;
- }
-
- /**
- * Queues an HTTP request
- * @param url The url to load.
- * @param method "GET" or "POST."
- * @param headers A hashmap of http headers.
- * @param eventHandler The event handler for handling returned
- * data. Callbacks will be made on the supplied instance.
- * @param bodyProvider InputStream providing HTTP body, null if none
- * @param bodyLength length of body, must be 0 if bodyProvider is null
- * @param highPriority If true, queues before low priority
- * requests if possible
- */
- public RequestHandle queueRequest(
- String url, String method,
- Map<String, String> headers, EventHandler eventHandler,
- InputStream bodyProvider, int bodyLength, boolean highPriority) {
- WebAddress uri = new WebAddress(url);
- return queueRequest(url, uri, method, headers, eventHandler,
- bodyProvider, bodyLength, highPriority);
- }
-
- /**
- * Queues an HTTP request
- * @param url The url to load.
- * @param uri The uri of the url to load.
- * @param method "GET" or "POST."
- * @param headers A hashmap of http headers.
- * @param eventHandler The event handler for handling returned
- * data. Callbacks will be made on the supplied instance.
- * @param bodyProvider InputStream providing HTTP body, null if none
- * @param bodyLength length of body, must be 0 if bodyProvider is null
- * @param highPriority If true, queues before low priority
- * requests if possible
- */
- public RequestHandle queueRequest(
- String url, WebAddress uri, String method, Map<String, String> headers,
- EventHandler eventHandler,
- InputStream bodyProvider, int bodyLength,
- boolean highPriority) {
-
- if (HttpLog.LOGV) HttpLog.v("RequestQueue.queueRequest " + uri);
-
- // Ensure there is an eventHandler set
- if (eventHandler == null) {
- eventHandler = new LoggingEventHandler();
- }
-
- /* Create and queue request */
- Request req;
- HttpHost httpHost = new HttpHost(uri.mHost, uri.mPort, uri.mScheme);
-
- // set up request
- req = new Request(method, httpHost, mProxyHost, uri.mPath, bodyProvider,
- bodyLength, eventHandler, headers, highPriority);
-
- queueRequest(req, highPriority);
-
- mActivePool.mTotalRequest++;
-
- // dump();
- mActivePool.startConnectionThread();
-
- return new RequestHandle(
- this, url, uri, method, headers, bodyProvider, bodyLength,
- req);
- }
-
- /**
- * Called by the NetworkStateTracker -- updates when network connectivity
- * is lost/restored.
- *
- * If isNetworkConnected is true, start processing requests
- */
- public void setNetworkState(boolean isNetworkConnected) {
- if (HttpLog.LOGV) HttpLog.v("RequestQueue.setNetworkState() " + isNetworkConnected);
- mNetworkConnected = isNetworkConnected;
- if (isNetworkConnected)
- mActivePool.startConnectionThread();
- }
-
- /**
- * @return true iff there are any non-active requests pending
- */
- synchronized boolean requestsPending() {
- return !mPending.isEmpty();
- }
-
-
- /**
- * debug tool: prints request queue to log
- */
- synchronized void dump() {
- HttpLog.v("dump()");
- StringBuilder dump = new StringBuilder();
- int count = 0;
- Iterator<Map.Entry<HttpHost, LinkedList<Request>>> iter;
-
- // mActivePool.log(dump);
-
- if (!mPending.isEmpty()) {
- iter = mPending.entrySet().iterator();
- while (iter.hasNext()) {
- Map.Entry<HttpHost, LinkedList<Request>> entry = iter.next();
- String hostName = entry.getKey().getHostName();
- StringBuilder line = new StringBuilder("p" + count++ + " " + hostName + " ");
-
- LinkedList<Request> reqList = entry.getValue();
- ListIterator reqIter = reqList.listIterator(0);
- while (iter.hasNext()) {
- Request request = (Request)iter.next();
- line.append(request + " ");
- }
- dump.append(line);
- dump.append("\n");
- }
- }
- HttpLog.v(dump.toString());
- }
-
- /*
- * RequestFeeder implementation
- */
- public synchronized Request getRequest() {
- Request ret = null;
-
- if (mNetworkConnected && !mPending.isEmpty()) {
- ret = removeFirst(mPending);
- }
- if (HttpLog.LOGV) HttpLog.v("RequestQueue.getRequest() => " + ret);
- return ret;
- }
-
- /**
- * @return a request for given host if possible
- */
- public synchronized Request getRequest(HttpHost host) {
- Request ret = null;
-
- if (mNetworkConnected && mPending.containsKey(host)) {
- LinkedList<Request> reqList = mPending.get(host);
- ret = reqList.removeFirst();
- if (reqList.isEmpty()) {
- mPending.remove(host);
- }
- }
- if (HttpLog.LOGV) HttpLog.v("RequestQueue.getRequest(" + host + ") => " + ret);
- return ret;
- }
-
- /**
- * @return true if a request for this host is available
- */
- public synchronized boolean haveRequest(HttpHost host) {
- return mPending.containsKey(host);
- }
-
- /**
- * Put request back on head of queue
- */
- public void requeueRequest(Request request) {
- queueRequest(request, true);
- }
-
- /**
- * This must be called to cleanly shutdown RequestQueue
- */
- public void shutdown() {
- mActivePool.shutdown();
- }
-
- protected synchronized void queueRequest(Request request, boolean head) {
- HttpHost host = request.mProxyHost == null ? request.mHost : request.mProxyHost;
- LinkedList<Request> reqList;
- if (mPending.containsKey(host)) {
- reqList = mPending.get(host);
- } else {
- reqList = new LinkedList<Request>();
- mPending.put(host, reqList);
- }
- if (head) {
- reqList.addFirst(request);
- } else {
- reqList.add(request);
- }
- }
-
-
- public void startTiming() {
- mActivePool.startTiming();
- }
-
- public void stopTiming() {
- mActivePool.stopTiming();
- }
-
- /* helper */
- private Request removeFirst(LinkedHashMap<HttpHost, LinkedList<Request>> requestQueue) {
- Request ret = null;
- Iterator<Map.Entry<HttpHost, LinkedList<Request>>> iter = requestQueue.entrySet().iterator();
- if (iter.hasNext()) {
- Map.Entry<HttpHost, LinkedList<Request>> entry = iter.next();
- LinkedList<Request> reqList = entry.getValue();
- ret = reqList.removeFirst();
- if (reqList.isEmpty()) {
- requestQueue.remove(entry.getKey());
- }
- }
- return ret;
- }
-
- /**
- * This interface is exposed to each connection
- */
- interface ConnectionManager {
- boolean isNetworkConnected();
- HttpHost getProxyHost();
- Connection getConnection(Context context, HttpHost host);
- boolean recycleConnection(HttpHost host, Connection connection);
- }
-}
diff --git a/core/java/android/net/http/SslCertificate.java b/core/java/android/net/http/SslCertificate.java
deleted file mode 100644
index 46b2bee4a93..00000000000
--- a/core/java/android/net/http/SslCertificate.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * 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 android.net.http;
-
-import android.os.Bundle;
-
-import java.text.DateFormat;
-import java.util.Vector;
-
-import java.security.cert.X509Certificate;
-
-import org.bouncycastle.asn1.DERObjectIdentifier;
-import org.bouncycastle.asn1.x509.X509Name;
-
-/**
- * SSL certificate info (certificate details) class
- */
-public class SslCertificate {
-
- /**
- * Name of the entity this certificate is issued to
- */
- private DName mIssuedTo;
-
- /**
- * Name of the entity this certificate is issued by
- */
- private DName mIssuedBy;
-
- /**
- * Not-before date from the validity period
- */
- private String mValidNotBefore;
-
- /**
- * Not-after date from the validity period
- */
- private String mValidNotAfter;
-
- /**
- * Bundle key names
- */
- private static final String ISSUED_TO = "issued-to";
- private static final String ISSUED_BY = "issued-by";
- private static final String VALID_NOT_BEFORE = "valid-not-before";
- private static final String VALID_NOT_AFTER = "valid-not-after";
-
- /**
- * Saves the certificate state to a bundle
- * @param certificate The SSL certificate to store
- * @return A bundle with the certificate stored in it or null if fails
- */
- public static Bundle saveState(SslCertificate certificate) {
- Bundle bundle = null;
-
- if (certificate != null) {
- bundle = new Bundle();
-
- bundle.putString(ISSUED_TO, certificate.getIssuedTo().getDName());
- bundle.putString(ISSUED_BY, certificate.getIssuedBy().getDName());
-
- bundle.putString(VALID_NOT_BEFORE, certificate.getValidNotBefore());
- bundle.putString(VALID_NOT_AFTER, certificate.getValidNotAfter());
- }
-
- return bundle;
- }
-
- /**
- * Restores the certificate stored in the bundle
- * @param bundle The bundle with the certificate state stored in it
- * @return The SSL certificate stored in the bundle or null if fails
- */
- public static SslCertificate restoreState(Bundle bundle) {
- if (bundle != null) {
- return new SslCertificate(
- bundle.getString(ISSUED_TO),
- bundle.getString(ISSUED_BY),
- bundle.getString(VALID_NOT_BEFORE),
- bundle.getString(VALID_NOT_AFTER));
- }
-
- return null;
- }
-
- /**
- * Creates a new SSL certificate object
- * @param issuedTo The entity this certificate is issued to
- * @param issuedBy The entity that issued this certificate
- * @param validNotBefore The not-before date from the certificate validity period
- * @param validNotAfter The not-after date from the certificate validity period
- */
- public SslCertificate(
- String issuedTo, String issuedBy, String validNotBefore, String validNotAfter) {
- mIssuedTo = new DName(issuedTo);
- mIssuedBy = new DName(issuedBy);
-
- mValidNotBefore = validNotBefore;
- mValidNotAfter = validNotAfter;
- }
-
- /**
- * Creates a new SSL certificate object from an X509 certificate
- * @param certificate X509 certificate
- */
- public SslCertificate(X509Certificate certificate) {
- this(certificate.getSubjectDN().getName(),
- certificate.getIssuerDN().getName(),
- DateFormat.getInstance().format(certificate.getNotBefore()),
- DateFormat.getInstance().format(certificate.getNotAfter()));
- }
-
- /**
- * @return Not-before date from the certificate validity period or
- * "" if none has been set
- */
- public String getValidNotBefore() {
- return mValidNotBefore != null ? mValidNotBefore : "";
- }
-
- /**
- * @return Not-after date from the certificate validity period or
- * "" if none has been set
- */
- public String getValidNotAfter() {
- return mValidNotAfter != null ? mValidNotAfter : "";
- }
-
- /**
- * @return Issued-to distinguished name or null if none has been set
- */
- public DName getIssuedTo() {
- return mIssuedTo;
- }
-
- /**
- * @return Issued-by distinguished name or null if none has been set
- */
- public DName getIssuedBy() {
- return mIssuedBy;
- }
-
- /**
- * @return A string representation of this certificate for debugging
- */
- public String toString() {
- return
- "Issued to: " + mIssuedTo.getDName() + ";\n" +
- "Issued by: " + mIssuedBy.getDName() + ";\n";
- }
-
- /**
- * A distinguished name helper class: a 3-tuple of:
- * - common name (CN),
- * - organization (O),
- * - organizational unit (OU)
- */
- public class DName {
- /**
- * Distinguished name (normally includes CN, O, and OU names)
- */
- private String mDName;
-
- /**
- * Common-name (CN) component of the name
- */
- private String mCName;
-
- /**
- * Organization (O) component of the name
- */
- private String mOName;
-
- /**
- * Organizational Unit (OU) component of the name
- */
- private String mUName;
-
- /**
- * Creates a new distinguished name
- * @param dName The distinguished name
- */
- public DName(String dName) {
- if (dName != null) {
- X509Name x509Name = new X509Name(mDName = dName);
-
- Vector val = x509Name.getValues();
- Vector oid = x509Name.getOIDs();
-
- for (int i = 0; i < oid.size(); i++) {
- if (oid.elementAt(i).equals(X509Name.CN)) {
- mCName = (String) val.elementAt(i);
- continue;
- }
-
- if (oid.elementAt(i).equals(X509Name.O)) {
- mOName = (String) val.elementAt(i);
- continue;
- }
-
- if (oid.elementAt(i).equals(X509Name.OU)) {
- mUName = (String) val.elementAt(i);
- continue;
- }
- }
- }
- }
-
- /**
- * @return The distinguished name (normally includes CN, O, and OU names)
- */
- public String getDName() {
- return mDName != null ? mDName : "";
- }
-
- /**
- * @return The Common-name (CN) component of this name
- */
- public String getCName() {
- return mCName != null ? mCName : "";
- }
-
- /**
- * @return The Organization (O) component of this name
- */
- public String getOName() {
- return mOName != null ? mOName : "";
- }
-
- /**
- * @return The Organizational Unit (OU) component of this name
- */
- public String getUName() {
- return mUName != null ? mUName : "";
- }
- }
-}
diff --git a/core/java/android/net/http/SslError.java b/core/java/android/net/http/SslError.java
deleted file mode 100644
index 2788cb1ae24..00000000000
--- a/core/java/android/net/http/SslError.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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 android.net.http;
-
-import java.security.cert.X509Certificate;
-
-/**
- * One or more individual SSL errors and the associated SSL certificate
- *
- * {@hide}
- */
-public class SslError {
-
- /**
- * Individual SSL errors (in the order from the least to the most severe):
- */
-
- /**
- * The certificate is not yet valid
- */
- public static final int SSL_NOTYETVALID = 0;
- /**
- * The certificate has expired
- */
- public static final int SSL_EXPIRED = 1;
- /**
- * Hostname mismatch
- */
- public static final int SSL_IDMISMATCH = 2;
- /**
- * The certificate authority is not trusted
- */
- public static final int SSL_UNTRUSTED = 3;
-
-
- /**
- * The number of different SSL errors (update if you add a new SSL error!!!)
- */
- public static final int SSL_MAX_ERROR = 4;
-
- /**
- * The SSL error set bitfield (each individual error is an bit index;
- * multiple individual errors can be OR-ed)
- */
- int mErrors;
-
- /**
- * The SSL certificate associated with the error set
- */
- SslCertificate mCertificate;
-
- /**
- * Creates a new SSL error set object
- * @param error The SSL error
- * @param certificate The associated SSL certificate
- */
- public SslError(int error, SslCertificate certificate) {
- addError(error);
- mCertificate = certificate;
- }
-
- /**
- * Creates a new SSL error set object
- * @param error The SSL error
- * @param certificate The associated SSL certificate
- */
- public SslError(int error, X509Certificate certificate) {
- addError(error);
- mCertificate = new SslCertificate(certificate);
- }
-
- /**
- * @return The SSL certificate associated with the error set
- */
- public SslCertificate getCertificate() {
- return mCertificate;
- }
-
- /**
- * Adds the SSL error to the error set
- * @param error The SSL error to add
- * @return True iff the error being added is a known SSL error
- */
- public boolean addError(int error) {
- boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
- if (rval) {
- mErrors |= (0x1 << error);
- }
-
- return rval;
- }
-
- /**
- * @param error The SSL error to check
- * @return True iff the set includes the error
- */
- public boolean hasError(int error) {
- boolean rval = (0 <= error && error < SslError.SSL_MAX_ERROR);
- if (rval) {
- rval = ((mErrors & (0x1 << error)) != 0);
- }
-
- return rval;
- }
-
- /**
- * @return The primary, most severe, SSL error in the set
- */
- public int getPrimaryError() {
- if (mErrors != 0) {
- // go from the most to the least severe errors
- for (int error = SslError.SSL_MAX_ERROR - 1; error >= 0; --error) {
- if ((mErrors & (0x1 << error)) != 0) {
- return error;
- }
- }
- }
-
- return 0;
- }
-
- /**
- * @return A String representation of this SSL error object
- * (used mostly for debugging).
- */
- public String toString() {
- return "primary error: " + getPrimaryError() +
- " certificate: " + getCertificate();
- }
-}
diff --git a/core/java/android/net/http/Timer.java b/core/java/android/net/http/Timer.java
deleted file mode 100644
index cc15a3085f6..00000000000
--- a/core/java/android/net/http/Timer.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 android.net.http;
-
-import android.os.SystemClock;
-
-/**
- * {@hide}
- * Debugging tool
- */
-class Timer {
-
- private long mStart;
- private long mLast;
-
- public Timer() {
- mStart = mLast = SystemClock.uptimeMillis();
- }
-
- public void mark(String message) {
- long now = SystemClock.uptimeMillis();
- if (HttpLog.LOGV) {
- HttpLog.v(message + " " + (now - mLast) + " total " + (now - mStart));
- }
- mLast = now;
- }
-}
diff --git a/core/java/android/net/http/package.html b/core/java/android/net/http/package.html
deleted file mode 100755
index a81cbce375a..00000000000
--- a/core/java/android/net/http/package.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<body>
-</body>
diff --git a/core/java/android/net/package.html b/core/java/android/net/package.html
deleted file mode 100755
index 47c57e6a13e..00000000000
--- a/core/java/android/net/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-Classes that help with network access, beyond the normal java.net.* APIs.
-
-</body>