Home | History | Annotate | Download | only in scene
      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.DeviceBridge;
     21 import com.android.hierarchyviewer.device.Window;
     22 
     23 import org.openide.util.Exceptions;
     24 
     25 import java.io.BufferedReader;
     26 import java.io.BufferedWriter;
     27 import java.io.IOException;
     28 import java.io.InputStreamReader;
     29 import java.io.OutputStreamWriter;
     30 import java.net.InetSocketAddress;
     31 import java.net.Socket;
     32 import java.util.Collections;
     33 import java.util.Comparator;
     34 import java.util.Stack;
     35 
     36 public class ViewHierarchyLoader {
     37     @SuppressWarnings("empty-statement")
     38     public static ViewHierarchyScene loadScene(IDevice device, Window window) {
     39         ViewHierarchyScene scene = new ViewHierarchyScene();
     40 
     41         // Read the views tree
     42         Socket socket = null;
     43         BufferedReader in = null;
     44         BufferedWriter out = null;
     45 
     46         String line;
     47 
     48         try {
     49             System.out.println("==> Starting client");
     50 
     51             socket = new Socket();
     52             socket.connect(new InetSocketAddress("127.0.0.1",
     53                     DeviceBridge.getDeviceLocalPort(device)));
     54 
     55             out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
     56             in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
     57 
     58             System.out.println("==> DUMP");
     59 
     60             out.write("DUMP " + window.encode());
     61             out.newLine();
     62             out.flush();
     63 
     64             Stack<ViewNode> stack = new Stack<ViewNode>();
     65 
     66             boolean setRoot = true;
     67             ViewNode lastNode = null;
     68             int lastWhitespaceCount = Integer.MAX_VALUE;
     69 
     70             while ((line = in.readLine()) != null) {
     71                 if ("DONE.".equalsIgnoreCase(line)) {
     72                     break;
     73                 }
     74 
     75                 int whitespaceCount = countFrontWhitespace(line);
     76                 if (lastWhitespaceCount < whitespaceCount) {
     77                     stack.push(lastNode);
     78                 } else if (!stack.isEmpty()) {
     79                     final int count = lastWhitespaceCount - whitespaceCount;
     80                     for (int i = 0; i < count; i++) {
     81                         stack.pop();
     82                     }
     83                 }
     84 
     85                 lastWhitespaceCount = whitespaceCount;
     86                 line = line.trim();
     87                 int index = line.indexOf(' ');
     88 
     89                 lastNode = new ViewNode();
     90                 lastNode.name = line.substring(0, index);
     91 
     92                 line = line.substring(index + 1);
     93                 loadProperties(lastNode, line);
     94 
     95                 scene.addNode(lastNode);
     96 
     97                 if (setRoot) {
     98                     scene.setRoot(lastNode);
     99                     setRoot = false;
    100                 }
    101 
    102                 if (!stack.isEmpty()) {
    103                     final ViewNode parent = stack.peek();
    104                     final String edge = parent.name + lastNode.name;
    105                     scene.addEdge(edge);
    106                     scene.setEdgeSource(edge, parent);
    107                     scene.setEdgeTarget(edge, lastNode);
    108                     lastNode.parent = parent;
    109                     parent.children.add(lastNode);
    110                 }
    111             }
    112 
    113             updateIndices(scene.getRoot());
    114 
    115         } catch (IOException ex) {
    116             Exceptions.printStackTrace(ex);
    117         } finally {
    118             try {
    119                 if (out != null) {
    120                     out.close();
    121                 }
    122                 if (in != null) {
    123                     in.close();
    124                 }
    125                 socket.close();
    126             } catch (IOException ex) {
    127                 Exceptions.printStackTrace(ex);
    128             }
    129         }
    130 
    131         System.out.println("==> DONE");
    132 
    133         return scene;
    134     }
    135 
    136     private static void updateIndices(ViewNode root) {
    137         if (root == null) return;
    138 
    139         root.computeIndex();
    140 
    141         for (ViewNode node : root.children) {
    142             updateIndices(node);
    143         }
    144     }
    145 
    146     private static int countFrontWhitespace(String line) {
    147         int count = 0;
    148         while (line.charAt(count) == ' ') {
    149             count++;
    150         }
    151         return count;
    152     }
    153 
    154     private static void loadProperties(ViewNode node, String data) {
    155         int start = 0;
    156         boolean stop;
    157 
    158         do {
    159             int index = data.indexOf('=', start);
    160             ViewNode.Property property = new ViewNode.Property();
    161             property.name = data.substring(start, index);
    162 
    163             int colonIndex = property.name.indexOf(':');
    164             if (colonIndex != -1) {
    165                 property.name = property.name.substring(colonIndex + 1);
    166             }
    167 
    168             int index2 = data.indexOf(',', index + 1);
    169             int length = Integer.parseInt(data.substring(index + 1, index2));
    170             start = index2 + 1 + length;
    171             property.value = data.substring(index2 + 1, index2 + 1 + length);
    172 
    173             node.properties.add(property);
    174             node.namedProperties.put(property.name, property);
    175 
    176             stop = start >= data.length();
    177             if (!stop) {
    178                 start += 1;
    179             }
    180         } while (!stop);
    181 
    182         Collections.sort(node.properties, new Comparator<ViewNode.Property>() {
    183             public int compare(ViewNode.Property source, ViewNode.Property destination) {
    184                 return source.name.compareTo(destination.name);
    185             }
    186         });
    187 
    188         node.decode();
    189     }
    190 }
    191