1 /*
2  * Copyright (C) 2011 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.monitor;
18 
19 import com.android.ide.eclipse.monitor.SdkToolsLocator.SdkInstallStatus;
20 import com.android.prefs.AndroidLocation;
21 import com.android.sdklib.SdkManager;
22 import com.android.sdkstats.SdkStatsService;
23 import com.android.sdkuilib.internal.repository.ui.AdtUpdateDialog;
24 import com.android.utils.ILogger;
25 import com.android.utils.NullLogger;
26 
27 import org.eclipse.core.runtime.IPath;
28 import org.eclipse.core.runtime.Path;
29 import org.eclipse.core.runtime.Platform;
30 import org.eclipse.equinox.app.IApplication;
31 import org.eclipse.equinox.app.IApplicationContext;
32 import org.eclipse.jface.dialogs.MessageDialog;
33 import org.eclipse.jface.window.Window;
34 import org.eclipse.osgi.service.datalocation.Location;
35 import org.eclipse.swt.widgets.Display;
36 import org.eclipse.swt.widgets.Shell;
37 import org.eclipse.ui.IWorkbench;
38 import org.eclipse.ui.PlatformUI;
39 
40 import java.io.File;
41 
42 public class MonitorApplication implements IApplication {
43     private static final String SDK_PATH_ENVVAR = "com.android.sdk.path";
44     private static final String MONITOR_WORKSPACE_PATH = "monitor-workspace";
45 
46     @Override
start(IApplicationContext context)47     public Object start(IApplicationContext context) throws Exception {
48         Display display = PlatformUI.createDisplay();
49 
50         // set workspace location
51         Location instanceLoc = Platform.getInstanceLocation();
52         IPath workspacePath = new Path(AndroidLocation.getFolder()).append(MONITOR_WORKSPACE_PATH);
53         instanceLoc.set(workspacePath.toFile().toURI().toURL(), true);
54 
55         // figure out path to SDK
56         String sdkPath = findSdkPath(display);
57         if (!isValidSdkLocation(sdkPath)) {
58             // exit with return code -1
59             return Integer.valueOf(-1);
60         }
61         MonitorPlugin.getDefault().setSdkFolder(new File(sdkPath));
62 
63         // install platform tools if necessary
64         ILogger sdkLog = NullLogger.getLogger();
65         SdkManager manager = SdkManager.createManager(sdkPath, sdkLog);
66         if (manager.getPlatformToolsVersion() == null) {
67             boolean install = MessageDialog.openQuestion(new Shell(display),
68                     "Monitor",
69                     "The platform tools package that provides adb is missing from your SDK installation. "
70                     + "Monitor requires this package to work properly. Would you like to install that package now?");
71             if (!install) {
72                 return Integer.valueOf(-1);
73             }
74             AdtUpdateDialog window = new AdtUpdateDialog(new Shell(display), sdkLog, sdkPath);
75             window.installPlatformTools();
76         }
77 
78         // If this is the first time using ddms or adt, open up the stats service
79         // opt out dialog, and request user for permissions.
80         // Note that the actual ping is performed in MonitorStartup
81         SdkStatsService stats = new SdkStatsService();
82         stats.checkUserPermissionForPing(new Shell(display));
83 
84         // open up RCP
85         try {
86             int returnCode = PlatformUI.createAndRunWorkbench(display,
87                     new MonitorWorkbenchAdvisor());
88             if (returnCode == PlatformUI.RETURN_RESTART) {
89                 return IApplication.EXIT_RESTART;
90             }
91             return IApplication.EXIT_OK;
92         } finally {
93             display.dispose();
94         }
95     }
96 
97     @Override
stop()98     public void stop() {
99         if (!PlatformUI.isWorkbenchRunning())
100             return;
101         final IWorkbench workbench = PlatformUI.getWorkbench();
102         final Display display = workbench.getDisplay();
103         display.syncExec(new Runnable() {
104             @Override
105             public void run() {
106                 if (!display.isDisposed())
107                     workbench.close();
108             }
109         });
110     }
111 
findSdkPath(Display display)112     private String findSdkPath(Display display) {
113         // see if there is a system property set (passed in via a command line arg)
114         String sdkLocation = System.getProperty(SDK_PATH_ENVVAR);
115         if (isValidSdkLocation(sdkLocation)) {
116             return sdkLocation;
117         }
118 
119         // see if there is an environment variable set
120         sdkLocation = System.getenv(SDK_PATH_ENVVAR);
121         if (isValidSdkLocation(sdkLocation)) {
122             return sdkLocation;
123         }
124 
125         // The monitor app should be located in "<sdk>/tools/lib/monitor-platform/"
126         // So see if the folder one level up from the install location is a valid SDK.
127         Location install = Platform.getInstallLocation();
128         if (install != null && install.getURL() != null) {
129             File libFolder = new File(install.getURL().getFile()).getParentFile();
130             if (libFolder != null) {
131                 String toolsFolder = libFolder.getParent();
132                 if (toolsFolder != null) {
133                     sdkLocation = new File(toolsFolder).getParent();
134                     if (isValidSdkLocation(sdkLocation)) {
135                         MonitorPlugin.getDdmsPreferenceStore().setLastSdkPath(sdkLocation);
136                         return sdkLocation;
137                     }
138                 }
139 
140             }
141         }
142 
143         // check for the last used SDK
144         sdkLocation = MonitorPlugin.getDdmsPreferenceStore().getLastSdkPath();
145         if (isValidSdkLocation(sdkLocation)) {
146             return sdkLocation;
147         }
148 
149         // if nothing else works, prompt the user
150         sdkLocation = getSdkLocationFromUser(new Shell(display));
151         if (isValidSdkLocation(sdkLocation)) {
152             MonitorPlugin.getDdmsPreferenceStore().setLastSdkPath(sdkLocation);
153         }
154 
155         return sdkLocation;
156     }
157 
isValidSdkLocation(String sdkLocation)158     private boolean isValidSdkLocation(String sdkLocation) {
159         if (sdkLocation == null) {
160             return false;
161         }
162 
163         if (sdkLocation.trim().length() == 0) {
164             return false;
165         }
166 
167         SdkToolsLocator locator = new SdkToolsLocator(new File(sdkLocation));
168         return locator.isValidInstallation() == SdkInstallStatus.VALID;
169     }
170 
getSdkLocationFromUser(Shell shell)171     private String getSdkLocationFromUser(Shell shell) {
172         SdkLocationChooserDialog dlg = new SdkLocationChooserDialog(shell);
173         if (dlg.open() == Window.OK) {
174             return dlg.getPath();
175         } else {
176             return null;
177         }
178     }
179 }
180