155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project/* 255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * 455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * you may not use this file except in compliance with the License. 655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * You may obtain a copy of the License at 755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * 855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * 1055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * See the License for the specific language governing permissions and 1455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * limitations under the License. 1555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */ 1655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 1755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectpackage com.android.hierarchyviewer; 1855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 19f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guyimport com.android.ddmlib.IDevice; 20f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guyimport com.android.hierarchyviewer.device.Window; 21f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guyimport com.android.hierarchyviewer.scene.CaptureLoader; 2255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport com.android.hierarchyviewer.ui.Workspace; 2355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport com.android.hierarchyviewer.device.DeviceBridge; 2455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 2555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport javax.swing.SwingUtilities; 2655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport javax.swing.UIManager; 2755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport javax.swing.UnsupportedLookAndFeelException; 28f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guyimport java.io.File; 2955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 3055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectpublic class HierarchyViewer { 3155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project private static final CharSequence OS_WINDOWS = "Windows"; 3255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project private static final CharSequence OS_MACOSX = "Mac OS X"; 3355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 34cfa3a826f5924552889c750e6abb28d73b6d0597Romain Guy private static boolean sProfilingEnabled = true; 35cfa3a826f5924552889c750e6abb28d73b6d0597Romain Guy 36cfa3a826f5924552889c750e6abb28d73b6d0597Romain Guy public static boolean isProfilingEnabled() { 37cfa3a826f5924552889c750e6abb28d73b6d0597Romain Guy return sProfilingEnabled; 38cfa3a826f5924552889c750e6abb28d73b6d0597Romain Guy } 39cfa3a826f5924552889c750e6abb28d73b6d0597Romain Guy 4055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project private static void initUserInterface() { 4155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project System.setProperty("apple.laf.useScreenMenuBar", "true"); 4255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project System.setProperty("apple.awt.brushMetalLook", "true"); 4355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project System.setProperty("com.apple.mrj.application.apple.menu.about.name", "HierarchyViewer"); 4455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 4555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project final String os = System.getProperty("os.name"); 4655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 4755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project try { 4855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (os.contains(OS_WINDOWS) || os.contains(OS_MACOSX)) { 4955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 5055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } else { 51f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); 5255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 5355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } catch (ClassNotFoundException e) { 5455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project e.printStackTrace(); 5555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } catch (InstantiationException e) { 5655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project e.printStackTrace(); 5755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } catch (IllegalAccessException e) { 5855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project e.printStackTrace(); 5955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } catch (UnsupportedLookAndFeelException e) { 6055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project e.printStackTrace(); 6155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 6255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 6355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 64f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy private static void listDevices() { 65f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.out.println("List of devices attached"); 66f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy try { 67f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy Thread.sleep(500); 68f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } catch (InterruptedException e) { 69f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy e.printStackTrace(); 70f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 71f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy for (IDevice device : DeviceBridge.getDevices()) { 72f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy printDevice(device); 73f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 74f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy DeviceBridge.terminate(); 75f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 76f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy 77f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy private static void printDevice(IDevice device) { 78f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.out.println(device.toString() + "\t\t" + 79f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy (device.isEmulator() ? "emulator" : "device")); 80f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 81f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy 82f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy private static void outputPsd(String deviceName, String file) { 83f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy IDevice device = selectDevice(deviceName); 84f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy if (device != null) { 85f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy if (DeviceBridge.isViewServerRunning(device)) { 86f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy DeviceBridge.stopViewServer(device); 87f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 88f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy DeviceBridge.startViewServer(device); 89f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy DeviceBridge.setupDeviceForward(device); 90f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.out.println("Capturing layers to " + file); 91f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy CaptureLoader.saveLayers(device, Window.FOCUSED_WINDOW, new File(file)); 92f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } else { 93f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.out.println("The selected device does not exist"); 94f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 95f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy DeviceBridge.terminate(); 96f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 97f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy 98f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy private static IDevice selectDevice(String deviceName) { 99f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy try { 100f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy Thread.sleep(500); 101f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } catch (InterruptedException e) { 102f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy e.printStackTrace(); 103f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 104f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy if (DeviceBridge.getDevices() == null) return null; 105f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy if (deviceName == null) return DeviceBridge.getDevices()[0]; 106f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy for (IDevice device : DeviceBridge.getDevices()) { 107f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy if (device.getSerialNumber().equalsIgnoreCase(deviceName)) { 108f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy return device; 109f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 110f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 111f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy return null; 112f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 113f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy 11455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public static void main(String[] args) { 115f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy DeviceBridge.initDebugBridge(); 116f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy 117cfa3a826f5924552889c750e6abb28d73b6d0597Romain Guy if (args.length > 0) { 118f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy for (int i = 0; i < args.length; i++) { 119f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy String arg = args[i]; 120f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy if ("--help".equalsIgnoreCase(arg)) { 121f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.out.println("Usage: hierarchyviewer1 [options]\n"); 122f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.out.println("Options:"); 123f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.out.println(" --help\t\t\t Show this help message and exit"); 124f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.out.println(" --no-profiling\t Disable views profiling"); 125f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.out.println(" --devices\t\t\t Show the list of available devices"); 126f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.out.println(" --psd [device] <file>\t Export psd and exit"); 127f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.exit(0); 128f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } else if ("--no-profiling".equalsIgnoreCase(arg)) { 129f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy sProfilingEnabled = false; 130f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } else if ("--devices".equalsIgnoreCase(arg)) { 131f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy listDevices(); 132f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.exit(0); 133f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } else if ("--psd".equalsIgnoreCase(arg)) { 134f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy if (i == args.length - 1) { 135f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.out.println("You must specify at least an output file with --psd"); 136f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.exit(1); 137f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 138f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy String device = null; 139f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy String file = null; 140f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy if (i < args.length - 2) { 141f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy device = args[++i]; 142f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 143f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy if (i < args.length - 1) { 144f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy file = args[++i]; 145f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 146f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy outputPsd(device, file); 147f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy System.exit(0); 148f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 149f50f3488336e613b8ffe1b7dd6a0c204e7350280Romain Guy } 150cfa3a826f5924552889c750e6abb28d73b6d0597Romain Guy } 151cfa3a826f5924552889c750e6abb28d73b6d0597Romain Guy 15255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project initUserInterface(); 15355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project SwingUtilities.invokeLater(new Runnable() { 15455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public void run() { 15555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project Workspace workspace = new Workspace(); 15655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project workspace.setDefaultCloseOperation(Workspace.EXIT_ON_CLOSE); 15755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project workspace.setLocationRelativeTo(null); 15855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project workspace.setVisible(true); 15955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 16055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project }); 16155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 16255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project} 163