Search in sources :

Example 1 with DeviceData

use of com.android.tools.idea.ddms.screenshot.DeviceArtPainter.DeviceData in project android by JetBrains.

the class DeviceArtPainterTest method testCropData.

// This test no longer applies; it was used to convert assets with a lot of padding into more tightly cropped screenshots.
// We're preserving the code since for future device releases we might get new artwork which includes padding.
@Test
@Ignore
public void testCropData() throws Exception {
    // Apply crop
    DeviceArtPainter framePainter = DeviceArtPainter.getInstance();
    Device device = newDevice();
    File srcDir = DeviceArtDescriptor.getBundledDescriptorsFolder();
    File destDir = new File(myTemporaryFolder.newFolder(), "device-art");
    if (!destDir.exists()) {
        boolean ok = destDir.mkdirs();
        assertTrue(ok);
    }
    StringBuilder sb = new StringBuilder(1000);
    sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<!-- Copyright (C) 2013 The Android Open Source Project\n" + "\n" + "     Licensed under the Apache License, Version 2.0 (the \"License\");\n" + "     you may not use this file except in compliance with the License.\n" + "     You may obtain a copy of the License at\n" + "\n" + "          http://www.apache.org/licenses/LICENSE-2.0\n" + "\n" + "     Unless required by applicable law or agreed to in writing, software\n" + "     distributed under the License is distributed on an \"AS IS\" BASIS,\n" + "     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" + "     See the License for the specific language governing permissions and\n" + "     limitations under the License.\n" + "-->\n" + "<devices>\n" + "\n");
    for (DeviceArtDescriptor spec : framePainter.getDescriptors()) {
        sb.append("  <device id=\"");
        sb.append(spec.getId());
        sb.append("\" name=\"");
        sb.append(spec.getName());
        sb.append("\">\n");
        DeviceData deviceData = new DeviceData(device, spec);
        for (ScreenOrientation orientation : ScreenOrientation.values()) {
            if (orientation == ScreenOrientation.SQUARE) {
                continue;
            }
            if (orientation != ScreenOrientation.LANDSCAPE && spec.getId().startsWith("tv_")) {
                // Android TV only uses landscape orientation
                continue;
            }
            Rectangle cropRect = spec.getCrop(orientation);
            sb.append("    <orientation name=\"");
            sb.append(orientation.getResourceValue());
            sb.append("\" ");
            DeviceArtDescriptor descriptor = deviceData.getDescriptor();
            if (spec.getName().startsWith("Generic ") || cropRect == null || spec.getName().startsWith("Android TV")) {
                System.out.println("Nothing to do for " + spec.getId() + " orientation " + orientation);
                cropRect = new Rectangle(0, 0, descriptor.getFrameSize(orientation).width, descriptor.getFrameSize(orientation).height);
            }
            sb.append("size=\"");
            sb.append(Integer.toString(cropRect.width));
            sb.append(",");
            sb.append(Integer.toString(cropRect.height));
            sb.append("\" screenPos=\"");
            sb.append(Integer.toString(descriptor.getScreenPos(orientation).x - cropRect.x));
            sb.append(",");
            sb.append(Integer.toString(descriptor.getScreenPos(orientation).y - cropRect.y));
            sb.append("\" screenSize=\"");
            sb.append(Integer.toString(descriptor.getScreenSize(orientation).width));
            sb.append(",");
            sb.append(Integer.toString(descriptor.getScreenSize(orientation).height));
            sb.append("\"");
            if (descriptor.getDropShadow(orientation) != null) {
                sb.append(" shadow=\"");
                //noinspection ConstantConditions
                sb.append(descriptor.getDropShadow(orientation).getName());
                sb.append("\"");
            }
            if (descriptor.getFrame(orientation) != null) {
                sb.append(" back=\"");
                //noinspection ConstantConditions
                sb.append(descriptor.getFrame(orientation).getName());
                sb.append("\"");
            }
            if (descriptor.getReflectionOverlay(orientation) != null) {
                sb.append(" lights=\"");
                //noinspection ConstantConditions
                sb.append(descriptor.getReflectionOverlay(orientation).getName());
                sb.append("\"");
            }
            if (descriptor.getMask(orientation) != null) {
                sb.append(" mask=\"");
                //noinspection ConstantConditions
                sb.append(descriptor.getMask(orientation).getName());
                sb.append("\"");
            }
            sb.append("/>\n");
            // Must use computeImage rather than getImage here since we want to get the
            // full size images, not the already cropped images
            writeCropped(srcDir, destDir, spec, cropRect, descriptor.getFrame(orientation));
            writeCropped(srcDir, destDir, spec, cropRect, descriptor.getDropShadow(orientation));
            writeCropped(srcDir, destDir, spec, cropRect, descriptor.getReflectionOverlay(orientation));
            writeCropped(srcDir, destDir, spec, cropRect, descriptor.getMask(orientation));
        }
        // (3) Rewrite emulator skin file
        File layoutFile = new File(srcDir, spec.getId() + File.separator + SdkConstants.FN_SKIN_LAYOUT);
        if (layoutFile.exists() && !spec.getId().startsWith("tv_")) {
            // no crop data in tv (and lack of portrait fails below)
            String layout = Files.toString(layoutFile, Charsets.UTF_8);
            final Rectangle portraitCrop = spec.getCrop(ScreenOrientation.PORTRAIT);
            if (portraitCrop != null) {
                final Rectangle landscapeCrop = spec.getCrop(ScreenOrientation.LANDSCAPE);
                layout = replace(layout, new String[] { "layouts {", "portrait {", "width " }, new Function<Integer, Integer>() {

                    @Override
                    public Integer apply(@Nullable Integer input) {
                        return portraitCrop.width;
                    }
                });
                layout = replace(layout, new String[] { "layouts {", "portrait {", "height " }, new Function<Integer, Integer>() {

                    @Override
                    public Integer apply(@Nullable Integer input) {
                        return portraitCrop.height;
                    }
                });
                layout = replace(layout, new String[] { "layouts {", "portrait {", "part2 {", "x " }, new Function<Integer, Integer>() {

                    @Override
                    public Integer apply(@Nullable Integer input) {
                        //noinspection ConstantConditions
                        return input - portraitCrop.x;
                    }
                });
                layout = replace(layout, new String[] { "layouts {", "portrait {", "part2 {", "y " }, new Function<Integer, Integer>() {

                    @Override
                    public Integer apply(@Nullable Integer input) {
                        //noinspection ConstantConditions
                        return input - portraitCrop.y;
                    }
                });
                // landscape
                layout = replace(layout, new String[] { "layouts {", "landscape {", "width " }, new Function<Integer, Integer>() {

                    @Override
                    public Integer apply(@Nullable Integer input) {
                        return landscapeCrop.width;
                    }
                });
                layout = replace(layout, new String[] { "layouts {", "landscape {", "height " }, new Function<Integer, Integer>() {

                    @Override
                    public Integer apply(@Nullable Integer input) {
                        return landscapeCrop.height;
                    }
                });
                layout = replace(layout, new String[] { "layouts {", "landscape {", "part2 {", "x " }, new Function<Integer, Integer>() {

                    @Override
                    public Integer apply(@Nullable Integer input) {
                        //noinspection ConstantConditions
                        return input - landscapeCrop.x;
                    }
                });
                layout = replace(layout, new String[] { "layouts {", "landscape {", "part2 {", "y " }, new Function<Integer, Integer>() {

                    @Override
                    public Integer apply(@Nullable Integer input) {
                        //noinspection ConstantConditions
                        return input - landscapeCrop.y;
                    }
                });
                File outputLayoutFile = new File(destDir, spec.getId() + File.separator + SdkConstants.FN_SKIN_LAYOUT);
                if (!outputLayoutFile.getParentFile().exists()) {
                    boolean mkdirs = outputLayoutFile.getParentFile().mkdirs();
                    assertTrue(mkdirs);
                }
                Files.write(layout, outputLayoutFile, Charsets.UTF_8);
            } else {
            // No crop data found; this device frame has already been cropped
            }
        }
        sb.append("  </device>\n\n");
    }
    sb.append("\n</devices>\n");
    File deviceArt = new File(destDir, "device-art.xml");
    Files.write(sb.toString(), deviceArt, Charsets.UTF_8);
    System.out.println("Wrote device art file " + deviceArt);
}
Also used : Device(com.android.sdklib.devices.Device) ScreenOrientation(com.android.resources.ScreenOrientation) Function(com.google.common.base.Function) DeviceData(com.android.tools.idea.ddms.screenshot.DeviceArtPainter.DeviceData) File(java.io.File) Nullable(org.jetbrains.annotations.Nullable) Ignore(org.junit.Ignore) DeviceSchemaTest(com.android.dvlib.DeviceSchemaTest) Test(org.junit.Test)

