OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / sdk / hierarchyviewer / src / com / android / hierarchyviewer / device / DeviceBridge.java
1 /*
2  * Copyright (C) 2008 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
17 package com.android.hierarchyviewer.device;
18
19 import com.android.ddmlib.AdbCommandRejectedException;
20 import com.android.ddmlib.AndroidDebugBridge;
21 import com.android.ddmlib.IDevice;
22 import com.android.ddmlib.Log;
23 import com.android.ddmlib.MultiLineReceiver;
24 import com.android.ddmlib.TimeoutException;
25
26 import java.io.IOException;
27 import java.io.File;
28 import java.util.HashMap;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31
32 public class DeviceBridge {
33     private static AndroidDebugBridge bridge;
34
35     private static final HashMap<IDevice, Integer> devicePortMap = new HashMap<IDevice, Integer>();
36     private static int nextLocalPort = Configuration.DEFAULT_SERVER_PORT;
37
38     public static void initDebugBridge() {
39         if (bridge == null) {
40             AndroidDebugBridge.init(false /* debugger support */);
41         }
42         if (bridge == null || !bridge.isConnected()) {
43             String adbLocation = System.getProperty("hierarchyviewer.adb");
44             if (adbLocation != null && adbLocation.length() != 0) {
45                 adbLocation += File.separator + "adb";
46             } else {
47                 adbLocation = "adb";
48             }
49
50             bridge = AndroidDebugBridge.createBridge(adbLocation, true);
51         }
52     }
53
54     public static void startListenForDevices(AndroidDebugBridge.IDeviceChangeListener listener) {
55         AndroidDebugBridge.addDeviceChangeListener(listener);
56     }
57
58     public static void stopListenForDevices(AndroidDebugBridge.IDeviceChangeListener listener) {
59         AndroidDebugBridge.removeDeviceChangeListener(listener);
60     }
61
62     public static IDevice[] getDevices() {
63         return bridge.getDevices();
64     }
65
66     public static boolean isViewServerRunning(IDevice device) {
67         initDebugBridge();
68         final boolean[] result = new boolean[1];
69         try {
70             if (device.isOnline()) {
71                 device.executeShellCommand(buildIsServerRunningShellCommand(),
72                         new BooleanResultReader(result));
73             }
74         } catch (IOException e) {
75             e.printStackTrace();
76         }
77         return result[0];
78     }
79
80     public static boolean startViewServer(IDevice device) {
81         return startViewServer(device, Configuration.DEFAULT_SERVER_PORT);
82     }
83
84     public static boolean startViewServer(IDevice device, int port) {
85         initDebugBridge();
86         final boolean[] result = new boolean[1];
87         try {
88             if (device.isOnline()) {
89                 device.executeShellCommand(buildStartServerShellCommand(port),
90                         new BooleanResultReader(result));
91             }
92         } catch (IOException e) {
93             e.printStackTrace();
94         }
95         return result[0];
96     }
97
98     public static boolean stopViewServer(IDevice device) {
99         initDebugBridge();
100         final boolean[] result = new boolean[1];
101         try {
102             if (device.isOnline()) {
103                 device.executeShellCommand(buildStopServerShellCommand(),
104                         new BooleanResultReader(result));
105             }
106         } catch (IOException e) {
107             e.printStackTrace();
108         }
109         return result[0];
110     }
111
112     public static void terminate() {
113         AndroidDebugBridge.terminate();
114     }
115
116     /**
117      * Sets up a just-connected device to work with the view server.
118      * <p/>This starts a port forwarding between a local port and a port on the device.
119      * @param device
120      */
121     public static void setupDeviceForward(IDevice device) {
122         synchronized (devicePortMap) {
123             if (device.getState() == IDevice.DeviceState.ONLINE) {
124                 int localPort = nextLocalPort++;
125                 try {
126                     device.createForward(localPort, Configuration.DEFAULT_SERVER_PORT);
127                     devicePortMap.put(device, localPort);
128                 } catch (TimeoutException e) {
129                     Log.e("hierarchy", "Timeout setting up port forwarding for " + device);
130                 } catch (AdbCommandRejectedException e) {
131                     Log.e("hierarchy", String.format(
132                             "Adb rejected forward command for device %1$s: %2$s",
133                             device, e.getMessage()));
134                 } catch (IOException e) {
135                     Log.e("hierarchy", String.format(
136                             "Failed to create forward for device %1$s: %2$s",
137                             device, e.getMessage()));
138                 }
139             }
140         }
141     }
142
143     public static void removeDeviceForward(IDevice device) {
144         synchronized (devicePortMap) {
145             final Integer localPort = devicePortMap.get(device);
146             if (localPort != null) {
147                 try {
148                     device.removeForward(localPort, Configuration.DEFAULT_SERVER_PORT);
149                     devicePortMap.remove(device);
150                 } catch (TimeoutException e) {
151                     Log.e("hierarchy", "Timeout removing port forwarding for " + device);
152                 } catch (AdbCommandRejectedException e) {
153                     Log.e("hierarchy", String.format(
154                             "Adb rejected remove-forward command for device %1$s: %2$s",
155                             device, e.getMessage()));
156                 } catch (IOException e) {
157                     Log.e("hierarchy", String.format(
158                             "Failed to remove forward for device %1$s: %2$s",
159                             device, e.getMessage()));
160                 }
161             }
162         }
163     }
164
165     public static int getDeviceLocalPort(IDevice device) {
166         synchronized (devicePortMap) {
167             Integer port = devicePortMap.get(device);
168             if (port != null) {
169                 return port;
170             }
171
172             Log.e("hierarchy", "Missing forwarded port for " + device.getSerialNumber());
173             return -1;
174         }
175
176     }
177
178     private static String buildStartServerShellCommand(int port) {
179         return String.format("service call window %d i32 %d",
180                 Configuration.SERVICE_CODE_START_SERVER, port);
181     }
182
183     private static String buildStopServerShellCommand() {
184         return String.format("service call window %d", Configuration.SERVICE_CODE_STOP_SERVER);
185     }
186
187     private static String buildIsServerRunningShellCommand() {
188         return String.format("service call window %d",
189                 Configuration.SERVICE_CODE_IS_SERVER_RUNNING);
190     }
191
192     private static class BooleanResultReader extends MultiLineReceiver {
193         private final boolean[] mResult;
194
195         public BooleanResultReader(boolean[] result) {
196             mResult = result;
197         }
198
199         @Override
200         public void processNewLines(String[] strings) {
201             if (strings.length > 0) {
202                 Pattern pattern = Pattern.compile(".*?\\([0-9]{8} ([0-9]{8}).*");
203                 Matcher matcher = pattern.matcher(strings[0]);
204                 if (matcher.matches()) {
205                     if (Integer.parseInt(matcher.group(1)) == 1) {
206                         mResult[0] = true;
207                     }
208                 }
209             }
210         }
211
212         public boolean isCancelled() {
213             return false;
214         }
215     }
216 }