Split out sdk.go from java.go

Split out SDK handling functions from java.go to sdk.go and tests
from java_test.go to sdk.go.

Test: sdk_test.go
Change-Id: I83ef48cbe5230572c1d4ecc0e89021d2f7c71b76
diff --git a/java/sdk.go b/java/sdk.go
new file mode 100644
index 0000000..cd128d1
--- /dev/null
+++ b/java/sdk.go
@@ -0,0 +1,172 @@
+// Copyright 2019 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+	"android/soong/android"
+	"android/soong/java/config"
+	"fmt"
+	"path/filepath"
+	"strconv"
+	"strings"
+)
+
+type sdkContext interface {
+	// sdkVersion eturns the sdk_version property of the current module, or an empty string if it is not set.
+	sdkVersion() string
+	// minSdkVersion returns the min_sdk_version property of the current module, or sdkVersion() if it is not set.
+	minSdkVersion() string
+	// targetSdkVersion returns the target_sdk_version property of the current module, or sdkVersion() if it is not set.
+	targetSdkVersion() string
+}
+
+func sdkVersionOrDefault(ctx android.BaseContext, v string) string {
+	switch v {
+	case "", "current", "system_current", "test_current", "core_current":
+		return ctx.Config().DefaultAppTargetSdk()
+	default:
+		return v
+	}
+}
+
+// Returns a sdk version as a number.  For modules targeting an unreleased SDK (meaning it does not yet have a number)
+// it returns android.FutureApiLevel (10000).
+func sdkVersionToNumber(ctx android.BaseContext, v string) (int, error) {
+	switch v {
+	case "", "current", "test_current", "system_current", "core_current":
+		return ctx.Config().DefaultAppTargetSdkInt(), nil
+	default:
+		n := android.GetNumericSdkVersion(v)
+		if i, err := strconv.Atoi(n); err != nil {
+			return -1, fmt.Errorf("invalid sdk version %q", n)
+		} else {
+			return i, nil
+		}
+	}
+}
+
+func sdkVersionToNumberAsString(ctx android.BaseContext, v string) (string, error) {
+	n, err := sdkVersionToNumber(ctx, v)
+	if err != nil {
+		return "", err
+	}
+	return strconv.Itoa(n), nil
+}
+
+func decodeSdkDep(ctx android.BaseContext, sdkContext sdkContext) sdkDep {
+	v := sdkContext.sdkVersion()
+	i, err := sdkVersionToNumber(ctx, v)
+	if err != nil {
+		ctx.PropertyErrorf("sdk_version", "%s", err)
+		return sdkDep{}
+	}
+
+	// Ensures that the specificed system SDK version is one of BOARD_SYSTEMSDK_VERSIONS (for vendor apks)
+	// or PRODUCT_SYSTEMSDK_VERSIONS (for other apks or when BOARD_SYSTEMSDK_VERSIONS is not set)
+	if strings.HasPrefix(v, "system_") && i != android.FutureApiLevel {
+		allowed_versions := ctx.DeviceConfig().PlatformSystemSdkVersions()
+		if ctx.DeviceSpecific() || ctx.SocSpecific() {
+			if len(ctx.DeviceConfig().SystemSdkVersions()) > 0 {
+				allowed_versions = ctx.DeviceConfig().SystemSdkVersions()
+			}
+		}
+		version := strings.TrimPrefix(v, "system_")
+		if len(allowed_versions) > 0 && !android.InList(version, allowed_versions) {
+			ctx.PropertyErrorf("sdk_version", "incompatible sdk version %q. System SDK version should be one of %q",
+				v, allowed_versions)
+		}
+	}
+
+	toPrebuilt := func(sdk string) sdkDep {
+		var api, v string
+		if strings.Contains(sdk, "_") {
+			t := strings.Split(sdk, "_")
+			api = t[0]
+			v = t[1]
+		} else {
+			api = "public"
+			v = sdk
+		}
+		dir := filepath.Join("prebuilts", "sdk", v, api)
+		jar := filepath.Join(dir, "android.jar")
+		// There's no aidl for other SDKs yet.
+		// TODO(77525052): Add aidl files for other SDKs too.
+		public_dir := filepath.Join("prebuilts", "sdk", v, "public")
+		aidl := filepath.Join(public_dir, "framework.aidl")
+		jarPath := android.ExistentPathForSource(ctx, jar)
+		aidlPath := android.ExistentPathForSource(ctx, aidl)
+		lambdaStubsPath := android.PathForSource(ctx, config.SdkLambdaStubsPath)
+
+		if (!jarPath.Valid() || !aidlPath.Valid()) && ctx.Config().AllowMissingDependencies() {
+			return sdkDep{
+				invalidVersion: true,
+				modules:        []string{fmt.Sprintf("sdk_%s_%s_android", api, v)},
+			}
+		}
+
+		if !jarPath.Valid() {
+			ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", v, jar)
+			return sdkDep{}
+		}
+
+		if !aidlPath.Valid() {
+			ctx.PropertyErrorf("sdk_version", "invalid sdk version %q, %q does not exist", v, aidl)
+			return sdkDep{}
+		}
+
+		return sdkDep{
+			useFiles: true,
+			jars:     android.Paths{jarPath.Path(), lambdaStubsPath},
+			aidl:     aidlPath.Path(),
+		}
+	}
+
+	toModule := func(m, r string) sdkDep {
+		ret := sdkDep{
+			useModule:          true,
+			modules:            []string{m, config.DefaultLambdaStubsLibrary},
+			systemModules:      m + "_system_modules",
+			frameworkResModule: r,
+		}
+		if m == "core.current.stubs" {
+			ret.systemModules = "core-system-modules"
+		} else if m == "core.platform.api.stubs" {
+			ret.systemModules = "core-platform-api-stubs-system-modules"
+		}
+		return ret
+	}
+
+	if ctx.Config().UnbundledBuildPrebuiltSdks() && v != "" {
+		return toPrebuilt(v)
+	}
+
+	switch v {
+	case "":
+		return sdkDep{
+			useDefaultLibs:     true,
+			frameworkResModule: "framework-res",
+		}
+	case "current":
+		return toModule("android_stubs_current", "framework-res")
+	case "system_current":
+		return toModule("android_system_stubs_current", "framework-res")
+	case "test_current":
+		return toModule("android_test_stubs_current", "framework-res")
+	case "core_current":
+		return toModule("core.current.stubs", "")
+	default:
+		return toPrebuilt(v)
+	}
+}