diff --git a/plugins/lint/lint-api/lint-api.iml b/plugins/lint/lint-api/lint-api.iml index 9158eb89551..6ce6a410525 100644 --- a/plugins/lint/lint-api/lint-api.iml +++ b/plugins/lint/lint-api/lint-api.iml @@ -14,5 +14,6 @@ + \ No newline at end of file diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintClient.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintClient.java index 75eeee87656..3b9fc9df8e8 100755 --- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintClient.java +++ b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintClient.java @@ -685,7 +685,7 @@ public abstract class LintClient { @NonNull public IAndroidTarget[] getTargets() { if (mTargets == null) { - LocalSdk localSdk = getSdk(); + SdkWrapper localSdk = getSdk(); if (localSdk != null) { mTargets = localSdk.getTargets(); } else { @@ -696,7 +696,7 @@ public abstract class LintClient { return mTargets; } - protected LocalSdk mSdk; + protected SdkWrapper mSdk; /** * Returns the SDK installation (used to look up platforms etc) @@ -704,11 +704,11 @@ public abstract class LintClient { * @return the SDK if known */ @Nullable - public LocalSdk getSdk() { + public SdkWrapper getSdk() { if (mSdk == null) { File sdkHome = getSdkHome(); if (sdkHome != null) { - mSdk = new LocalSdk(sdkHome); + mSdk = SdkWrapper.createLocalSdk(sdkHome); } } diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java index 0e3adb523e5..142ceb76544 100644 --- a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java +++ b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/LintDriver.java @@ -1927,7 +1927,7 @@ public class LintDriver { @Nullable @Override - public LocalSdk getSdk() { + public SdkWrapper getSdk() { return mDelegate.getSdk(); } diff --git a/plugins/lint/lint-api/src/com/android/tools/klint/client/api/SdkWrapper.kt b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/SdkWrapper.kt new file mode 100644 index 00000000000..b21d46fbe11 --- /dev/null +++ b/plugins/lint/lint-api/src/com/android/tools/klint/client/api/SdkWrapper.kt @@ -0,0 +1,104 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * 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 com.android.tools.klint.client.api + +import com.android.sdklib.IAndroidTarget +import java.io.File + +class SdkWrapper(val sdk: Any) { + + companion object { + val PROGRESS_INDICATOR_CLASS_NAME = "com.android.repository.api.ConsoleProgressIndicator" + + @JvmStatic + fun createLocalSdk(file: File): SdkWrapper? { + try { + val clazz = Class.forName("com.android.sdklib.repository.local.LocalSdk") + return SdkWrapper(clazz.getConstructor(File::class.java).newInstance(file)) + } + catch (t: Throwable) { + try { + val clazz = Class.forName("com.android.sdklib.repositoryv2.AndroidSdkHandler") + return SdkWrapper(clazz.getMethod("getInstance", File::class.java).invoke(null, file)) + } + catch (t2: Throwable) { + return null + } + } + } + } + + fun getTargets(): Array? { + try { + @Suppress("UNCHECKED_CAST") + return sdk.javaClass.getMethod("getTargets").invoke(sdk) as? Array + } catch (t: Throwable) { + @Suppress("UNCHECKED_CAST") + try { + val targets = sdk.javaClass + .getMethod("getAndroidTargetManager", Class.forName(PROGRESS_INDICATOR_CLASS_NAME)) + .invoke(sdk, createProgressIndicator()) as? Collection ?: return null + return targets.toTypedArray() + } + catch (t2: Throwable) { + return null + } + } + } + + fun getPlatformVersion(): String? { + try { + val pkgPlatformTools = Class.forName("com.android.sdklib.repository.descriptors.PkgType") + .getField("PKG_PLATFORM_TOOLS").get(null) + val pkgInfo = sdk.javaClass.declaredMethods + .first { it.name == "getPkgInfo" && it.parameterTypes.size == 1 } + .invoke(sdk, pkgPlatformTools) + if (pkgInfo != null) { + val desc = pkgInfo.javaClass.getMethod("getDesc").invoke(pkgInfo) + val version = desc.javaClass.getMethod("getFullRevision").invoke(desc) + if (version != null) { + return version.javaClass.getMethod("toShortString").invoke(version) as? String + } + } + else { + return null + } + } catch (t: Throwable) { + try { + val pkgPlatformTools = Class.forName("com.android.SdkConstants") + .getField("FD_PLATFORM_TOOLS").get(null) + val pkgInfo = sdk.javaClass.declaredMethods + .first { it.name == "getLocalPackage" && it.parameterTypes.size == 2 } + .invoke(sdk, pkgPlatformTools, createProgressIndicator()) + if (pkgInfo != null) { + val version = pkgInfo.javaClass.getMethod("getVersion").invoke(pkgInfo) + return version.javaClass.getMethod("toShortString").invoke(version) as? String + } + else { + return null + } + } + catch (ignore: Throwable) {} + } + + return null + } + + private fun createProgressIndicator(): Any { + return Class.forName(PROGRESS_INDICATOR_CLASS_NAME).newInstance() + } +} \ No newline at end of file diff --git a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiLookup.java b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiLookup.java index b7341afbaad..5de0963b948 100644 --- a/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiLookup.java +++ b/plugins/lint/lint-checks/src/com/android/tools/klint/checks/ApiLookup.java @@ -22,11 +22,8 @@ import static com.android.SdkConstants.DOT_XML; import com.android.annotations.NonNull; import com.android.annotations.Nullable; import com.android.annotations.VisibleForTesting; -import com.android.sdklib.repository.FullRevision; -import com.android.sdklib.repository.descriptors.PkgType; -import com.android.sdklib.repository.local.LocalPkgInfo; -import com.android.sdklib.repository.local.LocalSdk; import com.android.tools.klint.client.api.LintClient; +import com.android.tools.klint.client.api.SdkWrapper; import com.android.tools.klint.detector.api.LintUtils; import com.google.common.base.Charsets; import com.google.common.collect.Lists; @@ -138,15 +135,9 @@ public class ApiLookup { @VisibleForTesting @Nullable static String getPlatformVersion(@NonNull LintClient client) { - LocalSdk sdk = client.getSdk(); + SdkWrapper sdk = client.getSdk(); if (sdk != null) { - LocalPkgInfo pkgInfo = sdk.getPkgInfo(PkgType.PKG_PLATFORM_TOOLS); - if (pkgInfo != null) { - FullRevision version = pkgInfo.getDesc().getFullRevision(); - if (version != null) { - return version.toShortString(); - } - } + return sdk.getPlatformVersion(); } return null; diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidModelFacade.kt b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidModelFacade.kt index cfa1fc8f015..0ce449157a0 100644 --- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidModelFacade.kt +++ b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/AndroidModelFacade.kt @@ -4,6 +4,7 @@ import com.android.builder.model.AndroidProject import com.android.builder.model.SourceProvider import com.android.builder.model.Variant import com.android.tools.idea.gradle.util.GradleUtil +import com.android.tools.klint.client.api.SdkWrapper import org.jetbrains.android.facet.AndroidFacet import kotlin.reflect.memberFunctions import kotlin.reflect.staticFunctions @@ -19,6 +20,14 @@ class AndroidModelFacade(val facet: AndroidFacet) { } } + fun getLocalSdk(): SdkWrapper? { + val sdkData = facet.sdkData ?: return null + val localSdk = sdkData.javaClass.kotlin.memberFunctions + .firstOrNull { it.name == "getLocalSdk" || it.name == "getSdkHandler" } + ?.call(sdkData) ?: return null + return SdkWrapper(localSdk) + } + fun isModelReady() = model != null @Suppress("UNCHECKED_CAST") diff --git a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintClient.java b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintClient.java index e27d8260e5a..102010772fb 100644 --- a/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintClient.java +++ b/plugins/lint/lint-idea/src/org/jetbrains/android/inspections/klint/IntellijLintClient.java @@ -7,8 +7,6 @@ import com.android.ide.common.repository.ResourceVisibilityLookup; import com.android.ide.common.res2.AbstractResourceRepository; import com.android.ide.common.res2.ResourceFile; import com.android.ide.common.res2.ResourceItem; -import com.android.sdklib.repository.local.LocalSdk; -import com.android.tools.idea.gradle.util.Projects; import com.android.tools.idea.rendering.AppResourceRepository; import com.android.tools.idea.rendering.LocalResourceRepository; import com.android.tools.idea.sdk.IdeSdks; @@ -50,7 +48,6 @@ import com.intellij.util.containers.HashMap; import com.intellij.util.net.HttpConfigurable; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.facet.AndroidRootUtil; -import org.jetbrains.android.sdk.AndroidSdkData; import org.jetbrains.android.sdk.AndroidSdkType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -329,10 +326,10 @@ public class IntellijLintClient extends LintClient implements Disposable { @Nullable @Override - public LocalSdk getSdk() { + public SdkWrapper getSdk() { if (mSdk == null) { Module module = getModule(); - LocalSdk sdk = getLocalSdk(module); + SdkWrapper sdk = getLocalSdk(module); if (sdk != null) { mSdk = sdk; } else { @@ -354,14 +351,11 @@ public class IntellijLintClient extends LintClient implements Disposable { } @Nullable - private static LocalSdk getLocalSdk(@Nullable Module module) { + private static SdkWrapper getLocalSdk(@Nullable Module module) { if (module != null) { AndroidFacet facet = AndroidFacet.getInstance(module); if (facet != null) { - AndroidSdkData sdkData = facet.getSdkData(); - if (sdkData != null) { - return sdkData.getLocalSdk(); - } + return IntellijLintUtils.getModelFacade(facet).getLocalSdk(); } }