Home | History | Annotate | Download | only in cts
      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