blob: 21a5faa5588c6449e830d7163b57e4590a01696d [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.motorola.studio.android;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import com.motorola.studio.android.adt.DDMSFacade;
import com.motorola.studio.android.common.IAndroidConstants;
import com.motorola.studio.android.common.log.StudioLogger;
/**
* The activator class controls the plug-in life cycle
*/
public class AndroidPlugin extends AbstractUIPlugin
{
//Listening to this job, instead of loading sdk job, which seems to don't exist anymore.
private static final String ANDROID_SDK_CONTENT_LOADER_JOB = "Android SDK Content Loader";
private final LinkedList<Runnable> listeners = new LinkedList<Runnable>();
protected boolean sdkLoaded = false;
/**
* The plug-in ID
*/
public static final String PLUGIN_ID = "com.motorola.studio.android";
/**
* Studio for Android Perspective ID
*/
public static final String PERSPECTIVE_ID = "com.motorola.studio.android.perspective";
/**
* Nature of Android projects
*/
public static final String Android_Nature = IAndroidConstants.ANDROID_NATURE;
/**
* The Motorola Android Branding icon
*/
public static final String ANDROID_MOTOROLA_BRAND_ICON_PATH = "icons/obj16/plate16.png";
public static final String SHALL_UNEMBED_EMULATORS_PREF_KEY = "shallUnembedEmulators";
// The shared instance
private static AndroidPlugin plugin;
public static final String NDK_LOCATION_PREFERENCE = PLUGIN_ID + ".ndkpath";
public static final String CYGWIN_LOCATION_PREFERENCE = PLUGIN_ID + ".cigwinpath";
public static final String WARN_ABOUT_HPROF_PREFERENCE = PLUGIN_ID
+ ".warnAboutHprofSaveAction";
public static final String GCC_VERSION_PROPERTY = "gccversion";
public static final String PLATFORM_PROPERTY = "platform";
public static final String SRC_LOCATION_PROPERTY = "srclocation";
public static final String OBJ_LOCATION_PROPERTY = "objlocation";
public static final String LIB_LOCATION_PROPERTY = "liblocation";
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
@Override
public void start(BundleContext context) throws Exception
{
StudioLogger.debug(AndroidPlugin.class, "Starting MOTODEV Android Plugin...");
super.start(context);
plugin = this;
Thread t = new Thread("DDMS Setup")
{
@Override
public void run()
{
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
/* Linux problem with e4.
* Check if workbench window is done before calling DDMSFacade#setup().
* If the workbench window is not done yet, then add a listener to the workbench window
* that will be responsible to call DDMSFacade#setup().
* It seems that e4 changed its behavior when loading plugins, which was causing deadlocks
* on linux startup.
* This workaround works in any OS.
*/
if (window != null)
{
StudioLogger.debug(AndroidPlugin.class,
"Starting DDMS facade WITHOUT using listener...");
DDMSFacade.setup();
StudioLogger.debug(AndroidPlugin.class,
"DDMS facade started WITHOUT using listener.");
}
else
{
workbench.addWindowListener(new IWindowListener()
{
public void windowActivated(IWorkbenchWindow window)
{
//do nothing
}
public void windowDeactivated(IWorkbenchWindow window)
{
//do nothing
}
public void windowClosed(IWorkbenchWindow window)
{
//do nothing
}
public void windowOpened(IWorkbenchWindow window)
{
StudioLogger.debug(AndroidPlugin.class,
"Starting DDMS facade using listener...");
DDMSFacade.setup();
StudioLogger.debug(AndroidPlugin.class,
"DDMS facade started using listener.");
}
});
}
};
};
getPreferenceStore().setDefault(AndroidPlugin.SHALL_UNEMBED_EMULATORS_PREF_KEY, true);
// every time the Android SDK Job finishes its execution
IJobManager manager = Job.getJobManager();
manager.addJobChangeListener(new JobChangeAdapter()
{
@Override
public void done(IJobChangeEvent event)
{
Job job = event.getJob();
if (job != null)
{
String jobName = job.getName();
if (jobName != null)
{
if (jobName.equals(ANDROID_SDK_CONTENT_LOADER_JOB))
{
sdkLoaded = true;
/*
* Workaround
* The Listener should be copied in this set, to avoid exceptions in the loop.
* The exception occurs when a listener remove itself.
*/
StudioLogger.debug(AndroidPlugin.this, "Notify SDK loader listeners");
Set<Runnable> setListeners = new HashSet<Runnable>(listeners);
for (Runnable listener : setListeners)
{
try
{
listener.run();
}
catch (Throwable e)
{
// Log error of this listener and keep handling the next listener...
StudioLogger.error(AndroidPlugin.class,
"Error while handling SDK loader procedure.", e);
}
}
}
}
}
}
});
t.start();
StudioLogger.debug(AndroidPlugin.class, "MOTODEV Android Plugin started.");
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
@Override
public void stop(BundleContext context) throws Exception
{
plugin = null;
super.stop(context);
}
/**
* Add a Listener that will be executed after any SDK loader action.
* @param listener
*/
public void addSDKLoaderListener(Runnable listener)
{
listeners.addLast(listener);
if (sdkLoaded)
{
listener.run();
}
}
/**
* Remove the given Listener.
* @param listener
*/
public void removeSDKLoaderListener(Runnable listener)
{
if (listeners.contains(listener))
{
listeners.remove(listener);
}
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static AndroidPlugin getDefault()
{
return plugin;
}
/**
* Creates and returns a new image descriptor for an image file in this plug-in.
* @param path the relative path of the image file, relative to the root of the plug-in; the path must be legal
* @return an image descriptor, or null if no image could be found
*/
public static ImageDescriptor getImageDescriptor(String path)
{
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}
}