Search in sources :

Example 1 with LayoutLibrary

use of com.android.ide.common.rendering.LayoutLibrary in project android by JetBrains.

the class Configuration method syncFolderConfig.

/**
   * Updates the folder configuration such that it reflects changes in
   * configuration state such as the device orientation, the UI mode, the
   * rendering target, etc.
   */
protected void syncFolderConfig() {
    Device device = getDevice();
    if (device == null) {
        return;
    }
    // get the device config from the device/state combos.
    State deviceState = getDeviceState();
    if (deviceState == null) {
        deviceState = device.getDefaultState();
    }
    FolderConfiguration config = getFolderConfig(getModule(), deviceState, getLocale(), getTarget());
    // replace the config with the one from the device
    myFullConfig.set(config);
    // sync the selected locale
    Locale locale = getLocale();
    myFullConfig.setLocaleQualifier(locale.qualifier);
    if (myEditedConfig.getLayoutDirectionQualifier() != null) {
        myFullConfig.setLayoutDirectionQualifier(myEditedConfig.getLayoutDirectionQualifier());
    } else if (!locale.hasLanguage()) {
        // Avoid getting the layout library if the locale doesn't have any language.
        myFullConfig.setLayoutDirectionQualifier(new LayoutDirectionQualifier(LayoutDirection.LTR));
    } else {
        LayoutLibrary layoutLib = RenderService.getLayoutLibrary(getModule(), getTarget());
        if (layoutLib != null) {
            if (layoutLib.isRtl(locale.toLocaleId())) {
                myFullConfig.setLayoutDirectionQualifier(new LayoutDirectionQualifier(LayoutDirection.RTL));
            } else {
                myFullConfig.setLayoutDirectionQualifier(new LayoutDirectionQualifier(LayoutDirection.LTR));
            }
        }
    }
    // Replace the UiMode with the selected one, if one is selected
    UiMode uiMode = getUiMode();
    myFullConfig.setUiModeQualifier(new UiModeQualifier(uiMode));
    // Replace the NightMode with the selected one, if one is selected
    NightMode nightMode = getNightMode();
    myFullConfig.setNightModeQualifier(new NightModeQualifier(nightMode));
    // replace the API level by the selection of the combo
    IAndroidTarget target = getTarget();
    if (target != null) {
        int apiLevel = target.getVersion().getFeatureLevel();
        myFullConfig.setVersionQualifier(new VersionQualifier(apiLevel));
    }
    myFolderConfigDirty = 0;
    myProjectStateVersion = myManager.getStateVersion();
}
Also used : Locale(com.android.tools.idea.rendering.Locale) LayoutLibrary(com.android.ide.common.rendering.LayoutLibrary) Device(com.android.sdklib.devices.Device) IAndroidTarget(com.android.sdklib.IAndroidTarget) State(com.android.sdklib.devices.State)

Example 2 with LayoutLibrary

use of com.android.ide.common.rendering.LayoutLibrary in project android by JetBrains.

the class RenderService method supportsCapability.

public static boolean supportsCapability(@NotNull final Module module, @NotNull IAndroidTarget target, @MagicConstant(flagsFromClass = Features.class) int capability) {
    Project project = module.getProject();
    AndroidPlatform platform = AndroidPlatform.getInstance(module);
    if (platform != null) {
        try {
            LayoutLibrary library = platform.getSdkData().getTargetData(target).getLayoutLibrary(project);
            if (library != null) {
                return library.supports(capability);
            }
        } catch (RenderingException | IOException e) {
        // Ignore: if service can't be found, that capability isn't available
        }
    }
    return false;
}
Also used : Project(com.intellij.openapi.project.Project) LayoutLibrary(com.android.ide.common.rendering.LayoutLibrary) RenderingException(com.android.tools.idea.layoutlib.RenderingException) AndroidPlatform(org.jetbrains.android.sdk.AndroidPlatform) IOException(java.io.IOException)

Example 3 with LayoutLibrary