Example 2 with DeviceData

use of com.android.tools.idea.ddms.screenshot.DeviceArtPainter.DeviceData in project android by JetBrains.

the class DeviceArtPainterTest method testRendering.

// This test is disabled but code is preserved here; this is handy for quickly checking rendering results when tweaking the code to
// assemble composite images. (Make sure you also turn off the thumbnail cache first! Return null from DeviceArtPainter#getCachedImage.)
@Test
@Ignore
public void testRendering() throws Exception {
    DeviceArtPainter framePainter = DeviceArtPainter.getInstance();
    for (DeviceArtDescriptor spec : framePainter.getDescriptors()) {
        if ("wear_round".equals(spec.getId())) {
            FrameData frameData = new DeviceData(null, spec).getFrameData(ScreenOrientation.LANDSCAPE, 320);
            BufferedImage image = frameData.getImage(true);
            @SuppressWarnings("SSBasedInspection") File file = File.createTempFile("test-rendering", "png");
            if (file.exists()) {
                boolean deleted = file.delete();
                assertTrue(deleted);
            }
            ImageIO.write(image, "PNG", file);
            if (file.exists() && SystemInfo.isMac) {
                Runtime.getRuntime().exec("/usr/bin/open " + file.getPath());
            }
        }
    }
}
Also used : DeviceData(com.android.tools.idea.ddms.screenshot.DeviceArtPainter.DeviceData) File(java.io.File) BufferedImage(java.awt.image.BufferedImage) FrameData(com.android.tools.idea.ddms.screenshot.DeviceArtPainter.FrameData) Ignore(org.junit.Ignore) DeviceSchemaTest(com.android.dvlib.DeviceSchemaTest) Test(org.junit.Test)

