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.Log; 21 import com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener; 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 public void run() { 82 errorConsoleStream.setColor(mRedColor); 83 } 84 }); 85 86 // set up the ddms log to use the ddms console. 87 Log.setLogOutput(new ILogOutput() { 88 public void printLog(LogLevel logLevel, String tag, String message) { 89 if (logLevel.getPriority() >= LogLevel.ERROR.getPriority()) { 90 printToStream(errorConsoleStream, tag, message); 91 ConsolePlugin.getDefault().getConsoleManager().showConsoleView(messageConsole); 92 } else { 93 printToStream(consoleStream, tag, message); 94 } 95 } 96 97 public void printAndPromptLog(final LogLevel logLevel, final String tag, 98 final String message) { 99 printLog(logLevel, tag, message); 100 // dialog box only run in UI thread.. 101 Display.getDefault().asyncExec(new Runnable() { 102 public void run() { 103 Shell shell = Display.getDefault().getActiveShell(); 104 if (logLevel == LogLevel.ERROR) { 105 MessageDialog.openError(shell, tag, message); 106 } else { 107 MessageDialog.openWarning(shell, tag, message); 108 } 109 } 110 }); 111 } 112 113 }); 114 115 final HierarchyViewerDirector director = HierarchyViewerPluginDirector.createDirector(); 116 director.startListenForDevices(); 117 118 // make the director receive change in ADB. 119 AndroidDebugBridge.addDebugBridgeChangeListener(new IDebugBridgeChangeListener() { 120 public void bridgeChanged(AndroidDebugBridge bridge) { 121 director.acquireBridge(bridge); 122 } 123 }); 124 125 // get the current ADB if any 126 director.acquireBridge(AndroidDebugBridge.getBridge()); 127 128 // populate the UI with current devices (if any) in a thread 129 new Thread() { 130 @Override 131 public void run() { 132 director.populateDeviceSelectionModel(); 133 } 134 }.start(); 135 } 136 137 /* 138 * (non-Javadoc) 139 * @see 140 * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext 141 * ) 142 */ 143 @Override stop(BundleContext context)144 public void stop(BundleContext context) throws Exception { 145 sPlugin = null; 146 super.stop(context); 147 148 mRedColor.dispose(); 149 150 HierarchyViewerDirector director = HierarchyViewerDirector.getDirector(); 151 director.stopListenForDevices(); 152 director.stopDebugBridge(); 153 director.terminate(); 154 } 155 156 /** 157 * Returns the shared instance 158 * 159 * @return the shared instance 160 */ getPlugin()161 public static HierarchyViewerPlugin getPlugin() { 162 return sPlugin; 163 } 164 165 /** 166 * Prints a message, associated with a project to the specified stream 167 * 168 * @param stream The stream to write to 169 * @param tag The tag associated to the message. Can be null 170 * @param message The message to print. 171 */ printToStream(MessageConsoleStream stream, String tag, String message)172 private static synchronized void printToStream(MessageConsoleStream stream, String tag, 173 String message) { 174 String dateTag = getMessageTag(tag); 175 176 stream.print(dateTag); 177 stream.println(message); 178 } 179 180 /** 181 * Creates a string containing the current date/time, and the tag 182 * 183 * @param tag The tag associated to the message. Can be null 184 * @return The dateTag 185 */ getMessageTag(String tag)186 private static String getMessageTag(String tag) { 187 Calendar c = Calendar.getInstance(); 188 189 if (tag == null) { 190 return String.format("[%1$tF %1$tT]", c); //$NON-NLS-1$ 191 } 192 193 return String.format("[%1$tF %1$tT - %2$s]", c, tag); //$NON-NLS-1$ 194 } 195 } 196