use of com.android.ide.common.rendering.LayoutLibrary in project android by JetBrains.

the class RenderService method createTask.

/**
   * Creates a new {@link RenderService} associated with the given editor.
   *
   * @return a {@link RenderService} which can perform rendering services
   */
@Nullable
public RenderTask createTask(@Nullable final PsiFile psiFile, @NotNull final Configuration configuration, @NotNull final RenderLogger logger, @Nullable final EditorDesignSurface surface) {
    Module module = myFacet.getModule();
    final Project project = module.getProject();
    AndroidPlatform platform = getPlatform(module, logger);
    if (platform == null) {
        return null;
    }
    IAndroidTarget target = configuration.getTarget();
    if (target == null) {
        logger.addMessage(RenderProblem.createPlain(ERROR, "No render target was chosen"));
        return null;
    }
    warnIfObsoleteLayoutLib(module, logger, surface, target);
    LayoutLibrary layoutLib;
    try {
        layoutLib = platform.getSdkData().getTargetData(target).getLayoutLibrary(project);
        if (layoutLib == null) {
            String message = AndroidBundle.message("android.layout.preview.cannot.load.library.error");
            logger.addMessage(RenderProblem.createPlain(ERROR, message));
            return null;
        }
    } catch (UnsupportedJavaRuntimeException e) {
        RenderProblem.Html javaVersionProblem = RenderProblem.create(ERROR);
        javaVersionProblem.getHtmlBuilder().add(e.getPresentableMessage()).newline().addLink("Install a supported JDK", JDK_INSTALL_URL);
        logger.addMessage(javaVersionProblem);
        return null;
    } catch (RenderingException e) {
        String message = e.getPresentableMessage();
        message = message != null ? message : AndroidBundle.message("android.layout.preview.default.error.message");
        logger.addMessage(RenderProblem.createPlain(ERROR, message, module.getProject(), logger.getLinkManager(), e));
        return null;
    } catch (IOException e) {
        final String message = e.getMessage();
        logger.error(null, "I/O error: " + (message != null ? ": " + message : ""), e);
        return null;
    }
    if (psiFile != null && TAG_PREFERENCE_SCREEN.equals(AndroidPsiUtils.getRootTagName(psiFile)) && !layoutLib.supports(Features.PREFERENCES_RENDERING)) {
        // This means that user is using an outdated version of layoutlib. A warning to update has already been
        // presented in warnIfObsoleteLayoutLib(). Just log a plain message asking users to update.
        logger.addMessage(RenderProblem.createPlain(ERROR, "This version of the rendering library does not support rendering Preferences. " + "Update it using the SDK Manager"));
        return null;
    }
    Device device = configuration.getDevice();
    if (device == null) {
        logger.addMessage(RenderProblem.createPlain(ERROR, "No device selected"));
        return null;
    }
    try {
        RenderTask task = new RenderTask(this, configuration, logger, layoutLib, device, myCredential, CrashReporter.getInstance());
        if (psiFile != null) {
            task.setPsiFile(psiFile);
        }
        task.setDesignSurface(surface);
        return task;
    } catch (IncorrectOperationException | AssertionError e) {
        // We can get this exception if the module/project is closed while we are updating the model. Ignore it.
        assert myFacet.isDisposed();
    }
    return null;
}
Also used : LayoutLibrary(com.android.ide.common.rendering.LayoutLibrary) Device(com.android.sdklib.devices.Device) UnsupportedJavaRuntimeException(com.android.tools.idea.layoutlib.UnsupportedJavaRuntimeException) RenderingException(com.android.tools.idea.layoutlib.RenderingException) AndroidPlatform(org.jetbrains.android.sdk.AndroidPlatform) IAndroidTarget(com.android.sdklib.IAndroidTarget) IOException(java.io.IOException) Project(com.intellij.openapi.project.Project) IncorrectOperationException(com.intellij.util.IncorrectOperationException) Module(com.intellij.openapi.module.Module) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with LayoutLibrary

