--- /dev/null
+/*
+ * Emulator Manager
+ *
+ * Copyright (C) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Minkee Lee <minkee.lee@samsung.com>
+ * JiHye Kim <jihye424.kim@samsung.com>
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ * Sangho Park <sangho.p@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+
+package org.tizen.emulator.manager.ui.renewal.dialog.network;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.tizen.emulator.manager.EmulatorManager;
+import org.tizen.emulator.manager.logging.EMLogger;
+import org.tizen.emulator.manager.renewal.resources.ColorResources;
+import org.tizen.emulator.manager.resources.FilePathResources;
+import org.tizen.emulator.manager.resources.StringResources;
+import org.tizen.emulator.manager.tool.TapUtil;
+import org.tizen.emulator.manager.ui.Messages;
+import org.tizen.emulator.manager.ui.dialog.TapGuideDialogForWin;
+import org.tizen.emulator.manager.ui.renewal.dialog.Dialog;
+import org.tizen.emulator.manager.ui.renewal.dialog.MessageDialog;
+import org.tizen.emulator.manager.ui.renewal.item.modify.comp.ModifyItem;
+import org.tizen.emulator.manager.ui.renewal.item.modify.vm.NetTapDeviceItemForWin;
+import org.tizen.emulator.manager.ui.renewal.widgets.ComboBox;
+import org.tizen.emulator.manager.ui.renewal.widgets.TextInputBox;
+import org.tizen.emulator.manager.ui.renewal.widgets.WidgetHelper;
+import org.tizen.emulator.manager.vms.helper.HelperClass;
+import org.tizen.emulator.manager.vms.helper.ProcessResult;
+import org.tizen.emulator.manager.vms.helper.VMWorkerException;
+
+public class TapDeviceDialogForWin extends Dialog {
+
+
+ private static int WIDTH = 380;
+ private static int HEIGHT = 155;
+ private static String TITLE = Messages.getString("TapDeviceDialog.Title");
+
+ private String tapName;
+ private String ifName;
+
+ private final NetTapDeviceItemForWin viewItem;
+ private final String platformVersion;
+
+ private final int ROW_NUM = 2;
+
+ private TextInputBox nameTextInput;
+ private ComboBox comboBox;
+
+ static int TEXT_WIDGET_MARGIN_WIDTH = 5;
+
+ public static Integer[] rate = {2,5};
+ private static int rateTotal;
+
+ static {
+ int total = 0;
+ for (int i : rate) {
+ total += i;
+ }
+ rateTotal = total;
+ }
+
+ public String getTapName() {
+ return tapName;
+ }
+
+ public String getInterfaceName() {
+ return ifName;
+ }
+
+ public TapDeviceDialogForWin(Shell parent,
+ NetTapDeviceItemForWin viewItem, String platformVersion) {
+ super(parent, TITLE, WIDTH, HEIGHT, SWT.OK | SWT.CANCEL);
+ this.viewItem = viewItem;
+ this.platformVersion = platformVersion;
+ // TODO Auto-generated constructor stub
+ }
+
+ public static int CONTENT_WIDTH = WIDTH - (CONTENT_MARGIN_WIDTH * 2) - (BORDER_WIDTH * 2);
+
+
+ public static void open(Shell parent, NetTapDeviceItemForWin viewItem, String platformVersion) {
+ TapDeviceDialogForWin dialog = new TapDeviceDialogForWin(parent, viewItem, platformVersion);
+ dialog.create();
+ dialog.makeBody();
+
+ int res = dialog.open();
+ if (res == SWT.OK){
+ createTapDevice(dialog.getTapName(), dialog.getInterfaceName(),
+ viewItem, platformVersion);
+ }
+ }
+
+ public void makeBody() {
+
+ setBodyLayoutGrid(1, CONTENT_MARGIN_WIDTH, CONTENT_MARGIN_HEIGHT);
+ addTapNameItem();
+
+ if (!EmulatorManager.isWin8AndAbove()) {
+ addHostNetworkItem();
+ }
+ }
+
+ private void addTapNameItem() {
+ // item comp
+ Composite comp = createItemComp();
+ addTitle(comp, "Tap Name");
+ nameTextInput = addTextBox(comp);
+
+ nameTextInput.setEnabled(false);
+ nameTextInput.setText(TapUtil.getAvailableTapName());
+ tapName = nameTextInput.getValue();
+ }
+
+ private void addHostNetworkItem() {
+ Composite comp = createItemComp();
+ addTitle(comp, "Host Network");
+ comboBox = addComboBox(comp);
+
+ for (String str : getInterfaceList()) {
+ comboBox.addItem(str);
+ }
+ comboBox.select(0);
+ ifName = comboBox.getSelectedItem();
+
+ addListener();
+ }
+
+ private void addListener() {
+ Listener listener = new Listener() {
+ @Override
+ public void handleEvent(Event event) {
+ switch(event.type) {
+ case SWT.Selection:
+ ifName = comboBox.getSelectedItem();
+
+ default:
+ break;
+ }
+
+ }
+ };
+ comboBox.addListener(SWT.Selection, listener);
+ }
+
+ private Composite createItemComp() {
+ Composite comp = new Composite(getBodyComposite(), SWT.NONE);
+ comp.setLayoutData(makeLayoutData(ROW_NUM));
+ comp.setBackground(ColorResources.WHITE.getColor());
+
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.horizontalSpacing = 0;
+ comp.setLayout(layout);
+ return comp;
+ }
+
+ private ComboBox addComboBox(Composite parent) {
+ Composite comp = createWidgetComp(parent, 1);
+ comp.setBackground(ColorResources.WHITE.getColor());
+ ComboBox combo = new ComboBox(getShell(), comp, SWT.NONE);
+ combo.setLayoutData(getWidgetLayoutData(
+ ((GridData)parent.getLayoutData()).heightHint));
+ return combo;
+ }
+
+ private TextInputBox addTextBox(Composite parent) {
+ Composite comp = createWidgetComp(parent, 1);
+ comp.setBackground(ColorResources.WHITE.getColor());
+ TextInputBox textBox = new TextInputBox(comp, SWT.NONE);
+ textBox.setLayoutData(getWidgetLayoutData(
+ ((GridData)parent.getLayoutData()).heightHint));
+ return textBox;
+ }
+
+ private FormData getWidgetLayoutData(int height) {
+ FormData data = new FormData();
+ data.top = new FormAttachment(0, (height - ModifyItem.WIDGET_HEIGHT) / 2);
+ data.height = ModifyItem.WIDGET_HEIGHT;
+ data.left = new FormAttachment(0, TEXT_WIDGET_MARGIN_WIDTH);
+ data.right = new FormAttachment(100, -TEXT_WIDGET_MARGIN_WIDTH);
+ return data;
+ }
+
+ private void addTitle(Composite parent, String title) {
+ Composite comp = createWidgetComp(parent, 0);
+ Canvas canvas = new Canvas(comp, SWT.NONE);
+ canvas.setBackground(ColorResources.WHITE.getColor());
+ canvas.setLayoutData(getTitleLayout());
+ WidgetHelper.drawText(canvas, title, SWT.NONE);
+ }
+
+
+ private static FormData getTitleLayout() {
+ FormData data = new FormData();
+ data.top = new FormAttachment(0, 0);
+ data.left = new FormAttachment(0, 5);
+ data.right = new FormAttachment(100, -10);
+ data.bottom = new FormAttachment(100, 0);
+ return data;
+ }
+
+ private Composite createWidgetComp(Composite parent, int index) {
+ Composite widgetComp = new Composite(parent, SWT.NONE);
+ widgetComp.setBackground(ColorResources.WHITE.getColor());
+ widgetComp.setLayoutData(getWidgetLayout(index));
+ widgetComp.setLayout(new FormLayout());
+ return widgetComp;
+ }
+
+ private static GridData getWidgetLayout(int index) {
+ GridData data = new GridData();
+ data.grabExcessVerticalSpace = true;
+ data.verticalAlignment = SWT.FILL;
+ data.widthHint = getWidth(index);
+ return data;
+ }
+
+ public static int getWidth(int index) {
+ if (index >= rate.length) {
+ return 0;
+ }
+ return CONTENT_WIDTH * rate[index] / rateTotal;
+ }
+
+
+
+
+ public ArrayList<String> getInterfaceList() {
+ // Get intereface list
+ ProcessResult res;
+ ArrayList<String> ifList = new ArrayList<String>();
+ List<String> cmd = Arrays.asList(FilePathResources.getPlatformEmulatorBinPath(platformVersion)
+ + File.separator + "devcon.exe", "find", "=net", "@pci*"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ res = HelperClass.runProcess(cmd);
+ boolean isCommandSuccess = false;
+ if (res.isSuccess()) {
+ for (String str : res.getStdOutMsg()) {
+ if (str.contains(": ")) { //$NON-NLS-1$
+ isCommandSuccess = true;
+ String pciNet = str.split(": ")[1].trim(); //$NON-NLS-1$
+ EMLogger.getLogger().info(
+ "PCI network interface: " + pciNet); //$NON-NLS-1$
+ ifList.add(pciNet);
+ }
+ }
+
+ } else if (!res.isSuccess() || !isCommandSuccess) {
+ EMLogger.getLogger().warning(res.getResultMessage());
+ }
+
+ return ifList;
+ }
+
+
+
+ public static void createTapDevice(String tapName, String ifName,
+ NetTapDeviceItemForWin viewItem, String platformVersion) {
+ if (EmulatorManager.isWin()) {
+ MessageDialog msgDialog = new MessageDialog();
+ msgDialog
+ .openNoButtonInfoDialog(Messages.getString("TapUtil.CreateTapDevice.0")); //$NON-NLS-1$
+ TapCreateWorker worker = new TapCreateWorker(tapName, ifName,
+ msgDialog, viewItem, platformVersion);
+ worker.start();
+ }
+
+ }
+
+ static class TapCreateWorker extends Thread {
+
+ final MessageDialog dialog;
+ final String tapName;
+ final String ifName;
+ final NetTapDeviceItemForWin viewItem; // for refresh combo-list
+ final String platformVersion;
+
+ public TapCreateWorker(String tapName, String ifName,
+ MessageDialog dialog, NetTapDeviceItemForWin viewItem, String platformVersion) {
+ this.dialog = dialog;
+ this.tapName = tapName;
+ this.ifName = ifName;
+ this.viewItem = viewItem;
+ this.platformVersion = platformVersion;
+ }
+
+ @Override
+ public void run() {
+ // Create tap device
+ // - Create tap device and rename(user input name) because
+ // windows OS generate device name automatically.
+ // - For rename, inquire tap list before and after create and
+ // compare both to find what is new one.
+ List<String> cmd;
+ ProcessResult res;
+ try {
+ if (!EmulatorManager.isWin8AndAbove()) {
+ EMLogger.getLogger().info(
+ "get CompatibleIDs from pci network device"); //$NON-NLS-1$
+ cmd = Arrays.asList(TapUtil.getDevconPath(platformVersion), "find", "=net", //$NON-NLS-1$ //$NON-NLS-2$
+ "@pci*"); //$NON-NLS-1$
+ res = HelperClass.runProcess(cmd);
+ boolean isCommandSuccess = false;
+ String CompatibleIDs = null;
+ if (res.isSuccess()) {
+ for (String str : res.getStdOutMsg()) {
+ if (str.endsWith(ifName)) {
+ isCommandSuccess = true;
+ CompatibleIDs = str.split(":")[0].trim(); //$NON-NLS-1$
+ EMLogger.getLogger().info(
+ "CompatibleIDs: " + CompatibleIDs); //$NON-NLS-1$
+ break;
+ }
+ }
+ } else if (!res.isSuccess() || !isCommandSuccess) {
+ EMLogger.getLogger().warning(res.getResultMessage());
+ }
+
+ if (TapUtil.isWinBridgeExist() == false) {
+ // Create Bridge device and set IP
+ EMLogger.getLogger().info("create bridge"); //$NON-NLS-1$
+ cmd = Arrays
+ .asList(TapUtil.getDevconPath(platformVersion),
+ "install", //$NON-NLS-1$
+ "c:\\windows\\inf\\netbrdgm.inf", //$NON-NLS-1$
+ "ms_bridgemp"); //$NON-NLS-1$
+ res = HelperClass.runProcess(cmd);
+ if (!res.isSuccess()) {
+ throw new VMWorkerException(res.getResultMessage());
+ }
+
+ EMLogger.getLogger().info("bind interface to bridge"); //$NON-NLS-1$
+ cmd = Arrays.asList(FilePathResources.getPlatformEmulatorBinPath(platformVersion)
+ + File.separator + "bindbridge.exe", //$NON-NLS-1$
+ "ms_bridge", CompatibleIDs, "bind"); //$NON-NLS-1$ //$NON-NLS-2$
+ res = HelperClass.runProcess(cmd);
+ if (!res.isSuccess()) {
+ throw new VMWorkerException(res.getResultMessage());
+ }
+ EMLogger.getLogger().info("set bridge's IP"); //$NON-NLS-1$
+ TapUtil.setWinbridgeNetwork(TapUtil.getClassIDFromPnpInstanceID(CompatibleIDs));
+ }
+ }
+
+ // Get tap list before create new tap.
+ EMLogger.getLogger()
+ .info("Get tap list before create new tap."); //$NON-NLS-1$
+ List<String> before = TapUtil.getTapList();
+
+ // Create new tap
+ EMLogger.getLogger().info("Create new tap."); //$NON-NLS-1$
+ cmd = Arrays.asList(TapUtil.getDevconPath(platformVersion), "install", //$NON-NLS-1$
+ FilePathResources.getPlatformEmulatorBinPath(platformVersion) + File.separator
+ + "OemWin2k.inf", "Tap0901"); //$NON-NLS-1$ //$NON-NLS-2$
+ res = HelperClass.runProcess(cmd);
+
+ if (!res.isSuccess()) {
+ throw new VMWorkerException(res.getResultMessage());
+ }
+
+ // Get tap list and find new one.
+ EMLogger.getLogger().info("Get tap list and find new one."); //$NON-NLS-1$
+ List<String> after = TapUtil.getTapList();
+ String newOne = null;
+ for (String str : after) {
+ if (!before.contains(str)) {
+ newOne = str;
+ break;
+ }
+ }
+
+ if (newOne == null) {
+ throw new VMWorkerException(
+ "Tap create fail. Cannot find new tap device."); //$NON-NLS-1$
+ }
+
+ // Rename new tap to tapX
+ EMLogger.getLogger().info("Rename new tap to tapX."); //$NON-NLS-1$
+ cmd = Arrays.asList("netsh", "interface", "set", "interface", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ "name=" + newOne, "newname=" + tapName); //$NON-NLS-1$ //$NON-NLS-2$
+ res = HelperClass.runProcess(cmd);
+ if (!res.isSuccess()) {
+ throw new VMWorkerException(res.getResultMessage());
+ }
+
+ // Check tap create in success.
+ EMLogger.getLogger().info("Check tap create in success."); //$NON-NLS-1$
+ boolean isTapExist = false;
+ for (String str : TapUtil.getTapList()) {
+ if (str.equals(tapName)) {
+ isTapExist = true;
+ }
+ }
+
+ if (!EmulatorManager.isWin8AndAbove()) {
+ EMLogger.getLogger().info("bind host network to bridge"); //$NON-NLS-1$
+ String tapPnpInstanceID = TapUtil.getPnpInstanceIDFromName(tapName);
+
+ cmd = Arrays.asList(FilePathResources.getPlatformEmulatorBinPath(platformVersion)
+ + File.separator + "bindbridge.exe", "ms_bridge", //$NON-NLS-1$ //$NON-NLS-2$
+ tapPnpInstanceID, "bind"); //$NON-NLS-1$
+ res = HelperClass.runProcess(cmd);
+ if (!res.isSuccess()) {
+ throw new VMWorkerException(res.getResultMessage());
+ }
+
+ EMLogger.getLogger().info(
+ "wait while finishing bridged network setting"); //$NON-NLS-1$
+ String proxyCommand = "check-net.exe"; //$NON-NLS-1$
+ cmd = Arrays.asList(FilePathResources.getEmulatorCheckToolPath()
+ + File.separator + proxyCommand, "--bridge"); //$NON-NLS-1$
+ res = HelperClass.runProcess(cmd);
+ while (!res.getStdOutMsg().isEmpty()) {
+ boolean isCommandSuccess = false;
+ String ipAddr = null;
+ if (res.isSuccess()) {
+ for (String str : res.getStdOutMsg()) {
+ if (str.startsWith("IP Address:")) { //$NON-NLS-1$
+ isCommandSuccess = true;
+ ipAddr = str.split("IP Address: ")[1] //$NON-NLS-1$
+ .trim();
+ EMLogger.getLogger().info(
+ "bridge IP address: " + ipAddr); //$NON-NLS-1$
+ break;
+ }
+ }
+ } else if (!res.isSuccess() || !isCommandSuccess) {
+ EMLogger.getLogger()
+ .warning(res.getResultMessage());
+ }
+ if (ipAddr != null) {
+ break;
+ }
+ res = HelperClass.runProcess(cmd);
+ }
+
+ // shows success message
+ final MessageDialog messageDialog = new MessageDialog();
+ if (isTapExist) {
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ messageDialog
+ .openInfoDialog(Messages.getString("TapUtil.CreatedTapDevice.0") //$NON-NLS-1$
+ + tapName);
+ }
+ });
+ }
+ } else {
+ final MessageDialog resultDialog = new MessageDialog();
+ if (isTapExist) {
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ int res = resultDialog
+ .openSelectionDialog(Messages.getString("TapUtil.CreatedTapDevice.0") //$NON-NLS-1$
+ + StringResources.NEW_LINE
+ + Messages.getString("TapUtil.CreatedTapDevice.1") //$NON-NLS-1$
+ + tapName + StringResources.NEW_LINE
+ + Messages.getString("TapUtil.CreatedTapDevice.1")); //$NON-NLS-1$
+ if (res == SWT.OK) {
+ // Show bridge guide dialog
+ TapGuideDialogForWin.open();
+ }
+ }
+ });
+
+ } else {
+ throw new VMWorkerException("Tap is not exist : " //$NON-NLS-1$
+ + tapName);
+ }
+ }
+ } catch (VMWorkerException e) {
+ EMLogger.getLogger().warning("Failed to create tap device."); //$NON-NLS-1$
+ EMLogger.getLogger().warning(e.getMessage());
+ final String msg = e.getMessage();
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ new MessageDialog()
+ .openWarningDialog(StringResources.NEW_LINE
+ + Messages.getString("TapUtil.FailedCreateTapDevice.0") //$NON-NLS-1$
+ + StringResources.NEW_LINE + StringResources.NEW_LINE
+ + msg);
+ }
+ });
+
+ } finally {
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ dialog.close();
+ viewItem.resetCombo(true);
+ }
+ });
+ }
+ }
+ }
+
+}