blob: ec7c49ed0205cea6a5ac6c5cd305612c22fdcca6 [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.emulator.device.sync;
import java.lang.reflect.Method;
import java.util.List;
import org.eclipse.sequoyah.device.framework.factory.InstanceRegistry;
import org.eclipse.sequoyah.device.framework.model.IInstance;
import org.eclipse.sequoyah.device.framework.ui.view.InstanceMgtView;
import org.eclipse.sequoyah.device.framework.ui.view.model.InstanceSelectionChangeEvent;
import org.eclipse.sequoyah.device.framework.ui.view.model.InstanceSelectionChangeListener;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import com.android.ddmlib.Client;
import com.android.ddmlib.IDevice;
import com.android.ide.eclipse.ddms.DdmsPlugin;
import com.motorola.studio.android.adt.DDMSFacade;
import com.motorola.studio.android.common.log.StudioLogger;
import com.motorola.studio.android.emulator.EmulatorPlugin;
import com.motorola.studio.android.emulator.core.devfrm.DeviceFrameworkManager;
import com.motorola.studio.android.emulator.core.model.IAndroidEmulatorInstance;
import com.motorola.studio.android.emulator.ui.view.AbstractAndroidView;
public class DeviceViewsSync
{
/**
* DeviceViewsSync unique instance
*/
private static DeviceViewsSync instance = null;
/**
* Views
*/
public static final int EMULATOR_VIEW = 0; // Emulator View
public static final int DEVICE_VIEW = 1; // Device Management View
public static final int DDMS_VIEW = 2; // DDMS Device View
/**
* Methods used to update the Views
*/
private Method[] syncMethods = null;
/**
* During the synchronization, it stores the instance
* that shall be set to avoid loops
*/
private static String syncInstance = null;
/**
* Singleton
*
* @return DeviceViewsSync
*/
public static DeviceViewsSync getInstance()
{
if (instance == null)
{
instance = new DeviceViewsSync();
}
return instance;
}
/*
* Constructor
*
* Define the synchronization methods
* Define the methods that retrieve the current selection in a View
*/
@SuppressWarnings("rawtypes")
private DeviceViewsSync()
{
try
{
/*
* Register methods that update each view
*/
Class parameterTypes[] = new Class[1];
parameterTypes[0] = String.class;
syncMethods = new Method[3];
syncMethods[EMULATOR_VIEW] =
this.getClass().getDeclaredMethod("syncEmulatorView", parameterTypes);
syncMethods[DEVICE_VIEW] =
this.getClass().getDeclaredMethod("syncDeviceView", parameterTypes);
syncMethods[DDMS_VIEW] =
this.getClass().getDeclaredMethod("syncDDMSView", parameterTypes);
}
catch (Exception e)
{
StudioLogger.error("Could not add syncronization method: " + e.getMessage());
}
}
/**
* Add listeners to events that must initiate the synchronization procedures
*
* #1) Emulator View
*
* #2) Device Management View
*
* #3) DDMS Device View
*/
public void initialize()
{
/*
* Synchronization #1
* Add listener to Emulator View tab switch event
*/
AbstractAndroidView.addTabSwitchListener(new Listener()
{
@Override
public void handleEvent(Event event)
{
IAndroidEmulatorInstance activeInstance = AbstractAndroidView.getActiveInstance();
if (activeInstance != null)
{
String selectedInstanceName = activeInstance.getName();
if ((selectedInstanceName != null)
&& (!selectedInstanceName.equals(syncInstance)))
{
sync(EMULATOR_VIEW, selectedInstanceName);
}
}
}
});
/*
* Synchronization #2
*/
InstanceMgtView.addInstanceSelectionChangeListener(new InstanceSelectionChangeListener()
{
@Override
public void instanceSelectionChanged(InstanceSelectionChangeEvent event)
{
IInstance instance = event.getInstance();
if ((instance != null)
&& (EmulatorPlugin.STATUS_ONLINE_ID.equals(instance.getStatus())))
{
String selectedInstanceName = instance.getName();
if ((selectedInstanceName != null)
&& (!selectedInstanceName.equals(syncInstance)))
{
sync(DEVICE_VIEW, selectedInstanceName);
}
}
}
});
/*
* Synchronization #3
*/
DdmsPlugin.getDefault().addSelectionListener(new DdmsPlugin.ISelectionListener()
{
@Override
public void selectionChanged(Client client)
{
// none
}
@Override
public void selectionChanged(IDevice device)
{
if (device != null)
{
String selectedInstanceName = device.getAvdName();
if ((selectedInstanceName != null)
&& (!selectedInstanceName.equals(syncInstance)))
{
sync(DDMS_VIEW, selectedInstanceName);
}
}
}
});
}
/*
* Run the synchronization procedures
*
* @param fireSyncView the View that has been changed and requires others to synchronize
* @param instanceName the Device Instance name
*/
private void sync(Integer fireSyncView, String instanceName)
{
syncInstance = instanceName;
Object arglist[] = new Object[1];
arglist[0] = instanceName;
for (int i = 0; i < syncMethods.length; i++)
{
if (i != fireSyncView)
{
try
{
syncMethods[i].invoke(this, arglist);
}
catch (Exception e)
{
StudioLogger.error("Could not call syncronization method for " + i + " : "
+ e.getMessage());
}
}
}
syncInstance = null;
}
/*
* Synchronize the Emulator View by setting the selected instance
*
* @param instanceName the Device Instance name
*/
@SuppressWarnings("unused")
private void syncEmulatorView(String instanceName)
{
try
{
IAndroidEmulatorInstance emulatorInstance =
DeviceFrameworkManager.getInstance().getInstanceByName(instanceName);
if (emulatorInstance != null)
{
AbstractAndroidView.setInstance(emulatorInstance);
}
else
{
StudioLogger.warn("Could not synchronize with Emulator View: " + instanceName
+ " not in DeviceFrameworkManager model");
}
}
catch (Exception e)
{
StudioLogger.error("Could not synchronize with Emulator View: " + e.getMessage());
}
}
/*
* Synchronize the Device Management View by setting the selected instance
*
* @param instanceName the Device Instance name
*/
@SuppressWarnings("unused")
private void syncDeviceView(String instanceName)
{
try
{
InstanceRegistry registry = InstanceRegistry.getInstance();
List<IInstance> tmlInstances = registry.getInstancesByName(instanceName);
if (tmlInstances.size() > 0)
{
IInstance tmlInstance = tmlInstances.get(0);
InstanceMgtView.setSeletectedInstance(tmlInstance);
}
else
{
StudioLogger.warn("Could not synchronize with Device Management View: "
+ instanceName + " not in TmL InstanceManager model");
}
}
catch (Exception e)
{
StudioLogger.error("Could not synchronize with Device Management View: "
+ e.getMessage());
}
}
/*
* Synchronize the DDMS Device View by setting the selected instance
*
* @param instanceName the Device Instance name
*/
@SuppressWarnings("unused")
private void syncDDMSView(String instanceName)
{
try
{
IDevice device = DDMSFacade.getDeviceWithVmName(instanceName);
if (device != null)
{
DdmsPlugin.getDefault().selectionChanged(device, null);
}
else
{
StudioLogger
.warn("Could not synchronize with DDMS Devices View: Could not retrieve Device object from ADT model");
}
}
catch (Exception e)
{
StudioLogger.error("Could not synchronize with DDMS Devices View: " + e.getMessage());
}
}
}