use of com.android.ide.common.rendering.LayoutLibrary in project android by JetBrains.

the class ModuleClassLoaderTest method testAARPriority.

/**
   * Verifies that the AAR generated R classes are given priority vs the build generated files. This is important in cases like support
   * library upgrades/downgrades. In those cases, the build generated file, will be outdated so it shouldn't be used by the ModuleClassLoader.
   * By preferring the AAR geneated versions, we make sure we are always up-to-date.
   * See <a href="http://b.android.com/229382">229382</a>
   */
public void testAARPriority() throws ClassNotFoundException, IOException {
    LayoutLibrary layoutLibrary = mock(LayoutLibrary.class);
    Module module = myFixture.getModule();
    File tmpDir = Files.createTempDir();
    File outputDir = new File(tmpDir, CompilerModuleExtension.PRODUCTION + "/" + module.getName() + "/test");
    assertTrue(FileUtil.createDirectory(outputDir));
    CompilerProjectExtension.getInstance(getProject()).setCompilerOutputUrl(pathToIdeaUrl(tmpDir));
    generateRClass("test", new File(outputDir, "R.class"));
    AppResourceRepository appResources = AppResourceRepository.getAppResources(module, true);
    ResourceClassRegistry rClassRegistry = ResourceClassRegistry.get(module.getProject());
    rClassRegistry.addLibrary(appResources, "test");
    AtomicBoolean noSuchField = new AtomicBoolean(false);
    ApplicationManager.getApplication().runReadAction(() -> {
        ModuleClassLoader loader = ModuleClassLoader.get(layoutLibrary, module);
        try {
            Class<?> rClass = loader.loadClass("test.R");
            rClass.getDeclaredField("ID");
        } catch (NoSuchFieldException e) {
            noSuchField.set(true);
        } catch (ClassNotFoundException e) {
            fail("Unexpected exception " + e.getLocalizedMessage());
        }
    });
    assertTrue(noSuchField.get());
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) LayoutLibrary(com.android.ide.common.rendering.LayoutLibrary) AppResourceRepository(com.android.tools.idea.res.AppResourceRepository) Module(com.intellij.openapi.module.Module) ResourceClassRegistry(com.android.tools.idea.res.ResourceClassRegistry) File(java.io.File)

Example 5 with LayoutLibrary

use of com.android.ide.common.rendering.LayoutLibrary in project android by JetBrains.

the class LayoutLibraryLoader method load.

