FileDocCategorySizeDatePackage
Main.javaAPI DocAndroid 5.1 API15817Thu Mar 12 22:22:44 GMT 2015com.android.layoutlib.bridge.intensive

Main

public class Main extends Object
This is a set of tests that loads all the framework resources and a project checked in this test's resources. The main dependencies are: 1. Fonts directory. 2. Framework Resources. 3. App resources. 4. build.prop file These are configured by two variables set in the system properties. 1. platform.dir: This is the directory for the current platform in the built SDK (.../sdk/platforms/android-). The fonts are platform.dir/data/fonts. The Framework resources are platform.dir/data/res. build.prop is at platform.dir/build.prop. 2. test_res.dir: This is the directory for the resources of the test. If not specified, this falls back to getClass().getProtectionDomain().getCodeSource().getLocation() The app resources are at: test_res.dir/testApp/MyApplication/app/src/main/res

Fields Summary
private static final String
PLATFORM_DIR_PROPERTY
private static final String
RESOURCE_DIR_PROPERTY
private static final String
PLATFORM_DIR
private static final String
TEST_RES_DIR
private static final String
APP_TEST_DIR
Location of the app to test inside {@link #TEST_RES_DIR}
private static final String
APP_TEST_RES
Location of the app's res dir inside {@link #TEST_RES_DIR}
private com.android.ide.common.rendering.api.LayoutLog
mLayoutLibLog
private com.android.ide.common.resources.FrameworkResources
mFrameworkRepo
private com.android.ide.common.resources.ResourceRepository
mProjectResources
private com.android.utils.ILogger
mLogger
private com.android.layoutlib.bridge.Bridge
mBridge
Constructors Summary
Methods Summary
private com.android.ide.common.rendering.api.LayoutLoggetLayoutLog()

        if (mLayoutLibLog == null) {
            mLayoutLibLog = new LayoutLog() {
                @Override
                public void warning(String tag, String message, Object data) {
                    System.out.println("Warning " + tag + ": " + message);
                    fail(message);
                }

                @Override
                public void fidelityWarning(String tag, String message, Throwable throwable,
                        Object data) {
                    System.out.println("FidelityWarning " + tag + ": " + message);
                    if (throwable != null) {
                        throwable.printStackTrace();
                    }
                    fail(message);
                }

                @Override
                public void error(String tag, String message, Object data) {
                    System.out.println("Error " + tag + ": " + message);
                    fail(message);
                }

                @Override
                public void error(String tag, String message, Throwable throwable, Object data) {
                    System.out.println("Error " + tag + ": " + message);
                    if (throwable != null) {
                        throwable.printStackTrace();
                    }
                    fail(message);
                }
            };
        }
        return mLayoutLibLog;
    
private com.android.utils.ILoggergetLogger()

        if (mLogger == null) {
            mLogger = new ILogger() {
                @Override
                public void error(Throwable t, String msgFormat, Object... args) {
                    if (t != null) {
                        t.printStackTrace();
                    }
                    fail(String.format(msgFormat, args));
                }

                @Override
                public void warning(String msgFormat, Object... args) {
                    fail(String.format(msgFormat, args));
                }

                @Override
                public void info(String msgFormat, Object... args) {
                    // pass.
                }

                @Override
                public void verbose(String msgFormat, Object... args) {
                    // pass.
                }
            };
        }
        return mLogger;
    
private static java.lang.StringgetPlatformDir()


     
        // Test that System Properties are properly set.
        PLATFORM_DIR = getPlatformDir();
        if (PLATFORM_DIR == null) {
            fail(String.format("System Property %1$s not properly set. The value is %2$s",
                    PLATFORM_DIR_PROPERTY, System.getProperty(PLATFORM_DIR_PROPERTY)));
        }

        TEST_RES_DIR = getTestResDir();
        if (TEST_RES_DIR == null) {
            fail(String.format("System property %1$s.dir not properly set. The value is %2$s",
                    RESOURCE_DIR_PROPERTY, System.getProperty(RESOURCE_DIR_PROPERTY)));
        }
    
        String platformDir = System.getProperty(PLATFORM_DIR_PROPERTY);
        if (platformDir != null && !platformDir.isEmpty() && new File(platformDir).isDirectory()) {
            return platformDir;
        }
        // System Property not set. Try to find the directory in the build directory.
        String androidHostOut = System.getenv("ANDROID_HOST_OUT");
        if (androidHostOut != null) {
            platformDir = getPlatformDirFromHostOut(new File(androidHostOut));
            if (platformDir != null) {
                return platformDir;
            }
        }
        String workingDirString = System.getProperty("user.dir");
        File workingDir = new File(workingDirString);
        // Test if workingDir is android checkout root.
        platformDir = getPlatformDirFromRoot(workingDir);
        if (platformDir != null) {
            return platformDir;
        }
        // Test if workingDir is  platform/frameworks/base/tools/layoutlib. That is, root should be
        // workingDir/../../../../  (4 levels up)
        File currentDir = workingDir;
        for (int i = 0; i < 4; i++) {
            if (currentDir != null) {
                currentDir = currentDir.getParentFile();
            }
        }
        return currentDir == null ? null : getPlatformDirFromRoot(currentDir);
    
private static java.lang.StringgetPlatformDirFromHostOut(java.io.File out)

        if (!out.isDirectory()) {
            return null;
        }
        File sdkDir = new File(out, "sdk");
        if (!sdkDir.isDirectory()) {
            return null;
        }
        File[] sdkDirs = sdkDir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File path) {
                // We need to search for $TARGET_PRODUCT (usually, sdk_phone_armv7)
                return path.isDirectory() && path.getName().startsWith("sdk");
            }
        });
        for (File dir : sdkDirs) {
            String platformDir = getPlatformDirFromHostOutSdkSdk(dir);
            if (platformDir != null) {
                return platformDir;
            }
        }
        return null;
    
