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();
}
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;
}
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;
}
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());
}
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;
}
}
Aggregations