2 * Copyright (C) 2010 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.dumprendertree2.forwarder;
19 import android.util.Log;
21 import java.io.IOException;
22 import java.net.ServerSocket;
23 import java.net.Socket;
24 import java.util.HashSet;
28 * A port forwarding server. Listens on localhost on specified port and forwards the tcp
29 * communications to external socket via adb networking proxy.
31 public class Forwarder extends Thread {
32 private static final String LOG_TAG = "Forwarder";
35 private String mRemoteMachineIpAddress;
37 private ServerSocket mServerSocket;
39 private Set<ConnectionHandler> mConnectionHandlers = new HashSet<ConnectionHandler>();
41 public Forwarder(int port, String remoteMachineIpAddress) {
43 mRemoteMachineIpAddress = remoteMachineIpAddress;
48 Log.i(LOG_TAG, "start(): Starting fowarder on port: " + mPort);
51 mServerSocket = new ServerSocket(mPort);
52 } catch (IOException e) {
53 Log.e(LOG_TAG, "mPort=" + mPort, e);
65 localSocket = mServerSocket.accept();
66 } catch (IOException e) {
67 /** This most likely means that mServerSocket is already closed */
68 Log.w(LOG_TAG, "mPort=" + mPort, e);
72 Socket remoteSocket = null;
73 final ConnectionHandler connectionHandler;
75 remoteSocket = AdbUtils.createSocket();
76 connectionHandler = new ConnectionHandler(
77 mRemoteMachineIpAddress, mPort, localSocket, remoteSocket);
78 } catch (IOException exception) {
81 } catch (IOException e) {
82 Log.e(LOG_TAG, "mPort=" + mPort, e);
84 if (remoteSocket != null) {
87 } catch (IOException e) {
88 Log.e(LOG_TAG, "mPort=" + mPort, e);
95 * We have to close the sockets after the ConnectionHandler finishes, so we
96 * don't get "Too may open files" exception. We also remove the ConnectionHandler
97 * from the collection to avoid memory issues.
99 ConnectionHandler.OnFinishedCallback callback =
100 new ConnectionHandler.OnFinishedCallback() {
102 public void onFinished() {
103 synchronized (this) {
104 if (!mConnectionHandlers.remove(connectionHandler)) {
105 assert false : "removeConnectionHandler(): not in the collection";
110 connectionHandler.registerOnConnectionHandlerFinishedCallback(callback);
112 synchronized (this) {
113 mConnectionHandlers.add(connectionHandler);
115 connectionHandler.start();
118 synchronized (this) {
119 for (ConnectionHandler connectionHandler : mConnectionHandlers) {
120 connectionHandler.stop();
125 public void finish() {
127 mServerSocket.close();
128 } catch (IOException e) {
129 Log.e(LOG_TAG, "mPort=" + mPort, e);