private static java.lang.StringgetPlatformDirFromHostOutSdkSdk(java.io.File sdkDir)

        File[] possibleSdks = sdkDir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File path) {
                return path.isDirectory() && path.getName().contains("android-sdk");
            }
        });
        for (File possibleSdk : possibleSdks) {
            File platformsDir = new File(possibleSdk, "platforms");
            File[] platforms = platformsDir.listFiles(new FileFilter() {
                @Override
                public boolean accept(File path) {
                    return path.isDirectory() && path.getName().startsWith("android-");
                }
            });
            if (platforms == null || platforms.length == 0) {
                continue;
            }
            Arrays.sort(platforms, new Comparator<File>() {
                // Codenames before ints. Higher APIs precede lower.
                @Override
                public int compare(File o1, File o2) {
                    final int MAX_VALUE = 1000;
                    String suffix1 = o1.getName().substring("android-".length());
                    String suffix2 = o2.getName().substring("android-".length());
                    int suff1, suff2;
                    try {
                        suff1 = Integer.parseInt(suffix1);
                    } catch (NumberFormatException e) {
                        suff1 = MAX_VALUE;
                    }
                    try {
                        suff2 = Integer.parseInt(suffix2);
                    } catch (NumberFormatException e) {
                        suff2 = MAX_VALUE;
                    }
                    if (suff1 != MAX_VALUE || suff2 != MAX_VALUE) {
                        return suff2 - suff1;
                    }
                    return suffix2.compareTo(suffix1);
                }
            });
            return platforms[0].getAbsolutePath();
        }
        return null;
    
private static java.lang.StringgetPlatformDirFromRoot(java.io.File root)

        if (!root.isDirectory()) {
            return null;
        }
        File out = new File(root, "out");
        if (!out.isDirectory()) {
            return null;
        }
        File host = new File(out, "host");
        if (!host.isDirectory()) {
            return null;
        }
        File[] hosts = host.listFiles(new FileFilter() {
            @Override
            public boolean accept(File path) {
                return path.isDirectory() && (path.getName().startsWith("linux-") || path.getName()
                        .startsWith("darwin-"));
            }
        });
        for (File hostOut : hosts) {
            String platformDir = getPlatformDirFromHostOut(hostOut);
            if (platformDir != null) {
                return platformDir;
            }
        }
        return null;
    
