Back to Repositories

Validating 9-Patch PNG Divider Processing in Apktool

This test suite validates the handling of 9-patch PNG images in Android APK decompilation, specifically focusing on the correct addition of missing divider lines. It ensures proper decoding and preservation of 9-patch image specifications during the APK tool’s processing.

Test Coverage Overview

The test suite provides comprehensive coverage of 9-patch image processing, focusing on edge cases where divider lines may be missing. It verifies the decoder’s ability to properly handle and reconstruct 9-patch images during APK decompilation.

  • Tests missing divider addition in 9-patch PNGs
  • Validates pixel color values for NinePatch specifications
  • Ensures proper image dimension handling

Implementation Analysis

The testing approach utilizes JUnit framework to validate the Res9patchStreamDecoder functionality. It implements a systematic verification of image processing by examining individual pixel values and ensuring correct color application for NinePatch markers.

  • Uses ByteArrayStream for image data manipulation
  • Implements pixel-level verification using BufferedImage
  • Employs resource directory copying for test setup

Technical Details

  • JUnit testing framework
  • Java ImageIO for image processing
  • ByteArrayInputStream/OutputStream for data handling
  • Custom Res9patchStreamDecoder implementation
  • TestUtils for resource management

Best Practices Demonstrated

The test demonstrates excellent testing practices by isolating the 9-patch processing functionality and providing clear validation points. It properly handles resource cleanup and implements thorough verification of image processing results.

  • Proper test setup using @BeforeClass
  • Clear assertion messages for debugging
  • Efficient resource handling with try-with-resources
  • Systematic pixel validation approach

ibotpeaches/apktool

brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/MissingDiv9PatchTest.java

            
/*
 *  Copyright (C) 2010 Ryszard Wiśniewski <[email protected]>
 *  Copyright (C) 2010 Connor Tumbleson <[email protected]>
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package brut.androlib.decode;

import brut.androlib.BaseTest;
import brut.androlib.TestUtils;
import brut.androlib.res.decoder.Res9patchStreamDecoder;
import brut.common.BrutException;
import brut.directory.ExtFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.File;
import java.nio.file.Files;

import org.junit.*;
import static org.junit.Assert.*;

public class MissingDiv9PatchTest extends BaseTest {
    private static final int NP_COLOR = 0xff000000;

    @BeforeClass
    public static void beforeClass() throws Exception {
        TestUtils.copyResourceDir(MissingDiv9PatchTest.class, "decode/issue1522", sTmpDir);
    }

    @Test
    public void assertMissingDivAdded() throws Exception {
        File file = new File(sTmpDir, "pip_dismiss_scrim.9.png");
        byte[] data;

        try (InputStream in = Files.newInputStream(file.toPath())) {
            Res9patchStreamDecoder decoder = new Res9patchStreamDecoder();
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            decoder.decode(in, out);
            data = out.toByteArray();
        }

        BufferedImage image = ImageIO.read(new ByteArrayInputStream(data));
        int height = image.getHeight() - 1;

        // First and last pixel will be invisible, so lets check the first column and ensure its all black
        for (int y = 1; y < height; y++) {
            assertEquals("y coordinate failed at: " + y, NP_COLOR, image.getRGB(0, y));
        }
    }
}