diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-06-18 12:01:58 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-06-18 12:01:58 -0700 |
commit | 6a43cc460c94ad3892a32e458dd38d248d334d78 (patch) | |
tree | 904c79ce616f529620236946f91f496556859b0b /sdkmanager | |
parent | c81bcfd5e1feadc772ebb465fdee66f0fd8033d3 (diff) | |
parent | 6c8ec1d6479f51e269138633aedceb0bed9d2340 (diff) | |
download | sdk-6a43cc460c94ad3892a32e458dd38d248d334d78.zip sdk-6a43cc460c94ad3892a32e458dd38d248d334d78.tar.gz sdk-6a43cc460c94ad3892a32e458dd38d248d334d78.tar.bz2 |
Merge change 4575 into donut
* changes:
SDK Updater: Better guess for the addon folder name.
Diffstat (limited to 'sdkmanager')
9 files changed, 149 insertions, 77 deletions
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java index 6d39098..c9372de 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java @@ -182,25 +182,46 @@ public class AddonPackage extends Package { * has this add-ons installed, we'll use that one.
*
* @param osSdkRoot The OS path of the SDK root folder.
+ * @param suggestedDir A suggestion for the installation folder name, based on the root
+ * folder used in the zip archive.
+ * @param sdkManager An existing SDK manager to list current platforms and addons.
* @return A new {@link File} corresponding to the directory to use to install this package.
*/
@Override
- public File getInstallFolder(String osSdkRoot) {
+ public File getInstallFolder(String osSdkRoot, String suggestedDir, SdkManager sdkManager) {
File addons = new File(osSdkRoot, SdkConstants.FD_ADDONS);
- String name = String.format("%s-%d", getName(), getApiLevel()); // $NON-NLS-1$
+ // First find if this add-on is already installed. If so, reuse the same directory.
+ for (IAndroidTarget target : sdkManager.getTargets()) {
+ if (!target.isPlatform() &&
+ target.getApiVersionNumber() == getApiLevel() &&
+ target.getName().equals(getName()) &&
+ target.getVendor().equals(getVendor())) {
+ return new File(target.getLocation());
+ }
+ }
+
+ // Otherwise, see about reusing the suggestedDir. It must not be already used or
+ // add some index to it, or we try to make up one.
+ String name = suggestedDir;
- // FIXME this will fail if the name is not ASCII compatible. This could easily
- // happen: a Chinese or Japanese name etc for example,
- // to name a few.
- name = name.toLowerCase();
- name = name.replaceAll("[^a-zA-Z0-9_-]+", "_"); // $NON-NLS-1$
- name = name.replaceAll("_+", "_"); // $NON-NLS-1$
+ if (suggestedDir == null || suggestedDir.length() == 0) {
+ name = String.format("addon-%s-%s-%d", getName(), getVendor(), getApiLevel()); //$NON-NLS-1$
+ name = name.toLowerCase();
+ name = name.replaceAll("[^a-z0-9_-]+", "_"); //$NON-NLS-1$ //$NON-NLS-2$
+ name = name.replaceAll("_+", "_"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
- File folder = new File(addons, name);
+ for (int i = 0; i < 100; i++) {
+ String name2 = i == 0 ? name : String.format("%s-%d", name, i); //$NON-NLS-1$
+ File folder = new File(addons, name2);
+ if (!folder.exists()) {
+ return folder;
+ }
+ }
- // TODO find similar existing addon in addons folder
- return folder;
+ // We shouldn't really get here. I mean, seriously, we tried hard enough.
+ return null;
}
/**
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java index 08a536b..826d629 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java @@ -16,6 +16,8 @@ package com.android.sdklib.internal.repository;
+import com.android.sdklib.SdkManager;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -341,7 +343,10 @@ public class Archive implements IDescription { *
* @return True if the archive was installed, false otherwise.
*/
- public boolean install(String osSdkRoot, boolean forceHttp, ITaskMonitor monitor) {
+ public boolean install(String osSdkRoot,
+ boolean forceHttp,
+ SdkManager sdkManager,
+ ITaskMonitor monitor) {
File archiveFile = null;
try {
@@ -364,7 +369,7 @@ public class Archive implements IDescription { archiveFile = downloadFile(monitor, forceHttp);
if (archiveFile != null) {
- if (unarchive(osSdkRoot, archiveFile, monitor)) {
+ if (unarchive(osSdkRoot, archiveFile, sdkManager, monitor)) {
monitor.setResult("Installed: %1$s", name);
return true;
}
@@ -568,48 +573,63 @@ public class Archive implements IDescription { /**
* Install the given archive in the given folder.
*/
- private boolean unarchive(String osSdkRoot, File archiveFile, ITaskMonitor monitor) {
- String name = getParentPackage().getShortDescription();
- String desc = String.format("Installing %1$s", name);
- monitor.setDescription(desc);
+ private boolean unarchive(String osSdkRoot,
+ File archiveFile,
+ SdkManager sdkManager,
+ ITaskMonitor monitor) {
+ String pkgName = getParentPackage().getShortDescription();
+ String pkgDesc = String.format("Installing %1$s", pkgName);
+ monitor.setDescription(pkgDesc);
+
+ // We always unzip in a temp folder which name depends on the package type
+ // (e.g. addon, tools, etc.) and then move the folder to the destination folder.
+ // If the destination folder exists, it will be renamed and deleted at the very
+ // end if everything succeeded.
- File destFolder = getParentPackage().getInstallFolder(osSdkRoot);
+ String pkgKind = getParentPackage().getClass().getSimpleName();
- File unzipDestFolder = destFolder;
+ File destFolder = null;
+ File unzipDestFolder = null;
File renamedDestFolder = null;
try {
- // If this folder already exists, unzip in a temporary folder and then move/unlink.
- if (destFolder.exists()) {
- // Find a new temp folder that doesn't exist yet
- unzipDestFolder = findTempFolder(destFolder, "new"); //$NON-NLS-1$
+ // Find a new temp folder that doesn't exist yet
+ unzipDestFolder = findTempFolder(osSdkRoot, pkgKind, "new"); //$NON-NLS-1$
- if (unzipDestFolder == null) {
- // this should not seriously happen.
- monitor.setResult("Failed to find a suitable temp directory similar to %1$s.",
- destFolder.getPath());
- return false;
- }
+ if (unzipDestFolder == null) {
+ // this should not seriously happen.
+ monitor.setResult("Failed to find a temp directory in %1$s.", osSdkRoot);
+ return false;
}
if (!unzipDestFolder.mkdirs()) {
- monitor.setResult("Failed to create directory %1$s",
- unzipDestFolder.getPath());
+ monitor.setResult("Failed to create directory %1$s", unzipDestFolder.getPath());
+ return false;
+ }
+
+ String[] zipRootFolder = new String[] { null };
+ if (!unzipFolder(archiveFile, getSize(),
+ unzipDestFolder, pkgDesc,
+ zipRootFolder, monitor)) {
return false;
}
- if (!unzipFolder(archiveFile, getSize(), unzipDestFolder, desc, monitor)) {
+ // Compute destination directory
+ destFolder = getParentPackage().getInstallFolder(
+ osSdkRoot, zipRootFolder[0], sdkManager);
+
+ if (destFolder == null) {
+ // this should not seriously happen.
+ monitor.setResult("Failed to compute installation directory for %1$s.", pkgName);
return false;
}
- if (unzipDestFolder != destFolder) {
- // Swap the old folder by the new one.
- // Both original folders will be deleted in the finally clause below.
- renamedDestFolder = findTempFolder(destFolder, "old"); //$NON-NLS-1$
+ // Swap the old folder by the new one.
+ if (destFolder.isDirectory()) {
+ renamedDestFolder = findTempFolder(osSdkRoot, pkgKind, "old"); //$NON-NLS-1$
if (renamedDestFolder == null) {
// this should not seriously happen.
- monitor.setResult("Failed to find a suitable temp directory similar to %1$s.",
- destFolder.getPath());
+ monitor.setResult("Failed to find a temp directory in %1$s.", osSdkRoot);
return false;
}
@@ -619,28 +639,36 @@ public class Archive implements IDescription { return false;
}
- if (!unzipDestFolder.renameTo(destFolder)) {
- monitor.setResult("Failed to rename directory %1$s to %2$s",
- unzipDestFolder.getPath(), destFolder.getPath());
- return false;
- }
}
+ if (!unzipDestFolder.renameTo(destFolder)) {
+ monitor.setResult("Failed to rename directory %1$s to %2$s",
+ unzipDestFolder.getPath(), destFolder.getPath());
+ return false;
+ }
+
+ unzipDestFolder = null;
return true;
} finally {
// Cleanup if the unzip folder is still set.
deleteFileOrFolder(renamedDestFolder);
- if (unzipDestFolder != destFolder) {
- deleteFileOrFolder(unzipDestFolder);
- }
+ deleteFileOrFolder(unzipDestFolder);
}
}
+ /**
+ * Unzips a zip file into the given destination directory.
+ *
+ * The archive file MUST have a unique "root" folder. This root folder is skipped when
+ * unarchiving. However we return that root folder name to the caller, as it can be used
+ * as a template to know what destination directory to use in the Add-on case.
+ */
private boolean unzipFolder(File archiveFile,
long compressedSize,
File unzipDestFolder,
String description,
+ String[] outZipRootFolder,
ITaskMonitor monitor) {
description += " (%1$d%%)";
@@ -678,6 +706,9 @@ public class Archive implements IDescription { if (pos < 0 || pos == name.length() - 1) {
continue;
} else {
+ if (outZipRootFolder[0] == null && pos > 0) {
+ outZipRootFolder[0] = name.substring(0, pos);
+ }
name = name.substring(pos + 1);
}
@@ -762,21 +793,27 @@ public class Archive implements IDescription { }
/**
- * Finds a temp folder which name is similar to the one of the ideal folder
- * and with a ".tmpN" appended.
+ * Finds a temp folder in the form of osBasePath/temp/prefix.suffixNNN.
* <p/>
* This operation is not atomic so there's no guarantee the folder can't get
* created in between. This is however unlikely and the caller can assume the
* returned folder does not exist yet.
* <p/>
- * Returns null if no such folder can be found (e.g. if all candidates exist),
- * which is rather unlikely.
+ * Returns null if no such folder can be found (e.g. if all candidates exist,
+ * which is rather unlikely) or if the base temp folder cannot be created.
*/
- private File findTempFolder(File idealFolder, String suffix) {
- String basePath = idealFolder.getPath();
+ private File findTempFolder(String osBasePath, String prefix, String suffix) {
+ File baseTempFolder = new File(osBasePath, "temp");
+
+ if (!baseTempFolder.isDirectory()) {
+ if (!baseTempFolder.mkdirs()) {
+ return null;
+ }
+ }
for (int i = 1; i < 100; i++) {
- File folder = new File(String.format("%1$s.%2$s%3$02d", basePath, suffix, i)); //$NON-NLS-1$
+ File folder = new File(baseTempFolder,
+ String.format("%1$s.%2$s%3$02d", prefix, suffix, i)); //$NON-NLS-1$
if (!folder.exists()) {
return folder;
}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DocPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DocPackage.java index 66e3255..0e94717 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DocPackage.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DocPackage.java @@ -17,6 +17,7 @@ package com.android.sdklib.internal.repository;
import com.android.sdklib.SdkConstants;
+import com.android.sdklib.SdkManager;
import com.android.sdklib.internal.repository.Archive.Arch;
import com.android.sdklib.internal.repository.Archive.Os;
import com.android.sdklib.repository.SdkRepository;
@@ -98,10 +99,13 @@ public class DocPackage extends Package { * A "doc" package should always be located in SDK/docs.
*
* @param osSdkRoot The OS path of the SDK root folder.
+ * @param suggestedDir A suggestion for the installation folder name, based on the root
+ * folder used in the zip archive.
+ * @param sdkManager An existing SDK manager to list current platforms and addons.
* @return A new {@link File} corresponding to the directory to use to install this package.
*/
@Override
- public File getInstallFolder(String osSdkRoot) {
+ public File getInstallFolder(String osSdkRoot, String suggestedDir, SdkManager sdkManager) {
return new File(osSdkRoot, SdkConstants.FD_DOCS);
}
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java index 4ff8fb8..10f297e 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java @@ -17,7 +17,6 @@ package com.android.sdklib.internal.repository;
import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.ISdkLog;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.SdkManager;
import com.android.sdklib.internal.repository.Archive.Arch;
@@ -63,7 +62,7 @@ public class LocalSdkParser { }
/**
- * Returns the packages found by the last call to {@link #parseSdk(String)}.
+ * Returns the packages found by the last call to {@link #parseSdk(String, SdkManager)}.
*/
public Package[] getPackages() {
return mPackages;
@@ -71,7 +70,7 @@ public class LocalSdkParser { /**
* Clear the internal packages list. After this call, {@link #getPackages()} will return
- * null till {@link #parseSdk(String)} is called.
+ * null till {@link #parseSdk(String, SdkManager)} is called.
*/
public void clearPackages() {
mPackages = null;
@@ -84,9 +83,10 @@ public class LocalSdkParser { * at any time later.
*
* @param osSdkRoot The path to the SDK folder.
+ * @param sdkManager An existing SDK manager to list current platforms and addons.
* @return The packages found. Can be retrieved later using {@link #getPackages()}.
*/
- public Package[] parseSdk(String osSdkRoot) {
+ public Package[] parseSdk(String osSdkRoot, SdkManager sdkManager) {
ArrayList<Package> packages = new ArrayList<Package>();
Package pkg = scanDoc(new File(osSdkRoot, SdkConstants.FD_DOCS));
@@ -100,20 +100,7 @@ public class LocalSdkParser { }
// for platforms and add-ons, rely on the SdkManager parser
- SdkManager sdkman = SdkManager.createManager(osSdkRoot, new ISdkLog() {
- // A dummy sdk logger that doesn't log anything.
- public void error(Throwable t, String errorFormat, Object... args) {
- // pass
- }
- public void printf(String msgFormat, Object... args) {
- // pass
- }
- public void warning(String warningFormat, Object... args) {
- // pass
- }
- });
-
- for(IAndroidTarget target : sdkman.getTargets()) {
+ for(IAndroidTarget target : sdkManager.getTargets()) {
pkg = null;
if (target.isPlatform()) {
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java index cdac3c1..bd6ccc0 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java @@ -16,6 +16,7 @@ package com.android.sdklib.internal.repository;
+import com.android.sdklib.SdkManager;
import com.android.sdklib.internal.repository.Archive.Arch;
import com.android.sdklib.internal.repository.Archive.Os;
import com.android.sdklib.repository.SdkRepository;
@@ -198,9 +199,13 @@ public abstract class Package implements IDescription { * existing or new folder depending on the current content of the SDK.
*
* @param osSdkRoot The OS path of the SDK root folder.
+ * @param suggestedDir A suggestion for the installation folder name, based on the root
+ * folder used in the zip archive.
+ * @param sdkManager An existing SDK manager to list current platforms and addons.
* @return A new {@link File} corresponding to the directory to use to install this package.
*/
- public abstract File getInstallFolder(String osSdkRoot);
+ public abstract File getInstallFolder(
+ String osSdkRoot, String suggestedDir, SdkManager sdkManager);
/**
* Computes whether the given package is a suitable update for the current package.
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java index b4b8cf3..66dd529 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java @@ -102,10 +102,23 @@ public class PlatformPackage extends Package { * has this platform version installed, we'll use that one.
*
* @param osSdkRoot The OS path of the SDK root folder.
+ * @param suggestedDir A suggestion for the installation folder name, based on the root
+ * folder used in the zip archive.
+ * @param sdkManager An existing SDK manager to list current platforms and addons.
* @return A new {@link File} corresponding to the directory to use to install this package.
*/
@Override
- public File getInstallFolder(String osSdkRoot) {
+ public File getInstallFolder(String osSdkRoot, String suggestedDir, SdkManager sdkManager) {
+
+ // First find if this add-on is already installed. If so, reuse the same directory.
+ for (IAndroidTarget target : sdkManager.getTargets()) {
+ if (target.isPlatform() &&
+ target.getApiVersionNumber() == getApiLevel() &&
+ target.getApiVersionName().equals(getVersion())) {
+ return new File(target.getLocation());
+ }
+ }
+
File platforms = new File(osSdkRoot, SdkConstants.FD_PLATFORMS);
File folder = new File(platforms, String.format("android-%s", getVersion())); //$NON-NLS-1$
// TODO find similar existing platform in platforms folder
diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ToolPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ToolPackage.java index b355b93..b6d830c 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ToolPackage.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ToolPackage.java @@ -17,6 +17,7 @@ package com.android.sdklib.internal.repository;
import com.android.sdklib.SdkConstants;
+import com.android.sdklib.SdkManager;
import com.android.sdklib.internal.repository.Archive.Arch;
import com.android.sdklib.internal.repository.Archive.Os;
@@ -82,10 +83,13 @@ public class ToolPackage extends Package { * A "tool" package should always be located in SDK/tools.
*
* @param osSdkRoot The OS path of the SDK root folder.
+ * @param suggestedDir A suggestion for the installation folder name, based on the root
+ * folder used in the zip archive.
+ * @param sdkManager An existing SDK manager to list current platforms and addons.
* @return A new {@link File} corresponding to the directory to use to install this package.
*/
@Override
- public File getInstallFolder(String osSdkRoot) {
+ public File getInstallFolder(String osSdkRoot, String suggestedDir, SdkManager sdkManager) {
return new File(osSdkRoot, SdkConstants.FD_TOOLS);
}
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java index 05e0b06..a92129f 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java @@ -101,7 +101,8 @@ class LocalSdkAdapter { if (packages == null) {
// load on demand the first time
- packages = parser.parseSdk(mUpdaterData.getOsSdkRoot());
+ packages = parser.parseSdk(mUpdaterData.getOsSdkRoot(),
+ mUpdaterData.getSdkManager());
}
if (packages != null) {
diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java index f8373dd..455abcf 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java @@ -273,7 +273,7 @@ class UpdaterData { break;
}
- if (archive.install(mOsSdkRoot, forceHttp, monitor)) {
+ if (archive.install(mOsSdkRoot, forceHttp, mSdkManager, monitor)) {
numInstalled++;
}
|