blob: a1f3cdf582c86dfe1562d8156adb0538f1e41916 [file] [log] [blame]
Guang Zhu6bf18ba2009-09-15 23:47:20 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Guang Zhuf4bf5522009-07-23 14:19:35 -070017package com.android.dumprendertree.forwarder;
18
19import android.util.Log;
20
21import java.io.IOException;
22import java.io.InputStream;
23import java.io.OutputStream;
24import java.net.Socket;
25
26/**
27 *
28 * Worker class for {@link ForwardServer}. A Forwarder will be created once the ForwardServer
29 * accepts an incoming connection, and it will then forward the incoming/outgoing streams to a
30 * connection already proxied by adb networking (see also {@link AdbUtils}).
31 *
32 */
33public class Forwarder {
34
35 private ForwardServer server;
36 private Socket from, to;
37
38 private static final String LOGTAG = "Forwarder";
39
40 public Forwarder (Socket from, Socket to, ForwardServer server) {
41 this.server = server;
42 this.from = from;
43 this.to = to;
44 server.register(this);
45 }
46
47 public void start() {
48 Thread outgoing = new Thread(new SocketPipe(from, to));
49 Thread incoming = new Thread(new SocketPipe(to, from));
50 outgoing.setName(LOGTAG);
51 incoming.setName(LOGTAG);
52 outgoing.start();
53 incoming.start();
54 }
55
56 public void stop() {
57 shutdown(from);
58 shutdown(to);
59 }
60
61 private void shutdown(Socket socket) {
62 try {
63 socket.shutdownInput();
64 } catch (IOException e) {
65 Log.v(LOGTAG, "Socket#shutdownInput", e);
66 }
67 try {
68 socket.shutdownOutput();
69 } catch (IOException e) {
70 Log.v(LOGTAG, "Socket#shutdownOutput", e);
71 }
72 try {
73 socket.close();
74 } catch (IOException e) {
75 Log.v(LOGTAG, "Socket#close", e);
76 }
77 }
78
79 private class SocketPipe implements Runnable {
80
81 private Socket in, out;
82
83 public SocketPipe(Socket in, Socket out) {
84 this.in = in;
85 this.out = out;
86 }
87
88 public void run() {
89 try {
90 int length;
91 InputStream is = in.getInputStream();
92 OutputStream os = out.getOutputStream();
93 byte[] buffer = new byte[4096];
94 while ((length = is.read(buffer)) > 0) {
95 os.write(buffer, 0, length);
96 }
97 } catch (IOException ioe) {
98 } finally {
99 server.unregister(Forwarder.this);
100 }
101 }
102
103 @Override
104 public String toString() {
105 return "SocketPipe{" + in + "=>" + out + "}";
106 }
107 }
108}