package com.intellij.lang.javascript.flex.run; import com.intellij.CommonBundle; import com.intellij.compiler.options.CompileStepBeforeRun; import com.intellij.compiler.options.CompileStepBeforeRunNoErrorCheck; import com.intellij.execution.*; import com.intellij.execution.configurations.*; import com.intellij.execution.impl.RunDialog; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.GenericProgramRunner; import com.intellij.execution.testframework.sm.SMTestRunnerConnectionUtil; import com.intellij.execution.testframework.sm.runner.SMTRunnerConsoleProperties; import com.intellij.execution.testframework.sm.runner.SMTestLocator; import com.intellij.execution.testframework.ui.BaseTestsOutputConsoleView; import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.util.ExecUtil; import com.intellij.flex.FlexCommonBundle; import com.intellij.flex.FlexCommonUtils; import com.intellij.flex.model.bc.TargetPlatform; import com.intellij.ide.BrowserUtil; import com.intellij.ide.browsers.BrowserLauncher; import com.intellij.lang.javascript.flex.FlexBundle; import com.intellij.lang.javascript.flex.FlexStackTraceFilter; import com.intellij.lang.javascript.flex.FlexUtils; import com.intellij.lang.javascript.flex.actions.airpackage.AirPackageUtil; import com.intellij.lang.javascript.flex.actions.airpackage.DeviceInfo; import com.intellij.lang.javascript.flex.build.FlexCompilationUtils; import com.intellij.lang.javascript.flex.debug.FlexDebugProcess; import com.intellij.lang.javascript.flex.debug.FlexDebugRunner; import com.intellij.lang.javascript.flex.flexunit.FlexQualifiedNameLocationProvider; import com.intellij.lang.javascript.flex.flexunit.FlexUnitRunConfiguration; import com.intellij.lang.javascript.flex.flexunit.FlexUnitRunnerParameters; import com.intellij.lang.javascript.flex.projectStructure.FlexBuildConfigurationsExtension; import com.intellij.lang.javascript.flex.projectStructure.model.AirDesktopPackagingOptions; import com.intellij.lang.javascript.flex.projectStructure.model.AirPackagingOptions; import com.intellij.lang.javascript.flex.projectStructure.model.FlexBuildConfiguration; import com.intellij.lang.javascript.flex.projectStructure.options.BCUtils; import com.intellij.lang.javascript.flex.sdk.FlexSdkUtils; import com.intellij.notification.*; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.ui.HyperlinkAdapter; import com.intellij.ui.navigation.Place; import com.intellij.util.PathUtil; import com.intellij.xdebugger.*; import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import java.io.File; import java.io.IOException; import java.util.Collection; import java.util.List; import java.util.StringTokenizer; import static com.intellij.lang.javascript.flex.run.FlashRunnerParameters.AppDescriptorForEmulator; import static com.intellij.lang.javascript.flex.run.RemoteFlashRunnerParameters.RemoteDebugTarget; public abstract class FlexBaseRunner extends GenericProgramRunner { public static final NotificationGroup COMPILE_BEFORE_LAUNCH_NOTIFICATION_GROUP = NotificationGroup.toolWindowGroup( FlexBundle.message("check.flash.app.compiled.before.launch.notification.group"), ToolWindowId.RUN, false); @Override @Nullable protected RunContentDescriptor doExecute(@NotNull final RunProfileState state, @NotNull final ExecutionEnvironment env) throws ExecutionException { FileDocumentManager.getInstance().saveAllDocuments(); final RunProfile runProfile = env.getRunProfile(); final boolean isDebug = this instanceof FlexDebugRunner; try { if (runProfile instanceof RunProfileWithCompileBeforeLaunchOption) { checkMakeBeforeRunEnabled(env.getProject(), runProfile); } if (runProfile instanceof RemoteFlashRunConfiguration) { final RemoteFlashRunnerParameters params = ((RemoteFlashRunConfiguration)runProfile).getRunnerParameters(); final Pair<Module, FlexBuildConfiguration> moduleAndBC = params.checkAndGetModuleAndBC(env.getProject()); if (params.getDebugTransport() == FlashRunnerParameters.AirMobileDebugTransport.USB) { final Sdk sdk = moduleAndBC.second.getSdk(); assert sdk != null; if (params.getRemoteDebugTarget() == RemoteDebugTarget.AndroidDevice) { if (!AirPackageUtil.startAdbServer(env.getProject(), sdk) || !AirPackageUtil.scanAndroidDevices(env.getProject(), sdk, params) || !AirPackageUtil.androidForwardTcpPort(env.getProject(), sdk, params.getDeviceInfo(), params.getUsbDebugPort())) { return null; } } else if (params.getRemoteDebugTarget() == RemoteDebugTarget.iOSDevice) { final String adtVersion = AirPackageUtil.getAdtVersion(env.getProject(), sdk); if (!AirPackageUtil.checkAdtVersionForPackaging(env.getProject(), adtVersion, "3.4", sdk.getName(), FlexBundle.message("air.ios.debug.via.usb.requires.3.4"))) { return null; } if (!AirPackageUtil.scanIosDevices(env.getProject(), sdk, params)) { return null; } final DeviceInfo device = params.getDeviceInfo(); final int deviceHandle = device == null ? -1 : device.IOS_HANDLE; if (deviceHandle < 0) { return null; } if (!AirPackageUtil.iosForwardTcpPort(env.getProject(), sdk, params.getUsbDebugPort(), deviceHandle)) { return null; } } } return launchDebugProcess(moduleAndBC.first, moduleAndBC.second, params, env); } if (runProfile instanceof FlexUnitRunConfiguration) { final FlexUnitRunnerParameters params = ((FlexUnitRunConfiguration)runProfile).getRunnerParameters(); final Pair<Module, FlexBuildConfiguration> moduleAndConfig = params.checkAndGetModuleAndBC(env.getProject()); final Module module = moduleAndConfig.first; final FlexBuildConfiguration bc = moduleAndConfig.second; if (bc.getTargetPlatform() == TargetPlatform.Web) { FlashPlayerTrustUtil.updateTrustedStatus(module, bc, isDebug, params.isTrusted()); return launchWebFlexUnit(env.getProject(), env.getContentToReuse(), env, params, bc.getActualOutputFilePath()); } else { return launchAirFlexUnit(env.getProject(), state, env.getContentToReuse(), env, params); } } if (runProfile instanceof FlashRunConfiguration) { final FlashRunnerParameters params = ((FlashRunConfiguration)runProfile).getRunnerParameters(); params.setDeviceInfo(null); final Pair<Module, FlexBuildConfiguration> moduleAndConfig = params.checkAndGetModuleAndBC(env.getProject()); final Module module = moduleAndConfig.first; final FlexBuildConfiguration bc = moduleAndConfig.second; if (bc.isSkipCompile()) { showBCCompilationSkippedWarning(module, bc); } if (isDebug && SystemInfo.isMac && bc.getTargetPlatform() == TargetPlatform.Web) { checkDebuggerFromSdk4(env.getProject(), runProfile, params, bc); } if (bc.getTargetPlatform() == TargetPlatform.Web && !params.isLaunchUrl()) { FlashPlayerTrustUtil.updateTrustedStatus(module, bc, isDebug, params.isRunTrusted()); } return launchFlexConfig(module, bc, params, state, env.getContentToReuse(), env); } } catch (RuntimeConfigurationError e) { throw new ExecutionException(e.getMessage()); } return null; } protected RunContentDescriptor launchDebugProcess(final Module module, final FlexBuildConfiguration bc, final BCBasedRunnerParameters params, final ExecutionEnvironment env) throws ExecutionException { final XDebugSession debugSession = XDebuggerManager.getInstance(module.getProject()).startSession(env, new XDebugProcessStarter() { @Override @NotNull public XDebugProcess start(@NotNull final XDebugSession session) throws ExecutionException { try { if (params instanceof FlexUnitRunnerParameters) { return new FlexDebugProcess(session, bc, params) { @NotNull @Override public ExecutionConsole createConsole() { try { return createFlexUnitRunnerConsole(session.getProject(), env, getProcessHandler()); } catch (ExecutionException e) { Logger.getInstance(FlexBaseRunner.class.getName()).error(e); } return super.createConsole(); } }; } return new FlexDebugProcess(session, bc, params); } catch (IOException e) { iosStopForwardTcpPortIfNeeded(bc, params); throw new ExecutionException(e.getMessage(), e); } } }); debugSession.addSessionListener(new XDebugSessionListener() { @Override public void sessionStopped() { iosStopForwardTcpPortIfNeeded(bc, params); } }); return debugSession.getRunContentDescriptor(); } private static void iosStopForwardTcpPortIfNeeded(final FlexBuildConfiguration bc, final BCBasedRunnerParameters params) { if (params instanceof RemoteFlashRunnerParameters && ((RemoteFlashRunnerParameters)params).getRemoteDebugTarget() == RemoteDebugTarget.iOSDevice && ((RemoteFlashRunnerParameters)params).getDebugTransport() == FlashRunnerParameters.AirMobileDebugTransport.USB) { AirPackageUtil.iosStopForwardTcpPort(bc.getSdk(), ((RemoteFlashRunnerParameters)params).getUsbDebugPort()); } else if (bc.getTargetPlatform() == TargetPlatform.Mobile && params instanceof FlashRunnerParameters && ((FlashRunnerParameters)params).getMobileRunTarget() == FlashRunnerParameters.AirMobileRunTarget.iOSDevice && ((FlashRunnerParameters)params).getDebugTransport() == FlashRunnerParameters.AirMobileDebugTransport.USB) { AirPackageUtil.iosStopForwardTcpPort(bc.getSdk(), ((FlashRunnerParameters)params).getUsbDebugPort()); } } @Nullable protected abstract RunContentDescriptor launchAirFlexUnit(final Project project, final RunProfileState state, final RunContentDescriptor contentToReuse, final ExecutionEnvironment env, final FlexUnitRunnerParameters params) throws ExecutionException; protected abstract RunContentDescriptor launchWebFlexUnit(final Project project, final RunContentDescriptor contentToReuse, final ExecutionEnvironment env, final FlexUnitRunnerParameters params, final String swfFilePath) throws ExecutionException; @Nullable protected abstract RunContentDescriptor launchFlexConfig(final Module module, final FlexBuildConfiguration config, final FlashRunnerParameters params, final RunProfileState state, final RunContentDescriptor contentToReuse, final ExecutionEnvironment environment) throws ExecutionException; public static ExecutionConsole createFlexUnitRunnerConsole(Project project, ExecutionEnvironment env, ProcessHandler processHandler) throws ExecutionException { FlexStackTraceFilter stackTraceFilter = new FlexStackTraceFilter(project); SMTRunnerConsoleProperties consoleProps = new FlexUnitConsoleProperties((FlexUnitRunConfiguration)env.getRunProfile(), env); consoleProps.addStackTraceFilter(stackTraceFilter); BaseTestsOutputConsoleView consoleView = SMTestRunnerConnectionUtil.createAndAttachConsole("FlexUnit", processHandler, consoleProps); consoleView.addMessageFilter(stackTraceFilter); Disposer.register(project, consoleView); return consoleView; } public static void launchWithSelectedApplication(final String urlOrPath, final LauncherParameters launcherParams) { switch (launcherParams.getLauncherType()) { case OSDefault: BrowserUtil.open(urlOrPath); break; case Browser: final Runnable runnable1 = () -> BrowserLauncher.getInstance().browse(BrowserUtil.isAbsoluteURL(urlOrPath) ? urlOrPath : VfsUtilCore.pathToUrl(urlOrPath), launcherParams.getBrowser()); final Application application1 = ApplicationManager.getApplication(); if (application1.isDispatchThread()) { runnable1.run(); } else { application1.invokeLater(runnable1); } break; case Player: try { if (SystemInfo.isMac) { if (launcherParams.isNewPlayerInstance()) { Runtime.getRuntime().exec(new String[]{ExecUtil.getOpenCommandPath(), "-n", "-a", launcherParams.getPlayerPath(), urlOrPath}); } else { Runtime.getRuntime().exec(new String[]{ExecUtil.getOpenCommandPath(), "-a", launcherParams.getPlayerPath(), urlOrPath}); } } else { Runtime.getRuntime().exec(new String[]{launcherParams.getPlayerPath(), urlOrPath}); } // todo read error stream, report errors // todo keep process to be able to kill it on user demand } catch (final IOException e) { final Runnable runnable2 = () -> Messages.showErrorDialog(FlexBundle.message("cant.launch", urlOrPath, launcherParams.getPlayerPath(), e.getMessage()), CommonBundle.getErrorTitle()); final Application application2 = ApplicationManager.getApplication(); if (application2.isDispatchThread()) { runnable2.run(); } else { application2.invokeLater(runnable2); } } break; } } public static boolean packAndInstallToAndroidDevice(final Module module, final FlexBuildConfiguration bc, final FlashRunnerParameters runnerParameters, final String applicationId, final boolean isDebug) { final Project project = module.getProject(); final Sdk sdk = bc.getSdk(); final String outputFolder = PathUtil.getParentPath(bc.getActualOutputFilePath()); final String apkPath = outputFolder + "/" + bc.getAndroidPackagingOptions().getPackageFileName() + ".apk"; final String adtVersion; return (adtVersion = AirPackageUtil.getAdtVersion(project, sdk)) != null && AirPackageUtil.startAdbServer(project, sdk) && AirPackageUtil.scanAndroidDevices(project, sdk, runnerParameters) && AirPackageUtil.checkAirRuntimeOnDevice(project, sdk, runnerParameters, adtVersion) && AirPackageUtil.packageApk(module, bc, runnerParameters, isDebug) && AirPackageUtil.installApk(project, sdk, runnerParameters.getDeviceInfo(), apkPath, applicationId); } public static boolean packAndInstallToIOSSimulator(final Module module, final FlexBuildConfiguration bc, final FlashRunnerParameters runnerParameters, final String adtVersion, final String applicationId, final boolean isDebug) { final Sdk sdk = bc.getSdk(); assert sdk != null; final String outputFolder = PathUtil.getParentPath(bc.getActualOutputFilePath()); final String ipaPath = outputFolder + "/" + bc.getIosPackagingOptions().getPackageFileName() + ".ipa"; if (!AirPackageUtil.checkAdtVersionForPackaging(module.getProject(), adtVersion, "3.3", sdk.getName(), FlexBundle.message("air.ios.simulator.requires.3.3"))) { return false; } return (AirPackageUtil.packageIpaForSimulator(module, bc, runnerParameters, isDebug) && AirPackageUtil.installOnIosSimulator(module.getProject(), sdk, ipaPath, applicationId, runnerParameters.getIOSSimulatorSdkPath())); } public static boolean packAndInstallToIOSDevice(final Module module, final FlexBuildConfiguration bc, final FlashRunnerParameters runnerParameters, final String adtVersion, final boolean isDebug) { final String outputFolder = PathUtil.getParentPath(bc.getActualOutputFilePath()); final String ipaPath = outputFolder + "/" + bc.getIosPackagingOptions().getPackageFileName() + ".ipa"; return AirPackageUtil.packageIpaForDevice(module, bc, runnerParameters, adtVersion, isDebug) && AirPackageUtil.scanIosDevices(module.getProject(), bc.getSdk(), runnerParameters) && AirPackageUtil.installOnIosDevice(module.getProject(), bc.getSdk(), runnerParameters, ipaPath); } @Nullable public static String getApplicationId(final String airDescriptorPath) { final VirtualFile descriptorFile = WriteAction.compute(() -> { final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(airDescriptorPath); if (file != null) { file.refresh(false, false); } return file; }); if (descriptorFile != null) { try { return FlexUtils.findXMLElement(descriptorFile.getInputStream(), "<application><id>"); } catch (IOException ignored) {/*ignore*/} } return null; } @Nullable public static String getApplicationName(final String airDescriptorPath) { final VirtualFile descriptorFile = WriteAction.compute(() -> { final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(airDescriptorPath); if (file != null) { file.refresh(false, false); } return file; }); if (descriptorFile != null) { try { return FlexUtils.findXMLElement(descriptorFile.getInputStream(), "<application><name>"); } catch (IOException ignored) {/*ignore*/} } return null; } public static void launchOnAndroidDevice(final Project project, final Sdk flexSdk, final @Nullable DeviceInfo device, final String applicationId, final boolean isDebug) { if (AirPackageUtil.launchAndroidApplication(project, flexSdk, device, applicationId)) { ToolWindowManager.getInstance(project).notifyByBalloon(isDebug ? ToolWindowId.DEBUG : ToolWindowId.RUN, MessageType.INFO, FlexBundle.message("android.application.launched")); } } public static void launchOnIosSimulator(final Project project, final Sdk flexSdk, final String applicationId, final String iOSSdkPath, final boolean isDebug) { if (AirPackageUtil.launchOnIosSimulator(project, flexSdk, applicationId, iOSSdkPath)) { ToolWindowManager.getInstance(project).notifyByBalloon(isDebug ? ToolWindowId.DEBUG : ToolWindowId.RUN, MessageType.INFO, FlexBundle.message("ios.simulator.application.launched")); } } public static GeneralCommandLine createAdlCommandLine(final Project project, final BCBasedRunnerParameters params, final FlexBuildConfiguration bc, @Nullable String airRuntimePath) throws CantRunException { assert params instanceof FlashRunnerParameters || params instanceof FlexUnitRunnerParameters : params; assert bc.getTargetPlatform() == TargetPlatform.Desktop || bc.getTargetPlatform() == TargetPlatform.Mobile; final Module module = ModuleManager.getInstance(project).findModuleByName(params.getModuleName()); final Sdk sdk = bc.getSdk(); if (module == null) { throw new CantRunException(FlexBundle.message("module.not.found", params.getModuleName())); } if (sdk == null) { throw new CantRunException(FlexCommonBundle.message("sdk.not.set.for.bc.0.of.module.1", bc.getName(), params.getModuleName())); } final GeneralCommandLine commandLine = new GeneralCommandLine(); commandLine.setExePath(FileUtil.toSystemDependentName(FlexSdkUtils.getAdlPath(sdk))); String adlOptions; if (params instanceof FlashRunnerParameters) { adlOptions = bc.getTargetPlatform() == TargetPlatform.Desktop ? ((FlashRunnerParameters)params).getAdlOptions() : ((FlashRunnerParameters)params).getEmulatorAdlOptions(); } else { adlOptions = bc.getTargetPlatform() == TargetPlatform.Desktop ? "" : ((FlexUnitRunnerParameters)params).getEmulatorAdlOptions(); } final List<String> runtimePath = FlexCommonUtils.getOptionValues(adlOptions, "runtime"); if (!runtimePath.isEmpty()) { adlOptions = FlexCommonUtils.removeOptions(adlOptions, "runtime"); airRuntimePath = runtimePath.get(0); } if (airRuntimePath != null) { commandLine.addParameter("-runtime"); commandLine.addParameter(airRuntimePath); } final Collection<VirtualFile> aneFiles = FlexCompilationUtils.getANEFiles(ModuleRootManager.getInstance(module), bc.getDependencies()); if (!aneFiles.isEmpty()) { ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> { final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); if (indicator != null) indicator.setIndeterminate(true); FlexCompilationUtils.unzipANEFiles(aneFiles, indicator); }, "Unzipping ANE files", true, project); } if (bc.getNature().isDesktopPlatform()) { final AirDesktopPackagingOptions packagingOptions = bc.getAirDesktopPackagingOptions(); final String descriptorPath = getAirDescriptorPath(bc, packagingOptions); if ((FlexSdkUtils.isAirSdkWithoutFlex(sdk) || StringUtil.compareVersionNumbers(sdk.getVersionString(), "4.1") >= 0) && FlexCommonUtils.getOptionValues(adlOptions, "profile").isEmpty()) { final String profiles = getSupportedProfiles(descriptorPath); if (profiles == null || profiles.contains("extendedDesktop")) { commandLine.addParameter("-profile"); commandLine.addParameter("extendedDesktop"); } } if (!StringUtil.isEmptyOrSpaces(adlOptions)) { for (StringTokenizer tokenizer = new CommandLineTokenizer(adlOptions); tokenizer.hasMoreTokens(); ) { commandLine.addParameter(tokenizer.nextToken()); } } if (!aneFiles.isEmpty()) { commandLine.addParameter("-extdir"); commandLine.addParameter(FlexCompilationUtils.getPathToUnzipANE()); } commandLine.addParameter(FileUtil.toSystemDependentName(descriptorPath)); commandLine.addParameter(FileUtil.toSystemDependentName(PathUtil.getParentPath(bc.getActualOutputFilePath()))); final String programParameters = params instanceof FlashRunnerParameters ? ((FlashRunnerParameters)params).getAirProgramParameters() : ""; if (!StringUtil.isEmptyOrSpaces(programParameters)) { commandLine.addParameter("--"); for (StringTokenizer tokenizer = new CommandLineTokenizer(programParameters); tokenizer.hasMoreTokens(); ) { commandLine.addParameter(tokenizer.nextToken()); } } } else { final AppDescriptorForEmulator descriptorForEmulator = params instanceof FlashRunnerParameters ? ((FlashRunnerParameters)params).getAppDescriptorForEmulator() : ((FlexUnitRunnerParameters)params).getAppDescriptorForEmulator(); final String descriptorPath = getDescriptorForEmulatorPath(bc, descriptorForEmulator); if (params instanceof FlashRunnerParameters) { final FlashRunnerParameters.AirMobileRunTarget mobileRunTarget = ((FlashRunnerParameters)params).getMobileRunTarget(); assert mobileRunTarget == FlashRunnerParameters.AirMobileRunTarget.Emulator : mobileRunTarget; } if (FlexCommonUtils.getOptionValues(adlOptions, "profile").isEmpty()) { final String profiles = getSupportedProfiles(descriptorPath); if (profiles == null || profiles.contains("extendedMobileDevice")) { commandLine.addParameter("-profile"); commandLine.addParameter("extendedMobileDevice"); } } final FlashRunnerParameters.Emulator emulator = params instanceof FlashRunnerParameters ? ((FlashRunnerParameters)params).getEmulator() : FlashRunnerParameters.Emulator.NexusOne; final boolean customSize = emulator.adlAlias == null; commandLine.addParameter("-screensize"); if (customSize) { assert params instanceof FlashRunnerParameters; final FlashRunnerParameters flashParams = (FlashRunnerParameters)params; commandLine.addParameter(flashParams.getScreenWidth() + "x" + flashParams.getScreenHeight() + ":" + flashParams.getFullScreenWidth() + "x" + flashParams.getFullScreenHeight()); } else { commandLine.addParameter(emulator.adlAlias); } if (FlexCommonUtils.getOptionValues(adlOptions, "XscreenDPI").isEmpty()) { if (customSize && ((FlashRunnerParameters)params).getScreenDpi() > 0) { commandLine.addParameter("-XscreenDPI"); commandLine.addParameter(String.valueOf(((FlashRunnerParameters)params).getScreenDpi())); } else if (!customSize && emulator.screenDPI > 0) { commandLine.addParameter("-XscreenDPI"); commandLine.addParameter(String.valueOf(emulator.screenDPI)); } } if (FlexCommonUtils.getOptionValues(adlOptions, "XversionPlatform").isEmpty() && emulator.versionPlatform != null) { commandLine.addParameter("-XversionPlatform"); commandLine.addParameter(emulator.versionPlatform); } if (!StringUtil.isEmptyOrSpaces(adlOptions)) { for (StringTokenizer tokenizer = new CommandLineTokenizer(adlOptions); tokenizer.hasMoreTokens(); ) { commandLine.addParameter(tokenizer.nextToken()); } } if (!aneFiles.isEmpty()) { commandLine.addParameter("-extdir"); commandLine.addParameter(FlexCompilationUtils.getPathToUnzipANE()); } commandLine.addParameter(FileUtil.toSystemDependentName(descriptorPath)); commandLine.addParameter(FileUtil.toSystemDependentName(PathUtil.getParentPath(bc.getActualOutputFilePath()))); } return commandLine; } @Nullable private static String getSupportedProfiles(final String descriptorPath) { final File descriptorFile = new File(descriptorPath); if (descriptorFile.isFile()) { try { return JDOMUtil.load(descriptorFile).getChildTextNormalize("supportedProfiles", JDOMUtil.load(descriptorFile).getNamespace()); } catch (JDOMException ignore) {/*ignore*/} catch (IOException ignore) {/*ignore*/} } return null; } private static String getDescriptorForEmulatorPath(final FlexBuildConfiguration bc, final AppDescriptorForEmulator appDescriptorForEmulator) { final String airDescriptorPath; switch (appDescriptorForEmulator) { case Android: airDescriptorPath = getAirDescriptorPath(bc, bc.getAndroidPackagingOptions()); break; case IOS: airDescriptorPath = getAirDescriptorPath(bc, bc.getIosPackagingOptions()); break; default: assert false; airDescriptorPath = ""; } return airDescriptorPath; } public static String getAirDescriptorPath(final FlexBuildConfiguration bc, final AirPackagingOptions packagingOptions) { return PathUtil.getParentPath(bc.getActualOutputFilePath()) + "/" + getAirDescriptorFileName(bc, packagingOptions); } private static String getAirDescriptorFileName(final FlexBuildConfiguration bc, final AirPackagingOptions packagingOptions) { return packagingOptions.isUseGeneratedDescriptor() || bc.isTempBCForCompilation() ? BCUtils.getGeneratedAirDescriptorName(bc, packagingOptions) : PathUtil.getFileName(packagingOptions.getCustomDescriptorPath()); } private static void checkMakeBeforeRunEnabled(final Project project, final RunProfile runProfile) { final RunManager runManager = RunManagerEx.getInstance(project); int count = RunManagerEx.getTasksCount(project, (RunConfiguration)runProfile, CompileStepBeforeRun.ID, CompileStepBeforeRunNoErrorCheck.ID); if (count == 0) { for (RunnerAndConfigurationSettings settings : runManager.getConfigurationSettingsList(((RunConfiguration)runProfile).getType())) { if (settings.getConfiguration() == runProfile) { showMakeBeforeRunTurnedOffWarning(project, settings); break; } } } } private static void showMakeBeforeRunTurnedOffWarning(final Project project, final RunnerAndConfigurationSettings configuration) { final String message = FlexBundle.message("run.when.compile.before.run.turned.off"); COMPILE_BEFORE_LAUNCH_NOTIFICATION_GROUP.createNotification("", message, NotificationType.WARNING, new NotificationListener() { @Override public void hyperlinkUpdate(@NotNull final Notification notification, @NotNull final HyperlinkEvent event) { if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { notification.expire(); if ("RunConfiguration".equals(event.getDescription())) { RunDialog.editConfiguration(project, configuration, FlexBundle.message("edit.configuration.title")); } else if ("DisableWarning".equals(event.getDescription())) { disableCompilationSkippedWarning(project); } } } }).notify(project); } private static void showBCCompilationSkippedWarning(final Module module, final FlexBuildConfiguration bc) { final String message = FlexBundle.message("run.when.ide.builder.turned.off", bc.getName(), module.getName()); COMPILE_BEFORE_LAUNCH_NOTIFICATION_GROUP.createNotification("", message, NotificationType.WARNING, new NotificationListener() { @Override public void hyperlinkUpdate(@NotNull final Notification notification, @NotNull final HyperlinkEvent event) { if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { notification.expire(); if ("BuildConfiguration".equals(event.getDescription())) { final ProjectStructureConfigurable projectStructureConfigurable = ProjectStructureConfigurable.getInstance(module.getProject()); ShowSettingsUtil.getInstance().editConfigurable(module.getProject(), projectStructureConfigurable, () -> { Place p = FlexBuildConfigurationsExtension.getInstance().getConfigurator().getPlaceFor(module, bc.getName()); projectStructureConfigurable.navigateTo(p, true); }); } else if ("DisableWarning".equals(event.getDescription())) { disableCompilationSkippedWarning(module.getProject()); } } } }).notify(module.getProject()); } private static void disableCompilationSkippedWarning(final Project project) { NotificationsConfiguration.getNotificationsConfiguration() .changeSettings(COMPILE_BEFORE_LAUNCH_NOTIFICATION_GROUP.getDisplayId(), NotificationDisplayType.NONE, false, false); ToolWindowManager.getInstance(project) .notifyByBalloon(EventLog.LOG_TOOL_WINDOW_ID, MessageType.INFO, FlexBundle.message("make.before.launch.warning.disabled")); } private static void checkDebuggerFromSdk4(final Project project, final RunProfile runProfile, final FlashRunnerParameters params, final FlexBuildConfiguration bc) { final Sdk sdk = bc.getSdk(); assert sdk != null; final Sdk sdkForDebugger = FlexDebugProcess.getDebuggerSdk(params.getDebuggerSdkRaw(), sdk); if (!FlexSdkUtils.isAirSdkWithoutFlex(sdk) && StringUtil.compareVersionNumbers(sdkForDebugger.getVersionString(), "4") < 0) { final HyperlinkListener listener = new HyperlinkAdapter() { @Override protected void hyperlinkActivated(final HyperlinkEvent e) { if ("RunConfiguration".equals(e.getDescription())) { for (RunnerAndConfigurationSettings configuration : RunManager.getInstance(project).getConfigurationSettingsList(((RunConfiguration)runProfile).getType())) { if (configuration.getConfiguration() == runProfile) { RunDialog.editConfiguration(project, configuration, FlexBundle.message("edit.configuration.title")); break; } } } } }; final String message = FlexBundle.message("flex.sdk.3.mac.debug.problem", sdkForDebugger.getVersionString()); ToolWindowManager.getInstance(project).notifyByBalloon(ToolWindowId.DEBUG, MessageType.WARNING, message, null, listener); } } private static class FlexUnitConsoleProperties extends SMTRunnerConsoleProperties { public FlexUnitConsoleProperties(RunConfiguration runConfiguration, ExecutionEnvironment env) { super(runConfiguration, "FlexUnit", env.getExecutor()); } @Nullable @Override public SMTestLocator getTestLocator() { return FlexQualifiedNameLocationProvider.INSTANCE; } } }