1 /* 2 * Copyright (C) 2020 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 com.android.server.uri; 18 19 import static org.mockito.ArgumentMatchers.anyLong; 20 import static org.mockito.ArgumentMatchers.eq; 21 import static org.mockito.Mockito.mock; 22 import static org.mockito.Mockito.when; 23 24 import android.annotation.NonNull; 25 import android.app.ActivityManagerInternal; 26 import android.content.ContentResolver; 27 import android.content.Context; 28 import android.content.ContextWrapper; 29 import android.content.Intent; 30 import android.content.pm.ApplicationInfo; 31 import android.content.pm.PackageManager; 32 import android.content.pm.PackageManagerInternal; 33 import android.content.pm.PathPermission; 34 import android.content.pm.ProviderInfo; 35 import android.net.Uri; 36 import android.os.FileUtils; 37 import android.os.PatternMatcher; 38 import android.os.Process; 39 import android.os.UserHandle; 40 import android.test.mock.MockContentResolver; 41 import android.test.mock.MockPackageManager; 42 43 import com.android.server.LocalServices; 44 45 import java.io.File; 46 47 public class UriGrantsMockContext extends ContextWrapper { 48 static final String TAG = "UriGrants"; 49 50 static final int FLAG_READ = Intent.FLAG_GRANT_READ_URI_PERMISSION; 51 static final int FLAG_WRITE = Intent.FLAG_GRANT_WRITE_URI_PERMISSION; 52 static final int FLAG_PERSISTABLE = Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION; 53 static final int FLAG_PREFIX = Intent.FLAG_GRANT_PREFIX_URI_PERMISSION; 54 55 static final int USER_PRIMARY = 10; 56 static final int USER_SECONDARY = 11; 57 58 /** Typical social network app */ 59 static final String PKG_SOCIAL = "com.example.social"; 60 /** Typical camera app that allows grants */ 61 static final String PKG_CAMERA = "com.example.camera"; 62 /** Completely private app/provider that offers no grants */ 63 static final String PKG_PRIVATE = "com.example.private"; 64 /** Completely public app/provider that needs no grants */ 65 static final String PKG_PUBLIC = "com.example.public"; 66 /** Completely public app/provider that forces grants */ 67 static final String PKG_FORCE = "com.example.force"; 68 /** Complex provider that offers nested grants */ 69 static final String PKG_COMPLEX = "com.example.complex"; 70 71 private static final int UID_SOCIAL = android.os.Process.LAST_APPLICATION_UID - 1; 72 private static final int UID_CAMERA = android.os.Process.LAST_APPLICATION_UID - 2; 73 private static final int UID_PRIVATE = android.os.Process.LAST_APPLICATION_UID - 3; 74 private static final int UID_PUBLIC = android.os.Process.LAST_APPLICATION_UID - 4; 75 private static final int UID_FORCE = android.os.Process.LAST_APPLICATION_UID - 5; 76 private static final int UID_COMPLEX = android.os.Process.LAST_APPLICATION_UID - 6; 77 78 static final int UID_PRIMARY_SOCIAL = UserHandle.getUid(USER_PRIMARY, UID_SOCIAL); 79 static final int UID_PRIMARY_CAMERA = UserHandle.getUid(USER_PRIMARY, UID_CAMERA); 80 static final int UID_PRIMARY_PRIVATE = UserHandle.getUid(USER_PRIMARY, UID_PRIVATE); 81 static final int UID_PRIMARY_PUBLIC = UserHandle.getUid(USER_PRIMARY, UID_PUBLIC); 82 static final int UID_PRIMARY_FORCE = UserHandle.getUid(USER_PRIMARY, UID_FORCE); 83 static final int UID_PRIMARY_COMPLEX = UserHandle.getUid(USER_PRIMARY, UID_COMPLEX); 84 85 static final int UID_SECONDARY_SOCIAL = UserHandle.getUid(USER_SECONDARY, UID_SOCIAL); 86 static final int UID_SECONDARY_CAMERA = UserHandle.getUid(USER_SECONDARY, UID_CAMERA); 87 static final int UID_SECONDARY_PRIVATE = UserHandle.getUid(USER_SECONDARY, UID_PRIVATE); 88 static final int UID_SECONDARY_PUBLIC = UserHandle.getUid(USER_SECONDARY, UID_PUBLIC); 89 static final int UID_SECONDARY_FORCE = UserHandle.getUid(USER_SECONDARY, UID_FORCE); 90 static final int UID_SECONDARY_COMPLEX = UserHandle.getUid(USER_SECONDARY, UID_COMPLEX); 91 92 static final Uri URI_PHOTO_1 = Uri.parse("content://" + PKG_CAMERA + "/1"); 93 static final Uri URI_PHOTO_2 = Uri.parse("content://" + PKG_CAMERA + "/2"); 94 static final Uri URI_PRIVATE = Uri.parse("content://" + PKG_PRIVATE + "/42"); 95 static final Uri URI_PUBLIC = Uri.parse("content://" + PKG_PUBLIC + "/42"); 96 static final Uri URI_FORCE = Uri.parse("content://" + PKG_FORCE + "/42"); 97 98 private final File mDir; 99 100 private final MockPackageManager mPackage; 101 private final MockContentResolver mResolver; 102 103 final ActivityManagerInternal mAmInternal; 104 final PackageManagerInternal mPmInternal; 105 UriGrantsMockContext(@onNull Context base)106 public UriGrantsMockContext(@NonNull Context base) { 107 super(base); 108 mDir = new File(base.getFilesDir(), TAG); 109 mDir.mkdirs(); 110 FileUtils.deleteContents(mDir); 111 112 mPackage = new MockPackageManager(); 113 mResolver = new MockContentResolver(this); 114 115 mAmInternal = mock(ActivityManagerInternal.class); 116 LocalServices.removeServiceForTest(ActivityManagerInternal.class); 117 LocalServices.addService(ActivityManagerInternal.class, mAmInternal); 118 119 mPmInternal = mock(PackageManagerInternal.class); 120 LocalServices.removeServiceForTest(PackageManagerInternal.class); 121 LocalServices.addService(PackageManagerInternal.class, mPmInternal); 122 123 for (int userId : new int[] { USER_PRIMARY, USER_SECONDARY }) { 124 when(mPmInternal.getPackageUid(eq(PKG_SOCIAL), anyLong(), eq(userId))) 125 .thenReturn(UserHandle.getUid(userId, UID_SOCIAL)); 126 when(mPmInternal.getPackageUid(eq(PKG_CAMERA), anyLong(), eq(userId))) 127 .thenReturn(UserHandle.getUid(userId, UID_CAMERA)); 128 when(mPmInternal.getPackageUid(eq(PKG_PRIVATE), anyLong(), eq(userId))) 129 .thenReturn(UserHandle.getUid(userId, UID_PRIVATE)); 130 when(mPmInternal.getPackageUid(eq(PKG_PUBLIC), anyLong(), eq(userId))) 131 .thenReturn(UserHandle.getUid(userId, UID_PUBLIC)); 132 when(mPmInternal.getPackageUid(eq(PKG_FORCE), anyLong(), eq(userId))) 133 .thenReturn(UserHandle.getUid(userId, UID_FORCE)); 134 when(mPmInternal.getPackageUid(eq(PKG_COMPLEX), anyLong(), eq(userId))) 135 .thenReturn(UserHandle.getUid(userId, UID_COMPLEX)); 136 137 when(mPmInternal.resolveContentProvider(eq(PKG_CAMERA), anyLong(), eq(userId), 138 eq(Process.SYSTEM_UID))) 139 .thenReturn(buildCameraProvider(userId)); 140 when(mPmInternal.resolveContentProvider(eq(PKG_CAMERA), anyLong(), eq(userId), 141 eq(UserHandle.getUid(userId, UID_CAMERA)))) 142 .thenReturn(buildCameraProvider(userId)); 143 when(mPmInternal.resolveContentProvider(eq(PKG_PRIVATE), anyLong(), eq(userId), 144 eq(Process.SYSTEM_UID))) 145 .thenReturn(buildPrivateProvider(userId)); 146 when(mPmInternal.resolveContentProvider(eq(PKG_PRIVATE), anyLong(), eq(userId), 147 eq(UserHandle.getUid(userId, UID_PRIVATE)))) 148 .thenReturn(buildPrivateProvider(userId)); 149 when(mPmInternal.resolveContentProvider(eq(PKG_PUBLIC), anyLong(), eq(userId), 150 eq(Process.SYSTEM_UID))) 151 .thenReturn(buildPublicProvider(userId)); 152 when(mPmInternal.resolveContentProvider(eq(PKG_PUBLIC), anyLong(), eq(userId), 153 eq(UserHandle.getUid(userId, UID_PUBLIC)))) 154 .thenReturn(buildPublicProvider(userId)); 155 when(mPmInternal.resolveContentProvider(eq(PKG_FORCE), anyLong(), eq(userId), 156 eq(Process.SYSTEM_UID))) 157 .thenReturn(buildForceProvider(userId)); 158 when(mPmInternal.resolveContentProvider(eq(PKG_FORCE), anyLong(), eq(userId), 159 eq(UserHandle.getUid(userId, UID_FORCE)))) 160 .thenReturn(buildForceProvider(userId)); 161 when(mPmInternal.resolveContentProvider(eq(PKG_COMPLEX), anyLong(), eq(userId), 162 eq(Process.SYSTEM_UID))) 163 .thenReturn(buildComplexProvider(userId)); 164 when(mPmInternal.resolveContentProvider(eq(PKG_COMPLEX), anyLong(), eq(userId), 165 eq(UserHandle.getUid(userId, UID_COMPLEX)))) 166 .thenReturn(buildComplexProvider(userId)); 167 } 168 } 169 buildCameraProvider(int userId)170 private static ProviderInfo buildCameraProvider(int userId) { 171 final ProviderInfo pi = new ProviderInfo(); 172 pi.packageName = PKG_CAMERA; 173 pi.authority = PKG_CAMERA; 174 pi.readPermission = android.Manifest.permission.READ_EXTERNAL_STORAGE; 175 pi.writePermission = android.Manifest.permission.WRITE_EXTERNAL_STORAGE; 176 pi.grantUriPermissions = true; 177 pi.applicationInfo = new ApplicationInfo(); 178 pi.applicationInfo.uid = UserHandle.getUid(userId, UID_CAMERA); 179 return pi; 180 } 181 buildPrivateProvider(int userId)182 private static ProviderInfo buildPrivateProvider(int userId) { 183 final ProviderInfo pi = new ProviderInfo(); 184 pi.packageName = PKG_PRIVATE; 185 pi.authority = PKG_PRIVATE; 186 pi.exported = false; 187 pi.grantUriPermissions = false; 188 pi.applicationInfo = new ApplicationInfo(); 189 pi.applicationInfo.uid = UserHandle.getUid(userId, UID_PRIVATE); 190 return pi; 191 } 192 buildPublicProvider(int userId)193 private static ProviderInfo buildPublicProvider(int userId) { 194 final ProviderInfo pi = new ProviderInfo(); 195 pi.packageName = PKG_PUBLIC; 196 pi.authority = PKG_PUBLIC; 197 pi.exported = true; 198 pi.grantUriPermissions = false; 199 pi.applicationInfo = new ApplicationInfo(); 200 pi.applicationInfo.uid = UserHandle.getUid(userId, UID_PUBLIC); 201 return pi; 202 } 203 buildForceProvider(int userId)204 private static ProviderInfo buildForceProvider(int userId) { 205 final ProviderInfo pi = new ProviderInfo(); 206 pi.packageName = PKG_FORCE; 207 pi.authority = PKG_FORCE; 208 pi.exported = true; 209 pi.grantUriPermissions = true; 210 pi.forceUriPermissions = true; 211 pi.applicationInfo = new ApplicationInfo(); 212 pi.applicationInfo.uid = UserHandle.getUid(userId, UID_FORCE); 213 return pi; 214 } 215 buildComplexProvider(int userId)216 private static ProviderInfo buildComplexProvider(int userId) { 217 final ProviderInfo pi = new ProviderInfo(); 218 pi.packageName = PKG_COMPLEX; 219 pi.authority = PKG_COMPLEX; 220 pi.exported = true; 221 pi.grantUriPermissions = true; 222 pi.applicationInfo = new ApplicationInfo(); 223 pi.applicationInfo.uid = UserHandle.getUid(userId, UID_COMPLEX); 224 pi.pathPermissions = new PathPermission[] { 225 new PathPermission("/secure", PathPermission.PATTERN_PREFIX, 226 android.Manifest.permission.READ_EXTERNAL_STORAGE, 227 android.Manifest.permission.WRITE_EXTERNAL_STORAGE), 228 }; 229 pi.uriPermissionPatterns = new PatternMatcher[] { 230 new PatternMatcher("/secure", PathPermission.PATTERN_PREFIX), 231 new PatternMatcher("/insecure", PathPermission.PATTERN_PREFIX), 232 }; 233 return pi; 234 } 235 236 @Override getPackageManager()237 public PackageManager getPackageManager() { 238 return mPackage; 239 } 240 241 @Override getContentResolver()242 public ContentResolver getContentResolver() { 243 return mResolver; 244 } 245 246 @Override getFilesDir()247 public File getFilesDir() { 248 return mDir; 249 } 250 } 251