186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta/*
286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * Copyright (C) 2014 The Android Open Source Project
386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *
486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * Licensed under the Apache License, Version 2.0 (the "License");
586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * you may not use this file except in compliance with the License.
686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * You may obtain a copy of the License at
786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *
886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *      http://www.apache.org/licenses/LICENSE-2.0
986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *
1086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * Unless required by applicable law or agreed to in writing, software
1186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * distributed under the License is distributed on an "AS IS" BASIS,
1286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * See the License for the specific language governing permissions and
1486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * limitations under the License.
1586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta */
1686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
1786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptapackage com.android.layoutlib.bridge.intensive;
1886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
1986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.annotations.NonNull;
2086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.ide.common.rendering.api.LayoutLog;
2186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.ide.common.rendering.api.RenderSession;
2286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.ide.common.rendering.api.Result;
2386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.ide.common.rendering.api.SessionParams;
2486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.ide.common.rendering.api.SessionParams.RenderingMode;
2586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.ide.common.resources.FrameworkResources;
2686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.ide.common.resources.ResourceItem;
2786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.ide.common.resources.ResourceRepository;
2886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.ide.common.resources.ResourceResolver;
2986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.ide.common.resources.configuration.FolderConfiguration;
3086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.io.FolderWrapper;
3186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.layoutlib.bridge.Bridge;
3286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.layoutlib.bridge.intensive.setup.ConfigGenerator;
3386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback;
3486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
3586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport com.android.utils.ILogger;
3686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
3786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport org.junit.Before;
3886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport org.junit.Test;
3986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
4086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport java.io.File;
4186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport java.io.FileFilter;
4258df125bbc76fd71a9c056c6b6108fc149733b0eDeepanshu Guptaimport java.io.IOException;
4386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport java.net.URL;
4486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport java.util.Arrays;
4586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport java.util.Comparator;
4686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
4786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptaimport static org.junit.Assert.fail;
4886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
4986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta/**
5086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * This is a set of tests that loads all the framework resources and a project checked in this
5186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * test's resources. The main dependencies
5286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * are:
5386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * 1. Fonts directory.
5486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * 2. Framework Resources.
5586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * 3. App resources.
5686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * 4. build.prop file
5786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *
5886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * These are configured by two variables set in the system properties.
5986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *
6086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * 1. platform.dir: This is the directory for the current platform in the built SDK
6186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *     (.../sdk/platforms/android-<version>).
6286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *
6386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *     The fonts are platform.dir/data/fonts.
6486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *     The Framework resources are platform.dir/data/res.
6586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *     build.prop is at platform.dir/build.prop.
6686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *
6786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta * 2. test_res.dir: This is the directory for the resources of the test. If not specified, this
6886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *     falls back to getClass().getProtectionDomain().getCodeSource().getLocation()
6986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *
7086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta *     The app resources are at: test_res.dir/testApp/MyApplication/app/src/main/res
7186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta */
7286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Guptapublic class Main {
7386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
7486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private static final String PLATFORM_DIR_PROPERTY = "platform.dir";
7586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private static final String RESOURCE_DIR_PROPERTY = "test_res.dir";
7686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
7786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private static final String PLATFORM_DIR;
7886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private static final String TEST_RES_DIR;
79d657b149274aeba0561e68f7172907b300d1b452Deepanshu Gupta    /** Location of the app to test inside {@link #TEST_RES_DIR}*/
80d657b149274aeba0561e68f7172907b300d1b452Deepanshu Gupta    private static final String APP_TEST_DIR = "/testApp/MyApplication";
81d657b149274aeba0561e68f7172907b300d1b452Deepanshu Gupta    /** Location of the app's res dir inside {@link #TEST_RES_DIR}*/
82d657b149274aeba0561e68f7172907b300d1b452Deepanshu Gupta    private static final String APP_TEST_RES = APP_TEST_DIR + "/src/main/res";
8386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
8486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private LayoutLog mLayoutLibLog;
8586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private FrameworkResources mFrameworkRepo;
8686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private ResourceRepository mProjectResources;
8786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private ILogger mLogger;
8886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private Bridge mBridge;
8986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
9086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    static {
9186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        // Test that System Properties are properly set.
9286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        PLATFORM_DIR = getPlatformDir();
9386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        if (PLATFORM_DIR == null) {
9486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            fail(String.format("System Property %1$s not properly set. The value is %2$s",
9586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    PLATFORM_DIR_PROPERTY, System.getProperty(PLATFORM_DIR_PROPERTY)));
9686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
9786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
9886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        TEST_RES_DIR = getTestResDir();
9986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        if (TEST_RES_DIR == null) {
10086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            fail(String.format("System property %1$s.dir not properly set. The value is %2$s",
10186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    RESOURCE_DIR_PROPERTY, System.getProperty(RESOURCE_DIR_PROPERTY)));
10286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
10386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
10486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
10586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private static String getPlatformDir() {
10686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        String platformDir = System.getProperty(PLATFORM_DIR_PROPERTY);
10786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        if (platformDir != null && !platformDir.isEmpty() && new File(platformDir).isDirectory()) {
10886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            return platformDir;
10986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
11086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        // System Property not set. Try to find the directory in the build directory.
1110774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        String androidHostOut = System.getenv("ANDROID_HOST_OUT");
1120774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        if (androidHostOut != null) {
1130774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            platformDir = getPlatformDirFromHostOut(new File(androidHostOut));
1140774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            if (platformDir != null) {
1150774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta                return platformDir;
1160774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            }
1170774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        }
1180774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        String workingDirString = System.getProperty("user.dir");
1190774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        File workingDir = new File(workingDirString);
1200774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        // Test if workingDir is android checkout root.
1210774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        platformDir = getPlatformDirFromRoot(workingDir);
1220774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        if (platformDir != null) {
1230774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            return platformDir;
1240774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        }
1250774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        // Test if workingDir is  platform/frameworks/base/tools/layoutlib. That is, root should be
1260774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        // workingDir/../../../../  (4 levels up)
1270774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        File currentDir = workingDir;
1280774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        for (int i = 0; i < 4; i++) {
1290774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            if (currentDir != null) {
1300774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta                currentDir = currentDir.getParentFile();
1310774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            }
1320774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        }
1330774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        return currentDir == null ? null : getPlatformDirFromRoot(currentDir);
1340774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta    }
1350774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta
1360774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta    private static String getPlatformDirFromRoot(File root) {
1370774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        if (!root.isDirectory()) {
1380774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            return null;
1390774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        }
1400774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        File out = new File(root, "out");
1410774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        if (!out.isDirectory()) {
1420774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            return null;
1430774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        }
1440774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        File host = new File(out, "host");
1450774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        if (!host.isDirectory()) {
1460774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            return null;
1470774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        }
1480774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        File[] hosts = host.listFiles(new FileFilter() {
1490774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            @Override
1500774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            public boolean accept(File path) {
1510774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta                return path.isDirectory() && (path.getName().startsWith("linux-") || path.getName()
1520774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta                        .startsWith("darwin-"));
1530774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            }
1540774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        });
1550774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        for (File hostOut : hosts) {
1560774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            String platformDir = getPlatformDirFromHostOut(hostOut);
1570774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            if (platformDir != null) {
1580774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta                return platformDir;
1590774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta            }
1600774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        }
1610774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        return null;
1620774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta    }
1630774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta
1640774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta    private static String getPlatformDirFromHostOut(File out) {
1650774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta        if (!out.isDirectory()) {
16686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            return null;
16786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
1680359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta        File sdkDir = new File(out, "sdk");
16986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        if (!sdkDir.isDirectory()) {
17086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            return null;
17186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
1720359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta        File[] sdkDirs = sdkDir.listFiles(new FileFilter() {
1730359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta            @Override
1740359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta            public boolean accept(File path) {
1750359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta                // We need to search for $TARGET_PRODUCT (usually, sdk_phone_armv7)
1760359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta                return path.isDirectory() && path.getName().startsWith("sdk");
1770359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta            }
1780359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta        });
1790359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta        for (File dir : sdkDirs) {
1800359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta            String platformDir = getPlatformDirFromHostOutSdkSdk(dir);
1810359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta            if (platformDir != null) {
1820359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta                return platformDir;
1830359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta            }
1840359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta        }
1850359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta        return null;
1860359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta    }
1870359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta
1880359b4b19962a4e3c44925907dedb4a9bfd916d0Deepanshu Gupta    private static String getPlatformDirFromHostOutSdkSdk(File sdkDir) {
18986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        File[] possibleSdks = sdkDir.listFiles(new FileFilter() {
19086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            @Override
19170d1574db986610232d59ee1406d7532f71812f5Deepanshu Gupta            public boolean accept(File path) {
1920774bc4605fdd47178cc38258d1b4c40ae113b2fDeepanshu Gupta                return path.isDirectory() && path.getName().contains("android-sdk");
19386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            }
19486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        });
19586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        for (File possibleSdk : possibleSdks) {
19686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            File platformsDir = new File(possibleSdk, "platforms");
19786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            File[] platforms = platformsDir.listFiles(new FileFilter() {
19886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                @Override
19970d1574db986610232d59ee1406d7532f71812f5Deepanshu Gupta                public boolean accept(File path) {
20070d1574db986610232d59ee1406d7532f71812f5Deepanshu Gupta                    return path.isDirectory() && path.getName().startsWith("android-");
20186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                }
20286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            });
20386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            if (platforms == null || platforms.length == 0) {
20486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                continue;
20586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            }
20686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            Arrays.sort(platforms, new Comparator<File>() {
20786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                // Codenames before ints. Higher APIs precede lower.
20886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                @Override
20986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                public int compare(File o1, File o2) {
21086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    final int MAX_VALUE = 1000;
21170d1574db986610232d59ee1406d7532f71812f5Deepanshu Gupta                    String suffix1 = o1.getName().substring("android-".length());
21270d1574db986610232d59ee1406d7532f71812f5Deepanshu Gupta                    String suffix2 = o2.getName().substring("android-".length());
21386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    int suff1, suff2;
21486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    try {
21586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                        suff1 = Integer.parseInt(suffix1);
21686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    } catch (NumberFormatException e) {
21786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                        suff1 = MAX_VALUE;
21886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    }
21986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    try {
22086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                        suff2 = Integer.parseInt(suffix2);
22186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    } catch (NumberFormatException e) {
22286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                        suff2 = MAX_VALUE;
22386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    }
22486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    if (suff1 != MAX_VALUE || suff2 != MAX_VALUE) {
22586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                        return suff2 - suff1;
22686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    }
22786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    return suffix2.compareTo(suffix1);
22886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                }
22986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            });
23086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            return platforms[0].getAbsolutePath();
23186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
23286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        return null;
23386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
23486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
23586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private static String getTestResDir() {
23686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        String resourceDir = System.getProperty(RESOURCE_DIR_PROPERTY);
23786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        if (resourceDir != null && !resourceDir.isEmpty() && new File(resourceDir).isDirectory()) {
23886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            return resourceDir;
23986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
24086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        // TEST_RES_DIR not explicitly set. Fallback to the class's source location.
24186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        try {
24286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            URL location = Main.class.getProtectionDomain().getCodeSource().getLocation();
24386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            return new File(location.getPath()).exists() ? location.getPath() : null;
24486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        } catch (NullPointerException e) {
24586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            // Prevent a lot of null checks by just catching the exception.
24686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            return null;
24786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
24886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
24986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    /**
25086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta     * Initialize the bridge and the resource maps.
25186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta     */
25286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    @Before
25386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    public void setUp() {
25486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        File data_dir = new File(PLATFORM_DIR, "data");
25586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        File res = new File(data_dir, "res");
25686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        mFrameworkRepo = new FrameworkResources(new FolderWrapper(res));
25786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        mFrameworkRepo.loadResources();
25886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        mFrameworkRepo.loadPublicResources(getLogger());
25986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
26086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        mProjectResources =
26186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                new ResourceRepository(new FolderWrapper(TEST_RES_DIR + APP_TEST_RES), false) {
26286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            @NonNull
26386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            @Override
26486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            protected ResourceItem createResourceItem(String name) {
26586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                return new ResourceItem(name);
26686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            }
26786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        };
26886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        mProjectResources.loadResources();
26986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
27086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        File fontLocation = new File(data_dir, "fonts");
27186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        File buildProp = new File(PLATFORM_DIR, "build.prop");
27286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        File attrs = new File(res, "values" + File.separator + "attrs.xml");
27386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        mBridge = new Bridge();
27486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        mBridge.init(ConfigGenerator.loadProperties(buildProp), fontLocation,
27586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                ConfigGenerator.getEnumMap(attrs), getLayoutLog());
27686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
27786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
27886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    /**
27986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta     * Create a new rendering session and test that rendering /layout/activity.xml on nexus 5
28086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta     * doesn't throw any exceptions.
28186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta     */
28286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    @Test
28386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    public void testRendering() throws ClassNotFoundException {
28486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        // Create the layout pull parser.
28586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        LayoutPullParser parser = new LayoutPullParser(APP_TEST_RES + "/layout/activity.xml");
28686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        // Create LayoutLibCallback.
28786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        LayoutLibTestCallback layoutLibCallback = new LayoutLibTestCallback(getLogger());
28886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        layoutLibCallback.initResources();
28986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        // TODO: Set up action bar handler properly to test menu rendering.
29086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        // Create session params.
29186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5, layoutLibCallback);
29286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        RenderSession session = mBridge.createSession(params);
29386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        if (!session.getResult().isSuccess()) {
29486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            getLogger().error(session.getResult().getException(),
29586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    session.getResult().getErrorMessage());
29686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
29786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        // Render the session with a timeout of 50s.
29886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        Result renderResult = session.render(50000);
29986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        if (!renderResult.isSuccess()) {
30086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            getLogger().error(session.getResult().getException(),
30186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    session.getResult().getErrorMessage());
30286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
30358df125bbc76fd71a9c056c6b6108fc149733b0eDeepanshu Gupta        try {
304d657b149274aeba0561e68f7172907b300d1b452Deepanshu Gupta            String goldenImagePath = APP_TEST_DIR + "/golden/activity.png";
305d657b149274aeba0561e68f7172907b300d1b452Deepanshu Gupta            ImageUtils.requireSimilar(goldenImagePath, session.getImage());
30658df125bbc76fd71a9c056c6b6108fc149733b0eDeepanshu Gupta        } catch (IOException e) {
30758df125bbc76fd71a9c056c6b6108fc149733b0eDeepanshu Gupta            getLogger().error(e, e.getMessage());
30858df125bbc76fd71a9c056c6b6108fc149733b0eDeepanshu Gupta        }
30986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
31086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
31186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    /**
31286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta     * Uses Theme.Material and Target sdk version as 21.
31386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta     */
31486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private SessionParams getSessionParams(LayoutPullParser layoutParser,
31586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            ConfigGenerator configGenerator, LayoutLibTestCallback layoutLibCallback) {
31686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        FolderConfiguration config = configGenerator.getFolderConfig();
31786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        ResourceResolver resourceResolver =
31886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                ResourceResolver.create(mProjectResources.getConfiguredResources(config),
31986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                        mFrameworkRepo.getConfiguredResources(config), "Theme.Material", false);
32086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
32186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        return new SessionParams(
32286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                layoutParser,
32386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                RenderingMode.NORMAL,
32486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                null /*used for caching*/,
32586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                configGenerator.getHardwareConfig(),
32686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                resourceResolver,
32786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                layoutLibCallback,
32886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                0,
32986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                21, // TODO: Make it more configurable to run tests for various versions.
33086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                getLayoutLog());
33186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
33286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
33386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private LayoutLog getLayoutLog() {
33486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        if (mLayoutLibLog == null) {
33586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            mLayoutLibLog = new LayoutLog() {
33686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                @Override
33786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                public void warning(String tag, String message, Object data) {
33886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    System.out.println("Warning " + tag + ": " + message);
33986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    fail(message);
34086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                }
34186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
34286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                @Override
34386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                public void fidelityWarning(String tag, String message, Throwable throwable,
34486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                        Object data) {
34586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    System.out.println("FidelityWarning " + tag + ": " + message);
34686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    if (throwable != null) {
34786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                        throwable.printStackTrace();
34886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    }
34986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    fail(message);
35086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                }
35186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
35286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                @Override
35386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                public void error(String tag, String message, Object data) {
35486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    System.out.println("Error " + tag + ": " + message);
35586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    fail(message);
35686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                }
35786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
35886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                @Override
35986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                public void error(String tag, String message, Throwable throwable, Object data) {
36086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    System.out.println("Error " + tag + ": " + message);
36186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    if (throwable != null) {
36286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                        throwable.printStackTrace();
36386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    }
36486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    fail(message);
36586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                }
36686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            };
36786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
36886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        return mLayoutLibLog;
36986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
37086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
37186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    private ILogger getLogger() {
37286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        if (mLogger == null) {
37386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            mLogger = new ILogger() {
37486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                @Override
37586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                public void error(Throwable t, String msgFormat, Object... args) {
37686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    if (t != null) {
37786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                        t.printStackTrace();
37886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    }
37986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    fail(String.format(msgFormat, args));
38086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                }
38186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
38286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                @Override
38386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                public void warning(String msgFormat, Object... args) {
38486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    fail(String.format(msgFormat, args));
38586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                }
38686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
38786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                @Override
38886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                public void info(String msgFormat, Object... args) {
38986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    // pass.
39086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                }
39186eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta
39286eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                @Override
39386eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                public void verbose(String msgFormat, Object... args) {
39486eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                    // pass.
39586eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta                }
39686eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta            };
39786eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        }
39886eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta        return mLogger;
39986eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta    }
40086eb8b4e29b1ad889fc814bae723d4d6e491f53fDeepanshu Gupta}
401