1 /* 2 * Copyright (C) 2017 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 junit.framework.Assert.assertEquals; 20 import static junit.framework.Assert.assertTrue; 21 import static junit.framework.Assert.fail; 22 23 import android.os.Build; 24 25 import androidx.test.InstrumentationRegistry; 26 27 import org.junit.Test; 28 29 /** 30 * Test that modern apps cannot access the device serial number even with the phone permission as 31 * 3P apps are now restricted from accessing persistent device identifiers. 32 */ 33 public class AccessSerialModernTest { 34 @Test 35 public void testAccessSerialPermissionNeeded() throws Exception { 36 // Build.SERIAL should not provide the device serial for modern apps. 37 // We don't know the serial but know that it should be the dummy 38 // value returned to unauthorized callers, so make sure that value 39 assertTrue("Build.SERIAL must not work for modern apps", 40 Build.UNKNOWN.equals(Build.SERIAL)); 41 42 // We don't have the read phone state permission, so this should throw 43 try { 44 Build.getSerial(); 45 fail("getSerial() must be gated on the READ_PHONE_STATE permission"); 46 } catch (SecurityException e) { 47 /* expected */ 48 } 49 50 // Now grant ourselves READ_PHONE_STATE 51 grantReadPhoneStatePermission(); 52 53 // Build.SERIAL should not provide the device serial for modern apps. 54 assertTrue("Build.SERIAL must not work for modern apps", 55 Build.UNKNOWN.equals(Build.SERIAL)); 56 57 // To prevent breakage an app targeting pre-Q with the READ_PHONE_STATE permission will 58 // receive Build.UNKNOWN; once the app is targeting Q+ a SecurityException will be thrown 59 // even if the app has the READ_PHONE_STATE permission. 60 try { 61 assertEquals("Build.getSerial() must return " + Build.UNKNOWN 62 + " for an app targeting pre-Q with the READ_PHONE_STATE permission", 63 Build.UNKNOWN, Build.getSerial()); 64 } catch (SecurityException e) { 65 fail("Build.getSerial() must return " + Build.UNKNOWN 66 + " for an app targeting pre-Q with the READ_PHONE_STATE permission, caught " 67 + "SecurityException: " 68 + e); 69 } 70 } 71 72 private void grantReadPhoneStatePermission() { 73 InstrumentationRegistry.getInstrumentation().getUiAutomation().grantRuntimePermission( 74 InstrumentationRegistry.getContext().getPackageName(), 75 android.Manifest.permission.READ_PHONE_STATE); 76 } 77 } 78