diff options
8 files changed, 184 insertions, 16 deletions
@@ -266,6 +266,8 @@ LOCAL_SRC_FILES += \ wifi/java/android/net/wifi/IWifiManager.aidl \ wifi/java/android/net/wifi/p2p/IWifiP2pManager.aidl \ packages/services/PacProcessor/com/android/net/IProxyService.aidl \ + packages/services/Proxy/com/android/net/IProxyCallback.aidl \ + packages/services/Proxy/com/android/net/IProxyPortListener.aidl \ # FRAMEWORKS_BASE_JAVA_SRC_DIRS comes from build/core/pathmap.mk LOCAL_AIDL_INCLUDES += $(FRAMEWORKS_BASE_JAVA_SRC_DIRS) diff --git a/core/java/android/net/ProxyProperties.java b/core/java/android/net/ProxyProperties.java index 76aea9f..648a4b3 100644 --- a/core/java/android/net/ProxyProperties.java +++ b/core/java/android/net/ProxyProperties.java @@ -38,7 +38,7 @@ public class ProxyProperties implements Parcelable { private String mPacFileUrl; public static final String LOCAL_EXCL_LIST = ""; - public static final int LOCAL_PORT = 8182; + public static final int LOCAL_PORT = -1; public static final String LOCAL_HOST = "localhost"; public ProxyProperties(String host, int port, String exclList) { @@ -54,6 +54,14 @@ public class ProxyProperties implements Parcelable { mPacFileUrl = pacFileUrl; } + // Only used in PacManager after Local Proxy is bound. + public ProxyProperties(String pacFileUrl, int localProxyPort) { + mHost = LOCAL_HOST; + mPort = localProxyPort; + setExclusionList(LOCAL_EXCL_LIST); + mPacFileUrl = pacFileUrl; + } + private ProxyProperties(String host, int port, String exclList, String[] parsedExclList) { mHost = host; mPort = port; diff --git a/packages/services/Proxy/com/android/net/IProxyCallback.aidl b/packages/services/Proxy/com/android/net/IProxyCallback.aidl new file mode 100644 index 0000000..26b2a3f --- /dev/null +++ b/packages/services/Proxy/com/android/net/IProxyCallback.aidl @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2013, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.net; + +/** @hide */ +interface IProxyCallback +{ + oneway void getProxyPort(IBinder callback); +} diff --git a/packages/services/Proxy/com/android/net/IProxyPortListener.aidl b/packages/services/Proxy/com/android/net/IProxyPortListener.aidl new file mode 100644 index 0000000..fa4caf3 --- /dev/null +++ b/packages/services/Proxy/com/android/net/IProxyPortListener.aidl @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2013, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.net; + +/** @hide */ +interface IProxyPortListener +{ + oneway void setProxyPort(int port); +} diff --git a/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java b/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java index 77f3c8c..4bf1db8 100644 --- a/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java +++ b/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java @@ -15,8 +15,11 @@ */ package com.android.proxyhandler; +import android.net.ProxyProperties; +import android.os.RemoteException; import android.util.Log; +import com.android.net.IProxyPortListener; import com.google.android.collect.Lists; import java.io.IOException; @@ -49,6 +52,8 @@ public class ProxyServer extends Thread { public boolean mIsRunning = false; private ServerSocket serverSocket; + private int mPort; + private IProxyPortListener mCallback; private class ProxyConnection implements Runnable { private Socket connection; @@ -179,33 +184,59 @@ public class ProxyServer extends Thread { public ProxyServer() { threadExecutor = Executors.newCachedThreadPool(); + mPort = -1; + mCallback = null; } @Override public void run() { try { - serverSocket = new ServerSocket(ProxyService.PORT); + serverSocket = new ServerSocket(0); - serverSocket.setReuseAddress(true); + if (serverSocket != null) { + setPort(serverSocket.getLocalPort()); - while (mIsRunning) { - try { - ProxyConnection parser = new ProxyConnection(serverSocket.accept()); + while (mIsRunning) { + try { + ProxyConnection parser = new ProxyConnection(serverSocket.accept()); - threadExecutor.execute(parser); - } catch (IOException e) { - e.printStackTrace(); + threadExecutor.execute(parser); + } catch (IOException e) { + e.printStackTrace(); + } } } } catch (SocketException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + Log.e(TAG, "Failed to start proxy server", e); + } catch (IOException e1) { + Log.e(TAG, "Failed to start proxy server", e1); } mIsRunning = false; } + public synchronized void setPort(int port) { + if (mCallback != null) { + try { + mCallback.setProxyPort(port); + } catch (RemoteException e) { + Log.w(TAG, "Proxy failed to report port to PacManager", e); + } + } + mPort = port; + } + + public synchronized void setCallback(IProxyPortListener callback) { + if (mPort != -1) { + try { + callback.setProxyPort(mPort); + } catch (RemoteException e) { + Log.w(TAG, "Proxy failed to report port to PacManager", e); + } + } + mCallback = callback; + } + public synchronized void startServer() { mIsRunning = true; start(); @@ -222,4 +253,12 @@ public class ProxyServer extends Thread { } } } + + public boolean isBound() { + return (mPort != -1); + } + + public int getPort() { + return mPort; + } } diff --git a/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java b/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java index cef3659..109435c 100644 --- a/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java +++ b/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java @@ -21,8 +21,12 @@ import android.net.Proxy; import android.net.ProxyProperties; import android.os.Bundle; import android.os.IBinder; +import android.os.RemoteException; import android.text.TextUtils; +import com.android.net.IProxyCallback; +import com.android.net.IProxyPortListener; + /** * @hide */ @@ -56,6 +60,16 @@ public class ProxyService extends Service { @Override public IBinder onBind(Intent intent) { - return null; + return new IProxyCallback.Stub() { + @Override + public void getProxyPort(IBinder callback) throws RemoteException { + if (server != null) { + IProxyPortListener portListener = IProxyPortListener.Stub.asInterface(callback); + if (portListener != null) { + server.setCallback(portListener); + } + } + } + }; } }
\ No newline at end of file diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 4e3faca..47f18e7 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -114,7 +114,6 @@ import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneConstants; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.XmlUtils; -import com.android.net.IProxyService; import com.android.server.am.BatteryStatsService; import com.android.server.connectivity.DataConnectionStats; import com.android.server.connectivity.Nat464Xlat; @@ -3471,7 +3470,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { private void sendProxyBroadcast(ProxyProperties proxy) { if (proxy == null) proxy = new ProxyProperties("", 0, ""); - mPacManager.setCurrentProxyScriptUrl(proxy); + if (mPacManager.setCurrentProxyScriptUrl(proxy)) return; if (DBG) log("sending Proxy Broadcast for " + proxy); Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | diff --git a/services/java/com/android/server/connectivity/PacManager.java b/services/java/com/android/server/connectivity/PacManager.java index c8cc85e..772921a 100644 --- a/services/java/com/android/server/connectivity/PacManager.java +++ b/services/java/com/android/server/connectivity/PacManager.java @@ -24,17 +24,22 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; +import android.net.Proxy; import android.net.ProxyProperties; +import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.GuardedBy; +import com.android.net.IProxyCallback; +import com.android.net.IProxyPortListener; import com.android.net.IProxyService; import com.android.server.IoThread; @@ -79,6 +84,7 @@ public class PacManager { private Context mContext; private int mCurrentDelay; + private int mLastPort; /** * Used for locking when setting mProxyService and all references to mPacUrl or mCurrentPac. @@ -119,6 +125,7 @@ public class PacManager { public PacManager(Context context) { mContext = context; + mLastPort = -1; mPacRefreshIntent = PendingIntent.getBroadcast( context, 0, new Intent(ACTION_PAC_REFRESH), 0); @@ -133,7 +140,16 @@ public class PacManager { return mAlarmManager; } - public synchronized void setCurrentProxyScriptUrl(ProxyProperties proxy) { + /** + * Updates the PAC Manager with current Proxy information. This is called by + * the ConnectivityService directly before a broadcast takes place to allow + * the PacManager to indicate that the broadcast should not be sent and the + * PacManager will trigger a new broadcast when it is ready. + * + * @param proxy Proxy information that is about to be broadcast. + * @return Returns true when the broadcast should not be sent + */ + public synchronized boolean setCurrentProxyScriptUrl(ProxyProperties proxy) { if (!TextUtils.isEmpty(proxy.getPacFileUrl())) { synchronized (mProxyLock) { mPacUrl = proxy.getPacFileUrl(); @@ -141,6 +157,7 @@ public class PacManager { mCurrentDelay = DELAY_1; getAlarmManager().cancel(mPacRefreshIntent); bind(); + return true; } else { getAlarmManager().cancel(mPacRefreshIntent); synchronized (mProxyLock) { @@ -156,6 +173,7 @@ public class PacManager { } } } + return false; } } @@ -233,6 +251,16 @@ public class PacManager { } Intent intent = new Intent(); intent.setClassName(PAC_PACKAGE, PAC_SERVICE); + // Already bound no need to bind again. + if (mProxyConnection != null) { + if (mLastPort != -1) { + sendPacBroadcast(new ProxyProperties(mPacUrl, mLastPort)); + } else { + Log.e(TAG, "Received invalid port from Local Proxy," + + " PAC will not be operational"); + } + return; + } mConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName component) { @@ -277,6 +305,26 @@ public class PacManager { @Override public void onServiceConnected(ComponentName component, IBinder binder) { + IProxyCallback callbackService = IProxyCallback.Stub.asInterface(binder); + if (callbackService != null) { + try { + callbackService.getProxyPort(new IProxyPortListener.Stub() { + @Override + public void setProxyPort(int port) throws RemoteException { + mLastPort = port; + if (port != -1) { + Log.d(TAG, "Local proxy is bound on " + port); + sendPacBroadcast(new ProxyProperties(mPacUrl, port)); + } else { + Log.e(TAG, "Received invalid port from Local Proxy," + + " PAC will not be operational"); + } + } + }); + } catch (RemoteException e) { + e.printStackTrace(); + } + } } }; mContext.bindService(intent, mProxyConnection, @@ -287,5 +335,19 @@ public class PacManager { mContext.unbindService(mConnection); mContext.unbindService(mProxyConnection); mConnection = null; + mProxyConnection = null; + } + + private void sendPacBroadcast(ProxyProperties proxy) { + Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | + Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy); + final long ident = Binder.clearCallingIdentity(); + try { + mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); + } finally { + Binder.restoreCallingIdentity(ident); + } } } |