summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Monk <jmonk@google.com>2017-12-08 09:48:25 -0500
committerJason Monk <jmonk@google.com>2017-12-08 09:49:08 -0500
commitd01cef91b09a74b49b359ae637cb02f985269be9 (patch)
treebf01e084effe23717aeb92c2cb73a9d2ec342e3c
parent4d51f44535ff3935c0aabed0371dc988112b925b (diff)
Add TestablePermissons, which allows basic control
Test: runtest --path frameworks/base/tests/testables Change-Id: I8db323cfc26f592e2e002c9328ab97bc130d559b
-rw-r--r--tests/testables/src/android/testing/TestableContext.java155
-rw-r--r--tests/testables/src/android/testing/TestablePermissions.java80
-rw-r--r--tests/testables/tests/src/android/testing/TestablePermissionsTest.java90
3 files changed, 325 insertions, 0 deletions
diff --git a/tests/testables/src/android/testing/TestableContext.java b/tests/testables/src/android/testing/TestableContext.java
index 498d517c104b..ffe721993a37 100644
--- a/tests/testables/src/android/testing/TestableContext.java
+++ b/tests/testables/src/android/testing/TestableContext.java
@@ -25,6 +25,7 @@ import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.res.Resources;
+import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.UserHandle;
@@ -69,6 +70,7 @@ public class TestableContext extends ContextWrapper implements TestRule {
private LeakCheck.Tracker mService;
private LeakCheck.Tracker mComponent;
private TestableResources mTestableResources;
+ private TestablePermissions mTestablePermissions;
public TestableContext(Context base) {
this(base, null);
@@ -302,6 +304,159 @@ public class TestableContext extends ContextWrapper implements TestRule {
super.unregisterComponentCallbacks(callback);
}
+ public TestablePermissions getTestablePermissions() {
+ if (mTestablePermissions == null) {
+ mTestablePermissions = new TestablePermissions();
+ }
+ return mTestablePermissions;
+ }
+
+ @Override
+ public int checkCallingOrSelfPermission(String permission) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
+ return mTestablePermissions.check(permission);
+ }
+ return super.checkCallingOrSelfPermission(permission);
+ }
+
+ @Override
+ public int checkCallingPermission(String permission) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
+ return mTestablePermissions.check(permission);
+ }
+ return super.checkCallingPermission(permission);
+ }
+
+ @Override
+ public int checkPermission(String permission, int pid, int uid) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
+ return mTestablePermissions.check(permission);
+ }
+ return super.checkPermission(permission, pid, uid);
+ }
+
+ @Override
+ public int checkPermission(String permission, int pid, int uid, IBinder callerToken) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
+ return mTestablePermissions.check(permission);
+ }
+ return super.checkPermission(permission, pid, uid, callerToken);
+ }
+
+ @Override
+ public int checkSelfPermission(String permission) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
+ return mTestablePermissions.check(permission);
+ }
+ return super.checkSelfPermission(permission);
+ }
+
+ @Override
+ public void enforceCallingOrSelfPermission(String permission, String message) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
+ mTestablePermissions.enforce(permission);
+ } else {
+ super.enforceCallingOrSelfPermission(permission, message);
+ }
+ }
+
+ @Override
+ public void enforceCallingPermission(String permission, String message) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
+ mTestablePermissions.enforce(permission);
+ } else {
+ super.enforceCallingPermission(permission, message);
+ }
+ }
+
+ @Override
+ public void enforcePermission(String permission, int pid, int uid, String message) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(permission)) {
+ mTestablePermissions.enforce(permission);
+ } else {
+ super.enforcePermission(permission, pid, uid, message);
+ }
+ }
+
+ @Override
+ public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
+ return mTestablePermissions.check(uri, modeFlags);
+ }
+ return super.checkCallingOrSelfUriPermission(uri, modeFlags);
+ }
+
+ @Override
+ public int checkCallingUriPermission(Uri uri, int modeFlags) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
+ return mTestablePermissions.check(uri, modeFlags);
+ }
+ return super.checkCallingUriPermission(uri, modeFlags);
+ }
+
+ @Override
+ public void enforceCallingOrSelfUriPermission(Uri uri, int modeFlags, String message) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
+ mTestablePermissions.enforce(uri, modeFlags);
+ } else {
+ super.enforceCallingOrSelfUriPermission(uri, modeFlags, message);
+ }
+ }
+
+ @Override
+ public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
+ return mTestablePermissions.check(uri, modeFlags);
+ }
+ return super.checkUriPermission(uri, pid, uid, modeFlags);
+ }
+
+ @Override
+ public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
+ return mTestablePermissions.check(uri, modeFlags);
+ }
+ return super.checkUriPermission(uri, pid, uid, modeFlags, callerToken);
+ }
+
+ @Override
+ public int checkUriPermission(Uri uri, String readPermission, String writePermission, int pid,
+ int uid, int modeFlags) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
+ return mTestablePermissions.check(uri, modeFlags);
+ }
+ return super.checkUriPermission(uri, readPermission, writePermission, pid, uid, modeFlags);
+ }
+
+ @Override
+ public void enforceCallingUriPermission(Uri uri, int modeFlags, String message) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
+ mTestablePermissions.enforce(uri, modeFlags);
+ } else {
+ super.enforceCallingUriPermission(uri, modeFlags, message);
+ }
+ }
+
+ @Override
+ public void enforceUriPermission(Uri uri, int pid, int uid, int modeFlags, String message) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
+ mTestablePermissions.enforce(uri, modeFlags);
+ } else {
+ super.enforceUriPermission(uri, pid, uid, modeFlags, message);
+ }
+ }
+
+ @Override
+ public void enforceUriPermission(Uri uri, String readPermission, String writePermission,
+ int pid, int uid, int modeFlags, String message) {
+ if (mTestablePermissions != null && mTestablePermissions.wantsCall(uri)) {
+ mTestablePermissions.enforce(uri, modeFlags);
+ } else {
+ super.enforceUriPermission(uri, readPermission, writePermission, pid, uid, modeFlags,
+ message);
+ }
+ }
+
@Override
public Statement apply(Statement base, Description description) {
return new TestWatcher() {
diff --git a/tests/testables/src/android/testing/TestablePermissions.java b/tests/testables/src/android/testing/TestablePermissions.java
new file mode 100644
index 000000000000..4f009e406ca7
--- /dev/null
+++ b/tests/testables/src/android/testing/TestablePermissions.java
@@ -0,0 +1,80 @@
+/*
+ * 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 android.testing;
+
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.util.ArrayMap;
+
+/**
+ * Simple class for simulating basic permission states for tests.
+ *
+ * All enforce* and check* calls on TestableContext are considered the same
+ * and routed through the same check here. If more fine-grained control is
+ * required, then either a sub-class or spy on TestableContext is recommended.
+ */
+public class TestablePermissions {
+
+ private final ArrayMap<String, Integer> mPermissions = new ArrayMap<>();
+ private final ArrayMap<Uri, Integer> mUris = new ArrayMap<>();
+
+ /**
+ * Sets the return value for checkPermission* calls on TestableContext
+ * for a specific permission value. For all enforcePermission* calls
+ * they will throw a security exception if value != PERMISSION_GRANTED.
+ */
+ public void setPermission(String permission, int value) {
+ mPermissions.put(permission, value);
+ }
+
+ /**
+ * Sets the return value for checkUriPermission* calls on TestableContext
+ * for a specific permission value. For all enforceUriPermission* calls
+ * they will throw a security exception if value != PERMISSION_GRANTED.
+ */
+ public void setPermission(Uri uri, int value) {
+ // TODO: Support modeFlags
+ mUris.put(uri, value);
+ }
+
+ boolean wantsCall(String permission) {
+ return mPermissions.containsKey(permission);
+ }
+
+ boolean wantsCall(Uri uri) {
+ return mUris.containsKey(uri);
+ }
+
+ int check(String permission) {
+ return mPermissions.get(permission);
+ }
+
+ int check(Uri uri, int modeFlags) {
+ // TODO: Support modeFlags
+ return mUris.get(uri);
+ }
+
+ public void enforce(String permission) {
+ if (check(permission) != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException();
+ }
+ }
+
+ public void enforce(Uri uri, int modeFlags) {
+ if (check(uri, modeFlags) != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException();
+ }
+ }
+}
diff --git a/tests/testables/tests/src/android/testing/TestablePermissionsTest.java b/tests/testables/tests/src/android/testing/TestablePermissionsTest.java
new file mode 100644
index 000000000000..c56146e19a40
--- /dev/null
+++ b/tests/testables/tests/src/android/testing/TestablePermissionsTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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 android.testing;
+
+import static android.content.pm.PackageManager.PERMISSION_DENIED;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import static org.junit.Assert.assertEquals;
+
+import android.Manifest.permission;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.testing.TestableLooper.RunWithLooper;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class TestablePermissionsTest {
+
+ private static final Uri URI_1 = Uri.parse("content://my.authority/path1");
+ private static final Uri URI_2 = Uri.parse("content://my.authority/path2");
+
+ @Rule
+ public TestableContext mContext = new TestableContext(InstrumentationRegistry.getContext());
+
+ @Test
+ public void testCheck() {
+ mContext.getTestablePermissions().setPermission(permission.INTERACT_ACROSS_USERS,
+ PERMISSION_GRANTED);
+ mContext.getTestablePermissions().setPermission(permission.INTERACT_ACROSS_USERS_FULL,
+ PERMISSION_DENIED);
+ assertEquals(PERMISSION_GRANTED,
+ mContext.checkPermission(permission.INTERACT_ACROSS_USERS, 0, 0));
+ assertEquals(PERMISSION_DENIED,
+ mContext.checkPermission(permission.INTERACT_ACROSS_USERS_FULL, 0, 0));
+ }
+
+ @Test
+ public void testCheckUri() {
+ mContext.getTestablePermissions().setPermission(URI_1, PERMISSION_GRANTED);
+ mContext.getTestablePermissions().setPermission(URI_2, PERMISSION_DENIED);
+
+ assertEquals(PERMISSION_GRANTED, mContext.checkUriPermission(URI_1, 0, 0, 0));
+ assertEquals(PERMISSION_DENIED, mContext.checkUriPermission(URI_2, 0, 0, 0));
+ }
+
+ @Test
+ public void testEnforceNoException() {
+ mContext.getTestablePermissions().setPermission(permission.INTERACT_ACROSS_USERS,
+ PERMISSION_GRANTED);
+ mContext.enforceCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS, "");
+ }
+
+ @Test(expected = SecurityException.class)
+ public void testEnforceWithException() {
+ mContext.getTestablePermissions().setPermission(permission.INTERACT_ACROSS_USERS,
+ PERMISSION_DENIED);
+ mContext.enforceCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS, "");
+ }
+
+ @Test
+ public void testEnforceUriNoException() {
+ mContext.getTestablePermissions().setPermission(URI_1, PERMISSION_GRANTED);
+ mContext.enforceUriPermission(URI_1, 0, 0, 0, "");
+ }
+
+ @Test(expected = SecurityException.class)
+ public void testEnforceUriWithException() {
+ mContext.getTestablePermissions().setPermission(URI_1, PERMISSION_DENIED);
+ mContext.enforceUriPermission(URI_1, 0, 0, 0, "");
+ }
+
+} \ No newline at end of file