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.permission.cts; 18 19 import android.content.ContentValues; 20 import android.content.Intent; 21 import android.content.pm.PackageInfo; 22 import android.content.pm.PackageManager; 23 import android.content.pm.ResolveInfo; 24 import android.net.Uri; 25 import android.platform.test.annotations.AppModeFull; 26 import android.provider.CallLog; 27 import android.provider.Contacts; 28 import android.provider.Settings; 29 import android.test.AndroidTestCase; 30 import android.test.suitebuilder.annotation.MediumTest; 31 32 import java.util.List; 33 import java.util.Objects; 34 35 /** 36 * Tests Permissions related to reading from and writing to providers 37 */ 38 @MediumTest 39 public class ProviderPermissionTest extends AndroidTestCase { 40 /** 41 * Verify that read and write to contact requires permissions. 42 * <p>Tests Permission: 43 * {@link android.Manifest.permission#READ_CONTACTS} 44 */ 45 public void testReadContacts() { 46 assertReadingContentUriRequiresPermission(Contacts.People.CONTENT_URI, 47 android.Manifest.permission.READ_CONTACTS); 48 } 49 50 /** 51 * Verify that write to contact requires permissions. 52 * <p>Tests Permission: 53 * {@link android.Manifest.permission#WRITE_CONTACTS} 54 */ 55 public void testWriteContacts() { 56 assertWritingContentUriRequiresPermission(Contacts.People.CONTENT_URI, 57 android.Manifest.permission.WRITE_CONTACTS); 58 } 59 60 public void assertWritingContentUriRequiresPermission(Uri uri, String permission, 61 boolean allowIAE) { 62 try { 63 getContext().getContentResolver().insert(uri, new ContentValues()); 64 fail("expected SecurityException requiring " + permission); 65 } catch (IllegalArgumentException e) { 66 if (!allowIAE) { 67 fail("expected SecurityException requiring " + permission + " got " + e); 68 } 69 } catch (SecurityException expected) { 70 assertNotNull("security exception's error message.", expected.getMessage()); 71 assertTrue("error message should contain " + permission + ".", 72 expected.getMessage().contains(permission)); 73 } 74 } 75 76 /** 77 * Verify that reading call logs requires permissions. 78 * <p>Tests Permission: 79 * {@link android.Manifest.permission#READ_CALL_LOG} 80 */ 81 @AppModeFull 82 public void testReadCallLog() { 83 assertReadingContentUriRequiresPermission(CallLog.CONTENT_URI, 84 android.Manifest.permission.READ_CALL_LOG); 85 } 86 87 /** 88 * Verify that writing call logs requires permissions. 89 * <p>Tests Permission: 90 * {@link android.Manifest.permission#WRITE_CALL_LOG} 91 */ 92 public void testWriteCallLog() { 93 assertWritingContentUriRequiresPermission(CallLog.CONTENT_URI, 94 android.Manifest.permission.WRITE_CALL_LOG, 95 getContext().getPackageManager().isInstantApp()); 96 } 97 98 /** 99 * Verify that write to settings requires permissions. 100 * <p>Tests Permission: 101 * {@link android.Manifest.permission#WRITE_SETTINGS} 102 */ 103 public void testWriteSettings() { 104 final String permission = android.Manifest.permission.WRITE_SETTINGS; 105 ContentValues value = new ContentValues(); 106 value.put(Settings.System.NAME, "name"); 107 value.put(Settings.System.VALUE, "value_insert"); 108 109 try { 110 getContext().getContentResolver().insert(Settings.System.CONTENT_URI, value); 111 fail("expected SecurityException requiring " + permission); 112 } catch (SecurityException expected) { 113 assertNotNull("security exception's error message.", expected.getMessage()); 114 assertTrue("error message should contain \"" + permission + "\". Got: \"" 115 + expected.getMessage() + "\".", 116 expected.getMessage().contains(permission)); 117 } 118 } 119 120 /** 121 * Verify that the {@link android.Manifest.permission#MANAGE_DOCUMENTS} 122 * permission is only held by exactly one package: whoever handles the 123 * {@link android.content.Intent#ACTION_OPEN_DOCUMENT} intent. 124 * <p> 125 * No other apps should <em>ever</em> attempt to acquire this permission, 126 * since it would give those apps extremely broad access to all storage 127 * providers on the device without user involvement in the arbitration 128 * process. Apps should instead always rely on Uri permission grants for 129 * access, using 130 * {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION} and related 131 * APIs. 132 */ 133 public void testManageDocuments() { 134 final PackageManager pm = getContext().getPackageManager(); 135 136 final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); 137 intent.addCategory(Intent.CATEGORY_OPENABLE); 138 intent.setType("*/*"); 139 final ResolveInfo ri = pm.resolveActivity(intent, 0); 140 final String validPkg = ri.activityInfo.packageName; 141 142 final List<PackageInfo> holding = pm.getPackagesHoldingPermissions(new String[] { 143 android.Manifest.permission.MANAGE_DOCUMENTS 144 }, PackageManager.MATCH_UNINSTALLED_PACKAGES); 145 for (PackageInfo pi : holding) { 146 if (!Objects.equals(pi.packageName, validPkg)) { 147 fail("Exactly one package (must be " + validPkg 148 + ") can request the MANAGE_DOCUMENTS permission; found package " 149 + pi.packageName + " which must be revoked for security reasons"); 150 } 151 } 152 } 153 } 154