Add TestablePermissons, which allows basic control
Test: runtest --path frameworks/base/tests/testables Change-Id: I8db323cfc26f592e2e002c9328ab97bc130d559b
This commit is contained in:
@@ -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() {
|
||||
|
||||
80
tests/testables/src/android/testing/TestablePermissions.java
Normal file
80
tests/testables/src/android/testing/TestablePermissions.java
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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, "");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user