diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/SdkManagerAction.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/SdkManagerAction.java | 354 |
1 files changed, 0 insertions, 354 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/SdkManagerAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/SdkManagerAction.java deleted file mode 100644 index 48667bea0..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/SdkManagerAction.java +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.ide.eclipse.adt.internal.actions; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs; -import com.android.ide.eclipse.adt.internal.sdk.AdtConsoleSdkLog; -import com.android.ide.eclipse.adt.internal.sdk.Sdk; -import com.android.sdklib.io.FileOp; -import com.android.sdklib.repository.ISdkChangeListener; -import com.android.utils.GrabProcessOutput; -import com.android.utils.GrabProcessOutput.IProcessOutput; -import com.android.utils.GrabProcessOutput.Wait; -import com.android.sdkuilib.repository.SdkUpdaterWindow; -import com.android.sdkuilib.repository.SdkUpdaterWindow.SdkInvocationContext; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IObjectActionDelegate; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.IWorkbenchWindowActionDelegate; - -import java.io.File; -import java.lang.reflect.InvocationTargetException; -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Delegate for the toolbar/menu action "Android SDK Manager". - * It displays the Android SDK Manager. - */ -public class SdkManagerAction implements IWorkbenchWindowActionDelegate, IObjectActionDelegate { - - @Override - public void dispose() { - // nothing to dispose. - } - - @Override - public void init(IWorkbenchWindow window) { - // no init - } - - @Override - public void run(IAction action) { - // Although orthogonal to the sdk manager action, this is a good time - // to check whether the SDK has changed on disk. - AdtPlugin.getDefault().refreshSdk(); - - if (!openExternalSdkManager()) { - // If we failed to execute the sdk manager, check the SDK location. - // If it's not properly set, the check will display a dialog to state - // so to the user and a link to the prefs. - // Here's it's ok to call checkSdkLocationAndId() since it will not try - // to run the SdkManagerAction (it might run openExternalSdkManager though.) - // If checkSdkLocationAndId tries to open the SDK Manager, it end up using - // the internal one. - if (AdtPlugin.getDefault().checkSdkLocationAndId()) { - // The SDK check was successful, yet the sdk manager fail to launch anyway. - AdtPlugin.displayError( - "Android SDK", - "Failed to run the Android SDK Manager. Check the Android Console View for details."); - } - } - } - - /** - * A custom implementation of {@link ProgressMonitorDialog} that allows us - * to rename the "Cancel" button to "Close" from the internal task. - */ - private static class CloseableProgressMonitorDialog extends ProgressMonitorDialog { - - public CloseableProgressMonitorDialog(Shell parent) { - super(parent); - } - - public void changeCancelToClose() { - if (cancel != null && !cancel.isDisposed()) { - Display display = getShell() == null ? null : getShell().getDisplay(); - if (display != null) { - display.syncExec(new Runnable() { - @Override - public void run() { - if (cancel != null && !cancel.isDisposed()) { - cancel.setText(IDialogConstants.CLOSE_LABEL); - } - } - }); - } - } - } - } - - /** - * Opens the SDK Manager as an external application. - * This call is asynchronous, it doesn't wait for the manager to be closed. - * <p/> - * Important: this method must NOT invoke {@link AdtPlugin#checkSdkLocationAndId} - * (in any of its variations) since the dialog uses this method to invoke the sdk - * manager if needed. - * - * @return True if the application was found and executed. False if it could not - * be located or could not be launched. - */ - public static boolean openExternalSdkManager() { - - // On windows this takes a couple seconds and it's not clear the launch action - // has been invoked. To prevent the user from randomly clicking the "open sdk manager" - // button multiple times, show a progress window that will automatically close - // after a couple seconds. - - // By default openExternalSdkManager will return false. - final AtomicBoolean returnValue = new AtomicBoolean(false); - - final CloseableProgressMonitorDialog p = - new CloseableProgressMonitorDialog(AdtPlugin.getShell()); - p.setOpenOnRun(true); - try { - p.run(true /*fork*/, true /*cancelable*/, new IRunnableWithProgress() { - @Override - public void run(IProgressMonitor monitor) - throws InvocationTargetException, InterruptedException { - - // Get the SDK locatiom from the current SDK or as fallback - // directly from the ADT preferences. - Sdk sdk = Sdk.getCurrent(); - String osSdkLocation = sdk == null ? null : sdk.getSdkOsLocation(); - if (osSdkLocation == null || !new File(osSdkLocation).isDirectory()) { - osSdkLocation = AdtPrefs.getPrefs().getOsSdkFolder(); - } - - // If there's no SDK location or it's not a valid directory, - // there's nothing we can do. When this is invoked from run() - // the checkSdkLocationAndId method call should display a dialog - // telling the user to configure the preferences. - if (osSdkLocation == null || !new File(osSdkLocation).isDirectory()) { - return; - } - - final int numIter = 30; //30*100=3s to wait for window - final int sleepMs = 100; - monitor.beginTask("Starting Android SDK Manager", numIter); - - File androidBat = FileOp.append( - osSdkLocation, - SdkConstants.FD_TOOLS, - SdkConstants.androidCmdName()); - - if (!androidBat.exists()) { - AdtPlugin.printErrorToConsole("SDK Manager", - "Missing %s file in Android SDK.", SdkConstants.androidCmdName()); - return; - } - - if (monitor.isCanceled()) { - // Canceled by user; return true as if it succeeded. - returnValue.set(true); - return; - } - - p.changeCancelToClose(); - - try { - final AdtConsoleSdkLog logger = new AdtConsoleSdkLog(); - - String command[] = new String[] { - androidBat.getAbsolutePath(), - "sdk" //$NON-NLS-1$ - }; - Process process = Runtime.getRuntime().exec(command); - GrabProcessOutput.grabProcessOutput( - process, - Wait.ASYNC, - new IProcessOutput() { - @Override - public void out(@Nullable String line) { - // Ignore stdout - } - - @Override - public void err(@Nullable String line) { - if (line != null) { - logger.info("[SDK Manager] %s", line); - } - } - }); - - // Set openExternalSdkManager to return true. - returnValue.set(true); - } catch (Exception ignore) { - } - - // This small wait prevents the progress dialog from closing too fast. - for (int i = 0; i < numIter; i++) { - if (monitor.isCanceled()) { - // Canceled by user; return true as if it succeeded. - returnValue.set(true); - return; - } - if (i == 10) { - monitor.subTask("Initializing... SDK Manager will show up shortly."); - } - try { - Thread.sleep(sleepMs); - monitor.worked(1); - } catch (InterruptedException e) { - // ignore - } - } - - monitor.done(); - } - }); - } catch (Exception e) { - AdtPlugin.log(e, "SDK Manager exec failed"); //$NON-NLS-1# - return false; - } - - return returnValue.get(); - } - - /** - * Opens the SDK Manager bundled within ADT. - * The call is blocking and does not return till the SD Manager window is closed. - * - * @return True if the SDK location is known and the SDK Manager was started. - * False if the SDK location is not set and we can't open a SDK Manager to - * manage files in an unknown location. - */ - public static boolean openAdtSdkManager() { - final Sdk sdk = Sdk.getCurrent(); - if (sdk == null) { - return false; - } - - // Runs the updater window, directing only warning/errors logs to the ADT console - // (normal log is just dropped, which is fine since the SDK Manager has its own - // log window now.) - - SdkUpdaterWindow window = new SdkUpdaterWindow( - AdtPlugin.getShell(), - new AdtConsoleSdkLog() { - @Override - public void info(@NonNull String msgFormat, Object... args) { - // Do not show non-error/warning log in Eclipse. - }; - @Override - public void verbose(@NonNull String msgFormat, Object... args) { - // Do not show non-error/warning log in Eclipse. - }; - }, - sdk.getSdkOsLocation(), - SdkInvocationContext.IDE); - - ISdkChangeListener listener = new ISdkChangeListener() { - @Override - public void onSdkLoaded() { - // Ignore initial load of the SDK. - } - - /** - * Unload all we can from the SDK before new packages are installed. - * Typically we need to get rid of references to dx from platform-tools - * and to any platform resource data. - * <p/> - * {@inheritDoc} - */ - @Override - public void preInstallHook() { - - // TODO we need to unload as much of as SDK as possible. Otherwise - // on Windows we end up with Eclipse locking some files and we can't - // replace them. - // - // At this point, we know what the user wants to install so it would be - // possible to pass in flags to know what needs to be unloaded. Typically - // we need to: - // - unload dex if platform-tools is going to be updated. There's a vague - // attempt below at removing any references to dex and GCing. Seems - // to do the trick. - // - unload any target that is going to be updated since it may have - // resource data used by a current layout editor (e.g. data/*.ttf - // and various data/res/*.xml). - // - // Most important we need to make sure there isn't a build going on - // and if there is one, either abort it or wait for it to complete and - // then we want to make sure we don't get any attempt to use the SDK - // before the postInstallHook is called. - - if (sdk != null) { - sdk.unloadTargetData(true /*preventReload*/); - sdk.unloadDexWrappers(); - } - } - - /** - * Nothing to do. We'll reparse the SDK later in onSdkReload. - * <p/> - * {@inheritDoc} - */ - @Override - public void postInstallHook() { - } - - /** - * Reparse the SDK in case anything was add/removed. - * <p/> - * {@inheritDoc} - */ - @Override - public void onSdkReload() { - AdtPlugin.getDefault().reparseSdk(); - } - }; - - window.addListener(listener); - window.open(); - - return true; - } - - @Override - public void selectionChanged(IAction action, ISelection selection) { - // nothing related to the current selection. - } - - @Override - public void setActivePart(IAction action, IWorkbenchPart targetPart) { - // nothing to do. - } -} |