1 /* 2 * Copyright (C) 2011 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 package com.android.tradefed.build; 17 18 import com.android.tradefed.log.LogUtil.CLog; 19 import com.android.tradefed.util.CommandResult; 20 import com.android.tradefed.util.CommandStatus; 21 import com.android.tradefed.util.FileUtil; 22 import com.android.tradefed.util.IRunUtil; 23 import com.android.tradefed.util.RunUtil; 24 25 import java.io.File; 26 import java.io.IOException; 27 28 /** 29 * Implementation of a {@link ISdkBuildInfo} 30 */ 31 public class SdkBuildInfo extends BuildInfo implements ISdkBuildInfo { 32 33 private static final long serialVersionUID = BuildSerializedVersion.VERSION; 34 private File mTestDir = null; 35 private File mSdkDir = null; 36 private boolean mDeleteSdkDirParent; 37 private static final boolean IS_WINDOWS = 38 System.getProperty("os.name") != null 39 && System.getProperty("os.name").startsWith("Windows"); 40 41 private static final int ANDROID_TIMEOUT_MS = 15*1000; 42 43 /** 44 * Creates a {@link SdkBuildInfo} using default attribute values. 45 */ 46 public SdkBuildInfo() { 47 } 48 49 /** 50 * Creates a {@link SdkBuildInfo} 51 * 52 * @param buildId the build id 53 * @param buildName the build name 54 */ 55 public SdkBuildInfo(String buildId, String buildName) { 56 super(buildId, buildName); 57 } 58 59 /** 60 * {@inheritDoc} 61 */ 62 @Override 63 public File getSdkDir() { 64 return mSdkDir; 65 } 66 67 /** 68 * {@inheritDoc} 69 */ 70 @Override 71 public File getTestsDir() { 72 return mTestDir; 73 } 74 75 /** 76 * {@inheritDoc} 77 */ 78 @Override 79 public void setTestsDir(File testDir) { 80 mTestDir = testDir; 81 } 82 83 /** 84 * {@inheritDoc} 85 */ 86 @Override 87 public void setSdkDir(File sdkDir) { 88 setSdkDir(sdkDir, false); 89 } 90 91 /** 92 * {@inheritDoc} 93 */ 94 @Override 95 public void setSdkDir(File sdkDir, boolean deleteParent) { 96 mSdkDir = sdkDir; 97 mDeleteSdkDirParent = deleteParent; 98 } 99 100 @Override 101 public void cleanUp() { 102 if (mSdkDir != null) { 103 if (mDeleteSdkDirParent) { 104 FileUtil.recursiveDelete(mSdkDir.getParentFile()); 105 } else { 106 FileUtil.recursiveDelete(mSdkDir); 107 } 108 } 109 if (mTestDir != null) { 110 FileUtil.recursiveDelete(mTestDir); 111 } 112 mSdkDir = null; 113 mTestDir = null; 114 } 115 116 @Override 117 public IBuildInfo clone() { 118 SdkBuildInfo cloneBuild = new SdkBuildInfo(getBuildId(), getBuildTargetName()); 119 cloneBuild.addAllBuildAttributes(this); 120 try { 121 File cloneTestDir = null; 122 if (getTestsDir() != null) { 123 cloneTestDir = FileUtil.createTempDir("cloneTest"); 124 FileUtil.recursiveCopy(getTestsDir(), cloneTestDir); 125 cloneBuild.setTestsDir(cloneTestDir); 126 } 127 File cloneSdkDir = null; 128 if (getSdkDir() != null) { 129 cloneSdkDir = FileUtil.createTempDir("cloneSdk"); 130 FileUtil.recursiveCopy(getSdkDir(), cloneSdkDir); 131 cloneBuild.setSdkDir(cloneSdkDir); 132 cloneBuild.makeToolsExecutable(); 133 } 134 return cloneBuild; 135 } catch (IOException e) { 136 throw new RuntimeException("Could not clone sdk build", e); 137 } 138 } 139 140 /** 141 * {@inheritDoc} 142 */ 143 @Override 144 public String getAndroidToolPath() { 145 if (getSdkDir() == null) { 146 throw new IllegalStateException("sdk dir is not set"); 147 } 148 return FileUtil.getPath(getSdkDir().getAbsolutePath(), "tools", 149 getAndroidExecutableName()); 150 } 151 152 /** 153 * {@inheritDoc} 154 */ 155 @Override 156 public String[] getSdkTargets() { 157 CommandResult result = getRunUtil().runTimedCmd(ANDROID_TIMEOUT_MS, 158 getAndroidToolPath(), "list", "targets", "--compact"); 159 if (!result.getStatus().equals(CommandStatus.SUCCESS)) { 160 CLog.e(String.format( 161 "Unable to get list of SDK targets using %s. Result %s, err %s", 162 getAndroidToolPath(), result.getStatus(), result.getStderr())); 163 return null; 164 } 165 return result.getStdout().split("\n"); 166 } 167 168 /** 169 * Gets the {@link IRunUtil} instance to use. 170 * <p/> 171 * Exposed for unit testing 172 */ 173 IRunUtil getRunUtil() { 174 return RunUtil.getDefault(); 175 } 176 177 /** 178 * {@inheritDoc} 179 */ 180 @Override 181 public String getEmulatorToolPath() { 182 if (getSdkDir() == null) { 183 throw new IllegalStateException("sdk dir is not set"); 184 } 185 return FileUtil.getPath(getSdkDir().getAbsolutePath(), "tools", 186 getEmulatorExecutableName()); 187 } 188 189 /** 190 * {@inheritDoc} 191 */ 192 @Override 193 public void makeToolsExecutable() { 194 File toolsDir = FileUtil.getFileForPath(getSdkDir(), "tools"); 195 makeExecutable(toolsDir.listFiles()); 196 File platformToolsDir = FileUtil.getFileForPath(getSdkDir(), "platform-tools"); 197 makeExecutable(platformToolsDir.listFiles()); 198 } 199 200 /** 201 * Helper method to make a array of files executable 202 * 203 * @param files the files to make executable 204 */ 205 private void makeExecutable(File[] files) { 206 if (files != null) { 207 for (File file : files) { 208 file.setExecutable(true, true); 209 } 210 } 211 } 212 213 /** 214 * Helper method to return appropriate android executable 215 * filename based on current OS. 216 */ 217 private String getAndroidExecutableName() { 218 if (IS_WINDOWS) { 219 return "android.bat"; 220 } 221 return "android"; 222 } 223 224 /** 225 * Helper method to return appropriate emulator executable 226 * filename based on current OS. 227 */ 228 private String getEmulatorExecutableName() { 229 if (IS_WINDOWS) { 230 return "emulator.exe"; 231 } 232 return "emulator"; 233 } 234 } 235