1 /* 2 * Copyright (C) 2009 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 17 package android.os.cts; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.hamcrest.Matchers.emptyOrNullString; 22 import static org.hamcrest.Matchers.hasItem; 23 import static org.hamcrest.Matchers.in; 24 import static org.hamcrest.Matchers.not; 25 import static org.junit.Assert.assertEquals; 26 import static org.junit.Assert.assertThat; 27 import static org.junit.Assert.assertTrue; 28 import static org.junit.Assert.fail; 29 30 import android.content.res.AssetManager; 31 import android.os.Build; 32 import android.platform.test.annotations.AppModeSdkSandbox; 33 import android.platform.test.annotations.RestrictedBuildTest; 34 import android.util.Log; 35 36 import androidx.test.InstrumentationRegistry; 37 import androidx.test.runner.AndroidJUnit4; 38 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 42 import java.io.BufferedReader; 43 import java.io.IOException; 44 import java.io.InputStreamReader; 45 import java.util.Arrays; 46 import java.util.HashSet; 47 import java.util.List; 48 import java.util.Set; 49 50 @AppModeSdkSandbox(reason = "Allow test in the SDK sandbox (does not prevent other modes).") 51 @RunWith(AndroidJUnit4.class) 52 public class BuildVersionTest { 53 54 private static final String LOG_TAG = "BuildVersionTest"; 55 private static final List<Integer> EXPECTED_SDKS = List.of(34, 35); 56 private static final String EXPECTED_BUILD_VARIANT = "user"; 57 private static final String EXPECTED_KEYS = "release-keys"; 58 private static final String PLATFORM_RELEASES_FILE = "platform_releases.txt"; 59 60 @Test 61 @SuppressWarnings("deprecation") 62 @RestrictedBuildTest testReleaseVersion()63 public void testReleaseVersion() { 64 // Applications may rely on the exact release version 65 assertThat("BUILD.VERSION.RELEASE", Build.VERSION.RELEASE, in(getExpectedReleases())); 66 if ("REL".equals(Build.VERSION.CODENAME)) { 67 assertEquals("BUILD.VERSION.RELEASE_OR_CODENAME", Build.VERSION.RELEASE, 68 Build.VERSION.RELEASE_OR_CODENAME); 69 } else { 70 assertEquals("BUILD.VERSION.RELEASE_OR_CODENAME", Build.VERSION.CODENAME, 71 Build.VERSION.RELEASE_OR_CODENAME); 72 } 73 assertThat(EXPECTED_SDKS).contains(Integer.parseInt(Build.VERSION.SDK)); 74 assertThat(EXPECTED_SDKS).contains(Build.VERSION.SDK_INT); 75 } 76 77 @Test testIncremental()78 public void testIncremental() { 79 assertThat(Build.VERSION.INCREMENTAL, not(emptyOrNullString())); 80 } 81 82 /** 83 * Verifies {@link Build#FINGERPRINT} follows expected format: 84 * <p/> 85 * <code> 86 * (BRAND)/(PRODUCT)/(DEVICE):(VERSION.RELEASE_OR_CODENAME)/(BUILD_ID)/ 87 * (BUILD_NUMBER):(BUILD_VARIANT)/(TAGS) 88 * </code> 89 */ 90 @Test 91 @RestrictedBuildTest testBuildFingerprint()92 public void testBuildFingerprint() { 93 String fingerprint = Build.FINGERPRINT; 94 Log.i(LOG_TAG, String.format("Testing fingerprint %s", fingerprint)); 95 96 verifyFingerprintStructure(fingerprint); 97 98 String[] fingerprintSegs = fingerprint.split("/"); 99 assertEquals(Build.BRAND, fingerprintSegs[0]); 100 assertEquals(Build.PRODUCT, fingerprintSegs[1]); 101 102 String[] devicePlatform = fingerprintSegs[2].split(":"); 103 assertEquals(2, devicePlatform.length); 104 assertEquals(Build.DEVICE, devicePlatform[0]); 105 assertEquals(Build.VERSION.RELEASE_OR_CODENAME, devicePlatform[1]); 106 107 assertEquals(Build.ID, fingerprintSegs[3]); 108 109 String[] buildNumberVariant = fingerprintSegs[4].split(":"); 110 String buildVariant = buildNumberVariant[1]; 111 assertEquals("Variant", EXPECTED_BUILD_VARIANT, buildVariant); 112 113 List<String> buildTagsList = Arrays.asList(fingerprintSegs[5].split(",")); 114 assertThat("Keys", buildTagsList, hasItem(EXPECTED_KEYS)); 115 } 116 117 @Test testPartitions()118 public void testPartitions() { 119 List<Build.Partition> partitions = Build.getFingerprintedPartitions(); 120 Set<String> seenPartitions = new HashSet<>(); 121 for (Build.Partition partition : partitions) { 122 verifyFingerprintStructure(partition.getFingerprint()); 123 assertTrue(partition.getBuildTimeMillis() > 0); 124 boolean unique = seenPartitions.add(partition.getName()); 125 assertTrue("partitions not unique, " + partition.getName() + " is duplicated", unique); 126 } 127 assertTrue(seenPartitions.contains(Build.Partition.PARTITION_NAME_SYSTEM)); 128 } 129 verifyFingerprintStructure(String fingerprint)130 private void verifyFingerprintStructure(String fingerprint) { 131 assertEquals("Build fingerprint must not include whitespace", -1, fingerprint.indexOf(' ')); 132 133 String[] segments = fingerprint.split("/"); 134 assertEquals("Build fingerprint does not match expected format", 6, segments.length); 135 136 String[] devicePlatform = segments[2].split(":"); 137 assertEquals(2, devicePlatform.length); 138 139 assertTrue(segments[4].contains(":")); 140 String buildVariant = segments[4].split(":")[1]; 141 assertTrue(buildVariant.length() > 0); 142 } 143 getExpectedReleases()144 private Set<String> getExpectedReleases() { 145 Set<String> expectedReleases = new HashSet<String>(); 146 final AssetManager assets = 147 InstrumentationRegistry.getInstrumentation().getTargetContext().getAssets(); 148 String line; 149 try (BufferedReader br = 150 new BufferedReader(new InputStreamReader(assets.open(PLATFORM_RELEASES_FILE)))) { 151 while ((line = br.readLine()) != null) { 152 expectedReleases.add(line); 153 } 154 } catch (IOException e) { 155 fail("Could not open file " + PLATFORM_RELEASES_FILE + " to run test"); 156 } 157 return expectedReleases; 158 } 159 } 160