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
17package com.android.hierarchyviewer.scene;
18
19import com.android.ddmlib.IDevice;
20import com.android.hierarchyviewer.device.Window;
21import com.android.hierarchyviewer.device.DeviceBridge;
22import com.android.hierarchyviewer.ui.util.PsdFile;
23
24import java.awt.Graphics2D;
25import java.awt.Image;
26import java.awt.Point;
27import java.awt.image.BufferedImage;
28import java.io.BufferedInputStream;
29import java.io.BufferedWriter;
30import java.io.ByteArrayInputStream;
31import java.io.DataInputStream;
32import java.io.File;
33import java.io.FileOutputStream;
34import java.io.IOException;
35import java.io.OutputStreamWriter;
36import java.net.InetSocketAddress;
37import java.net.Socket;
38import javax.imageio.ImageIO;
39
40public class CaptureLoader {
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
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
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