blob: 480dc1a8ae0c37701ba3db9e0d79174355a652a8 [file] [log] [blame]
/*
* Copyright (C) 2016 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.apksig.apk;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import com.android.apksig.ApkSigner;
import com.android.apksig.internal.util.HexEncoding;
import com.android.apksig.internal.util.Resources;
import com.android.apksig.util.DataSources;
@RunWith(JUnit4.class)
public class ApkUtilsTest {
@Test
public void testGetMinSdkVersionForValidCodename() throws Exception {
assertEquals(1, ApkUtils.getMinSdkVersionForCodename("AAAA"));
assertEquals(2, ApkUtils.getMinSdkVersionForCodename("CUPCAKE"));
assertEquals(7, ApkUtils.getMinSdkVersionForCodename("FROYO"));
assertEquals(23, ApkUtils.getMinSdkVersionForCodename("N"));
assertEquals(23, ApkUtils.getMinSdkVersionForCodename("NMR1"));
assertEquals(25, ApkUtils.getMinSdkVersionForCodename("OMG"));
// Speculative: Q should be 27 or higher (not yet known at the time of writing)
assertEquals(27, ApkUtils.getMinSdkVersionForCodename("QQQ"));
}
@Test(expected = CodenameMinSdkVersionException.class)
public void testGetMinSdkVersionForEmptyCodename() throws Exception {
ApkUtils.getMinSdkVersionForCodename("");
}
@Test(expected = CodenameMinSdkVersionException.class)
public void testGetMinSdkVersionForUnexpectedCodename() throws Exception {
ApkUtils.getMinSdkVersionForCodename("1ABC");
}
@Test
public void testGetMinSdkVersionFromBinaryAndroidManifest() throws Exception {
ByteBuffer manifest = getAndroidManifest("original.apk");
assertEquals(23, ApkUtils.getMinSdkVersionFromBinaryAndroidManifest(manifest));
}
@Test
public void testGetDebuggableFromBinaryAndroidManifest() throws Exception {
ByteBuffer manifest = getAndroidManifest("original.apk");
assertFalse(ApkUtils.getDebuggableFromBinaryAndroidManifest(manifest));
manifest = getAndroidManifest("debuggable-boolean.apk");
assertTrue(ApkUtils.getDebuggableFromBinaryAndroidManifest(manifest));
// android:debuggable value is a resource reference -- this must be rejected
manifest = getAndroidManifest("debuggable-resource.apk");
try {
ApkUtils.getDebuggableFromBinaryAndroidManifest(manifest);
fail();
} catch (ApkFormatException expected) {}
}
@Test
public void testGetPackageNameFromBinaryAndroidManifest() throws Exception {
ByteBuffer manifest = getAndroidManifest("original.apk");
assertEquals(
"android.appsecurity.cts.tinyapp",
ApkUtils.getPackageNameFromBinaryAndroidManifest(manifest));
}
@Test
public void testGetAndroidManifest() throws Exception {
ByteBuffer manifest = getAndroidManifest("original.apk");
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(manifest);
byte[] actualDigest = md.digest();
assertEquals(
"8b3de63a282652221162cdc327f424924ac3c7c24e642035975a1ee7a395c4dc",
HexEncoding.encode(actualDigest));
}
private static ByteBuffer getAndroidManifest(String apkResourceName)
throws IOException, ApkFormatException {
return getAndroidManifest(getResource(apkResourceName));
}
private static ByteBuffer getAndroidManifest(byte[] apk)
throws IOException, ApkFormatException {
return ApkUtils.getAndroidManifest(DataSources.asDataSource(ByteBuffer.wrap(apk)));
}
private static byte[] getResource(String resourceName) throws IOException {
return Resources.toByteArray(ApkSigner.class, resourceName);
}
}