1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.settings.testutils;
17
18import java.net.MalformedURLException;
19import java.net.URL;
20import org.junit.runners.model.InitializationError;
21import org.robolectric.RobolectricTestRunner;
22import org.robolectric.annotation.Config;
23import org.robolectric.manifest.AndroidManifest;
24import org.robolectric.res.Fs;
25import org.robolectric.res.ResourcePath;
26
27import java.util.List;
28
29/**
30 * Custom test runner for the testing of BluetoothPairingDialogs. This is needed because the
31 * default behavior for robolectric is just to grab the resource directory in the target package.
32 * We want to override this to add several spanning different projects.
33 */
34public class SettingsRobolectricTestRunner extends RobolectricTestRunner {
35
36    /**
37     * We don't actually want to change this behavior, so we just call super.
38     */
39    public SettingsRobolectricTestRunner(Class<?> testClass) throws InitializationError {
40        super(testClass);
41    }
42
43    /**
44     * We are going to create our own custom manifest so that we can add multiple resource
45     * paths to it. This lets us access resources in both Settings and SettingsLib in our tests.
46     */
47    @Override
48    protected AndroidManifest getAppManifest(Config config) {
49        try {
50            // Using the manifest file's relative path, we can figure out the application directory.
51            final URL appRoot = new URL("file:packages/apps/Settings/");
52            final URL manifestPath = new URL(appRoot, "AndroidManifest.xml");
53            final URL resDir = new URL(appRoot, "tests/robotests/res");
54            final URL assetsDir = new URL(appRoot, "tests/robotests/assets");
55
56            // By adding any resources from libraries we need the AndroidManifest, we can access
57            // them from within the parallel universe's resource loader.
58            return new AndroidManifest(Fs.fromURL(manifestPath), Fs.fromURL(resDir),
59                Fs.fromURL(assetsDir), "com.android.settings") {
60                @Override
61                public List<ResourcePath> getIncludedResourcePaths() {
62                    final List<ResourcePath> paths = super.getIncludedResourcePaths();
63                    addIncludedResourcePaths(paths);
64                    return paths;
65                }
66            };
67        } catch (MalformedURLException e) {
68            throw new RuntimeException("SettingsRobolectricTestRunner failure", e);
69        }
70    }
71
72    public static void addIncludedResourcePaths(List<ResourcePath> paths) {
73        try {
74            paths.add(new ResourcePath(null,
75                Fs.fromURL(new URL("file:packages/apps/Settings/res")), null));
76            paths.add(new ResourcePath(null,
77                Fs.fromURL(new URL("file:frameworks/base/packages/SettingsLib/res")), null));
78            paths.add(new ResourcePath(null,
79                Fs.fromURL(new URL("file:frameworks/base/core/res/res")), null));
80            paths.add(new ResourcePath(null,
81                Fs.fromURL(new URL("file:frameworks/opt/setupwizard/library/main/res")), null));
82            paths.add(new ResourcePath(null,
83                Fs.fromURL(new URL("file:frameworks/opt/setupwizard/library/gingerbread/res")), null));
84            paths.add(new ResourcePath(null,
85                Fs.fromURL(new URL("file:frameworks/opt/setupwizard/library/recyclerview/res")), null));
86            paths.add(new ResourcePath(null,
87                Fs.fromURL(new URL("file:frameworks/support/v7/appcompat/res")), null));
88            paths.add(new ResourcePath(null,
89                Fs.fromURL(new URL("file:frameworks/support/v7/cardview/res")), null));
90        } catch (MalformedURLException e) {
91            throw new RuntimeException("SettingsRobolectricTestRunner failure", e);
92        }
93    }
94}
95