1/*
2 * Copyright (C) 2009 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 */
16
17package vogar;
18
19import java.util.ArrayList;
20import java.util.Arrays;
21import java.util.List;
22
23public enum ModeId {
24    /** ART (works >= L) */
25    DEVICE,
26    /** Dalvik (works <= KitKat) */
27    DEVICE_DALVIK,
28    /** ART (for KitKat only, use DEVICE_DALVIK otherwise) */
29    DEVICE_ART_KITKAT,
30
31    /** ART (works >= L) */
32    HOST,
33    /** Dalvik (works <= KitKat) */
34    HOST_DALVIK,
35    /** ART for KitKat only */
36    HOST_ART_KITKAT,
37    /** Local Java */
38    JVM,
39    /** Device, execution as an Android app with Zygote */
40    ACTIVITY,
41    /** Device using app_process binary */
42    APP_PROCESS;
43
44    // $BOOTCLASSPATH defined by system/core/rootdir/init.rc
45    private static final String[] DALVIK_DEVICE_JARS = new String[] {"core"};
46    private static final String[] ART_DEVICE_JARS = new String[] {"core-libart"};
47    private static final String[] COMMON_DEVICE_JARS = new String[] {
48            "conscrypt",
49            "okhttp",
50            "core-junit",
51            "bouncycastle",
52            "ext",
53            "framework",
54            "telephony-common",
55            "mms-common",
56            "framework",
57            "android.policy",
58            "services",
59            "apache-xml"};
60
61    private static final String[] DALVIK_HOST_JARS = new String[] {"core-hostdex"};
62    private static final String[] ART_HOST_JARS = new String[] {"core-libart-hostdex"};
63    private static final String[] COMMON_HOST_JARS = new String[] {
64            "conscrypt-hostdex",
65            "okhttp-hostdex",
66            "bouncycastle-hostdex",
67            "apache-xml-hostdex",
68    };
69
70    public boolean acceptsVmArgs() {
71        return this != ACTIVITY;
72    }
73
74    /**
75     * Returns {@code true} if execution happens on the local machine. e.g. host-mode android or a
76     * JVM.
77     */
78    public boolean isLocal() {
79        return isHost() || this == ModeId.JVM;
80    }
81
82    /** Returns {@code true} if execution takes place with a host-mode Android runtime */
83    public boolean isHost() {
84        return this == HOST || this == HOST_DALVIK || this == ModeId.HOST_ART_KITKAT;
85    }
86
87    /** Returns {@code true} if execution takes place with a device-mode Android runtime */
88    public boolean isDevice() {
89        return this == ModeId.DEVICE || this == ModeId.DEVICE_ART_KITKAT
90                || this == ModeId.DEVICE_DALVIK || this == ModeId.APP_PROCESS;
91    }
92
93    public boolean requiresAndroidSdk() {
94        return this != JVM;
95    }
96
97    public boolean supportsVariant(Variant variant) {
98        return (variant == Variant.X32)
99                || ((this == HOST || this == DEVICE) && (variant == Variant.X64));
100    }
101
102    /** The default command to use for the mode unless overridden by --vm-command */
103    public String defaultVmCommand(Variant variant) {
104        if (!supportsVariant(variant)) {
105            throw new AssertionError("Unsupported variant: " + variant + " for " + this);
106        }
107        switch (this) {
108            case DEVICE:
109            case HOST:
110                if (variant == Variant.X32) {
111                    return "dalvikvm32";
112                } else {
113                    return "dalvikvm64";
114                }
115            case DEVICE_DALVIK:
116            case DEVICE_ART_KITKAT:
117            case HOST_DALVIK:
118            case HOST_ART_KITKAT:
119                return "dalvikvm";
120            case JVM:
121                return "java";
122            case APP_PROCESS:
123                return "app_process";
124            case ACTIVITY:
125                return null;
126            default:
127                throw new IllegalArgumentException("Unknown mode: " + this);
128        }
129    }
130
131    /**
132     * Return the names of jars required to compile in this mode when android.jar is not being used.
133     * Also used to generated the classpath in HOST* and DEVICE* modes.
134     */
135    public String[] getJarNames() {
136        List<String> jarNames = new ArrayList<String>();
137        switch (this) {
138            case DEVICE_DALVIK:
139                jarNames.addAll(Arrays.asList(DALVIK_DEVICE_JARS));
140                jarNames.addAll(Arrays.asList(COMMON_DEVICE_JARS));
141                break;
142            case ACTIVITY:
143            case APP_PROCESS:
144            case DEVICE:
145            case DEVICE_ART_KITKAT:
146                jarNames.addAll(Arrays.asList(ART_DEVICE_JARS));
147                jarNames.addAll(Arrays.asList(COMMON_DEVICE_JARS));
148                break;
149            case HOST_DALVIK:
150                jarNames.addAll(Arrays.asList(DALVIK_HOST_JARS));
151                jarNames.addAll(Arrays.asList(COMMON_HOST_JARS));
152                break;
153            case HOST:
154            case HOST_ART_KITKAT:
155                jarNames.addAll(Arrays.asList(ART_HOST_JARS));
156                jarNames.addAll(Arrays.asList(COMMON_HOST_JARS));
157                break;
158            default:
159                throw new IllegalArgumentException("Unsupported mode: " + this);
160        }
161        return jarNames.toArray(new String[jarNames.size()]);
162    }
163}
164