Example 3 with DeviceData

use of com.android.tools.idea.ddms.screenshot.DeviceArtPainter.DeviceData in project android by JetBrains.

the class DeviceArtPainterTest method generateCropData.

public void generateCropData() throws Exception {
    DeviceArtPainter framePainter = DeviceArtPainter.getInstance();
    Device device = newDevice();
    for (DeviceArtDescriptor spec : framePainter.getDescriptors()) {
        DeviceData data = new DeviceData(device, spec);
        Rectangle cropRect = spec.getCrop(ScreenOrientation.LANDSCAPE);
        if (spec.getName().startsWith("Generic ")) {
            // No crop data for generic nine patches since they are stretchable
            continue;
        }
        if (cropRect != null && !cropRect.getSize().equals(spec.getScreenSize(ScreenOrientation.LANDSCAPE))) {
            // Already have crop data for this spec; skipping
            continue;
        }
        if (spec.getName().startsWith("Android TV")) {
            // These images are already cropped
            continue;
        }
        System.out.println("for spec " + spec.getName() + " -- " + spec.getId());
        FrameData landscapeData = data.getFrameData(ScreenOrientation.LANDSCAPE, Integer.MAX_VALUE);
        // Must use computeImage rather than getImage here since we want to get the
        // full size images, not the already cropped images
        BufferedImage effectsImage;
        Rectangle crop;
        ImageUtils.CropFilter filter = new ImageUtils.CropFilter() {

            @Override
            public boolean crop(BufferedImage bufferedImage, int x, int y) {
                int rgb = bufferedImage.getRGB(x, y);
                return ((rgb & 0xFF000000) >>> 24) < 2;
            }
        };
        FrameData portraitData = data.getFrameData(ScreenOrientation.PORTRAIT, Integer.MAX_VALUE);
        try {
            effectsImage = portraitData.computeImage(true, 0, 0, portraitData.getFrameWidth(), portraitData.getFrameHeight());
        } catch (OutOfMemoryError oome) {
            // This test sometimes fails on the build server because it runs out of memory; it's a memory
            // hungry test which sometimes fails when run as part of thousands of other tests.
            // Ignore those types of failures.
            // Make sure it's not failing to allocate memory due to some crazy large bounds we didn't anticipate:
            assertTrue(portraitData.getFrameWidth() < 4000);
            assertTrue(portraitData.getFrameHeight() < 4000);
            return;
        }
        assertNotNull(effectsImage);
        crop = ImageUtils.getCropBounds(effectsImage, filter, null);
        assertNotNull(crop);
        System.out.print("      port crop=\"");
        System.out.print(crop.x);
        System.out.print(",");
        System.out.print(crop.y);
        System.out.print(",");
        System.out.print(crop.width);
        System.out.print(",");
        System.out.print(crop.height);
        System.out.println("\"");
        try {
            effectsImage = landscapeData.computeImage(true, 0, 0, landscapeData.getFrameWidth(), landscapeData.getFrameHeight());
        } catch (OutOfMemoryError oome) {
            // See portrait case above
            assertTrue(landscapeData.getFrameWidth() < 4000);
            assertTrue(landscapeData.getFrameHeight() < 4000);
            return;
        }
        assertNotNull(effectsImage);
        crop = ImageUtils.getCropBounds(effectsImage, filter, null);
        assertNotNull(crop);
        System.out.print("      landscape crop=\"");
        System.out.print(crop.x);
        System.out.print(",");
        System.out.print(crop.y);
        System.out.print(",");
        System.out.print(crop.width);
        System.out.print(",");
        System.out.print(crop.height);
        System.out.println("\"");
    }
}
Also used : ImageUtils(com.android.tools.idea.rendering.ImageUtils) Device(com.android.sdklib.devices.Device) DeviceData(com.android.tools.idea.ddms.screenshot.DeviceArtPainter.DeviceData) BufferedImage(java.awt.image.BufferedImage) FrameData(com.android.tools.idea.ddms.screenshot.DeviceArtPainter.FrameData)

Aggregations

DeviceData (com.android.tools.idea.ddms.screenshot.DeviceArtPainter.DeviceData)3 DeviceSchemaTest (com.android.dvlib.DeviceSchemaTest)2 Device (com.android.sdklib.devices.Device)2 FrameData (com.android.tools.idea.ddms.screenshot.DeviceArtPainter.FrameData)2 BufferedImage (java.awt.image.BufferedImage)2 File (java.io.File)2 Ignore (org.junit.Ignore)2 Test (org.junit.Test)2 ScreenOrientation (com.android.resources.ScreenOrientation)1 ImageUtils (com.android.tools.idea.rendering.ImageUtils)1 Function (com.google.common.base.Function)1 Nullable (org.jetbrains.annotations.Nullable)1