blob: c06845943fde42c45ec76b84cf09618d3fb94142 [file] [log] [blame]
/*
* Copyright (C) 2016 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.providers.contacts.enterprise;
import android.app.admin.DevicePolicyManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Directory;
import android.test.mock.MockContext;
import android.test.suitebuilder.annotation.SmallTest;
import org.mockito.Matchers;
import java.util.Arrays;
import java.util.List;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.android.providers.contacts.FixedAndroidTestCase;
/**
* Unit tests for {@link EnterprisePolicyGuard}.
*/
@SmallTest
public class EnterprisePolicyGuardTest extends FixedAndroidTestCase {
private static final String SYSTEM_PROPERTY_DEXMAKER_DEXCACHE = "dexmaker.dexcache";
private static final int CONTACT_ID = 10;
private static final String CONTACT_NAME = "david";
private static final String CONTACT_EMAIL = "david.green@android.com";
private static final String CONTACT_PHONE = "+1234567890";
private static final long DIRECTORY_ID = Directory.ENTERPRISE_DEFAULT;
private static final Uri URI_CONTACTS_ID_PHOTO =
Uri.parse("content://com.android.contacts/contacts/" + CONTACT_ID + "/photo");
private static final Uri URI_CONTACTS_ID_DISPLAY_PHOTO = Uri
.parse("content://com.android.contacts/contacts/" + CONTACT_ID + "/display_photo");
private static final Uri URI_CONTACTS_FILTER =
Uri.parse("content://com.android.contacts/contacts/filter/" + CONTACT_NAME);
private static final Uri URI_PHONES_FILTER = Uri
.parse("content://com.android.contacts/data/phones/filter/" + CONTACT_NAME);
private static final Uri URI_CALLABLES_FILTER = Uri.parse(
"content://com.android.contacts/data/callables/filter/" + CONTACT_NAME);
private static final Uri URI_EMAILS_FILTER = Uri
.parse("content://com.android.contacts/data/emails/filter/" + CONTACT_NAME);
private static final Uri URI_EMAILS_LOOKUP =
Uri.parse("content://com.android.contacts/data/emails/lookup/"
+ Uri.encode(CONTACT_EMAIL));
private static final Uri URI_PHONE_LOOKUP = Uri.parse(
"content://com.android.contacts/phone_lookup/" + Uri.encode(CONTACT_PHONE));
private static final Uri URI_DIRECTORIES =
Uri.parse("content://com.android.contacts/directories");
private static final Uri URI_DIRECTORIES_ID =
Uri.parse("content://com.android.contacts/directories/" + DIRECTORY_ID);
private static final Uri URI_DIRECTORY_FILE =
Uri.parse("content://com.android.contacts/directory_file_enterprise/content%3A%2F%2F"
+ "com.google.contacts.gal.provider%2Fphoto%2F?directory=1000000002");
private static final Uri URI_OTHER =
Uri.parse("content://com.android.contacts/contacts/" + CONTACT_ID);
// Please notice that the directory id should be < ENTERPRISE_BASE because the id should be
// substracted before passing to enterprise side.
private static final int REMOTE_DIRECTORY_ID = 10;
@Override
protected void setUp() throws Exception {
super.setUp();
System.setProperty(SYSTEM_PROPERTY_DEXMAKER_DEXCACHE, getContext().getCacheDir().getPath());
Thread.currentThread().setContextClassLoader(EnterprisePolicyGuard.class.getClassLoader());
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
System.clearProperty(SYSTEM_PROPERTY_DEXMAKER_DEXCACHE);
}
public void testDirectorySupport() {
EnterprisePolicyGuard guard = new EnterprisePolicyGuardTestable(getContext(), true);
checkDirectorySupport(guard, URI_PHONE_LOOKUP, true);
checkDirectorySupport(guard, URI_EMAILS_LOOKUP, true);
checkDirectorySupport(guard, URI_CONTACTS_FILTER, true);
checkDirectorySupport(guard, URI_PHONES_FILTER, true);
checkDirectorySupport(guard, URI_CALLABLES_FILTER, true);
checkDirectorySupport(guard, URI_EMAILS_FILTER, true);
checkDirectorySupport(guard, URI_DIRECTORY_FILE, true);
checkDirectorySupport(guard, URI_DIRECTORIES, false);
checkDirectorySupport(guard, URI_DIRECTORIES_ID, false);
checkDirectorySupport(guard, URI_CONTACTS_ID_PHOTO, false);
checkDirectorySupport(guard, URI_CONTACTS_ID_DISPLAY_PHOTO, false);
checkDirectorySupport(guard, URI_OTHER, false);
}
public void testCrossProfile_userSettingOn() {
Context context;
EnterprisePolicyGuard guard;
// All enabled.
context = getMockContext(true, true);
guard = new EnterprisePolicyGuardTestable(context, true);
checkCrossProfile(guard, URI_PHONE_LOOKUP, true);
checkCrossProfile(guard, URI_EMAILS_LOOKUP, true);
checkCrossProfile(guard, URI_CONTACTS_FILTER, true);
checkCrossProfile(guard, URI_PHONES_FILTER, true);
checkCrossProfile(guard, URI_CALLABLES_FILTER, true);
checkCrossProfile(guard, URI_EMAILS_FILTER, true);
checkCrossProfile(guard, URI_DIRECTORY_FILE, true);
checkCrossProfile(guard, URI_DIRECTORIES, true);
checkCrossProfile(guard, URI_DIRECTORIES_ID, true);
checkCrossProfile(guard, URI_CONTACTS_ID_PHOTO, true);
checkCrossProfile(guard, URI_CONTACTS_ID_DISPLAY_PHOTO, true);
checkCrossProfile(guard, URI_OTHER, false);
// Only ContactsSearch is disabled
context = getMockContext(true, /* isContactsSearchEnabled= */ false);
guard = new EnterprisePolicyGuardTestable(context, true);
checkCrossProfile(guard, URI_PHONE_LOOKUP, true);
checkCrossProfile(guard, URI_EMAILS_LOOKUP, true);
checkCrossProfile(guard, URI_CONTACTS_FILTER, false);
checkCrossProfile(guard, URI_PHONES_FILTER, false);
checkCrossProfile(guard, URI_CALLABLES_FILTER, false);
checkCrossProfile(guard, URI_EMAILS_FILTER, false);
checkCrossProfile(guard, URI_DIRECTORY_FILE, true);
checkCrossProfile(guard, URI_DIRECTORIES, true);
checkCrossProfile(guard, URI_DIRECTORIES_ID, true);
checkCrossProfile(guard, URI_CONTACTS_ID_PHOTO, true);
checkCrossProfile(guard, URI_CONTACTS_ID_DISPLAY_PHOTO, true);
checkCrossProfile(guard, URI_OTHER, false);
// Only CallerId is disabled
context = getMockContext(/* isCallerIdEnabled= */ false, true);
guard = new EnterprisePolicyGuardTestable(context, true);
checkCrossProfile(guard, URI_PHONE_LOOKUP, false);
checkCrossProfile(guard, URI_EMAILS_LOOKUP, false);
checkCrossProfile(guard, URI_CONTACTS_FILTER, true);
checkCrossProfile(guard, URI_PHONES_FILTER, true);
checkCrossProfile(guard, URI_CALLABLES_FILTER, true);
checkCrossProfile(guard, URI_EMAILS_FILTER, true);
checkCrossProfile(guard, URI_DIRECTORY_FILE, true);
checkCrossProfile(guard, URI_DIRECTORIES, true);
checkCrossProfile(guard, URI_DIRECTORIES_ID, true);
checkCrossProfile(guard, URI_CONTACTS_ID_PHOTO, true);
checkCrossProfile(guard, URI_CONTACTS_ID_DISPLAY_PHOTO, true);
checkCrossProfile(guard, URI_OTHER, false);
// CallerId and ContactsSearch are disabled
context = getMockContext(/* isCallerIdEnabled= */ false,
/* isContactsSearchEnabled= */ false);
guard = new EnterprisePolicyGuardTestable(context, true);
checkCrossProfile(guard, URI_PHONE_LOOKUP, false);
checkCrossProfile(guard, URI_EMAILS_LOOKUP, false);
checkCrossProfile(guard, URI_CONTACTS_FILTER, false);
checkCrossProfile(guard, URI_PHONES_FILTER, false);
checkCrossProfile(guard, URI_CALLABLES_FILTER, false);
checkCrossProfile(guard, URI_EMAILS_FILTER, false);
checkCrossProfile(guard, URI_DIRECTORY_FILE, false);
checkCrossProfile(guard, URI_DIRECTORIES, false);
checkCrossProfile(guard, URI_DIRECTORIES_ID, false);
checkCrossProfile(guard, URI_CONTACTS_ID_PHOTO, false);
checkCrossProfile(guard, URI_CONTACTS_ID_DISPLAY_PHOTO, false);
checkCrossProfile(guard, URI_OTHER, false);
}
public void testCrossProfile_userSettingOff() {
// All enabled.
Context context = getMockContext(true, true);
EnterprisePolicyGuard guard = new EnterprisePolicyGuardTestable(context, false);
// All directory supported Uris with remote directory id should not allowed.
checkCrossProfile(guard, appendRemoteDirectoryId(URI_PHONE_LOOKUP), false);
checkCrossProfile(guard, appendRemoteDirectoryId(URI_EMAILS_LOOKUP), false);
checkCrossProfile(guard, appendRemoteDirectoryId(URI_CONTACTS_FILTER), false);
checkCrossProfile(guard, appendRemoteDirectoryId(URI_PHONES_FILTER), false);
checkCrossProfile(guard, appendRemoteDirectoryId(URI_CALLABLES_FILTER), false);
checkCrossProfile(guard, appendRemoteDirectoryId(URI_EMAILS_FILTER), false);
checkCrossProfile(guard, URI_DIRECTORY_FILE, false);
// Always allow uri with no directory support.
checkCrossProfile(guard, URI_DIRECTORIES, true);
checkCrossProfile(guard, URI_DIRECTORIES_ID, true);
checkCrossProfile(guard, URI_CONTACTS_ID_PHOTO, true);
checkCrossProfile(guard, URI_CONTACTS_ID_DISPLAY_PHOTO, true);
checkCrossProfile(guard, URI_OTHER, false);
// Always allow uri with no remote directory id.
checkCrossProfile(guard, URI_PHONE_LOOKUP, true);
checkCrossProfile(guard, URI_EMAILS_LOOKUP, true);
checkCrossProfile(guard, URI_CONTACTS_FILTER, true);
checkCrossProfile(guard, URI_PHONES_FILTER, true);
checkCrossProfile(guard, URI_CALLABLES_FILTER, true);
checkCrossProfile(guard, URI_EMAILS_FILTER, true);
}
private static Uri appendRemoteDirectoryId(Uri uri) {
return appendDirectoryId(uri, REMOTE_DIRECTORY_ID);
}
private static Uri appendDirectoryId(Uri uri, int directoryId) {
return uri.buildUpon().appendQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY,
String.valueOf(directoryId)).build();
}
private static void checkDirectorySupport(EnterprisePolicyGuard guard, Uri uri,
boolean expected) {
if (expected) {
assertTrue("Expected true but got false for uri: " + uri,
guard.isCrossProfileDirectorySupported(uri));
} else {
assertFalse("Expected false but got true for uri: " + uri,
guard.isCrossProfileDirectorySupported(uri));
}
}
private static void checkCrossProfile(EnterprisePolicyGuard guard, Uri uri, boolean expected) {
if (expected) {
assertTrue("Expected true but got false for uri: " + uri,
guard.isCrossProfileAllowed(uri));
} else {
assertFalse("Expected false but got true for uri: " + uri,
guard.isCrossProfileAllowed(uri));
}
}
private static final int CURRENT_USER_ID = 0;
private static final int WORK_USER_ID = 10;
private static final UserInfo CURRENT_USER_INFO =
new UserInfo(CURRENT_USER_ID, "user0", CURRENT_USER_ID);
private static final UserInfo WORK_USER_INFO =
new UserInfo(WORK_USER_ID, "user10", UserInfo.FLAG_MANAGED_PROFILE);
private static final List<UserInfo> NORMAL_USERINFO_LIST =
Arrays.asList(new UserInfo[] {CURRENT_USER_INFO});
private static final List<UserInfo> MANAGED_USERINFO_LIST =
Arrays.asList(new UserInfo[] {CURRENT_USER_INFO, WORK_USER_INFO});
private Context getMockContext(boolean isCallerIdEnabled, boolean isContactsSearchEnabled) {
DevicePolicyManager mockDpm = mock(DevicePolicyManager.class);
when(mockDpm.getCrossProfileCallerIdDisabled(Matchers.<UserHandle>any()))
.thenReturn(!isCallerIdEnabled);
when(mockDpm.getCrossProfileContactsSearchDisabled(Matchers.<UserHandle>any()))
.thenReturn(!isContactsSearchEnabled);
List<UserInfo> userInfos = MANAGED_USERINFO_LIST;
UserManager mockUm = mock(UserManager.class);
when(mockUm.getUserHandle()).thenReturn(CURRENT_USER_ID);
when(mockUm.getUsers()).thenReturn(userInfos);
when(mockUm.getProfiles(Matchers.anyInt())).thenReturn(userInfos);
when(mockUm.getProfileParent(WORK_USER_ID)).thenReturn(CURRENT_USER_INFO);
Context mockContext = new TestMockContext(getContext(), mockDpm, mockUm);
return mockContext;
}
private static final class TestMockContext extends MockContext {
private Context mRealContext;
private DevicePolicyManager mDpm;
private UserManager mUm;
public TestMockContext(Context realContext, DevicePolicyManager dpm, UserManager um) {
mRealContext = realContext;
mDpm = dpm;
mUm = um;
}
public Object getSystemService(String name) {
if (Context.DEVICE_POLICY_SERVICE.equals(name)) {
return mDpm;
} else if (Context.USER_SERVICE.equals(name)) {
return mUm;
} else {
return super.getSystemService(name);
}
}
public String getSystemServiceName(Class<?> serviceClass) {
return mRealContext.getSystemServiceName(serviceClass);
}
}
private static class EnterprisePolicyGuardTestable extends EnterprisePolicyGuard {
private boolean mIsContactRemoteSearchUserSettingEnabled;
public EnterprisePolicyGuardTestable(Context context,
boolean isContactRemoteSearchUserSettingEnabled) {
super(context);
mIsContactRemoteSearchUserSettingEnabled = isContactRemoteSearchUserSettingEnabled;
}
@Override
protected boolean isContactRemoteSearchUserSettingEnabled() {
return mIsContactRemoteSearchUserSettingEnabled;
}
}
}