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 com.android.tools.metalava 18 19 import com.android.tools.metalava.lint.DefaultLintErrorMessage 20 import com.android.tools.metalava.testing.java 21 import org.junit.Test 22 23 class SystemServiceCheckTest : DriverTest() { 24 @Test SystemService OK, loaded from signature filenull25 fun `SystemService OK, loaded from signature file`() { 26 check( 27 expectedIssues = "", // OK 28 includeSystemApiAnnotations = true, 29 sourceFiles = 30 arrayOf( 31 java( 32 """ 33 package test.pkg; 34 import android.annotation.RequiresPermission; 35 @android.annotation.SystemService 36 public class MyTest2 { 37 @RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"}) 38 public int myMethod1() { } 39 } 40 """ 41 ), 42 systemServiceSource, 43 requiresPermissionSource 44 ), 45 manifest = 46 """<?xml version="1.0" encoding="UTF-8"?> 47 <manifest xmlns:android="http://schemas.android.com/apk/res/android"> 48 <permission 49 android:name="foo.bar.PERMISSION1" 50 android:label="@string/foo" 51 android:description="@string/foo" 52 android:protectionLevel="signature"/> 53 <permission 54 android:name="foo.bar.PERMISSION2" 55 android:protectionLevel="signature"/> 56 57 </manifest> 58 """ 59 ) 60 } 61 62 @Test SystemService OK, loaded from sourcenull63 fun `SystemService OK, loaded from source`() { 64 check( 65 expectedIssues = "", // OK 66 includeSystemApiAnnotations = true, 67 sourceFiles = 68 arrayOf( 69 java( 70 """ 71 package test.pkg; 72 73 @android.annotation.SystemService 74 public class MyTest2 { 75 @android.annotation.RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"}) 76 public void myMethod1() { 77 } 78 } 79 """ 80 ), 81 systemServiceSource 82 ), 83 manifest = 84 """<?xml version="1.0" encoding="UTF-8"?> 85 <manifest xmlns:android="http://schemas.android.com/apk/res/android"> 86 <permission 87 android:name="foo.bar.PERMISSION1" 88 android:label="@string/foo" 89 android:description="@string/foo" 90 android:protectionLevel="signature"/> 91 <permission 92 android:name="foo.bar.PERMISSION2" 93 android:protectionLevel="signature"/> 94 95 </manifest> 96 """ 97 ) 98 } 99 100 @Test Check SystemService -- no permission annotationnull101 fun `Check SystemService -- no permission annotation`() { 102 check( 103 expectedFail = DefaultLintErrorMessage, 104 expectedIssues = 105 "src/test/pkg/MyTest1.java:4: error: Method 'myMethod2' must be protected with a system permission. [RequiresPermission]", 106 includeSystemApiAnnotations = true, 107 sourceFiles = 108 arrayOf( 109 java( 110 """ 111 package test.pkg; 112 @android.annotation.SystemService 113 public class MyTest1 { 114 public int myMethod2() { } 115 } 116 """ 117 ), 118 systemServiceSource, 119 requiresPermissionSource 120 ), 121 manifest = 122 """<?xml version="1.0" encoding="UTF-8"?> 123 <manifest/> 124 """ 125 ) 126 } 127 128 @Test Check SystemService -- can miss a permission with anyOfnull129 fun `Check SystemService -- can miss a permission with anyOf`() { 130 check( 131 expectedIssues = "", 132 includeSystemApiAnnotations = true, 133 sourceFiles = 134 arrayOf( 135 java( 136 """ 137 package test.pkg; 138 import android.annotation.RequiresPermission; 139 @android.annotation.SystemService 140 public class MyTest2 { 141 @RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"}) 142 public int myMethod1() { } 143 } 144 """ 145 ), 146 systemServiceSource, 147 requiresPermissionSource 148 ), 149 manifest = 150 """<?xml version="1.0" encoding="UTF-8"?> 151 <manifest xmlns:android="http://schemas.android.com/apk/res/android"> 152 <permission 153 android:name="foo.bar.PERMISSION1" 154 android:label="@string/foo" 155 android:description="@string/foo" 156 android:protectionLevel="signature"/> 157 </manifest> 158 """ 159 ) 160 } 161 162 @Test Check SystemService such that at least one permission must be defined with anyOfnull163 fun `Check SystemService such that at least one permission must be defined with anyOf`() { 164 check( 165 expectedFail = DefaultLintErrorMessage, 166 expectedIssues = 167 """ 168 src/test/pkg/MyTest2.java:6: error: Method 'myMethod1' must be protected with a system permission. [RequiresPermission] 169 src/test/pkg/MyTest2.java:6: error: None of the permissions foo.bar.PERMISSION1, foo.bar.PERMISSION2 are defined by manifest TESTROOT/manifest.xml. [RequiresPermission] 170 """, 171 includeSystemApiAnnotations = true, 172 sourceFiles = 173 arrayOf( 174 java( 175 """ 176 package test.pkg; 177 import android.annotation.RequiresPermission; 178 @android.annotation.SystemService 179 public class MyTest2 { 180 @RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"}) 181 public int myMethod1() { } 182 } 183 """ 184 ), 185 systemServiceSource, 186 requiresPermissionSource 187 ), 188 manifest = 189 """<?xml version="1.0" encoding="UTF-8"?> 190 <manifest/> 191 """ 192 ) 193 } 194 195 @Test Check SystemService -- missing one permission with allOfnull196 fun `Check SystemService -- missing one permission with allOf`() { 197 check( 198 expectedFail = DefaultLintErrorMessage, 199 expectedIssues = 200 "src/test/pkg/MyTest2.java:6: error: Permission 'foo.bar.PERMISSION2' is not defined by manifest TESTROOT/manifest.xml. [RequiresPermission]", 201 includeSystemApiAnnotations = true, 202 sourceFiles = 203 arrayOf( 204 java( 205 """ 206 package test.pkg; 207 import android.annotation.RequiresPermission; 208 @android.annotation.SystemService 209 public class MyTest2 { 210 @RequiresPermission(allOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"}) 211 public int test() { } 212 } 213 """ 214 ), 215 systemServiceSource, 216 requiresPermissionSource 217 ), 218 manifest = 219 """<?xml version="1.0" encoding="UTF-8"?> 220 <manifest xmlns:android="http://schemas.android.com/apk/res/android"> 221 <permission 222 android:name="foo.bar.PERMISSION1" 223 android:label="@string/foo" 224 android:description="@string/foo" 225 android:protectionLevel="signature"/> 226 </manifest> 227 """ 228 ) 229 } 230 231 @Test Check SystemService -- must be system permission, not normalnull232 fun `Check SystemService -- must be system permission, not normal`() { 233 check( 234 expectedFail = DefaultLintErrorMessage, 235 expectedIssues = 236 "src/test/pkg/MyTest2.java:7: error: Method 'test' must be protected with a system " + 237 "permission; it currently allows non-system callers holding [foo.bar.PERMISSION1, " + 238 "foo.bar.PERMISSION2] [RequiresPermission]", 239 includeSystemApiAnnotations = true, 240 sourceFiles = 241 arrayOf( 242 java( 243 """ 244 package test.pkg; 245 import android.annotation.RequiresPermission; 246 @SuppressWarnings("WeakerAccess") 247 @android.annotation.SystemService 248 public class MyTest2 { 249 @RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"}) 250 public int test() { } 251 } 252 """ 253 ), 254 systemServiceSource, 255 requiresPermissionSource 256 ), 257 manifest = 258 """<?xml version="1.0" encoding="UTF-8"?> 259 <manifest xmlns:android="http://schemas.android.com/apk/res/android"> 260 <permission 261 android:name="foo.bar.PERMISSION1" 262 android:label="@string/foo" 263 android:description="@string/foo" 264 android:protectionLevel="normal"/> 265 <permission 266 android:name="foo.bar.PERMISSION2" 267 android:protectionLevel="normal"/> 268 269 </manifest> 270 """ 271 ) 272 } 273 274 @Test Check SystemService -- missing manifest permissionsnull275 fun `Check SystemService -- missing manifest permissions`() { 276 check( 277 expectedFail = DefaultLintErrorMessage, 278 expectedIssues = 279 """ 280 src/test/pkg/MyTest2.java:6: error: Method 'test' must be protected with a system permission. [RequiresPermission] 281 src/test/pkg/MyTest2.java:6: error: Permission 'Manifest.permission.MY_PERMISSION' is not defined by manifest TESTROOT/manifest.xml. [RequiresPermission] 282 src/test/pkg/MyTest2.java:6: error: Permission 'Manifest.permission.MY_PERMISSION2' is not defined by manifest TESTROOT/manifest.xml. [RequiresPermission] 283 """, 284 includeSystemApiAnnotations = true, 285 sourceFiles = 286 arrayOf( 287 java( 288 """ 289 package test.pkg; 290 import android.annotation.RequiresPermission; 291 @android.annotation.SystemService 292 public class MyTest2 { 293 @RequiresPermission(allOf={Manifest.permission.MY_PERMISSION,Manifest.permission.MY_PERMISSION2}) 294 public int test() { } 295 } 296 """ 297 ), 298 systemServiceSource, 299 requiresPermissionSource 300 ), 301 manifest = 302 """<?xml version="1.0" encoding="UTF-8"?> 303 <manifest/> 304 """ 305 ) 306 } 307 308 @Test Invalid manifestnull309 fun `Invalid manifest`() { 310 check( 311 expectedFail = DefaultLintErrorMessage, 312 expectedIssues = 313 """ 314 manifest.xml: error: Failed to parse TESTROOT/manifest.xml: The markup in the document preceding the root element must be well-formed. [ParseError] 315 src/test/pkg/MyTest2.java:7: error: Method 'test' must be protected with a system permission. [RequiresPermission] 316 src/test/pkg/MyTest2.java:7: error: None of the permissions foo.bar.PERMISSION1, foo.bar.PERMISSION2 are defined by manifest TESTROOT/manifest.xml. [RequiresPermission] 317 """, 318 includeSystemApiAnnotations = true, 319 sourceFiles = 320 arrayOf( 321 java( 322 """ 323 package test.pkg; 324 import android.annotation.RequiresPermission; 325 @SuppressWarnings("WeakerAccess") 326 @android.annotation.SystemService 327 public class MyTest2 { 328 @RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"}) 329 public int test() { } 330 } 331 """ 332 ), 333 systemServiceSource, 334 requiresPermissionSource 335 ), 336 manifest = 337 """<?xml version="1.0" encoding="UTF-8"?> 338 </error> 339 """ 340 ) 341 } 342 343 @Test Warning suppressed via annotationnull344 fun `Warning suppressed via annotation`() { 345 check( 346 expectedIssues = "", // OK (suppressed) 347 includeSystemApiAnnotations = true, 348 sourceFiles = 349 arrayOf( 350 java( 351 """ 352 package test.pkg; 353 354 @android.annotation.SystemService 355 public class MyTest1 { 356 @android.annotation.SuppressLint({"RemovedField","RequiresPermission"}) 357 @android.annotation.RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"}) 358 public void myMethod1() { 359 } 360 } 361 """ 362 ), 363 systemServiceSource 364 ), 365 manifest = 366 """<?xml version="1.0" encoding="UTF-8"?> 367 <manifest/> 368 """ 369 ) 370 } 371 } 372