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.scene;
18 
19 import com.android.ddmlib.IDevice;
20 import com.android.hierarchyviewer.device.Window;
21 import com.android.hierarchyviewer.device.DeviceBridge;
22 import com.android.hierarchyviewer.ui.util.PsdFile;
23 
24 import java.awt.Graphics2D;
25 import java.awt.Image;
26 import java.awt.Point;
27 import java.awt.image.BufferedImage;
28 import java.io.BufferedInputStream;
29 import java.io.BufferedWriter;
30 import java.io.ByteArrayInputStream;
31 import java.io.DataInputStream;
32 import java.io.File;
33 import java.io.FileOutputStream;
34 import java.io.IOException;
35 import java.io.OutputStreamWriter;
36 import java.net.InetSocketAddress;
37 import java.net.Socket;
38 import javax.imageio.ImageIO;
39 
40 public class CaptureLoader {
saveLayers(IDevice device, Window window, File file)41     public static boolean saveLayers(IDevice device, Window window, File file) {
42         Socket socket = null;
43         DataInputStream in = null;
44         BufferedWriter out = null;
45         boolean result = false;
46 
47         try {
48             socket = new Socket();
49             socket.connect(new InetSocketAddress("127.0.0.1",
50                     DeviceBridge.getDeviceLocalPort(device)));
51 
52             out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
53             in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
54 
55             out.write("CAPTURE_LAYERS " + window.encode());
56             out.newLine();
57             out.flush();
58 
59             int width = in.readInt();
60             int height = in.readInt();
61 
62             PsdFile psd = new PsdFile(width, height);
63 
64             while (readLayer(in, psd)) {
65             }
66 
67             psd.write(new FileOutputStream(file));
68 
69             result = true;
70         } catch (IOException e) {
71             e.printStackTrace();
72         } finally {
73             try {
74                 if (out != null) {
75                     out.close();
76                 }
77                 if (in != null) {
78                     in.close();
79                 }
80                 if (socket != null) {
81                     socket.close();
82                 }
83             } catch (IOException ex) {
84                 ex.printStackTrace();
85             }
86         }
87 
88         return result;
89     }
90 
readLayer(DataInputStream in, PsdFile psd)91     private static boolean readLayer(DataInputStream in, PsdFile psd) {
92         try {
93             if (in.read() == 2) {
94                 System.out.println("Found end of layers list");
95                 return false;
96             }
97             String name = in.readUTF();
98             System.out.println("name = " + name);
99             boolean visible = in.read() == 1;
100             int x = in.readInt();
101             int y = in.readInt();
102             int dataSize = in.readInt();
103 
104             byte[] data = new byte[dataSize];
105             int read = 0;
106             while (read < dataSize) {
107                 read += in.read(data, read, dataSize - read);
108             }
109 
110             ByteArrayInputStream arrayIn = new ByteArrayInputStream(data);
111             BufferedImage chunk = ImageIO.read(arrayIn);
112 
113             // Ensure the image is in the right format
114             BufferedImage image = new BufferedImage(chunk.getWidth(), chunk.getHeight(),
115                     BufferedImage.TYPE_INT_ARGB);
116             Graphics2D g = image.createGraphics();
117             g.drawImage(chunk, null, 0, 0);
118             g.dispose();
119 
120             psd.addLayer(name, image, new Point(x, y), visible);
121 
122             return true;
123         } catch (Exception e) {
124             e.printStackTrace();
125             return false;
126         }
127     }
128 
loadCapture(IDevice device, Window window, String params)129     public static Image loadCapture(IDevice device, Window window, String params) {
130         Socket socket = null;
131         BufferedInputStream in = null;
132         BufferedWriter out = null;
133 
134         try {
135             socket = new Socket();
136             socket.connect(new InetSocketAddress("127.0.0.1",
137                     DeviceBridge.getDeviceLocalPort(device)));
138 
139             out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
140             in = new BufferedInputStream(socket.getInputStream());
141 
142             out.write("CAPTURE " + window.encode() + " " + params);
143             out.newLine();
144             out.flush();
145 
146             return ImageIO.read(in);
147         } catch (IOException e) {
148             // Empty
149         } finally {
150             try {
151                 if (out != null) {
152                     out.close();
153                 }
154                 if (in != null) {
155                     in.close();
156                 }
157                 if (socket != null) {
158                     socket.close();
159                 }
160             } catch (IOException ex) {
161                 ex.printStackTrace();
162             }
163         }
164 
165         return null;
166     }
167 }
168