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;
18 
19 import com.android.ddmlib.IDevice;
20 import com.android.hierarchyviewer.device.Window;
21 import com.android.hierarchyviewer.scene.CaptureLoader;
22 import com.android.hierarchyviewer.ui.Workspace;
23 import com.android.hierarchyviewer.device.DeviceBridge;
24 
25 import javax.swing.SwingUtilities;
26 import javax.swing.UIManager;
27 import javax.swing.UnsupportedLookAndFeelException;
28 import java.io.File;
29 
30 public class HierarchyViewer {
31     private static final CharSequence OS_WINDOWS = "Windows";
32     private static final CharSequence OS_MACOSX = "Mac OS X";
33 
34     private static boolean sProfilingEnabled = true;
35 
isProfilingEnabled()36     public static boolean isProfilingEnabled() {
37         return sProfilingEnabled;
38     }
39 
initUserInterface()40     private static void initUserInterface() {
41         System.setProperty("apple.laf.useScreenMenuBar", "true");
42         System.setProperty("apple.awt.brushMetalLook", "true");
43         System.setProperty("com.apple.mrj.application.apple.menu.about.name", "HierarchyViewer");
44 
45         final String os = System.getProperty("os.name");
46 
47         try {
48             if (os.contains(OS_WINDOWS) || os.contains(OS_MACOSX)) {
49                 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
50             } else {
51                 UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
52             }
53         } catch (ClassNotFoundException e) {
54             e.printStackTrace();
55         } catch (InstantiationException e) {
56             e.printStackTrace();
57         } catch (IllegalAccessException e) {
58             e.printStackTrace();
59         } catch (UnsupportedLookAndFeelException e) {
60             e.printStackTrace();
61         }
62     }
63 
listDevices()64     private static void listDevices() {
65         System.out.println("List of devices attached");
66         try {
67             Thread.sleep(500);
68         } catch (InterruptedException e) {
69             e.printStackTrace();
70         }
71         for (IDevice device : DeviceBridge.getDevices()) {
72             printDevice(device);
73         }
74         DeviceBridge.terminate();
75     }
76 
printDevice(IDevice device)77     private static void printDevice(IDevice device) {
78         System.out.println(device.toString() + "\t\t" +
79                 (device.isEmulator() ? "emulator" : "device"));
80     }
81 
outputPsd(String deviceName, String file)82     private static void outputPsd(String deviceName, String file) {
83         IDevice device = selectDevice(deviceName);
84         if (device != null) {
85             if (DeviceBridge.isViewServerRunning(device)) {
86                 DeviceBridge.stopViewServer(device);
87             }
88             DeviceBridge.startViewServer(device);
89             DeviceBridge.setupDeviceForward(device);
90             System.out.println("Capturing layers to " + file);
91             CaptureLoader.saveLayers(device, Window.FOCUSED_WINDOW, new File(file));
92         } else {
93             System.out.println("The selected device does not exist");
94         }
95         DeviceBridge.terminate();
96     }
97 
selectDevice(String deviceName)98     private static IDevice selectDevice(String deviceName) {
99         try {
100             Thread.sleep(500);
101         } catch (InterruptedException e) {
102             e.printStackTrace();
103         }
104         if (DeviceBridge.getDevices() == null) return null;
105         if (deviceName == null) return DeviceBridge.getDevices()[0];
106         for (IDevice device : DeviceBridge.getDevices()) {
107             if (device.getSerialNumber().equalsIgnoreCase(deviceName)) {
108                 return device;
109             }
110         }
111         return null;
112     }
113 
main(String[] args)114     public static void main(String[] args) {
115         DeviceBridge.initDebugBridge();
116 
117         if (args.length > 0) {
118             for (int i = 0; i < args.length; i++) {
119                 String arg = args[i];
120                 if ("--help".equalsIgnoreCase(arg)) {
121                     System.out.println("Usage: hierarchyviewer1 [options]\n");
122                     System.out.println("Options:");
123                     System.out.println("  --help\t\t\t Show this help message and exit");
124                     System.out.println("  --no-profiling\t Disable views profiling");
125                     System.out.println("  --devices\t\t\t Show the list of available devices");
126                     System.out.println("  --psd [device] <file>\t Export psd and exit");
127                     System.exit(0);
128                 } else if ("--no-profiling".equalsIgnoreCase(arg)) {
129                     sProfilingEnabled = false;
130                 } else if ("--devices".equalsIgnoreCase(arg)) {
131                     listDevices();
132                     System.exit(0);
133                 } else if ("--psd".equalsIgnoreCase(arg)) {
134                     if (i == args.length - 1) {
135                         System.out.println("You must specify at least an output file with --psd");
136                         System.exit(1);
137                     }
138                     String device = null;
139                     String file = null;
140                     if (i < args.length - 2) {
141                         device = args[++i];
142                     }
143                     if (i < args.length - 1) {
144                         file = args[++i];
145                     }
146                     outputPsd(device, file);
147                     System.exit(0);
148                 }
149             }
150         }
151 
152         initUserInterface();
153         SwingUtilities.invokeLater(new Runnable() {
154             public void run() {
155                 Workspace workspace = new Workspace();
156                 workspace.setDefaultCloseOperation(Workspace.EXIT_ON_CLOSE);
157                 workspace.setLocationRelativeTo(null);
158                 workspace.setVisible(true);
159             }
160         });
161     }
162 }
163