blob: 5a2fe7f6f06bf284dc22f40654f34103abad664a [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* 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.builder.sdk;
import static com.android.SdkConstants.FD_EXTRAS;
import static com.android.SdkConstants.FD_M2_REPOSITORY;
import static com.android.SdkConstants.FD_PLATFORM_TOOLS;
import static com.android.SdkConstants.FD_SUPPORT;
import static com.android.SdkConstants.FD_TOOLS;
import static com.android.SdkConstants.FN_ADB;
import static com.android.SdkConstants.FN_ANNOTATIONS_JAR;
import static com.android.SdkConstants.FN_SOURCE_PROP;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkManager;
import com.android.sdklib.repository.FullRevision;
import com.android.sdklib.repository.PkgProps;
import com.android.utils.ILogger;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.io.Closeables;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.List;
import java.util.Properties;
/**
* Singleton-based implementation of SdkLoader for a standard SDK
*/
public class DefaultSdkLoader implements SdkLoader {
private static DefaultSdkLoader sLoader;
@NonNull
private final File mSdkLocation;
private SdkManager mSdkManager;
private SdkInfo mSdkInfo;
private final ImmutableList<File> mRepositories;
public static synchronized SdkLoader getLoader(
@NonNull File sdkLocation) {
if (sLoader == null) {
sLoader = new DefaultSdkLoader(sdkLocation);
} else if (!sdkLocation.equals(sLoader.mSdkLocation)) {
throw new IllegalStateException("Already created an SDK Loader with different SDK Path");
}
return sLoader;
}
public static synchronized void unload() {
sLoader = null;
}
@Override
@NonNull
public TargetInfo getTargetInfo(
@NonNull String targetHash,
@NonNull FullRevision buildToolRevision,
@NonNull ILogger logger) {
init(logger);
IAndroidTarget target = mSdkManager.getTargetFromHashString(targetHash);
if (target == null) {
throw new IllegalStateException("failed to find target with hash string '" + targetHash + "' in: " + mSdkLocation);
}
BuildToolInfo buildToolInfo = mSdkManager.getBuildTool(buildToolRevision);
if (buildToolInfo == null) {
throw new IllegalStateException("failed to find Build Tools revision "
+ buildToolRevision.toString());
}
return new TargetInfo(target, buildToolInfo);
}
@Override
@NonNull
public SdkInfo getSdkInfo(@NonNull ILogger logger) {
init(logger);
return mSdkInfo;
}
@Override
@NonNull
public ImmutableList<File> getRepositories() {
return mRepositories;
}
private DefaultSdkLoader(@NonNull File sdkLocation) {
mSdkLocation = sdkLocation;
mRepositories = computeRepositories();
}
private synchronized void init(@NonNull ILogger logger) {
if (mSdkManager == null) {
mSdkManager = SdkManager.createManager(mSdkLocation.getPath(), logger);
if (mSdkManager == null) {
throw new IllegalStateException("failed to parse SDK! Check console for details");
}
File toolsFolder = new File(mSdkLocation, FD_TOOLS);
File supportToolsFolder = new File(toolsFolder, FD_SUPPORT);
File platformTools = new File(mSdkLocation, FD_PLATFORM_TOOLS);
mSdkInfo = new SdkInfo(
new File(supportToolsFolder, FN_ANNOTATIONS_JAR),
new File(platformTools, FN_ADB));
}
}
@Nullable
private FullRevision getPlatformToolsRevision(@NonNull File platformToolsFolder) {
if (!platformToolsFolder.isDirectory()) {
return null;
}
Reader reader = null;
try {
reader = new InputStreamReader(
new FileInputStream(new File(platformToolsFolder, FN_SOURCE_PROP)),
Charsets.UTF_8);
Properties props = new Properties();
props.load(reader);
String value = props.getProperty(PkgProps.PKG_REVISION);
return FullRevision.parseRevision(value);
} catch (FileNotFoundException ignore) {
// return null below.
} catch (IOException ignore) {
// return null below.
} catch (NumberFormatException ignore) {
// return null below.
} finally {
try {
Closeables.close(reader, true /* swallowIOException */);
} catch (IOException e) {
// cannot happen
}
}
return null;
}
@NonNull
public ImmutableList<File> computeRepositories() {
List<File> repositories = Lists.newArrayListWithExpectedSize(2);
File androidRepo = new File(mSdkLocation, FD_EXTRAS + File.separator + "android"
+ File.separator + FD_M2_REPOSITORY);
if (androidRepo.isDirectory()) {
repositories.add(androidRepo);
}
File googleRepo = new File(mSdkLocation, FD_EXTRAS + File.separator + "google"
+ File.separator + FD_M2_REPOSITORY);
if (googleRepo.isDirectory()) {
repositories.add(googleRepo);
}
return ImmutableList.copyOf(repositories);
}
}