1 /*
2  * Copyright (C) 2023 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 
17 package com.android.tools.metalava.testing
18 
19 import java.io.File
20 
21 private const val API_LEVEL = 31
22 
getAndroidJarFromEnvnull23 private fun getAndroidJarFromEnv(apiLevel: Int): File {
24     val sdkRoot =
25         System.getenv("ANDROID_SDK_ROOT")
26             ?: System.getenv("ANDROID_HOME") ?: error("Expected ANDROID_SDK_ROOT to be set")
27     val jar = File(sdkRoot, "platforms/android-$apiLevel/android.jar")
28     if (!jar.exists()) {
29         error("Missing ${jar.absolutePath} file in the SDK")
30     }
31     return jar
32 }
33 
34 /**
35  * Check to see if this file is the top level metalava directory by looking for a `metalava-model`
36  * directory.
37  */
isMetalavaRootDirnull38 private fun File.isMetalavaRootDir(): Boolean = resolve("metalava-model").isDirectory
39 
40 /** Get a [File] for the public `android.jar` of the specified [apiLevel]. */
41 fun getAndroidJar(apiLevel: Int = API_LEVEL): File {
42     val metalavaDir = getMetalavaDir()
43 
44     val localFile = metalavaDir.resolve("../../prebuilts/sdk/$apiLevel/public/android.jar")
45     if (localFile.exists()) {
46         return localFile
47     } else {
48         val androidJar = File("../../prebuilts/sdk/$apiLevel/android.jar")
49         if (androidJar.exists()) return androidJar
50         return getAndroidJarFromEnv(apiLevel)
51     }
52 }
53 
54 /** Get a [File] for the [apiSurface] `android.txt` of the specified [apiLevel]. */
getAndroidTxtnull55 fun getAndroidTxt(apiLevel: Int = API_LEVEL, apiSurface: String = "public"): File {
56     val metalavaDir = getMetalavaDir()
57 
58     val localFile = metalavaDir.resolve("../../prebuilts/sdk/$apiLevel/$apiSurface/api/android.txt")
59     if (!localFile.exists()) {
60         error("Missing ${localFile.absolutePath} file in the SDK")
61     }
62 
63     return localFile
64 }
65 
getMetalavaDirnull66 private fun getMetalavaDir(): File {
67     // This is either running in tools/metalava or tools/metalava/subproject-dir and we need to look
68     // in prebuilts/sdk, so first find tools/metalava then resolve relative to that.
69     val cwd = File("").absoluteFile
70     val metalavaDir =
71         if (cwd.isMetalavaRootDir()) cwd
72         else {
73             val parent = cwd.parentFile
74             if (parent.isMetalavaRootDir()) parent
75             else {
76                 throw IllegalArgumentException("Could not find metalava-model in $cwd")
77             }
78         }
79     return metalavaDir
80 }
81