Merge "Add end-to-end tests for @EnforcePermission" am: cdac5de216
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2486756 Change-Id: I838015c65392febe5044cfac37e3a5f133b7203f Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
22
tests/EnforcePermission/Android.bp
Normal file
22
tests/EnforcePermission/Android.bp
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright (C) 2023 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 {
|
||||
default_applicable_licenses: ["frameworks_base_license"],
|
||||
}
|
||||
|
||||
filegroup {
|
||||
name: "frameworks-enforce-permission-test-aidl",
|
||||
srcs: ["aidl/**/*.aidl"],
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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 android.tests.enforcepermission;
|
||||
|
||||
interface INested {
|
||||
@EnforcePermission("ACCESS_NETWORK_STATE")
|
||||
void ProtectedByAccessNetworkState();
|
||||
|
||||
@EnforcePermission("READ_SYNC_SETTINGS")
|
||||
void ProtectedByReadSyncSettings();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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 android.tests.enforcepermission;
|
||||
|
||||
interface IProtected {
|
||||
@EnforcePermission("INTERNET")
|
||||
void ProtectedByInternet();
|
||||
|
||||
@EnforcePermission("VIBRATE")
|
||||
void ProtectedByVibrate();
|
||||
|
||||
@EnforcePermission("INTERNET")
|
||||
void ProtectedByInternetAndVibrateImplicitly();
|
||||
|
||||
@EnforcePermission("INTERNET")
|
||||
void ProtectedByInternetAndAccessNetworkStateImplicitly();
|
||||
|
||||
@EnforcePermission("INTERNET")
|
||||
void ProtectedByInternetAndReadSyncSettingsImplicitly();
|
||||
}
|
||||
23
tests/EnforcePermission/service-app/Android.bp
Normal file
23
tests/EnforcePermission/service-app/Android.bp
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (C) 2023 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.
|
||||
|
||||
android_test_helper_app {
|
||||
name: "EnforcePermissionTestHelper",
|
||||
srcs: [
|
||||
"src/**/*.java",
|
||||
":frameworks-enforce-permission-test-aidl",
|
||||
],
|
||||
platform_apis: true,
|
||||
certificate: "platform",
|
||||
}
|
||||
27
tests/EnforcePermission/service-app/AndroidManifest.xml
Normal file
27
tests/EnforcePermission/service-app/AndroidManifest.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2023 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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="android.tests.enforcepermission.service">
|
||||
<application>
|
||||
<service
|
||||
android:name=".TestService"
|
||||
android:exported="true" />
|
||||
|
||||
<service
|
||||
android:name=".NestedTestService"
|
||||
android:exported="true" />
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (C) 2023 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 android.tests.enforcepermission.service;
|
||||
|
||||
import android.annotation.EnforcePermission;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.tests.enforcepermission.INested;
|
||||
import android.util.Log;
|
||||
|
||||
public class NestedTestService extends Service {
|
||||
private static final String TAG = "EnforcePermission.NestedTestService";
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
Log.i(TAG, "onBind");
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
private final INested.Stub mBinder = new INested.Stub() {
|
||||
@Override
|
||||
@EnforcePermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
|
||||
public void ProtectedByAccessNetworkState() {
|
||||
ProtectedByAccessNetworkState_enforcePermission();
|
||||
}
|
||||
|
||||
@Override
|
||||
@EnforcePermission(android.Manifest.permission.READ_SYNC_SETTINGS)
|
||||
public void ProtectedByReadSyncSettings() {
|
||||
ProtectedByReadSyncSettings_enforcePermission();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* Copyright (C) 2023 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 android.tests.enforcepermission.service;
|
||||
|
||||
import android.annotation.EnforcePermission;
|
||||
import android.app.Service;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.tests.enforcepermission.INested;
|
||||
import android.tests.enforcepermission.IProtected;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
public class TestService extends Service {
|
||||
|
||||
private static final String TAG = "EnforcePermission.TestService";
|
||||
private volatile ServiceConnection mNestedServiceConnection;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
mNestedServiceConnection = new ServiceConnection();
|
||||
Intent intent = new Intent(this, NestedTestService.class);
|
||||
boolean bound = bindService(intent, mNestedServiceConnection, Context.BIND_AUTO_CREATE);
|
||||
if (!bound) {
|
||||
Log.wtf(TAG, "bindService() on NestedTestService failed");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
unbindService(mNestedServiceConnection);
|
||||
}
|
||||
|
||||
private static final class ServiceConnection implements android.content.ServiceConnection {
|
||||
private volatile CompletableFuture<INested> mFuture = new CompletableFuture<>();
|
||||
|
||||
public INested get() {
|
||||
try {
|
||||
return mFuture.get(1, TimeUnit.SECONDS);
|
||||
} catch (ExecutionException | InterruptedException | TimeoutException e) {
|
||||
throw new RuntimeException("Unable to reach NestedTestService: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
mFuture.complete(INested.Stub.asInterface(service));
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
mFuture = new CompletableFuture<>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
private final IProtected.Stub mBinder = new IProtected.Stub() {
|
||||
@Override
|
||||
@EnforcePermission(android.Manifest.permission.INTERNET)
|
||||
public void ProtectedByInternet() {
|
||||
ProtectedByInternet_enforcePermission();
|
||||
}
|
||||
|
||||
@Override
|
||||
@EnforcePermission(android.Manifest.permission.VIBRATE)
|
||||
public void ProtectedByVibrate() {
|
||||
ProtectedByVibrate_enforcePermission();
|
||||
}
|
||||
|
||||
@Override
|
||||
@EnforcePermission(android.Manifest.permission.INTERNET)
|
||||
public void ProtectedByInternetAndVibrateImplicitly() {
|
||||
ProtectedByInternetAndVibrateImplicitly_enforcePermission();
|
||||
|
||||
ProtectedByVibrate();
|
||||
}
|
||||
|
||||
@Override
|
||||
@EnforcePermission(android.Manifest.permission.INTERNET)
|
||||
public void ProtectedByInternetAndAccessNetworkStateImplicitly() throws RemoteException {
|
||||
ProtectedByInternetAndAccessNetworkStateImplicitly_enforcePermission();
|
||||
|
||||
mNestedServiceConnection.get().ProtectedByAccessNetworkState();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@EnforcePermission(android.Manifest.permission.INTERNET)
|
||||
public void ProtectedByInternetAndReadSyncSettingsImplicitly() throws RemoteException {
|
||||
ProtectedByInternetAndReadSyncSettingsImplicitly_enforcePermission();
|
||||
|
||||
mNestedServiceConnection.get().ProtectedByReadSyncSettings();
|
||||
}
|
||||
};
|
||||
}
|
||||
38
tests/EnforcePermission/test-app/Android.bp
Normal file
38
tests/EnforcePermission/test-app/Android.bp
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2023 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 {
|
||||
default_applicable_licenses: ["frameworks_base_license"],
|
||||
}
|
||||
|
||||
android_test {
|
||||
name: "EnforcePermissionTests",
|
||||
srcs: [
|
||||
"src/**/*.java",
|
||||
":frameworks-enforce-permission-test-aidl",
|
||||
],
|
||||
static_libs: [
|
||||
"androidx.test.rules",
|
||||
],
|
||||
libs: [
|
||||
"android.test.base",
|
||||
"android.test.runner",
|
||||
],
|
||||
data: [
|
||||
":EnforcePermissionTestHelper",
|
||||
],
|
||||
platform_apis: true,
|
||||
certificate: "platform",
|
||||
test_suites: ["general-tests"],
|
||||
}
|
||||
32
tests/EnforcePermission/test-app/AndroidManifest.xml
Normal file
32
tests/EnforcePermission/test-app/AndroidManifest.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2023 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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="android.tests.enforcepermission.tests">
|
||||
|
||||
<!-- Expected for the tests (not actually used) -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
|
||||
|
||||
<queries>
|
||||
<package android:name="android.tests.enforcepermission.service" />
|
||||
</queries>
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
</application>
|
||||
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
|
||||
android:targetPackage="android.tests.enforcepermission.tests"/>
|
||||
</manifest>
|
||||
28
tests/EnforcePermission/test-app/AndroidTest.xml
Normal file
28
tests/EnforcePermission/test-app/AndroidTest.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2023 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.
|
||||
-->
|
||||
<configuration description="Runs EnforcePermission End-to-End Tests">
|
||||
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
|
||||
<option name="test-file-name" value="EnforcePermissionTestHelper.apk"/>
|
||||
<option name="test-file-name" value="EnforcePermissionTests.apk"/>
|
||||
<option name="cleanup-apks" value="true" />
|
||||
</target_preparer>
|
||||
|
||||
<option name="test-tag" value="EnforcePermissionTests"/>
|
||||
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
|
||||
<option name="package" value="android.tests.enforcepermission.tests"/>
|
||||
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
|
||||
</test>
|
||||
</configuration>
|
||||
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* Copyright (C) 2023 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 android.tests.enforcepermission.tests;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.tests.enforcepermission.IProtected;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ServiceTest {
|
||||
|
||||
private static final String TAG = "EnforcePermission.Tests";
|
||||
private static final String SERVICE_NAME = "android.tests.enforcepermission.service";
|
||||
private static final int SERVICE_TIMEOUT_SEC = 5;
|
||||
|
||||
private Context mContext;
|
||||
private volatile ServiceConnection mServiceConnection;
|
||||
|
||||
@Before
|
||||
public void bindTestService() throws Exception {
|
||||
Log.d(TAG, "bindTestService");
|
||||
mContext = InstrumentationRegistry.getTargetContext();
|
||||
mServiceConnection = new ServiceConnection();
|
||||
Intent intent = new Intent();
|
||||
intent.setClassName(SERVICE_NAME, SERVICE_NAME + ".TestService");
|
||||
assertTrue(mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE));
|
||||
}
|
||||
|
||||
@After
|
||||
public void unbindTestService() throws Exception {
|
||||
mContext.unbindService(mServiceConnection);
|
||||
}
|
||||
|
||||
private static final class ServiceConnection implements android.content.ServiceConnection {
|
||||
private volatile CompletableFuture<IProtected> mFuture = new CompletableFuture<>();
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
mFuture.complete(IProtected.Stub.asInterface(service));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
mFuture = new CompletableFuture<>();
|
||||
}
|
||||
|
||||
public IProtected get() {
|
||||
try {
|
||||
return mFuture.get(SERVICE_TIMEOUT_SEC, TimeUnit.SECONDS);
|
||||
} catch (ExecutionException | InterruptedException | TimeoutException e) {
|
||||
throw new RuntimeException("Unable to reach TestService: " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImmediatePermissionGranted_succeeds()
|
||||
throws RemoteException {
|
||||
mServiceConnection.get().ProtectedByInternet();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImmediatePermissionNotGranted_fails()
|
||||
throws RemoteException {
|
||||
final Exception ex = assertThrows(SecurityException.class,
|
||||
() -> mServiceConnection.get().ProtectedByVibrate());
|
||||
assertThat(ex.getMessage(), containsString("VIBRATE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImmediatePermissionGrantedButImplicitLocalNotGranted_fails()
|
||||
throws RemoteException {
|
||||
final Exception ex = assertThrows(SecurityException.class,
|
||||
() -> mServiceConnection.get().ProtectedByInternetAndVibrateImplicitly());
|
||||
assertThat(ex.getMessage(), containsString("VIBRATE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImmediatePermissionGrantedButImplicitNestedNotGranted_fails()
|
||||
throws RemoteException {
|
||||
final Exception ex = assertThrows(SecurityException.class,
|
||||
() -> mServiceConnection.get()
|
||||
.ProtectedByInternetAndAccessNetworkStateImplicitly());
|
||||
assertThat(ex.getMessage(), containsString("ACCESS_NETWORK_STATE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImmediatePermissionGrantedAndImplicitNestedGranted_succeeds()
|
||||
throws RemoteException {
|
||||
mServiceConnection.get().ProtectedByInternetAndReadSyncSettingsImplicitly();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user