File: sdkpath.go

package info (click to toggle)
golang-golang-x-mobile 0.0~git20250520.a1d9079%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,784 kB
  • sloc: objc: 1,512; java: 1,489; ansic: 1,159; xml: 365; asm: 34; sh: 14; makefile: 5
file content (89 lines) | stat: -rw-r--r-- 2,798 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package sdkpath provides functions for locating the Android SDK.
// These functions respect the ANDROID_HOME environment variable, and
// otherwise use the default SDK location.
package sdkpath

import (
	"fmt"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
)

// AndroidHome returns the absolute path of the selected Android SDK,
// if one can be found.
func AndroidHome() (string, error) {
	androidHome := os.Getenv("ANDROID_HOME")
	if androidHome == "" {
		home, err := os.UserHomeDir()
		if err != nil {
			return "", err
		}
		switch runtime.GOOS {
		case "windows":
			// See https://android.googlesource.com/platform/tools/adt/idea/+/85b4bfb7a10ad858a30ffa4003085b54f9424087/native/installer/win/setup_android_studio.nsi#100
			androidHome = filepath.Join(home, "AppData", "Local", "Android", "sdk")
		case "darwin":
			// See https://android.googlesource.com/platform/tools/asuite/+/67e0cd9604379e9663df57f16a318d76423c0aa8/aidegen/lib/ide_util.py#88
			androidHome = filepath.Join(home, "Library", "Android", "sdk")
		default: // Linux, BSDs, etc.
			// See LINUX_ANDROID_SDK_PATH in ide_util.py above.
			androidHome = filepath.Join(home, "Android", "Sdk")
		}
	}
	if info, err := os.Stat(androidHome); err != nil {
		return "", fmt.Errorf("%w; Android SDK was not found at %s", err, androidHome)
	} else if !info.IsDir() {
		return "", fmt.Errorf("%s is not a directory", androidHome)
	}
	return androidHome, nil
}

// AndroidAPIPath returns an android SDK platform directory within the configured SDK.
// If there are multiple platforms that satisfy the minimum version requirement,
// AndroidAPIPath returns the latest one among them.
func AndroidAPIPath(api int) (string, error) {
	sdk, err := AndroidHome()
	if err != nil {
		return "", err
	}
	sdkDir, err := os.Open(filepath.Join(sdk, "platforms"))
	if err != nil {
		return "", fmt.Errorf("failed to find android SDK platform: %w", err)
	}
	defer sdkDir.Close()
	fis, err := sdkDir.Readdir(-1)
	if err != nil {
		return "", fmt.Errorf("failed to find android SDK platform (API level: %d): %w", api, err)
	}

	var apiPath string
	var apiVer int
	for _, fi := range fis {
		name := fi.Name()
		if !strings.HasPrefix(name, "android-") {
			continue
		}
		n, err := strconv.Atoi(name[len("android-"):])
		if err != nil || n < api {
			continue
		}
		p := filepath.Join(sdkDir.Name(), name)
		_, err = os.Stat(filepath.Join(p, "android.jar"))
		if err == nil && apiVer < n {
			apiPath = p
			apiVer = n
		}
	}
	if apiVer == 0 {
		return "", fmt.Errorf("failed to find android SDK platform (API level: %d) in %s",
			api, sdkDir.Name())
	}
	return apiPath, nil
}