private com.android.ide.common.rendering.api.SessionParamsgetSessionParams(com.android.layoutlib.bridge.intensive.setup.LayoutPullParser layoutParser, com.android.layoutlib.bridge.intensive.setup.ConfigGenerator configGenerator, com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback layoutLibCallback)
Uses Theme.Material and Target sdk version as 21.

        FolderConfiguration config = configGenerator.getFolderConfig();
        ResourceResolver resourceResolver =
                ResourceResolver.create(mProjectResources.getConfiguredResources(config),
                        mFrameworkRepo.getConfiguredResources(config), "Theme.Material", false);

        return new SessionParams(
                layoutParser,
                RenderingMode.NORMAL,
                null /*used for caching*/,
                configGenerator.getHardwareConfig(),
                resourceResolver,
                layoutLibCallback,
                0,
                21, // TODO: Make it more configurable to run tests for various versions.
                getLayoutLog());
    
private static java.lang.StringgetTestResDir()

        String resourceDir = System.getProperty(RESOURCE_DIR_PROPERTY);
        if (resourceDir != null && !resourceDir.isEmpty() && new File(resourceDir).isDirectory()) {
            return resourceDir;
        }
        // TEST_RES_DIR not explicitly set. Fallback to the class's source location.
        try {
            URL location = Main.class.getProtectionDomain().getCodeSource().getLocation();
            return new File(location.getPath()).exists() ? location.getPath() : null;
        } catch (NullPointerException e) {
            // Prevent a lot of null checks by just catching the exception.
            return null;
        }
    
public voidsetUp()
Initialize the bridge and the resource maps.

        File data_dir = new File(PLATFORM_DIR, "data");
        File res = new File(data_dir, "res");
        mFrameworkRepo = new FrameworkResources(new FolderWrapper(res));
        mFrameworkRepo.loadResources();
        mFrameworkRepo.loadPublicResources(getLogger());

        mProjectResources =
                new ResourceRepository(new FolderWrapper(TEST_RES_DIR + APP_TEST_RES), false) {
            @NonNull
            @Override
            protected ResourceItem createResourceItem(String name) {
                return new ResourceItem(name);
            }
        };
        mProjectResources.loadResources();

        File fontLocation = new File(data_dir, "fonts");
        File buildProp = new File(PLATFORM_DIR, "build.prop");
        File attrs = new File(res, "values" + File.separator + "attrs.xml");
        mBridge = new Bridge();
        mBridge.init(ConfigGenerator.loadProperties(buildProp), fontLocation,
                ConfigGenerator.getEnumMap(attrs), getLayoutLog());
    
public voidtestRendering()
Create a new rendering session and test that rendering /layout/activity.xml on nexus 5 doesn't throw any exceptions.

        // Create the layout pull parser.
        LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/activity.xml");
        // Create LayoutLibCallback.
        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
        layoutLibCallback.initResources();
        // TODO: Set up action bar handler properly to test menu rendering.
        // Create session params.
        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5, layoutLibCallback);
        RenderSession session = mBridge.createSession(params);
        if (!session.getResult().isSuccess()) {
            getLogger().error(session.getResult().getException(),
                    session.getResult().getErrorMessage());
        }
        // Render the session with a timeout of 50s.
        Result renderResult = session.render(50000);
        if (!renderResult.isSuccess()) {
            getLogger().error(session.getResult().getException(),
                    session.getResult().getErrorMessage());
        }
        try {
            String goldenImagePath = APP_TEST_DIR + "/golden/activity.png";
            ImageUtils.requireSimilar(goldenImagePath, session.getImage());
        } catch (IOException e) {
            getLogger().error(e, e.getMessage());
        }