@Nullable
public static LayoutLibrary load(@NotNull IAndroidTarget target, @NotNull Map<String, Map<String, Integer>> enumMap) throws RenderingException, IOException {
    final String fontFolderPath = FileUtil.toSystemIndependentName((target.getPath(IAndroidTarget.FONTS)));
    final VirtualFile fontFolder = LocalFileSystem.getInstance().findFileByPath(fontFolderPath);
    if (fontFolder == null || !fontFolder.isDirectory()) {
        throw new RenderingException(LayoutlibBundle.message("android.directory.cannot.be.found.error", FileUtil.toSystemDependentName(fontFolderPath)));
    }
    final String platformFolderPath = target.isPlatform() ? target.getLocation() : target.getParent().getLocation();
    final File platformFolder = new File(platformFolderPath);
    if (!platformFolder.isDirectory()) {
        throw new RenderingException(LayoutlibBundle.message("android.directory.cannot.be.found.error", FileUtil.toSystemDependentName(platformFolderPath)));
    }
    final File buildProp = new File(platformFolder, SdkConstants.FN_BUILD_PROP);
    if (!buildProp.isFile()) {
        throw new RenderingException(LayoutlibBundle.message("android.file.not.exist.error", FileUtil.toSystemDependentName(buildProp.getPath())));
    }
    if (!SystemInfo.isJavaVersionAtLeast("1.8") && target.getVersion().getFeatureLevel() >= 24) {
        // From N, we require to be running in Java 8
        throw new UnsupportedJavaRuntimeException(LayoutlibBundle.message("android.layout.preview.unsupported.jdk", SdkVersionInfo.getCodeName(target.getVersion().getFeatureLevel())));
    }
    LayoutLibrary library;
    final ILogger logger = new LogWrapper(LOG);
    if (USE_SDK_LAYOUTLIB) {
        final String resFolderPath = FileUtil.toSystemIndependentName((target.getPath(IAndroidTarget.RESOURCES)));
        final VirtualFile resFolder = LocalFileSystem.getInstance().findFileByPath(resFolderPath);
        if (resFolder == null || !resFolder.isDirectory()) {
            throw new RenderingException(LayoutlibBundle.message("android.directory.cannot.be.found.error", FileUtil.toSystemDependentName(resFolderPath)));
        }
        final String layoutLibJarPath = FileUtil.toSystemIndependentName((target.getPath(IAndroidTarget.LAYOUT_LIB)));
        final VirtualFile layoutLibJar = LocalFileSystem.getInstance().findFileByPath(layoutLibJarPath);
        if (layoutLibJar == null || layoutLibJar.isDirectory()) {
            throw new RenderingException(LayoutlibBundle.message("android.file.not.exist.error", FileUtil.toSystemDependentName(layoutLibJarPath)));
        }
        library = LayoutLibrary.load(layoutLibJar.getPath(), logger, ApplicationNamesInfo.getInstance().getFullProductName());
    } else {
        // We instantiate the local Bridge implementation and pass it to the LayoutLibrary instance
        library = LayoutLibrary.load(new Bridge(), LayoutLibraryLoader.class.getClassLoader());
    }
    if (library.getStatus() != LoadStatus.LOADED) {
        throw new RenderingException(library.getLoadMessage());
    }
    final Map<String, String> buildPropMap = ProjectProperties.parsePropertyFile(new BufferingFileWrapper(buildProp), logger);
    final LayoutLog layoutLog = new LayoutLogWrapper(LOG);
    if (library.init(buildPropMap, new File(fontFolder.getPath()), enumMap, layoutLog)) {
        return library;
    } else {
        return null;
    }
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) BufferingFileWrapper(org.jetbrains.android.util.BufferingFileWrapper) LayoutLibrary(com.android.ide.common.rendering.LayoutLibrary) ILogger(com.android.utils.ILogger) VirtualFile(com.intellij.openapi.vfs.VirtualFile) File(java.io.File) Bridge(com.android.layoutlib.bridge.Bridge) LayoutLog(com.android.ide.common.rendering.api.LayoutLog) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

LayoutLibrary (com.android.ide.common.rendering.LayoutLibrary)9 Module (com.intellij.openapi.module.Module)5 IAndroidTarget (com.android.sdklib.IAndroidTarget)4 Device (com.android.sdklib.devices.Device)3 RenderingException (com.android.tools.idea.layoutlib.RenderingException)3 File (java.io.File)3 IOException (java.io.IOException)3 AndroidPlatform (org.jetbrains.android.sdk.AndroidPlatform)3 Nullable (org.jetbrains.annotations.Nullable)3 AppResourceRepository (com.android.tools.idea.res.AppResourceRepository)2 Project (com.intellij.openapi.project.Project)2 HardwareConfigHelper (com.android.ide.common.rendering.HardwareConfigHelper)1 LayoutLog (com.android.ide.common.rendering.api.LayoutLog)1 ResourceResolver (com.android.ide.common.resources.ResourceResolver)1 FolderConfiguration (com.android.ide.common.resources.configuration.FolderConfiguration)1 Bridge (com.android.layoutlib.bridge.Bridge)1 State (com.android.sdklib.devices.State)1 UnsupportedJavaRuntimeException (com.android.tools.idea.layoutlib.UnsupportedJavaRuntimeException)1 AndroidModuleInfo (com.android.tools.idea.model.AndroidModuleInfo)1 Locale (com.android.tools.idea.rendering.Locale)1