diff --git a/build/sdk.atree b/build/sdk.atree index a5dc1fe31..72de93bf2 100644 --- a/build/sdk.atree +++ b/build/sdk.atree @@ -127,6 +127,7 @@ framework/anttasks.jar tools/lib/anttasks.jar # sdkmanager bin/android tools/android +framework/commons-compress-1.0.jar tools/lib/commons-compress-1.0.jar framework/sdklib.jar tools/lib/sdklib.jar framework/sdkuilib.jar tools/lib/sdkuilib.jar framework/sdkmanager.jar tools/lib/sdkmanager.jar diff --git a/tools/sdkmanager/libs/sdklib/.classpath b/tools/sdkmanager/libs/sdklib/.classpath index 050eeb261..123ceef71 100644 --- a/tools/sdkmanager/libs/sdklib/.classpath +++ b/tools/sdkmanager/libs/sdklib/.classpath @@ -1,9 +1,10 @@ - - - - - - - - - + + + + + + + + + + diff --git a/tools/sdkmanager/libs/sdklib/src/Android.mk b/tools/sdkmanager/libs/sdklib/src/Android.mk index 25c712672..c8d6f71c1 100644 --- a/tools/sdkmanager/libs/sdklib/src/Android.mk +++ b/tools/sdkmanager/libs/sdklib/src/Android.mk @@ -20,7 +20,8 @@ LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_JAVA_RESOURCE_DIRS := . LOCAL_JAVA_LIBRARIES := \ - androidprefs + androidprefs \ + commons-compress-1.0 LOCAL_MODULE := sdklib diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java index c34e859ea..3757b7491 100755 --- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java +++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java @@ -16,19 +16,21 @@ package com.android.sdklib.internal.repository; +import com.android.sdklib.SdkConstants; import com.android.sdklib.SdkManager; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipFile; + import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.Enumeration; import java.util.Properties; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; /** @@ -692,6 +694,7 @@ public class Archive implements IDescription { * 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. */ + @SuppressWarnings("unchecked") private boolean unzipFolder(File archiveFile, long compressedSize, File unzipDestFolder, @@ -701,11 +704,13 @@ public class Archive implements IDescription { description += " (%1$d%%)"; - FileInputStream fis = null; - ZipInputStream zis = null; + ZipFile zipFile = null; try { - fis = new FileInputStream(archiveFile); - zis = new ZipInputStream(fis); + zipFile = new ZipFile(archiveFile); + + // figure if we'll need to set the unix permission + boolean usingUnixPerm = SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN || + SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_LINUX; // To advance the percent and the progress bar, we don't know the number of // items left to unzip. However we know the size of the archive and the size of @@ -718,8 +723,10 @@ public class Archive implements IDescription { byte[] buf = new byte[65536]; - ZipEntry entry; - while ((entry = zis.getNextEntry()) != null) { + Enumeration entries = + (Enumeration)zipFile.getEntries(); + while (entries.hasMoreElements()) { + ZipArchiveEntry entry = entries.nextElement(); String name = entry.getName(); @@ -768,7 +775,8 @@ public class Archive implements IDescription { try { fos = new FileOutputStream(destFile); int n; - while ((n = zis.read(buf)) != -1) { + InputStream entryContent = zipFile.getInputStream(entry); + while ((n = entryContent.read(buf)) != -1) { if (n > 0) { fos.write(buf, 0, n); } @@ -779,6 +787,11 @@ public class Archive implements IDescription { } } + // if needed set the permissions. + if (usingUnixPerm) { + setPermission(destFile, entry.getUnixMode()); + } + // Increment progress bar to match. We update only between files. for(incTotal += entry.getCompressedSize(); incCurr < incTotal; incCurr += incStep) { monitor.incProgress(1); @@ -801,16 +814,9 @@ public class Archive implements IDescription { monitor.setResult("Unzip failed: %1$s", e.getMessage()); } finally { - if (zis != null) { + if (zipFile != null) { try { - zis.close(); - } catch (IOException e) { - // pass - } - } - if (fis != null) { - try { - fis.close(); + zipFile.close(); } catch (IOException e) { // pass } @@ -902,5 +908,20 @@ public class Archive implements IDescription { return false; } + /** + * Sets the Unix permission on a file or folder. + * @param file The file to set permissions on. + * @param unixMode the permissions as received from {@link ZipArchiveEntry#getUnixMode()}. + * @throws IOException + */ + private void setPermission(File file, int unixMode) throws IOException { + // permissions contains more than user/group/all, and we need the 777 display mode, so we + // convert it in octal string and take the last 3 digits. + String permission = String.format("%o", unixMode); + permission = permission.substring(permission.length() - 3, permission.length()); + Runtime.getRuntime().exec(new String[] { + "chmod", permission, file.getAbsolutePath() + }); + } }