blob: 95c18aaef34bc576107613f6c1d954741116b074 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tools.metalava
import org.junit.Test
class SystemServiceCheckTest : DriverTest() {
@Test
fun `SystemService OK, loaded from signature file`() {
check(
warnings = "", // OK
compatibilityMode = false,
includeSystemApiAnnotations = true,
sourceFiles = arrayOf(
java(
"""
package test.pkg;
import android.annotation.RequiresPermission;
@android.annotation.SystemService
public class MyTest2 {
@RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"})
public int myMethod1() { }
}
"""
),
systemServiceSource,
requiresPermissionSource
),
manifest = """<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<permission
android:name="foo.bar.PERMISSION1"
android:label="@string/foo"
android:description="@string/foo"
android:protectionLevel="signature"/>
<permission
android:name="foo.bar.PERMISSION2"
android:protectionLevel="signature"/>
</manifest>
"""
)
}
@Test
fun `SystemService OK, loaded from source`() {
check(
warnings = "", // OK
compatibilityMode = false,
includeSystemApiAnnotations = true,
sourceFiles = arrayOf(
java(
"""
package test.pkg;
@android.annotation.SystemService
public class MyTest2 {
@android.annotation.RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"})
public void myMethod1() {
}
}
"""
),
systemServiceSource
),
manifest = """<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<permission
android:name="foo.bar.PERMISSION1"
android:label="@string/foo"
android:description="@string/foo"
android:protectionLevel="signature"/>
<permission
android:name="foo.bar.PERMISSION2"
android:protectionLevel="signature"/>
</manifest>
"""
)
}
@Test
fun `Check SystemService -- no permission annotation`() {
check(
warnings = "src/test/pkg/MyTest1.java:4: lint: Method 'myMethod2' must be protected with a system permission. [RequiresPermission]",
compatibilityMode = false,
includeSystemApiAnnotations = true,
sourceFiles = arrayOf(
java(
"""
package test.pkg;
@android.annotation.SystemService
public class MyTest1 {
public int myMethod2() { }
}
"""
),
systemServiceSource,
requiresPermissionSource
),
manifest = """<?xml version="1.0" encoding="UTF-8"?>
<manifest/>
"""
)
}
@Test
fun `Check SystemService -- can miss a permission with anyOf`() {
check(
warnings = "",
compatibilityMode = false,
includeSystemApiAnnotations = true,
sourceFiles = arrayOf(
java(
"""
package test.pkg;
import android.annotation.RequiresPermission;
@android.annotation.SystemService
public class MyTest2 {
@RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"})
public int myMethod1() { }
}
"""
),
systemServiceSource,
requiresPermissionSource
),
manifest = """<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<permission
android:name="foo.bar.PERMISSION1"
android:label="@string/foo"
android:description="@string/foo"
android:protectionLevel="signature"/>
</manifest>
"""
)
}
@Test
fun `Check SystemService such that at least one permission must be defined with anyOf`() {
check(
warnings = """
src/test/pkg/MyTest2.java:5: lint: None of the permissions foo.bar.PERMISSION1, foo.bar.PERMISSION2 are defined by manifest TESTROOT/manifest.xml. [RequiresPermission]
src/test/pkg/MyTest2.java:5: lint: Method 'myMethod1' must be protected with a system permission. [RequiresPermission]
""",
compatibilityMode = false,
includeSystemApiAnnotations = true,
sourceFiles = arrayOf(
java(
"""
package test.pkg;
import android.annotation.RequiresPermission;
@android.annotation.SystemService
public class MyTest2 {
@RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"})
public int myMethod1() { }
}
"""
),
systemServiceSource,
requiresPermissionSource
),
manifest = """<?xml version="1.0" encoding="UTF-8"?>
<manifest/>
"""
)
}
@Test
fun `Check SystemService -- missing one permission with allOf`() {
check(
warnings = "src/test/pkg/MyTest2.java:5: lint: Permission 'foo.bar.PERMISSION2' is not defined by manifest TESTROOT/manifest.xml. [RequiresPermission]",
compatibilityMode = false,
includeSystemApiAnnotations = true,
sourceFiles = arrayOf(
java(
"""
package test.pkg;
import android.annotation.RequiresPermission;
@android.annotation.SystemService
public class MyTest2 {
@RequiresPermission(allOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"})
public int test() { }
}
"""
),
systemServiceSource,
requiresPermissionSource
),
manifest = """<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<permission
android:name="foo.bar.PERMISSION1"
android:label="@string/foo"
android:description="@string/foo"
android:protectionLevel="signature"/>
</manifest>
"""
)
}
@Test
fun `Check SystemService -- must be system permission, not normal`() {
check(
warnings = "src/test/pkg/MyTest2.java:6: lint: Method 'test' must be protected with a system " +
"permission; it currently allows non-system callers holding [foo.bar.PERMISSION1, " +
"foo.bar.PERMISSION2] [RequiresPermission]",
compatibilityMode = false,
includeSystemApiAnnotations = true,
sourceFiles = arrayOf(
java(
"""
package test.pkg;
import android.annotation.RequiresPermission;
@SuppressWarnings("WeakerAccess")
@android.annotation.SystemService
public class MyTest2 {
@RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"})
public int test() { }
}
"""
),
systemServiceSource,
requiresPermissionSource
),
manifest = """<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<permission
android:name="foo.bar.PERMISSION1"
android:label="@string/foo"
android:description="@string/foo"
android:protectionLevel="normal"/>
<permission
android:name="foo.bar.PERMISSION2"
android:protectionLevel="normal"/>
</manifest>
"""
)
}
@Test
fun `Check SystemService -- missing manifest permissions`() {
check(
warnings = """
src/test/pkg/MyTest2.java:5: lint: Permission 'Manifest.permission.MY_PERMISSION' is not defined by manifest TESTROOT/manifest.xml. [RequiresPermission]
src/test/pkg/MyTest2.java:5: lint: Permission 'Manifest.permission.MY_PERMISSION2' is not defined by manifest TESTROOT/manifest.xml. [RequiresPermission]
src/test/pkg/MyTest2.java:5: lint: Method 'test' must be protected with a system permission. [RequiresPermission]
""",
compatibilityMode = false,
includeSystemApiAnnotations = true,
sourceFiles = arrayOf(
java(
"""
package test.pkg;
import android.annotation.RequiresPermission;
@android.annotation.SystemService
public class MyTest2 {
@RequiresPermission(allOf={Manifest.permission.MY_PERMISSION,Manifest.permission.MY_PERMISSION2})
public int test() { }
}
"""
),
systemServiceSource,
requiresPermissionSource
),
manifest = """<?xml version="1.0" encoding="UTF-8"?>
<manifest/>
"""
)
}
@Test
fun `Invalid manifest`() {
check(
warnings = """
TESTROOT/manifest.xml: error: Failed to parse TESTROOT/manifest.xml: The markup in the document preceding the root element must be well-formed. [ParseError]
src/test/pkg/MyTest2.java:6: lint: None of the permissions foo.bar.PERMISSION1, foo.bar.PERMISSION2 are defined by manifest TESTROOT/manifest.xml. [RequiresPermission]
src/test/pkg/MyTest2.java:6: lint: Method 'test' must be protected with a system permission. [RequiresPermission]
""",
compatibilityMode = false,
includeSystemApiAnnotations = true,
sourceFiles = arrayOf(
java(
"""
package test.pkg;
import android.annotation.RequiresPermission;
@SuppressWarnings("WeakerAccess")
@android.annotation.SystemService
public class MyTest2 {
@RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"})
public int test() { }
}
"""
),
systemServiceSource,
requiresPermissionSource
),
manifest = """<?xml version="1.0" encoding="UTF-8"?>
</error>
"""
)
}
@Test
fun `Warning suppressed via annotation`() {
check(
warnings = "", // OK (suppressed)
compatibilityMode = false,
includeSystemApiAnnotations = true,
sourceFiles = arrayOf(
java(
"""
package test.pkg;
@android.annotation.SystemService
public class MyTest1 {
@android.annotation.SuppressLint({"RemovedField","RequiresPermission"})
@android.annotation.RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"})
public void myMethod1() {
}
}
"""
),
java(
"""
package test.pkg;
@android.annotation.SystemService
public class MyTest2 {
// Old suppress syntax
@android.annotation.SuppressLint({"Doclava10","Doclava125"})
@android.annotation.RequiresPermission(anyOf={"foo.bar.PERMISSION1","foo.bar.PERMISSION2"})
public void myMethod1() {
}
}
"""
),
systemServiceSource
),
manifest = """<?xml version="1.0" encoding="UTF-8"?>
<manifest/>
"""
)
}
}