1 /* 2 * Copyright (C) 2010 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.ide.eclipse.hierarchyviewer; 18 19 import com.android.ddmlib.AndroidDebugBridge; 20 import com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener; 21 import com.android.ddmlib.Log; 22 import com.android.ddmlib.Log.ILogOutput; 23 import com.android.ddmlib.Log.LogLevel; 24 import com.android.hierarchyviewerlib.HierarchyViewerDirector; 25 26 import org.eclipse.jface.dialogs.MessageDialog; 27 import org.eclipse.swt.graphics.Color; 28 import org.eclipse.swt.widgets.Display; 29 import org.eclipse.swt.widgets.Shell; 30 import org.eclipse.ui.console.ConsolePlugin; 31 import org.eclipse.ui.console.IConsole; 32 import org.eclipse.ui.console.MessageConsole; 33 import org.eclipse.ui.console.MessageConsoleStream; 34 import org.eclipse.ui.plugin.AbstractUIPlugin; 35 import org.osgi.framework.BundleContext; 36 37 import java.util.Calendar; 38 39 /** 40 * The activator class controls the plug-in life cycle 41 */ 42 public class HierarchyViewerPlugin extends AbstractUIPlugin { 43 44 public static final String PLUGIN_ID = "com.android.ide.eclipse.hierarchyviewer"; //$NON-NLS-1$ 45 46 public static final String ADB_LOCATION = PLUGIN_ID + ".adb"; //$NON-NLS-1$ 47 48 // The shared instance 49 private static HierarchyViewerPlugin sPlugin; 50 51 private Color mRedColor; 52 53 /** 54 * The constructor 55 */ HierarchyViewerPlugin()56 public HierarchyViewerPlugin() { 57 } 58 59 @Override start(BundleContext context)60 public void start(BundleContext context) throws Exception { 61 super.start(context); 62 sPlugin = this; 63 64 65 // set the consoles. 66 final MessageConsole messageConsole = new MessageConsole("Hierarchy Viewer", null); //$NON-NLS-1$ 67 ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { 68 messageConsole 69 }); 70 71 final MessageConsoleStream consoleStream = messageConsole.newMessageStream(); 72 final MessageConsoleStream errorConsoleStream = messageConsole.newMessageStream(); 73 mRedColor = new Color(Display.getDefault(), 0xFF, 0x00, 0x00); 74 75 // because this can be run, in some cases, by a non UI thread, and 76 // because 77 // changing the console properties update the UI, we need to make this 78 // change 79 // in the UI thread. 80 Display.getDefault().asyncExec(new Runnable() { 81 @Override 82 public void run() { 83 errorConsoleStream.setColor(mRedColor); 84 } 85 }); 86 87 // set up the ddms log to use the ddms console. 88 Log.setLogOutput(new ILogOutput() { 89 @Override 90 public void printLog(LogLevel logLevel, String tag, String message) { 91 if (logLevel.getPriority() >= LogLevel.ERROR.getPriority()) { 92 printToStream(errorConsoleStream, tag, message); 93 ConsolePlugin.getDefault().getConsoleManager().showConsoleView(messageConsole); 94 } else { 95 printToStream(consoleStream, tag, message); 96 } 97 } 98 99 @Override 100 public void printAndPromptLog(final LogLevel logLevel, final String tag, 101 final String message) { 102 printLog(logLevel, tag, message); 103 // dialog box only run in UI thread.. 104 Display.getDefault().asyncExec(new Runnable() { 105 @Override 106 public void run() { 107 Shell shell = Display.getDefault().getActiveShell(); 108 if (logLevel == LogLevel.ERROR) { 109 MessageDialog.openError(shell, tag, message); 110 } else { 111 MessageDialog.openWarning(shell, tag, message); 112 } 113 } 114 }); 115 } 116 117 }); 118 119 final HierarchyViewerDirector director = HierarchyViewerPluginDirector.createDirector(); 120 director.startListenForDevices(); 121 122 // make the director receive change in ADB. 123 AndroidDebugBridge.addDebugBridgeChangeListener(new IDebugBridgeChangeListener() { 124 @Override 125 public void bridgeChanged(AndroidDebugBridge bridge) { 126 director.acquireBridge(bridge); 127 } 128 }); 129 130 // get the current ADB if any 131 director.acquireBridge(AndroidDebugBridge.getBridge()); 132 133 // populate the UI with current devices (if any) in a thread 134 new Thread() { 135 @Override 136 public void run() { 137 director.populateDeviceSelectionModel(); 138 } 139 }.start(); 140 } 141 142 /* 143 * (non-Javadoc) 144 * @see 145 * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext 146 * ) 147 */ 148 @Override stop(BundleContext context)149 public void stop(BundleContext context) throws Exception { 150 sPlugin = null; 151 super.stop(context); 152 153 mRedColor.dispose(); 154 155 HierarchyViewerDirector director = HierarchyViewerDirector.getDirector(); 156 director.stopListenForDevices(); 157 director.stopDebugBridge(); 158 director.terminate(); 159 } 160 161 /** 162 * Returns the shared instance 163 * 164 * @return the shared instance 165 */ getPlugin()166 public static HierarchyViewerPlugin getPlugin() { 167 return sPlugin; 168 } 169 170 /** 171 * Prints a message, associated with a project to the specified stream 172 * 173 * @param stream The stream to write to 174 * @param tag The tag associated to the message. Can be null 175 * @param message The message to print. 176 */ printToStream(MessageConsoleStream stream, String tag, String message)177 private static synchronized void printToStream(MessageConsoleStream stream, String tag, 178 String message) { 179 String dateTag = getMessageTag(tag); 180 181 stream.print(dateTag); 182 stream.println(message); 183 } 184 185 /** 186 * Creates a string containing the current date/time, and the tag 187 * 188 * @param tag The tag associated to the message. Can be null 189 * @return The dateTag 190 */ getMessageTag(String tag)191 private static String getMessageTag(String tag) { 192 Calendar c = Calendar.getInstance(); 193 194 if (tag == null) { 195 return String.format("[%1$tF %1$tT]", c); //$NON-NLS-1$ 196 } 197 198 return String.format("[%1$tF %1$tT - %2$s]", c, tag); //$NON-NLS-1$ 199 } 200 } 201