1 /* 2 * Copyright (C) 2007 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.ddms; 18 19 import com.android.ddmlib.AndroidDebugBridge; 20 import com.android.ddmlib.DebugPortManager; 21 import com.android.ddmlib.Log; 22 import com.android.sdkstats.SdkStatsService; 23 24 import org.eclipse.swt.widgets.Display; 25 import org.eclipse.swt.widgets.Shell; 26 27 import java.io.File; 28 import java.io.FileInputStream; 29 import java.io.FileNotFoundException; 30 import java.io.IOException; 31 import java.lang.management.ManagementFactory; 32 import java.lang.management.RuntimeMXBean; 33 import java.util.Properties; 34 35 36 /** 37 * Start the UI and network. 38 */ 39 public class Main { 40 41 public static String sRevision; 42 Main()43 public Main() { 44 } 45 46 /* 47 * If a thread bails with an uncaught exception, bring the whole 48 * thing down. 49 */ 50 private static class UncaughtHandler implements Thread.UncaughtExceptionHandler { uncaughtException(Thread t, Throwable e)51 public void uncaughtException(Thread t, Throwable e) { 52 Log.e("ddms", "shutting down due to uncaught exception"); 53 Log.e("ddms", e); 54 System.exit(1); 55 } 56 } 57 58 /** 59 * Parse args, start threads. 60 */ main(String[] args)61 public static void main(String[] args) { 62 // In order to have the AWT/SWT bridge work on Leopard, we do this little hack. 63 if (isMac()) { 64 RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean(); 65 System.setProperty( 66 "JAVA_STARTED_ON_FIRST_THREAD_" + (rt.getName().split("@"))[0], //$NON-NLS-1$ 67 "1"); //$NON-NLS-1$ 68 } 69 70 Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler()); 71 72 // load prefs and init the default values 73 PrefsDialog.init(); 74 75 Log.d("ddms", "Initializing"); 76 77 // if this is the first time using ddms or adt, open up the stats service 78 // opt out dialog, and request user for permissions. 79 SdkStatsService stats = new SdkStatsService(); 80 stats.checkUserPermissionForPing(new Shell(Display.getDefault())); 81 82 // the "ping" argument means to check in with the server and exit 83 // the application name and version number must also be supplied 84 if (args.length >= 3 && args[0].equals("ping")) { 85 stats.ping(args[1], args[2]); 86 return; 87 } else if (args.length > 0) { 88 Log.e("ddms", "Unknown argument: " + args[0]); 89 System.exit(1); 90 } 91 92 // get the ddms parent folder location 93 String ddmsParentLocation = System.getProperty("com.android.ddms.bindir"); //$NON-NLS-1$ 94 95 if (ddmsParentLocation == null) { 96 // Tip: for debugging DDMS in eclipse, set this env var to the SDK/tools 97 // directory path. 98 ddmsParentLocation = System.getenv("com.android.ddms.bindir"); //$NON-NLS-1$ 99 } 100 101 // we're past the point where ddms can be called just to send a ping, so we can 102 // ping for ddms itself. 103 ping(stats, ddmsParentLocation); 104 stats = null; 105 106 DebugPortManager.setProvider(DebugPortProvider.getInstance()); 107 108 // create the three main threads 109 UIThread ui = UIThread.getInstance(); 110 111 try { 112 ui.runUI(ddmsParentLocation); 113 } finally { 114 PrefsDialog.save(); 115 116 AndroidDebugBridge.terminate(); 117 } 118 119 Log.d("ddms", "Bye"); 120 121 // this is kinda bad, but on MacOS the shutdown doesn't seem to finish because of 122 // a thread called AWT-Shutdown. This will help while I track this down. 123 System.exit(0); 124 } 125 126 /** Return true iff we're running on a Mac */ isMac()127 static boolean isMac() { 128 // TODO: Replace usages of this method with 129 // org.eclipse.jface.util.Util#isMac() when we switch to Eclipse 3.5 130 // (ddms is currently built with SWT 3.4.2 from ANDROID_SWT) 131 return System.getProperty("os.name").startsWith("Mac OS"); //$NON-NLS-1$ //$NON-NLS-2$ 132 } 133 ping(SdkStatsService stats, String ddmsParentLocation)134 private static void ping(SdkStatsService stats, String ddmsParentLocation) { 135 Properties p = new Properties(); 136 try{ 137 File sourceProp; 138 if (ddmsParentLocation != null && ddmsParentLocation.length() > 0) { 139 sourceProp = new File(ddmsParentLocation, "source.properties"); //$NON-NLS-1$ 140 } else { 141 sourceProp = new File("source.properties"); //$NON-NLS-1$ 142 } 143 p.load(new FileInputStream(sourceProp)); 144 sRevision = p.getProperty("Pkg.Revision"); //$NON-NLS-1$ 145 if (sRevision != null && sRevision.length() > 0) { 146 stats.ping("ddms", sRevision); //$NON-NLS-1$ 147 } 148 } catch (FileNotFoundException e) { 149 // couldn't find the file? don't ping. 150 } catch (IOException e) { 151 // couldn't find the file? don't ping. 152 } 153 } 154 } 155